From d806fb200af6441c89659667471441919a4f4e5a Mon Sep 17 00:00:00 2001 From: Ellen Marie Dash Date: Fri, 28 Aug 2020 12:26:14 -0400 Subject: [PATCH] Add (untested) mv implementation. --- src/mv.c | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/mv.c b/src/mv.c index b02fe56..1485943 100644 --- a/src/mv.c +++ b/src/mv.c @@ -20,8 +20,11 @@ * --version Print version information and exit. */ +#include #include +#include #include +#include #include "boreutils.h" static int prompt(char *dest) { @@ -35,9 +38,41 @@ static int prompt(char *dest) { return 0; } -static int would_overwrite(char *src, char *dest) { - (void)src; - return access(dest, F_OK) + 1; +// If dest is a directory, returns `/`. +// Otherwise, returns ``. +static char *normalize_dest(char *src, char *dest) { + struct stat statbuf; + if (stat(dest, &statbuf) != 0) { + // `dest` doesn't exist. + return dest; + } + + if (!S_ISDIR(statbuf.st_mode)) { + // `dest` is a file (not a directory). + return dest; + } + + // Beyond this point, `dest` is known to be a directory. + // This means we need `/`. + + // First, get the basename of `src`. + char *base_name = basename(src); + size_t base_name_size = strlen(base_name); + + size_t dest_size = strlen(dest); + // + <1 for slash> + + <1 for null terminator> + char *full_dest = malloc(sizeof(char) * (dest_size + 1 + base_name_size + 1)); + memset(full_dest, 0, dest_size + 1 + base_name_size + 1); + + strncpy(full_dest, dest, dest_size + 1); + if (dest[dest_size - 1] != '/') { + full_dest[dest_size] = '/'; + strncpy(full_dest + dest_size + 1, base_name, base_name_size + 1); + } else { + strncpy(full_dest + dest_size, base_name, base_name_size + 1); + } + + return full_dest; } int main(int argc, char **argv) { @@ -77,8 +112,9 @@ int main(int argc, char **argv) { } for (; i < argc - 1; i++) { - if (should_prompt && would_overwrite(argv[i], dest)) { - if (prompt(dest) == 0) { + char *normalized_dest = normalize_dest(argv[i], dest); + if (should_prompt && access(normalized_dest, F_OK) == 0) { + if (prompt(normalized_dest) == 0) { continue; } }