Linux程序设计---chown命令的简单实现

来源:互联网 发布:淘宝买处方药审核难吗 编辑:程序博客网 时间:2024/06/12 00:19

chown命令的基本使用格式:chown owner:group filename

所以在命令行中这一行命令有三个参数:第一个是程序的执行文件名,第二个是属主和属组连在一起的字符串,第三个是要修改的文件名

基本思路:

chown系统调用的原型:

#include <sys/types.h>

#Include <unistd.h>

int chown(const char *path, uid_t owner, gid_t group);


这个系统调用的参数是文件路径,owner和group的uid和gid。而命令的使用是提供属主名和属组名,所以需要用系统调用getpwnam来获得相应的id值。

getpwnam系统调用原型:

#include <sys/types.h>

#include <pwd.h>

struct passwd *getpwnam(const char *name);

在passwd结构中声明了 pw_uid 成员,可通过这个成员来获得相应的uid。


所以程序的思路就是:先从第二个参数字符串中分离出属主名和属组名,然后通过系统调用getpwnam获得相应的uid。再然后判断第三个参数是否存在,如果存在则修改,如果不存在则输出错误信息,并退出程序。

程序源码:

#include <unistd.h>#include <fcntl.h>#include <dirent.h>#include <sys/types.h>#include <pwd.h>#include <stdlib.h>#include <stdio.h>int main(int argc, char **argv){char owner[128] = {'\0'}, group[128] = {'\0'};int i, o, g;struct passwd *pw_own, *pw_gro; //struct passwd 结构用于获得用户信息,如用户名,uid,gid...等 DIR *dp;i = o = g = 0;if (argc != 3){fprintf(stderr, "usage: %s owner:group path\n", argv[0]);exit(EXIT_FAILURE);}//argv[1]表示命令行第二个参数,argv[1][i]表示这个参数下标为 i 的字符 while (argv[1][i] != ':'){ //分离属主 owner[o] = argv[1][i];++i;++o;}owner[o] = '\0';++i;while (argv[1][i] != '\0'){ //分离出属组 group[g] = argv[1][i];++i;++g;}group[g] = '\0';//getpwnam函数用于按用户名获得用户信息 if ((pw_own = getpwnam(owner)) == NULL || (pw_gro = getpwnam(group)) == NULL){ printf("error: invalid user '%s'\n", argv[1]);exit(EXIT_FAILURE);}//41--58行代码主要是判断第三个参数是否存在,如果既不是目录也不是普通文件,则判断该参数不存在 if ((dp = opendir(argv[2])) == NULL){ //如果不是目录 if ((i = open(argv[2], O_RDONLY)) != -1) //如果是文件则将其关闭 close(i);else{ //既不是目录也不是文件,则输出该参数不存在 printf("error: cannot access '%s': %m\n", argv[2]); //%m插入等同于perror函数输出的错误信息 exit(EXIT_FAILURE);}}//与上面相反,先判断是否是文件,如果不是再判断是否是目录。再不是则判断不存在 if ((i = open(argv[2], O_RDONLY)) == -1){if ((dp = opendir(argv[2])) != NULL)closedir(dp);else{printf("error: cannot access '%s': %m\n", argv[2]);exit(EXIT_FAILURE);}}//修改属主,属组 if (chown(argv[2], pw_own->pw_uid, pw_gro->pw_uid) < 0) //chown系统调用的第二,第三个参数是用户的 uid perror("error"); //无法修改则输出错误信息 exit(EXIT_SUCCESS);}


原创粉丝点击