#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int err_code; /* * here are some function...

https://cs.nyu.edu/~mwalfish/classes/21sp/labs/lab2.html


#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int err_code; /* * here are some function signatures and macros that may be helpful. */ void handle_error(char* fullname, char* action); bool test_file(char* pathandname); bool is_dir(char* pathandname); const char* ftype_to_str(mode_t mode); void list_file(char* pathandname, char* name, bool list_long); void list_dir(char* dirname, bool list_long, bool list_all, bool recursive); /* * You can use the NOT_YET_IMPLEMENTED macro to error out when you reach parts * of the code you have not yet finished implementing. */ #define NOT_YET_IMPLEMENTED(msg) \ do { \ printf("Not yet implemented: " msg "\n"); \ exit(255); \ } while (0) /* * PRINT_ERROR: This can be used to print the cause of an error returned by a * system call. It can help with debugging and reporting error causes to * the user. Example usage: * if ( error_condition ) { * PRINT_ERROR(); * } */ #define PRINT_ERROR(progname, what_happened, pathandname) \ do { \ printf("%s: %s %s: %s\n", progname, what_happened, pathandname, \ strerror(errno)); \ } while (0) /* PRINT_PERM_CHAR: * * This will be useful for -l permission printing. It prints the given * 'ch' if the permission exists, or "-" otherwise. * Example usage: * PRINT_PERM_CHAR(sb.st_mode, S_IRUSR, "r"); */ #define PRINT_PERM_CHAR(mode, mask, ch) printf("%s", (mode & mask) ? ch : "-"); /* * Get username for uid. Return 1 on failure, 0 otherwise. */ static int uname_for_uid(uid_t uid, char* buf, size_t buflen) { struct passwd* p = getpwuid(uid); if (p == NULL) { return 1; } strncpy(buf, p->pw_name, buflen); return 0; } /* * Get group name for gid. Return 1 on failure, 0 otherwise. */ static int group_for_gid(gid_t gid, char* buf, size_t buflen) { struct group* g = getgrgid(gid); if (g == NULL) { return 1; } strncpy(buf, g->gr_name, buflen); return 0; } /* * Format the supplied `struct timespec` in `ts` (e.g., from `stat.st_mtim`) as a * string in `char *out`. Returns the length of the formatted string (see, `man * 3 strftime`). */ static size_t date_string(struct timespec* ts, char* out, size_t len) { struct timespec now; timespec_get(&now, TIME_UTC); struct tm* t = localtime(&ts->tv_sec); if (now.tv_sec < ts-="">tv_sec) { // Future time, treat with care. return strftime(out, len, "%b %e %Y", t); } else { time_t difference = now.tv_sec - ts->tv_sec; if (difference < 31556952ull)="" {="" return="" strftime(out,="" len,="" "%b="" %e="" %h:%m",="" t);="" }="" else="" {="" return="" strftime(out,="" len,="" "%b="" %e="" %y",="" t);="" }="" }="" }="" *="" *="" print="" help="" message="" and="" exit.="" */="" static="" void="" help()="" {="" *="" todo:="" add="" to="" this="" */="" printf("ls:="" list="" files\n");="" printf("\t--help:="" print="" this="" help\n");="" printf("-l="" or="" -l:="" long="" listing="" format="" for="" files,="" print="" owner,="" date,="" file="" size,="" etc:="" ");="" printf("-r="" or="" -r:="" recursively="" list="" all="" sub="" directories="" inside="" of="" current="" directory:="" ");="" printf("./ls=""> : display singular file: ") exit(0); } /* * call this when there's been an error. * The function should: * - print a suitable error message (this is already implemented) * - set appropriate bits in err_code */ void handle_error(char* what_happened, char* fullname) { PRINT_ERROR("ls", what_happened, fullname); // TODO: your code here: inspect errno and set err_code accordingly. return; } /* * test_file(): * test whether stat() returns successfully and if not, handle error. * Use this to test for whether a file or dir exists */ bool test_file(char* pathandname) { struct stat sb; if (stat(pathandname, &sb)) { handle_error("cannot access", pathandname); return false; } return true; } /* * is_dir(): tests whether the argument refers to a directory. * precondition: test_file() returns true. that is, call this function * only if test_file(pathandname) returned true. */ bool is_dir(char* pathandname) { /* TODO: fillin */ if (test_file(pathandname)) { struct stat paths; stat(pathandname, &paths); return S_ISREG(paths.st_mode) } return false; } /* convert the mode field in a struct stat to a file type, for -l printing */ const char* ftype_to_str(mode_t mode) { /* TODO: fillin */ char* temp = (char*)malloc(10); memset(temp,0,10); temp[0] = (mode & S_IFDIR) ? 'd' : '-'; temp[1] = (mode & S_IRUSR) ? 'R' : '-'; temp[2] = (mode & S_IWUSR) ? 'W' : '-'; temp[3] = (mode & S_IXUSR) ? 'X' : '-'; temp[4] = (mode & S_IRGRP) ? 'R' : '-'; temp[5] = (mode & S_IWGRP) ? 'W' : '-'; temp[6] = (mode & S_IXGRP) ? 'X' : '-'; temp[7] = (mode & S_IROTH) ? 'R' : '-'; temp[8] = (mode & S_IWOTH) ? 'W' : '-'; temp[9] = (mode & S_IXOTH) ? 'X' : '-'; return (const char*)temp; } /* list_file(): * implement the logic for listing a single file. * This function takes: * - pathandname: the directory name plus the file name. * - name: just the name "component". * - list_long: a flag indicated whether the printout should be in * long mode. * * The reason for this signature is convenience: some of the file-outputting * logic requires the full pathandname (specifically, testing for a directory * so you can print a '/' and outputting in long mode), and some of it * requires only the 'name' part. So we pass in both. An alternative * implementation would pass in pathandname and parse out 'name'. */ void list_file(char* pathandname,char* name, bool list_long) { /* TODO: fill in*/ dir *dirp struct dirent *dp; dirp = opendir(pathandname); if (dirp) { printf("%s\n", dp->d_name); closedir(dirp); } if (list_long) { } } /* list_dir(): * implement the logic for listing a directory. * This function takes: * - dirname: the name of the directory * - list_long: should the directory be listed in long mode? * - list_all: are we in "-a" mode? * - recursive: are we supposed to list sub-directories? */ void list_dir(char* dirname, bool list_long, bool list_all, bool recursive) { /* TODO: fill in * You'll probably want to make use of: * opendir() * readdir() * list_file() * snprintf() [to make the 'pathandname' argument to * list_file(). that requires
Mar 03, 2021
SOLUTION.PDF

Get Answer To This Question

Related Questions & Answers

More Questions »

Submit New Assignment

Copy and Paste Your Assignment Here