diff --git a/Main.c b/Main.c index 9d1c69624696ad4a2acdf3255cf6aa96fbf587e3..639c94c3e8c1f979a1474be0acc26e01978e0e23 100644 --- a/Main.c +++ b/Main.c @@ -38,16 +38,17 @@ // Variables. -char* root_path; // Root path, minus innermost dir. +char* root_path; // Root path, minus innermost dir. // Method Declaration. -void set_root_directory(); -char* get_path_end(); -void print_file_type(); -void print_file_type_full(); -void list_directory(); -void exit_program(); +void set_root_directory(); // Sets root directory for program. +char* get_path_end(); // Parses the last dir of the given path. +void print_file_type(); // Prints file mode/type, color coded. +void print_file_type_full(); // Prints all file mode/types. Incase types ever overlap. +int change_directory(); // Safely changes into directory based on permissions. +void list_directory(); // Lists all items within directory. +void exit_program(); // Cleanly exits program. /** @@ -88,7 +89,7 @@ int main(int argc, char* argv[]) { ANSI_COLOR_MAGENTA " Named Pipe " ANSI_COLOR_RESET ANSI_COLOR_GREEN " Symbolic Link " ANSI_COLOR_RESET ANSI_COLOR_CYAN " Socket " ANSI_COLOR_RESET - "\n\n" + "\n" ); // Change to root directory. @@ -98,8 +99,6 @@ int main(int argc, char* argv[]) { } set_root_directory(argv[1]); - //printf("Path: %s\n", root_path); - // print_file_type(argv[1]); return_int = enqueue_node(root_path); if (return_int == 0) { @@ -108,20 +107,19 @@ int main(int argc, char* argv[]) { while (head_node != NULL) { printf("\n"); - printf("Listing Directory for: %s\n", head_node->absolute_path); + printf("\n%s\n", head_node->absolute_path); - // Change current directory to node path. - return_int = chdir(head_node->absolute_path); - if (return_int < 0) { - err_sys("Failed to change directory."); + // Change current directory to current node's path. + return_int = change_directory(head_node->absolute_path); + if (return_int == 1) { + list_directory(head_node->absolute_path); } - - list_directory(); temp_node = dequeue_node(); free(temp_node->directory_name); free(temp_node->absolute_path); free(temp_node); } + printf("\n\n"); exit_program(); return 0; @@ -169,16 +167,53 @@ char* get_path_end(char* path) { } +/** + * Safely changes directory by first checking path value and permissions. + * + * Return: 1 on success or 0 on failure. + */ +int change_directory(char* given_path) { + int return_int; + struct stat stat_buffer; + + // First read in node directory. + return_int = lstat(given_path, &stat_buffer); + if (return_int < 0) { + err_sys("Failed to stat file."); + } + + // First, ensure that it is, infact, a directory. + if (S_ISDIR(stat_buffer.st_mode)) { + // Next, check permissions. Only change upon owner permission. + if (stat_buffer.st_mode & S_IXUSR) { + // Change directory. + return_int = chdir(given_path); + if (return_int < 0) { + err_sys("Failed to change directory."); + return 0; + } + return 1; + } else { // No execute permission. + printf("No execute permission. Cannot change into dir.\n"); + return 0; + } + } else { // Not a directory. + printf("Provided path is not a directory.\n"); + return 0; + } +} + + /** * Lists contents of current directory (dictated by head_node values). * If subdirectory is found, append to queue and continue. */ -void list_directory() { +void list_directory(char* given_path) { int return_int; char* temp_string; struct dirent* dir_file; struct stat stat_buffer; - DIR* dir_pointer = opendir(head_node->absolute_path); + DIR* dir_pointer = opendir(given_path); // Loop until no more files to read in current directory.. while (dir_pointer != NULL) { @@ -197,7 +232,7 @@ void list_directory() { if ((strcmp(dir_file->d_name, ".") != 0) && (strcmp(dir_file->d_name, "..") != 0)) { // Is directory and not symbolic. Add to queue. - temp_string = copy_string_with_buffer(head_node->absolute_path, BUFFER_SIZE); + temp_string = copy_string_with_buffer(given_path, BUFFER_SIZE); strcat(temp_string, "/"); strcat(temp_string, dir_file->d_name); return_int = enqueue_node(temp_string); @@ -208,8 +243,8 @@ void list_directory() { } } - //print_file_type(dir_file->d_name, stat_buffer); - print_file_type_full(dir_file->d_name, stat_buffer); + print_file_type(dir_file->d_name, stat_buffer); + //print_file_type_full(dir_file->d_name, stat_buffer); } else { // End of files in directory. Closing stream. @@ -228,21 +263,21 @@ void list_directory() { */ void print_file_type(char* file_name, struct stat stat_buffer) { if (S_ISREG(stat_buffer.st_mode)) { - printf(ANSI_COLOR_RESET "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_RESET " %s " ANSI_COLOR_RESET, file_name); } else if (S_ISDIR(stat_buffer.st_mode)) { - printf(ANSI_COLOR_BLUE "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_BLUE " %s " ANSI_COLOR_RESET, file_name); } else if (S_ISCHR(stat_buffer.st_mode)) { - printf(ANSI_COLOR_YELLOW "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_YELLOW " %s " ANSI_COLOR_RESET, file_name); } else if (S_ISBLK(stat_buffer.st_mode)) { - printf(ANSI_COLOR_RED "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_RED " %s " ANSI_COLOR_RESET, file_name); } else if (S_ISFIFO(stat_buffer.st_mode)) { - printf(ANSI_COLOR_MAGENTA "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_MAGENTA " %s " ANSI_COLOR_RESET, file_name); } else if (S_ISLNK(stat_buffer.st_mode)) { - printf(ANSI_COLOR_GREEN "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_GREEN " %s " ANSI_COLOR_RESET, file_name); } else if (S_ISSOCK(stat_buffer.st_mode)) { - printf(ANSI_COLOR_CYAN "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_CYAN " %s " ANSI_COLOR_RESET, file_name); } else { - printf("%s - Unknown file mode.\n", file_name); + printf("%s - Unknown file mode.", file_name); } } @@ -253,35 +288,35 @@ void print_file_type(char* file_name, struct stat stat_buffer) { void print_file_type_full(char* file_name, struct stat stat_buffer) { int found_bool = 0; if (S_ISREG(stat_buffer.st_mode)) { - printf(ANSI_COLOR_RESET "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_RESET " %s " ANSI_COLOR_RESET, file_name); found_bool = 1; } if (S_ISDIR(stat_buffer.st_mode)) { - printf(ANSI_COLOR_BLUE "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_BLUE " %s " ANSI_COLOR_RESET, file_name); found_bool = 1; } if (S_ISCHR(stat_buffer.st_mode)) { - printf(ANSI_COLOR_YELLOW "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_YELLOW " %s " ANSI_COLOR_RESET, file_name); found_bool = 1; } if (S_ISBLK(stat_buffer.st_mode)) { - printf(ANSI_COLOR_RED "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_RED " %s " ANSI_COLOR_RESET, file_name); found_bool = 1; } if (S_ISFIFO(stat_buffer.st_mode)) { - printf(ANSI_COLOR_MAGENTA "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_MAGENTA " %s " ANSI_COLOR_RESET, file_name); found_bool = 1; } if (S_ISLNK(stat_buffer.st_mode)) { - printf(ANSI_COLOR_GREEN "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_GREEN " %s " ANSI_COLOR_RESET, file_name); found_bool = 1; } if (S_ISSOCK(stat_buffer.st_mode)) { - printf(ANSI_COLOR_CYAN "%s" ANSI_COLOR_RESET "\n", file_name); + printf(ANSI_COLOR_CYAN " %s " ANSI_COLOR_RESET, file_name); found_bool = 1; } if (!(found_bool)) { - printf("%s - Unknown file mode.\n", file_name); + printf(" %s - Unknown file mode. ", file_name); } }