summaryrefslogtreecommitdiff
path: root/command
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
parentupdate ls (diff)
downloadlazysphere-67173fb97117a41cebb82a1364ae686a9574927b.tar.gz
lazysphere-67173fb97117a41cebb82a1364ae686a9574927b.tar.bz2
lazysphere-67173fb97117a41cebb82a1364ae686a9574927b.zip
slight refactor and start documenting
Diffstat (limited to 'command')
-rw-r--r--command/cat.c89
-rw-r--r--command/chmod.c122
-rw-r--r--command/chown.c123
-rw-r--r--command/ls.c17
4 files changed, 238 insertions, 113 deletions
diff --git a/command/cat.c b/command/cat.c
index f88ca28..8a87369 100644
--- a/command/cat.c
+++ b/command/cat.c
@@ -1,27 +1,28 @@
+/**
+ * file: cat.c
+ * author: Tyler Murphy
+ */
+
#include "command.h"
#include "lslib.h"
#include <ctype.h>
#include <stdlib.h>
+/**
+ * Flags that are to be used with cat
+ */
static struct {
- bool number_lines;
- bool number_non_empty;
- bool change_non_print;
- bool change_tabs;
- bool end_lines_dollar;
+ bool number_lines; /* if to number the lines */
+ bool number_non_empty; /* if to number empty lines */
+ bool change_non_print; /* if to change non printable characters to be printable */
+ bool change_tabs; /* if to change tabs to ^I */
+ bool end_lines_dollar; /* if to print a $ at the end of lines */
} flags;
-static bool printable(char c) {
- switch (c) {
- case '\n': return true;
- case '\r': return true;
- case '\b': return true;
- case '\t': return true;
- default: return isprint(c) == 0;
- }
-}
-
+/**
+ * Help function for cat
+ */
static void help(void) {
printf("Usage: cat [-nbvteA] [FILE]...\n\n");
printf("Print FILEs to stdout\n\n");
@@ -33,52 +34,68 @@ static void help(void) {
printf("\t-A Same as -vte\n");
}
+/**
+ * Give a file pointer, cat all its contents
+ * @param file the file to cat
+ */
static void cat_file(FILE* file) {
- char c;
- size_t read;
+ char c; /* current character read */
+ size_t read; /* amount read */
- size_t line = 1;
- bool empty = true;
- bool newline = true;
+ /* default arguments */
+ size_t line = 1; /* what line we are on, 1 indexed */
+ bool empty = true; /* if the current line is empty (nothing printed) */
+ bool newline = true; /* if we are on a new line */
+ /* read file a character at a time */
while ((read = fread(&c, 1, 1, file)) != 0) {
+ /* if its a new line, update the new line pointer */
if (c == '\n') {
- if (empty && flags.number_lines) {
+ if (empty && flags.number_lines) { /* print line number if set to */
printf("\t%ld ", line);
}
- if (flags.end_lines_dollar) {
+ if (flags.end_lines_dollar) { /* pint $ if set to */
printf("$");
}
line++;
- newline = true;
- empty = true;
+ newline = true; /* tell that the new line number is set to be printed */
+ empty = true; /* set line to empty */
goto print;
} else {
empty = false;
}
-
+
+ /* skip next check if not newline */
if (!newline) {
goto print;
}
+ /* if on a new line and is a valid char, print line number */
if (!empty && (flags.number_non_empty || flags.number_lines)) {
printf("\t%ld ", line);
newline = false;
}
print:
- if (!flags.change_non_print || printable(c)) {
+ /* print character */
+ if (!flags.change_non_print || printable_char(c)) {
if (flags.change_tabs && c == '\t') {
- fwrite("^I", 1, 2, stdout);
+ fwrite("^I", 1, 2, stdout); /* print ^I instead of tab */
} else {
- fwrite(&c, 1, 1, stdout);
+ fwrite(&c, 1, 1, stdout); /* print character to stdout */
}
- } else {
+ } else { /* if set to change non print, fix char code */
c |= '@';
fwrite(&c, 1, 1, stdout);
}
}
}
+/**
+ * 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) {
@@ -110,33 +127,41 @@ static int short_arg(char c, char* next) {
return ARG_UNUSED;
}
+/**
+ * Output a files contents
+ */
COMMAND(cat_main) {
int start;
int arg_len;
int i;
+ /* set flag defaults */
flags.number_lines = false;
flags.number_non_empty = false;
flags.change_non_print = false;
flags.change_tabs = false;
flags.end_lines_dollar = false;
+ /* parse user arguments */
start = parse_args(argc, argv, help, short_arg, NULL);
+ /* get the number of arguments to cat */
arg_len = argc - start;
+ /* if not read from stdin */
if (arg_len < 1) {
cat_file(stdin);
return EXIT_SUCCESS;
}
+ /* foreach file, try to open it, and then cat it */
for (i = start; i < argc; i++) {
- FILE* in = get_file(argv[i], "r");
- cat_file(in);
+ FILE* in = get_file(argv[i], "r"); /* open file as read */
+ cat_file(in); /* print it out */
if (in != stdin)
fclose(in);
}
- return EXIT_SUCCESS;
+ return EXIT_SUCCESS; /* success */
}
diff --git a/command/chmod.c b/command/chmod.c
index eabb91c..8bf6aab 100644
--- a/command/chmod.c
+++ b/command/chmod.c
@@ -1,3 +1,8 @@
+/**
+ * file: chmod.c
+ * author: Tyler Murphy
+ */
+
#include "command.h"
#include "lslib.h"
@@ -8,21 +13,30 @@
#include <dirent.h>
#include <string.h>
+/**
+ * If to add remove or directly set bits to a file
+ */
enum method {
ADD,
SUB,
SET
};
+/**
+ * Flags to set in chmod
+ */
static struct {
- bool recurse;
- bool list_changed;
- bool verbose;
- bool quiet;
- enum method method;
- mode_t mode;
+ bool recurse; /* if to recurse directorys */
+ bool list_changed; /* if to list what was updated */
+ bool verbose; /* if to list all output */
+ bool quiet; /* if to silence errors */
+ enum method method; /* the method to apply to the mode */
+ mode_t mode; /* the mode to apply with the method */
} flags;
+/**
+ * Help function for chmod
+ */
static void help (void) {
printf("Usage: chmod [-Rcvf] MODE[,MODE]... FILE...\n\n");
printf("MODE is octal number (bit pattern sstrwxrwxrwx) or {+|-|=}[rwxXst]\n\n");
@@ -32,6 +46,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) {
@@ -60,23 +80,31 @@ static int short_arg(char c, char* next) {
return ARG_UNUSED;
}
+/**
+ * Given a file path, modify its mode, and recurse if set to
+ * @param path the file path to modify
+ */
static void chmod_file(char* path) {
- int save;
- struct stat s;
- DIR* d;
- struct dirent* file;
- mode_t mode = 0;
+ /* allocate arguments on stack */
+ int save; /* path buffer save */
+ struct stat s; /* file info */
+ DIR* d; /* if recursing, open dir */
+ struct dirent* file; /* if recursing, file being read */
+ mode_t mode = 0; /* silence the uninitalized var error */
+ /* add path to path buffer */
save = push_path_buffer(path);
+ /* get file statics, if failed return */
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);
return;
}
+ /* get the new mode given the method and proved mode */
if (flags.method == SET) {
mode = flags.mode;;
} else if (flags.method == ADD) {
@@ -85,48 +113,60 @@ static void chmod_file(char* path) {
mode = s.st_mode & ~flags.mode;
}
+ /* attempt to modify the file mode, error and return if failed */
if (chmod(get_path_buffer(), mode) < 0) {
if (!flags.quiet) {
- error_s("cannot chmod '%s'", get_path_buffer());
+ error_s("cannot chmod '%s'", get_path_buffer()); /* error if failed */
}
- pop_path_buffer(save);
+ pop_path_buffer(save); /* clean up */
return;
} else if (flags.list_changed) {
- printf("chmod: changed '%s' to %o\n", get_path_buffer(), mode);
+ output("changed '%s' to %o", get_path_buffer(), mode); /* print if set to be verbose */
}
+ /* if not set to recurse, dont bother to do future checks */
if (!flags.recurse) {
pop_path_buffer(save);
return;
}
+ /* if not a dir, cant recurse and then return */
if (!S_ISDIR(s.st_mode)) {
pop_path_buffer(save);
return;
}
+ /* get the directory, if failed, error and return */
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;
}
+ /* chmod each file read */
while ((file = readdir(d)) != NULL) {
- if (is_dot_dir(file->d_name)) continue;
+ if (is_dot_dir(file->d_name)) continue; /* ignore dot dirs */
chmod_file(file->d_name);
}
+ /* clean up */
closedir(d);
pop_path_buffer(save);
}
+/**
+ * Parse a given mode and its method
+ * @param input a pointer to the string to check
+ * @return the mode parsed, mode parsing could not be done if reached , if so call again
+ */
static mode_t parse_mode(char** input) {
- mode_t mode = 00000;
- char* str = *input;
+ mode_t mode = 00000; /* default mode */
+ char* str = *input; /* get the input string */
+ /* check method for mode */
switch (*str) {
case '=':
flags.method = SET;
@@ -139,69 +179,76 @@ static mode_t parse_mode(char** input) {
break;
default:
flags.method = SET;
- mode = get_mode(str);
+ mode = get_mode(str); /* get mode and skip next checks */
goto end;
}
-next:
+next: /* check what bits to update */
str++;
switch (*str) {
- case 'r':
+ case 'r': /* read */
mode |= 00444;
goto next;
- case 'w':
+ case 'w': /* read */
mode |= 00200;
goto next;
- case 'x':
+ case 'x': /* execute */
mode |= 00111;
goto next;
- case 'X':
+ case 'X': /* empty */
mode |= 00000;
goto next;
- case 's':
+ case 's': /* setuid and setgid */
mode |= 06000;
goto next;
- case 't':
+ case 't': /* sticky */
mode |= 01000;
goto next;
case '\0':
- case ',':
+ case ',': /* stop reading args */
goto end;
default:
- error("invalid option: %c", *str);
+ error("invalid option: %c", *str); /* error when invalid */
}
-end:
+end: /* read till next argument and update input string pointer */
+
while (true) {
if (*str == '\0') {
- *input = NULL;
+ *input = NULL; /* no mroe args */
break;
}
if (*str == ',') {
- *input = ++str;
+ *input = ++str; /* another argument found */
break;
}
str++;
}
- return mode;
+ return mode; /* return mode */
}
+/**
+ * Modify a files permission mode
+ */
COMMAND(chmod_main) {
- int start, i;
+ int start, i;
+ /* get default flags */
flags.recurse = false;
flags.list_changed = false;
flags.verbose = false;
flags.quiet = false;
flags.mode = 0;
+ /* parse arguments */
start = parse_args(argc, argv, help, short_arg, NULL);
+ /* if not arguments error and return */
if (argc - start < 1) {
if (!flags.quiet) {
error("no mode provided");
@@ -210,10 +257,12 @@ COMMAND(chmod_main) {
}
}
+ /* parse mode continusally until no more mode arguments found */
do {
flags.mode |= parse_mode(&argv[start]);
} while (argv[start] != NULL);
+ /* if no files found error and return */
if (argc - start < 2) {
if (!flags.quiet) {
error("no files passed");
@@ -222,9 +271,10 @@ COMMAND(chmod_main) {
}
}
+ /* for each file passed, chmod */
for (i = start + 1; i < argc; i++) {
chmod_file(argv[i]);
}
- return EXIT_SUCCESS;
+ return EXIT_SUCCESS; /* return */
}
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 */
}
diff --git a/command/ls.c b/command/ls.c
index 788f2ff..f40cdf3 100644
--- a/command/ls.c
+++ b/command/ls.c
@@ -1,3 +1,8 @@
+/**
+ * file: ls.c
+ * author: Tyler Murphy
+ */
+
#include "command.h"
#include "lslib.h"
@@ -37,12 +42,12 @@ enum When {
* Flags that are to be used with ls
*/
static struct {
- bool hidden; /* -a */
- bool hide_dot; /* -A */
- bool more_info; /* -l */
- bool one_column; /* -1 */
- bool recurse; /* -R */
- bool octets; /* -o */
+ bool hidden; /* -a if to show hidden files */
+ bool hide_dot; /* -A if to hide dot dirs */
+ bool more_info; /* -l if to print info as a long list */
+ bool one_column; /* -1 if to print files as a single column */
+ bool recurse; /* -R if to recurse directorys */
+ bool octets; /* -o if to print mode as its octet instead of romanized */
enum When colored; /* --color=never/no/yes/always/auto */
} flags;