summaryrefslogtreecommitdiff
path: root/src/commands/cp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands/cp.c')
-rw-r--r--src/commands/cp.c240
1 files changed, 0 insertions, 240 deletions
diff --git a/src/commands/cp.c b/src/commands/cp.c
deleted file mode 100644
index df88155..0000000
--- a/src/commands/cp.c
+++ /dev/null
@@ -1,240 +0,0 @@
-#include "../command.h"
-#include <dirent.h>
-#include <limits.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-static struct {
- bool recurse;
- bool preserve;
- bool sym_link;
- bool hard_link;
- bool verbose;
-} flags;
-
-static void help(void) {
- printf("Usage: cp [-rplsv] SOURCE... DEST\n\n");
- printf("Copy SOURCEs to DEST\n\n");
- printf("\t-R,-r\tRecurse\n");
- printf("\t-p\tPreserve file attributes if possible\n");
- printf("\t-l,-s\tCreate (sym)links\n");
- printf("\t-v\tVerbose\n");
-}
-
-static int short_arg(char c, char* next) {
- UNUSED(next);
- switch (c) {
- case 'R':
- case 'r':
- flags.recurse = true;
- break;
- case 'p':
- flags.preserve = true;
- break;
- case 'l':
- flags.hard_link = true;
- flags.sym_link = false;
- break;
- case 's':
- flags.sym_link = true;
- flags.hard_link = false;
- break;
- case 'v':
- flags.verbose = true;
- break;
- default:
- return ARG_INVALID;
- }
- return ARG_UNUSED;
-}
-
-static bool copy_file(char* from, char* to) {
- #define BS 1024
-
- FILE *from_f, *to_f;
- char buf[BS];
- int read;
-
- from_f = get_file_s(from, "r");
- if (from_f == NULL) { return false; }
-
- to_f = get_file_s(to, "w");
- if (to_f == NULL) { fclose(from_f); return false; }
-
-
- while ((read = fread(buf, 1, BS, from_f)) > 0) {
- fwrite(buf, 1, read, to_f);
- }
-
- if (flags.verbose) {
- output("copied '%s'", from);
- }
-
- return true;
-}
-
-static bool symlink_file(char* from, char* to) {
- if (symlink(from, to) < 0) {
- error_s("failed to symlink '%s': %s", from, strerror(errno));
- return false;
- } else if (flags.verbose) {
- output("symlinked '%s'", from);
- }
- return true;
-}
-
-static bool hardlink_file(char* from, char* to) {
- if (link(from, to) < 0) {
- error_s("failed to hardlink '%s': %s", from, strerror(errno));
- return false;
- } else if (flags.verbose) {
- output("hardlinked '%s'", from);
- }
- return true;
-}
-
-static void run_copy(struct stat* s) {
-
- char* from = get_path_buffer();
- char* to = get_path_buffer_2();
-
- bool result;
- if (flags.sym_link) {
- result = symlink_file(from, to);
- } else if (flags.hard_link) {
- result = hardlink_file(from, to);
- } else {
- result = copy_file(from, to);
- }
-
- if (!result) return;
- if (!flags.preserve) return;
-
- if (chmod(to, s->st_mode) < 0) {
- error_s("cannot chmod '%s': %s", to, strerror(errno));
- return;
- }
-
- if (chown(to, s->st_uid, s->st_gid) < 0) {
- error_s("cannot chown '%s': %s", to, strerror(errno));
- return;
- }
-}
-
-static void cp_file(char* path);
-
-static void cp_directory(struct stat* s) {
-
- DIR* d;
- struct dirent* file;
-
- if (!flags.recurse) {
- error_s("-r not specified; omitting directory '%s'", get_path_buffer());
- return;
- }
-
- if (mkdir(get_path_buffer_2(), s->st_mode) < 0 && errno != EEXIST) {
- error_s("cannot create directory '%s': %s", get_path_buffer_2(), strerror(errno));
- return;
- }
-
- d = opendir(get_path_buffer());
-
- if (d == NULL) {
- error_s("cannot open directory '%s': %s", get_path_buffer(), strerror(errno));
- return;
- }
-
- while ((file = readdir(d)) != NULL) {
- if (is_dot_dir(file->d_name)) continue;
- cp_file(file->d_name);
- }
-}
-
-static char* get_file_name(char* path) {
- int last = 0;
- int i = 0;
-
- if (path[0] == '\0') return path;
-
- while (true) {
- if (path[i+1] == '\0') break;
- if (path[i] == '/') {
- last = i;
- }
- i++;
- }
-
- if (last == 0) return path;
- else return path + last + 1;
-}
-
-static void cp_file(char* path) {
-
- int save = push_path_buffer(path);
- int save2 = push_path_buffer_2(get_file_name(path));
-
- struct stat s;
- if (lstat(get_path_buffer(), &s) < 0) {
- pop_path_buffer(save);
- error_s("cannot stat '%s': %s", get_path_buffer(), strerror(errno));
- return;
- }
-
- if (S_ISDIR(s.st_mode)) {
- cp_directory(&s);
- } else {
- run_copy(&s);
- }
-
- pop_path_buffer(save);
- pop_path_buffer_2(save2);
-}
-
-COMMAND(cp) {
-
- int start, i;
- struct stat s;
-
- flags.hard_link = false;
- flags.sym_link = false;
- flags.preserve = false;
- flags.recurse = false;
- flags.verbose = false;
-
- start = parse_args(argc, argv, help, short_arg, NULL);
-
- if (argc - start < 2) {
- global_help(help);
- }
-
- /* only when 2 args and first is a file, the 2nd will be a file */
- if (argc - start == 2) {
- struct stat s;
- if (lstat(argv[start], &s) < 0) {
- error("cannot stat '%s': %s", argv[start], strerror(errno));
- }
- push_path_buffer(argv[argc-2]);
- push_path_buffer_2(argv[argc-1]);
- if (!S_ISDIR(s.st_mode)) {
- run_copy(&s);
- } else {
- cp_directory(&s);
- }
- return EXIT_SUCCESS;
- }
-
- /* push directory */
- push_path_buffer_2(argv[argc-1]);
-
- if (lstat(get_path_buffer_2(), &s) < 0) {
- error("target: '%s': %s", get_path_buffer_2(), strerror(errno));
- }
-
- for (i = start; i < argc - 1; i++) {
- cp_file(argv[i]);
- }
-
- return EXIT_SUCCESS;
-}