More stuff
No binary (build failed)
—
(log yok)
| @@ -199,12 +199,7 @@ int busybox_main(int argc, char **argv) | |
| argc--; | |
| argv++; | |
| - | /* If we've already been here once, exit now */ |
| - | if (been_there_done_that == 1) |
| - | return -1; |
| - | been_there_done_that = 1; |
| - | |
| - | if (argc < 1) { |
| + | if (been_there_done_that == 1 || argc < 1) { |
| const struct Applet *a = applets; | |
| fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n", | |
| BB_VER, BB_BT); | |
| @@ -224,6 +219,9 @@ int busybox_main(int argc, char **argv) | |
| } | |
| fprintf(stderr, "\n\n"); | |
| exit(-1); | |
| - | } else |
| + | } else { |
| + | /* If we've already been here once, exit now */ |
| + | been_there_done_that = 1; |
| return (main(argc, argv)); | |
| + | } |
| } | |
| @@ -1,64 +0,0 @@ | |
| - | #include "internal.h" |
| - | #include <dirent.h> |
| - | #include <string.h> |
| - | #include <stdio.h> |
| - | |
| - | const char block_device_usage[] = "block_device mount-point"; |
| - | |
| - | static dev_t *my_device; |
| - | static char *my_device_name; |
| - | |
| - | int |
| - | match_mount(const struct FileInfo * i) { |
| - | if ( S_ISBLK(i->stat.st_mode) |
| - | && (i->stat.st_rdev == *my_device)) { |
| - | my_device_name=strdup(i->source); |
| - | return 1; |
| - | } else |
| - | return 0; |
| - | } |
| - | |
| - | extern int |
| - | block_device_main(struct FileInfo * i, int argc, char * * argv) |
| - | { |
| - | char *device_name = block_device(argv[1],i); |
| - | if ( device_name == NULL ) |
| - | return -1; |
| - | printf("%s\n", device_name); |
| - | exit(0); |
| - | } |
| - | |
| - | char * block_device(const char *name, struct FileInfo *i) |
| - | { |
| - | struct stat s; |
| - | char *buf; |
| - | int dinam=0; |
| - | |
| - | if ( stat(name, &s) ) return (char *) NULL; |
| - | if (!i) { |
| - | i=(struct FileInfo*)malloc(sizeof(struct FileInfo)); |
| - | dinam = 1; |
| - | } |
| - | memset((void *)i, 0, sizeof(struct FileInfo)); |
| - | my_device=(dev_t *)malloc(sizeof(dev_t)); |
| - | *my_device = s.st_dev; |
| - | my_device_name = NULL; |
| - | i->source = "/dev"; |
| - | i->stat = s; |
| - | i->processDirectoriesAfterTheirContents=1; |
| - | descend(i, match_mount); |
| - | if (dinam) free(i); |
| - | if ( my_device_name ) { |
| - | buf = strdup(my_device_name); |
| - | free(my_device); |
| - | free(my_device_name); |
| - | return buf; |
| - | } else { |
| - | fprintf( stderr |
| - | ,"Can't find special file for block device %d, %d.\n" |
| - | ,(int) *my_device >> 8 & 0xff |
| - | ,(int) *my_device & 0xff); |
| - | free(my_device); |
| - | return (char *) NULL; |
| - | } |
| - | } |
| @@ -199,12 +199,7 @@ int busybox_main(int argc, char **argv) | |
| argc--; | |
| argv++; | |
| - | /* If we've already been here once, exit now */ |
| - | if (been_there_done_that == 1) |
| - | return -1; |
| - | been_there_done_that = 1; |
| - | |
| - | if (argc < 1) { |
| + | if (been_there_done_that == 1 || argc < 1) { |
| const struct Applet *a = applets; | |
| fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n", | |
| BB_VER, BB_BT); | |
| @@ -224,6 +219,9 @@ int busybox_main(int argc, char **argv) | |
| } | |
| fprintf(stderr, "\n\n"); | |
| exit(-1); | |
| - | } else |
| + | } else { |
| + | /* If we've already been here once, exit now */ |
| + | been_there_done_that = 1; |
| return (main(argc, argv)); | |
| + | } |
| } | |
| @@ -13,11 +13,9 @@ | |
| #define BB_CP | |
| #define BB_DATE | |
| #define BB_DD | |
| - | //#define BB_DESCEND |
| #define BB_DF | |
| #define BB_DMESG | |
| #define BB_DUTMP | |
| - | //#define BB_DYADIC |
| #define BB_FALSE | |
| //#define BB_FDFLUSH | |
| #define BB_FIND | |
| @@ -36,7 +34,6 @@ | |
| //#define BB_MKNOD | |
| ////#define BB_MKSWAP | |
| #define BB_MNC | |
| - | //#define BB_MONADIC |
| #define BB_MORE | |
| #define BB_MOUNT | |
| ////#define BB_MT | |
| @@ -48,9 +48,9 @@ static int fileAction(const char *fileName) | |
| ((chownApp==TRUE)? uid: statBuf.st_uid), | |
| gid) < 0)) { | |
| perror(fileName); | |
| - | return( TRUE); |
| + | return( FALSE); |
| } | |
| - | return( FALSE); |
| + | return( TRUE); |
| } | |
| int chown_main(int argc, char **argv) | |
| @@ -48,9 +48,9 @@ static int fileAction(const char *fileName) | |
| ((chownApp==TRUE)? uid: statBuf.st_uid), | |
| gid) < 0)) { | |
| perror(fileName); | |
| - | return( TRUE); |
| + | return( FALSE); |
| } | |
| - | return( FALSE); |
| + | return( TRUE); |
| } | |
| int chown_main(int argc, char **argv) | |
| @@ -47,43 +47,9 @@ static int fileAction(const char *fileName) | |
| char newdestName[NAME_MAX]; | |
| strcpy(newdestName, destName); | |
| strcat(newdestName, fileName+(strlen(srcName))); | |
| - | fprintf(stderr, "A: copying %s to %s\n", fileName, newdestName); |
| return (copyFile(fileName, newdestName, preserveFlag, followLinks)); | |
| } | |
| - | static int dirAction(const char *fileName) |
| - | { |
| - | char newdestName[NAME_MAX]; |
| - | struct stat statBuf; |
| - | struct utimbuf times; |
| - | |
| - | strcpy(newdestName, destName); |
| - | strcat(newdestName, fileName+(strlen(srcName))); |
| - | if (stat(newdestName, &statBuf)) { |
| - | if (mkdir( newdestName, 0777777 ^ umask (0))) { |
| - | perror(newdestName); |
| - | return( FALSE); |
| - | } |
| - | } |
| - | else if (!S_ISDIR (statBuf.st_mode)) { |
| - | fprintf(stderr, "`%s' exists but is not a directory", newdestName); |
| - | return( FALSE); |
| - | } |
| - | if (preserveFlag==TRUE) { |
| - | /* Try to preserve premissions, but don't whine on failure */ |
| - | if (stat(newdestName, &statBuf)) { |
| - | perror(newdestName); |
| - | return( FALSE); |
| - | } |
| - | chmod(newdestName, statBuf.st_mode); |
| - | chown(newdestName, statBuf.st_uid, statBuf.st_gid); |
| - | times.actime = statBuf.st_atime; |
| - | times.modtime = statBuf.st_mtime; |
| - | utime(newdestName, ×); |
| - | } |
| - | return TRUE; |
| - | } |
| - | |
| extern int cp_main(int argc, char **argv) | |
| { | |
| @@ -43,6 +43,50 @@ df(char* device, const char * mountPoint) | |
| return 0; | |
| } | |
| + | /* |
| + | * Given a block device, find the mount table entry if that block device |
| + | * is mounted. |
| + | * |
| + | * Given any other file (or directory), find the mount table entry for its |
| + | * filesystem. |
| + | */ |
| + | extern struct mntent * |
| + | findMountPoint(const char* name, const char* table) |
| + | { |
| + | struct stat s; |
| + | dev_t mountDevice; |
| + | FILE * mountTable; |
| + | struct mntent * mountEntry; |
| + | |
| + | if ( stat(name, &s) != 0 ) |
| + | return 0; |
| + | |
| + | if ( (s.st_mode & S_IFMT) == S_IFBLK ) |
| + | mountDevice = s.st_rdev; |
| + | else |
| + | mountDevice = s.st_dev; |
| + | |
| + | |
| + | if ( (mountTable = setmntent(table, "r")) == 0 ) |
| + | return 0; |
| + | |
| + | while ( (mountEntry = getmntent(mountTable)) != 0 ) { |
| + | if ( strcmp(name, mountEntry->mnt_dir) == 0 |
| + | || strcmp(name, mountEntry->mnt_fsname) == 0 ) /* String match. */ |
| + | break; |
| + | if ( stat(mountEntry->mnt_fsname, &s) == 0 |
| + | && s.st_rdev == mountDevice ) /* Match the device. */ |
| + | break; |
| + | if ( stat(mountEntry->mnt_dir, &s) == 0 |
| + | && s.st_dev == mountDevice ) /* Match the directory's mount point. */ |
| + | break; |
| + | } |
| + | endmntent(mountTable); |
| + | return mountEntry; |
| + | } |
| + | |
| + | |
| + | |
| extern int | |
| df_main(int argc, char * * argv) | |
| { | |
| @@ -90,47 +134,3 @@ df_main(int argc, char * * argv) | |
| - | |
| - | /* |
| - | * Given a block device, find the mount table entry if that block device |
| - | * is mounted. |
| - | * |
| - | * Given any other file (or directory), find the mount table entry for its |
| - | * filesystem. |
| - | */ |
| - | extern struct mntent * |
| - | findMountPoint(const char* name, const char* table) |
| - | { |
| - | struct stat s; |
| - | dev_t mountDevice; |
| - | FILE * mountTable; |
| - | struct mntent * mountEntry; |
| - | |
| - | if ( stat(name, &s) != 0 ) |
| - | return 0; |
| - | |
| - | if ( (s.st_mode & S_IFMT) == S_IFBLK ) |
| - | mountDevice = s.st_rdev; |
| - | else |
| - | mountDevice = s.st_dev; |
| - | |
| - | |
| - | if ( (mountTable = setmntent(table, "r")) == 0 ) |
| - | return 0; |
| - | |
| - | while ( (mountEntry = getmntent(mountTable)) != 0 ) { |
| - | if ( strcmp(name, mountEntry->mnt_dir) == 0 |
| - | || strcmp(name, mountEntry->mnt_fsname) == 0 ) /* String match. */ |
| - | break; |
| - | if ( stat(mountEntry->mnt_fsname, &s) == 0 |
| - | && s.st_rdev == mountDevice ) /* Match the device. */ |
| - | break; |
| - | if ( stat(mountEntry->mnt_dir, &s) == 0 |
| - | && s.st_dev == mountDevice ) /* Match the directory's mount point. */ |
| - | break; |
| - | } |
| - | endmntent(mountTable); |
| - | return mountEntry; |
| - | } |
| - | |
| - | |
| @@ -47,43 +47,9 @@ static int fileAction(const char *fileName) | |
| char newdestName[NAME_MAX]; | |
| strcpy(newdestName, destName); | |
| strcat(newdestName, fileName+(strlen(srcName))); | |
| - | fprintf(stderr, "A: copying %s to %s\n", fileName, newdestName); |
| return (copyFile(fileName, newdestName, preserveFlag, followLinks)); | |
| } | |
| - | static int dirAction(const char *fileName) |
| - | { |
| - | char newdestName[NAME_MAX]; |
| - | struct stat statBuf; |
| - | struct utimbuf times; |
| - | |
| - | strcpy(newdestName, destName); |
| - | strcat(newdestName, fileName+(strlen(srcName))); |
| - | if (stat(newdestName, &statBuf)) { |
| - | if (mkdir( newdestName, 0777777 ^ umask (0))) { |
| - | perror(newdestName); |
| - | return( FALSE); |
| - | } |
| - | } |
| - | else if (!S_ISDIR (statBuf.st_mode)) { |
| - | fprintf(stderr, "`%s' exists but is not a directory", newdestName); |
| - | return( FALSE); |
| - | } |
| - | if (preserveFlag==TRUE) { |
| - | /* Try to preserve premissions, but don't whine on failure */ |
| - | if (stat(newdestName, &statBuf)) { |
| - | perror(newdestName); |
| - | return( FALSE); |
| - | } |
| - | chmod(newdestName, statBuf.st_mode); |
| - | chown(newdestName, statBuf.st_uid, statBuf.st_gid); |
| - | times.actime = statBuf.st_atime; |
| - | times.modtime = statBuf.st_mtime; |
| - | utime(newdestName, ×); |
| - | } |
| - | return TRUE; |
| - | } |
| - | |
| extern int cp_main(int argc, char **argv) | |
| { | |
| @@ -1,124 +0,0 @@ | |
| - | #include "internal.h" |
| - | #include <stdio.h> |
| - | #include <dirent.h> |
| - | #include <string.h> |
| - | #include <errno.h> |
| - | |
| - | |
| - | static int |
| - | noDots(const struct dirent * e) |
| - | { |
| - | if ( e->d_name[0] == '.' |
| - | && (e->d_name[1] == '\0' |
| - | || (e->d_name[1] == '.' && e->d_name[2] == '\0')) ) |
| - | return 0; |
| - | else |
| - | return 1; |
| - | } |
| - | |
| - | extern int |
| - | descend( |
| - | struct FileInfo *oldInfo |
| - | ,int (*function)(const struct FileInfo * i)) |
| - | { |
| - | char pathname[1024]; |
| - | struct dirent * * names; |
| - | struct dirent * * n; |
| - | int length; |
| - | char * filename; |
| - | int status = 0; |
| - | int count; |
| - | |
| - | if ( *oldInfo->source == '\0' ) { |
| - | errno = EINVAL; |
| - | return -1; |
| - | } |
| - | |
| - | if ( oldInfo->stat.st_dev == 0 |
| - | && oldInfo->stat.st_ino == 0 |
| - | && oldInfo->stat.st_mode == 0 ) { |
| - | if ( lstat(oldInfo->source, &oldInfo->stat) != 0 ) |
| - | return -1; |
| - | oldInfo->isSymbolicLink = ((oldInfo->stat.st_mode & S_IFMT) == S_IFLNK); |
| - | |
| - | if ( oldInfo->isSymbolicLink ) |
| - | if ( stat(oldInfo->source, &oldInfo->stat) != 0 ) |
| - | memset((void *)&oldInfo->stat, 0, sizeof(oldInfo->stat)); |
| - | } |
| - | |
| - | if ( !oldInfo->processDirectoriesAfterTheirContents ) { |
| - | if ( function ) |
| - | status = (*function)(oldInfo); |
| - | if ( status == 0 ) |
| - | status = post_process(oldInfo); |
| - | } |
| - | |
| - | if ( (count = scandir(oldInfo->source, &names, noDots, alphasort)) < 0 ) |
| - | return -1; |
| - | |
| - | length = strlen(oldInfo->source); |
| - | if ( oldInfo->source[length-1] == '/' ) |
| - | length--; |
| - | |
| - | memcpy(pathname, oldInfo->source, length+1); |
| - | pathname[length] = '/'; |
| - | filename = &pathname[length+1]; |
| - | |
| - | n = names; |
| - | while ( count-- > 0 ) { |
| - | struct FileInfo i = *oldInfo; |
| - | |
| - | strcpy(filename, (*n)->d_name); |
| - | free(*n++); |
| - | |
| - | if ( lstat(pathname, &i.stat) != 0 && errno != ENOENT ) { |
| - | fprintf(stderr, "Can't stat %s: %s\n", pathname, strerror(errno)); |
| - | return -1; |
| - | } |
| - | i.isSymbolicLink = ((i.stat.st_mode & S_IFMT) == S_IFLNK); |
| - | |
| - | if ( i.isSymbolicLink ) |
| - | if ( stat(pathname, &i.stat) != 0 ) |
| - | memset((void *)&i.stat, 0, sizeof(i.stat)); |
| - | |
| - | i.source = pathname; |
| - | |
| - | if ( i.dyadic ) { |
| - | char d[1024]; |
| - | |
| - | i.destination = join_paths(d, i.destination, &i.source[i.directoryLength]); |
| - | } |
| - | else |
| - | i.destination = i.source; |
| - | |
| - | if ( !i.isSymbolicLink && (i.stat.st_mode & S_IFMT) == S_IFDIR ) |
| - | status = descend(&i, function); |
| - | else { |
| - | if ( function ) |
| - | status = (*function)(&i); |
| - | if ( status == 0 ) |
| - | status = post_process(&i); |
| - | } |
| - | |
| - | if ( !i.processDirectoriesAfterTheirContents |
| - | && status == 0 |
| - | && (i.stat.st_mode & S_IFMT) == S_IFDIR ) |
| - | descend(&i, function); |
| - | |
| - | if ( status != 0 && !i.force ) { |
| - | while ( count-- > 0 ) |
| - | free(*n++); |
| - | break; |
| - | } |
| - | } |
| - | free(names); |
| - | |
| - | if ( oldInfo->processDirectoriesAfterTheirContents ) { |
| - | if ( function ) |
| - | status = (*function)(oldInfo); |
| - | if ( status == 0 ) |
| - | status = post_process(oldInfo); |
| - | } |
| - | |
| - | return status; |
| - | } |
| @@ -43,6 +43,50 @@ df(char* device, const char * mountPoint) | |
| return 0; | |
| } | |
| + | /* |
| + | * Given a block device, find the mount table entry if that block device |
| + | * is mounted. |
| + | * |
| + | * Given any other file (or directory), find the mount table entry for its |
| + | * filesystem. |
| + | */ |
| + | extern struct mntent * |
| + | findMountPoint(const char* name, const char* table) |
| + | { |
| + | struct stat s; |
| + | dev_t mountDevice; |
| + | FILE * mountTable; |
| + | struct mntent * mountEntry; |
| + | |
| + | if ( stat(name, &s) != 0 ) |
| + | return 0; |
| + | |
| + | if ( (s.st_mode & S_IFMT) == S_IFBLK ) |
| + | mountDevice = s.st_rdev; |
| + | else |
| + | mountDevice = s.st_dev; |
| + | |
| + | |
| + | if ( (mountTable = setmntent(table, "r")) == 0 ) |
| + | return 0; |
| + | |
| + | while ( (mountEntry = getmntent(mountTable)) != 0 ) { |
| + | if ( strcmp(name, mountEntry->mnt_dir) == 0 |
| + | || strcmp(name, mountEntry->mnt_fsname) == 0 ) /* String match. */ |
| + | break; |
| + | if ( stat(mountEntry->mnt_fsname, &s) == 0 |
| + | && s.st_rdev == mountDevice ) /* Match the device. */ |
| + | break; |
| + | if ( stat(mountEntry->mnt_dir, &s) == 0 |
| + | && s.st_dev == mountDevice ) /* Match the directory's mount point. */ |
| + | break; |
| + | } |
| + | endmntent(mountTable); |
| + | return mountEntry; |
| + | } |
| + | |
| + | |
| + | |
| extern int | |
| df_main(int argc, char * * argv) | |
| { | |
| @@ -90,47 +134,3 @@ df_main(int argc, char * * argv) | |
| - | |
| - | /* |
| - | * Given a block device, find the mount table entry if that block device |
| - | * is mounted. |
| - | * |
| - | * Given any other file (or directory), find the mount table entry for its |
| - | * filesystem. |
| - | */ |
| - | extern struct mntent * |
| - | findMountPoint(const char* name, const char* table) |
| - | { |
| - | struct stat s; |
| - | dev_t mountDevice; |
| - | FILE * mountTable; |
| - | struct mntent * mountEntry; |
| - | |
| - | if ( stat(name, &s) != 0 ) |
| - | return 0; |
| - | |
| - | if ( (s.st_mode & S_IFMT) == S_IFBLK ) |
| - | mountDevice = s.st_rdev; |
| - | else |
| - | mountDevice = s.st_dev; |
| - | |
| - | |
| - | if ( (mountTable = setmntent(table, "r")) == 0 ) |
| - | return 0; |
| - | |
| - | while ( (mountEntry = getmntent(mountTable)) != 0 ) { |
| - | if ( strcmp(name, mountEntry->mnt_dir) == 0 |
| - | || strcmp(name, mountEntry->mnt_fsname) == 0 ) /* String match. */ |
| - | break; |
| - | if ( stat(mountEntry->mnt_fsname, &s) == 0 |
| - | && s.st_rdev == mountDevice ) /* Match the device. */ |
| - | break; |
| - | if ( stat(mountEntry->mnt_dir, &s) == 0 |
| - | && s.st_dev == mountDevice ) /* Match the directory's mount point. */ |
| - | break; |
| - | } |
| - | endmntent(mountTable); |
| - | return mountEntry; |
| - | } |
| - | |
| - | |
| @@ -1,28 +0,0 @@ | |
| - | #include "internal.h" |
| - | #include <stdio.h> |
| - | |
| - | extern int |
| - | dyadic_main( |
| - | struct FileInfo * i |
| - | ,int argc |
| - | ,char * * argv) |
| - | { |
| - | int flags; |
| - | |
| - | i->dyadic = 1; |
| - | i->destination = argv[argc - 1]; |
| - | |
| - | for ( flags = 0; flags < (argc - 1) && argv[flags + 1][0] == '-' ; flags++ ) |
| - | ; |
| - | if ( argc - flags < 3 ) { |
| - | usage(i->applet->usage); |
| - | return 1; |
| - | } |
| - | else if ( argc - flags > 3 ) { |
| - | if ( !is_a_directory(i->destination) ) { |
| - | fprintf(stderr, "%s: not a directory.\n", i->destination); |
| - | return 1; |
| - | } |
| - | } |
| - | return monadic_main(i, argc - 1, argv); |
| - | } |
| @@ -1,46 +0,0 @@ | |
| - | #include "internal.h" |
| - | #include <stdio.h> |
| - | #include <mntent.h> |
| - | #include <sys/stat.h> |
| - | |
| - | /* |
| - | * Given a block device, find the mount table entry if that block device |
| - | * is mounted. |
| - | * |
| - | * Given any other file (or directory), find the mount table entry for its |
| - | * filesystem. |
| - | */ |
| - | extern struct mntent * |
| - | findMountPoint(const char * name, const char * table) |
| - | { |
| - | struct stat s; |
| - | dev_t mountDevice; |
| - | FILE * mountTable; |
| - | struct mntent * mountEntry; |
| - | |
| - | if ( stat(name, &s) != 0 ) |
| - | return 0; |
| - | |
| - | if ( (s.st_mode & S_IFMT) == S_IFBLK ) |
| - | mountDevice = s.st_rdev; |
| - | else |
| - | mountDevice = s.st_dev; |
| - | |
| - | |
| - | if ( (mountTable = setmntent(table, "r")) == 0 ) |
| - | return 0; |
| - | |
| - | while ( (mountEntry = getmntent(mountTable)) != 0 ) { |
| - | if ( strcmp(name, mountEntry->mnt_dir) == 0 |
| - | || strcmp(name, mountEntry->mnt_fsname) == 0 ) /* String match. */ |
| - | break; |
| - | if ( stat(mountEntry->mnt_fsname, &s) == 0 |
| - | && s.st_rdev == mountDevice ) /* Match the device. */ |
| - | break; |
| - | if ( stat(mountEntry->mnt_dir, &s) == 0 |
| - | && s.st_dev == mountDevice ) /* Match the directory's mount point. */ |
| - | break; |
| - | } |
| - | endmntent(mountTable); |
| - | return mountEntry; |
| - | } |
| @@ -49,49 +49,11 @@ | |
| - | struct FileInfo { |
| - | unsigned int complainInPostProcess:1; |
| - | unsigned int changeUserID:1; |
| - | unsigned int changeGroupID:1; |
| - | unsigned int changeMode:1; |
| - | unsigned int create:1; |
| - | unsigned int force:1; |
| - | unsigned int recursive:1; |
| - | unsigned int processDirectoriesAfterTheirContents; |
| - | unsigned int makeParentDirectories:1; |
| - | unsigned int didOperation:1; |
| - | unsigned int isSymbolicLink:1; |
| - | unsigned int makeSymbolicLink:1; |
| - | unsigned int dyadic:1; |
| - | const char* source; |
| - | const char* destination; |
| - | int directoryLength; |
| - | uid_t userID; |
| - | gid_t groupID; |
| - | mode_t andWithMode; |
| - | mode_t orWithMode; |
| - | struct stat stat; |
| - | const struct Applet * |
| - | applet; |
| - | }; |
| - | |
| struct Applet { | |
| const char* name; | |
| int (*main)(int argc, char** argv); | |
| }; | |
| - | extern void name_and_error(const char*); |
| - | extern int is_a_directory(const char*); |
| - | extern char* join_paths(char *, const char *, const char *); |
| - | |
| - | extern int descend( |
| - | struct FileInfo *o |
| - | ,int (*function)(const struct FileInfo * i)); |
| - | |
| - | extern struct mntent * |
| - | findMountPoint(const char*, const char *); |
| - | |
| - | extern void usage(const char*); |
| extern int busybox_main(int argc, char** argv); | |
| extern int block_device_main(int argc, char** argv); | |
| extern int cat_more_main(int argc, char** argv); | |
| @@ -146,29 +108,6 @@ extern int update_main(int argc, char** argv); | |
| extern int zcat_main(int argc, char** argv); | |
| extern int gzip_main(int argc, char** argv); | |
| - | extern int |
| - | parse_mode( |
| - | const char* s |
| - | ,mode_t * or |
| - | ,mode_t * and |
| - | ,int * group_execute); |
| - | |
| - | extern int parse_user_name(const char* string, struct FileInfo * i); |
| - | |
| - | |
| - | /* |
| - | * A chunk of data. |
| - | * Chunks contain data which is allocated as needed, but which is |
| - | * not freed until all of the data needs freeing, such as at |
| - | * the beginning of the next command. |
| - | */ |
| - | typedef struct chunk CHUNK; |
| - | #define CHUNK_INIT_SIZE 4 |
| - | |
| - | struct chunk { |
| - | CHUNK *next; |
| - | char data[CHUNK_INIT_SIZE]; /* actually of varying length */ |
| - | }; |
| const char *modeString(int mode); | |
| const char *timeString(time_t timeVal); | |
| @@ -1,126 +0,0 @@ | |
| - | #include "internal.h" |
| - | #include <stdio.h> |
| - | #include <string.h> |
| - | #include <grp.h> |
| - | |
| - | extern int |
| - | monadic_main( |
| - | struct FileInfo * i |
| - | ,int argc |
| - | ,char * * argv) |
| - | { |
| - | int status = 0; |
| - | |
| - | while ( argc > 1 && argv[1][0] == '-' ) { |
| - | switch ( argv[1][1] ) { |
| - | case 'c': |
| - | i->create = 1; |
| - | break; |
| - | case 'f': |
| - | i->force = 1; |
| - | break; |
| - | case 'g': |
| - | if ( argc > 2 ) { |
| - | struct group * g; |
| - | if ( (g = getgrnam(argv[2])) == 0 ) { |
| - | fprintf(stderr, "%s: no such group.\n", argv[1]); |
| - | return 1; |
| - | } |
| - | i->groupID = g->gr_gid; |
| - | i->changeGroupID = 1; |
| - | i->complainInPostProcess = 1; |
| - | argc--; |
| - | argv++; |
| - | break; |
| - | } |
| - | usage(i->applet->usage); |
| - | return 1; |
| - | case 'm': |
| - | if ( argc > 2 ) { |
| - | status = parse_mode( |
| - | argv[2] |
| - | ,&i->orWithMode |
| - | ,&i->andWithMode, 0); |
| - | |
| - | if ( status == 0 ) { |
| - | i->changeMode = 1; |
| - | i->complainInPostProcess = 1; |
| - | argc--; |
| - | argv++; |
| - | break; |
| - | } |
| - | } |
| - | usage(i->applet->usage); |
| - | return 1; |
| - | case 'o': |
| - | if ( argc > 2 ) { |
| - | status = parse_user_name(argv[2], i); |
| - | if ( status != 0 ) |
| - | return status; |
| - | |
| - | i->changeUserID = 1; |
| - | i->complainInPostProcess = 1; |
| - | argc--; |
| - | argv++; |
| - | break; |
| - | } |
| - | usage(i->applet->usage); |
| - | return 1; |
| - | case 'p': |
| - | i->makeParentDirectories = 1; |
| - | break; |
| - | case 'r': |
| - | case 'R': |
| - | i->recursive = 1; |
| - | break; |
| - | case 's': |
| - | i->makeSymbolicLink = 1; |
| - | break; |
| - | default: |
| - | usage(i->applet->usage); |
| - | return 1; |
| - | } |
| - | argv++; |
| - | argc--; |
| - | } |
| - | while ( argc > 1 ) { |
| - | char * slash; |
| - | i->source = argv[1]; |
| - | if ( (slash = strrchr(i->source, '/')) != 0 ) { |
| - | i->directoryLength = slash - i->source; |
| - | if ( i->source[i->directoryLength] == '\0' ) |
| - | i->directoryLength = 0; |
| - | } |
| - | else |
| - | i->directoryLength = 0; |
| - | if ( !i->dyadic ) |
| - | i->destination = i->source; |
| - | |
| - | if ( lstat(i->source, &i->stat) == 0 ) { |
| - | i->isSymbolicLink = (i->stat.st_mode & S_IFMT)==S_IFLNK; |
| - | if ( i->isSymbolicLink ) |
| - | if ( stat(i->source, &i->stat) != 0 ) |
| - | memset(&i->stat, 0, sizeof(i->stat)); |
| - | } |
| - | else |
| - | memset(&i->stat, 0, sizeof(i->stat)); |
| - | |
| - | if ( i->isSymbolicLink |
| - | || !i->recursive |
| - | || ((i->stat.st_mode & S_IFMT) != S_IFDIR) ) { |
| - | |
| - | if ( i->applet->function ) |
| - | status = i->applet->function(i); |
| - | if ( status == 0 ) |
| - | status = post_process(i); |
| - | } |
| - | else |
| - | status = descend(i, i->applet->function); |
| - | |
| - | if ( status != 0 && !i->force ) |
| - | return status; |
| - | argv++; |
| - | argc--; |
| - | } |
| - | return 0; |
| - | } |
| @@ -1,41 +0,0 @@ | |
| - | #include "internal.h" |
| - | |
| - | extern int |
| - | post_process(const struct FileInfo * i) |
| - | { |
| - | int status = 0; |
| - | |
| - | if ( i->destination == 0 || *i->destination == 0 ) |
| - | return 0; |
| - | |
| - | if ( status == 0 && i->changeMode ) { |
| - | mode_t mode = i->stat.st_mode & 07777; |
| - | mode &= i->andWithMode; |
| - | mode |= i->orWithMode; |
| - | status = chmod(i->destination, mode); |
| - | |
| - | if ( status != 0 && i->complainInPostProcess && !i->force ) { |
| - | name_and_error(i->destination); |
| - | return 1; |
| - | } |
| - | } |
| - | |
| - | if ( i->changeUserID || i->changeGroupID ) { |
| - | uid_t uid = i->stat.st_uid; |
| - | gid_t gid = i->stat.st_gid; |
| - | |
| - | if ( i->changeUserID ) |
| - | uid = i->userID; |
| - | if ( i->changeGroupID ) |
| - | gid = i->groupID; |
| - | |
| - | status = chown(i->destination, uid, gid); |
| - | |
| - | if ( status != 0 && i->complainInPostProcess && !i->force ) { |
| - | name_and_error(i->destination); |
| - | return 1; |
| - | } |
| - | } |
| - | |
| - | return status; |
| - | } |
| @@ -33,102 +33,9 @@ | |
| #include <sys/stat.h> | |
| #include <unistd.h> | |
| - | #if 0 |
| - | |
| - | extern char *join_paths(char *buffer, const char *a, const char *b) |
| - | { |
| - | int length = 0; |
| - | |
| - | if (a && *a) { |
| - | length = strlen(a); |
| - | memcpy(buffer, a, length); |
| - | } |
| - | if (b && *b) { |
| - | if (length > 0 && buffer[length - 1] != '/') |
| - | buffer[length++] = '/'; |
| - | if (*b == '/') |
| - | b++; |
| - | strcpy(&buffer[length], b); |
| - | } |
| - | return buffer; |
| - | } |
| - | |
| - | #endif |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | static CHUNK *chunkList; |
| - | |
| - | |
| - | /* |
| - | * Return the standard ls-like mode string from a file mode. |
| - | * This is static and so is overwritten on each call. |
| - | */ |
| - | const char *modeString(int mode) |
| - | { |
| - | static char buf[12]; |
| - | |
| - | strcpy(buf, "----------"); |
| - | |
| - | /* |
| - | * Fill in the file type. |
| - | */ |
| - | if (S_ISDIR(mode)) |
| - | buf[0] = 'd'; |
| - | if (S_ISCHR(mode)) |
| - | buf[0] = 'c'; |
| - | if (S_ISBLK(mode)) |
| - | buf[0] = 'b'; |
| - | if (S_ISFIFO(mode)) |
| - | buf[0] = 'p'; |
| - | #ifdef S_ISLNK |
| - | if (S_ISLNK(mode)) |
| - | buf[0] = 'l'; |
| - | #endif |
| - | #ifdef S_ISSOCK |
| - | if (S_ISSOCK(mode)) |
| - | buf[0] = 's'; |
| - | #endif |
| - | |
| - | /* |
| - | * Now fill in the normal file permissions. |
| - | */ |
| - | if (mode & S_IRUSR) |
| - | buf[1] = 'r'; |
| - | if (mode & S_IWUSR) |
| - | buf[2] = 'w'; |
| - | if (mode & S_IXUSR) |
| - | buf[3] = 'x'; |
| - | if (mode & S_IRGRP) |
| - | buf[4] = 'r'; |
| - | if (mode & S_IWGRP) |
| - | buf[5] = 'w'; |
| - | if (mode & S_IXGRP) |
| - | buf[6] = 'x'; |
| - | if (mode & S_IROTH) |
| - | buf[7] = 'r'; |
| - | if (mode & S_IWOTH) |
| - | buf[8] = 'w'; |
| - | if (mode & S_IXOTH) |
| - | buf[9] = 'x'; |
| - | |
| - | /* |
| - | * Finally fill in magic stuff like suid and sticky text. |
| - | */ |
| - | if (mode & S_ISUID) |
| - | buf[3] = ((mode & S_IXUSR) ? 's' : 'S'); |
| - | if (mode & S_ISGID) |
| - | buf[6] = ((mode & S_IXGRP) ? 's' : 'S'); |
| - | if (mode & S_ISVTX) |
| - | buf[9] = ((mode & S_IXOTH) ? 't' : 'T'); |
| - | |
| - | return buf; |
| - | } |
| + | #if defined (BB_CP) || defined (BB_MV) |
| /* | |
| * Return TRUE if a fileName is a directory. | |
| * Nonexistant files return FALSE. | |
| @@ -144,21 +51,6 @@ int isDirectory(const char *name) | |
| } | |
| - | /* |
| - | * Return TRUE if a filename is a block or character device. |
| - | * Nonexistant files return FALSE. |
| - | */ |
| - | int isDevice(const char *name) |
| - | { |
| - | struct stat statBuf; |
| - | |
| - | if (stat(name, &statBuf) < 0) |
| - | return FALSE; |
| - | |
| - | return S_ISBLK(statBuf.st_mode) || S_ISCHR(statBuf.st_mode); |
| - | } |
| - | |
| - | |
| /* | |
| * Copy one file to another, while possibly preserving its modes, times, | |
| * and modes. Returns TRUE if successful, or FALSE on a failure with an | |
| @@ -173,47 +65,49 @@ copyFile( | |
| int rfd; | |
| int wfd; | |
| int rcc; | |
| + | int result; |
| char buf[BUF_SIZE]; | |
| - | struct stat statBuf1; |
| - | struct stat statBuf2; |
| + | struct stat srcStatBuf; |
| + | struct stat dstStatBuf; |
| struct utimbuf times; | |
| - | if (stat(srcName, &statBuf1) < 0) { |
| + | if (followLinks == FALSE) |
| + | result = stat(srcName, &srcStatBuf); |
| + | else |
| + | result = lstat(srcName, &srcStatBuf); |
| + | |
| + | if (result < 0) { |
| perror(srcName); | |
| return FALSE; | |
| } | |
| - | if (stat(destName, &statBuf2) < 0) { |
| - | statBuf2.st_ino = -1; |
| - | statBuf2.st_dev = -1; |
| + | if (followLinks == FALSE) |
| + | result = stat(destName, &dstStatBuf); |
| + | else |
| + | result = lstat(destName, &dstStatBuf); |
| + | if (result < 0) { |
| + | dstStatBuf.st_ino = -1; |
| + | dstStatBuf.st_dev = -1; |
| } | |
| - | if ((statBuf1.st_dev == statBuf2.st_dev) && |
| - | (statBuf1.st_ino == statBuf2.st_ino)) { |
| + | if ((srcStatBuf.st_dev == dstStatBuf.st_dev) && |
| + | (srcStatBuf.st_ino == dstStatBuf.st_ino)) { |
| fprintf(stderr, "Copying file \"%s\" to itself\n", srcName); | |
| return FALSE; | |
| } | |
| - | if (S_ISDIR(statBuf1.st_mode)) { |
| + | if (S_ISDIR(srcStatBuf.st_mode)) { |
| + | //fprintf(stderr, "copying directory %s to %s\n", srcName, destName); |
| /* Make sure the directory is writable */ | |
| if (mkdir(destName, 0777777 ^ umask(0))) { | |
| perror(destName); | |
| return (FALSE); | |
| } | |
| - | } else if (S_ISFIFO(statBuf1.st_mode)) { |
| - | if (mkfifo(destName, 644)) { |
| - | perror(destName); |
| - | return (FALSE); |
| - | } |
| - | } else if (S_ISBLK(statBuf1.st_mode) || S_ISCHR(statBuf1.st_mode)) { |
| - | if (mknod(destName, 644, statBuf1.st_rdev)) { |
| - | perror(destName); |
| - | return (FALSE); |
| - | } |
| - | } else if (S_ISLNK(statBuf1.st_mode)) { |
| + | } else if (S_ISLNK(srcStatBuf.st_mode)) { |
| char *link_val; | |
| int link_size; | |
| + | //fprintf(stderr, "copying link %s to %s\n", srcName, destName); |
| link_val = (char *) alloca(PATH_MAX + 2); | |
| link_size = readlink(srcName, link_val, PATH_MAX + 1); | |
| if (link_size < 0) { | |
| @@ -222,17 +116,31 @@ copyFile( | |
| } | |
| link_val[link_size] = '\0'; | |
| if (symlink(link_val, destName)) { | |
| - | perror(srcName); |
| + | perror(destName); |
| return (FALSE); | |
| } | |
| - | } else { |
| + | } else if (S_ISFIFO(srcStatBuf.st_mode)) { |
| + | //fprintf(stderr, "copying fifo %s to %s\n", srcName, destName); |
| + | if (mkfifo(destName, 644)) { |
| + | perror(destName); |
| + | return (FALSE); |
| + | } |
| + | } else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode) |
| + | || S_ISSOCK (srcStatBuf.st_mode)) { |
| + | //fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName); |
| + | if (mknod(destName, srcStatBuf.st_mode, srcStatBuf.st_rdev)) { |
| + | perror(destName); |
| + | return (FALSE); |
| + | } |
| + | } else if (S_ISREG(srcStatBuf.st_mode)) { |
| + | //fprintf(stderr, "copying regular file %s to %s\n", srcName, destName); |
| rfd = open(srcName, O_RDONLY); | |
| if (rfd < 0) { | |
| perror(srcName); | |
| return FALSE; | |
| } | |
| - | wfd = creat(destName, statBuf1.st_mode); |
| + | wfd = creat(destName, srcStatBuf.st_mode); |
| if (wfd < 0) { | |
| perror(destName); | |
| close(rfd); | |
| @@ -244,27 +152,25 @@ copyFile( | |
| goto error_exit; | |
| } | |
| if (rcc < 0) { | |
| - | perror(srcName); |
| goto error_exit; | |
| } | |
| close(rfd); | |
| - | |
| if (close(wfd) < 0) { | |
| - | perror(destName); |
| return FALSE; | |
| } | |
| } | |
| if (setModes == TRUE) { | |
| - | chmod(destName, statBuf1.st_mode); |
| + | //fprintf(stderr, "Setting permissions for %s\n", destName); |
| + | chmod(destName, srcStatBuf.st_mode); |
| if (followLinks == TRUE) | |
| - | chown(destName, statBuf1.st_uid, statBuf1.st_gid); |
| + | chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid); |
| else | |
| - | lchown(destName, statBuf1.st_uid, statBuf1.st_gid); |
| + | lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid); |
| - | times.actime = statBuf1.st_atime; |
| - | times.modtime = statBuf1.st_mtime; |
| + | times.actime = srcStatBuf.st_atime; |
| + | times.modtime = srcStatBuf.st_mtime; |
| utime(destName, ×); | |
| } | |
| @@ -273,13 +179,17 @@ copyFile( | |
| error_exit: | |
| + | //fprintf(stderr, "choking on %s\n", destName); |
| + | perror(destName); |
| close(rfd); | |
| close(wfd); | |
| return FALSE; | |
| } | |
| + | #endif |
| + | #ifdef BB_MV |
| /* | |
| * Build a path name from the specified directory name and file name. | |
| * If the directory name is NULL, then the original fileName is returned. | |
| @@ -305,106 +215,77 @@ char *buildName(const char *dirName, const char *fileName) | |
| return buf; | |
| } | |
| + | #endif |
| /* | |
| - | * Make a NULL-terminated string out of an argc, argv pair. |
| - | * Returns TRUE if successful, or FALSE if the string is too long, |
| - | * with an error message given. This does not handle spaces within |
| - | * arguments correctly. |
| - | */ |
| - | int makeString( int argc, const char **argv, char *buf, int bufLen) |
| - | { |
| - | int len; |
| - | |
| - | while (argc-- > 0) { |
| - | len = strlen(*argv); |
| - | |
| - | if (len >= bufLen) { |
| - | fprintf(stderr, "Argument string too long\n"); |
| - | |
| - | return FALSE; |
| - | } |
| - | |
| - | strcpy(buf, *argv++); |
| - | |
| - | buf += len; |
| - | bufLen -= len; |
| - | |
| - | if (argc) |
| - | *buf++ = ' '; |
| - | |
| - | bufLen--; |
| - | } |
| - | |
| - | *buf = '\0'; |
| - | |
| - | return TRUE; |
| - | } |
| - | |
| - | |
| - | /* |
| - | * Allocate a chunk of memory (like malloc). |
| - | * The difference, though, is that the memory allocated is put on a |
| - | * list of chunks which can be freed all at one time. You CAN NOT free |
| - | * an individual chunk. |
| - | */ |
| - | char *getChunk(int size) |
| - | { |
| - | CHUNK *chunk; |
| - | |
| - | if (size < CHUNK_INIT_SIZE) |
| - | size = CHUNK_INIT_SIZE; |
| - | |
| - | chunk = (CHUNK *) malloc(size + sizeof(CHUNK) - CHUNK_INIT_SIZE); |
| - | |
| - | if (chunk == NULL) |
| - | return NULL; |
| - | |
| - | chunk->next = chunkList; |
| - | chunkList = chunk; |
| - | |
| - | return chunk->data; |
| - | } |
| - | |
| - | |
| - | /* |
| - | * Duplicate a string value using the chunk allocator. |
| - | * The returned string cannot be individually freed, but can only be freed |
| - | * with other strings when freeChunks is called. Returns NULL on failure. |
| + | * Return the standard ls-like mode string from a file mode. |
| + | * This is static and so is overwritten on each call. |
| */ | |
| - | char *chunkstrdup(const char *str) |
| + | const char *modeString(int mode) |
| { | |
| - | int len; |
| - | char *newStr; |
| - | |
| - | len = strlen(str) + 1; |
| - | newStr = getChunk(len); |
| + | static char buf[12]; |
| - | if (newStr) |
| - | memcpy(newStr, str, len); |
| + | strcpy(buf, "----------"); |
| - | return newStr; |
| - | } |
| + | /* |
| + | * Fill in the file type. |
| + | */ |
| + | if (S_ISDIR(mode)) |
| + | buf[0] = 'd'; |
| + | if (S_ISCHR(mode)) |
| + | buf[0] = 'c'; |
| + | if (S_ISBLK(mode)) |
| + | buf[0] = 'b'; |
| + | if (S_ISFIFO(mode)) |
| + | buf[0] = 'p'; |
| + | #ifdef S_ISLNK |
| + | if (S_ISLNK(mode)) |
| + | buf[0] = 'l'; |
| + | #endif |
| + | #ifdef S_ISSOCK |
| + | if (S_ISSOCK(mode)) |
| + | buf[0] = 's'; |
| + | #endif |
| + | /* |
| + | * Now fill in the normal file permissions. |
| + | */ |
| + | if (mode & S_IRUSR) |
| + | buf[1] = 'r'; |
| + | if (mode & S_IWUSR) |
| + | buf[2] = 'w'; |
| + | if (mode & S_IXUSR) |
| + | buf[3] = 'x'; |
| + | if (mode & S_IRGRP) |
| + | buf[4] = 'r'; |
| + | if (mode & S_IWGRP) |
| + | buf[5] = 'w'; |
| + | if (mode & S_IXGRP) |
| + | buf[6] = 'x'; |
| + | if (mode & S_IROTH) |
| + | buf[7] = 'r'; |
| + | if (mode & S_IWOTH) |
| + | buf[8] = 'w'; |
| + | if (mode & S_IXOTH) |
| + | buf[9] = 'x'; |
| - | /* |
| - | * Free all chunks of memory that had been allocated since the last |
| - | * call to this routine. |
| - | */ |
| - | void freeChunks(void) |
| - | { |
| - | CHUNK *chunk; |
| + | /* |
| + | * Finally fill in magic stuff like suid and sticky text. |
| + | */ |
| + | if (mode & S_ISUID) |
| + | buf[3] = ((mode & S_IXUSR) ? 's' : 'S'); |
| + | if (mode & S_ISGID) |
| + | buf[6] = ((mode & S_IXGRP) ? 's' : 'S'); |
| + | if (mode & S_ISVTX) |
| + | buf[9] = ((mode & S_IXOTH) ? 't' : 'T'); |
| - | while (chunkList) { |
| - | chunk = chunkList; |
| - | chunkList = chunk->next; |
| - | free((char *) chunk); |
| - | } |
| + | return buf; |
| } | |
| + | #ifdef BB_TAR |
| /* | |
| * Get the time string to be used for a file. | |
| * This is down to the minute for new files, but only the date for old files. | |
| @@ -577,8 +458,10 @@ int fullRead(int fd, char *buf, int len) | |
| return total; | |
| } | |
| + | #endif |
| + | #if defined (BB_CHOWN) || defined (BB_CP) || defined (BB_FIND) || defined (BB_LS) |
| /* | |
| * Walk down all the directories under the specified | |
| * location, and do something (something specified | |
| @@ -618,7 +501,6 @@ recursiveAction(const char *fileName, int recurse, int followLinks, | |
| if (S_ISDIR(statbuf.st_mode)) { | |
| DIR *dir; | |
| - | fprintf(stderr, "Dir: %s\n", fileName); |
| dir = opendir(fileName); | |
| if (!dir) { | |
| perror(fileName); | |
| @@ -627,7 +509,7 @@ recursiveAction(const char *fileName, int recurse, int followLinks, | |
| if (dirAction != NULL) { | |
| status = dirAction(fileName); | |
| if (status == FALSE) { | |
| - | perror("cp"); |
| + | perror(fileName); |
| return (FALSE); | |
| } | |
| } | |
| @@ -652,7 +534,6 @@ recursiveAction(const char *fileName, int recurse, int followLinks, | |
| return (FALSE); | |
| } | |
| } else { | |
| - | fprintf(stderr, "File: %s\n", fileName); |
| if (fileAction == NULL) | |
| return (TRUE); | |
| else | |
| @@ -661,6 +542,6 @@ recursiveAction(const char *fileName, int recurse, int followLinks, | |
| return (TRUE); | |
| } | |
| - | |
| + | #endif |
| /* END CODE */ | |