diff --git a/Main.c b/Main.c index 7abcbb42e6b7bccc2626501874de924cbaa8adaa..cf1ad0a97fe228808503758a9c5581db7002de5f 100644 --- a/Main.c +++ b/Main.c @@ -18,11 +18,14 @@ */ +#define _BSD_SOURCE + // Import headers. #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/stat.h> #include <sys/wait.h> #include <unistd.h> #include "apue.h" @@ -46,10 +49,11 @@ makeargv_struct* command_argv; // Pointer to/array of makeargv structs. // Method Declaration. int makeargv(); // Creates argv using passed line. void parse_line(); // Parses provided line into commands. - void parse_command(); // Further parses line into smaller subsections. void execute_command(); // Executes provided command. void recursive_execute(); // Continues executing command. +void change_directory(); // Change current directory. +char* get_directory_path(); // Gets full pathname of current directory. void redirect_fd(); // Redirects passed file descriptors. void free_memory(); // Frees memory of vars. @@ -63,6 +67,7 @@ void make_arg_example(); int main(int argc, char* argv[]) { int run_program = 1; char* user_input; + char* current_directory; // parse_line(""); // parse_line("ls"); @@ -73,7 +78,11 @@ int main(int argc, char* argv[]) { // Run until user willingly quits. while (run_program == 1) { - user_input = get_user_input_with_prompt("$ "); + current_directory = get_directory_path(); + + printf(ANSI_COLOR_BLUE "%s$ " ANSI_COLOR_RESET, current_directory); + user_input = get_user_input_with_prompt(""); + free(current_directory); parse_line(user_input); @@ -89,7 +98,22 @@ int main(int argc, char* argv[]) { // Check for cd command. } else if (strcmp(**command_argv->argv, "cd") == 0) { - + if (line_argv->argc > 1) { + err_msg("Too many arguments."); + } else { + if (command_argv->argc < 2) { + err_msg("Need path argument."); + } else if (command_argv->argc > 2) { + err_msg("Too many arguments."); + } else { + change_directory(*(*command_argv->argv + 1)); + } + } + + } else if (strcmp(**command_argv->argv, "pwd") == 0) { + current_directory = get_directory_path(); + printf("%s\n", current_directory); + free(current_directory); // Attempt to exec command. } else { @@ -240,6 +264,57 @@ void recursive_execute(int argc, makeargv_struct* args, int current_arg) { } +/** + * Safely changes directory by first checking path value and permissions. + * + * Return: 1 on success or 0 on failure. + */ +void 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.\n"); + } + + // First, ensure that it is, infact, a directory. + if (S_ISDIR(stat_buffer.st_mode)) { + // Next, check permissions. + if ((access(given_path, X_OK)) == 0) { + // Change into directory. + return_int = chdir(given_path); + if (return_int < 0) { + err_msg("Failed to change directory.\n"); + } + } else { // No execute permission. + err_msg("No execute permission. Cannot change into dir.\n"); + } + } else { // Not a directory. + err_msg("Provided path is not a directory.\n"); + } +} + + +/** + * Gets current directory path. + */ +char* get_directory_path() { + char* root_path; + + // Allocate memory. + root_path = calloc(BUFFER_SIZE, sizeof(char)); + + // Set absolute path. + if ((getcwd(root_path, BUFFER_SIZE)) == NULL) { + err_sys("Failed to set root directory."); + } + + return root_path; +} + + /** * Frees memory of main program variables. */