diff options
Diffstat (limited to 'cp_mv.c')
-rw-r--r-- | cp_mv.c | 359 |
1 files changed, 174 insertions, 185 deletions
@@ -1,3 +1,4 @@ +/* vi: set sw=4 ts=4: */ /* * Mini `cp' and `mv' implementation for BusyBox. * @@ -39,217 +40,205 @@ #define is_cp 0 #define is_mv 1 -static const char *dz; /* dollar zero, .bss */ -static int dz_i; /* index, .bss */ -static const char *cp_mv_usage[] = /* .rodata */ +static const char *dz; /* dollar zero, .bss */ +static int dz_i; /* index, .bss */ +static const char *cp_mv_usage[] = /* .rodata */ { - "cp [OPTION]... SOURCE DEST\n" - " or: cp [OPTION]... SOURCE... DIRECTORY\n\n" - "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n" - "\n" - "\t-a\tsame as -dpR\n" - "\t-d\tpreserve links\n" - "\t-p\tpreserve file attributes if possible\n" - "\t-R\tcopy directories recursively\n" - , - "mv SOURCE DEST\n" - " or: mv SOURCE... DIRECTORY\n\n" - "Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n" - "Warning!! This is not GNU `mv'. It does not preserve hard links.\n" + "cp [OPTION]... SOURCE DEST\n" + " or: cp [OPTION]... SOURCE... DIRECTORY\n\n" + "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n" + "\n" + "\t-a\tsame as -dpR\n" + "\t-d\tpreserve links\n" + "\t-p\tpreserve file attributes if possible\n" + "\t-R\tcopy directories recursively\n", + "mv SOURCE DEST\n" + " or: mv SOURCE... DIRECTORY\n\n" + "Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n" + "Warning!! This is not GNU `mv'. It does not preserve hard links.\n" }; extern int cp_mv_main(int argc, char **argv) { - __label__ name_too_long__exit; - __label__ exit_false; - - int recursiveFlag; - int followLinks; - int preserveFlag; + __label__ name_too_long__exit; + __label__ exit_false; + + int recursiveFlag; + int followLinks; + int preserveFlag; + + const char *baseSrcName; + int srcDirFlag; + + char baseDestName[PATH_MAX + 1]; + size_t baseDestLen; + int destDirFlag; + + void fill_baseDest_buf(char *_buf, size_t * _buflen) { + const char *srcBasename; + if ((srcBasename = strrchr(baseSrcName, '/')) == NULL) { + srcBasename = baseSrcName; + if (_buf[*_buflen - 1] != '/') { + if (++(*_buflen) > PATH_MAX) + goto name_too_long__exit; + strcat(_buf, "/"); + } + } + if (*_buflen + strlen(srcBasename) > PATH_MAX) + goto name_too_long__exit; + strcat(_buf, srcBasename); + return; + } - const char *baseSrcName; - int srcDirFlag; + int fileAction(const char *fileName, struct stat *statbuf) { + __label__ return_false; + char destName[PATH_MAX + 1]; + size_t destLen; + const char *srcBasename; + + strcpy(destName, baseDestName); + destLen = strlen(destName); + + if (srcDirFlag == TRUE) { + if (recursiveFlag == FALSE) { + fprintf(stderr, omitting_directory, "cp", baseSrcName); + return TRUE; + } + srcBasename = (strstr(fileName, baseSrcName) + + strlen(baseSrcName)); + + if (destLen + strlen(srcBasename) > PATH_MAX) { + fprintf(stderr, name_too_long, "cp"); + goto return_false; + } + strcat(destName, srcBasename); + } else if (destDirFlag == TRUE) { + fill_baseDest_buf(&destName[0], &destLen); + } else { + srcBasename = baseSrcName; + } + return copyFile(fileName, destName, preserveFlag, followLinks); - char baseDestName[PATH_MAX + 1]; - size_t baseDestLen; - int destDirFlag; + return_false: + return FALSE; + } - void fill_baseDest_buf(char *_buf, size_t *_buflen) - { - const char *srcBasename; - if ((srcBasename = strrchr(baseSrcName, '/')) == NULL) - { - srcBasename = baseSrcName; - if (_buf[*_buflen - 1] != '/') - { - if (++(*_buflen) > PATH_MAX) - goto name_too_long__exit; - strcat(_buf, "/"); + int rmfileAction(const char *fileName, struct stat *statbuf) { + if (unlink(fileName) < 0) { + perror(fileName); + return FALSE; } - } - if (*_buflen + strlen(srcBasename) > PATH_MAX) - goto name_too_long__exit; - strcat(_buf, srcBasename); - return; + return TRUE; } - int fileAction(const char *fileName, struct stat *statbuf) - { - __label__ return_false; - char destName[PATH_MAX + 1]; - size_t destLen; - const char *srcBasename; - - strcpy(destName, baseDestName); - destLen = strlen(destName); - - if (srcDirFlag == TRUE) - { - if (recursiveFlag == FALSE) - { - fprintf(stderr, omitting_directory, "cp", baseSrcName); - return TRUE; - } - srcBasename = (strstr(fileName, baseSrcName) - + strlen(baseSrcName)); - if (destLen + strlen(srcBasename) > PATH_MAX) - { - fprintf(stderr, name_too_long, "cp"); - goto return_false; + int rmdirAction(const char *fileName, struct stat *statbuf) { + if (rmdir(fileName) < 0) { + perror(fileName); + return FALSE; } - strcat(destName, srcBasename); - } - else if (destDirFlag == TRUE) - { - fill_baseDest_buf(&destName[0], &destLen); - } - else - { - srcBasename = baseSrcName; - } - return copyFile(fileName, destName, preserveFlag, followLinks); - - return_false: - return FALSE; + return TRUE; } - int rmfileAction(const char *fileName, struct stat* statbuf) - { - if (unlink(fileName) < 0 ) { - perror(fileName); - return FALSE; - } - return TRUE; - } - - int rmdirAction(const char *fileName, struct stat* statbuf) - { - if (rmdir(fileName) < 0 ) { - perror(fileName); - return FALSE; - } - return TRUE; - } - - if ((dz = strrchr(*argv, '/')) == NULL) dz = *argv; else dz++; - if (*dz == 'c' && *(dz + 1) == 'p') dz_i = is_cp; else dz_i = is_mv; - if (argc < 3) usage(cp_mv_usage[dz_i]); - argc--; - argv++; - - if (dz_i == is_cp) - { - recursiveFlag = preserveFlag = FALSE; - followLinks = TRUE; - while (**argv == '-') - { - while (*++(*argv)) - { - switch (**argv) - { - case 'a': - followLinks = FALSE; - preserveFlag = TRUE; - recursiveFlag = TRUE; - break; - case 'd': - followLinks = FALSE; - break; - case 'p': - preserveFlag = TRUE; - break; - case 'R': - recursiveFlag = TRUE; - break; - default: - usage(cp_mv_usage[is_cp]); + if ((dz = strrchr(*argv, '/')) == NULL) + dz = *argv; + else + dz++; + if (*dz == 'c' && *(dz + 1) == 'p') + dz_i = is_cp; + else + dz_i = is_mv; + if (argc < 3) + usage(cp_mv_usage[dz_i]); + argc--; + argv++; + + if (dz_i == is_cp) { + recursiveFlag = preserveFlag = FALSE; + followLinks = TRUE; + while (**argv == '-') { + while (*++(*argv)) { + switch (**argv) { + case 'a': + followLinks = FALSE; + preserveFlag = TRUE; + recursiveFlag = TRUE; + break; + case 'd': + followLinks = FALSE; + break; + case 'p': + preserveFlag = TRUE; + break; + case 'R': + recursiveFlag = TRUE; + break; + default: + usage(cp_mv_usage[is_cp]); + } + } + argc--; + argv++; } - } - argc--; - argv++; - } - } - else /* (dz_i == is_mv) */ - { - recursiveFlag = preserveFlag = TRUE; - followLinks = FALSE; - } + } else { /* (dz_i == is_mv) */ - if (strlen(argv[argc - 1]) > PATH_MAX) - { - fprintf(stderr, name_too_long, "cp"); - goto exit_false; - } - strcpy(baseDestName, argv[argc - 1]); - baseDestLen = strlen(baseDestName); - if (baseDestLen == 0) goto exit_false; + recursiveFlag = preserveFlag = TRUE; + followLinks = FALSE; + } - destDirFlag = isDirectory(baseDestName, TRUE); - if ((argc > 3) && destDirFlag == FALSE) - { - fprintf(stderr, not_a_directory, "cp", baseDestName); - goto exit_false; - } + if (strlen(argv[argc - 1]) > PATH_MAX) { + fprintf(stderr, name_too_long, "cp"); + goto exit_false; + } + strcpy(baseDestName, argv[argc - 1]); + baseDestLen = strlen(baseDestName); + if (baseDestLen == 0) + goto exit_false; + + destDirFlag = isDirectory(baseDestName, TRUE); + if ((argc > 3) && destDirFlag == FALSE) { + fprintf(stderr, not_a_directory, "cp", baseDestName); + goto exit_false; + } - while (argc-- > 1) - { - size_t srcLen; - int flags_memo; + while (argc-- > 1) { + size_t srcLen; + int flags_memo; - baseSrcName = *(argv++); + baseSrcName = *(argv++); - if ((srcLen = strlen(baseSrcName)) > PATH_MAX) - goto name_too_long__exit; + if ((srcLen = strlen(baseSrcName)) > PATH_MAX) + goto name_too_long__exit; - if (srcLen == 0) continue; + if (srcLen == 0) + continue; - srcDirFlag = isDirectory(baseSrcName, followLinks); + srcDirFlag = isDirectory(baseSrcName, followLinks); - if ((flags_memo = (recursiveFlag == TRUE && - srcDirFlag == TRUE && destDirFlag == TRUE))) - { - fill_baseDest_buf(&baseDestName[0], &baseDestLen); + if ((flags_memo = (recursiveFlag == TRUE && + srcDirFlag == TRUE && destDirFlag == TRUE))) { + fill_baseDest_buf(&baseDestName[0], &baseDestLen); + } + if (recursiveAction(baseSrcName, + recursiveFlag, followLinks, FALSE, + fileAction, fileAction) == FALSE) + goto exit_false; + + if (dz_i == is_mv && + recursiveAction(baseSrcName, + recursiveFlag, followLinks, TRUE, + rmfileAction, rmdirAction) == FALSE) + goto exit_false; + + if (flags_memo) + *(baseDestName + baseDestLen) = '\0'; } - if (recursiveAction(baseSrcName, - recursiveFlag, followLinks, FALSE, - fileAction, fileAction) - == FALSE) goto exit_false; - - if (dz_i == is_mv && - recursiveAction(baseSrcName, - recursiveFlag, followLinks, TRUE, - rmfileAction, rmdirAction) - == FALSE) goto exit_false; - if (flags_memo) *(baseDestName + baseDestLen) = '\0'; - } + exit TRUE; - exit TRUE; - - name_too_long__exit: - fprintf(stderr, name_too_long, "cp"); - exit_false: - exit FALSE; + name_too_long__exit: + fprintf(stderr, name_too_long, "cp"); + exit_false: + exit FALSE; } // Local Variables: |