Skip to content

Commit

Permalink
Add (untested) mv implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
duckinator committed Aug 28, 2020
1 parent dfc9ba2 commit 8f3f966
Showing 1 changed file with 41 additions and 5 deletions.
46 changes: 41 additions & 5 deletions src/mv.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@
* --version Print version information and exit.
*/

#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include "boreutils.h"

static int prompt(char *dest) {
Expand All @@ -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 `<dest>/<basename of src>`.
// Otherwise, returns `<dest>`.
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 `<dest>/<basename of src>`.

// 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);
// <dest size> + <1 for slash> + <basename size> + <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) {
Expand Down Expand Up @@ -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;
}
}
Expand Down

0 comments on commit 8f3f966

Please sign in to comment.