diff options
author | Tyler Murphy <tylerm@tylerm.dev> | 2023-05-16 19:15:01 -0400 |
---|---|---|
committer | Tyler Murphy <tylerm@tylerm.dev> | 2023-05-16 19:15:01 -0400 |
commit | 67173fb97117a41cebb82a1364ae686a9574927b (patch) | |
tree | e631e7515bcb7420b6348c0e3159336298d4e3df /command/chown.c | |
parent | update ls (diff) | |
download | lazysphere-67173fb97117a41cebb82a1364ae686a9574927b.tar.gz lazysphere-67173fb97117a41cebb82a1364ae686a9574927b.tar.bz2 lazysphere-67173fb97117a41cebb82a1364ae686a9574927b.zip |
slight refactor and start documenting
Diffstat (limited to 'command/chown.c')
-rw-r--r-- | command/chown.c | 123 |
1 files changed, 84 insertions, 39 deletions
diff --git a/command/chown.c b/command/chown.c index e78c1d2..7f9cb0f 100644 --- a/command/chown.c +++ b/command/chown.c @@ -1,3 +1,8 @@ +/** + * file: chown.c + * author: Tyler Murphy + */ + #include "command.h" #include "lslib.h" @@ -10,15 +15,21 @@ #include <sys/types.h> #include <pwd.h> +/** + * File flags to be used with chown + */ static struct { - bool recurse; - bool list_changed; - bool verbose; - bool quiet; - uid_t uid; - gid_t gid; + bool recurse; /* -R if to recurse directorys */ + bool list_changed; /* -c if to list what was changed */ + bool verbose; /* -v if to list all output */ + bool quiet; /* -f if to silence errors */ + uid_t uid; /* the uid to set the file to */ + gid_t gid; /* the gid to set the file to */ } flags; +/** + * Help function for chown + */ static void help (void) { printf("Usage: chown [-Rcvf]... USER[:[GRP]] FILE...\n\n"); printf("Change the owner and/or group of FILEs to USER and/or GRP\n\n"); @@ -28,6 +39,12 @@ static void help (void) { printf("\t-f\tHide errors\n"); } +/** + * Takes in each argument that has a single - and parses it + * @param c the character after the - + * @param next the next argument in argv that hasnt been parsed + * @reutrn if the next arg was used or if the arg was invalid + */ static int short_arg(char c, char* next) { UNUSED(next); switch (c) { @@ -49,68 +66,86 @@ static int short_arg(char c, char* next) { return ARG_UNUSED; } +/** + * Given a file path change the filw ownership with the given flags + * @param path the file to change the ownership + */ static void chown_file(char* path) { - int save; - struct stat s; - DIR* d; - struct dirent* file; + + /* allocate arguments on the stack */ + int save; /* path buffer save */ + struct stat s; /* file stats */ + DIR* d; /* recursing dir if recursing */ + struct dirent* file; /*if recursing current file being read */ save = push_path_buffer(path); + /* attempt to change file ownership, if failed error and return */ if (chown(get_path_buffer(), flags.uid, flags.gid) < 0) { if (!flags.quiet) { - error_s("cannot chown '%s'", get_path_buffer()); + error_s("cannot chown '%s'", get_path_buffer()); /* error if failed */ } - pop_path_buffer(save); + pop_path_buffer(save); /* cleanup */ return; - } else if (flags.list_changed) { - printf("chown: changed '%s' to %u:%u\n", get_path_buffer(), flags.uid, flags.gid); + } else if (flags.list_changed) { /* list changed if verbose */ + output("changed '%s' to %u:%u", get_path_buffer(), flags.uid, flags.gid); } + /* if not recurse dont do future checks and return */ if (!flags.recurse) { pop_path_buffer(save); return; } + /* stat file info and return if failed */ if (lstat(get_path_buffer(), &s) < 0) { if (!flags.quiet) { - error_s("cannot stat '%s'", get_path_buffer()); + error_s("cannot stat '%s'", get_path_buffer()); /* error if failed */ } - pop_path_buffer(save); + pop_path_buffer(save); /* clean up */ return; } + /* if not dir, cannot recurse so return */ if (!S_ISDIR(s.st_mode)) { - pop_path_buffer(save); + pop_path_buffer(save); /* clean up */ return; } + /* open dir, if failed return and error */ d = opendir(get_path_buffer()); if (d == NULL) { if (!flags.quiet) { - error_s("cannot open dir '%s'", get_path_buffer()); + error_s("cannot open dir '%s'", get_path_buffer()); /* error if failed */ } - pop_path_buffer(save); + pop_path_buffer(save); /* clean up */ return; } + /* read each file in directory, and modify its ownership recursivly */ while ((file = readdir(d)) != NULL) { - if (is_dot_dir(file->d_name)) continue; + if (is_dot_dir(file->d_name)) continue; /* if dot dir skip */ chown_file(file->d_name); } + /* clean up */ closedir(d); pop_path_buffer(save); } +/** + * Parse a given user and group from a string + * @param str the stirng to parse + */ static void parse_ownership(char* str) { - char* user = str; - char* group = NULL; - char* end = NULL; - unsigned long i; - struct passwd* p = NULL; - struct group* g = NULL; - + char* user = str; /* a copy of the input string */ + char* group = NULL; /* the group name found in str */ + char* end = NULL; /* the end of a string to parse a number if passed */ + unsigned long i; /* a number i */ + struct passwd* p = NULL; /* a user if found */ + struct group* g = NULL; /* a group if found */ + + /* attempy to find a colon seperating the user and group in the string, if not parse it as a user only */ for (i = 0; i < strlen(str); i++) { if (str[i] == ':') { str[i] = '\0'; @@ -119,33 +154,38 @@ static void parse_ownership(char* str) { } } + /* attempt to parse input as a number */ flags.uid = strtol(user, &end, 10); - if (end != user) goto group; + if (end != user) goto group; /* if successfull they ave a direct uid */ + /* if not try to get the user by the string */ if ((p = getpwnam(user)) == NULL) { - error("invalid user '%s'", user); + error("invalid user '%s'", user); /* error and abort if failed */ } else { - flags.uid = p->pw_uid; + flags.uid = p->pw_uid; /* update flags */ } group: + /* if the group string was not found set the gorup to the user */ if (group == NULL) { if (p == NULL) { - flags.gid = flags.uid; + flags.gid = flags.uid; /* if a int was passed set that int to the group as well */ } else { - flags.gid = p->pw_gid; + flags.gid = p->pw_gid; /* if a user was passed set the group to the users gid */ } return; } + /* if a group was passed, attempt to parse it as a gid first */ flags.gid = strtol(group, &end, 10); - if (end != group) return; + if (end != group) return; /* if succssfull return were done */ + /* otherwise try to get the group from the name */ if ((g = getgrnam(group)) == NULL) { - error("invalid group '%s'", group); + error("invalid group '%s'", group); /* error and abort if failed */ } else { - flags.gid = g->gr_gid; + flags.gid = g->gr_gid; /* update gid */ } } @@ -153,15 +193,18 @@ COMMAND(chown_main) { int start, i; + /* set default flags for chown */ flags.recurse = false; flags.list_changed = false; flags.verbose = false; flags.quiet = false; + /* parse argument */ start = parse_args(argc, argv, help, short_arg, NULL); + /* if no more arguments error and abort since no ownership passed */ if (argc - start < 1) { - if (!flags.quiet) { + if (!flags.quiet) { /* if not set to hide errors */ error("no onwership passed"); } else { return EXIT_FAILURE; @@ -170,17 +213,19 @@ COMMAND(chown_main) { parse_ownership(argv[start]); + /* if not more arugumnets error and abort since no files passed */ if (argc - start < 1) { - if (!flags.quiet) { - error("no files passed"); + if (!flags.quiet) { /* if not set to hide errors */ + error("no files passed"); } else { return EXIT_FAILURE; } } + /* change ownership for each file passed */ for (i = start + 1; i < argc; i++) { chown_file(argv[i]); } - return EXIT_SUCCESS; + return EXIT_SUCCESS; /* done */ } |