diff options
| author | Eric Andersen <andersen@codepoet.org> | 1999-10-13 18:01:10 +0000 |
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 1999-10-13 18:01:10 +0000 |
| commit | c6cb79dedfb1af4ce64e75cd1c0d3cc1bfa71225 (patch) | |
| tree | 685c18e7a6e52b315c9b8a142b8b21fc55e635fc | |
| parent | 5de3065f5870526a68adee314fe181af976a9246 (diff) | |
| download | busybox-w32-c6cb79dedfb1af4ce64e75cd1c0d3cc1bfa71225.tar.gz busybox-w32-c6cb79dedfb1af4ce64e75cd1c0d3cc1bfa71225.tar.bz2 busybox-w32-c6cb79dedfb1af4ce64e75cd1c0d3cc1bfa71225.zip | |
More stuff
| -rw-r--r-- | applets/busybox.c | 12 | ||||
| -rw-r--r-- | block_device.c | 64 | ||||
| -rw-r--r-- | busybox.c | 12 | ||||
| -rw-r--r-- | busybox.def.h | 3 | ||||
| -rw-r--r-- | chown.c | 4 | ||||
| -rw-r--r-- | coreutils/chown.c | 4 | ||||
| -rw-r--r-- | coreutils/cp.c | 34 | ||||
| -rw-r--r-- | coreutils/df.c | 88 | ||||
| -rw-r--r-- | cp.c | 34 | ||||
| -rw-r--r-- | descend.c | 124 | ||||
| -rw-r--r-- | df.c | 88 | ||||
| -rw-r--r-- | dyadic.c | 28 | ||||
| -rw-r--r-- | findmount.c | 46 | ||||
| -rw-r--r-- | internal.h | 61 | ||||
| -rw-r--r-- | monadic.c | 126 | ||||
| -rw-r--r-- | postprocess.c | 41 | ||||
| -rw-r--r-- | utility.c | 341 |
17 files changed, 213 insertions, 897 deletions
diff --git a/applets/busybox.c b/applets/busybox.c index f0258c36e..0892e84ec 100644 --- a/applets/busybox.c +++ b/applets/busybox.c | |||
| @@ -199,12 +199,7 @@ int busybox_main(int argc, char **argv) | |||
| 199 | argc--; | 199 | argc--; |
| 200 | argv++; | 200 | argv++; |
| 201 | 201 | ||
| 202 | /* If we've already been here once, exit now */ | 202 | if (been_there_done_that == 1 || argc < 1) { |
| 203 | if (been_there_done_that == 1) | ||
| 204 | return -1; | ||
| 205 | been_there_done_that = 1; | ||
| 206 | |||
| 207 | if (argc < 1) { | ||
| 208 | const struct Applet *a = applets; | 203 | const struct Applet *a = applets; |
| 209 | fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n", | 204 | fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n", |
| 210 | BB_VER, BB_BT); | 205 | BB_VER, BB_BT); |
| @@ -224,6 +219,9 @@ int busybox_main(int argc, char **argv) | |||
| 224 | } | 219 | } |
| 225 | fprintf(stderr, "\n\n"); | 220 | fprintf(stderr, "\n\n"); |
| 226 | exit(-1); | 221 | exit(-1); |
| 227 | } else | 222 | } else { |
| 223 | /* If we've already been here once, exit now */ | ||
| 224 | been_there_done_that = 1; | ||
| 228 | return (main(argc, argv)); | 225 | return (main(argc, argv)); |
| 226 | } | ||
| 229 | } | 227 | } |
diff --git a/block_device.c b/block_device.c deleted file mode 100644 index 87e7209c0..000000000 --- a/block_device.c +++ /dev/null | |||
| @@ -1,64 +0,0 @@ | |||
| 1 | #include "internal.h" | ||
| 2 | #include <dirent.h> | ||
| 3 | #include <string.h> | ||
| 4 | #include <stdio.h> | ||
| 5 | |||
| 6 | const char block_device_usage[] = "block_device mount-point"; | ||
| 7 | |||
| 8 | static dev_t *my_device; | ||
| 9 | static char *my_device_name; | ||
| 10 | |||
| 11 | int | ||
| 12 | match_mount(const struct FileInfo * i) { | ||
| 13 | if ( S_ISBLK(i->stat.st_mode) | ||
| 14 | && (i->stat.st_rdev == *my_device)) { | ||
| 15 | my_device_name=strdup(i->source); | ||
| 16 | return 1; | ||
| 17 | } else | ||
| 18 | return 0; | ||
| 19 | } | ||
| 20 | |||
| 21 | extern int | ||
| 22 | block_device_main(struct FileInfo * i, int argc, char * * argv) | ||
| 23 | { | ||
| 24 | char *device_name = block_device(argv[1],i); | ||
| 25 | if ( device_name == NULL ) | ||
| 26 | return -1; | ||
| 27 | printf("%s\n", device_name); | ||
| 28 | exit(0); | ||
| 29 | } | ||
| 30 | |||
| 31 | char * block_device(const char *name, struct FileInfo *i) | ||
| 32 | { | ||
| 33 | struct stat s; | ||
| 34 | char *buf; | ||
| 35 | int dinam=0; | ||
| 36 | |||
| 37 | if ( stat(name, &s) ) return (char *) NULL; | ||
| 38 | if (!i) { | ||
| 39 | i=(struct FileInfo*)malloc(sizeof(struct FileInfo)); | ||
| 40 | dinam = 1; | ||
| 41 | } | ||
| 42 | memset((void *)i, 0, sizeof(struct FileInfo)); | ||
| 43 | my_device=(dev_t *)malloc(sizeof(dev_t)); | ||
| 44 | *my_device = s.st_dev; | ||
| 45 | my_device_name = NULL; | ||
| 46 | i->source = "/dev"; | ||
| 47 | i->stat = s; | ||
| 48 | i->processDirectoriesAfterTheirContents=1; | ||
| 49 | descend(i, match_mount); | ||
| 50 | if (dinam) free(i); | ||
| 51 | if ( my_device_name ) { | ||
| 52 | buf = strdup(my_device_name); | ||
| 53 | free(my_device); | ||
| 54 | free(my_device_name); | ||
| 55 | return buf; | ||
| 56 | } else { | ||
| 57 | fprintf( stderr | ||
| 58 | ,"Can't find special file for block device %d, %d.\n" | ||
| 59 | ,(int) *my_device >> 8 & 0xff | ||
| 60 | ,(int) *my_device & 0xff); | ||
| 61 | free(my_device); | ||
| 62 | return (char *) NULL; | ||
| 63 | } | ||
| 64 | } | ||
| @@ -199,12 +199,7 @@ int busybox_main(int argc, char **argv) | |||
| 199 | argc--; | 199 | argc--; |
| 200 | argv++; | 200 | argv++; |
| 201 | 201 | ||
| 202 | /* If we've already been here once, exit now */ | 202 | if (been_there_done_that == 1 || argc < 1) { |
| 203 | if (been_there_done_that == 1) | ||
| 204 | return -1; | ||
| 205 | been_there_done_that = 1; | ||
| 206 | |||
| 207 | if (argc < 1) { | ||
| 208 | const struct Applet *a = applets; | 203 | const struct Applet *a = applets; |
| 209 | fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n", | 204 | fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n", |
| 210 | BB_VER, BB_BT); | 205 | BB_VER, BB_BT); |
| @@ -224,6 +219,9 @@ int busybox_main(int argc, char **argv) | |||
| 224 | } | 219 | } |
| 225 | fprintf(stderr, "\n\n"); | 220 | fprintf(stderr, "\n\n"); |
| 226 | exit(-1); | 221 | exit(-1); |
| 227 | } else | 222 | } else { |
| 223 | /* If we've already been here once, exit now */ | ||
| 224 | been_there_done_that = 1; | ||
| 228 | return (main(argc, argv)); | 225 | return (main(argc, argv)); |
| 226 | } | ||
| 229 | } | 227 | } |
diff --git a/busybox.def.h b/busybox.def.h index 848783b9f..090bd7e7c 100644 --- a/busybox.def.h +++ b/busybox.def.h | |||
| @@ -13,11 +13,9 @@ | |||
| 13 | #define BB_CP | 13 | #define BB_CP |
| 14 | #define BB_DATE | 14 | #define BB_DATE |
| 15 | #define BB_DD | 15 | #define BB_DD |
| 16 | //#define BB_DESCEND | ||
| 17 | #define BB_DF | 16 | #define BB_DF |
| 18 | #define BB_DMESG | 17 | #define BB_DMESG |
| 19 | #define BB_DUTMP | 18 | #define BB_DUTMP |
| 20 | //#define BB_DYADIC | ||
| 21 | #define BB_FALSE | 19 | #define BB_FALSE |
| 22 | //#define BB_FDFLUSH | 20 | //#define BB_FDFLUSH |
| 23 | #define BB_FIND | 21 | #define BB_FIND |
| @@ -36,7 +34,6 @@ | |||
| 36 | //#define BB_MKNOD | 34 | //#define BB_MKNOD |
| 37 | ////#define BB_MKSWAP | 35 | ////#define BB_MKSWAP |
| 38 | #define BB_MNC | 36 | #define BB_MNC |
| 39 | //#define BB_MONADIC | ||
| 40 | #define BB_MORE | 37 | #define BB_MORE |
| 41 | #define BB_MOUNT | 38 | #define BB_MOUNT |
| 42 | ////#define BB_MT | 39 | ////#define BB_MT |
| @@ -48,9 +48,9 @@ static int fileAction(const char *fileName) | |||
| 48 | ((chownApp==TRUE)? uid: statBuf.st_uid), | 48 | ((chownApp==TRUE)? uid: statBuf.st_uid), |
| 49 | gid) < 0)) { | 49 | gid) < 0)) { |
| 50 | perror(fileName); | 50 | perror(fileName); |
| 51 | return( TRUE); | 51 | return( FALSE); |
| 52 | } | 52 | } |
| 53 | return( FALSE); | 53 | return( TRUE); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | int chown_main(int argc, char **argv) | 56 | int chown_main(int argc, char **argv) |
diff --git a/coreutils/chown.c b/coreutils/chown.c index bcaeea38e..8d6cffa14 100644 --- a/coreutils/chown.c +++ b/coreutils/chown.c | |||
| @@ -48,9 +48,9 @@ static int fileAction(const char *fileName) | |||
| 48 | ((chownApp==TRUE)? uid: statBuf.st_uid), | 48 | ((chownApp==TRUE)? uid: statBuf.st_uid), |
| 49 | gid) < 0)) { | 49 | gid) < 0)) { |
| 50 | perror(fileName); | 50 | perror(fileName); |
| 51 | return( TRUE); | 51 | return( FALSE); |
| 52 | } | 52 | } |
| 53 | return( FALSE); | 53 | return( TRUE); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | int chown_main(int argc, char **argv) | 56 | int chown_main(int argc, char **argv) |
diff --git a/coreutils/cp.c b/coreutils/cp.c index 4cdfc843b..94b4ab024 100644 --- a/coreutils/cp.c +++ b/coreutils/cp.c | |||
| @@ -47,43 +47,9 @@ static int fileAction(const char *fileName) | |||
| 47 | char newdestName[NAME_MAX]; | 47 | char newdestName[NAME_MAX]; |
| 48 | strcpy(newdestName, destName); | 48 | strcpy(newdestName, destName); |
| 49 | strcat(newdestName, fileName+(strlen(srcName))); | 49 | strcat(newdestName, fileName+(strlen(srcName))); |
| 50 | fprintf(stderr, "A: copying %s to %s\n", fileName, newdestName); | ||
| 51 | return (copyFile(fileName, newdestName, preserveFlag, followLinks)); | 50 | return (copyFile(fileName, newdestName, preserveFlag, followLinks)); |
| 52 | } | 51 | } |
| 53 | 52 | ||
| 54 | static int dirAction(const char *fileName) | ||
| 55 | { | ||
| 56 | char newdestName[NAME_MAX]; | ||
| 57 | struct stat statBuf; | ||
| 58 | struct utimbuf times; | ||
| 59 | |||
| 60 | strcpy(newdestName, destName); | ||
| 61 | strcat(newdestName, fileName+(strlen(srcName))); | ||
| 62 | if (stat(newdestName, &statBuf)) { | ||
| 63 | if (mkdir( newdestName, 0777777 ^ umask (0))) { | ||
| 64 | perror(newdestName); | ||
| 65 | return( FALSE); | ||
| 66 | } | ||
| 67 | } | ||
| 68 | else if (!S_ISDIR (statBuf.st_mode)) { | ||
| 69 | fprintf(stderr, "`%s' exists but is not a directory", newdestName); | ||
| 70 | return( FALSE); | ||
| 71 | } | ||
| 72 | if (preserveFlag==TRUE) { | ||
| 73 | /* Try to preserve premissions, but don't whine on failure */ | ||
| 74 | if (stat(newdestName, &statBuf)) { | ||
| 75 | perror(newdestName); | ||
| 76 | return( FALSE); | ||
| 77 | } | ||
| 78 | chmod(newdestName, statBuf.st_mode); | ||
| 79 | chown(newdestName, statBuf.st_uid, statBuf.st_gid); | ||
| 80 | times.actime = statBuf.st_atime; | ||
| 81 | times.modtime = statBuf.st_mtime; | ||
| 82 | utime(newdestName, ×); | ||
| 83 | } | ||
| 84 | return TRUE; | ||
| 85 | } | ||
| 86 | |||
| 87 | extern int cp_main(int argc, char **argv) | 53 | extern int cp_main(int argc, char **argv) |
| 88 | { | 54 | { |
| 89 | 55 | ||
diff --git a/coreutils/df.c b/coreutils/df.c index 8cc93814b..a777d70f4 100644 --- a/coreutils/df.c +++ b/coreutils/df.c | |||
| @@ -43,6 +43,50 @@ df(char* device, const char * mountPoint) | |||
| 43 | return 0; | 43 | return 0; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | /* | ||
| 47 | * Given a block device, find the mount table entry if that block device | ||
| 48 | * is mounted. | ||
| 49 | * | ||
| 50 | * Given any other file (or directory), find the mount table entry for its | ||
| 51 | * filesystem. | ||
| 52 | */ | ||
| 53 | extern struct mntent * | ||
| 54 | findMountPoint(const char* name, const char* table) | ||
| 55 | { | ||
| 56 | struct stat s; | ||
| 57 | dev_t mountDevice; | ||
| 58 | FILE * mountTable; | ||
| 59 | struct mntent * mountEntry; | ||
| 60 | |||
| 61 | if ( stat(name, &s) != 0 ) | ||
| 62 | return 0; | ||
| 63 | |||
| 64 | if ( (s.st_mode & S_IFMT) == S_IFBLK ) | ||
| 65 | mountDevice = s.st_rdev; | ||
| 66 | else | ||
| 67 | mountDevice = s.st_dev; | ||
| 68 | |||
| 69 | |||
| 70 | if ( (mountTable = setmntent(table, "r")) == 0 ) | ||
| 71 | return 0; | ||
| 72 | |||
| 73 | while ( (mountEntry = getmntent(mountTable)) != 0 ) { | ||
| 74 | if ( strcmp(name, mountEntry->mnt_dir) == 0 | ||
| 75 | || strcmp(name, mountEntry->mnt_fsname) == 0 ) /* String match. */ | ||
| 76 | break; | ||
| 77 | if ( stat(mountEntry->mnt_fsname, &s) == 0 | ||
| 78 | && s.st_rdev == mountDevice ) /* Match the device. */ | ||
| 79 | break; | ||
| 80 | if ( stat(mountEntry->mnt_dir, &s) == 0 | ||
| 81 | && s.st_dev == mountDevice ) /* Match the directory's mount point. */ | ||
| 82 | break; | ||
| 83 | } | ||
| 84 | endmntent(mountTable); | ||
| 85 | return mountEntry; | ||
| 86 | } | ||
| 87 | |||
| 88 | |||
| 89 | |||
| 46 | extern int | 90 | extern int |
| 47 | df_main(int argc, char * * argv) | 91 | df_main(int argc, char * * argv) |
| 48 | { | 92 | { |
| @@ -90,47 +134,3 @@ df_main(int argc, char * * argv) | |||
| 90 | 134 | ||
| 91 | 135 | ||
| 92 | 136 | ||
| 93 | |||
| 94 | /* | ||
| 95 | * Given a block device, find the mount table entry if that block device | ||
| 96 | * is mounted. | ||
| 97 | * | ||
| 98 | * Given any other file (or directory), find the mount table entry for its | ||
| 99 | * filesystem. | ||
| 100 | */ | ||
| 101 | extern struct mntent * | ||
| 102 | findMountPoint(const char* name, const char* table) | ||
| 103 | { | ||
| 104 | struct stat s; | ||
| 105 | dev_t mountDevice; | ||
| 106 | FILE * mountTable; | ||
| 107 | struct mntent * mountEntry; | ||
| 108 | |||
| 109 | if ( stat(name, &s) != 0 ) | ||
| 110 | return 0; | ||
| 111 | |||
| 112 | if ( (s.st_mode & S_IFMT) == S_IFBLK ) | ||
| 113 | mountDevice = s.st_rdev; | ||
| 114 | else | ||
| 115 | mountDevice = s.st_dev; | ||
| 116 | |||
| 117 | |||
| 118 | if ( (mountTable = setmntent(table, "r")) == 0 ) | ||
| 119 | return 0; | ||
| 120 | |||
| 121 | while ( (mountEntry = getmntent(mountTable)) != 0 ) { | ||
| 122 | if ( strcmp(name, mountEntry->mnt_dir) == 0 | ||
| 123 | || strcmp(name, mountEntry->mnt_fsname) == 0 ) /* String match. */ | ||
| 124 | break; | ||
| 125 | if ( stat(mountEntry->mnt_fsname, &s) == 0 | ||
| 126 | && s.st_rdev == mountDevice ) /* Match the device. */ | ||
| 127 | break; | ||
| 128 | if ( stat(mountEntry->mnt_dir, &s) == 0 | ||
| 129 | && s.st_dev == mountDevice ) /* Match the directory's mount point. */ | ||
| 130 | break; | ||
| 131 | } | ||
| 132 | endmntent(mountTable); | ||
| 133 | return mountEntry; | ||
| 134 | } | ||
| 135 | |||
| 136 | |||
| @@ -47,43 +47,9 @@ static int fileAction(const char *fileName) | |||
| 47 | char newdestName[NAME_MAX]; | 47 | char newdestName[NAME_MAX]; |
| 48 | strcpy(newdestName, destName); | 48 | strcpy(newdestName, destName); |
| 49 | strcat(newdestName, fileName+(strlen(srcName))); | 49 | strcat(newdestName, fileName+(strlen(srcName))); |
| 50 | fprintf(stderr, "A: copying %s to %s\n", fileName, newdestName); | ||
| 51 | return (copyFile(fileName, newdestName, preserveFlag, followLinks)); | 50 | return (copyFile(fileName, newdestName, preserveFlag, followLinks)); |
| 52 | } | 51 | } |
| 53 | 52 | ||
| 54 | static int dirAction(const char *fileName) | ||
| 55 | { | ||
| 56 | char newdestName[NAME_MAX]; | ||
| 57 | struct stat statBuf; | ||
| 58 | struct utimbuf times; | ||
| 59 | |||
| 60 | strcpy(newdestName, destName); | ||
| 61 | strcat(newdestName, fileName+(strlen(srcName))); | ||
| 62 | if (stat(newdestName, &statBuf)) { | ||
| 63 | if (mkdir( newdestName, 0777777 ^ umask (0))) { | ||
| 64 | perror(newdestName); | ||
| 65 | return( FALSE); | ||
| 66 | } | ||
| 67 | } | ||
| 68 | else if (!S_ISDIR (statBuf.st_mode)) { | ||
| 69 | fprintf(stderr, "`%s' exists but is not a directory", newdestName); | ||
| 70 | return( FALSE); | ||
| 71 | } | ||
| 72 | if (preserveFlag==TRUE) { | ||
| 73 | /* Try to preserve premissions, but don't whine on failure */ | ||
| 74 | if (stat(newdestName, &statBuf)) { | ||
| 75 | perror(newdestName); | ||
| 76 | return( FALSE); | ||
| 77 | } | ||
| 78 | chmod(newdestName, statBuf.st_mode); | ||
| 79 | chown(newdestName, statBuf.st_uid, statBuf.st_gid); | ||
| 80 | times.actime = statBuf.st_atime; | ||
| 81 | times.modtime = statBuf.st_mtime; | ||
| 82 | utime(newdestName, ×); | ||
| 83 | } | ||
| 84 | return TRUE; | ||
| 85 | } | ||
| 86 | |||
| 87 | extern int cp_main(int argc, char **argv) | 53 | extern int cp_main(int argc, char **argv) |
| 88 | { | 54 | { |
| 89 | 55 | ||
diff --git a/descend.c b/descend.c deleted file mode 100644 index 9ada7b4fc..000000000 --- a/descend.c +++ /dev/null | |||
| @@ -1,124 +0,0 @@ | |||
| 1 | #include "internal.h" | ||
| 2 | #include <stdio.h> | ||
| 3 | #include <dirent.h> | ||
| 4 | #include <string.h> | ||
| 5 | #include <errno.h> | ||
| 6 | |||
| 7 | |||
| 8 | static int | ||
| 9 | noDots(const struct dirent * e) | ||
| 10 | { | ||
| 11 | if ( e->d_name[0] == '.' | ||
| 12 | && (e->d_name[1] == '\0' | ||
| 13 | || (e->d_name[1] == '.' && e->d_name[2] == '\0')) ) | ||
| 14 | return 0; | ||
| 15 | else | ||
| 16 | return 1; | ||
| 17 | } | ||
| 18 | |||
| 19 | extern int | ||
| 20 | descend( | ||
| 21 | struct FileInfo *oldInfo | ||
| 22 | ,int (*function)(const struct FileInfo * i)) | ||
| 23 | { | ||
| 24 | char pathname[1024]; | ||
| 25 | struct dirent * * names; | ||
| 26 | struct dirent * * n; | ||
| 27 | int length; | ||
| 28 | char * filename; | ||
| 29 | int status = 0; | ||
| 30 | int count; | ||
| 31 | |||
| 32 | if ( *oldInfo->source == '\0' ) { | ||
| 33 | errno = EINVAL; | ||
| 34 | return -1; | ||
| 35 | } | ||
| 36 | |||
| 37 | if ( oldInfo->stat.st_dev == 0 | ||
| 38 | && oldInfo->stat.st_ino == 0 | ||
| 39 | && oldInfo->stat.st_mode == 0 ) { | ||
| 40 | if ( lstat(oldInfo->source, &oldInfo->stat) != 0 ) | ||
| 41 | return -1; | ||
| 42 | oldInfo->isSymbolicLink = ((oldInfo->stat.st_mode & S_IFMT) == S_IFLNK); | ||
| 43 | |||
| 44 | if ( oldInfo->isSymbolicLink ) | ||
| 45 | if ( stat(oldInfo->source, &oldInfo->stat) != 0 ) | ||
| 46 | memset((void *)&oldInfo->stat, 0, sizeof(oldInfo->stat)); | ||
| 47 | } | ||
| 48 | |||
| 49 | if ( !oldInfo->processDirectoriesAfterTheirContents ) { | ||
| 50 | if ( function ) | ||
| 51 | status = (*function)(oldInfo); | ||
| 52 | if ( status == 0 ) | ||
| 53 | status = post_process(oldInfo); | ||
| 54 | } | ||
| 55 | |||
| 56 | if ( (count = scandir(oldInfo->source, &names, noDots, alphasort)) < 0 ) | ||
| 57 | return -1; | ||
| 58 | |||
| 59 | length = strlen(oldInfo->source); | ||
| 60 | if ( oldInfo->source[length-1] == '/' ) | ||
| 61 | length--; | ||
| 62 | |||
| 63 | memcpy(pathname, oldInfo->source, length+1); | ||
| 64 | pathname[length] = '/'; | ||
| 65 | filename = &pathname[length+1]; | ||
| 66 | |||
| 67 | n = names; | ||
| 68 | while ( count-- > 0 ) { | ||
| 69 | struct FileInfo i = *oldInfo; | ||
| 70 | |||
| 71 | strcpy(filename, (*n)->d_name); | ||
| 72 | free(*n++); | ||
| 73 | |||
| 74 | if ( lstat(pathname, &i.stat) != 0 && errno != ENOENT ) { | ||
| 75 | fprintf(stderr, "Can't stat %s: %s\n", pathname, strerror(errno)); | ||
| 76 | return -1; | ||
| 77 | } | ||
| 78 | i.isSymbolicLink = ((i.stat.st_mode & S_IFMT) == S_IFLNK); | ||
| 79 | |||
| 80 | if ( i.isSymbolicLink ) | ||
| 81 | if ( stat(pathname, &i.stat) != 0 ) | ||
| 82 | memset((void *)&i.stat, 0, sizeof(i.stat)); | ||
| 83 | |||
| 84 | i.source = pathname; | ||
| 85 | |||
| 86 | if ( i.dyadic ) { | ||
| 87 | char d[1024]; | ||
| 88 | |||
| 89 | i.destination = join_paths(d, i.destination, &i.source[i.directoryLength]); | ||
| 90 | } | ||
| 91 | else | ||
| 92 | i.destination = i.source; | ||
| 93 | |||
| 94 | if ( !i.isSymbolicLink && (i.stat.st_mode & S_IFMT) == S_IFDIR ) | ||
| 95 | status = descend(&i, function); | ||
| 96 | else { | ||
| 97 | if ( function ) | ||
| 98 | status = (*function)(&i); | ||
| 99 | if ( status == 0 ) | ||
| 100 | status = post_process(&i); | ||
| 101 | } | ||
| 102 | |||
| 103 | if ( !i.processDirectoriesAfterTheirContents | ||
| 104 | && status == 0 | ||
| 105 | && (i.stat.st_mode & S_IFMT) == S_IFDIR ) | ||
| 106 | descend(&i, function); | ||
| 107 | |||
| 108 | if ( status != 0 && !i.force ) { | ||
| 109 | while ( count-- > 0 ) | ||
| 110 | free(*n++); | ||
| 111 | break; | ||
| 112 | } | ||
| 113 | } | ||
| 114 | free(names); | ||
| 115 | |||
| 116 | if ( oldInfo->processDirectoriesAfterTheirContents ) { | ||
| 117 | if ( function ) | ||
| 118 | status = (*function)(oldInfo); | ||
| 119 | if ( status == 0 ) | ||
| 120 | status = post_process(oldInfo); | ||
| 121 | } | ||
| 122 | |||
| 123 | return status; | ||
| 124 | } | ||
| @@ -43,6 +43,50 @@ df(char* device, const char * mountPoint) | |||
| 43 | return 0; | 43 | return 0; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | /* | ||
| 47 | * Given a block device, find the mount table entry if that block device | ||
| 48 | * is mounted. | ||
| 49 | * | ||
| 50 | * Given any other file (or directory), find the mount table entry for its | ||
| 51 | * filesystem. | ||
| 52 | */ | ||
| 53 | extern struct mntent * | ||
| 54 | findMountPoint(const char* name, const char* table) | ||
| 55 | { | ||
| 56 | struct stat s; | ||
| 57 | dev_t mountDevice; | ||
| 58 | FILE * mountTable; | ||
| 59 | struct mntent * mountEntry; | ||
| 60 | |||
| 61 | if ( stat(name, &s) != 0 ) | ||
| 62 | return 0; | ||
| 63 | |||
| 64 | if ( (s.st_mode & S_IFMT) == S_IFBLK ) | ||
| 65 | mountDevice = s.st_rdev; | ||
| 66 | else | ||
| 67 | mountDevice = s.st_dev; | ||
| 68 | |||
| 69 | |||
| 70 | if ( (mountTable = setmntent(table, "r")) == 0 ) | ||
| 71 | return 0; | ||
| 72 | |||
| 73 | while ( (mountEntry = getmntent(mountTable)) != 0 ) { | ||
| 74 | if ( strcmp(name, mountEntry->mnt_dir) == 0 | ||
| 75 | || strcmp(name, mountEntry->mnt_fsname) == 0 ) /* String match. */ | ||
| 76 | break; | ||
| 77 | if ( stat(mountEntry->mnt_fsname, &s) == 0 | ||
| 78 | && s.st_rdev == mountDevice ) /* Match the device. */ | ||
| 79 | break; | ||
| 80 | if ( stat(mountEntry->mnt_dir, &s) == 0 | ||
| 81 | && s.st_dev == mountDevice ) /* Match the directory's mount point. */ | ||
| 82 | break; | ||
| 83 | } | ||
| 84 | endmntent(mountTable); | ||
| 85 | return mountEntry; | ||
| 86 | } | ||
| 87 | |||
| 88 | |||
| 89 | |||
| 46 | extern int | 90 | extern int |
| 47 | df_main(int argc, char * * argv) | 91 | df_main(int argc, char * * argv) |
| 48 | { | 92 | { |
| @@ -90,47 +134,3 @@ df_main(int argc, char * * argv) | |||
| 90 | 134 | ||
| 91 | 135 | ||
| 92 | 136 | ||
| 93 | |||
| 94 | /* | ||
| 95 | * Given a block device, find the mount table entry if that block device | ||
| 96 | * is mounted. | ||
| 97 | * | ||
| 98 | * Given any other file (or directory), find the mount table entry for its | ||
| 99 | * filesystem. | ||
| 100 | */ | ||
| 101 | extern struct mntent * | ||
| 102 | findMountPoint(const char* name, const char* table) | ||
| 103 | { | ||
| 104 | struct stat s; | ||
| 105 | dev_t mountDevice; | ||
| 106 | FILE * mountTable; | ||
| 107 | struct mntent * mountEntry; | ||
| 108 | |||
| 109 | if ( stat(name, &s) != 0 ) | ||
| 110 | return 0; | ||
| 111 | |||
| 112 | if ( (s.st_mode & S_IFMT) == S_IFBLK ) | ||
| 113 | mountDevice = s.st_rdev; | ||
| 114 | else | ||
| 115 | mountDevice = s.st_dev; | ||
| 116 | |||
| 117 | |||
| 118 | if ( (mountTable = setmntent(table, "r")) == 0 ) | ||
| 119 | return 0; | ||
| 120 | |||
| 121 | while ( (mountEntry = getmntent(mountTable)) != 0 ) { | ||
| 122 | if ( strcmp(name, mountEntry->mnt_dir) == 0 | ||
| 123 | || strcmp(name, mountEntry->mnt_fsname) == 0 ) /* String match. */ | ||
| 124 | break; | ||
| 125 | if ( stat(mountEntry->mnt_fsname, &s) == 0 | ||
| 126 | && s.st_rdev == mountDevice ) /* Match the device. */ | ||
| 127 | break; | ||
| 128 | if ( stat(mountEntry->mnt_dir, &s) == 0 | ||
| 129 | && s.st_dev == mountDevice ) /* Match the directory's mount point. */ | ||
| 130 | break; | ||
| 131 | } | ||
| 132 | endmntent(mountTable); | ||
| 133 | return mountEntry; | ||
| 134 | } | ||
| 135 | |||
| 136 | |||
diff --git a/dyadic.c b/dyadic.c deleted file mode 100644 index 8136bb573..000000000 --- a/dyadic.c +++ /dev/null | |||
| @@ -1,28 +0,0 @@ | |||
| 1 | #include "internal.h" | ||
| 2 | #include <stdio.h> | ||
| 3 | |||
| 4 | extern int | ||
| 5 | dyadic_main( | ||
| 6 | struct FileInfo * i | ||
| 7 | ,int argc | ||
| 8 | ,char * * argv) | ||
| 9 | { | ||
| 10 | int flags; | ||
| 11 | |||
| 12 | i->dyadic = 1; | ||
| 13 | i->destination = argv[argc - 1]; | ||
| 14 | |||
| 15 | for ( flags = 0; flags < (argc - 1) && argv[flags + 1][0] == '-' ; flags++ ) | ||
| 16 | ; | ||
| 17 | if ( argc - flags < 3 ) { | ||
| 18 | usage(i->applet->usage); | ||
| 19 | return 1; | ||
| 20 | } | ||
| 21 | else if ( argc - flags > 3 ) { | ||
| 22 | if ( !is_a_directory(i->destination) ) { | ||
| 23 | fprintf(stderr, "%s: not a directory.\n", i->destination); | ||
| 24 | return 1; | ||
| 25 | } | ||
| 26 | } | ||
| 27 | return monadic_main(i, argc - 1, argv); | ||
| 28 | } | ||
diff --git a/findmount.c b/findmount.c deleted file mode 100644 index 26e28fcd3..000000000 --- a/findmount.c +++ /dev/null | |||
| @@ -1,46 +0,0 @@ | |||
| 1 | #include "internal.h" | ||
| 2 | #include <stdio.h> | ||
| 3 | #include <mntent.h> | ||
| 4 | #include <sys/stat.h> | ||
| 5 | |||
| 6 | /* | ||
| 7 | * Given a block device, find the mount table entry if that block device | ||
| 8 | * is mounted. | ||
| 9 | * | ||
| 10 | * Given any other file (or directory), find the mount table entry for its | ||
| 11 | * filesystem. | ||
| 12 | */ | ||
| 13 | extern struct mntent * | ||
| 14 | findMountPoint(const char * name, const char * table) | ||
| 15 | { | ||
| 16 | struct stat s; | ||
| 17 | dev_t mountDevice; | ||
| 18 | FILE * mountTable; | ||
| 19 | struct mntent * mountEntry; | ||
| 20 | |||
| 21 | if ( stat(name, &s) != 0 ) | ||
| 22 | return 0; | ||
| 23 | |||
| 24 | if ( (s.st_mode & S_IFMT) == S_IFBLK ) | ||
| 25 | mountDevice = s.st_rdev; | ||
| 26 | else | ||
| 27 | mountDevice = s.st_dev; | ||
| 28 | |||
| 29 | |||
| 30 | if ( (mountTable = setmntent(table, "r")) == 0 ) | ||
| 31 | return 0; | ||
| 32 | |||
| 33 | while ( (mountEntry = getmntent(mountTable)) != 0 ) { | ||
| 34 | if ( strcmp(name, mountEntry->mnt_dir) == 0 | ||
| 35 | || strcmp(name, mountEntry->mnt_fsname) == 0 ) /* String match. */ | ||
| 36 | break; | ||
| 37 | if ( stat(mountEntry->mnt_fsname, &s) == 0 | ||
| 38 | && s.st_rdev == mountDevice ) /* Match the device. */ | ||
| 39 | break; | ||
| 40 | if ( stat(mountEntry->mnt_dir, &s) == 0 | ||
| 41 | && s.st_dev == mountDevice ) /* Match the directory's mount point. */ | ||
| 42 | break; | ||
| 43 | } | ||
| 44 | endmntent(mountTable); | ||
| 45 | return mountEntry; | ||
| 46 | } | ||
diff --git a/internal.h b/internal.h index d36d218a9..a67c22339 100644 --- a/internal.h +++ b/internal.h | |||
| @@ -49,49 +49,11 @@ | |||
| 49 | 49 | ||
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | struct FileInfo { | ||
| 53 | unsigned int complainInPostProcess:1; | ||
| 54 | unsigned int changeUserID:1; | ||
| 55 | unsigned int changeGroupID:1; | ||
| 56 | unsigned int changeMode:1; | ||
| 57 | unsigned int create:1; | ||
| 58 | unsigned int force:1; | ||
| 59 | unsigned int recursive:1; | ||
| 60 | unsigned int processDirectoriesAfterTheirContents; | ||
| 61 | unsigned int makeParentDirectories:1; | ||
| 62 | unsigned int didOperation:1; | ||
| 63 | unsigned int isSymbolicLink:1; | ||
| 64 | unsigned int makeSymbolicLink:1; | ||
| 65 | unsigned int dyadic:1; | ||
| 66 | const char* source; | ||
| 67 | const char* destination; | ||
| 68 | int directoryLength; | ||
| 69 | uid_t userID; | ||
| 70 | gid_t groupID; | ||
| 71 | mode_t andWithMode; | ||
| 72 | mode_t orWithMode; | ||
| 73 | struct stat stat; | ||
| 74 | const struct Applet * | ||
| 75 | applet; | ||
| 76 | }; | ||
| 77 | |||
| 78 | struct Applet { | 52 | struct Applet { |
| 79 | const char* name; | 53 | const char* name; |
| 80 | int (*main)(int argc, char** argv); | 54 | int (*main)(int argc, char** argv); |
| 81 | }; | 55 | }; |
| 82 | 56 | ||
| 83 | extern void name_and_error(const char*); | ||
| 84 | extern int is_a_directory(const char*); | ||
| 85 | extern char* join_paths(char *, const char *, const char *); | ||
| 86 | |||
| 87 | extern int descend( | ||
| 88 | struct FileInfo *o | ||
| 89 | ,int (*function)(const struct FileInfo * i)); | ||
| 90 | |||
| 91 | extern struct mntent * | ||
| 92 | findMountPoint(const char*, const char *); | ||
| 93 | |||
| 94 | extern void usage(const char*); | ||
| 95 | extern int busybox_main(int argc, char** argv); | 57 | extern int busybox_main(int argc, char** argv); |
| 96 | extern int block_device_main(int argc, char** argv); | 58 | extern int block_device_main(int argc, char** argv); |
| 97 | extern int cat_more_main(int argc, char** argv); | 59 | extern int cat_more_main(int argc, char** argv); |
| @@ -146,29 +108,6 @@ extern int update_main(int argc, char** argv); | |||
| 146 | extern int zcat_main(int argc, char** argv); | 108 | extern int zcat_main(int argc, char** argv); |
| 147 | extern int gzip_main(int argc, char** argv); | 109 | extern int gzip_main(int argc, char** argv); |
| 148 | 110 | ||
| 149 | extern int | ||
| 150 | parse_mode( | ||
| 151 | const char* s | ||
| 152 | ,mode_t * or | ||
| 153 | ,mode_t * and | ||
| 154 | ,int * group_execute); | ||
| 155 | |||
| 156 | extern int parse_user_name(const char* string, struct FileInfo * i); | ||
| 157 | |||
| 158 | |||
| 159 | /* | ||
| 160 | * A chunk of data. | ||
| 161 | * Chunks contain data which is allocated as needed, but which is | ||
| 162 | * not freed until all of the data needs freeing, such as at | ||
| 163 | * the beginning of the next command. | ||
| 164 | */ | ||
| 165 | typedef struct chunk CHUNK; | ||
| 166 | #define CHUNK_INIT_SIZE 4 | ||
| 167 | |||
| 168 | struct chunk { | ||
| 169 | CHUNK *next; | ||
| 170 | char data[CHUNK_INIT_SIZE]; /* actually of varying length */ | ||
| 171 | }; | ||
| 172 | 111 | ||
| 173 | const char *modeString(int mode); | 112 | const char *modeString(int mode); |
| 174 | const char *timeString(time_t timeVal); | 113 | const char *timeString(time_t timeVal); |
diff --git a/monadic.c b/monadic.c deleted file mode 100644 index 3c7fac25b..000000000 --- a/monadic.c +++ /dev/null | |||
| @@ -1,126 +0,0 @@ | |||
| 1 | #include "internal.h" | ||
| 2 | #include <stdio.h> | ||
| 3 | #include <string.h> | ||
| 4 | #include <grp.h> | ||
| 5 | |||
| 6 | extern int | ||
| 7 | monadic_main( | ||
| 8 | struct FileInfo * i | ||
| 9 | ,int argc | ||
| 10 | ,char * * argv) | ||
| 11 | { | ||
| 12 | int status = 0; | ||
| 13 | |||
| 14 | while ( argc > 1 && argv[1][0] == '-' ) { | ||
| 15 | switch ( argv[1][1] ) { | ||
| 16 | case 'c': | ||
| 17 | i->create = 1; | ||
| 18 | break; | ||
| 19 | case 'f': | ||
| 20 | i->force = 1; | ||
| 21 | break; | ||
| 22 | case 'g': | ||
| 23 | if ( argc > 2 ) { | ||
| 24 | struct group * g; | ||
| 25 | if ( (g = getgrnam(argv[2])) == 0 ) { | ||
| 26 | fprintf(stderr, "%s: no such group.\n", argv[1]); | ||
| 27 | return 1; | ||
| 28 | } | ||
| 29 | i->groupID = g->gr_gid; | ||
| 30 | i->changeGroupID = 1; | ||
| 31 | i->complainInPostProcess = 1; | ||
| 32 | argc--; | ||
| 33 | argv++; | ||
| 34 | break; | ||
| 35 | } | ||
| 36 | usage(i->applet->usage); | ||
| 37 | return 1; | ||
| 38 | case 'm': | ||
| 39 | if ( argc > 2 ) { | ||
| 40 | status = parse_mode( | ||
| 41 | argv[2] | ||
| 42 | ,&i->orWithMode | ||
| 43 | ,&i->andWithMode, 0); | ||
| 44 | |||
| 45 | if ( status == 0 ) { | ||
| 46 | i->changeMode = 1; | ||
| 47 | i->complainInPostProcess = 1; | ||
| 48 | argc--; | ||
| 49 | argv++; | ||
| 50 | break; | ||
| 51 | } | ||
| 52 | } | ||
| 53 | usage(i->applet->usage); | ||
| 54 | return 1; | ||
| 55 | case 'o': | ||
| 56 | if ( argc > 2 ) { | ||
| 57 | status = parse_user_name(argv[2], i); | ||
| 58 | if ( status != 0 ) | ||
| 59 | return status; | ||
| 60 | |||
| 61 | i->changeUserID = 1; | ||
| 62 | i->complainInPostProcess = 1; | ||
| 63 | argc--; | ||
| 64 | argv++; | ||
| 65 | break; | ||
| 66 | } | ||
| 67 | usage(i->applet->usage); | ||
| 68 | return 1; | ||
| 69 | case 'p': | ||
| 70 | i->makeParentDirectories = 1; | ||
| 71 | break; | ||
| 72 | case 'r': | ||
| 73 | case 'R': | ||
| 74 | i->recursive = 1; | ||
| 75 | break; | ||
| 76 | case 's': | ||
| 77 | i->makeSymbolicLink = 1; | ||
| 78 | break; | ||
| 79 | default: | ||
| 80 | usage(i->applet->usage); | ||
| 81 | return 1; | ||
| 82 | } | ||
| 83 | argv++; | ||
| 84 | argc--; | ||
| 85 | } | ||
| 86 | while ( argc > 1 ) { | ||
| 87 | char * slash; | ||
| 88 | i->source = argv[1]; | ||
| 89 | if ( (slash = strrchr(i->source, '/')) != 0 ) { | ||
| 90 | i->directoryLength = slash - i->source; | ||
| 91 | if ( i->source[i->directoryLength] == '\0' ) | ||
| 92 | i->directoryLength = 0; | ||
| 93 | } | ||
| 94 | else | ||
| 95 | i->directoryLength = 0; | ||
| 96 | if ( !i->dyadic ) | ||
| 97 | i->destination = i->source; | ||
| 98 | |||
| 99 | if ( lstat(i->source, &i->stat) == 0 ) { | ||
| 100 | i->isSymbolicLink = (i->stat.st_mode & S_IFMT)==S_IFLNK; | ||
| 101 | if ( i->isSymbolicLink ) | ||
| 102 | if ( stat(i->source, &i->stat) != 0 ) | ||
| 103 | memset(&i->stat, 0, sizeof(i->stat)); | ||
| 104 | } | ||
| 105 | else | ||
| 106 | memset(&i->stat, 0, sizeof(i->stat)); | ||
| 107 | |||
| 108 | if ( i->isSymbolicLink | ||
| 109 | || !i->recursive | ||
| 110 | || ((i->stat.st_mode & S_IFMT) != S_IFDIR) ) { | ||
| 111 | |||
| 112 | if ( i->applet->function ) | ||
| 113 | status = i->applet->function(i); | ||
| 114 | if ( status == 0 ) | ||
| 115 | status = post_process(i); | ||
| 116 | } | ||
| 117 | else | ||
| 118 | status = descend(i, i->applet->function); | ||
| 119 | |||
| 120 | if ( status != 0 && !i->force ) | ||
| 121 | return status; | ||
| 122 | argv++; | ||
| 123 | argc--; | ||
| 124 | } | ||
| 125 | return 0; | ||
| 126 | } | ||
diff --git a/postprocess.c b/postprocess.c deleted file mode 100644 index bbc87e689..000000000 --- a/postprocess.c +++ /dev/null | |||
| @@ -1,41 +0,0 @@ | |||
| 1 | #include "internal.h" | ||
| 2 | |||
| 3 | extern int | ||
| 4 | post_process(const struct FileInfo * i) | ||
| 5 | { | ||
| 6 | int status = 0; | ||
| 7 | |||
| 8 | if ( i->destination == 0 || *i->destination == 0 ) | ||
| 9 | return 0; | ||
| 10 | |||
| 11 | if ( status == 0 && i->changeMode ) { | ||
| 12 | mode_t mode = i->stat.st_mode & 07777; | ||
| 13 | mode &= i->andWithMode; | ||
| 14 | mode |= i->orWithMode; | ||
| 15 | status = chmod(i->destination, mode); | ||
| 16 | |||
| 17 | if ( status != 0 && i->complainInPostProcess && !i->force ) { | ||
| 18 | name_and_error(i->destination); | ||
| 19 | return 1; | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | if ( i->changeUserID || i->changeGroupID ) { | ||
| 24 | uid_t uid = i->stat.st_uid; | ||
| 25 | gid_t gid = i->stat.st_gid; | ||
| 26 | |||
| 27 | if ( i->changeUserID ) | ||
| 28 | uid = i->userID; | ||
| 29 | if ( i->changeGroupID ) | ||
| 30 | gid = i->groupID; | ||
| 31 | |||
| 32 | status = chown(i->destination, uid, gid); | ||
| 33 | |||
| 34 | if ( status != 0 && i->complainInPostProcess && !i->force ) { | ||
| 35 | name_and_error(i->destination); | ||
| 36 | return 1; | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | return status; | ||
| 41 | } | ||
| @@ -33,102 +33,9 @@ | |||
| 33 | #include <sys/stat.h> | 33 | #include <sys/stat.h> |
| 34 | #include <unistd.h> | 34 | #include <unistd.h> |
| 35 | 35 | ||
| 36 | #if 0 | ||
| 37 | |||
| 38 | extern char *join_paths(char *buffer, const char *a, const char *b) | ||
| 39 | { | ||
| 40 | int length = 0; | ||
| 41 | |||
| 42 | if (a && *a) { | ||
| 43 | length = strlen(a); | ||
| 44 | memcpy(buffer, a, length); | ||
| 45 | } | ||
| 46 | if (b && *b) { | ||
| 47 | if (length > 0 && buffer[length - 1] != '/') | ||
| 48 | buffer[length++] = '/'; | ||
| 49 | if (*b == '/') | ||
| 50 | b++; | ||
| 51 | strcpy(&buffer[length], b); | ||
| 52 | } | ||
| 53 | return buffer; | ||
| 54 | } | ||
| 55 | |||
| 56 | #endif | ||
| 57 | |||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | |||
| 63 | static CHUNK *chunkList; | ||
| 64 | |||
| 65 | |||
| 66 | /* | ||
| 67 | * Return the standard ls-like mode string from a file mode. | ||
| 68 | * This is static and so is overwritten on each call. | ||
| 69 | */ | ||
| 70 | const char *modeString(int mode) | ||
| 71 | { | ||
| 72 | static char buf[12]; | ||
| 73 | |||
| 74 | strcpy(buf, "----------"); | ||
| 75 | |||
| 76 | /* | ||
| 77 | * Fill in the file type. | ||
| 78 | */ | ||
| 79 | if (S_ISDIR(mode)) | ||
| 80 | buf[0] = 'd'; | ||
| 81 | if (S_ISCHR(mode)) | ||
| 82 | buf[0] = 'c'; | ||
| 83 | if (S_ISBLK(mode)) | ||
| 84 | buf[0] = 'b'; | ||
| 85 | if (S_ISFIFO(mode)) | ||
| 86 | buf[0] = 'p'; | ||
| 87 | #ifdef S_ISLNK | ||
| 88 | if (S_ISLNK(mode)) | ||
| 89 | buf[0] = 'l'; | ||
| 90 | #endif | ||
| 91 | #ifdef S_ISSOCK | ||
| 92 | if (S_ISSOCK(mode)) | ||
| 93 | buf[0] = 's'; | ||
| 94 | #endif | ||
| 95 | |||
| 96 | /* | ||
| 97 | * Now fill in the normal file permissions. | ||
| 98 | */ | ||
| 99 | if (mode & S_IRUSR) | ||
| 100 | buf[1] = 'r'; | ||
| 101 | if (mode & S_IWUSR) | ||
| 102 | buf[2] = 'w'; | ||
| 103 | if (mode & S_IXUSR) | ||
| 104 | buf[3] = 'x'; | ||
| 105 | if (mode & S_IRGRP) | ||
| 106 | buf[4] = 'r'; | ||
| 107 | if (mode & S_IWGRP) | ||
| 108 | buf[5] = 'w'; | ||
| 109 | if (mode & S_IXGRP) | ||
| 110 | buf[6] = 'x'; | ||
| 111 | if (mode & S_IROTH) | ||
| 112 | buf[7] = 'r'; | ||
| 113 | if (mode & S_IWOTH) | ||
| 114 | buf[8] = 'w'; | ||
| 115 | if (mode & S_IXOTH) | ||
| 116 | buf[9] = 'x'; | ||
| 117 | |||
| 118 | /* | ||
| 119 | * Finally fill in magic stuff like suid and sticky text. | ||
| 120 | */ | ||
| 121 | if (mode & S_ISUID) | ||
| 122 | buf[3] = ((mode & S_IXUSR) ? 's' : 'S'); | ||
| 123 | if (mode & S_ISGID) | ||
| 124 | buf[6] = ((mode & S_IXGRP) ? 's' : 'S'); | ||
| 125 | if (mode & S_ISVTX) | ||
| 126 | buf[9] = ((mode & S_IXOTH) ? 't' : 'T'); | ||
| 127 | |||
| 128 | return buf; | ||
| 129 | } | ||
| 130 | 36 | ||
| 131 | 37 | ||
| 38 | #if defined (BB_CP) || defined (BB_MV) | ||
| 132 | /* | 39 | /* |
| 133 | * Return TRUE if a fileName is a directory. | 40 | * Return TRUE if a fileName is a directory. |
| 134 | * Nonexistant files return FALSE. | 41 | * Nonexistant files return FALSE. |
| @@ -145,21 +52,6 @@ int isDirectory(const char *name) | |||
| 145 | 52 | ||
| 146 | 53 | ||
| 147 | /* | 54 | /* |
| 148 | * Return TRUE if a filename is a block or character device. | ||
| 149 | * Nonexistant files return FALSE. | ||
| 150 | */ | ||
| 151 | int isDevice(const char *name) | ||
| 152 | { | ||
| 153 | struct stat statBuf; | ||
| 154 | |||
| 155 | if (stat(name, &statBuf) < 0) | ||
| 156 | return FALSE; | ||
| 157 | |||
| 158 | return S_ISBLK(statBuf.st_mode) || S_ISCHR(statBuf.st_mode); | ||
| 159 | } | ||
| 160 | |||
| 161 | |||
| 162 | /* | ||
| 163 | * Copy one file to another, while possibly preserving its modes, times, | 55 | * Copy one file to another, while possibly preserving its modes, times, |
| 164 | * and modes. Returns TRUE if successful, or FALSE on a failure with an | 56 | * and modes. Returns TRUE if successful, or FALSE on a failure with an |
| 165 | * error message output. (Failure is not indicted if the attributes cannot | 57 | * error message output. (Failure is not indicted if the attributes cannot |
| @@ -173,47 +65,49 @@ copyFile( | |||
| 173 | int rfd; | 65 | int rfd; |
| 174 | int wfd; | 66 | int wfd; |
| 175 | int rcc; | 67 | int rcc; |
| 68 | int result; | ||
| 176 | char buf[BUF_SIZE]; | 69 | char buf[BUF_SIZE]; |
| 177 | struct stat statBuf1; | 70 | struct stat srcStatBuf; |
| 178 | struct stat statBuf2; | 71 | struct stat dstStatBuf; |
| 179 | struct utimbuf times; | 72 | struct utimbuf times; |
| 180 | 73 | ||
| 181 | if (stat(srcName, &statBuf1) < 0) { | 74 | if (followLinks == FALSE) |
| 75 | result = stat(srcName, &srcStatBuf); | ||
| 76 | else | ||
| 77 | result = lstat(srcName, &srcStatBuf); | ||
| 78 | |||
| 79 | if (result < 0) { | ||
| 182 | perror(srcName); | 80 | perror(srcName); |
| 183 | return FALSE; | 81 | return FALSE; |
| 184 | } | 82 | } |
| 185 | 83 | ||
| 186 | if (stat(destName, &statBuf2) < 0) { | 84 | if (followLinks == FALSE) |
| 187 | statBuf2.st_ino = -1; | 85 | result = stat(destName, &dstStatBuf); |
| 188 | statBuf2.st_dev = -1; | 86 | else |
| 87 | result = lstat(destName, &dstStatBuf); | ||
| 88 | if (result < 0) { | ||
| 89 | dstStatBuf.st_ino = -1; | ||
| 90 | dstStatBuf.st_dev = -1; | ||
| 189 | } | 91 | } |
| 190 | 92 | ||
| 191 | if ((statBuf1.st_dev == statBuf2.st_dev) && | 93 | if ((srcStatBuf.st_dev == dstStatBuf.st_dev) && |
| 192 | (statBuf1.st_ino == statBuf2.st_ino)) { | 94 | (srcStatBuf.st_ino == dstStatBuf.st_ino)) { |
| 193 | fprintf(stderr, "Copying file \"%s\" to itself\n", srcName); | 95 | fprintf(stderr, "Copying file \"%s\" to itself\n", srcName); |
| 194 | return FALSE; | 96 | return FALSE; |
| 195 | } | 97 | } |
| 196 | 98 | ||
| 197 | if (S_ISDIR(statBuf1.st_mode)) { | 99 | if (S_ISDIR(srcStatBuf.st_mode)) { |
| 100 | //fprintf(stderr, "copying directory %s to %s\n", srcName, destName); | ||
| 198 | /* Make sure the directory is writable */ | 101 | /* Make sure the directory is writable */ |
| 199 | if (mkdir(destName, 0777777 ^ umask(0))) { | 102 | if (mkdir(destName, 0777777 ^ umask(0))) { |
| 200 | perror(destName); | 103 | perror(destName); |
| 201 | return (FALSE); | 104 | return (FALSE); |
| 202 | } | 105 | } |
| 203 | } else if (S_ISFIFO(statBuf1.st_mode)) { | 106 | } else if (S_ISLNK(srcStatBuf.st_mode)) { |
| 204 | if (mkfifo(destName, 644)) { | ||
| 205 | perror(destName); | ||
| 206 | return (FALSE); | ||
| 207 | } | ||
| 208 | } else if (S_ISBLK(statBuf1.st_mode) || S_ISCHR(statBuf1.st_mode)) { | ||
| 209 | if (mknod(destName, 644, statBuf1.st_rdev)) { | ||
| 210 | perror(destName); | ||
| 211 | return (FALSE); | ||
| 212 | } | ||
| 213 | } else if (S_ISLNK(statBuf1.st_mode)) { | ||
| 214 | char *link_val; | 107 | char *link_val; |
| 215 | int link_size; | 108 | int link_size; |
| 216 | 109 | ||
| 110 | //fprintf(stderr, "copying link %s to %s\n", srcName, destName); | ||
| 217 | link_val = (char *) alloca(PATH_MAX + 2); | 111 | link_val = (char *) alloca(PATH_MAX + 2); |
| 218 | link_size = readlink(srcName, link_val, PATH_MAX + 1); | 112 | link_size = readlink(srcName, link_val, PATH_MAX + 1); |
| 219 | if (link_size < 0) { | 113 | if (link_size < 0) { |
| @@ -222,17 +116,31 @@ copyFile( | |||
| 222 | } | 116 | } |
| 223 | link_val[link_size] = '\0'; | 117 | link_val[link_size] = '\0'; |
| 224 | if (symlink(link_val, destName)) { | 118 | if (symlink(link_val, destName)) { |
| 225 | perror(srcName); | 119 | perror(destName); |
| 226 | return (FALSE); | 120 | return (FALSE); |
| 227 | } | 121 | } |
| 228 | } else { | 122 | } else if (S_ISFIFO(srcStatBuf.st_mode)) { |
| 123 | //fprintf(stderr, "copying fifo %s to %s\n", srcName, destName); | ||
| 124 | if (mkfifo(destName, 644)) { | ||
| 125 | perror(destName); | ||
| 126 | return (FALSE); | ||
| 127 | } | ||
| 128 | } else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode) | ||
| 129 | || S_ISSOCK (srcStatBuf.st_mode)) { | ||
| 130 | //fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName); | ||
| 131 | if (mknod(destName, srcStatBuf.st_mode, srcStatBuf.st_rdev)) { | ||
| 132 | perror(destName); | ||
| 133 | return (FALSE); | ||
| 134 | } | ||
| 135 | } else if (S_ISREG(srcStatBuf.st_mode)) { | ||
| 136 | //fprintf(stderr, "copying regular file %s to %s\n", srcName, destName); | ||
| 229 | rfd = open(srcName, O_RDONLY); | 137 | rfd = open(srcName, O_RDONLY); |
| 230 | if (rfd < 0) { | 138 | if (rfd < 0) { |
| 231 | perror(srcName); | 139 | perror(srcName); |
| 232 | return FALSE; | 140 | return FALSE; |
| 233 | } | 141 | } |
| 234 | 142 | ||
| 235 | wfd = creat(destName, statBuf1.st_mode); | 143 | wfd = creat(destName, srcStatBuf.st_mode); |
| 236 | if (wfd < 0) { | 144 | if (wfd < 0) { |
| 237 | perror(destName); | 145 | perror(destName); |
| 238 | close(rfd); | 146 | close(rfd); |
| @@ -244,27 +152,25 @@ copyFile( | |||
| 244 | goto error_exit; | 152 | goto error_exit; |
| 245 | } | 153 | } |
| 246 | if (rcc < 0) { | 154 | if (rcc < 0) { |
| 247 | perror(srcName); | ||
| 248 | goto error_exit; | 155 | goto error_exit; |
| 249 | } | 156 | } |
| 250 | 157 | ||
| 251 | close(rfd); | 158 | close(rfd); |
| 252 | |||
| 253 | if (close(wfd) < 0) { | 159 | if (close(wfd) < 0) { |
| 254 | perror(destName); | ||
| 255 | return FALSE; | 160 | return FALSE; |
| 256 | } | 161 | } |
| 257 | } | 162 | } |
| 258 | 163 | ||
| 259 | if (setModes == TRUE) { | 164 | if (setModes == TRUE) { |
| 260 | chmod(destName, statBuf1.st_mode); | 165 | //fprintf(stderr, "Setting permissions for %s\n", destName); |
| 166 | chmod(destName, srcStatBuf.st_mode); | ||
| 261 | if (followLinks == TRUE) | 167 | if (followLinks == TRUE) |
| 262 | chown(destName, statBuf1.st_uid, statBuf1.st_gid); | 168 | chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid); |
| 263 | else | 169 | else |
| 264 | lchown(destName, statBuf1.st_uid, statBuf1.st_gid); | 170 | lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid); |
| 265 | 171 | ||
| 266 | times.actime = statBuf1.st_atime; | 172 | times.actime = srcStatBuf.st_atime; |
| 267 | times.modtime = statBuf1.st_mtime; | 173 | times.modtime = srcStatBuf.st_mtime; |
| 268 | 174 | ||
| 269 | utime(destName, ×); | 175 | utime(destName, ×); |
| 270 | } | 176 | } |
| @@ -273,13 +179,17 @@ copyFile( | |||
| 273 | 179 | ||
| 274 | 180 | ||
| 275 | error_exit: | 181 | error_exit: |
| 182 | //fprintf(stderr, "choking on %s\n", destName); | ||
| 183 | perror(destName); | ||
| 276 | close(rfd); | 184 | close(rfd); |
| 277 | close(wfd); | 185 | close(wfd); |
| 278 | 186 | ||
| 279 | return FALSE; | 187 | return FALSE; |
| 280 | } | 188 | } |
| 189 | #endif | ||
| 281 | 190 | ||
| 282 | 191 | ||
| 192 | #ifdef BB_MV | ||
| 283 | /* | 193 | /* |
| 284 | * Build a path name from the specified directory name and file name. | 194 | * Build a path name from the specified directory name and file name. |
| 285 | * If the directory name is NULL, then the original fileName is returned. | 195 | * If the directory name is NULL, then the original fileName is returned. |
| @@ -305,106 +215,77 @@ char *buildName(const char *dirName, const char *fileName) | |||
| 305 | 215 | ||
| 306 | return buf; | 216 | return buf; |
| 307 | } | 217 | } |
| 218 | #endif | ||
| 308 | 219 | ||
| 309 | 220 | ||
| 310 | 221 | ||
| 311 | /* | 222 | /* |
| 312 | * Make a NULL-terminated string out of an argc, argv pair. | 223 | * Return the standard ls-like mode string from a file mode. |
| 313 | * Returns TRUE if successful, or FALSE if the string is too long, | 224 | * This is static and so is overwritten on each call. |
| 314 | * with an error message given. This does not handle spaces within | ||
| 315 | * arguments correctly. | ||
| 316 | */ | ||
| 317 | int makeString( int argc, const char **argv, char *buf, int bufLen) | ||
| 318 | { | ||
| 319 | int len; | ||
| 320 | |||
| 321 | while (argc-- > 0) { | ||
| 322 | len = strlen(*argv); | ||
| 323 | |||
| 324 | if (len >= bufLen) { | ||
| 325 | fprintf(stderr, "Argument string too long\n"); | ||
| 326 | |||
| 327 | return FALSE; | ||
| 328 | } | ||
| 329 | |||
| 330 | strcpy(buf, *argv++); | ||
| 331 | |||
| 332 | buf += len; | ||
| 333 | bufLen -= len; | ||
| 334 | |||
| 335 | if (argc) | ||
| 336 | *buf++ = ' '; | ||
| 337 | |||
| 338 | bufLen--; | ||
| 339 | } | ||
| 340 | |||
| 341 | *buf = '\0'; | ||
| 342 | |||
| 343 | return TRUE; | ||
| 344 | } | ||
| 345 | |||
| 346 | |||
| 347 | /* | ||
| 348 | * Allocate a chunk of memory (like malloc). | ||
| 349 | * The difference, though, is that the memory allocated is put on a | ||
| 350 | * list of chunks which can be freed all at one time. You CAN NOT free | ||
| 351 | * an individual chunk. | ||
| 352 | */ | ||
| 353 | char *getChunk(int size) | ||
| 354 | { | ||
| 355 | CHUNK *chunk; | ||
| 356 | |||
| 357 | if (size < CHUNK_INIT_SIZE) | ||
| 358 | size = CHUNK_INIT_SIZE; | ||
| 359 | |||
| 360 | chunk = (CHUNK *) malloc(size + sizeof(CHUNK) - CHUNK_INIT_SIZE); | ||
| 361 | |||
| 362 | if (chunk == NULL) | ||
| 363 | return NULL; | ||
| 364 | |||
| 365 | chunk->next = chunkList; | ||
| 366 | chunkList = chunk; | ||
| 367 | |||
| 368 | return chunk->data; | ||
| 369 | } | ||
| 370 | |||
| 371 | |||
| 372 | /* | ||
| 373 | * Duplicate a string value using the chunk allocator. | ||
| 374 | * The returned string cannot be individually freed, but can only be freed | ||
| 375 | * with other strings when freeChunks is called. Returns NULL on failure. | ||
| 376 | */ | 225 | */ |
| 377 | char *chunkstrdup(const char *str) | 226 | const char *modeString(int mode) |
| 378 | { | 227 | { |
| 379 | int len; | 228 | static char buf[12]; |
| 380 | char *newStr; | ||
| 381 | |||
| 382 | len = strlen(str) + 1; | ||
| 383 | newStr = getChunk(len); | ||
| 384 | 229 | ||
| 385 | if (newStr) | 230 | strcpy(buf, "----------"); |
| 386 | memcpy(newStr, str, len); | ||
| 387 | 231 | ||
| 388 | return newStr; | 232 | /* |
| 389 | } | 233 | * Fill in the file type. |
| 234 | */ | ||
| 235 | if (S_ISDIR(mode)) | ||
| 236 | buf[0] = 'd'; | ||
| 237 | if (S_ISCHR(mode)) | ||
| 238 | buf[0] = 'c'; | ||
| 239 | if (S_ISBLK(mode)) | ||
| 240 | buf[0] = 'b'; | ||
| 241 | if (S_ISFIFO(mode)) | ||
| 242 | buf[0] = 'p'; | ||
| 243 | #ifdef S_ISLNK | ||
| 244 | if (S_ISLNK(mode)) | ||
| 245 | buf[0] = 'l'; | ||
| 246 | #endif | ||
| 247 | #ifdef S_ISSOCK | ||
| 248 | if (S_ISSOCK(mode)) | ||
| 249 | buf[0] = 's'; | ||
| 250 | #endif | ||
| 390 | 251 | ||
| 252 | /* | ||
| 253 | * Now fill in the normal file permissions. | ||
| 254 | */ | ||
| 255 | if (mode & S_IRUSR) | ||
| 256 | buf[1] = 'r'; | ||
| 257 | if (mode & S_IWUSR) | ||
| 258 | buf[2] = 'w'; | ||
| 259 | if (mode & S_IXUSR) | ||
| 260 | buf[3] = 'x'; | ||
| 261 | if (mode & S_IRGRP) | ||
| 262 | buf[4] = 'r'; | ||
| 263 | if (mode & S_IWGRP) | ||
| 264 | buf[5] = 'w'; | ||
| 265 | if (mode & S_IXGRP) | ||
| 266 | buf[6] = 'x'; | ||
| 267 | if (mode & S_IROTH) | ||
| 268 | buf[7] = 'r'; | ||
| 269 | if (mode & S_IWOTH) | ||
| 270 | buf[8] = 'w'; | ||
| 271 | if (mode & S_IXOTH) | ||
| 272 | buf[9] = 'x'; | ||
| 391 | 273 | ||
| 392 | /* | 274 | /* |
| 393 | * Free all chunks of memory that had been allocated since the last | 275 | * Finally fill in magic stuff like suid and sticky text. |
| 394 | * call to this routine. | 276 | */ |
| 395 | */ | 277 | if (mode & S_ISUID) |
| 396 | void freeChunks(void) | 278 | buf[3] = ((mode & S_IXUSR) ? 's' : 'S'); |
| 397 | { | 279 | if (mode & S_ISGID) |
| 398 | CHUNK *chunk; | 280 | buf[6] = ((mode & S_IXGRP) ? 's' : 'S'); |
| 281 | if (mode & S_ISVTX) | ||
| 282 | buf[9] = ((mode & S_IXOTH) ? 't' : 'T'); | ||
| 399 | 283 | ||
| 400 | while (chunkList) { | 284 | return buf; |
| 401 | chunk = chunkList; | ||
| 402 | chunkList = chunk->next; | ||
| 403 | free((char *) chunk); | ||
| 404 | } | ||
| 405 | } | 285 | } |
| 406 | 286 | ||
| 407 | 287 | ||
| 288 | #ifdef BB_TAR | ||
| 408 | /* | 289 | /* |
| 409 | * Get the time string to be used for a file. | 290 | * Get the time string to be used for a file. |
| 410 | * This is down to the minute for new files, but only the date for old files. | 291 | * 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) | |||
| 577 | 458 | ||
| 578 | return total; | 459 | return total; |
| 579 | } | 460 | } |
| 461 | #endif | ||
| 580 | 462 | ||
| 581 | 463 | ||
| 464 | #if defined (BB_CHOWN) || defined (BB_CP) || defined (BB_FIND) || defined (BB_LS) | ||
| 582 | /* | 465 | /* |
| 583 | * Walk down all the directories under the specified | 466 | * Walk down all the directories under the specified |
| 584 | * location, and do something (something specified | 467 | * location, and do something (something specified |
| @@ -618,7 +501,6 @@ recursiveAction(const char *fileName, int recurse, int followLinks, | |||
| 618 | 501 | ||
| 619 | if (S_ISDIR(statbuf.st_mode)) { | 502 | if (S_ISDIR(statbuf.st_mode)) { |
| 620 | DIR *dir; | 503 | DIR *dir; |
| 621 | fprintf(stderr, "Dir: %s\n", fileName); | ||
| 622 | dir = opendir(fileName); | 504 | dir = opendir(fileName); |
| 623 | if (!dir) { | 505 | if (!dir) { |
| 624 | perror(fileName); | 506 | perror(fileName); |
| @@ -627,7 +509,7 @@ recursiveAction(const char *fileName, int recurse, int followLinks, | |||
| 627 | if (dirAction != NULL) { | 509 | if (dirAction != NULL) { |
| 628 | status = dirAction(fileName); | 510 | status = dirAction(fileName); |
| 629 | if (status == FALSE) { | 511 | if (status == FALSE) { |
| 630 | perror("cp"); | 512 | perror(fileName); |
| 631 | return (FALSE); | 513 | return (FALSE); |
| 632 | } | 514 | } |
| 633 | } | 515 | } |
| @@ -652,7 +534,6 @@ recursiveAction(const char *fileName, int recurse, int followLinks, | |||
| 652 | return (FALSE); | 534 | return (FALSE); |
| 653 | } | 535 | } |
| 654 | } else { | 536 | } else { |
| 655 | fprintf(stderr, "File: %s\n", fileName); | ||
| 656 | if (fileAction == NULL) | 537 | if (fileAction == NULL) |
| 657 | return (TRUE); | 538 | return (TRUE); |
| 658 | else | 539 | else |
| @@ -661,6 +542,6 @@ recursiveAction(const char *fileName, int recurse, int followLinks, | |||
| 661 | return (TRUE); | 542 | return (TRUE); |
| 662 | } | 543 | } |
| 663 | 544 | ||
| 664 | 545 | #endif | |
| 665 | 546 | ||
| 666 | /* END CODE */ | 547 | /* END CODE */ |
