diff --git a/elkscmd/file_utils/cp.c b/elkscmd/file_utils/cp.c index 6e23864..ed1e66c 100644 --- a/elkscmd/file_utils/cp.c +++ b/elkscmd/file_utils/cp.c @@ -22,9 +22,16 @@ #include #define BUF_SIZE 4096 +#define NOT_OVERWRITING 0xABCD static char *buf; +static unsigned int copy_count; + +/* we need some flags for command-line-options */ +static int option_no_overwrite; +static int option_verbose; +static int option_interactive; /* * Build a path name from the specified directory name and file name. @@ -79,14 +86,26 @@ int copyfile(char *srcname, char *destname, int setmodes) struct stat statbuf2; struct utimbuf times; - if (stat(srcname, &statbuf1) < 0) { + if (stat(srcname, &statbuf1) < 0) { // src nonexistent perror(srcname); return 0; } - if (stat(destname, &statbuf2) < 0) { + if (stat(destname, &statbuf2) < 0) { // dst nonexistent statbuf2.st_ino = -1; statbuf2.st_dev = -1; + } else { // dst existent + if(option_no_overwrite) { + fprintf(stderr, "dest '%s' is existent, not overwriting\n", destname); + return NOT_OVERWRITING; + } + if(option_interactive) { + /* TODO fix this, getchar wants return and seems not to work properly */ + //printf("really overwrite '%s'? (y/n) \n", destname); + //if(getchar() != 'y') { + // return NOT_OVERWRITING; + //} + } } if ((statbuf1.st_dev == statbuf2.st_dev) && @@ -143,6 +162,12 @@ int copyfile(char *srcname, char *destname, int setmodes) (void) utime(destname, ×); } + if(option_verbose) { + printf("copied '%s' -> '%s'\n", srcname, destname); + } + + copy_count++; + return 1; @@ -157,37 +182,78 @@ error_exit: int main(int argc, char **argv) { int dirflag; + int arg_counter; + int options_counter; + int retval; + unsigned int file_count; char *srcname; char *destname; char *lastarg; if (argc < 3) goto usage; - lastarg = argv[argc - 1]; + lastarg = argv[argc - 1]; // lastarg is copy destination - dirflag = isadir(lastarg); + dirflag = isadir(lastarg); // is destination a directory? + + // set defaults for options // + option_no_overwrite = 0; + option_verbose = 0; + option_interactive = 0; + + // walk throug all args, see if there are options for copy-operation + // count options for later addition to arg-counter + arg_counter = 1; // start at argv[1] + options_counter = 0; + while(arg_counter < argc) { + if(!strcmp(argv[arg_counter], "-n")) { + options_counter++; + option_no_overwrite = 1; + } + if(!strcmp(argv[arg_counter], "-v")) { + options_counter++; + option_verbose = 1; + } + if(!strcmp(argv[arg_counter], "-i")) { + options_counter++; + option_interactive = 1; + } + if(!strcmp(argv[arg_counter], "-h")) goto usage; + arg_counter++; + } - if ((argc > 3) && !dirflag) { - fprintf(stderr, "%s: not a directory\n", lastarg); + if((argc > (3+options_counter)) && !dirflag) { // can't copy more than one src-files into one dst-file + fprintf(stderr, "%s is not a directory\n", lastarg); exit(1); } buf = malloc(BUF_SIZE); - while (argc-- > 2) { - srcname = argv[1]; + copy_count = 0; + file_count = 0; + while (argc-- > (2+options_counter)) { + srcname = argv[options_counter+1+file_count]; destname = lastarg; - if (dirflag) destname = buildname(destname, srcname); + if(dirflag) destname = buildname(destname, srcname); - if (!copyfile(*++argv, destname, 0)) goto error_copy; + retval = copyfile(srcname, destname, 0); + if((!retval) && (!(retval == NOT_OVERWRITING))) goto error_copy; + file_count++; } free(buf); + if(option_verbose) printf("copy-count = %d\n", copy_count); exit(0); error_copy: fprintf(stderr, "Failed to copy %s -> %s\n", srcname, destname); exit(1); usage: - fprintf(stderr, "usage: %s source_file dest_file\n", argv[0]); - fprintf(stderr, " %s file1 file2 ... dest_directory\n", argv[0]); + fprintf(stderr, "usage: %s [options] source_file dest_file\n", argv[0]); + fprintf(stderr, " %s [options] file1 file2 ... dest_directory\n", argv[0]); + fprintf(stderr, "options: -b make a backup of each exisiting destination file\n"); + fprintf(stderr, " -f if a existing destination file cannot be opened, remove it and try again\n"); + fprintf(stderr, " -n no overwriting\n"); + fprintf(stderr, " -v be verbose\n"); + fprintf(stderr, " -i interactive, prompt before overwrite\n"); + fprintf(stderr, " -u copy only if source file is newer than destination file\n"); exit(1); }