The common format of the CHMOD command is as follows:
Chmod U + x filename
Therefore, this program can be compiled according to the CHMOD command format, File Permission acquisition, intermediate Parameter Parsing, permission summary, and File Permission modification. The analysis is as follows:
1. You can use the stat function to obtain file permissions. The function is prototype:
#include <sys/stat.h>#include <unistd.h>int stat(const char *file_name, struct stat *buf);
Of course, we need to know how the stat struct is declared here. The statement is as follows:
Struct stat {dev_t st_dev; // The device Number of the file ino_t st_ino; // node mode_t st_mode; // the file type and access permission nlink_t st_nlink; // number of hard connections to the file. The value of the created file is 1 uid_t st_uid; // user ID gid_t st_gid; // group ID dev_t st_rdev; // (device type) if this file is a device file, its device number off_t st_size is used; // The number of file bytes (file size) unsigned long st_blksize; // block size (File System I/O buffer size) unsigned long st_blocks; // number of blocks time_t st_atime; // The last access time time_t st_mtime; // The last modification time time_t st_ctime; // The last modification time (attribute )};
Here, you only need to use the st_mode field. St_mode contains all permissions for the file. The declared function prototype is:
mode_t get_file_mode(const char *path);
2. File permissions are divided into three categories: file owner, file owner, and other users. Therefore, three different cases are required. Of course, in order to reduce code writing, nine permissions can be stored in a two-dimensional array in advance.
mode_t mode[3][3]={{S_IRUSR , S_IWUSR , S_IXUSR} , {S_IRGRP , S_IWGRP , S_IXGRP} , {S_IROTH , S_IWOTH , S_IXOTH}};
Then, you can easily obtain the intermediate parameters for convenient permissions. This problem can be solved. Of course, to solve this problem, you need to compile a function to implement it. The prototype of the function is:
mode_t all_file_access(mode_t access , const char *argument);
3. In fact, this program can be basically completed here. Here, we only need to summarize the above two parts, and then simply call a chmod function to change the file permissions. The chmod function is prototype:
#include <sys/ctypes.h>#include <sys/stat.h>int chmod(const char *path, mode_t mode)
Well, the above are some ideas for implementing your own chmod command. The following is all the source code of your own chmod command:
#include <sys/types.h>#include <sys/stat.h>#include <stdio.h>#include <unistd.h>mode_t get_file_mode(const char *path){ struct stat buffer; if(stat(path , &buffer) == -1) { printf("The function stat error\n"); perror("stat error"); return (mode_t)0; } return buffer.st_mode;}mode_t all_file_access(mode_t access , const char *argument){ mode_t mode[3][3] = {{S_IRUSR , S_IWUSR , S_IXUSR} , {S_IRGRP , S_IWGRP , S_IXGRP} , {S_IROTH , S_IWOTH , S_IXOTH}}; int user; int user_access; mode_t user_mode; switch(argument[0]) { case ‘U‘: case ‘u‘: user = 0; break; case ‘g‘: case ‘G‘: user = 1; break; case ‘o‘: case ‘O‘: user = 2; break; default: printf("argument error !"); break; } switch(argument[2]) { case ‘r‘: case ‘R‘: user_access = 0; break; case ‘w‘: case ‘W‘: user_access = 1; break; case ‘x‘: case ‘X‘: user_access = 2; } user_mode = mode[user][user_access]; if(argument[1] == ‘+‘) return access | user_mode; return access ^ user_mode;}int my_chmod_function(const char *path , const char *argument){ mode_t mode; mode = all_file_access(get_file_mode(path) , argument); if(chmod(path , mode) == -1) { printf("Change file access failed !\n"); perror("Change file access failed "); return -1; } return 0;}int main(int argc , char **argv){ if(my_chmod_function(argv[2] , argv[1]) == -1) { printf("Access change failed !\n"); perror("Access change failed !"); return -1; } return 0;}
The running result is: