summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>1999-10-09 00:25:00 +0000
committerEric Andersen <andersen@codepoet.org>1999-10-09 00:25:00 +0000
commitf811e07b072600a3784a92e5a1dc8a93dac477eb (patch)
tree820c6366f8bdacf617a9591cc2ca9dfe107b1fa3
parent8341a1565306a54e685455d19efb0516ad3328a1 (diff)
downloadbusybox-w32-f811e07b072600a3784a92e5a1dc8a93dac477eb.tar.gz
busybox-w32-f811e07b072600a3784a92e5a1dc8a93dac477eb.tar.bz2
busybox-w32-f811e07b072600a3784a92e5a1dc8a93dac477eb.zip
More stuff.
-rw-r--r--applets/busybox.c2
-rw-r--r--archival/tar.c44
-rw-r--r--busybox.c2
-rw-r--r--busybox.def.h4
-rw-r--r--coreutils/cp.c206
-rw-r--r--coreutils/mv.c6
-rw-r--r--cp.c206
-rw-r--r--find.c2
-rw-r--r--findutils/find.c2
-rw-r--r--findutils/grep.c10
-rw-r--r--grep.c10
-rw-r--r--internal.h21
-rw-r--r--mv.c6
-rw-r--r--tar.c44
-rw-r--r--umount.c196
-rw-r--r--util-linux/umount.c196
-rw-r--r--utility.c795
17 files changed, 881 insertions, 871 deletions
diff --git a/applets/busybox.c b/applets/busybox.c
index 15e1bef87..cdbefbe94 100644
--- a/applets/busybox.c
+++ b/applets/busybox.c
@@ -30,7 +30,7 @@ static const struct Applet applets[] = {
30 {"clear", clear_main}, 30 {"clear", clear_main},
31#endif 31#endif
32#ifdef BB_CP //bin 32#ifdef BB_CP //bin
33 {"cp", dyadic_main}, 33 {"cp", cp_main},
34#endif 34#endif
35#ifdef BB_DATE //bin 35#ifdef BB_DATE //bin
36 {"date", date_main}, 36 {"date", date_main},
diff --git a/archival/tar.c b/archival/tar.c
index 498d4a300..1a9f84217 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -73,18 +73,18 @@ typedef struct
73/* 73/*
74 * Static data. 74 * Static data.
75 */ 75 */
76static BOOL listFlag; 76static int listFlag;
77static BOOL extractFlag; 77static int extractFlag;
78static BOOL createFlag; 78static int createFlag;
79static BOOL verboseFlag; 79static int verboseFlag;
80static BOOL tostdoutFlag; 80static int tostdoutFlag;
81 81
82static BOOL inHeader; 82static int inHeader;
83static BOOL badHeader; 83static int badHeader;
84static BOOL errorFlag; 84static int errorFlag;
85static BOOL skipFileFlag; 85static int skipFileFlag;
86static BOOL warnedRoot; 86static int warnedRoot;
87static BOOL eofFlag; 87static int eofFlag;
88static long dataCc; 88static long dataCc;
89static int outFd; 89static int outFd;
90static char outName[TAR_NAME_SIZE]; 90static char outName[TAR_NAME_SIZE];
@@ -114,7 +114,7 @@ static void readHeader(const TarHeader * hp,
114/* 114/*
115 * Local procedures to save files into a tar file. 115 * Local procedures to save files into a tar file.
116 */ 116 */
117static void saveFile(const char * fileName, BOOL seeLinks); 117static void saveFile(const char * fileName, int seeLinks);
118 118
119static void saveRegularFile(const char * fileName, 119static void saveRegularFile(const char * fileName,
120 const struct stat * statbuf); 120 const struct stat * statbuf);
@@ -122,7 +122,7 @@ static void saveRegularFile(const char * fileName,
122static void saveDirectory(const char * fileName, 122static void saveDirectory(const char * fileName,
123 const struct stat * statbuf); 123 const struct stat * statbuf);
124 124
125static BOOL wantFileName(const char * fileName, 125static int wantFileName(const char * fileName,
126 int fileCount, char ** fileTable); 126 int fileCount, char ** fileTable);
127 127
128static void writeHeader(const char * fileName, 128static void writeHeader(const char * fileName,
@@ -130,7 +130,7 @@ static void writeHeader(const char * fileName,
130 130
131static void writeTarFile(int fileCount, char ** fileTable); 131static void writeTarFile(int fileCount, char ** fileTable);
132static void writeTarBlock(const char * buf, int len); 132static void writeTarBlock(const char * buf, int len);
133static BOOL putOctal(char * cp, int len, long value); 133static int putOctal(char * cp, int len, long value);
134 134
135 135
136extern int 136extern int
@@ -383,8 +383,8 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
383 time_t mtime; 383 time_t mtime;
384 const char * name; 384 const char * name;
385 int cc; 385 int cc;
386 BOOL hardLink; 386 int hardLink;
387 BOOL softLink; 387 int softLink;
388 388
389 /* 389 /*
390 * If the block is completely empty, then this is the end of the 390 * If the block is completely empty, then this is the end of the
@@ -710,7 +710,7 @@ done:
710 * they really are, instead of blindly following them. 710 * they really are, instead of blindly following them.
711 */ 711 */
712static void 712static void
713saveFile(const char * fileName, BOOL seeLinks) 713saveFile(const char * fileName, int seeLinks)
714{ 714{
715 int status; 715 int status;
716 int mode; 716 int mode;
@@ -788,7 +788,7 @@ saveFile(const char * fileName, BOOL seeLinks)
788static void 788static void
789saveRegularFile(const char * fileName, const struct stat * statbuf) 789saveRegularFile(const char * fileName, const struct stat * statbuf)
790{ 790{
791 BOOL sawEof; 791 int sawEof;
792 int fileFd; 792 int fileFd;
793 int cc; 793 int cc;
794 int dataCount; 794 int dataCount;
@@ -897,7 +897,7 @@ saveDirectory(const char * dirName, const struct stat * statbuf)
897{ 897{
898 DIR * dir; 898 DIR * dir;
899 struct dirent * entry; 899 struct dirent * entry;
900 BOOL needSlash; 900 int needSlash;
901 char fullName[PATH_LEN]; 901 char fullName[PATH_LEN];
902 902
903 /* 903 /*
@@ -1160,7 +1160,7 @@ getOctal(const char * cp, int len)
1160 * The number is zero and space padded and possibly null padded. 1160 * The number is zero and space padded and possibly null padded.
1161 * Returns TRUE if successful. 1161 * Returns TRUE if successful.
1162 */ 1162 */
1163static BOOL 1163static int
1164putOctal(char * cp, int len, long value) 1164putOctal(char * cp, int len, long value)
1165{ 1165{
1166 int tempLength; 1166 int tempLength;
@@ -1212,7 +1212,7 @@ putOctal(char * cp, int len, long value)
1212 * of path prefixes. An empty list implies that all files are wanted. 1212 * of path prefixes. An empty list implies that all files are wanted.
1213 * Returns TRUE if the file is selected. 1213 * Returns TRUE if the file is selected.
1214 */ 1214 */
1215static BOOL 1215static int
1216wantFileName(const char * fileName, int fileCount, char ** fileTable) 1216wantFileName(const char * fileName, int fileCount, char ** fileTable)
1217{ 1217{
1218 const char * pathName; 1218 const char * pathName;
diff --git a/busybox.c b/busybox.c
index 15e1bef87..cdbefbe94 100644
--- a/busybox.c
+++ b/busybox.c
@@ -30,7 +30,7 @@ static const struct Applet applets[] = {
30 {"clear", clear_main}, 30 {"clear", clear_main},
31#endif 31#endif
32#ifdef BB_CP //bin 32#ifdef BB_CP //bin
33 {"cp", dyadic_main}, 33 {"cp", cp_main},
34#endif 34#endif
35#ifdef BB_DATE //bin 35#ifdef BB_DATE //bin
36 {"date", date_main}, 36 {"date", date_main},
diff --git a/busybox.def.h b/busybox.def.h
index c78deebc2..3999df37e 100644
--- a/busybox.def.h
+++ b/busybox.def.h
@@ -10,7 +10,7 @@
10#define BB_CHOWN 10#define BB_CHOWN
11#define BB_CHROOT 11#define BB_CHROOT
12#define BB_CLEAR 12#define BB_CLEAR
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 16//#define BB_DESCEND
@@ -54,7 +54,7 @@
54#define BB_TAR 54#define BB_TAR
55#define BB_TOUCH 55#define BB_TOUCH
56#define BB_TRUE 56#define BB_TRUE
57//#define BB_UMOUNT 57#define BB_UMOUNT
58//#define BB_UPDATE 58//#define BB_UPDATE
59#define BB_UTILITY 59#define BB_UTILITY
60#define BB_ZCAT 60#define BB_ZCAT
diff --git a/coreutils/cp.c b/coreutils/cp.c
index 078a57c56..797663d2b 100644
--- a/coreutils/cp.c
+++ b/coreutils/cp.c
@@ -1,89 +1,141 @@
1/*
2 * Mini cp implementation for busybox
3 *
4 * Copyright (C) 1998 by Erik Andersen <andersee@debian.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
1#include "internal.h" 22#include "internal.h"
2#include <stdio.h> 23#include <stdio.h>
3#include <sys/stat.h> 24#include <time.h>
4#include <sys/fcntl.h> 25#include <utime.h>
5#include <sys/param.h> 26#include <dirent.h>
6#include <errno.h> 27
7 28const char cp_usage[] = "cp [OPTION]... SOURCE DEST\n"
8const char cp_usage[] = "cp [-r] source-file destination-file\n" 29 " or: cp [OPTION]... SOURCE... DIRECTORY\n"
9"\t\tcp [-r] source-file [source-file ...] destination-directory\n" 30 "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n"
10"\n" 31 "\n"
11"\tCopy the source files to the destination.\n" 32 "\t-a\tsame as -dpR\n"
12"\n" 33 "\t-d\tpreserve links\n"
13"\t-r:\tRecursively copy all files and directories\n" 34 "\t-p\tpreserve file attributes if possable\n"
14"\t\tunder the argument directory."; 35 "\t-R\tcopy directories recursively\n";
15 36
16extern int 37
17cp_fn(const struct FileInfo * i) 38static int recursiveFlag = FALSE;
39static int followLinks = FALSE;
40static int preserveFlag = FALSE;
41static const char *srcName;
42static const char *destName;
43
44
45static int fileAction(const char *fileName)
18{ 46{
19 int sourceFd; 47 char newdestName[NAME_MAX];
20 int destinationFd; 48 strcpy(newdestName, destName);
21 const char * destination = i->destination; 49 strcat(newdestName, fileName+(strlen(srcName)));
22 struct stat destination_stat; 50 fprintf(stderr, "A: copying %s to %s\n", fileName, newdestName);
23 int status; 51 return (copyFile(fileName, newdestName, preserveFlag, followLinks));
24 char buf[8192]; 52}
25 char d[PATH_MAX]; 53
26 54static int dirAction(const char *fileName)
27 if ( (i->stat.st_mode & S_IFMT) == S_IFDIR ) { 55{
28 if ( mkdir(destination, i->stat.st_mode & ~S_IFMT) 56 char newdestName[NAME_MAX];
29 != 0 && errno != EEXIST ) { 57 struct stat statBuf;
30 name_and_error(destination); 58 struct utimbuf times;
31 return 1; 59
32 } 60 strcpy(newdestName, destName);
33 return 0; 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 }
34 } 67 }
35 if ( (sourceFd = open(i->source, O_RDONLY)) < 0 ) { 68 else if (!S_ISDIR (statBuf.st_mode)) {
36 name_and_error(i->source); 69 fprintf(stderr, "`%s' exists but is not a directory", newdestName);
37 return 1; 70 return( FALSE);
38 } 71 }
39 if ( stat(destination, &destination_stat) == 0 ) { 72 if (preserveFlag==TRUE) {
40 if ( i->stat.st_ino == destination_stat.st_ino 73 /* Try to preserve premissions, but don't whine on failure */
41 && i->stat.st_dev == destination_stat.st_dev ) { 74 if (stat(newdestName, &statBuf)) {
42 fprintf(stderr 75 perror(newdestName);
43 ,"copy of %s to %s would copy file to itself.\n" 76 return( FALSE);
44 ,i->source 77 }
45 ,destination); 78 chmod(newdestName, statBuf.st_mode);
46 close(sourceFd); 79 chown(newdestName, statBuf.st_uid, statBuf.st_gid);
47 return 1; 80 times.actime = statBuf.st_atime;
48 } 81 times.modtime = statBuf.st_mtime;
82 utime(newdestName, &times);
49 } 83 }
50 /* 84 return TRUE;
51 * If the destination is a directory, create a file within it. 85}
52 */ 86
53 if ( (destination_stat.st_mode & S_IFMT) == S_IFDIR ) { 87extern int cp_main(int argc, char **argv)
54 destination = join_paths( 88{
55 d 89
56 ,i->destination 90 int dirFlag;
57 ,&i->source[i->directoryLength]); 91
58 92 if (argc < 3) {
59 if ( stat(destination, &destination_stat) == 0 ) { 93 fprintf(stderr, "Usage: %s", cp_usage);
60 if ( i->stat.st_ino == destination_stat.st_ino 94 return (FALSE);
61 && i->stat.st_dev == destination_stat.st_dev ) {
62 fprintf(stderr
63 ,"copy of %s to %s would copy file to itself.\n"
64 ,i->source
65 ,destination);
66 close(sourceFd);
67 return 1;
68 }
69 }
70 } 95 }
96 argc--;
97 argv++;
71 98
72 destinationFd = creat(destination, i->stat.st_mode & 07777); 99 /* Parse any options */
100 while (**argv == '-') {
101 while (*++(*argv))
102 switch (**argv) {
103 case 'a':
104 followLinks = TRUE;
105 preserveFlag = TRUE;
106 recursiveFlag = TRUE;
107 break;
108 case 'd':
109 followLinks = TRUE;
110 break;
111 case 'p':
112 preserveFlag = TRUE;
113 break;
114 case 'R':
115 recursiveFlag = TRUE;
116 break;
117 default:
118 fprintf(stderr, "Usage: %s\n", cp_usage);
119 exit(FALSE);
120 }
121 argc--;
122 argv++;
123 }
124
125
126 destName = argv[argc - 1];
73 127
74 while ( (status = read(sourceFd, buf, sizeof(buf))) > 0 ) { 128 dirFlag = isDirectory(destName);
75 if ( write(destinationFd, buf, status) != status ) { 129
76 name_and_error(destination); 130 if ((argc > 3) && !dirFlag) {
77 close(sourceFd); 131 fprintf(stderr, "%s: not a directory\n", destName);
78 close(destinationFd); 132 return (FALSE);
79 return 1;
80 }
81 } 133 }
82 close(sourceFd); 134
83 close(destinationFd); 135 while (argc-- >= 2) {
84 if ( status < 0 ) { 136 srcName = *(argv++);
85 name_and_error(i->source); 137 return recursiveAction(srcName, recursiveFlag, followLinks,
86 return 1; 138 fileAction, fileAction);
87 } 139 }
88 return 0; 140 return( TRUE);
89} 141}
diff --git a/coreutils/mv.c b/coreutils/mv.c
index 610040d92..df56206a3 100644
--- a/coreutils/mv.c
+++ b/coreutils/mv.c
@@ -37,7 +37,7 @@ extern int mv_main (int argc, char **argv)
37 const char *srcName; 37 const char *srcName;
38 const char *destName; 38 const char *destName;
39 const char *lastArg; 39 const char *lastArg;
40 BOOL dirFlag; 40 int dirFlag;
41 41
42 if (argc < 3) { 42 if (argc < 3) {
43 fprintf (stderr, "Usage: %s %s", *argv, mv_usage); 43 fprintf (stderr, "Usage: %s %s", *argv, mv_usage);
@@ -63,7 +63,7 @@ extern int mv_main (int argc, char **argv)
63 63
64 destName = lastArg; 64 destName = lastArg;
65 65
66 if (dirFlag) 66 if (dirFlag==TRUE)
67 destName = buildName (destName, srcName); 67 destName = buildName (destName, srcName);
68 68
69 if (rename (srcName, destName) >= 0) 69 if (rename (srcName, destName) >= 0)
@@ -74,7 +74,7 @@ extern int mv_main (int argc, char **argv)
74 continue; 74 continue;
75 } 75 }
76 76
77 if (!copyFile (srcName, destName, TRUE)) 77 if (!copyFile (srcName, destName, TRUE, FALSE))
78 continue; 78 continue;
79 79
80 if (unlink (srcName) < 0) 80 if (unlink (srcName) < 0)
diff --git a/cp.c b/cp.c
index 078a57c56..797663d2b 100644
--- a/cp.c
+++ b/cp.c
@@ -1,89 +1,141 @@
1/*
2 * Mini cp implementation for busybox
3 *
4 * Copyright (C) 1998 by Erik Andersen <andersee@debian.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
1#include "internal.h" 22#include "internal.h"
2#include <stdio.h> 23#include <stdio.h>
3#include <sys/stat.h> 24#include <time.h>
4#include <sys/fcntl.h> 25#include <utime.h>
5#include <sys/param.h> 26#include <dirent.h>
6#include <errno.h> 27
7 28const char cp_usage[] = "cp [OPTION]... SOURCE DEST\n"
8const char cp_usage[] = "cp [-r] source-file destination-file\n" 29 " or: cp [OPTION]... SOURCE... DIRECTORY\n"
9"\t\tcp [-r] source-file [source-file ...] destination-directory\n" 30 "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n"
10"\n" 31 "\n"
11"\tCopy the source files to the destination.\n" 32 "\t-a\tsame as -dpR\n"
12"\n" 33 "\t-d\tpreserve links\n"
13"\t-r:\tRecursively copy all files and directories\n" 34 "\t-p\tpreserve file attributes if possable\n"
14"\t\tunder the argument directory."; 35 "\t-R\tcopy directories recursively\n";
15 36
16extern int 37
17cp_fn(const struct FileInfo * i) 38static int recursiveFlag = FALSE;
39static int followLinks = FALSE;
40static int preserveFlag = FALSE;
41static const char *srcName;
42static const char *destName;
43
44
45static int fileAction(const char *fileName)
18{ 46{
19 int sourceFd; 47 char newdestName[NAME_MAX];
20 int destinationFd; 48 strcpy(newdestName, destName);
21 const char * destination = i->destination; 49 strcat(newdestName, fileName+(strlen(srcName)));
22 struct stat destination_stat; 50 fprintf(stderr, "A: copying %s to %s\n", fileName, newdestName);
23 int status; 51 return (copyFile(fileName, newdestName, preserveFlag, followLinks));
24 char buf[8192]; 52}
25 char d[PATH_MAX]; 53
26 54static int dirAction(const char *fileName)
27 if ( (i->stat.st_mode & S_IFMT) == S_IFDIR ) { 55{
28 if ( mkdir(destination, i->stat.st_mode & ~S_IFMT) 56 char newdestName[NAME_MAX];
29 != 0 && errno != EEXIST ) { 57 struct stat statBuf;
30 name_and_error(destination); 58 struct utimbuf times;
31 return 1; 59
32 } 60 strcpy(newdestName, destName);
33 return 0; 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 }
34 } 67 }
35 if ( (sourceFd = open(i->source, O_RDONLY)) < 0 ) { 68 else if (!S_ISDIR (statBuf.st_mode)) {
36 name_and_error(i->source); 69 fprintf(stderr, "`%s' exists but is not a directory", newdestName);
37 return 1; 70 return( FALSE);
38 } 71 }
39 if ( stat(destination, &destination_stat) == 0 ) { 72 if (preserveFlag==TRUE) {
40 if ( i->stat.st_ino == destination_stat.st_ino 73 /* Try to preserve premissions, but don't whine on failure */
41 && i->stat.st_dev == destination_stat.st_dev ) { 74 if (stat(newdestName, &statBuf)) {
42 fprintf(stderr 75 perror(newdestName);
43 ,"copy of %s to %s would copy file to itself.\n" 76 return( FALSE);
44 ,i->source 77 }
45 ,destination); 78 chmod(newdestName, statBuf.st_mode);
46 close(sourceFd); 79 chown(newdestName, statBuf.st_uid, statBuf.st_gid);
47 return 1; 80 times.actime = statBuf.st_atime;
48 } 81 times.modtime = statBuf.st_mtime;
82 utime(newdestName, &times);
49 } 83 }
50 /* 84 return TRUE;
51 * If the destination is a directory, create a file within it. 85}
52 */ 86
53 if ( (destination_stat.st_mode & S_IFMT) == S_IFDIR ) { 87extern int cp_main(int argc, char **argv)
54 destination = join_paths( 88{
55 d 89
56 ,i->destination 90 int dirFlag;
57 ,&i->source[i->directoryLength]); 91
58 92 if (argc < 3) {
59 if ( stat(destination, &destination_stat) == 0 ) { 93 fprintf(stderr, "Usage: %s", cp_usage);
60 if ( i->stat.st_ino == destination_stat.st_ino 94 return (FALSE);
61 && i->stat.st_dev == destination_stat.st_dev ) {
62 fprintf(stderr
63 ,"copy of %s to %s would copy file to itself.\n"
64 ,i->source
65 ,destination);
66 close(sourceFd);
67 return 1;
68 }
69 }
70 } 95 }
96 argc--;
97 argv++;
71 98
72 destinationFd = creat(destination, i->stat.st_mode & 07777); 99 /* Parse any options */
100 while (**argv == '-') {
101 while (*++(*argv))
102 switch (**argv) {
103 case 'a':
104 followLinks = TRUE;
105 preserveFlag = TRUE;
106 recursiveFlag = TRUE;
107 break;
108 case 'd':
109 followLinks = TRUE;
110 break;
111 case 'p':
112 preserveFlag = TRUE;
113 break;
114 case 'R':
115 recursiveFlag = TRUE;
116 break;
117 default:
118 fprintf(stderr, "Usage: %s\n", cp_usage);
119 exit(FALSE);
120 }
121 argc--;
122 argv++;
123 }
124
125
126 destName = argv[argc - 1];
73 127
74 while ( (status = read(sourceFd, buf, sizeof(buf))) > 0 ) { 128 dirFlag = isDirectory(destName);
75 if ( write(destinationFd, buf, status) != status ) { 129
76 name_and_error(destination); 130 if ((argc > 3) && !dirFlag) {
77 close(sourceFd); 131 fprintf(stderr, "%s: not a directory\n", destName);
78 close(destinationFd); 132 return (FALSE);
79 return 1;
80 }
81 } 133 }
82 close(sourceFd); 134
83 close(destinationFd); 135 while (argc-- >= 2) {
84 if ( status < 0 ) { 136 srcName = *(argv++);
85 name_and_error(i->source); 137 return recursiveAction(srcName, recursiveFlag, followLinks,
86 return 1; 138 fileAction, fileAction);
87 } 139 }
88 return 0; 140 return( TRUE);
89} 141}
diff --git a/find.c b/find.c
index a42f9e979..d618401bf 100644
--- a/find.c
+++ b/find.c
@@ -27,7 +27,7 @@
27 27
28static char* pattern=NULL; 28static char* pattern=NULL;
29static char* directory=NULL; 29static char* directory=NULL;
30int dereferenceFlag=FALSE; 30static int dereferenceFlag=FALSE;
31 31
32static const char find_usage[] = "find [path...] [expression]\n" 32static const char find_usage[] = "find [path...] [expression]\n"
33"default path is the current directory; default expression is -print\n" 33"default path is the current directory; default expression is -print\n"
diff --git a/findutils/find.c b/findutils/find.c
index a42f9e979..d618401bf 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -27,7 +27,7 @@
27 27
28static char* pattern=NULL; 28static char* pattern=NULL;
29static char* directory=NULL; 29static char* directory=NULL;
30int dereferenceFlag=FALSE; 30static int dereferenceFlag=FALSE;
31 31
32static const char find_usage[] = "find [path...] [expression]\n" 32static const char find_usage[] = "find [path...] [expression]\n"
33"default path is the current directory; default expression is -print\n" 33"default path is the current directory; default expression is -print\n"
diff --git a/findutils/grep.c b/findutils/grep.c
index 11198b851..52ef6c0fe 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -31,7 +31,7 @@ const char grep_usage[] =
31 31
32 32
33 33
34static BOOL search (const char *string, const char *word, BOOL ignoreCase); 34static int search (const char *string, const char *word, int ignoreCase);
35 35
36 36
37extern int grep_main (int argc, char **argv) 37extern int grep_main (int argc, char **argv)
@@ -40,9 +40,9 @@ extern int grep_main (int argc, char **argv)
40 const char *word; 40 const char *word;
41 const char *name; 41 const char *name;
42 const char *cp; 42 const char *cp;
43 BOOL tellName; 43 int tellName;
44 BOOL ignoreCase; 44 int ignoreCase;
45 BOOL tellLine; 45 int tellLine;
46 long line; 46 long line;
47 char buf[BUF_SIZE]; 47 char buf[BUF_SIZE];
48 48
@@ -125,7 +125,7 @@ extern int grep_main (int argc, char **argv)
125/* 125/*
126 * See if the specified word is found in the specified string. 126 * See if the specified word is found in the specified string.
127 */ 127 */
128static BOOL search (const char *string, const char *word, BOOL ignoreCase) 128static int search (const char *string, const char *word, int ignoreCase)
129{ 129{
130 const char *cp1; 130 const char *cp1;
131 const char *cp2; 131 const char *cp2;
diff --git a/grep.c b/grep.c
index 11198b851..52ef6c0fe 100644
--- a/grep.c
+++ b/grep.c
@@ -31,7 +31,7 @@ const char grep_usage[] =
31 31
32 32
33 33
34static BOOL search (const char *string, const char *word, BOOL ignoreCase); 34static int search (const char *string, const char *word, int ignoreCase);
35 35
36 36
37extern int grep_main (int argc, char **argv) 37extern int grep_main (int argc, char **argv)
@@ -40,9 +40,9 @@ extern int grep_main (int argc, char **argv)
40 const char *word; 40 const char *word;
41 const char *name; 41 const char *name;
42 const char *cp; 42 const char *cp;
43 BOOL tellName; 43 int tellName;
44 BOOL ignoreCase; 44 int ignoreCase;
45 BOOL tellLine; 45 int tellLine;
46 long line; 46 long line;
47 char buf[BUF_SIZE]; 47 char buf[BUF_SIZE];
48 48
@@ -125,7 +125,7 @@ extern int grep_main (int argc, char **argv)
125/* 125/*
126 * See if the specified word is found in the specified string. 126 * See if the specified word is found in the specified string.
127 */ 127 */
128static BOOL search (const char *string, const char *word, BOOL ignoreCase) 128static int search (const char *string, const char *word, int ignoreCase)
129{ 129{
130 const char *cp1; 130 const char *cp1;
131 const char *cp2; 131 const char *cp2;
diff --git a/internal.h b/internal.h
index beb347671..d36d218a9 100644
--- a/internal.h
+++ b/internal.h
@@ -33,11 +33,10 @@
33 33
34 34
35/* Some useful definitions */ 35/* Some useful definitions */
36typedef int BOOL;
37#define STDIN 0 36#define STDIN 0
38#define STDOUT 1 37#define STDOUT 1
39#define FALSE ((BOOL) 1) 38#define FALSE ((int) 1)
40#define TRUE ((BOOL) 0) 39#define TRUE ((int) 0)
41 40
42#define PATH_LEN 1024 41#define PATH_LEN 1024
43#define BUF_SIZE 8192 42#define BUF_SIZE 8192
@@ -97,6 +96,7 @@ extern int busybox_main(int argc, char** argv);
97extern int block_device_main(int argc, char** argv); 96extern int block_device_main(int argc, char** argv);
98extern int cat_more_main(int argc, char** argv); 97extern int cat_more_main(int argc, char** argv);
99extern int more_main(int argc, char** argv); 98extern int more_main(int argc, char** argv);
99extern int cp_main(int argc, char** argv);
100extern int chgrp_main(int argc, char** argv); 100extern int chgrp_main(int argc, char** argv);
101extern int chmod_main(int argc, char** argv); 101extern int chmod_main(int argc, char** argv);
102extern int chown_main(int argc, char** argv); 102extern int chown_main(int argc, char** argv);
@@ -172,20 +172,21 @@ struct chunk {
172 172
173const char *modeString(int mode); 173const char *modeString(int mode);
174const char *timeString(time_t timeVal); 174const char *timeString(time_t timeVal);
175BOOL isDirectory(const char *name); 175int isDirectory(const char *name);
176BOOL isDevice(const char *name); 176int isDevice(const char *name);
177BOOL copyFile(const char *srcName, const char *destName, BOOL setModes); 177int copyFile(const char *srcName, const char *destName, int setModes,
178const char *buildName(const char *dirName, const char *fileName); 178 int followLinks);
179BOOL makeString(int argc, const char **argv, char *buf, int bufLen); 179char *buildName(const char *dirName, const char *fileName);
180int makeString(int argc, const char **argv, char *buf, int bufLen);
180char *getChunk(int size); 181char *getChunk(int size);
181char *chunkstrdup(const char *str); 182char *chunkstrdup(const char *str);
182void freeChunks(void); 183void freeChunks(void);
183int fullWrite(int fd, const char *buf, int len); 184int fullWrite(int fd, const char *buf, int len);
184int fullRead(int fd, char *buf, int len); 185int fullRead(int fd, char *buf, int len);
185int recursiveAction(const char *fileName, BOOL recurse, BOOL followLinks, 186int recursiveAction(const char *fileName, int recurse, int followLinks,
186 int (*fileAction) (const char *fileName), 187 int (*fileAction) (const char *fileName),
187 int (*dirAction) (const char *fileName)); 188 int (*dirAction) (const char *fileName));
188BOOL match(const char* text, const char * pattern); 189int match(const char* text, const char * pattern);
189const char* timeString(time_t timeVal); 190const char* timeString(time_t timeVal);
190 191
191 192
diff --git a/mv.c b/mv.c
index 610040d92..df56206a3 100644
--- a/mv.c
+++ b/mv.c
@@ -37,7 +37,7 @@ extern int mv_main (int argc, char **argv)
37 const char *srcName; 37 const char *srcName;
38 const char *destName; 38 const char *destName;
39 const char *lastArg; 39 const char *lastArg;
40 BOOL dirFlag; 40 int dirFlag;
41 41
42 if (argc < 3) { 42 if (argc < 3) {
43 fprintf (stderr, "Usage: %s %s", *argv, mv_usage); 43 fprintf (stderr, "Usage: %s %s", *argv, mv_usage);
@@ -63,7 +63,7 @@ extern int mv_main (int argc, char **argv)
63 63
64 destName = lastArg; 64 destName = lastArg;
65 65
66 if (dirFlag) 66 if (dirFlag==TRUE)
67 destName = buildName (destName, srcName); 67 destName = buildName (destName, srcName);
68 68
69 if (rename (srcName, destName) >= 0) 69 if (rename (srcName, destName) >= 0)
@@ -74,7 +74,7 @@ extern int mv_main (int argc, char **argv)
74 continue; 74 continue;
75 } 75 }
76 76
77 if (!copyFile (srcName, destName, TRUE)) 77 if (!copyFile (srcName, destName, TRUE, FALSE))
78 continue; 78 continue;
79 79
80 if (unlink (srcName) < 0) 80 if (unlink (srcName) < 0)
diff --git a/tar.c b/tar.c
index 498d4a300..1a9f84217 100644
--- a/tar.c
+++ b/tar.c
@@ -73,18 +73,18 @@ typedef struct
73/* 73/*
74 * Static data. 74 * Static data.
75 */ 75 */
76static BOOL listFlag; 76static int listFlag;
77static BOOL extractFlag; 77static int extractFlag;
78static BOOL createFlag; 78static int createFlag;
79static BOOL verboseFlag; 79static int verboseFlag;
80static BOOL tostdoutFlag; 80static int tostdoutFlag;
81 81
82static BOOL inHeader; 82static int inHeader;
83static BOOL badHeader; 83static int badHeader;
84static BOOL errorFlag; 84static int errorFlag;
85static BOOL skipFileFlag; 85static int skipFileFlag;
86static BOOL warnedRoot; 86static int warnedRoot;
87static BOOL eofFlag; 87static int eofFlag;
88static long dataCc; 88static long dataCc;
89static int outFd; 89static int outFd;
90static char outName[TAR_NAME_SIZE]; 90static char outName[TAR_NAME_SIZE];
@@ -114,7 +114,7 @@ static void readHeader(const TarHeader * hp,
114/* 114/*
115 * Local procedures to save files into a tar file. 115 * Local procedures to save files into a tar file.
116 */ 116 */
117static void saveFile(const char * fileName, BOOL seeLinks); 117static void saveFile(const char * fileName, int seeLinks);
118 118
119static void saveRegularFile(const char * fileName, 119static void saveRegularFile(const char * fileName,
120 const struct stat * statbuf); 120 const struct stat * statbuf);
@@ -122,7 +122,7 @@ static void saveRegularFile(const char * fileName,
122static void saveDirectory(const char * fileName, 122static void saveDirectory(const char * fileName,
123 const struct stat * statbuf); 123 const struct stat * statbuf);
124 124
125static BOOL wantFileName(const char * fileName, 125static int wantFileName(const char * fileName,
126 int fileCount, char ** fileTable); 126 int fileCount, char ** fileTable);
127 127
128static void writeHeader(const char * fileName, 128static void writeHeader(const char * fileName,
@@ -130,7 +130,7 @@ static void writeHeader(const char * fileName,
130 130
131static void writeTarFile(int fileCount, char ** fileTable); 131static void writeTarFile(int fileCount, char ** fileTable);
132static void writeTarBlock(const char * buf, int len); 132static void writeTarBlock(const char * buf, int len);
133static BOOL putOctal(char * cp, int len, long value); 133static int putOctal(char * cp, int len, long value);
134 134
135 135
136extern int 136extern int
@@ -383,8 +383,8 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
383 time_t mtime; 383 time_t mtime;
384 const char * name; 384 const char * name;
385 int cc; 385 int cc;
386 BOOL hardLink; 386 int hardLink;
387 BOOL softLink; 387 int softLink;
388 388
389 /* 389 /*
390 * If the block is completely empty, then this is the end of the 390 * If the block is completely empty, then this is the end of the
@@ -710,7 +710,7 @@ done:
710 * they really are, instead of blindly following them. 710 * they really are, instead of blindly following them.
711 */ 711 */
712static void 712static void
713saveFile(const char * fileName, BOOL seeLinks) 713saveFile(const char * fileName, int seeLinks)
714{ 714{
715 int status; 715 int status;
716 int mode; 716 int mode;
@@ -788,7 +788,7 @@ saveFile(const char * fileName, BOOL seeLinks)
788static void 788static void
789saveRegularFile(const char * fileName, const struct stat * statbuf) 789saveRegularFile(const char * fileName, const struct stat * statbuf)
790{ 790{
791 BOOL sawEof; 791 int sawEof;
792 int fileFd; 792 int fileFd;
793 int cc; 793 int cc;
794 int dataCount; 794 int dataCount;
@@ -897,7 +897,7 @@ saveDirectory(const char * dirName, const struct stat * statbuf)
897{ 897{
898 DIR * dir; 898 DIR * dir;
899 struct dirent * entry; 899 struct dirent * entry;
900 BOOL needSlash; 900 int needSlash;
901 char fullName[PATH_LEN]; 901 char fullName[PATH_LEN];
902 902
903 /* 903 /*
@@ -1160,7 +1160,7 @@ getOctal(const char * cp, int len)
1160 * The number is zero and space padded and possibly null padded. 1160 * The number is zero and space padded and possibly null padded.
1161 * Returns TRUE if successful. 1161 * Returns TRUE if successful.
1162 */ 1162 */
1163static BOOL 1163static int
1164putOctal(char * cp, int len, long value) 1164putOctal(char * cp, int len, long value)
1165{ 1165{
1166 int tempLength; 1166 int tempLength;
@@ -1212,7 +1212,7 @@ putOctal(char * cp, int len, long value)
1212 * of path prefixes. An empty list implies that all files are wanted. 1212 * of path prefixes. An empty list implies that all files are wanted.
1213 * Returns TRUE if the file is selected. 1213 * Returns TRUE if the file is selected.
1214 */ 1214 */
1215static BOOL 1215static int
1216wantFileName(const char * fileName, int fileCount, char ** fileTable) 1216wantFileName(const char * fileName, int fileCount, char ** fileTable)
1217{ 1217{
1218 const char * pathName; 1218 const char * pathName;
diff --git a/umount.c b/umount.c
index 4efc9f9d9..5274e2f6f 100644
--- a/umount.c
+++ b/umount.c
@@ -1,135 +1,95 @@
1/*
2 * Mini umount implementation for busybox
3 *
4 * Copyright (C) 1998 by Erik Andersen <andersee@debian.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
1#include "internal.h" 22#include "internal.h"
2#include <stdlib.h>
3#include <unistd.h>
4#include <errno.h>
5#include <string.h>
6#include <stdio.h> 23#include <stdio.h>
7#include <mntent.h>
8#include <sys/mount.h> 24#include <sys/mount.h>
25#include <mntent.h>
26#include <fstab.h>
27#include <errno.h>
9 28
10const char umount_usage[] = "umount {filesystem|directory}\n" 29const char umount_usage[] = "\tumount {filesystem|directory}\n"
11"\tumount -a\n" 30"or to unmount all mounted file systems:\n\tumount -a\n";
12"\n"
13"\tUnmount a filesystem.\n"
14"\t-a:\tUnmounts all mounted filesystems.\n";
15
16static char *
17stralloc(const char * string)
18{
19 int length = strlen(string) + 1;
20 char * n = malloc(length);
21 memcpy(n, string, length);
22 return n;
23}
24
25extern void
26erase_mtab(const char * name)
27{
28 struct mntent entries[100];
29 int count = 0;
30 FILE * mountTable = setmntent("/etc/mtab", "r");
31 struct mntent * m;
32
33 if ( mountTable == 0
34 && (mountTable = setmntent("/proc/mounts", "r")) == 0 ) {
35 name_and_error("/etc/mtab");
36 return;
37 }
38
39 while ( (m = getmntent(mountTable)) != 0 ) {
40 entries[count].mnt_fsname = stralloc(m->mnt_fsname);
41 entries[count].mnt_dir = stralloc(m->mnt_dir);
42 entries[count].mnt_type = stralloc(m->mnt_type);
43 entries[count].mnt_opts = stralloc(m->mnt_opts);
44 entries[count].mnt_freq = m->mnt_freq;
45 entries[count].mnt_passno = m->mnt_passno;
46 count++;
47 }
48 endmntent(mountTable);
49 if ( (mountTable = setmntent("/etc/mtab", "w")) ) {
50 int i;
51 for ( i = 0; i < count; i++ ) {
52 int result = ( strcmp(entries[i].mnt_fsname, name) == 0
53 || strcmp(entries[i].mnt_dir, name) == 0 );
54
55 if ( result )
56 continue;
57 else
58 addmntent(mountTable, &entries[i]);
59 }
60 endmntent(mountTable);
61 }
62 else if ( errno != EROFS )
63 name_and_error("/etc/mtab");
64}
65 31
66static int 32static int
67umount_all(int noMtab) 33umount_all()
68{ 34{
69 struct mntent entries[100]; 35 int status;
70 int count = 0; 36 struct mntent *m;
71 FILE * mountTable = setmntent("/etc/mtab", "r"); 37 FILE *mountTable;
72 struct mntent * m;
73 int status = 0;
74
75 if ( mountTable == 0
76 && (mountTable = setmntent("/proc/mounts", "r")) == 0 ) {
77 name_and_error("/etc/mtab");
78 return 1;
79 }
80 38
81 while ( (m = getmntent(mountTable)) != 0 ) { 39 if ((mountTable = setmntent ("/proc/mounts", "r"))) {
82 entries[count].mnt_fsname = stralloc(m->mnt_fsname); 40 while ((m = getmntent (mountTable)) != 0) {
83 count++; 41 char *blockDevice = m->mnt_fsname;
84 } 42 if (strcmp (blockDevice, "/dev/root") == 0)
85 endmntent(mountTable); 43 blockDevice = (getfsfile ("/"))->fs_spec;
86 44 status=umount (m->mnt_dir);
87 while ( count > 0 ) { 45 if (status!=0) {
88 int result = umount(entries[--count].mnt_fsname) == 0; 46 /* Don't bother retrying the umount on busy devices */
89 /* free(entries[count].mnt_fsname); */ 47 if (errno==EBUSY) {
90 if ( result ) { 48 perror(m->mnt_dir);
91 if ( !noMtab ) 49 continue;
92 erase_mtab(entries[count].mnt_fsname); 50 }
51 printf ("Trying to umount %s failed: %s\n",
52 m->mnt_dir, strerror(errno));
53 printf ("Instead trying to umount %s\n", blockDevice);
54 status=umount (blockDevice);
55 if (status!=0) {
56 printf ("Couldn't umount %s on %s (type %s): %s\n",
57 blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
58 }
93 } 59 }
94 else { 60 }
95 status = 1; 61 endmntent (mountTable);
96 name_and_error(entries[count].mnt_fsname); 62 }
97 } 63 return( TRUE);
98 }
99 return status;
100} 64}
101 65
102extern int 66extern int
103do_umount(const char * name, int noMtab) 67umount_main(int argc, char * * argv)
104{ 68{
105 if ( umount(name) == 0 ) {
106 if ( !noMtab )
107 erase_mtab(name);
108 return 0;
109 }
110 return 1;
111}
112 69
113extern int 70 if (argc < 2) {
114umount_main(struct FileInfo * i, int argc, char * * argv) 71 fprintf(stderr, "Usage: %s", umount_usage);
115{ 72 return(FALSE);
116 int noMtab = 0; 73 }
74 argc--;
75 argv++;
117 76
118 if ( argv[1][0] == '-' ) { 77 /* Parse any options */
119 switch ( argv[1][1] ) { 78 while (**argv == '-') {
120 case 'a': 79 while (*++(*argv)) switch (**argv) {
121 return umount_all(noMtab); 80 case 'a':
122 case 'n': 81 return umount_all();
123 noMtab = 1; 82 break;
124 break; 83 default:
125 default: 84 fprintf(stderr, "Usage: %s\n", umount_usage);
126 usage(umount_usage); 85 exit( FALSE);
127 return 1;
128 }
129 }
130 if ( do_umount(argv[1],noMtab) != 0 ) {
131 fprintf(stderr, "%s: %s.\n", argv[1], strerror(errno));
132 return 1;
133 } 86 }
134 return 0; 87 }
88 if ( umount(*argv) == 0 )
89 return (TRUE);
90 else {
91 perror("umount");
92 return( FALSE);
93 }
135} 94}
95
diff --git a/util-linux/umount.c b/util-linux/umount.c
index 4efc9f9d9..5274e2f6f 100644
--- a/util-linux/umount.c
+++ b/util-linux/umount.c
@@ -1,135 +1,95 @@
1/*
2 * Mini umount implementation for busybox
3 *
4 * Copyright (C) 1998 by Erik Andersen <andersee@debian.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
1#include "internal.h" 22#include "internal.h"
2#include <stdlib.h>
3#include <unistd.h>
4#include <errno.h>
5#include <string.h>
6#include <stdio.h> 23#include <stdio.h>
7#include <mntent.h>
8#include <sys/mount.h> 24#include <sys/mount.h>
25#include <mntent.h>
26#include <fstab.h>
27#include <errno.h>
9 28
10const char umount_usage[] = "umount {filesystem|directory}\n" 29const char umount_usage[] = "\tumount {filesystem|directory}\n"
11"\tumount -a\n" 30"or to unmount all mounted file systems:\n\tumount -a\n";
12"\n"
13"\tUnmount a filesystem.\n"
14"\t-a:\tUnmounts all mounted filesystems.\n";
15
16static char *
17stralloc(const char * string)
18{
19 int length = strlen(string) + 1;
20 char * n = malloc(length);
21 memcpy(n, string, length);
22 return n;
23}
24
25extern void
26erase_mtab(const char * name)
27{
28 struct mntent entries[100];
29 int count = 0;
30 FILE * mountTable = setmntent("/etc/mtab", "r");
31 struct mntent * m;
32
33 if ( mountTable == 0
34 && (mountTable = setmntent("/proc/mounts", "r")) == 0 ) {
35 name_and_error("/etc/mtab");
36 return;
37 }
38
39 while ( (m = getmntent(mountTable)) != 0 ) {
40 entries[count].mnt_fsname = stralloc(m->mnt_fsname);
41 entries[count].mnt_dir = stralloc(m->mnt_dir);
42 entries[count].mnt_type = stralloc(m->mnt_type);
43 entries[count].mnt_opts = stralloc(m->mnt_opts);
44 entries[count].mnt_freq = m->mnt_freq;
45 entries[count].mnt_passno = m->mnt_passno;
46 count++;
47 }
48 endmntent(mountTable);
49 if ( (mountTable = setmntent("/etc/mtab", "w")) ) {
50 int i;
51 for ( i = 0; i < count; i++ ) {
52 int result = ( strcmp(entries[i].mnt_fsname, name) == 0
53 || strcmp(entries[i].mnt_dir, name) == 0 );
54
55 if ( result )
56 continue;
57 else
58 addmntent(mountTable, &entries[i]);
59 }
60 endmntent(mountTable);
61 }
62 else if ( errno != EROFS )
63 name_and_error("/etc/mtab");
64}
65 31
66static int 32static int
67umount_all(int noMtab) 33umount_all()
68{ 34{
69 struct mntent entries[100]; 35 int status;
70 int count = 0; 36 struct mntent *m;
71 FILE * mountTable = setmntent("/etc/mtab", "r"); 37 FILE *mountTable;
72 struct mntent * m;
73 int status = 0;
74
75 if ( mountTable == 0
76 && (mountTable = setmntent("/proc/mounts", "r")) == 0 ) {
77 name_and_error("/etc/mtab");
78 return 1;
79 }
80 38
81 while ( (m = getmntent(mountTable)) != 0 ) { 39 if ((mountTable = setmntent ("/proc/mounts", "r"))) {
82 entries[count].mnt_fsname = stralloc(m->mnt_fsname); 40 while ((m = getmntent (mountTable)) != 0) {
83 count++; 41 char *blockDevice = m->mnt_fsname;
84 } 42 if (strcmp (blockDevice, "/dev/root") == 0)
85 endmntent(mountTable); 43 blockDevice = (getfsfile ("/"))->fs_spec;
86 44 status=umount (m->mnt_dir);
87 while ( count > 0 ) { 45 if (status!=0) {
88 int result = umount(entries[--count].mnt_fsname) == 0; 46 /* Don't bother retrying the umount on busy devices */
89 /* free(entries[count].mnt_fsname); */ 47 if (errno==EBUSY) {
90 if ( result ) { 48 perror(m->mnt_dir);
91 if ( !noMtab ) 49 continue;
92 erase_mtab(entries[count].mnt_fsname); 50 }
51 printf ("Trying to umount %s failed: %s\n",
52 m->mnt_dir, strerror(errno));
53 printf ("Instead trying to umount %s\n", blockDevice);
54 status=umount (blockDevice);
55 if (status!=0) {
56 printf ("Couldn't umount %s on %s (type %s): %s\n",
57 blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
58 }
93 } 59 }
94 else { 60 }
95 status = 1; 61 endmntent (mountTable);
96 name_and_error(entries[count].mnt_fsname); 62 }
97 } 63 return( TRUE);
98 }
99 return status;
100} 64}
101 65
102extern int 66extern int
103do_umount(const char * name, int noMtab) 67umount_main(int argc, char * * argv)
104{ 68{
105 if ( umount(name) == 0 ) {
106 if ( !noMtab )
107 erase_mtab(name);
108 return 0;
109 }
110 return 1;
111}
112 69
113extern int 70 if (argc < 2) {
114umount_main(struct FileInfo * i, int argc, char * * argv) 71 fprintf(stderr, "Usage: %s", umount_usage);
115{ 72 return(FALSE);
116 int noMtab = 0; 73 }
74 argc--;
75 argv++;
117 76
118 if ( argv[1][0] == '-' ) { 77 /* Parse any options */
119 switch ( argv[1][1] ) { 78 while (**argv == '-') {
120 case 'a': 79 while (*++(*argv)) switch (**argv) {
121 return umount_all(noMtab); 80 case 'a':
122 case 'n': 81 return umount_all();
123 noMtab = 1; 82 break;
124 break; 83 default:
125 default: 84 fprintf(stderr, "Usage: %s\n", umount_usage);
126 usage(umount_usage); 85 exit( FALSE);
127 return 1;
128 }
129 }
130 if ( do_umount(argv[1],noMtab) != 0 ) {
131 fprintf(stderr, "%s: %s.\n", argv[1], strerror(errno));
132 return 1;
133 } 86 }
134 return 0; 87 }
88 if ( umount(*argv) == 0 )
89 return (TRUE);
90 else {
91 perror("umount");
92 return( FALSE);
93 }
135} 94}
95
diff --git a/utility.c b/utility.c
index 369aa21f2..277e27c70 100644
--- a/utility.c
+++ b/utility.c
@@ -27,31 +27,30 @@
27#include <string.h> 27#include <string.h>
28#include <errno.h> 28#include <errno.h>
29#include <fcntl.h> 29#include <fcntl.h>
30//#include <sys/types.h>
31//#include <sys/stat.h>
32#include <dirent.h> 30#include <dirent.h>
33#include <time.h> 31#include <time.h>
34#include <utime.h> 32#include <utime.h>
33#include <sys/stat.h>
34#include <unistd.h>
35 35
36#if 0 36#if 0
37 37
38extern char * 38extern char *join_paths(char *buffer, const char *a, const char *b)
39join_paths(char * buffer, const char * a, const char * b)
40{ 39{
41 int length = 0; 40 int length = 0;
42 41
43 if ( a && *a ) { 42 if (a && *a) {
44 length = strlen(a); 43 length = strlen(a);
45 memcpy(buffer, a, length); 44 memcpy(buffer, a, length);
46 } 45 }
47 if ( b && *b ) { 46 if (b && *b) {
48 if ( length > 0 && buffer[length - 1] != '/' ) 47 if (length > 0 && buffer[length - 1] != '/')
49 buffer[length++] = '/'; 48 buffer[length++] = '/';
50 if ( *b == '/' ) 49 if (*b == '/')
51 b++; 50 b++;
52 strcpy(&buffer[length], b); 51 strcpy(&buffer[length], b);
53 } 52 }
54 return buffer; 53 return buffer;
55} 54}
56 55
57#endif 56#endif
@@ -61,73 +60,72 @@ join_paths(char * buffer, const char * a, const char * b)
61 60
62 61
63 62
64static CHUNK * chunkList; 63static CHUNK *chunkList;
65 64
66 65
67/* 66/*
68 * Return the standard ls-like mode string from a file mode. 67 * Return the standard ls-like mode string from a file mode.
69 * This is static and so is overwritten on each call. 68 * This is static and so is overwritten on each call.
70 */ 69 */
71const char * 70const char *modeString(int mode)
72modeString(int mode)
73{ 71{
74 static char buf[12]; 72 static char buf[12];
75 73
76 strcpy(buf, "----------"); 74 strcpy(buf, "----------");
77 75
78 /* 76 /*
79 * Fill in the file type. 77 * Fill in the file type.
80 */ 78 */
81 if (S_ISDIR(mode)) 79 if (S_ISDIR(mode))
82 buf[0] = 'd'; 80 buf[0] = 'd';
83 if (S_ISCHR(mode)) 81 if (S_ISCHR(mode))
84 buf[0] = 'c'; 82 buf[0] = 'c';
85 if (S_ISBLK(mode)) 83 if (S_ISBLK(mode))
86 buf[0] = 'b'; 84 buf[0] = 'b';
87 if (S_ISFIFO(mode)) 85 if (S_ISFIFO(mode))
88 buf[0] = 'p'; 86 buf[0] = 'p';
89#ifdef S_ISLNK 87#ifdef S_ISLNK
90 if (S_ISLNK(mode)) 88 if (S_ISLNK(mode))
91 buf[0] = 'l'; 89 buf[0] = 'l';
92#endif 90#endif
93#ifdef S_ISSOCK 91#ifdef S_ISSOCK
94 if (S_ISSOCK(mode)) 92 if (S_ISSOCK(mode))
95 buf[0] = 's'; 93 buf[0] = 's';
96#endif 94#endif
97 95
98 /* 96 /*
99 * Now fill in the normal file permissions. 97 * Now fill in the normal file permissions.
100 */ 98 */
101 if (mode & S_IRUSR) 99 if (mode & S_IRUSR)
102 buf[1] = 'r'; 100 buf[1] = 'r';
103 if (mode & S_IWUSR) 101 if (mode & S_IWUSR)
104 buf[2] = 'w'; 102 buf[2] = 'w';
105 if (mode & S_IXUSR) 103 if (mode & S_IXUSR)
106 buf[3] = 'x'; 104 buf[3] = 'x';
107 if (mode & S_IRGRP) 105 if (mode & S_IRGRP)
108 buf[4] = 'r'; 106 buf[4] = 'r';
109 if (mode & S_IWGRP) 107 if (mode & S_IWGRP)
110 buf[5] = 'w'; 108 buf[5] = 'w';
111 if (mode & S_IXGRP) 109 if (mode & S_IXGRP)
112 buf[6] = 'x'; 110 buf[6] = 'x';
113 if (mode & S_IROTH) 111 if (mode & S_IROTH)
114 buf[7] = 'r'; 112 buf[7] = 'r';
115 if (mode & S_IWOTH) 113 if (mode & S_IWOTH)
116 buf[8] = 'w'; 114 buf[8] = 'w';
117 if (mode & S_IXOTH) 115 if (mode & S_IXOTH)
118 buf[9] = 'x'; 116 buf[9] = 'x';
119 117
120 /* 118 /*
121 * Finally fill in magic stuff like suid and sticky text. 119 * Finally fill in magic stuff like suid and sticky text.
122 */ 120 */
123 if (mode & S_ISUID) 121 if (mode & S_ISUID)
124 buf[3] = ((mode & S_IXUSR) ? 's' : 'S'); 122 buf[3] = ((mode & S_IXUSR) ? 's' : 'S');
125 if (mode & S_ISGID) 123 if (mode & S_ISGID)
126 buf[6] = ((mode & S_IXGRP) ? 's' : 'S'); 124 buf[6] = ((mode & S_IXGRP) ? 's' : 'S');
127 if (mode & S_ISVTX) 125 if (mode & S_ISVTX)
128 buf[9] = ((mode & S_IXOTH) ? 't' : 'T'); 126 buf[9] = ((mode & S_IXOTH) ? 't' : 'T');
129 127
130 return buf; 128 return buf;
131} 129}
132 130
133 131
@@ -135,15 +133,14 @@ modeString(int mode)
135 * Return TRUE if a fileName is a directory. 133 * Return TRUE if a fileName is a directory.
136 * Nonexistant files return FALSE. 134 * Nonexistant files return FALSE.
137 */ 135 */
138BOOL 136int isDirectory(const char *name)
139isDirectory(const char * name)
140{ 137{
141 struct stat statBuf; 138 struct stat statBuf;
142 139
143 if (stat(name, &statBuf) < 0) 140 if (stat(name, &statBuf) < 0)
144 return FALSE; 141 return FALSE;
145 142
146 return S_ISDIR(statBuf.st_mode); 143 return S_ISDIR(statBuf.st_mode);
147} 144}
148 145
149 146
@@ -151,15 +148,14 @@ isDirectory(const char * name)
151 * Return TRUE if a filename is a block or character device. 148 * Return TRUE if a filename is a block or character device.
152 * Nonexistant files return FALSE. 149 * Nonexistant files return FALSE.
153 */ 150 */
154BOOL 151int isDevice(const char *name)
155isDevice(const char * name)
156{ 152{
157 struct stat statBuf; 153 struct stat statBuf;
158 154
159 if (stat(name, &statBuf) < 0) 155 if (stat(name, &statBuf) < 0)
160 return FALSE; 156 return FALSE;
161 157
162 return S_ISBLK(statBuf.st_mode) || S_ISCHR(statBuf.st_mode); 158 return S_ISBLK(statBuf.st_mode) || S_ISCHR(statBuf.st_mode);
163} 159}
164 160
165 161
@@ -169,102 +165,118 @@ isDevice(const char * name)
169 * error message output. (Failure is not indicted if the attributes cannot 165 * error message output. (Failure is not indicted if the attributes cannot
170 * be set.) 166 * be set.)
171 */ 167 */
172BOOL 168int
173copyFile( 169copyFile(
174 const char * srcName, 170 const char *srcName,
175 const char * destName, 171 const char *destName, int setModes, int followLinks)
176 BOOL setModes
177)
178{ 172{
179 int rfd; 173 int rfd;
180 int wfd; 174 int wfd;
181 int rcc; 175 int rcc;
182 char buf[BUF_SIZE]; 176 char buf[BUF_SIZE];
183 struct stat statBuf1; 177 struct stat statBuf1;
184 struct stat statBuf2; 178 struct stat statBuf2;
185 struct utimbuf times; 179 struct utimbuf times;
186 180
187 if (stat(srcName, &statBuf1) < 0) 181 if (stat(srcName, &statBuf1) < 0) {
188 { 182 perror(srcName);
189 perror(srcName); 183 return FALSE;
190 184 }
191 return FALSE;
192 }
193 185
194 if (stat(destName, &statBuf2) < 0) 186 if (stat(destName, &statBuf2) < 0) {
195 { 187 statBuf2.st_ino = -1;
196 statBuf2.st_ino = -1; 188 statBuf2.st_dev = -1;
197 statBuf2.st_dev = -1; 189 }
198 }
199 190
200 if ((statBuf1.st_dev == statBuf2.st_dev) && 191 if ((statBuf1.st_dev == statBuf2.st_dev) &&
201 (statBuf1.st_ino == statBuf2.st_ino)) 192 (statBuf1.st_ino == statBuf2.st_ino)) {
202 { 193 fprintf(stderr, "Copying file \"%s\" to itself\n", srcName);
203 fprintf(stderr, "Copying file \"%s\" to itself\n", srcName); 194 return FALSE;
195 }
204 196
205 return FALSE; 197 if (S_ISDIR(statBuf1.st_mode)) {
198 /* Make sure the directory is writable */
199 if (mkdir(destName, 0777777 ^ umask(0))) {
200 perror(destName);
201 return (FALSE);
206 } 202 }
207 203 } else if (S_ISFIFO(statBuf1.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;
215 int link_size;
216
217 link_val = (char *) alloca(PATH_MAX + 2);
218 link_size = readlink(srcName, link_val, PATH_MAX + 1);
219 if (link_size < 0) {
220 perror(srcName);
221 return (FALSE);
222 }
223 link_val[link_size] = '\0';
224 if (symlink(link_val, destName)) {
225 perror(srcName);
226 return (FALSE);
227 }
228 } else {
208 rfd = open(srcName, O_RDONLY); 229 rfd = open(srcName, O_RDONLY);
209 230 if (rfd < 0) {
210 if (rfd < 0) 231 perror(srcName);
211 { 232 return FALSE;
212 perror(srcName);
213
214 return FALSE;
215 } 233 }
216 234
217 wfd = creat(destName, statBuf1.st_mode); 235 wfd = creat(destName, statBuf1.st_mode);
218 236 if (wfd < 0) {
219 if (wfd < 0) 237 perror(destName);
220 { 238 close(rfd);
221 perror(destName); 239 return FALSE;
222 close(rfd);
223
224 return FALSE;
225 }
226
227 while ((rcc = read(rfd, buf, sizeof(buf))) > 0)
228 {
229 if (fullWrite(wfd, buf, rcc) < 0)
230 goto error_exit;
231 } 240 }
232 241
233 if (rcc < 0) 242 while ((rcc = read(rfd, buf, sizeof(buf))) > 0) {
234 { 243 if (fullWrite(wfd, buf, rcc) < 0)
235 perror(srcName);
236 goto error_exit; 244 goto error_exit;
237 } 245 }
246 if (rcc < 0) {
247 perror(srcName);
248 goto error_exit;
249 }
238 250
239 (void) close(rfd); 251 close(rfd);
240
241 if (close(wfd) < 0)
242 {
243 perror(destName);
244 252
245 return FALSE; 253 if (close(wfd) < 0) {
254 perror(destName);
255 return FALSE;
246 } 256 }
257 }
247 258
248 if (setModes) 259 if (setModes == TRUE) {
249 { 260 chmod(destName, statBuf1.st_mode);
250 (void) chmod(destName, statBuf1.st_mode); 261 if (followLinks == TRUE)
251 262 chown(destName, statBuf1.st_uid, statBuf1.st_gid);
252 (void) chown(destName, statBuf1.st_uid, statBuf1.st_gid); 263 else
264 lchown(destName, statBuf1.st_uid, statBuf1.st_gid);
253 265
254 times.actime = statBuf1.st_atime; 266 times.actime = statBuf1.st_atime;
255 times.modtime = statBuf1.st_mtime; 267 times.modtime = statBuf1.st_mtime;
256 268
257 (void) utime(destName, &times); 269 utime(destName, &times);
258 } 270 }
259 271
260 return TRUE; 272 return TRUE;
261 273
262 274
263error_exit: 275 error_exit:
264 close(rfd); 276 close(rfd);
265 close(wfd); 277 close(wfd);
266 278
267 return FALSE; 279 return FALSE;
268} 280}
269 281
270 282
@@ -273,25 +285,25 @@ error_exit:
273 * If the directory name is NULL, then the original fileName is returned. 285 * If the directory name is NULL, then the original fileName is returned.
274 * The built path is in a static area, and is overwritten for each call. 286 * The built path is in a static area, and is overwritten for each call.
275 */ 287 */
276const char * 288char *buildName(const char *dirName, const char *fileName)
277buildName(const char * dirName, const char * fileName)
278{ 289{
279 const char * cp; 290 const char *cp;
280 static char buf[PATH_LEN]; 291 static char buf[PATH_LEN];
281 292
282 if ((dirName == NULL) || (*dirName == '\0')) 293 if ((dirName == NULL) || (*dirName == '\0')) {
283 return fileName; 294 strcpy(buf, fileName);
295 return buf;
296 }
284 297
285 cp = strrchr(fileName, '/'); 298 cp = strrchr(fileName, '/');
286 299
287 if (cp) 300 if (cp)
288 fileName = cp + 1; 301 fileName = cp + 1;
289 302
290 strcpy(buf, dirName); 303 strcpy(buf, dirName);
291 strcat(buf, "/"); 304 strcat(buf, "/");
292 strcat(buf, fileName);
293 305
294 return buf; 306 return buf;
295} 307}
296 308
297 309
@@ -302,41 +314,33 @@ buildName(const char * dirName, const char * fileName)
302 * with an error message given. This does not handle spaces within 314 * with an error message given. This does not handle spaces within
303 * arguments correctly. 315 * arguments correctly.
304 */ 316 */
305BOOL 317int makeString( int argc, const char **argv, char *buf, int bufLen)
306makeString(
307 int argc,
308 const char ** argv,
309 char * buf,
310 int bufLen
311)
312{ 318{
313 int len; 319 int len;
314 320
315 while (argc-- > 0) 321 while (argc-- > 0) {
316 { 322 len = strlen(*argv);
317 len = strlen(*argv);
318 323
319 if (len >= bufLen) 324 if (len >= bufLen) {
320 { 325 fprintf(stderr, "Argument string too long\n");
321 fprintf(stderr, "Argument string too long\n");
322 326
323 return FALSE; 327 return FALSE;
324 } 328 }
325 329
326 strcpy(buf, *argv++); 330 strcpy(buf, *argv++);
327 331
328 buf += len; 332 buf += len;
329 bufLen -= len; 333 bufLen -= len;
330 334
331 if (argc) 335 if (argc)
332 *buf++ = ' '; 336 *buf++ = ' ';
333 337
334 bufLen--; 338 bufLen--;
335 } 339 }
336 340
337 *buf = '\0'; 341 *buf = '\0';
338 342
339 return TRUE; 343 return TRUE;
340} 344}
341 345
342 346
@@ -346,23 +350,22 @@ makeString(
346 * list of chunks which can be freed all at one time. You CAN NOT free 350 * list of chunks which can be freed all at one time. You CAN NOT free
347 * an individual chunk. 351 * an individual chunk.
348 */ 352 */
349char * 353char *getChunk(int size)
350getChunk(int size)
351{ 354{
352 CHUNK * chunk; 355 CHUNK *chunk;
353 356
354 if (size < CHUNK_INIT_SIZE) 357 if (size < CHUNK_INIT_SIZE)
355 size = CHUNK_INIT_SIZE; 358 size = CHUNK_INIT_SIZE;
356 359
357 chunk = (CHUNK *) malloc(size + sizeof(CHUNK) - CHUNK_INIT_SIZE); 360 chunk = (CHUNK *) malloc(size + sizeof(CHUNK) - CHUNK_INIT_SIZE);
358 361
359 if (chunk == NULL) 362 if (chunk == NULL)
360 return NULL; 363 return NULL;
361 364
362 chunk->next = chunkList; 365 chunk->next = chunkList;
363 chunkList = chunk; 366 chunkList = chunk;
364 367
365 return chunk->data; 368 return chunk->data;
366} 369}
367 370
368 371
@@ -371,19 +374,18 @@ getChunk(int size)
371 * The returned string cannot be individually freed, but can only be freed 374 * The returned string cannot be individually freed, but can only be freed
372 * with other strings when freeChunks is called. Returns NULL on failure. 375 * with other strings when freeChunks is called. Returns NULL on failure.
373 */ 376 */
374char * 377char *chunkstrdup(const char *str)
375chunkstrdup(const char * str)
376{ 378{
377 int len; 379 int len;
378 char * newStr; 380 char *newStr;
379 381
380 len = strlen(str) + 1; 382 len = strlen(str) + 1;
381 newStr = getChunk(len); 383 newStr = getChunk(len);
382 384
383 if (newStr) 385 if (newStr)
384 memcpy(newStr, str, len); 386 memcpy(newStr, str, len);
385 387
386 return newStr; 388 return newStr;
387} 389}
388 390
389 391
@@ -391,17 +393,15 @@ chunkstrdup(const char * str)
391 * Free all chunks of memory that had been allocated since the last 393 * Free all chunks of memory that had been allocated since the last
392 * call to this routine. 394 * call to this routine.
393 */ 395 */
394void 396void freeChunks(void)
395freeChunks(void)
396{ 397{
397 CHUNK * chunk; 398 CHUNK *chunk;
398 399
399 while (chunkList) 400 while (chunkList) {
400 { 401 chunk = chunkList;
401 chunk = chunkList; 402 chunkList = chunk->next;
402 chunkList = chunk->next; 403 free((char *) chunk);
403 free((char *) chunk); 404 }
404 }
405} 405}
406 406
407 407
@@ -411,27 +411,25 @@ freeChunks(void)
411 * The string is returned from a static buffer, and so is overwritten for 411 * The string is returned from a static buffer, and so is overwritten for
412 * each call. 412 * each call.
413 */ 413 */
414const char * 414const char *timeString(time_t timeVal)
415timeString(time_t timeVal)
416{ 415{
417 time_t now; 416 time_t now;
418 char * str; 417 char *str;
419 static char buf[26]; 418 static char buf[26];
420 419
421 time(&now); 420 time(&now);
422 421
423 str = ctime(&timeVal); 422 str = ctime(&timeVal);
424 423
425 strcpy(buf, &str[4]); 424 strcpy(buf, &str[4]);
426 buf[12] = '\0'; 425 buf[12] = '\0';
427 426
428 if ((timeVal > now) || (timeVal < now - 365*24*60*60L)) 427 if ((timeVal > now) || (timeVal < now - 365 * 24 * 60 * 60L)) {
429 { 428 strcpy(&buf[7], &str[20]);
430 strcpy(&buf[7], &str[20]); 429 buf[11] = '\0';
431 buf[11] = '\0'; 430 }
432 }
433 431
434 return buf; 432 return buf;
435} 433}
436 434
437 435
@@ -445,88 +443,81 @@ timeString(time_t timeVal)
445 * \c quotes character c 443 * \c quotes character c
446 * Adapted from code written by Ingo Wilken. 444 * Adapted from code written by Ingo Wilken.
447 */ 445 */
448BOOL 446int match(const char *text, const char *pattern)
449match(const char * text, const char * pattern)
450{ 447{
451 const char * retryPat; 448 const char *retryPat;
452 const char * retryText; 449 const char *retryText;
453 int ch; 450 int ch;
454 BOOL found; 451 int found;
455 452
456 retryPat = NULL; 453 retryPat = NULL;
457 retryText = NULL; 454 retryText = NULL;
458 455
459 while (*text || *pattern) 456 while (*text || *pattern) {
460 { 457 ch = *pattern++;
461 ch = *pattern++; 458
462 459 switch (ch) {
463 switch (ch) 460 case '*':
464 { 461 retryPat = pattern;
465 case '*': 462 retryText = text;
466 retryPat = pattern; 463 break;
467 retryText = text; 464
468 break; 465 case '[':
469 466 found = FALSE;
470 case '[': 467
471 found = FALSE; 468 while ((ch = *pattern++) != ']') {
472 469 if (ch == '\\')
473 while ((ch = *pattern++) != ']') 470 ch = *pattern++;
474 { 471
475 if (ch == '\\') 472 if (ch == '\0')
476 ch = *pattern++; 473 return FALSE;
477 474
478 if (ch == '\0') 475 if (*text == ch)
479 return FALSE; 476 found = TRUE;
480 477 }
481 if (*text == ch) 478
482 found = TRUE; 479 if (!found) {
483 } 480 pattern = retryPat;
484 481 text = ++retryText;
485 if (!found) 482 }
486 { 483
487 pattern = retryPat; 484 /* fall into next case */
488 text = ++retryText; 485
489 } 486 case '?':
490 487 if (*text++ == '\0')
491 /* fall into next case */ 488 return FALSE;
492 489
493 case '?': 490 break;
494 if (*text++ == '\0') 491
495 return FALSE; 492 case '\\':
496 493 ch = *pattern++;
497 break; 494
498 495 if (ch == '\0')
499 case '\\': 496 return FALSE;
500 ch = *pattern++; 497
501 498 /* fall into next case */
502 if (ch == '\0') 499
503 return FALSE; 500 default:
504 501 if (*text == ch) {
505 /* fall into next case */ 502 if (*text)
506 503 text++;
507 default: 504 break;
508 if (*text == ch) 505 }
509 { 506
510 if (*text) 507 if (*text) {
511 text++; 508 pattern = retryPat;
512 break; 509 text = ++retryText;
513 } 510 break;
514 511 }
515 if (*text) 512
516 { 513 return FALSE;
517 pattern = retryPat;
518 text = ++retryText;
519 break;
520 }
521
522 return FALSE;
523 }
524
525 if (pattern == NULL)
526 return FALSE;
527 } 514 }
528 515
529 return TRUE; 516 if (pattern == NULL)
517 return FALSE;
518 }
519
520 return TRUE;
530} 521}
531 522
532 523
@@ -535,27 +526,25 @@ match(const char * text, const char * pattern)
535 * This does multiple writes as necessary. 526 * This does multiple writes as necessary.
536 * Returns the amount written, or -1 on an error. 527 * Returns the amount written, or -1 on an error.
537 */ 528 */
538int 529int fullWrite(int fd, const char *buf, int len)
539fullWrite(int fd, const char * buf, int len)
540{ 530{
541 int cc; 531 int cc;
542 int total; 532 int total;
543 533
544 total = 0; 534 total = 0;
545 535
546 while (len > 0) 536 while (len > 0) {
547 { 537 cc = write(fd, buf, len);
548 cc = write(fd, buf, len);
549 538
550 if (cc < 0) 539 if (cc < 0)
551 return -1; 540 return -1;
552 541
553 buf += cc; 542 buf += cc;
554 total+= cc; 543 total += cc;
555 len -= cc; 544 len -= cc;
556 } 545 }
557 546
558 return total; 547 return total;
559} 548}
560 549
561 550
@@ -565,30 +554,28 @@ fullWrite(int fd, const char * buf, int len)
565 * Returns the amount read, or -1 on an error. 554 * Returns the amount read, or -1 on an error.
566 * A short read is returned on an end of file. 555 * A short read is returned on an end of file.
567 */ 556 */
568int 557int fullRead(int fd, char *buf, int len)
569fullRead(int fd, char * buf, int len)
570{ 558{
571 int cc; 559 int cc;
572 int total; 560 int total;
573 561
574 total = 0; 562 total = 0;
575 563
576 while (len > 0) 564 while (len > 0) {
577 { 565 cc = read(fd, buf, len);
578 cc = read(fd, buf, len);
579 566
580 if (cc < 0) 567 if (cc < 0)
581 return -1; 568 return -1;
582 569
583 if (cc == 0) 570 if (cc == 0)
584 break; 571 break;
585 572
586 buf += cc; 573 buf += cc;
587 total+= cc; 574 total += cc;
588 len -= cc; 575 len -= cc;
589 } 576 }
590 577
591 return total; 578 return total;
592} 579}
593 580
594 581
@@ -598,84 +585,82 @@ fullRead(int fd, char * buf, int len)
598 * by the fileAction and dirAction function pointers). 585 * by the fileAction and dirAction function pointers).
599 */ 586 */
600int 587int
601recursiveAction( const char *fileName, BOOL recurse, BOOL followLinks, 588recursiveAction(const char *fileName, int recurse, int followLinks,
602 int (*fileAction)(const char* fileName), 589 int (*fileAction) (const char *fileName),
603 int (*dirAction)(const char* fileName)) 590 int (*dirAction) (const char *fileName))
604{ 591{
605 int status; 592 int status;
606 struct stat statbuf; 593 struct stat statbuf;
607 struct dirent* next; 594 struct dirent *next;
608
609 if (!recurse && S_ISDIR(statbuf.st_mode)) {
610 if (dirAction==NULL)
611 return(TRUE);
612 else
613 return(dirAction(fileName));
614 } else {
615 if (fileAction==NULL)
616 return(TRUE);
617 else
618 return(fileAction(fileName));
619 }
620 595
621 if (followLinks) 596 if (followLinks)
622 status = stat(fileName, &statbuf);
623 else
624 status = lstat(fileName, &statbuf); 597 status = lstat(fileName, &statbuf);
625 598 else
599 status = stat(fileName, &statbuf);
626 if (status < 0) { 600 if (status < 0) {
627 perror(fileName); 601 perror(fileName);
628 return( FALSE); 602 return (FALSE);
603 }
604
605 if (recurse == FALSE) {
606 if (S_ISDIR(statbuf.st_mode)) {
607 if (dirAction == NULL)
608 return (TRUE);
609 else
610 return (dirAction(fileName));
611 } else {
612 if (fileAction == NULL)
613 return (TRUE);
614 else
615 return (fileAction(fileName));
616 }
629 } 617 }
630 618
631 if (S_ISDIR(statbuf.st_mode)) { 619 if (S_ISDIR(statbuf.st_mode)) {
632 DIR *dir; 620 DIR *dir;
621 fprintf(stderr, "Dir: %s\n", fileName);
633 dir = opendir(fileName); 622 dir = opendir(fileName);
634 if (!dir) { 623 if (!dir) {
635 perror(fileName); 624 perror(fileName);
636 return(FALSE); 625 return (FALSE);
626 }
627 if (dirAction != NULL) {
628 status = dirAction(fileName);
629 if (status == FALSE) {
630 perror("cp");
631 return (FALSE);
632 }
637 } 633 }
638 while ((next = readdir (dir)) != NULL) { 634 while ((next = readdir(dir)) != NULL) {
639 char nextFile[NAME_MAX]; 635 char nextFile[NAME_MAX];
640 if ( (strcmp(next->d_name, "..") == 0) || (strcmp(next->d_name, ".") == 0) ) { 636 if ((strcmp(next->d_name, "..") == 0)
641 continue; 637 || (strcmp(next->d_name, ".") == 0)) {
642 } 638 continue;
643 sprintf(nextFile, "%s/%s", fileName, next->d_name); 639 }
644 status = recursiveAction(nextFile, TRUE, followLinks, fileAction, dirAction); 640 sprintf(nextFile, "%s/%s", fileName, next->d_name);
645 if (status < 0) { 641 status =
646 closedir(dir); 642 recursiveAction(nextFile, TRUE, followLinks, fileAction,
647 return(FALSE); 643 dirAction);
648 } 644 if (status < 0) {
645 closedir(dir);
646 return (FALSE);
647 }
649 } 648 }
650 status = closedir (dir); 649 status = closedir(dir);
651 if (status < 0) { 650 if (status < 0) {
652 perror(fileName); 651 perror(fileName);
653 return( FALSE); 652 return (FALSE);
654 } 653 }
655 if (dirAction==NULL) 654 } else {
656 return(TRUE); 655 fprintf(stderr, "File: %s\n", fileName);
657 else 656 if (fileAction == NULL)
658 return(dirAction(fileName)); 657 return (TRUE);
659 }
660 else {
661 if (fileAction==NULL)
662 return(TRUE);
663 else 658 else
664 return(fileAction(fileName)); 659 return (fileAction(fileName));
665 } 660 }
661 return (TRUE);
666} 662}
667 663
668 664
669 665
670/* END CODE */ 666/* END CODE */
671
672
673
674
675
676
677
678
679
680
681