Some formatting updates (ran the code through indent)
-Erik
This commit is contained in:
381
cp_mv.c
381
cp_mv.c
@@ -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;
|
||||
__label__ name_too_long__exit;
|
||||
__label__ exit_false;
|
||||
|
||||
int recursiveFlag;
|
||||
int followLinks;
|
||||
int preserveFlag;
|
||||
int recursiveFlag;
|
||||
int followLinks;
|
||||
int preserveFlag;
|
||||
|
||||
const char *baseSrcName;
|
||||
int srcDirFlag;
|
||||
const char *baseSrcName;
|
||||
int srcDirFlag;
|
||||
|
||||
char baseDestName[PATH_MAX + 1];
|
||||
size_t baseDestLen;
|
||||
int destDirFlag;
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return_false:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
} else { /* (dz_i == is_mv) */
|
||||
|
||||
recursiveFlag = preserveFlag = TRUE;
|
||||
followLinks = 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;
|
||||
|
||||
baseSrcName = *(argv++);
|
||||
|
||||
if ((srcLen = strlen(baseSrcName)) > PATH_MAX)
|
||||
goto name_too_long__exit;
|
||||
strcat(_buf, "/");
|
||||
|
||||
if (srcLen == 0)
|
||||
continue;
|
||||
|
||||
srcDirFlag = isDirectory(baseSrcName, followLinks);
|
||||
|
||||
if ((flags_memo = (recursiveFlag == TRUE &&
|
||||
srcDirFlag == TRUE && destDirFlag == TRUE))) {
|
||||
fill_baseDest_buf(&baseDestName[0], &baseDestLen);
|
||||
}
|
||||
}
|
||||
if (*_buflen + strlen(srcBasename) > PATH_MAX)
|
||||
goto name_too_long__exit;
|
||||
strcat(_buf, srcBasename);
|
||||
return;
|
||||
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';
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return_false:
|
||||
return FALSE;
|
||||
}
|
||||
exit 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]);
|
||||
}
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
else /* (dz_i == is_mv) */
|
||||
{
|
||||
recursiveFlag = preserveFlag = TRUE;
|
||||
followLinks = FALSE;
|
||||
}
|
||||
|
||||
if (strlen(argv[argc - 1]) > PATH_MAX)
|
||||
{
|
||||
name_too_long__exit:
|
||||
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;
|
||||
|
||||
baseSrcName = *(argv++);
|
||||
|
||||
if ((srcLen = strlen(baseSrcName)) > PATH_MAX)
|
||||
goto name_too_long__exit;
|
||||
|
||||
if (srcLen == 0) continue;
|
||||
|
||||
srcDirFlag = isDirectory(baseSrcName, followLinks);
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
exit TRUE;
|
||||
|
||||
name_too_long__exit:
|
||||
fprintf(stderr, name_too_long, "cp");
|
||||
exit_false:
|
||||
exit FALSE;
|
||||
exit_false:
|
||||
exit FALSE;
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
|
Reference in New Issue
Block a user