summaryrefslogtreecommitdiff
path: root/command/chown.c
diff options
context:
space:
mode:
authorTyler Murphy <tylerm@tylerm.dev>2023-05-16 19:15:01 -0400
committerTyler Murphy <tylerm@tylerm.dev>2023-05-16 19:15:01 -0400
commit67173fb97117a41cebb82a1364ae686a9574927b (patch)
treee631e7515bcb7420b6348c0e3159336298d4e3df /command/chown.c
parentupdate ls (diff)
downloadlazysphere-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.c123
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 */
}