summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>1999-10-07 08:30:23 +0000
committerEric Andersen <andersen@codepoet.org>1999-10-07 08:30:23 +0000
commit596e5469d00fa4a74d8a3b1ebfaae20ce8dc3afe (patch)
tree4d48d109e66c5197bb27c8215062aab28d385509
parent5c3199e0a519695c367b773e179b5458670f452b (diff)
downloadbusybox-w32-596e5469d00fa4a74d8a3b1ebfaae20ce8dc3afe.tar.gz
busybox-w32-596e5469d00fa4a74d8a3b1ebfaae20ce8dc3afe.tar.bz2
busybox-w32-596e5469d00fa4a74d8a3b1ebfaae20ce8dc3afe.zip
more stuff
-rw-r--r--Makefile2
-rw-r--r--applets/busybox.c8
-rw-r--r--busybox.c8
-rw-r--r--busybox.def.h9
-rw-r--r--coreutils/df.c9
-rw-r--r--coreutils/mv.c104
-rw-r--r--coreutils/touch.c87
-rw-r--r--df.c9
-rw-r--r--findutils/grep.c251
-rw-r--r--grep.c251
-rw-r--r--internal.h2
-rw-r--r--mount.c604
-rw-r--r--mv.c104
-rw-r--r--touch.c87
-rw-r--r--util-linux/mount.c604
15 files changed, 1015 insertions, 1124 deletions
diff --git a/Makefile b/Makefile
index 2b999f088..cf182097e 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,7 @@ BINDIR=$(prefix)
23 23
24LDFLAGS= -s 24LDFLAGS= -s
25LIBRARIES=-lc 25LIBRARIES=-lc
26OBJECTS=$(shell ./busybox.sh) utility.o 26OBJECTS=$(shell ./busybox.sh)
27CFLAGS+= -DBB_VER='"$(VERSION)"' 27CFLAGS+= -DBB_VER='"$(VERSION)"'
28CFLAGS+= -DBB_BT='"$(BUILDTIME)"' 28CFLAGS+= -DBB_BT='"$(BUILDTIME)"'
29 29
diff --git a/applets/busybox.c b/applets/busybox.c
index c36bc2626..15e1bef87 100644
--- a/applets/busybox.c
+++ b/applets/busybox.c
@@ -111,7 +111,7 @@ static const struct Applet applets[] = {
111 {"mt", mt_main}, 111 {"mt", mt_main},
112#endif 112#endif
113#ifdef BB_MV //bin 113#ifdef BB_MV //bin
114 {"mv", dyadic_main}, 114 {"mv", mv_main},
115#endif 115#endif
116#ifdef BB_PRINTF //usr/bin 116#ifdef BB_PRINTF //usr/bin
117 {"printf", printf_main}, 117 {"printf", printf_main},
@@ -144,7 +144,7 @@ static const struct Applet applets[] = {
144 {"sync", sync_main}, 144 {"sync", sync_main},
145#endif 145#endif
146#ifdef BB_TOUCH //usr/bin 146#ifdef BB_TOUCH //usr/bin
147 {"touch", monadic_main}, 147 {"touch", touch_main},
148#endif 148#endif
149#ifdef BB_TRUE //bin 149#ifdef BB_TRUE //bin
150 {"true", true_main}, 150 {"true", true_main},
@@ -208,8 +208,8 @@ int busybox_main(int argc, char **argv)
208 const struct Applet *a = applets; 208 const struct Applet *a = applets;
209 fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n", 209 fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n",
210 BB_VER, BB_BT); 210 BB_VER, BB_BT);
211 fprintf(stderr, "Usage: busybox [function] [arguments]...\n"); 211 fprintf(stderr, "\nUsage:\t[function] [arguments]...\n");
212 fprintf(stderr, "or\nUsage: [function] [arguments]...\n"); 212 fprintf(stderr, "\tbusybox [function] [arguments]...\n");
213 fprintf(stderr, 213 fprintf(stderr,
214 "\n\tMost people will create a symlink to busybox for each\n" 214 "\n\tMost people will create a symlink to busybox for each\n"
215 "\tfunction name, and busybox will act like whatever you invoke it as.\n"); 215 "\tfunction name, and busybox will act like whatever you invoke it as.\n");
diff --git a/busybox.c b/busybox.c
index c36bc2626..15e1bef87 100644
--- a/busybox.c
+++ b/busybox.c
@@ -111,7 +111,7 @@ static const struct Applet applets[] = {
111 {"mt", mt_main}, 111 {"mt", mt_main},
112#endif 112#endif
113#ifdef BB_MV //bin 113#ifdef BB_MV //bin
114 {"mv", dyadic_main}, 114 {"mv", mv_main},
115#endif 115#endif
116#ifdef BB_PRINTF //usr/bin 116#ifdef BB_PRINTF //usr/bin
117 {"printf", printf_main}, 117 {"printf", printf_main},
@@ -144,7 +144,7 @@ static const struct Applet applets[] = {
144 {"sync", sync_main}, 144 {"sync", sync_main},
145#endif 145#endif
146#ifdef BB_TOUCH //usr/bin 146#ifdef BB_TOUCH //usr/bin
147 {"touch", monadic_main}, 147 {"touch", touch_main},
148#endif 148#endif
149#ifdef BB_TRUE //bin 149#ifdef BB_TRUE //bin
150 {"true", true_main}, 150 {"true", true_main},
@@ -208,8 +208,8 @@ int busybox_main(int argc, char **argv)
208 const struct Applet *a = applets; 208 const struct Applet *a = applets;
209 fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n", 209 fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n",
210 BB_VER, BB_BT); 210 BB_VER, BB_BT);
211 fprintf(stderr, "Usage: busybox [function] [arguments]...\n"); 211 fprintf(stderr, "\nUsage:\t[function] [arguments]...\n");
212 fprintf(stderr, "or\nUsage: [function] [arguments]...\n"); 212 fprintf(stderr, "\tbusybox [function] [arguments]...\n");
213 fprintf(stderr, 213 fprintf(stderr,
214 "\n\tMost people will create a symlink to busybox for each\n" 214 "\n\tMost people will create a symlink to busybox for each\n"
215 "\tfunction name, and busybox will act like whatever you invoke it as.\n"); 215 "\tfunction name, and busybox will act like whatever you invoke it as.\n");
diff --git a/busybox.def.h b/busybox.def.h
index 111aca63d..c78deebc2 100644
--- a/busybox.def.h
+++ b/busybox.def.h
@@ -30,7 +30,6 @@
30//#define BB_LOADKMAP 30//#define BB_LOADKMAP
31////#define BB_LOSETUP 31////#define BB_LOSETUP
32#define BB_LS 32#define BB_LS
33//#define BB_MAIN
34//#define BB_MAKEDEVS 33//#define BB_MAKEDEVS
35////#define BB_MATH 34////#define BB_MATH
36//#define BB_MKDIR 35//#define BB_MKDIR
@@ -39,9 +38,9 @@
39//#define BB_MNC 38//#define BB_MNC
40//#define BB_MONADIC 39//#define BB_MONADIC
41#define BB_MORE 40#define BB_MORE
42//#define BB_MOUNT 41#define BB_MOUNT
43////#define BB_MT 42////#define BB_MT
44//#define BB_MV 43#define BB_MV
45//#define BB_POSTPROCESS 44//#define BB_POSTPROCESS
46//#define BB_PRINTF 45//#define BB_PRINTF
47//#define BB_PWD 46//#define BB_PWD
@@ -53,10 +52,10 @@
53//#define BB_SWAPON 52//#define BB_SWAPON
54//#define BB_SYNC 53//#define BB_SYNC
55#define BB_TAR 54#define BB_TAR
56//#define BB_TOUCH 55#define BB_TOUCH
57#define BB_TRUE 56#define BB_TRUE
58//#define BB_UMOUNT 57//#define BB_UMOUNT
59//#define BB_UPDATE 58//#define BB_UPDATE
60//#define BB_UTILITY 59#define BB_UTILITY
61#define BB_ZCAT 60#define BB_ZCAT
62#define BB_GZIP 61#define BB_GZIP
diff --git a/coreutils/df.c b/coreutils/df.c
index 354b2a7ca..8cc93814b 100644
--- a/coreutils/df.c
+++ b/coreutils/df.c
@@ -3,6 +3,7 @@
3#include <mntent.h> 3#include <mntent.h>
4#include <sys/stat.h> 4#include <sys/stat.h>
5#include <sys/vfs.h> 5#include <sys/vfs.h>
6#include <fstab.h>
6 7
7const char df_usage[] = "df [filesystem ...]\n" 8const char df_usage[] = "df [filesystem ...]\n"
8"\n" 9"\n"
@@ -10,7 +11,7 @@ const char df_usage[] = "df [filesystem ...]\n"
10 11
11 12
12static int 13static int
13df(const char * device, const char * mountPoint) 14df(char* device, const char * mountPoint)
14{ 15{
15 struct statfs s; 16 struct statfs s;
16 long blocks_used; 17 long blocks_used;
@@ -25,6 +26,8 @@ df(const char * device, const char * mountPoint)
25 blocks_used = s.f_blocks - s.f_bfree; 26 blocks_used = s.f_blocks - s.f_bfree;
26 blocks_percent_used = (long) 27 blocks_percent_used = (long)
27 (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5); 28 (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5);
29 if ( strcmp(device, "/dev/root")==0)
30 device=(getfsfile ("/"))->fs_spec;
28 31
29 printf( 32 printf(
30 "%-20s %9ld %9ld %9ld %3ld%% %s\n", 33 "%-20s %9ld %9ld %9ld %3ld%% %s\n",
@@ -75,7 +78,7 @@ df_main(int argc, char * * argv)
75 } 78 }
76 79
77 while ( (mountEntry = getmntent (mountTable))) { 80 while ( (mountEntry = getmntent (mountTable))) {
78 int status=df(mountEntry->mnt_fsname ,mountEntry->mnt_dir); 81 int status=df(mountEntry->mnt_fsname, mountEntry->mnt_dir);
79 if (status) 82 if (status)
80 return status; 83 return status;
81 } 84 }
@@ -129,3 +132,5 @@ findMountPoint(const char* name, const char* table)
129 endmntent(mountTable); 132 endmntent(mountTable);
130 return mountEntry; 133 return mountEntry;
131} 134}
135
136
diff --git a/coreutils/mv.c b/coreutils/mv.c
index 22c4a1207..610040d92 100644
--- a/coreutils/mv.c
+++ b/coreutils/mv.c
@@ -1,38 +1,84 @@
1/*
2 * Mini mv 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>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <fcntl.h>
27#include <utime.h>
3#include <errno.h> 28#include <errno.h>
4 29
5const char mv_usage[] = "mv source-file destination-file\n" 30const char mv_usage[] = "source-file [source-file ...] destination-file\n"
6"\t\tmv source-file [source-file ...] destination-directory\n" 31 "\n" "\tMove the source files to the destination.\n" "\n";
7"\n" 32
8"\tMove the source files to the destination.\n"
9"\n";
10 33
11extern int 34
12mv_fn(const struct FileInfo * i) 35extern int mv_main (int argc, char **argv)
13{ 36{
14 struct stat destination_stat; 37 const char *srcName;
15 char d[1024]; 38 const char *destName;
16 struct FileInfo n; 39 const char *lastArg;
17 40 BOOL dirFlag;
18 if ( stat(i->destination, &destination_stat) == 0 ) { 41
19 if ( i->stat.st_ino == destination_stat.st_ino 42 if (argc < 3) {
20 && i->stat.st_dev == destination_stat.st_dev ) 43 fprintf (stderr, "Usage: %s %s", *argv, mv_usage);
21 return 0; /* Move file to itself. */ 44 return (FALSE);
22 } 45 }
23 if ( (destination_stat.st_mode & S_IFMT) == S_IFDIR ) { 46 lastArg = argv[argc - 1];
24 n = *i; 47
25 n.destination = join_paths(d, i->destination, basename(i->source)); 48 dirFlag = isDirectory (lastArg);
26 i = &n; 49
50 if ((argc > 3) && !dirFlag) {
51 fprintf (stderr, "%s: not a directory\n", lastArg);
52
53 return (FALSE);
54 }
55
56 while (argc-- > 2) {
57 srcName = *(++argv);
58
59 if (access (srcName, 0) < 0) {
60 perror (srcName);
61 continue;
27 } 62 }
28 if ( rename(i->source, i->destination) == 0 ) 63
29 return 0; 64 destName = lastArg;
30 else if ( errno == EXDEV && is_a_directory(i->source) ) { 65
31 fprintf(stderr 66 if (dirFlag)
32 ,"%s: Can't move directory across filesystems.\n" 67 destName = buildName (destName, srcName);
33 ,i->source); 68
34 return 1; 69 if (rename (srcName, destName) >= 0)
70 continue;
71
72 if (errno != EXDEV) {
73 perror (destName);
74 continue;
35 } 75 }
36 else 76
37 return cp_fn(i); 77 if (!copyFile (srcName, destName, TRUE))
78 continue;
79
80 if (unlink (srcName) < 0)
81 perror (srcName);
82 }
83 return (TRUE);
38} 84}
diff --git a/coreutils/touch.c b/coreutils/touch.c
index ca4b98108..8dac10294 100644
--- a/coreutils/touch.c
+++ b/coreutils/touch.c
@@ -1,20 +1,85 @@
1/*
2 * Mini touch 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 <sys/types.h>
3#include <stdio.h> 23#include <stdio.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <fcntl.h>
4#include <utime.h> 27#include <utime.h>
28#include <errno.h>
29
5 30
6const char touch_usage[] = "touch [-c] file [file ...]\n" 31const char touch_usage[] = "touch [-c] file [file ...]\n\n"
7"\n"
8"\tUpdate the last-modified date on the given file[s].\n"; 32"\tUpdate the last-modified date on the given file[s].\n";
9 33
10extern int 34
11touch_fn(const struct FileInfo * i) 35
36extern int
37touch_main(int argc, char **argv)
12{ 38{
13 if ( (utime(i->source, 0) != 0) && (i->create != 1) ) { 39 int fd;
14 if ( fopen(i->source, "w") == NULL ) { 40 int create=TRUE;
15 name_and_error(i->source); 41
16 return 1; 42 if (argc < 2) {
17 } 43 fprintf(stderr, "Usage: %s %s", *argv, touch_usage);
44 exit( FALSE);
45 }
46 argc--;
47 argv++;
48
49 /* Parse options */
50 while (**argv == '-') {
51 while (*++(*argv)) switch (**argv) {
52 case 'c':
53 create = FALSE;
54 break;
55 default:
56 fprintf(stderr, "Unknown option: %c\n", **argv);
57 exit( FALSE);
18 } 58 }
19 return 0; 59 argc--;
60 argv++;
61 }
62
63 fd = open (*argv, (create==FALSE)? O_RDWR : O_RDWR | O_CREAT, 0644);
64 if (fd < 0 ) {
65 if (create==FALSE && errno == ENOENT)
66 exit( TRUE);
67 else {
68 perror("touch");
69 exit( FALSE);
70 }
71 }
72 close( fd);
73 if (utime (*argv, NULL)) {
74 perror("touch");
75 exit( FALSE);
76 }
77 else
78 exit( TRUE);
20} 79}
80
81
82
83
84
85
diff --git a/df.c b/df.c
index 354b2a7ca..8cc93814b 100644
--- a/df.c
+++ b/df.c
@@ -3,6 +3,7 @@
3#include <mntent.h> 3#include <mntent.h>
4#include <sys/stat.h> 4#include <sys/stat.h>
5#include <sys/vfs.h> 5#include <sys/vfs.h>
6#include <fstab.h>
6 7
7const char df_usage[] = "df [filesystem ...]\n" 8const char df_usage[] = "df [filesystem ...]\n"
8"\n" 9"\n"
@@ -10,7 +11,7 @@ const char df_usage[] = "df [filesystem ...]\n"
10 11
11 12
12static int 13static int
13df(const char * device, const char * mountPoint) 14df(char* device, const char * mountPoint)
14{ 15{
15 struct statfs s; 16 struct statfs s;
16 long blocks_used; 17 long blocks_used;
@@ -25,6 +26,8 @@ df(const char * device, const char * mountPoint)
25 blocks_used = s.f_blocks - s.f_bfree; 26 blocks_used = s.f_blocks - s.f_bfree;
26 blocks_percent_used = (long) 27 blocks_percent_used = (long)
27 (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5); 28 (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5);
29 if ( strcmp(device, "/dev/root")==0)
30 device=(getfsfile ("/"))->fs_spec;
28 31
29 printf( 32 printf(
30 "%-20s %9ld %9ld %9ld %3ld%% %s\n", 33 "%-20s %9ld %9ld %9ld %3ld%% %s\n",
@@ -75,7 +78,7 @@ df_main(int argc, char * * argv)
75 } 78 }
76 79
77 while ( (mountEntry = getmntent (mountTable))) { 80 while ( (mountEntry = getmntent (mountTable))) {
78 int status=df(mountEntry->mnt_fsname ,mountEntry->mnt_dir); 81 int status=df(mountEntry->mnt_fsname, mountEntry->mnt_dir);
79 if (status) 82 if (status)
80 return status; 83 return status;
81 } 84 }
@@ -129,3 +132,5 @@ findMountPoint(const char* name, const char* table)
129 endmntent(mountTable); 132 endmntent(mountTable);
130 return mountEntry; 133 return mountEntry;
131} 134}
135
136
diff --git a/findutils/grep.c b/findutils/grep.c
index a07feda03..11198b851 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -23,187 +23,174 @@
23 23
24 24
25const char grep_usage[] = 25const char grep_usage[] =
26"Search the input file(s) for lines matching the given pattern.\n" 26 "Search the input file(s) for lines matching the given pattern.\n"
27"\tI search stdin if no files are given.\n" 27 "\tI search stdin if no files are given.\n"
28"\tI can't grok full regular expressions.\n" 28 "\tI can't grok full regular expressions.\n"
29"usage: grep [in] PATTERN [FILES]...\n" 29 "usage: grep [in] PATTERN [FILES]...\n"
30"\ti=ignore case, n=list line numbers\n"; 30 "\ti=ignore case, n=list line numbers\n";
31 31
32 32
33 33
34static BOOL search 34static BOOL search (const char *string, const char *word, BOOL ignoreCase);
35 (const char * string, const char * word, BOOL ignoreCase);
36 35
37 36
38extern int 37extern int grep_main (int argc, char **argv)
39grep_main(int argc, char ** argv)
40{ 38{
41 FILE * fp; 39 FILE *fp;
42 const char * word; 40 const char *word;
43 const char * name; 41 const char *name;
44 const char * cp; 42 const char *cp;
45 BOOL tellName; 43 BOOL tellName;
46 BOOL ignoreCase; 44 BOOL ignoreCase;
47 BOOL tellLine; 45 BOOL tellLine;
48 long line; 46 long line;
49 char buf[BUF_SIZE]; 47 char buf[BUF_SIZE];
50 48
51 ignoreCase = FALSE; 49 ignoreCase = FALSE;
52 tellLine = FALSE; 50 tellLine = FALSE;
53 51
52 argc--;
53 argv++;
54 if (argc < 1) {
55 fprintf (stderr, "%s", grep_usage);
56 return 1;
57 }
58
59 if (**argv == '-') {
54 argc--; 60 argc--;
55 argv++; 61 cp = *argv++;
56 if (argc < 1)
57 {
58 fprintf(stderr, "%s", grep_usage);
59 return 1;
60 }
61 62
62 if (**argv == '-') 63 while (*++cp)
63 { 64 switch (*cp) {
64 argc--; 65 case 'i':
65 cp = *argv++; 66 ignoreCase = TRUE;
66 67 break;
67 while (*++cp) switch (*cp)
68 {
69 case 'i':
70 ignoreCase = TRUE;
71 break;
72
73 case 'n':
74 tellLine = TRUE;
75 break;
76
77 default:
78 fprintf(stderr, "Unknown option\n");
79 return 1;
80 }
81 }
82 68
83 word = *argv++; 69 case 'n':
84 argc--; 70 tellLine = TRUE;
71 break;
85 72
86 tellName = (argc > 1); 73 default:
74 fprintf (stderr, "Unknown option\n");
75 return 1;
76 }
77 }
87 78
88 while (argc-- > 0) 79 word = *argv++;
89 { 80 argc--;
90 name = *argv++;
91 81
92 fp = fopen(name, "r"); 82 tellName = (argc > 1);
93 83
94 if (fp == NULL) 84 while (argc-- > 0) {
95 { 85 name = *argv++;
96 perror(name);
97 86
98 continue; 87 fp = fopen (name, "r");
99 }
100 88
101 line = 0; 89 if (fp == NULL) {
90 perror (name);
102 91
103 while (fgets(buf, sizeof(buf), fp)) 92 continue;
104 { 93 }
105 line++;
106 94
107 cp = &buf[strlen(buf) - 1]; 95 line = 0;
108 96
109 if (*cp != '\n') 97 while (fgets (buf, sizeof (buf), fp)) {
110 fprintf(stderr, "%s: Line too long\n", name); 98 line++;
111 99
112 if (search(buf, word, ignoreCase)) 100 cp = &buf[strlen (buf) - 1];
113 {
114 if (tellName)
115 printf("%s: ", name);
116 101
117 if (tellLine) 102 if (*cp != '\n')
118 printf("%ld: ", line); 103 fprintf (stderr, "%s: Line too long\n", name);
119 104
120 fputs(buf, stdout); 105 if (search (buf, word, ignoreCase)) {
121 } 106 if (tellName)
122 } 107 printf ("%s: ", name);
123 108
124 if (ferror(fp)) 109 if (tellLine)
125 perror(name); 110 printf ("%ld: ", line);
126 111
127 fclose(fp); 112 fputs (buf, stdout);
113 }
128 } 114 }
129 return 0; 115
116 if (ferror (fp))
117 perror (name);
118
119 fclose (fp);
120 }
121 return 0;
130} 122}
131 123
132 124
133/* 125/*
134 * See if the specified word is found in the specified string. 126 * See if the specified word is found in the specified string.
135 */ 127 */
136static BOOL 128static BOOL search (const char *string, const char *word, BOOL ignoreCase)
137search(const char * string, const char * word, BOOL ignoreCase)
138{ 129{
139 const char * cp1; 130 const char *cp1;
140 const char * cp2; 131 const char *cp2;
141 int len; 132 int len;
142 int lowFirst; 133 int lowFirst;
143 int ch1; 134 int ch1;
144 int ch2; 135 int ch2;
145 136
146 len = strlen(word); 137 len = strlen (word);
147 138
148 if (!ignoreCase) 139 if (!ignoreCase) {
149 { 140 while (TRUE) {
150 while (TRUE) 141 string = strchr (string, word[0]);
151 {
152 string = strchr(string, word[0]);
153 142
154 if (string == NULL) 143 if (string == NULL)
155 return FALSE; 144 return FALSE;
156 145
157 if (memcmp(string, word, len) == 0) 146 if (memcmp (string, word, len) == 0)
158 return TRUE; 147 return TRUE;
159 148
160 string++; 149 string++;
161 }
162 } 150 }
151 }
163 152
164 /* 153 /*
165 * Here if we need to check case independence. 154 * Here if we need to check case independence.
166 * Do the search by lower casing both strings. 155 * Do the search by lower casing both strings.
167 */ 156 */
168 lowFirst = *word; 157 lowFirst = *word;
169 158
170 if (isupper(lowFirst)) 159 if (isupper (lowFirst))
171 lowFirst = tolower(lowFirst); 160 lowFirst = tolower (lowFirst);
172 161
173 while (TRUE) 162 while (TRUE) {
174 { 163 while (*string && (*string != lowFirst) &&
175 while (*string && (*string != lowFirst) && 164 (!isupper (*string) || (tolower (*string) != lowFirst))) {
176 (!isupper(*string) || (tolower(*string) != lowFirst))) 165 string++;
177 { 166 }
178 string++;
179 }
180
181 if (*string == '\0')
182 return FALSE;
183 167
184 cp1 = string; 168 if (*string == '\0')
185 cp2 = word; 169 return FALSE;
186 170
187 do 171 cp1 = string;
188 { 172 cp2 = word;
189 if (*cp2 == '\0')
190 return TRUE;
191 173
192 ch1 = *cp1++; 174 do {
175 if (*cp2 == '\0')
176 return TRUE;
193 177
194 if (isupper(ch1)) 178 ch1 = *cp1++;
195 ch1 = tolower(ch1);
196 179
197 ch2 = *cp2++; 180 if (isupper (ch1))
181 ch1 = tolower (ch1);
198 182
199 if (isupper(ch2)) 183 ch2 = *cp2++;
200 ch2 = tolower(ch2);
201 184
202 } 185 if (isupper (ch2))
203 while (ch1 == ch2); 186 ch2 = tolower (ch2);
204 187
205 string++;
206 } 188 }
189 while (ch1 == ch2);
190
191 string++;
192 }
193 return (TRUE);
207} 194}
208 195
209#endif 196#endif
diff --git a/grep.c b/grep.c
index a07feda03..11198b851 100644
--- a/grep.c
+++ b/grep.c
@@ -23,187 +23,174 @@
23 23
24 24
25const char grep_usage[] = 25const char grep_usage[] =
26"Search the input file(s) for lines matching the given pattern.\n" 26 "Search the input file(s) for lines matching the given pattern.\n"
27"\tI search stdin if no files are given.\n" 27 "\tI search stdin if no files are given.\n"
28"\tI can't grok full regular expressions.\n" 28 "\tI can't grok full regular expressions.\n"
29"usage: grep [in] PATTERN [FILES]...\n" 29 "usage: grep [in] PATTERN [FILES]...\n"
30"\ti=ignore case, n=list line numbers\n"; 30 "\ti=ignore case, n=list line numbers\n";
31 31
32 32
33 33
34static BOOL search 34static BOOL search (const char *string, const char *word, BOOL ignoreCase);
35 (const char * string, const char * word, BOOL ignoreCase);
36 35
37 36
38extern int 37extern int grep_main (int argc, char **argv)
39grep_main(int argc, char ** argv)
40{ 38{
41 FILE * fp; 39 FILE *fp;
42 const char * word; 40 const char *word;
43 const char * name; 41 const char *name;
44 const char * cp; 42 const char *cp;
45 BOOL tellName; 43 BOOL tellName;
46 BOOL ignoreCase; 44 BOOL ignoreCase;
47 BOOL tellLine; 45 BOOL tellLine;
48 long line; 46 long line;
49 char buf[BUF_SIZE]; 47 char buf[BUF_SIZE];
50 48
51 ignoreCase = FALSE; 49 ignoreCase = FALSE;
52 tellLine = FALSE; 50 tellLine = FALSE;
53 51
52 argc--;
53 argv++;
54 if (argc < 1) {
55 fprintf (stderr, "%s", grep_usage);
56 return 1;
57 }
58
59 if (**argv == '-') {
54 argc--; 60 argc--;
55 argv++; 61 cp = *argv++;
56 if (argc < 1)
57 {
58 fprintf(stderr, "%s", grep_usage);
59 return 1;
60 }
61 62
62 if (**argv == '-') 63 while (*++cp)
63 { 64 switch (*cp) {
64 argc--; 65 case 'i':
65 cp = *argv++; 66 ignoreCase = TRUE;
66 67 break;
67 while (*++cp) switch (*cp)
68 {
69 case 'i':
70 ignoreCase = TRUE;
71 break;
72
73 case 'n':
74 tellLine = TRUE;
75 break;
76
77 default:
78 fprintf(stderr, "Unknown option\n");
79 return 1;
80 }
81 }
82 68
83 word = *argv++; 69 case 'n':
84 argc--; 70 tellLine = TRUE;
71 break;
85 72
86 tellName = (argc > 1); 73 default:
74 fprintf (stderr, "Unknown option\n");
75 return 1;
76 }
77 }
87 78
88 while (argc-- > 0) 79 word = *argv++;
89 { 80 argc--;
90 name = *argv++;
91 81
92 fp = fopen(name, "r"); 82 tellName = (argc > 1);
93 83
94 if (fp == NULL) 84 while (argc-- > 0) {
95 { 85 name = *argv++;
96 perror(name);
97 86
98 continue; 87 fp = fopen (name, "r");
99 }
100 88
101 line = 0; 89 if (fp == NULL) {
90 perror (name);
102 91
103 while (fgets(buf, sizeof(buf), fp)) 92 continue;
104 { 93 }
105 line++;
106 94
107 cp = &buf[strlen(buf) - 1]; 95 line = 0;
108 96
109 if (*cp != '\n') 97 while (fgets (buf, sizeof (buf), fp)) {
110 fprintf(stderr, "%s: Line too long\n", name); 98 line++;
111 99
112 if (search(buf, word, ignoreCase)) 100 cp = &buf[strlen (buf) - 1];
113 {
114 if (tellName)
115 printf("%s: ", name);
116 101
117 if (tellLine) 102 if (*cp != '\n')
118 printf("%ld: ", line); 103 fprintf (stderr, "%s: Line too long\n", name);
119 104
120 fputs(buf, stdout); 105 if (search (buf, word, ignoreCase)) {
121 } 106 if (tellName)
122 } 107 printf ("%s: ", name);
123 108
124 if (ferror(fp)) 109 if (tellLine)
125 perror(name); 110 printf ("%ld: ", line);
126 111
127 fclose(fp); 112 fputs (buf, stdout);
113 }
128 } 114 }
129 return 0; 115
116 if (ferror (fp))
117 perror (name);
118
119 fclose (fp);
120 }
121 return 0;
130} 122}
131 123
132 124
133/* 125/*
134 * See if the specified word is found in the specified string. 126 * See if the specified word is found in the specified string.
135 */ 127 */
136static BOOL 128static BOOL search (const char *string, const char *word, BOOL ignoreCase)
137search(const char * string, const char * word, BOOL ignoreCase)
138{ 129{
139 const char * cp1; 130 const char *cp1;
140 const char * cp2; 131 const char *cp2;
141 int len; 132 int len;
142 int lowFirst; 133 int lowFirst;
143 int ch1; 134 int ch1;
144 int ch2; 135 int ch2;
145 136
146 len = strlen(word); 137 len = strlen (word);
147 138
148 if (!ignoreCase) 139 if (!ignoreCase) {
149 { 140 while (TRUE) {
150 while (TRUE) 141 string = strchr (string, word[0]);
151 {
152 string = strchr(string, word[0]);
153 142
154 if (string == NULL) 143 if (string == NULL)
155 return FALSE; 144 return FALSE;
156 145
157 if (memcmp(string, word, len) == 0) 146 if (memcmp (string, word, len) == 0)
158 return TRUE; 147 return TRUE;
159 148
160 string++; 149 string++;
161 }
162 } 150 }
151 }
163 152
164 /* 153 /*
165 * Here if we need to check case independence. 154 * Here if we need to check case independence.
166 * Do the search by lower casing both strings. 155 * Do the search by lower casing both strings.
167 */ 156 */
168 lowFirst = *word; 157 lowFirst = *word;
169 158
170 if (isupper(lowFirst)) 159 if (isupper (lowFirst))
171 lowFirst = tolower(lowFirst); 160 lowFirst = tolower (lowFirst);
172 161
173 while (TRUE) 162 while (TRUE) {
174 { 163 while (*string && (*string != lowFirst) &&
175 while (*string && (*string != lowFirst) && 164 (!isupper (*string) || (tolower (*string) != lowFirst))) {
176 (!isupper(*string) || (tolower(*string) != lowFirst))) 165 string++;
177 { 166 }
178 string++;
179 }
180
181 if (*string == '\0')
182 return FALSE;
183 167
184 cp1 = string; 168 if (*string == '\0')
185 cp2 = word; 169 return FALSE;
186 170
187 do 171 cp1 = string;
188 { 172 cp2 = word;
189 if (*cp2 == '\0')
190 return TRUE;
191 173
192 ch1 = *cp1++; 174 do {
175 if (*cp2 == '\0')
176 return TRUE;
193 177
194 if (isupper(ch1)) 178 ch1 = *cp1++;
195 ch1 = tolower(ch1);
196 179
197 ch2 = *cp2++; 180 if (isupper (ch1))
181 ch1 = tolower (ch1);
198 182
199 if (isupper(ch2)) 183 ch2 = *cp2++;
200 ch2 = tolower(ch2);
201 184
202 } 185 if (isupper (ch2))
203 while (ch1 == ch2); 186 ch2 = tolower (ch2);
204 187
205 string++;
206 } 188 }
189 while (ch1 == ch2);
190
191 string++;
192 }
193 return (TRUE);
207} 194}
208 195
209#endif 196#endif
diff --git a/internal.h b/internal.h
index 9c7dda4d4..beb347671 100644
--- a/internal.h
+++ b/internal.h
@@ -127,6 +127,7 @@ extern int mnc_main(int argc, char** argv);
127extern int monadic_main(int argc, char** argv); 127extern int monadic_main(int argc, char** argv);
128extern int mount_main(int argc, char** argv); 128extern int mount_main(int argc, char** argv);
129extern int mt_main(int argc, char** argv); 129extern int mt_main(int argc, char** argv);
130extern int mv_main(int argc, char** argv);
130extern int printf_main(int argc, char** argv); 131extern int printf_main(int argc, char** argv);
131extern int pwd_main(int argc, char** argv); 132extern int pwd_main(int argc, char** argv);
132extern int reboot_main(int argc, char** argv); 133extern int reboot_main(int argc, char** argv);
@@ -135,6 +136,7 @@ extern int scan_partitions_main(int argc, char** argv);
135extern int sh_main(int argc, char** argv); 136extern int sh_main(int argc, char** argv);
136extern int sleep_main(int argc, char** argv); 137extern int sleep_main(int argc, char** argv);
137extern int tar_main(int argc, char** argv); 138extern int tar_main(int argc, char** argv);
139extern int touch_main(int argc, char** argv);
138extern int sync_main(int argc, char** argv); 140extern int sync_main(int argc, char** argv);
139extern int tput_main(int argc, char** argv); 141extern int tput_main(int argc, char** argv);
140extern int true_main(int argc, char** argv); 142extern int true_main(int argc, char** argv);
diff --git a/mount.c b/mount.c
index 010757d1e..9a1accc88 100644
--- a/mount.c
+++ b/mount.c
@@ -1,9 +1,29 @@
1/* 1/*
2 3/21/1999 Charles P. Wright <cpwright@cpwright.com> 2 * Mini mount implementation for busybox
3 searches through fstab when -a is passed 3 *
4 will try mounting stuff with all fses when passed -t auto 4 * Copyright (C) 1999 by Erik Andersen <andersee@debian.org>
5 5 *
6 1999-04-17 Dave Cinege...Rewrote -t auto. Fixed ro mtab. 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 * 3/21/1999 Charles P. Wright <cpwright@cpwright.com>
21 * searches through fstab when -a is passed
22 * will try mounting stuff with all fses when passed -t auto
23 *
24 * 1999-04-17 Dave Cinege...Rewrote -t auto. Fixed ro mtab.
25 * 1999-10-07 Erik Andersen. Removed mtab usage, major adjustments,
26 * and some serious dieting all around.
7*/ 27*/
8 28
9#include "internal.h" 29#include "internal.h"
@@ -15,416 +35,238 @@
15#include <mntent.h> 35#include <mntent.h>
16#include <sys/mount.h> 36#include <sys/mount.h>
17#include <ctype.h> 37#include <ctype.h>
18 38#include <fstab.h>
19const char mount_usage[] = "mount\n" 39
20"\t\tmount [flags] special-device directory\n" 40const char mount_usage[] = "Usage:\tmount [flags]\n"
21"\n" 41 "\tmount [flags] device directory [-o options,more-options]\n"
22"Flags:\n" 42 "\n"
23"\t-a:\tMount all file systems in fstab.\n" 43 "Flags:\n"
24"\t-f:\t\"Fake\" mount. Add entry to mount table but don't mount it.\n" 44 "\t-a:\tMount all file systems in fstab.\n"
25"\t-n:\tDon't write a mount table entry.\n" 45 "\t-o option:\tOne of many filesystem options, listed below.\n"
26"\t-o option:\tOne of many filesystem options, listed below.\n" 46 "\t-r:\tMount the filesystem read-only.\n"
27"\t-r:\tMount the filesystem read-only.\n" 47 "\t-t filesystem-type:\tSpecify the filesystem type.\n"
28"\t-t filesystem-type:\tSpecify the filesystem type.\n" 48 "\t-w:\tMount for reading and writing (default).\n"
29"\t-w:\tMount for reading and writing (default).\n" 49 "\n"
30"\n" 50 "Options for use with the \"-o\" flag:\n"
31"Options for use with the \"-o\" flag:\n" 51 "\tasync / sync:\tWrites are asynchronous / synchronous.\n"
32"\tasync / sync:\tWrites are asynchronous / synchronous.\n" 52 "\tdev / nodev:\tAllow use of special device files / disallow them.\n"
33"\tdev / nodev:\tAllow use of special device files / disallow them.\n" 53 "\texec / noexec:\tAllow use of executable files / disallow them.\n"
34"\texec / noexec:\tAllow use of executable files / disallow them.\n" 54 "\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n"
35"\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n" 55 "\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n"
36"\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n" 56 "\tro / rw: Mount for read-only / read-write.\n"
37"\tro / rw: Mount for read-only / read-write.\n" 57 "\t"
38"\t" 58 "There are EVEN MORE flags that are specific to each filesystem.\n"
39"There are EVEN MORE flags that are specific to each filesystem.\n" 59 "You'll have to see the written documentation for those.\n";
40"You'll have to see the written documentation for those.\n";
41 60
42struct mount_options { 61struct mount_options {
43 const char * name; 62 const char *name;
44 unsigned long and; 63 unsigned long and;
45 unsigned long or; 64 unsigned long or;
46}; 65};
47 66
48static const struct mount_options mount_options[] = { 67static const struct mount_options mount_options[] = {
49 { "async", ~MS_SYNCHRONOUS,0 }, 68 {"async", ~MS_SYNCHRONOUS, 0},
50 { "defaults", ~0, 0 }, 69 {"defaults", ~0, 0},
51 { "dev", ~MS_NODEV, 0 }, 70 {"dev", ~MS_NODEV, 0},
52 { "exec", ~MS_NOEXEC, 0 }, 71 {"exec", ~MS_NOEXEC, 0},
53 { "nodev", ~0, MS_NODEV }, 72 {"nodev", ~0, MS_NODEV},
54 { "noexec", ~0, MS_NOEXEC }, 73 {"noexec", ~0, MS_NOEXEC},
55 { "nosuid", ~0, MS_NOSUID }, 74 {"nosuid", ~0, MS_NOSUID},
56 { "remount", ~0, MS_REMOUNT }, 75 {"remount", ~0, MS_REMOUNT},
57 { "ro", ~0, MS_RDONLY }, 76 {"ro", ~0, MS_RDONLY},
58 { "rw", ~MS_RDONLY, 0 }, 77 {"rw", ~MS_RDONLY, 0},
59 { "suid", ~MS_NOSUID, 0 }, 78 {"suid", ~MS_NOSUID, 0},
60 { "sync", ~0, MS_SYNCHRONOUS }, 79 {"sync", ~0, MS_SYNCHRONOUS},
61 { 0, 0, 0 } 80 {0, 0, 0}
62}; 81};
63 82
64static void
65show_flags(unsigned long flags, char * buffer)
66{
67 const struct mount_options * f = mount_options;
68 while ( f->name ) {
69 if ( flags & f->and ) {
70 int length = strlen(f->name);
71 memcpy(buffer, f->name, length);
72 buffer += length;
73 *buffer++ = ',';
74 *buffer = '\0';
75 }
76 f++;
77 }
78}
79 83
80static void 84static void
81one_option( 85parse_mount_options ( char *options, unsigned long *flags, char *data)
82 char * option
83,unsigned long * flags
84,char * data)
85{ 86{
86 const struct mount_options * f = mount_options; 87 printf("option=%s\n", options);
87 88 while (*options) {
88 while ( f->name != 0 ) { 89 char *comma = strchr (options, ',');
89 if ( strcasecmp(f->name, option) == 0 ) { 90 const struct mount_options* f = mount_options;
90 *flags &= f->and; 91 if (comma)
91 *flags |= f->or; 92 *comma = '\0';
92 return; 93
93 } 94 printf("checking option=%s vs %s\n", options, f->name);
94 f++; 95 while (f->name != 0) {
96 printf("checking option=%s vs %s\n", options, f->name);
97 if (strcasecmp (f->name, options) == 0) {
98 *flags &= f->and;
99 *flags |= f->or;
100 return;
101 }
102 f++;
95 } 103 }
96 if ( *data ) { 104 if (*data) {
97 data += strlen(data); 105 data += strlen (data);
98 *data++ = ','; 106 *data++ = ',';
99 }
100 strcpy(data, option);
101}
102
103static void
104parse_mount_options(
105 char * options
106,unsigned long * flags
107,char * data)
108{
109 while ( *options ) {
110 char * comma = strchr(options, ',');
111 if ( comma )
112 *comma = '\0';
113 one_option(options, flags, data);
114 if ( comma ) {
115 *comma = ',';
116 options = ++comma;
117 }
118 else
119 break;
120 } 107 }
108 strcpy (data, options);
109 if (comma) {
110 *comma = ',';
111 options = ++comma;
112 } else
113 break;
114 }
121} 115}
122 116
123int 117int
124mount_one( 118mount_one (
125 char * blockDevice 119 char *blockDevice, char *directory, char *filesystemType,
126,char * directory 120 unsigned long flags, char *string_flags)
127,char * filesystemType
128,unsigned long flags
129,char * string_flags
130,int noMtab
131,int fake)
132{ 121{
133 int error = 0; 122 int status = 0;
134 int status = 0;
135
136 char buf[255];
137
138 if (!fake) {
139 if (*filesystemType == 'a') { //Will fail on real FS starting with 'a'
140
141 FILE *f = fopen("/proc/filesystems", "r");
142
143 if (f == NULL) return 1;
144
145 while (fgets(buf, sizeof(buf), f) != NULL) {
146 filesystemType = buf;
147 if (*filesystemType == '\t') { // Not a nodev filesystem
148
149 while (*filesystemType && *filesystemType != '\n') filesystemType++;
150 *filesystemType = '\0';
151
152 filesystemType = buf;
153 filesystemType++; //hop past tab
154
155 status = mount(blockDevice, directory, filesystemType,
156 flags|MS_MGC_VAL ,string_flags);
157 error = errno;
158
159 if (status == 0) break;
160 }
161 }
162 fclose(f);
163 } else {
164
165 status = mount( blockDevice, directory, filesystemType,
166 flags|MS_MGC_VAL ,string_flags);
167 error = errno;
168 }
169 }
170
171 if ( status == 0 ) {
172 char * s = &string_flags[strlen(string_flags)];
173 FILE * mountTable;
174 if ( s != string_flags ) {
175 *s++ = ',';
176 show_flags(flags, s);
177 }
178 if ( !noMtab && (mountTable = setmntent("/etc/mtab", "a+")) ) {
179 int length = strlen(directory);
180 struct mntent m;
181 123
182 if ( length > 1 && directory[length - 1] == '/' ) 124 char buf[255];
183 directory[length - 1] = '\0';
184 125
185 if ( filesystemType == 0 ) { 126 if (strcmp(filesystemType, "auto") == 0) {
186 struct mntent * p 127 FILE *f = fopen ("/proc/filesystems", "r");
187 = findMountPoint(blockDevice, "/proc/mounts");
188 128
189 if ( p && p->mnt_type ) 129 if (f == NULL)
190 filesystemType = p->mnt_type; 130 return( FALSE);
191 }
192 m.mnt_fsname = blockDevice;
193 m.mnt_dir = directory;
194 m.mnt_type = filesystemType ? filesystemType : "default";
195
196 if (*string_flags) {
197 m.mnt_opts = string_flags;
198 } else {
199 if ( (flags | MS_RDONLY) == flags )
200 m.mnt_opts = "ro";
201 else
202 m.mnt_opts = "rw";
203 }
204
205 m.mnt_freq = 0;
206 m.mnt_passno = 0;
207 addmntent(mountTable, &m);
208 endmntent(mountTable);
209 }
210 return 0;
211 } else {
212 fprintf(stderr, "Mount %s", blockDevice);
213 if ( filesystemType && *filesystemType )
214 fprintf(stderr, " (type %s)", filesystemType);
215 131
216 fprintf( 132 while (fgets (buf, sizeof (buf), f) != NULL) {
217 stderr 133 filesystemType = buf;
218 ," on %s: " 134 if (*filesystemType == '\t') { // Not a nodev filesystem
219 ,directory);
220 135
221 switch ( error ) { 136 // Add NULL termination to each line
222 case EPERM: 137 while (*filesystemType && *filesystemType != '\n')
223 if (geteuid() == 0) 138 filesystemType++;
224 fprintf( 139 *filesystemType = '\0';
225 stderr
226 ,"mount point %s is not a directory"
227 ,blockDevice);
228 else
229 fprintf(
230 stderr
231 ,"must be superuser to use mount");
232 break;
233 case EBUSY:
234 fprintf(
235 stderr
236 ,"%s already mounted or %s busy"
237 ,blockDevice
238 ,directory);
239 break;
240 case ENOENT:
241 {
242 struct stat statbuf;
243 if ( stat(directory, &statbuf) != 0 )
244 fprintf(
245 stderr
246 ,"directory %s does not exist"
247 ,directory);
248 else if ( stat(blockDevice, &statbuf) != 0 )
249 fprintf(
250 stderr
251 ,"block device %s does not exist"
252 ,blockDevice);
253 else
254 fprintf(
255 stderr
256 ,"%s is not mounted on %s, but the mount table says it is."
257 ,blockDevice
258 ,directory);
259 break;
260 }
261 case ENOTDIR:
262 fprintf(
263 stderr
264 ,"%s is not a directory"
265 ,directory);
266 break;
267 case EINVAL:
268 fprintf(
269 stderr
270 ,"wrong filesystem type, or bad superblock on %s"
271 ,blockDevice);
272 break;
273 case EMFILE:
274 fprintf(stderr, "mount table full");
275 break;
276 case EIO:
277 fprintf(
278 stderr
279 ,"I/O error reading %s"
280 ,blockDevice);
281 break;
282 case ENODEV:
283 {
284 FILE * f = fopen("/proc/filesystems", "r");
285 140
286 fprintf( 141 filesystemType = buf;
287 stderr 142 filesystemType++; // hop past tab
288 ,"filesystem type %s not in kernel.\n"
289 ,filesystemType);
290 fprintf(stderr, "Do you need to load a module?\n");
291 if ( f ) {
292 char buf[100];
293 143
294 fprintf( 144 status = mount (blockDevice, directory, filesystemType,
295 stderr 145 flags | MS_MGC_VAL, string_flags);
296 ,"Here are the filesystem types the kernel" 146 if (status == 0)
297 " can mount:\n"); 147 break;
298 while ( fgets(buf, sizeof(buf), f) != 0 ) 148 }
299 fprintf(stderr, "\t%s", buf);
300 fclose(f);
301 }
302 break;
303 }
304 case ENOTBLK:
305 fprintf(
306 stderr
307 ,"%s is not a block device"
308 ,blockDevice);
309 break;
310 case ENXIO:
311 fprintf(
312 stderr
313 ,"%s is not a valid block device"
314 ,blockDevice);
315 break;
316 default:
317 fputs(strerror(errno), stderr);
318 }
319 putc('\n', stderr);
320 return -1;
321 } 149 }
150 fclose (f);
151 } else {
152 status = mount (blockDevice, directory, filesystemType,
153 flags | MS_MGC_VAL, string_flags);
154 }
155
156 if (status) {
157 fprintf (stderr, "Mounting %s on %s failed: %s\n",
158 blockDevice, directory, strerror(errno));
159 return (FALSE);
160 }
161 return (TRUE);
322} 162}
323 163
324extern int 164extern int mount_main (int argc, char **argv)
325mount_main(struct FileInfo * i, int argc, char * * argv)
326{ 165{
327 char string_flags[1024]; 166 char string_flags[1024]="\0";
328 unsigned long flags = 0; 167 unsigned long flags = 0;
329 char * filesystemType = "auto"; 168 char *filesystemType = "auto";
330 int fake = 0; 169 int all = 0;
331 int noMtab = 0; 170 int i = argc;
332 int all = 0; 171
333 172 if (argc == 1) {
334 *string_flags = '\0'; 173 FILE *mountTable;
335 174 if ((mountTable = setmntent ("/proc/mounts", "r"))) {
336 if ( argc == 1 ) { 175 struct mntent *m;
337 FILE * mountTable; 176 while ((m = getmntent (mountTable)) != 0) {
338 if ( (mountTable = setmntent("/etc/mtab", "r")) ) { 177 char *blockDevice = m->mnt_fsname;
339 struct mntent * m; 178 if (strcmp (blockDevice, "/dev/root") == 0)
340 while ( (m = getmntent(mountTable)) != 0 ) { 179 blockDevice = (getfsfile ("/"))->fs_spec;
341 printf( 180 printf ("%s on %s type %s (%s)\n", blockDevice, m->mnt_dir,
342 "%s on %s type %s (%s)\n" 181 m->mnt_type, m->mnt_opts);
343 ,m->mnt_fsname 182 }
344 ,m->mnt_dir 183 endmntent (mountTable);
345 ,m->mnt_type
346 ,m->mnt_opts);
347 }
348 endmntent(mountTable);
349 }
350 return 0;
351 } 184 }
352 185 return( TRUE);
353 while ( argc >= 2 && argv[1][0] == '-' ) { 186 }
354 switch ( argv[1][1] ) { 187
355 case 'f': 188
356 fake = 1; 189 /* Parse options */
357 break; 190 while (**argv) {
358 case 'n': 191 if (**argv == '-') {
359 noMtab = 1; 192 switch (**argv) {
360 break; 193 case 'o':
361 case 'o': 194 if (++argv == 0) {
362 if ( argc < 3 ) { 195 fprintf (stderr, "%s\n", mount_usage);
363 usage(mount_usage); 196 return( FALSE);
364 return 1;
365 }
366 parse_mount_options(argv[2], &flags, string_flags);
367 argc--;
368 argv++;
369 break;
370 case 'r':
371 flags |= MS_RDONLY;
372 break;
373 case 't':
374 if ( argc < 3 ) {
375 usage(mount_usage);
376 return 1;
377 }
378 filesystemType = argv[2];
379 argc--;
380 argv++;
381 break;
382 case 'v':
383 break;
384 case 'w':
385 flags &= ~MS_RDONLY;
386 break;
387 case 'a':
388 all = 1;
389 break;
390 default:
391 usage(mount_usage);
392 return 1;
393 } 197 }
198 parse_mount_options (*argv, &flags, string_flags);
394 argc--; 199 argc--;
395 argv++; 200 argv++;
396 } 201 break;
397 202 case 'r':
398 if (all == 1) { 203 flags |= MS_RDONLY;
399 struct mntent *m; 204 break;
400 FILE *f = setmntent("/etc/fstab", "r"); 205 case 't':
401 206 if (++argv == 0) {
402 if (f == NULL) { 207 fprintf (stderr, "%s\n", mount_usage);
403 return 1; 208 return( FALSE);
404 } 209 }
210 filesystemType = *argv;
211 argc--;
212 argv++;
213 break;
214 case 'w':
215 flags &= ~MS_RDONLY;
216 break;
217 case 'a':
218 all = 1;
219 break;
220 case 'v':
221 case 'h':
222 case '-':
223 fprintf (stderr, "%s\n", mount_usage);
224 return( TRUE);
225 }
226 }
227 i--;
228 argv++;
229 }
405 230
406 // FIXME: Combine read routine (make new function) with unmount_all to save space. 231 if (all == 1) {
232 struct mntent *m;
233 FILE *f = setmntent ("/etc/fstab", "r");
407 234
408 while ((m = getmntent(f)) != NULL) { 235 if (f == NULL) {
409 // If the file system isn't noauto, and isn't mounted on /, mount it 236 perror("/etc/fstab");
410 if ((!strstr(m->mnt_opts, "noauto")) && (m->mnt_dir[1] != '\0') 237 return( FALSE);
411 && !((m->mnt_type[0] == 's') && (m->mnt_type[1] == 'w')) 238 }
412 && !((m->mnt_type[0] == 'n') && (m->mnt_type[1] == 'f'))) { 239 // FIXME: Combine read routine (make new function) with unmount_all
413 mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, flags, m->mnt_opts, noMtab, fake); 240 // to save space.
414 } 241
415 } 242 while ((m = getmntent (f)) != NULL) {
243 // If the file system isn't noauto, and isn't mounted on /, mount
244 // it
245 if ((!strstr (m->mnt_opts, "noauto"))
246 && (m->mnt_dir[1] != '\0') && !((m->mnt_type[0] == 's')
247 && (m->mnt_type[1] == 'w'))
248 && !((m->mnt_type[0] == 'n') && (m->mnt_type[1] == 'f'))) {
249 mount_one (m->mnt_fsname, m->mnt_dir, m->mnt_type, flags,
250 m->mnt_opts);
251 }
252 }
416 253
417 endmntent(f); 254 endmntent (f);
255 } else {
256 if (argc >= 3) {
257 while (i < argc)
258 argv--;
259 while (**argv == '-')
260 argv++;
261 if (mount_one
262 (*argv, *(argv+1), filesystemType, flags,
263 string_flags) == 0) return 0;
264 else
265 return( FALSE);
418 } else { 266 } else {
419 if ( argc >= 3 ) { 267 fprintf (stderr, "%s\n", mount_usage);
420 if ( mount_one( argv[1], argv[2], filesystemType, flags, string_flags, noMtab, fake) == 0 ) 268 return( FALSE);
421 return 0;
422 else
423 return 1;
424 } else {
425 usage(mount_usage);
426 return 1;
427 }
428 } 269 }
429 return 0; 270 }
271 return( TRUE);
430} 272}
diff --git a/mv.c b/mv.c
index 22c4a1207..610040d92 100644
--- a/mv.c
+++ b/mv.c
@@ -1,38 +1,84 @@
1/*
2 * Mini mv 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>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <fcntl.h>
27#include <utime.h>
3#include <errno.h> 28#include <errno.h>
4 29
5const char mv_usage[] = "mv source-file destination-file\n" 30const char mv_usage[] = "source-file [source-file ...] destination-file\n"
6"\t\tmv source-file [source-file ...] destination-directory\n" 31 "\n" "\tMove the source files to the destination.\n" "\n";
7"\n" 32
8"\tMove the source files to the destination.\n"
9"\n";
10 33
11extern int 34
12mv_fn(const struct FileInfo * i) 35extern int mv_main (int argc, char **argv)
13{ 36{
14 struct stat destination_stat; 37 const char *srcName;
15 char d[1024]; 38 const char *destName;
16 struct FileInfo n; 39 const char *lastArg;
17 40 BOOL dirFlag;
18 if ( stat(i->destination, &destination_stat) == 0 ) { 41
19 if ( i->stat.st_ino == destination_stat.st_ino 42 if (argc < 3) {
20 && i->stat.st_dev == destination_stat.st_dev ) 43 fprintf (stderr, "Usage: %s %s", *argv, mv_usage);
21 return 0; /* Move file to itself. */ 44 return (FALSE);
22 } 45 }
23 if ( (destination_stat.st_mode & S_IFMT) == S_IFDIR ) { 46 lastArg = argv[argc - 1];
24 n = *i; 47
25 n.destination = join_paths(d, i->destination, basename(i->source)); 48 dirFlag = isDirectory (lastArg);
26 i = &n; 49
50 if ((argc > 3) && !dirFlag) {
51 fprintf (stderr, "%s: not a directory\n", lastArg);
52
53 return (FALSE);
54 }
55
56 while (argc-- > 2) {
57 srcName = *(++argv);
58
59 if (access (srcName, 0) < 0) {
60 perror (srcName);
61 continue;
27 } 62 }
28 if ( rename(i->source, i->destination) == 0 ) 63
29 return 0; 64 destName = lastArg;
30 else if ( errno == EXDEV && is_a_directory(i->source) ) { 65
31 fprintf(stderr 66 if (dirFlag)
32 ,"%s: Can't move directory across filesystems.\n" 67 destName = buildName (destName, srcName);
33 ,i->source); 68
34 return 1; 69 if (rename (srcName, destName) >= 0)
70 continue;
71
72 if (errno != EXDEV) {
73 perror (destName);
74 continue;
35 } 75 }
36 else 76
37 return cp_fn(i); 77 if (!copyFile (srcName, destName, TRUE))
78 continue;
79
80 if (unlink (srcName) < 0)
81 perror (srcName);
82 }
83 return (TRUE);
38} 84}
diff --git a/touch.c b/touch.c
index ca4b98108..8dac10294 100644
--- a/touch.c
+++ b/touch.c
@@ -1,20 +1,85 @@
1/*
2 * Mini touch 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 <sys/types.h>
3#include <stdio.h> 23#include <stdio.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <fcntl.h>
4#include <utime.h> 27#include <utime.h>
28#include <errno.h>
29
5 30
6const char touch_usage[] = "touch [-c] file [file ...]\n" 31const char touch_usage[] = "touch [-c] file [file ...]\n\n"
7"\n"
8"\tUpdate the last-modified date on the given file[s].\n"; 32"\tUpdate the last-modified date on the given file[s].\n";
9 33
10extern int 34
11touch_fn(const struct FileInfo * i) 35
36extern int
37touch_main(int argc, char **argv)
12{ 38{
13 if ( (utime(i->source, 0) != 0) && (i->create != 1) ) { 39 int fd;
14 if ( fopen(i->source, "w") == NULL ) { 40 int create=TRUE;
15 name_and_error(i->source); 41
16 return 1; 42 if (argc < 2) {
17 } 43 fprintf(stderr, "Usage: %s %s", *argv, touch_usage);
44 exit( FALSE);
45 }
46 argc--;
47 argv++;
48
49 /* Parse options */
50 while (**argv == '-') {
51 while (*++(*argv)) switch (**argv) {
52 case 'c':
53 create = FALSE;
54 break;
55 default:
56 fprintf(stderr, "Unknown option: %c\n", **argv);
57 exit( FALSE);
18 } 58 }
19 return 0; 59 argc--;
60 argv++;
61 }
62
63 fd = open (*argv, (create==FALSE)? O_RDWR : O_RDWR | O_CREAT, 0644);
64 if (fd < 0 ) {
65 if (create==FALSE && errno == ENOENT)
66 exit( TRUE);
67 else {
68 perror("touch");
69 exit( FALSE);
70 }
71 }
72 close( fd);
73 if (utime (*argv, NULL)) {
74 perror("touch");
75 exit( FALSE);
76 }
77 else
78 exit( TRUE);
20} 79}
80
81
82
83
84
85
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 010757d1e..9a1accc88 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -1,9 +1,29 @@
1/* 1/*
2 3/21/1999 Charles P. Wright <cpwright@cpwright.com> 2 * Mini mount implementation for busybox
3 searches through fstab when -a is passed 3 *
4 will try mounting stuff with all fses when passed -t auto 4 * Copyright (C) 1999 by Erik Andersen <andersee@debian.org>
5 5 *
6 1999-04-17 Dave Cinege...Rewrote -t auto. Fixed ro mtab. 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 * 3/21/1999 Charles P. Wright <cpwright@cpwright.com>
21 * searches through fstab when -a is passed
22 * will try mounting stuff with all fses when passed -t auto
23 *
24 * 1999-04-17 Dave Cinege...Rewrote -t auto. Fixed ro mtab.
25 * 1999-10-07 Erik Andersen. Removed mtab usage, major adjustments,
26 * and some serious dieting all around.
7*/ 27*/
8 28
9#include "internal.h" 29#include "internal.h"
@@ -15,416 +35,238 @@
15#include <mntent.h> 35#include <mntent.h>
16#include <sys/mount.h> 36#include <sys/mount.h>
17#include <ctype.h> 37#include <ctype.h>
18 38#include <fstab.h>
19const char mount_usage[] = "mount\n" 39
20"\t\tmount [flags] special-device directory\n" 40const char mount_usage[] = "Usage:\tmount [flags]\n"
21"\n" 41 "\tmount [flags] device directory [-o options,more-options]\n"
22"Flags:\n" 42 "\n"
23"\t-a:\tMount all file systems in fstab.\n" 43 "Flags:\n"
24"\t-f:\t\"Fake\" mount. Add entry to mount table but don't mount it.\n" 44 "\t-a:\tMount all file systems in fstab.\n"
25"\t-n:\tDon't write a mount table entry.\n" 45 "\t-o option:\tOne of many filesystem options, listed below.\n"
26"\t-o option:\tOne of many filesystem options, listed below.\n" 46 "\t-r:\tMount the filesystem read-only.\n"
27"\t-r:\tMount the filesystem read-only.\n" 47 "\t-t filesystem-type:\tSpecify the filesystem type.\n"
28"\t-t filesystem-type:\tSpecify the filesystem type.\n" 48 "\t-w:\tMount for reading and writing (default).\n"
29"\t-w:\tMount for reading and writing (default).\n" 49 "\n"
30"\n" 50 "Options for use with the \"-o\" flag:\n"
31"Options for use with the \"-o\" flag:\n" 51 "\tasync / sync:\tWrites are asynchronous / synchronous.\n"
32"\tasync / sync:\tWrites are asynchronous / synchronous.\n" 52 "\tdev / nodev:\tAllow use of special device files / disallow them.\n"
33"\tdev / nodev:\tAllow use of special device files / disallow them.\n" 53 "\texec / noexec:\tAllow use of executable files / disallow them.\n"
34"\texec / noexec:\tAllow use of executable files / disallow them.\n" 54 "\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n"
35"\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n" 55 "\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n"
36"\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n" 56 "\tro / rw: Mount for read-only / read-write.\n"
37"\tro / rw: Mount for read-only / read-write.\n" 57 "\t"
38"\t" 58 "There are EVEN MORE flags that are specific to each filesystem.\n"
39"There are EVEN MORE flags that are specific to each filesystem.\n" 59 "You'll have to see the written documentation for those.\n";
40"You'll have to see the written documentation for those.\n";
41 60
42struct mount_options { 61struct mount_options {
43 const char * name; 62 const char *name;
44 unsigned long and; 63 unsigned long and;
45 unsigned long or; 64 unsigned long or;
46}; 65};
47 66
48static const struct mount_options mount_options[] = { 67static const struct mount_options mount_options[] = {
49 { "async", ~MS_SYNCHRONOUS,0 }, 68 {"async", ~MS_SYNCHRONOUS, 0},
50 { "defaults", ~0, 0 }, 69 {"defaults", ~0, 0},
51 { "dev", ~MS_NODEV, 0 }, 70 {"dev", ~MS_NODEV, 0},
52 { "exec", ~MS_NOEXEC, 0 }, 71 {"exec", ~MS_NOEXEC, 0},
53 { "nodev", ~0, MS_NODEV }, 72 {"nodev", ~0, MS_NODEV},
54 { "noexec", ~0, MS_NOEXEC }, 73 {"noexec", ~0, MS_NOEXEC},
55 { "nosuid", ~0, MS_NOSUID }, 74 {"nosuid", ~0, MS_NOSUID},
56 { "remount", ~0, MS_REMOUNT }, 75 {"remount", ~0, MS_REMOUNT},
57 { "ro", ~0, MS_RDONLY }, 76 {"ro", ~0, MS_RDONLY},
58 { "rw", ~MS_RDONLY, 0 }, 77 {"rw", ~MS_RDONLY, 0},
59 { "suid", ~MS_NOSUID, 0 }, 78 {"suid", ~MS_NOSUID, 0},
60 { "sync", ~0, MS_SYNCHRONOUS }, 79 {"sync", ~0, MS_SYNCHRONOUS},
61 { 0, 0, 0 } 80 {0, 0, 0}
62}; 81};
63 82
64static void
65show_flags(unsigned long flags, char * buffer)
66{
67 const struct mount_options * f = mount_options;
68 while ( f->name ) {
69 if ( flags & f->and ) {
70 int length = strlen(f->name);
71 memcpy(buffer, f->name, length);
72 buffer += length;
73 *buffer++ = ',';
74 *buffer = '\0';
75 }
76 f++;
77 }
78}
79 83
80static void 84static void
81one_option( 85parse_mount_options ( char *options, unsigned long *flags, char *data)
82 char * option
83,unsigned long * flags
84,char * data)
85{ 86{
86 const struct mount_options * f = mount_options; 87 printf("option=%s\n", options);
87 88 while (*options) {
88 while ( f->name != 0 ) { 89 char *comma = strchr (options, ',');
89 if ( strcasecmp(f->name, option) == 0 ) { 90 const struct mount_options* f = mount_options;
90 *flags &= f->and; 91 if (comma)
91 *flags |= f->or; 92 *comma = '\0';
92 return; 93
93 } 94 printf("checking option=%s vs %s\n", options, f->name);
94 f++; 95 while (f->name != 0) {
96 printf("checking option=%s vs %s\n", options, f->name);
97 if (strcasecmp (f->name, options) == 0) {
98 *flags &= f->and;
99 *flags |= f->or;
100 return;
101 }
102 f++;
95 } 103 }
96 if ( *data ) { 104 if (*data) {
97 data += strlen(data); 105 data += strlen (data);
98 *data++ = ','; 106 *data++ = ',';
99 }
100 strcpy(data, option);
101}
102
103static void
104parse_mount_options(
105 char * options
106,unsigned long * flags
107,char * data)
108{
109 while ( *options ) {
110 char * comma = strchr(options, ',');
111 if ( comma )
112 *comma = '\0';
113 one_option(options, flags, data);
114 if ( comma ) {
115 *comma = ',';
116 options = ++comma;
117 }
118 else
119 break;
120 } 107 }
108 strcpy (data, options);
109 if (comma) {
110 *comma = ',';
111 options = ++comma;
112 } else
113 break;
114 }
121} 115}
122 116
123int 117int
124mount_one( 118mount_one (
125 char * blockDevice 119 char *blockDevice, char *directory, char *filesystemType,
126,char * directory 120 unsigned long flags, char *string_flags)
127,char * filesystemType
128,unsigned long flags
129,char * string_flags
130,int noMtab
131,int fake)
132{ 121{
133 int error = 0; 122 int status = 0;
134 int status = 0;
135
136 char buf[255];
137
138 if (!fake) {
139 if (*filesystemType == 'a') { //Will fail on real FS starting with 'a'
140
141 FILE *f = fopen("/proc/filesystems", "r");
142
143 if (f == NULL) return 1;
144
145 while (fgets(buf, sizeof(buf), f) != NULL) {
146 filesystemType = buf;
147 if (*filesystemType == '\t') { // Not a nodev filesystem
148
149 while (*filesystemType && *filesystemType != '\n') filesystemType++;
150 *filesystemType = '\0';
151
152 filesystemType = buf;
153 filesystemType++; //hop past tab
154
155 status = mount(blockDevice, directory, filesystemType,
156 flags|MS_MGC_VAL ,string_flags);
157 error = errno;
158
159 if (status == 0) break;
160 }
161 }
162 fclose(f);
163 } else {
164
165 status = mount( blockDevice, directory, filesystemType,
166 flags|MS_MGC_VAL ,string_flags);
167 error = errno;
168 }
169 }
170
171 if ( status == 0 ) {
172 char * s = &string_flags[strlen(string_flags)];
173 FILE * mountTable;
174 if ( s != string_flags ) {
175 *s++ = ',';
176 show_flags(flags, s);
177 }
178 if ( !noMtab && (mountTable = setmntent("/etc/mtab", "a+")) ) {
179 int length = strlen(directory);
180 struct mntent m;
181 123
182 if ( length > 1 && directory[length - 1] == '/' ) 124 char buf[255];
183 directory[length - 1] = '\0';
184 125
185 if ( filesystemType == 0 ) { 126 if (strcmp(filesystemType, "auto") == 0) {
186 struct mntent * p 127 FILE *f = fopen ("/proc/filesystems", "r");
187 = findMountPoint(blockDevice, "/proc/mounts");
188 128
189 if ( p && p->mnt_type ) 129 if (f == NULL)
190 filesystemType = p->mnt_type; 130 return( FALSE);
191 }
192 m.mnt_fsname = blockDevice;
193 m.mnt_dir = directory;
194 m.mnt_type = filesystemType ? filesystemType : "default";
195
196 if (*string_flags) {
197 m.mnt_opts = string_flags;
198 } else {
199 if ( (flags | MS_RDONLY) == flags )
200 m.mnt_opts = "ro";
201 else
202 m.mnt_opts = "rw";
203 }
204
205 m.mnt_freq = 0;
206 m.mnt_passno = 0;
207 addmntent(mountTable, &m);
208 endmntent(mountTable);
209 }
210 return 0;
211 } else {
212 fprintf(stderr, "Mount %s", blockDevice);
213 if ( filesystemType && *filesystemType )
214 fprintf(stderr, " (type %s)", filesystemType);
215 131
216 fprintf( 132 while (fgets (buf, sizeof (buf), f) != NULL) {
217 stderr 133 filesystemType = buf;
218 ," on %s: " 134 if (*filesystemType == '\t') { // Not a nodev filesystem
219 ,directory);
220 135
221 switch ( error ) { 136 // Add NULL termination to each line
222 case EPERM: 137 while (*filesystemType && *filesystemType != '\n')
223 if (geteuid() == 0) 138 filesystemType++;
224 fprintf( 139 *filesystemType = '\0';
225 stderr
226 ,"mount point %s is not a directory"
227 ,blockDevice);
228 else
229 fprintf(
230 stderr
231 ,"must be superuser to use mount");
232 break;
233 case EBUSY:
234 fprintf(
235 stderr
236 ,"%s already mounted or %s busy"
237 ,blockDevice
238 ,directory);
239 break;
240 case ENOENT:
241 {
242 struct stat statbuf;
243 if ( stat(directory, &statbuf) != 0 )
244 fprintf(
245 stderr
246 ,"directory %s does not exist"
247 ,directory);
248 else if ( stat(blockDevice, &statbuf) != 0 )
249 fprintf(
250 stderr
251 ,"block device %s does not exist"
252 ,blockDevice);
253 else
254 fprintf(
255 stderr
256 ,"%s is not mounted on %s, but the mount table says it is."
257 ,blockDevice
258 ,directory);
259 break;
260 }
261 case ENOTDIR:
262 fprintf(
263 stderr
264 ,"%s is not a directory"
265 ,directory);
266 break;
267 case EINVAL:
268 fprintf(
269 stderr
270 ,"wrong filesystem type, or bad superblock on %s"
271 ,blockDevice);
272 break;
273 case EMFILE:
274 fprintf(stderr, "mount table full");
275 break;
276 case EIO:
277 fprintf(
278 stderr
279 ,"I/O error reading %s"
280 ,blockDevice);
281 break;
282 case ENODEV:
283 {
284 FILE * f = fopen("/proc/filesystems", "r");
285 140
286 fprintf( 141 filesystemType = buf;
287 stderr 142 filesystemType++; // hop past tab
288 ,"filesystem type %s not in kernel.\n"
289 ,filesystemType);
290 fprintf(stderr, "Do you need to load a module?\n");
291 if ( f ) {
292 char buf[100];
293 143
294 fprintf( 144 status = mount (blockDevice, directory, filesystemType,
295 stderr 145 flags | MS_MGC_VAL, string_flags);
296 ,"Here are the filesystem types the kernel" 146 if (status == 0)
297 " can mount:\n"); 147 break;
298 while ( fgets(buf, sizeof(buf), f) != 0 ) 148 }
299 fprintf(stderr, "\t%s", buf);
300 fclose(f);
301 }
302 break;
303 }
304 case ENOTBLK:
305 fprintf(
306 stderr
307 ,"%s is not a block device"
308 ,blockDevice);
309 break;
310 case ENXIO:
311 fprintf(
312 stderr
313 ,"%s is not a valid block device"
314 ,blockDevice);
315 break;
316 default:
317 fputs(strerror(errno), stderr);
318 }
319 putc('\n', stderr);
320 return -1;
321 } 149 }
150 fclose (f);
151 } else {
152 status = mount (blockDevice, directory, filesystemType,
153 flags | MS_MGC_VAL, string_flags);
154 }
155
156 if (status) {
157 fprintf (stderr, "Mounting %s on %s failed: %s\n",
158 blockDevice, directory, strerror(errno));
159 return (FALSE);
160 }
161 return (TRUE);
322} 162}
323 163
324extern int 164extern int mount_main (int argc, char **argv)
325mount_main(struct FileInfo * i, int argc, char * * argv)
326{ 165{
327 char string_flags[1024]; 166 char string_flags[1024]="\0";
328 unsigned long flags = 0; 167 unsigned long flags = 0;
329 char * filesystemType = "auto"; 168 char *filesystemType = "auto";
330 int fake = 0; 169 int all = 0;
331 int noMtab = 0; 170 int i = argc;
332 int all = 0; 171
333 172 if (argc == 1) {
334 *string_flags = '\0'; 173 FILE *mountTable;
335 174 if ((mountTable = setmntent ("/proc/mounts", "r"))) {
336 if ( argc == 1 ) { 175 struct mntent *m;
337 FILE * mountTable; 176 while ((m = getmntent (mountTable)) != 0) {
338 if ( (mountTable = setmntent("/etc/mtab", "r")) ) { 177 char *blockDevice = m->mnt_fsname;
339 struct mntent * m; 178 if (strcmp (blockDevice, "/dev/root") == 0)
340 while ( (m = getmntent(mountTable)) != 0 ) { 179 blockDevice = (getfsfile ("/"))->fs_spec;
341 printf( 180 printf ("%s on %s type %s (%s)\n", blockDevice, m->mnt_dir,
342 "%s on %s type %s (%s)\n" 181 m->mnt_type, m->mnt_opts);
343 ,m->mnt_fsname 182 }
344 ,m->mnt_dir 183 endmntent (mountTable);
345 ,m->mnt_type
346 ,m->mnt_opts);
347 }
348 endmntent(mountTable);
349 }
350 return 0;
351 } 184 }
352 185 return( TRUE);
353 while ( argc >= 2 && argv[1][0] == '-' ) { 186 }
354 switch ( argv[1][1] ) { 187
355 case 'f': 188
356 fake = 1; 189 /* Parse options */
357 break; 190 while (**argv) {
358 case 'n': 191 if (**argv == '-') {
359 noMtab = 1; 192 switch (**argv) {
360 break; 193 case 'o':
361 case 'o': 194 if (++argv == 0) {
362 if ( argc < 3 ) { 195 fprintf (stderr, "%s\n", mount_usage);
363 usage(mount_usage); 196 return( FALSE);
364 return 1;
365 }
366 parse_mount_options(argv[2], &flags, string_flags);
367 argc--;
368 argv++;
369 break;
370 case 'r':
371 flags |= MS_RDONLY;
372 break;
373 case 't':
374 if ( argc < 3 ) {
375 usage(mount_usage);
376 return 1;
377 }
378 filesystemType = argv[2];
379 argc--;
380 argv++;
381 break;
382 case 'v':
383 break;
384 case 'w':
385 flags &= ~MS_RDONLY;
386 break;
387 case 'a':
388 all = 1;
389 break;
390 default:
391 usage(mount_usage);
392 return 1;
393 } 197 }
198 parse_mount_options (*argv, &flags, string_flags);
394 argc--; 199 argc--;
395 argv++; 200 argv++;
396 } 201 break;
397 202 case 'r':
398 if (all == 1) { 203 flags |= MS_RDONLY;
399 struct mntent *m; 204 break;
400 FILE *f = setmntent("/etc/fstab", "r"); 205 case 't':
401 206 if (++argv == 0) {
402 if (f == NULL) { 207 fprintf (stderr, "%s\n", mount_usage);
403 return 1; 208 return( FALSE);
404 } 209 }
210 filesystemType = *argv;
211 argc--;
212 argv++;
213 break;
214 case 'w':
215 flags &= ~MS_RDONLY;
216 break;
217 case 'a':
218 all = 1;
219 break;
220 case 'v':
221 case 'h':
222 case '-':
223 fprintf (stderr, "%s\n", mount_usage);
224 return( TRUE);
225 }
226 }
227 i--;
228 argv++;
229 }
405 230
406 // FIXME: Combine read routine (make new function) with unmount_all to save space. 231 if (all == 1) {
232 struct mntent *m;
233 FILE *f = setmntent ("/etc/fstab", "r");
407 234
408 while ((m = getmntent(f)) != NULL) { 235 if (f == NULL) {
409 // If the file system isn't noauto, and isn't mounted on /, mount it 236 perror("/etc/fstab");
410 if ((!strstr(m->mnt_opts, "noauto")) && (m->mnt_dir[1] != '\0') 237 return( FALSE);
411 && !((m->mnt_type[0] == 's') && (m->mnt_type[1] == 'w')) 238 }
412 && !((m->mnt_type[0] == 'n') && (m->mnt_type[1] == 'f'))) { 239 // FIXME: Combine read routine (make new function) with unmount_all
413 mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, flags, m->mnt_opts, noMtab, fake); 240 // to save space.
414 } 241
415 } 242 while ((m = getmntent (f)) != NULL) {
243 // If the file system isn't noauto, and isn't mounted on /, mount
244 // it
245 if ((!strstr (m->mnt_opts, "noauto"))
246 && (m->mnt_dir[1] != '\0') && !((m->mnt_type[0] == 's')
247 && (m->mnt_type[1] == 'w'))
248 && !((m->mnt_type[0] == 'n') && (m->mnt_type[1] == 'f'))) {
249 mount_one (m->mnt_fsname, m->mnt_dir, m->mnt_type, flags,
250 m->mnt_opts);
251 }
252 }
416 253
417 endmntent(f); 254 endmntent (f);
255 } else {
256 if (argc >= 3) {
257 while (i < argc)
258 argv--;
259 while (**argv == '-')
260 argv++;
261 if (mount_one
262 (*argv, *(argv+1), filesystemType, flags,
263 string_flags) == 0) return 0;
264 else
265 return( FALSE);
418 } else { 266 } else {
419 if ( argc >= 3 ) { 267 fprintf (stderr, "%s\n", mount_usage);
420 if ( mount_one( argv[1], argv[2], filesystemType, flags, string_flags, noMtab, fake) == 0 ) 268 return( FALSE);
421 return 0;
422 else
423 return 1;
424 } else {
425 usage(mount_usage);
426 return 1;
427 }
428 } 269 }
429 return 0; 270 }
271 return( TRUE);
430} 272}