/* * fileutil.c * * Alexander Occhipinti * Student ID: 29994705 * Created: 3 Sep 2020 * Last Modified: 7 Sep 2020 * * fileutil is a program which is a utility for files. It combines the functionality of cat cp and mv. * This program allows you to copy the contents of a given file to stdout or to a another file. * It also allows you to delete the original (i.e. mv) if you please. * */ #include #include #include #include #include #include "fileutil.h" /* * Prints a given string to stdout. Returns nothing. */ void to_stdout(char *string) { write(1, string, strlen(string)); } /* * Prints a given string to stderr. Returns nothing. */ void to_stderr(char *string) { write(2, string, strlen(string)); } /* * Prints the contents of a given file (provided a path) to stdout. * Returns nothing. */ int open_file(char *path, int flags){ // Read the input file int fd; if ((fd = open(path, flags, NEW_FILE_PERMS)) <= 2){ to_stderr(path); to_stderr(" could not be opened.\n"); exit(1); // Exit if an error occurs } return fd; } void file_into_file(int source_fd, int dest_fd){ int bytes_read; char buffer[FILE_BUF_SIZE]; while ((bytes_read = read(source_fd, buffer, FILE_BUF_SIZE))) { write(dest_fd, buffer, bytes_read); } } void print_file(char *read_path) { int read_fd; read_fd = open_file(read_path, O_RDONLY); file_into_file(read_fd, 1); close(read_fd); } void copy_file(char *read_path, char *write_path, bool overwrite) { int read_fd, write_fd; int write_flags = O_WRONLY | O_CREAT | O_TRUNC; if (!overwrite) write_flags |= O_EXCL; read_fd = open_file(read_path, O_RDONLY); write_fd = open_file(write_path, write_flags); file_into_file(read_fd, write_fd); close(read_fd); close(write_fd); } char* get_filename(char *full_path){ char* filename = strrchr(full_path, '/'); // Find the string after the last occurence of a '/' if (!filename) return full_path; // If there are no slashes, the whole path is already a filename return ++filename; // Return the filename without a leading slash } arguments_t parse_arguments(int argc, char **argv){ arguments_t args = { .src_path_index = -1, .dir_path_index = -1, .valid = false, .move_flag = false, .force_flag = false, .dir_flag = false }; if (argc > 1) args.src_path_index = 1; for (int i = 2; i < argc; i++) { if (strcmp(argv[i], "-d") == 0) { args.dir_flag = true; args.dir_path_index = i+1; } else if (strcmp(argv[i], "-M") == 0) { args.move_flag = true; } else if (strcmp(argv[i], "-F") == 0) { args.force_flag = true; } } bool correct_flags = (args.move_flag || args.force_flag) ? args.dir_flag : true; args.valid = correct_flags && (args.dir_path_index < argc) && (argc >= MIN_NUM_OF_ARGS) && (argc <= MAX_NUM_OF_ARGS); return args; } void execute_subprogram(arguments_t args, char *argv[]) { if (!args.valid) { to_stderr("Invalid arguments given.\n"); exit(1); } char *source_path = (args.src_path_index == -1 ) ? DEFAULT_READ_PATH : argv[args.src_path_index]; char *dir_path; if (args.dir_flag){ dir_path = argv[args.dir_path_index]; copy_into_dir(source_path, dir_path, args.move_flag, args.force_flag); } else { print_file(source_path); } } void copy_into_dir(char *file_path, char *dir_path, bool move, bool overwrite){ char* filename; char* new_path; size_t new_path_len; // filename = strrchr(dir_path, '/'); filename = get_filename(file_path); // printf("%s\n", filename); new_path_len = strlen(dir_path) + strlen(filename) + 1; new_path = (char *) malloc(new_path_len); strcpy(new_path, dir_path); strcat(new_path, "/"); strcat(new_path, filename); copy_file(file_path, new_path, overwrite); if (move) unlink(file_path); to_stdout("Copy successful\n"); free(new_path); } int main(int argc, char *argv[]) { // switch (argc){ // case 0: // exit(1); // case 1: // print_file(DEFAULT_READ_PATH); // break; // case 2: // print_file(argv[1]); // break; // case 3: // to_stderr("Invalid number of arguments sepcified\n"); // exit(1); // break; // default: // if (strcmp(argv[2], "-d") == 0){ // copy_into_dir(argv[1], argv[3]); // } else { // to_stderr("Invalid argument(s) sepcified\n"); // exit(1); // } // } arguments_t args = parse_arguments(argc, argv); if (!args.valid) { to_stderr("nah"); return 1; } else { execute_subprogram(args, argv); } return 0; }