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 */ |