more stuff
No binary (build failed)
—
(log yok)
| @@ -23,7 +23,7 @@ BINDIR=$(prefix) | |
| LDFLAGS= -s | |
| LIBRARIES=-lc | |
| - | OBJECTS=$(shell ./busybox.sh) utility.o |
| + | OBJECTS=$(shell ./busybox.sh) |
| CFLAGS+= -DBB_VER='"$(VERSION)"' | |
| CFLAGS+= -DBB_BT='"$(BUILDTIME)"' | |
| @@ -111,7 +111,7 @@ static const struct Applet applets[] = { | |
| {"mt", mt_main}, | |
| #endif | |
| #ifdef BB_MV //bin | |
| - | {"mv", dyadic_main}, |
| + | {"mv", mv_main}, |
| #endif | |
| #ifdef BB_PRINTF //usr/bin | |
| {"printf", printf_main}, | |
| @@ -144,7 +144,7 @@ static const struct Applet applets[] = { | |
| {"sync", sync_main}, | |
| #endif | |
| #ifdef BB_TOUCH //usr/bin | |
| - | {"touch", monadic_main}, |
| + | {"touch", touch_main}, |
| #endif | |
| #ifdef BB_TRUE //bin | |
| {"true", true_main}, | |
| @@ -208,8 +208,8 @@ int busybox_main(int argc, char **argv) | |
| const struct Applet *a = applets; | |
| fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n", | |
| BB_VER, BB_BT); | |
| - | fprintf(stderr, "Usage: busybox [function] [arguments]...\n"); |
| - | fprintf(stderr, "or\nUsage: [function] [arguments]...\n"); |
| + | fprintf(stderr, "\nUsage:\t[function] [arguments]...\n"); |
| + | fprintf(stderr, "\tbusybox [function] [arguments]...\n"); |
| fprintf(stderr, | |
| "\n\tMost people will create a symlink to busybox for each\n" | |
| "\tfunction name, and busybox will act like whatever you invoke it as.\n"); | |
| @@ -111,7 +111,7 @@ static const struct Applet applets[] = { | |
| {"mt", mt_main}, | |
| #endif | |
| #ifdef BB_MV //bin | |
| - | {"mv", dyadic_main}, |
| + | {"mv", mv_main}, |
| #endif | |
| #ifdef BB_PRINTF //usr/bin | |
| {"printf", printf_main}, | |
| @@ -144,7 +144,7 @@ static const struct Applet applets[] = { | |
| {"sync", sync_main}, | |
| #endif | |
| #ifdef BB_TOUCH //usr/bin | |
| - | {"touch", monadic_main}, |
| + | {"touch", touch_main}, |
| #endif | |
| #ifdef BB_TRUE //bin | |
| {"true", true_main}, | |
| @@ -208,8 +208,8 @@ int busybox_main(int argc, char **argv) | |
| const struct Applet *a = applets; | |
| fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n", | |
| BB_VER, BB_BT); | |
| - | fprintf(stderr, "Usage: busybox [function] [arguments]...\n"); |
| - | fprintf(stderr, "or\nUsage: [function] [arguments]...\n"); |
| + | fprintf(stderr, "\nUsage:\t[function] [arguments]...\n"); |
| + | fprintf(stderr, "\tbusybox [function] [arguments]...\n"); |
| fprintf(stderr, | |
| "\n\tMost people will create a symlink to busybox for each\n" | |
| "\tfunction name, and busybox will act like whatever you invoke it as.\n"); | |
| @@ -30,7 +30,6 @@ | |
| //#define BB_LOADKMAP | |
| ////#define BB_LOSETUP | |
| #define BB_LS | |
| - | //#define BB_MAIN |
| //#define BB_MAKEDEVS | |
| ////#define BB_MATH | |
| //#define BB_MKDIR | |
| @@ -39,9 +38,9 @@ | |
| //#define BB_MNC | |
| //#define BB_MONADIC | |
| #define BB_MORE | |
| - | //#define BB_MOUNT |
| + | #define BB_MOUNT |
| ////#define BB_MT | |
| - | //#define BB_MV |
| + | #define BB_MV |
| //#define BB_POSTPROCESS | |
| //#define BB_PRINTF | |
| //#define BB_PWD | |
| @@ -53,10 +52,10 @@ | |
| //#define BB_SWAPON | |
| //#define BB_SYNC | |
| #define BB_TAR | |
| - | //#define BB_TOUCH |
| + | #define BB_TOUCH |
| #define BB_TRUE | |
| //#define BB_UMOUNT | |
| //#define BB_UPDATE | |
| - | //#define BB_UTILITY |
| + | #define BB_UTILITY |
| #define BB_ZCAT | |
| #define BB_GZIP | |
| @@ -3,6 +3,7 @@ | |
| #include <mntent.h> | |
| #include <sys/stat.h> | |
| #include <sys/vfs.h> | |
| + | #include <fstab.h> |
| const char df_usage[] = "df [filesystem ...]\n" | |
| "\n" | |
| @@ -10,7 +11,7 @@ const char df_usage[] = "df [filesystem ...]\n" | |
| static int | |
| - | df(const char * device, const char * mountPoint) |
| + | df(char* device, const char * mountPoint) |
| { | |
| struct statfs s; | |
| long blocks_used; | |
| @@ -25,6 +26,8 @@ df(const char * device, const char * mountPoint) | |
| blocks_used = s.f_blocks - s.f_bfree; | |
| blocks_percent_used = (long) | |
| (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5); | |
| + | if ( strcmp(device, "/dev/root")==0) |
| + | device=(getfsfile ("/"))->fs_spec; |
| printf( | |
| "%-20s %9ld %9ld %9ld %3ld%% %s\n", | |
| @@ -75,7 +78,7 @@ df_main(int argc, char * * argv) | |
| } | |
| while ( (mountEntry = getmntent (mountTable))) { | |
| - | int status=df(mountEntry->mnt_fsname ,mountEntry->mnt_dir); |
| + | int status=df(mountEntry->mnt_fsname, mountEntry->mnt_dir); |
| if (status) | |
| return status; | |
| } | |
| @@ -129,3 +132,5 @@ findMountPoint(const char* name, const char* table) | |
| endmntent(mountTable); | |
| return mountEntry; | |
| } | |
| + | |
| + | |
| @@ -1,38 +1,84 @@ | |
| + | /* |
| + | * Mini mv implementation for busybox |
| + | * |
| + | * Copyright (C) 1998 by Erik Andersen <[email protected]> |
| + | * |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| + | * General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| + | * |
| + | */ |
| + | |
| #include "internal.h" | |
| #include <stdio.h> | |
| + | #include <sys/types.h> |
| + | #include <sys/stat.h> |
| + | #include <fcntl.h> |
| + | #include <utime.h> |
| #include <errno.h> | |
| - | const char mv_usage[] = "mv source-file destination-file\n" |
| - | "\t\tmv source-file [source-file ...] destination-directory\n" |
| - | "\n" |
| - | "\tMove the source files to the destination.\n" |
| - | "\n"; |
| + | const char mv_usage[] = "source-file [source-file ...] destination-file\n" |
| + | "\n" "\tMove the source files to the destination.\n" "\n"; |
| + | |
| - | extern int |
| - | mv_fn(const struct FileInfo * i) |
| + | |
| + | extern int mv_main (int argc, char **argv) |
| { | |
| - | struct stat destination_stat; |
| - | char d[1024]; |
| - | struct FileInfo n; |
| - | |
| - | if ( stat(i->destination, &destination_stat) == 0 ) { |
| - | if ( i->stat.st_ino == destination_stat.st_ino |
| - | && i->stat.st_dev == destination_stat.st_dev ) |
| - | return 0; /* Move file to itself. */ |
| - | } |
| - | if ( (destination_stat.st_mode & S_IFMT) == S_IFDIR ) { |
| - | n = *i; |
| - | n.destination = join_paths(d, i->destination, basename(i->source)); |
| - | i = &n; |
| + | const char *srcName; |
| + | const char *destName; |
| + | const char *lastArg; |
| + | BOOL dirFlag; |
| + | |
| + | if (argc < 3) { |
| + | fprintf (stderr, "Usage: %s %s", *argv, mv_usage); |
| + | return (FALSE); |
| + | } |
| + | lastArg = argv[argc - 1]; |
| + | |
| + | dirFlag = isDirectory (lastArg); |
| + | |
| + | if ((argc > 3) && !dirFlag) { |
| + | fprintf (stderr, "%s: not a directory\n", lastArg); |
| + | |
| + | return (FALSE); |
| + | } |
| + | |
| + | while (argc-- > 2) { |
| + | srcName = *(++argv); |
| + | |
| + | if (access (srcName, 0) < 0) { |
| + | perror (srcName); |
| + | continue; |
| } | |
| - | if ( rename(i->source, i->destination) == 0 ) |
| - | return 0; |
| - | else if ( errno == EXDEV && is_a_directory(i->source) ) { |
| - | fprintf(stderr |
| - | ,"%s: Can't move directory across filesystems.\n" |
| - | ,i->source); |
| - | return 1; |
| + | |
| + | destName = lastArg; |
| + | |
| + | if (dirFlag) |
| + | destName = buildName (destName, srcName); |
| + | |
| + | if (rename (srcName, destName) >= 0) |
| + | continue; |
| + | |
| + | if (errno != EXDEV) { |
| + | perror (destName); |
| + | continue; |
| } | |
| - | else |
| - | return cp_fn(i); |
| + | |
| + | if (!copyFile (srcName, destName, TRUE)) |
| + | continue; |
| + | |
| + | if (unlink (srcName) < 0) |
| + | perror (srcName); |
| + | } |
| + | return (TRUE); |
| } | |
| @@ -1,20 +1,85 @@ | |
| + | /* |
| + | * Mini touch implementation for busybox |
| + | * |
| + | * Copyright (C) 1998 by Erik Andersen <[email protected]> |
| + | * |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| + | * General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| + | * |
| + | */ |
| + | |
| #include "internal.h" | |
| - | #include <sys/types.h> |
| #include <stdio.h> | |
| + | #include <sys/types.h> |
| + | #include <sys/stat.h> |
| + | #include <fcntl.h> |
| #include <utime.h> | |
| + | #include <errno.h> |
| + | |
| - | const char touch_usage[] = "touch [-c] file [file ...]\n" |
| - | "\n" |
| + | const char touch_usage[] = "touch [-c] file [file ...]\n\n" |
| "\tUpdate the last-modified date on the given file[s].\n"; | |
| - | extern int |
| - | touch_fn(const struct FileInfo * i) |
| + | |
| + | |
| + | extern int |
| + | touch_main(int argc, char **argv) |
| { | |
| - | if ( (utime(i->source, 0) != 0) && (i->create != 1) ) { |
| - | if ( fopen(i->source, "w") == NULL ) { |
| - | name_and_error(i->source); |
| - | return 1; |
| - | } |
| + | int fd; |
| + | int create=TRUE; |
| + | |
| + | if (argc < 2) { |
| + | fprintf(stderr, "Usage: %s %s", *argv, touch_usage); |
| + | exit( FALSE); |
| + | } |
| + | argc--; |
| + | argv++; |
| + | |
| + | /* Parse options */ |
| + | while (**argv == '-') { |
| + | while (*++(*argv)) switch (**argv) { |
| + | case 'c': |
| + | create = FALSE; |
| + | break; |
| + | default: |
| + | fprintf(stderr, "Unknown option: %c\n", **argv); |
| + | exit( FALSE); |
| } | |
| - | return 0; |
| + | argc--; |
| + | argv++; |
| + | } |
| + | |
| + | fd = open (*argv, (create==FALSE)? O_RDWR : O_RDWR | O_CREAT, 0644); |
| + | if (fd < 0 ) { |
| + | if (create==FALSE && errno == ENOENT) |
| + | exit( TRUE); |
| + | else { |
| + | perror("touch"); |
| + | exit( FALSE); |
| + | } |
| + | } |
| + | close( fd); |
| + | if (utime (*argv, NULL)) { |
| + | perror("touch"); |
| + | exit( FALSE); |
| + | } |
| + | else |
| + | exit( TRUE); |
| } | |
| + | |
| + | |
| + | |
| + | |
| + | |
| + | |
| @@ -3,6 +3,7 @@ | |
| #include <mntent.h> | |
| #include <sys/stat.h> | |
| #include <sys/vfs.h> | |
| + | #include <fstab.h> |
| const char df_usage[] = "df [filesystem ...]\n" | |
| "\n" | |
| @@ -10,7 +11,7 @@ const char df_usage[] = "df [filesystem ...]\n" | |
| static int | |
| - | df(const char * device, const char * mountPoint) |
| + | df(char* device, const char * mountPoint) |
| { | |
| struct statfs s; | |
| long blocks_used; | |
| @@ -25,6 +26,8 @@ df(const char * device, const char * mountPoint) | |
| blocks_used = s.f_blocks - s.f_bfree; | |
| blocks_percent_used = (long) | |
| (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5); | |
| + | if ( strcmp(device, "/dev/root")==0) |
| + | device=(getfsfile ("/"))->fs_spec; |
| printf( | |
| "%-20s %9ld %9ld %9ld %3ld%% %s\n", | |
| @@ -75,7 +78,7 @@ df_main(int argc, char * * argv) | |
| } | |
| while ( (mountEntry = getmntent (mountTable))) { | |
| - | int status=df(mountEntry->mnt_fsname ,mountEntry->mnt_dir); |
| + | int status=df(mountEntry->mnt_fsname, mountEntry->mnt_dir); |
| if (status) | |
| return status; | |
| } | |
| @@ -129,3 +132,5 @@ findMountPoint(const char* name, const char* table) | |
| endmntent(mountTable); | |
| return mountEntry; | |
| } | |
| + | |
| + | |
| @@ -23,187 +23,174 @@ | |
| const char grep_usage[] = | |
| - | "Search the input file(s) for lines matching the given pattern.\n" |
| - | "\tI search stdin if no files are given.\n" |
| - | "\tI can't grok full regular expressions.\n" |
| - | "usage: grep [in] PATTERN [FILES]...\n" |
| - | "\ti=ignore case, n=list line numbers\n"; |
| + | "Search the input file(s) for lines matching the given pattern.\n" |
| + | "\tI search stdin if no files are given.\n" |
| + | "\tI can't grok full regular expressions.\n" |
| + | "usage: grep [in] PATTERN [FILES]...\n" |
| + | "\ti=ignore case, n=list line numbers\n"; |
| - | static BOOL search |
| - | (const char * string, const char * word, BOOL ignoreCase); |
| + | static BOOL search (const char *string, const char *word, BOOL ignoreCase); |
| - | extern int |
| - | grep_main(int argc, char ** argv) |
| + | extern int grep_main (int argc, char **argv) |
| { | |
| - | FILE * fp; |
| - | const char * word; |
| - | const char * name; |
| - | const char * cp; |
| - | BOOL tellName; |
| - | BOOL ignoreCase; |
| - | BOOL tellLine; |
| - | long line; |
| - | char buf[BUF_SIZE]; |
| - | |
| - | ignoreCase = FALSE; |
| - | tellLine = FALSE; |
| - | |
| + | FILE *fp; |
| + | const char *word; |
| + | const char *name; |
| + | const char *cp; |
| + | BOOL tellName; |
| + | BOOL ignoreCase; |
| + | BOOL tellLine; |
| + | long line; |
| + | char buf[BUF_SIZE]; |
| + | |
| + | ignoreCase = FALSE; |
| + | tellLine = FALSE; |
| + | |
| + | argc--; |
| + | argv++; |
| + | if (argc < 1) { |
| + | fprintf (stderr, "%s", grep_usage); |
| + | return 1; |
| + | } |
| + | |
| + | if (**argv == '-') { |
| argc--; | |
| - | argv++; |
| - | if (argc < 1) |
| - | { |
| - | fprintf(stderr, "%s", grep_usage); |
| - | return 1; |
| - | } |
| + | cp = *argv++; |
| - | if (**argv == '-') |
| - | { |
| - | argc--; |
| - | cp = *argv++; |
| - | |
| - | while (*++cp) switch (*cp) |
| - | { |
| - | case 'i': |
| - | ignoreCase = TRUE; |
| - | break; |
| - | |
| - | case 'n': |
| - | tellLine = TRUE; |
| - | break; |
| - | |
| - | default: |
| - | fprintf(stderr, "Unknown option\n"); |
| - | return 1; |
| - | } |
| - | } |
| + | while (*++cp) |
| + | switch (*cp) { |
| + | case 'i': |
| + | ignoreCase = TRUE; |
| + | break; |
| - | word = *argv++; |
| - | argc--; |
| + | case 'n': |
| + | tellLine = TRUE; |
| + | break; |
| - | tellName = (argc > 1); |
| + | default: |
| + | fprintf (stderr, "Unknown option\n"); |
| + | return 1; |
| + | } |
| + | } |
| - | while (argc-- > 0) |
| - | { |
| - | name = *argv++; |
| + | word = *argv++; |
| + | argc--; |
| - | fp = fopen(name, "r"); |
| + | tellName = (argc > 1); |
| - | if (fp == NULL) |
| - | { |
| - | perror(name); |
| + | while (argc-- > 0) { |
| + | name = *argv++; |
| - | continue; |
| - | } |
| + | fp = fopen (name, "r"); |
| - | line = 0; |
| + | if (fp == NULL) { |
| + | perror (name); |
| - | while (fgets(buf, sizeof(buf), fp)) |
| - | { |
| - | line++; |
| + | continue; |
| + | } |
| - | cp = &buf[strlen(buf) - 1]; |
| + | line = 0; |
| - | if (*cp != '\n') |
| - | fprintf(stderr, "%s: Line too long\n", name); |
| + | while (fgets (buf, sizeof (buf), fp)) { |
| + | line++; |
| - | if (search(buf, word, ignoreCase)) |
| - | { |
| - | if (tellName) |
| - | printf("%s: ", name); |
| + | cp = &buf[strlen (buf) - 1]; |
| - | if (tellLine) |
| - | printf("%ld: ", line); |
| + | if (*cp != '\n') |
| + | fprintf (stderr, "%s: Line too long\n", name); |
| - | fputs(buf, stdout); |
| - | } |
| - | } |
| + | if (search (buf, word, ignoreCase)) { |
| + | if (tellName) |
| + | printf ("%s: ", name); |
| - | if (ferror(fp)) |
| - | perror(name); |
| + | if (tellLine) |
| + | printf ("%ld: ", line); |
| - | fclose(fp); |
| + | fputs (buf, stdout); |
| + | } |
| } | |
| - | return 0; |
| + | |
| + | if (ferror (fp)) |
| + | perror (name); |
| + | |
| + | fclose (fp); |
| + | } |
| + | return 0; |
| } | |
| /* | |
| * See if the specified word is found in the specified string. | |
| */ | |
| - | static BOOL |
| - | search(const char * string, const char * word, BOOL ignoreCase) |
| + | static BOOL search (const char *string, const char *word, BOOL ignoreCase) |
| { | |
| - | const char * cp1; |
| - | const char * cp2; |
| - | int len; |
| - | int lowFirst; |
| - | int ch1; |
| - | int ch2; |
| + | const char *cp1; |
| + | const char *cp2; |
| + | int len; |
| + | int lowFirst; |
| + | int ch1; |
| + | int ch2; |
| - | len = strlen(word); |
| + | len = strlen (word); |
| - | if (!ignoreCase) |
| - | { |
| - | while (TRUE) |
| - | { |
| - | string = strchr(string, word[0]); |
| + | if (!ignoreCase) { |
| + | while (TRUE) { |
| + | string = strchr (string, word[0]); |
| - | if (string == NULL) |
| - | return FALSE; |
| + | if (string == NULL) |
| + | return FALSE; |
| - | if (memcmp(string, word, len) == 0) |
| - | return TRUE; |
| + | if (memcmp (string, word, len) == 0) |
| + | return TRUE; |
| - | string++; |
| - | } |
| + | string++; |
| } | |
| + | } |
| - | /* |
| - | * Here if we need to check case independence. |
| - | * Do the search by lower casing both strings. |
| - | */ |
| - | lowFirst = *word; |
| + | /* |
| + | * Here if we need to check case independence. |
| + | * Do the search by lower casing both strings. |
| + | */ |
| + | lowFirst = *word; |
| - | if (isupper(lowFirst)) |
| - | lowFirst = tolower(lowFirst); |
| + | if (isupper (lowFirst)) |
| + | lowFirst = tolower (lowFirst); |
| - | while (TRUE) |
| - | { |
| - | while (*string && (*string != lowFirst) && |
| - | (!isupper(*string) || (tolower(*string) != lowFirst))) |
| - | { |
| - | string++; |
| - | } |
| - | |
| - | if (*string == '\0') |
| - | return FALSE; |
| + | while (TRUE) { |
| + | while (*string && (*string != lowFirst) && |
| + | (!isupper (*string) || (tolower (*string) != lowFirst))) { |
| + | string++; |
| + | } |
| - | cp1 = string; |
| - | cp2 = word; |
| + | if (*string == '\0') |
| + | return FALSE; |
| - | do |
| - | { |
| - | if (*cp2 == '\0') |
| - | return TRUE; |
| + | cp1 = string; |
| + | cp2 = word; |
| - | ch1 = *cp1++; |
| + | do { |
| + | if (*cp2 == '\0') |
| + | return TRUE; |
| - | if (isupper(ch1)) |
| - | ch1 = tolower(ch1); |
| + | ch1 = *cp1++; |
| - | ch2 = *cp2++; |
| + | if (isupper (ch1)) |
| + | ch1 = tolower (ch1); |
| - | if (isupper(ch2)) |
| - | ch2 = tolower(ch2); |
| + | ch2 = *cp2++; |
| - | } |
| - | while (ch1 == ch2); |
| + | if (isupper (ch2)) |
| + | ch2 = tolower (ch2); |
| - | string++; |
| } | |
| + | while (ch1 == ch2); |
| + | |
| + | string++; |
| + | } |
| + | return (TRUE); |
| } | |
| #endif | |
| @@ -23,187 +23,174 @@ | |
| const char grep_usage[] = | |
| - | "Search the input file(s) for lines matching the given pattern.\n" |
| - | "\tI search stdin if no files are given.\n" |
| - | "\tI can't grok full regular expressions.\n" |
| - | "usage: grep [in] PATTERN [FILES]...\n" |
| - | "\ti=ignore case, n=list line numbers\n"; |
| + | "Search the input file(s) for lines matching the given pattern.\n" |
| + | "\tI search stdin if no files are given.\n" |
| + | "\tI can't grok full regular expressions.\n" |
| + | "usage: grep [in] PATTERN [FILES]...\n" |
| + | "\ti=ignore case, n=list line numbers\n"; |
| - | static BOOL search |
| - | (const char * string, const char * word, BOOL ignoreCase); |
| + | static BOOL search (const char *string, const char *word, BOOL ignoreCase); |
| - | extern int |
| - | grep_main(int argc, char ** argv) |
| + | extern int grep_main (int argc, char **argv) |
| { | |
| - | FILE * fp; |
| - | const char * word; |
| - | const char * name; |
| - | const char * cp; |
| - | BOOL tellName; |
| - | BOOL ignoreCase; |
| - | BOOL tellLine; |
| - | long line; |
| - | char buf[BUF_SIZE]; |
| - | |
| - | ignoreCase = FALSE; |
| - | tellLine = FALSE; |
| - | |
| + | FILE *fp; |
| + | const char *word; |
| + | const char *name; |
| + | const char *cp; |
| + | BOOL tellName; |
| + | BOOL ignoreCase; |
| + | BOOL tellLine; |
| + | long line; |
| + | char buf[BUF_SIZE]; |
| + | |
| + | ignoreCase = FALSE; |
| + | tellLine = FALSE; |
| + | |
| + | argc--; |
| + | argv++; |
| + | if (argc < 1) { |
| + | fprintf (stderr, "%s", grep_usage); |
| + | return 1; |
| + | } |
| + | |
| + | if (**argv == '-') { |
| argc--; | |
| - | argv++; |
| - | if (argc < 1) |
| - | { |
| - | fprintf(stderr, "%s", grep_usage); |
| - | return 1; |
| - | } |
| + | cp = *argv++; |
| - | if (**argv == '-') |
| - | { |
| - | argc--; |
| - | cp = *argv++; |
| - | |
| - | while (*++cp) switch (*cp) |
| - | { |
| - | case 'i': |
| - | ignoreCase = TRUE; |
| - | break; |
| - | |
| - | case 'n': |
| - | tellLine = TRUE; |
| - | break; |
| - | |
| - | default: |
| - | fprintf(stderr, "Unknown option\n"); |
| - | return 1; |
| - | } |
| - | } |
| + | while (*++cp) |
| + | switch (*cp) { |
| + | case 'i': |
| + | ignoreCase = TRUE; |
| + | break; |
| - | word = *argv++; |
| - | argc--; |
| + | case 'n': |
| + | tellLine = TRUE; |
| + | break; |
| - | tellName = (argc > 1); |
| + | default: |
| + | fprintf (stderr, "Unknown option\n"); |
| + | return 1; |
| + | } |
| + | } |
| - | while (argc-- > 0) |
| - | { |
| - | name = *argv++; |
| + | word = *argv++; |
| + | argc--; |
| - | fp = fopen(name, "r"); |
| + | tellName = (argc > 1); |
| - | if (fp == NULL) |
| - | { |
| - | perror(name); |
| + | while (argc-- > 0) { |
| + | name = *argv++; |
| - | continue; |
| - | } |
| + | fp = fopen (name, "r"); |
| - | line = 0; |
| + | if (fp == NULL) { |
| + | perror (name); |
| - | while (fgets(buf, sizeof(buf), fp)) |
| - | { |
| - | line++; |
| + | continue; |
| + | } |
| - | cp = &buf[strlen(buf) - 1]; |
| + | line = 0; |
| - | if (*cp != '\n') |
| - | fprintf(stderr, "%s: Line too long\n", name); |
| + | while (fgets (buf, sizeof (buf), fp)) { |
| + | line++; |
| - | if (search(buf, word, ignoreCase)) |
| - | { |
| - | if (tellName) |
| - | printf("%s: ", name); |
| + | cp = &buf[strlen (buf) - 1]; |
| - | if (tellLine) |
| - | printf("%ld: ", line); |
| + | if (*cp != '\n') |
| + | fprintf (stderr, "%s: Line too long\n", name); |
| - | fputs(buf, stdout); |
| - | } |
| - | } |
| + | if (search (buf, word, ignoreCase)) { |
| + | if (tellName) |
| + | printf ("%s: ", name); |
| - | if (ferror(fp)) |
| - | perror(name); |
| + | if (tellLine) |
| + | printf ("%ld: ", line); |
| - | fclose(fp); |
| + | fputs (buf, stdout); |
| + | } |
| } | |
| - | return 0; |
| + | |
| + | if (ferror (fp)) |
| + | perror (name); |
| + | |
| + | fclose (fp); |
| + | } |
| + | return 0; |
| } | |
| /* | |
| * See if the specified word is found in the specified string. | |
| */ | |
| - | static BOOL |
| - | search(const char * string, const char * word, BOOL ignoreCase) |
| + | static BOOL search (const char *string, const char *word, BOOL ignoreCase) |
| { | |
| - | const char * cp1; |
| - | const char * cp2; |
| - | int len; |
| - | int lowFirst; |
| - | int ch1; |
| - | int ch2; |
| + | const char *cp1; |
| + | const char *cp2; |
| + | int len; |
| + | int lowFirst; |
| + | int ch1; |
| + | int ch2; |
| - | len = strlen(word); |
| + | len = strlen (word); |
| - | if (!ignoreCase) |
| - | { |
| - | while (TRUE) |
| - | { |
| - | string = strchr(string, word[0]); |
| + | if (!ignoreCase) { |
| + | while (TRUE) { |
| + | string = strchr (string, word[0]); |
| - | if (string == NULL) |
| - | return FALSE; |
| + | if (string == NULL) |
| + | return FALSE; |
| - | if (memcmp(string, word, len) == 0) |
| - | return TRUE; |
| + | if (memcmp (string, word, len) == 0) |
| + | return TRUE; |
| - | string++; |
| - | } |
| + | string++; |
| } | |
| + | } |
| - | /* |
| - | * Here if we need to check case independence. |
| - | * Do the search by lower casing both strings. |
| - | */ |
| - | lowFirst = *word; |
| + | /* |
| + | * Here if we need to check case independence. |
| + | * Do the search by lower casing both strings. |
| + | */ |
| + | lowFirst = *word; |
| - | if (isupper(lowFirst)) |
| - | lowFirst = tolower(lowFirst); |
| + | if (isupper (lowFirst)) |
| + | lowFirst = tolower (lowFirst); |
| - | while (TRUE) |
| - | { |
| - | while (*string && (*string != lowFirst) && |
| - | (!isupper(*string) || (tolower(*string) != lowFirst))) |
| - | { |
| - | string++; |
| - | } |
| - | |
| - | if (*string == '\0') |
| - | return FALSE; |
| + | while (TRUE) { |
| + | while (*string && (*string != lowFirst) && |
| + | (!isupper (*string) || (tolower (*string) != lowFirst))) { |
| + | string++; |
| + | } |
| - | cp1 = string; |
| - | cp2 = word; |
| + | if (*string == '\0') |
| + | return FALSE; |
| - | do |
| - | { |
| - | if (*cp2 == '\0') |
| - | return TRUE; |
| + | cp1 = string; |
| + | cp2 = word; |
| - | ch1 = *cp1++; |
| + | do { |
| + | if (*cp2 == '\0') |
| + | return TRUE; |
| - | if (isupper(ch1)) |
| - | ch1 = tolower(ch1); |
| + | ch1 = *cp1++; |
| - | ch2 = *cp2++; |
| + | if (isupper (ch1)) |
| + | ch1 = tolower (ch1); |
| - | if (isupper(ch2)) |
| - | ch2 = tolower(ch2); |
| + | ch2 = *cp2++; |
| - | } |
| - | while (ch1 == ch2); |
| + | if (isupper (ch2)) |
| + | ch2 = tolower (ch2); |
| - | string++; |
| } | |
| + | while (ch1 == ch2); |
| + | |
| + | string++; |
| + | } |
| + | return (TRUE); |
| } | |
| #endif | |
| @@ -127,6 +127,7 @@ extern int mnc_main(int argc, char** argv); | |
| extern int monadic_main(int argc, char** argv); | |
| extern int mount_main(int argc, char** argv); | |
| extern int mt_main(int argc, char** argv); | |
| + | extern int mv_main(int argc, char** argv); |
| extern int printf_main(int argc, char** argv); | |
| extern int pwd_main(int argc, char** argv); | |
| extern int reboot_main(int argc, char** argv); | |
| @@ -135,6 +136,7 @@ extern int scan_partitions_main(int argc, char** argv); | |
| extern int sh_main(int argc, char** argv); | |
| extern int sleep_main(int argc, char** argv); | |
| extern int tar_main(int argc, char** argv); | |
| + | extern int touch_main(int argc, char** argv); |
| extern int sync_main(int argc, char** argv); | |
| extern int tput_main(int argc, char** argv); | |
| extern int true_main(int argc, char** argv); | |
| @@ -1,9 +1,29 @@ | |
| /* | |
| - | 3/21/1999 Charles P. Wright <[email protected]> |
| - | searches through fstab when -a is passed |
| - | will try mounting stuff with all fses when passed -t auto |
| - | |
| - | 1999-04-17 Dave Cinege...Rewrote -t auto. Fixed ro mtab. |
| + | * Mini mount implementation for busybox |
| + | * |
| + | * Copyright (C) 1999 by Erik Andersen <[email protected]> |
| + | * |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| + | * General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| + | * |
| + | * 3/21/1999 Charles P. Wright <[email protected]> |
| + | * searches through fstab when -a is passed |
| + | * will try mounting stuff with all fses when passed -t auto |
| + | * |
| + | * 1999-04-17 Dave Cinege...Rewrote -t auto. Fixed ro mtab. |
| + | * 1999-10-07 Erik Andersen. Removed mtab usage, major adjustments, |
| + | * and some serious dieting all around. |
| */ | |
| #include "internal.h" | |
| @@ -15,416 +35,238 @@ | |
| #include <mntent.h> | |
| #include <sys/mount.h> | |
| #include <ctype.h> | |
| - | |
| - | const char mount_usage[] = "mount\n" |
| - | "\t\tmount [flags] special-device directory\n" |
| - | "\n" |
| - | "Flags:\n" |
| - | "\t-a:\tMount all file systems in fstab.\n" |
| - | "\t-f:\t\"Fake\" mount. Add entry to mount table but don't mount it.\n" |
| - | "\t-n:\tDon't write a mount table entry.\n" |
| - | "\t-o option:\tOne of many filesystem options, listed below.\n" |
| - | "\t-r:\tMount the filesystem read-only.\n" |
| - | "\t-t filesystem-type:\tSpecify the filesystem type.\n" |
| - | "\t-w:\tMount for reading and writing (default).\n" |
| - | "\n" |
| - | "Options for use with the \"-o\" flag:\n" |
| - | "\tasync / sync:\tWrites are asynchronous / synchronous.\n" |
| - | "\tdev / nodev:\tAllow use of special device files / disallow them.\n" |
| - | "\texec / noexec:\tAllow use of executable files / disallow them.\n" |
| - | "\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n" |
| - | "\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n" |
| - | "\tro / rw: Mount for read-only / read-write.\n" |
| - | "\t" |
| - | "There are EVEN MORE flags that are specific to each filesystem.\n" |
| - | "You'll have to see the written documentation for those.\n"; |
| + | #include <fstab.h> |
| + | |
| + | const char mount_usage[] = "Usage:\tmount [flags]\n" |
| + | "\tmount [flags] device directory [-o options,more-options]\n" |
| + | "\n" |
| + | "Flags:\n" |
| + | "\t-a:\tMount all file systems in fstab.\n" |
| + | "\t-o option:\tOne of many filesystem options, listed below.\n" |
| + | "\t-r:\tMount the filesystem read-only.\n" |
| + | "\t-t filesystem-type:\tSpecify the filesystem type.\n" |
| + | "\t-w:\tMount for reading and writing (default).\n" |
| + | "\n" |
| + | "Options for use with the \"-o\" flag:\n" |
| + | "\tasync / sync:\tWrites are asynchronous / synchronous.\n" |
| + | "\tdev / nodev:\tAllow use of special device files / disallow them.\n" |
| + | "\texec / noexec:\tAllow use of executable files / disallow them.\n" |
| + | "\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n" |
| + | "\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n" |
| + | "\tro / rw: Mount for read-only / read-write.\n" |
| + | "\t" |
| + | "There are EVEN MORE flags that are specific to each filesystem.\n" |
| + | "You'll have to see the written documentation for those.\n"; |
| struct mount_options { | |
| - | const char * name; |
| - | unsigned long and; |
| - | unsigned long or; |
| + | const char *name; |
| + | unsigned long and; |
| + | unsigned long or; |
| }; | |
| - | static const struct mount_options mount_options[] = { |
| - | { "async", ~MS_SYNCHRONOUS,0 }, |
| - | { "defaults", ~0, 0 }, |
| - | { "dev", ~MS_NODEV, 0 }, |
| - | { "exec", ~MS_NOEXEC, 0 }, |
| - | { "nodev", ~0, MS_NODEV }, |
| - | { "noexec", ~0, MS_NOEXEC }, |
| - | { "nosuid", ~0, MS_NOSUID }, |
| - | { "remount", ~0, MS_REMOUNT }, |
| - | { "ro", ~0, MS_RDONLY }, |
| - | { "rw", ~MS_RDONLY, 0 }, |
| - | { "suid", ~MS_NOSUID, 0 }, |
| - | { "sync", ~0, MS_SYNCHRONOUS }, |
| - | { 0, 0, 0 } |
| + | static const struct mount_options mount_options[] = { |
| + | {"async", ~MS_SYNCHRONOUS, 0}, |
| + | {"defaults", ~0, 0}, |
| + | {"dev", ~MS_NODEV, 0}, |
| + | {"exec", ~MS_NOEXEC, 0}, |
| + | {"nodev", ~0, MS_NODEV}, |
| + | {"noexec", ~0, MS_NOEXEC}, |
| + | {"nosuid", ~0, MS_NOSUID}, |
| + | {"remount", ~0, MS_REMOUNT}, |
| + | {"ro", ~0, MS_RDONLY}, |
| + | {"rw", ~MS_RDONLY, 0}, |
| + | {"suid", ~MS_NOSUID, 0}, |
| + | {"sync", ~0, MS_SYNCHRONOUS}, |
| + | {0, 0, 0} |
| }; | |
| - | static void |
| - | show_flags(unsigned long flags, char * buffer) |
| - | { |
| - | const struct mount_options * f = mount_options; |
| - | while ( f->name ) { |
| - | if ( flags & f->and ) { |
| - | int length = strlen(f->name); |
| - | memcpy(buffer, f->name, length); |
| - | buffer += length; |
| - | *buffer++ = ','; |
| - | *buffer = '\0'; |
| - | } |
| - | f++; |
| - | } |
| - | } |
| static void | |
| - | one_option( |
| - | char * option |
| - | ,unsigned long * flags |
| - | ,char * data) |
| + | parse_mount_options ( char *options, unsigned long *flags, char *data) |
| { | |
| - | const struct mount_options * f = mount_options; |
| - | |
| - | while ( f->name != 0 ) { |
| - | if ( strcasecmp(f->name, option) == 0 ) { |
| - | *flags &= f->and; |
| - | *flags |= f->or; |
| - | return; |
| - | } |
| - | f++; |
| + | printf("option=%s\n", options); |
| + | while (*options) { |
| + | char *comma = strchr (options, ','); |
| + | const struct mount_options* f = mount_options; |
| + | if (comma) |
| + | *comma = '\0'; |
| + | |
| + | printf("checking option=%s vs %s\n", options, f->name); |
| + | while (f->name != 0) { |
| + | printf("checking option=%s vs %s\n", options, f->name); |
| + | if (strcasecmp (f->name, options) == 0) { |
| + | *flags &= f->and; |
| + | *flags |= f->or; |
| + | return; |
| + | } |
| + | f++; |
| } | |
| - | if ( *data ) { |
| - | data += strlen(data); |
| - | *data++ = ','; |
| - | } |
| - | strcpy(data, option); |
| - | } |
| - | |
| - | static void |
| - | parse_mount_options( |
| - | char * options |
| - | ,unsigned long * flags |
| - | ,char * data) |
| - | { |
| - | while ( *options ) { |
| - | char * comma = strchr(options, ','); |
| - | if ( comma ) |
| - | *comma = '\0'; |
| - | one_option(options, flags, data); |
| - | if ( comma ) { |
| - | *comma = ','; |
| - | options = ++comma; |
| - | } |
| - | else |
| - | break; |
| + | if (*data) { |
| + | data += strlen (data); |
| + | *data++ = ','; |
| } | |
| + | strcpy (data, options); |
| + | if (comma) { |
| + | *comma = ','; |
| + | options = ++comma; |
| + | } else |
| + | break; |
| + | } |
| } | |
| int | |
| - | mount_one( |
| - | char * blockDevice |
| - | ,char * directory |
| - | ,char * filesystemType |
| - | ,unsigned long flags |
| - | ,char * string_flags |
| - | ,int noMtab |
| - | ,int fake) |
| + | mount_one ( |
| + | char *blockDevice, char *directory, char *filesystemType, |
| + | unsigned long flags, char *string_flags) |
| { | |
| - | int error = 0; |
| - | int status = 0; |
| - | |
| - | char buf[255]; |
| - | |
| - | if (!fake) { |
| - | if (*filesystemType == 'a') { //Will fail on real FS starting with 'a' |
| - | |
| - | FILE *f = fopen("/proc/filesystems", "r"); |
| - | |
| - | if (f == NULL) return 1; |
| - | |
| - | while (fgets(buf, sizeof(buf), f) != NULL) { |
| - | filesystemType = buf; |
| - | if (*filesystemType == '\t') { // Not a nodev filesystem |
| - | |
| - | while (*filesystemType && *filesystemType != '\n') filesystemType++; |
| - | *filesystemType = '\0'; |
| - | |
| - | filesystemType = buf; |
| - | filesystemType++; //hop past tab |
| - | |
| - | status = mount(blockDevice, directory, filesystemType, |
| - | flags|MS_MGC_VAL ,string_flags); |
| - | error = errno; |
| - | |
| - | if (status == 0) break; |
| - | } |
| - | } |
| - | fclose(f); |
| - | } else { |
| - | |
| - | status = mount( blockDevice, directory, filesystemType, |
| - | flags|MS_MGC_VAL ,string_flags); |
| - | error = errno; |
| - | } |
| - | } |
| - | |
| - | if ( status == 0 ) { |
| - | char * s = &string_flags[strlen(string_flags)]; |
| - | FILE * mountTable; |
| - | if ( s != string_flags ) { |
| - | *s++ = ','; |
| - | show_flags(flags, s); |
| - | } |
| - | if ( !noMtab && (mountTable = setmntent("/etc/mtab", "a+")) ) { |
| - | int length = strlen(directory); |
| - | struct mntent m; |
| + | int status = 0; |
| - | if ( length > 1 && directory[length - 1] == '/' ) |
| - | directory[length - 1] = '\0'; |
| + | char buf[255]; |
| - | if ( filesystemType == 0 ) { |
| - | struct mntent * p |
| - | = findMountPoint(blockDevice, "/proc/mounts"); |
| + | if (strcmp(filesystemType, "auto") == 0) { |
| + | FILE *f = fopen ("/proc/filesystems", "r"); |
| - | if ( p && p->mnt_type ) |
| - | filesystemType = p->mnt_type; |
| - | } |
| - | m.mnt_fsname = blockDevice; |
| - | m.mnt_dir = directory; |
| - | m.mnt_type = filesystemType ? filesystemType : "default"; |
| - | |
| - | if (*string_flags) { |
| - | m.mnt_opts = string_flags; |
| - | } else { |
| - | if ( (flags | MS_RDONLY) == flags ) |
| - | m.mnt_opts = "ro"; |
| - | else |
| - | m.mnt_opts = "rw"; |
| - | } |
| - | |
| - | m.mnt_freq = 0; |
| - | m.mnt_passno = 0; |
| - | addmntent(mountTable, &m); |
| - | endmntent(mountTable); |
| - | } |
| - | return 0; |
| - | } else { |
| - | fprintf(stderr, "Mount %s", blockDevice); |
| - | if ( filesystemType && *filesystemType ) |
| - | fprintf(stderr, " (type %s)", filesystemType); |
| + | if (f == NULL) |
| + | return( FALSE); |
| - | fprintf( |
| - | stderr |
| - | ," on %s: " |
| - | ,directory); |
| + | while (fgets (buf, sizeof (buf), f) != NULL) { |
| + | filesystemType = buf; |
| + | if (*filesystemType == '\t') { // Not a nodev filesystem |
| - | switch ( error ) { |
| - | case EPERM: |
| - | if (geteuid() == 0) |
| - | fprintf( |
| - | stderr |
| - | ,"mount point %s is not a directory" |
| - | ,blockDevice); |
| - | else |
| - | fprintf( |
| - | stderr |
| - | ,"must be superuser to use mount"); |
| - | break; |
| - | case EBUSY: |
| - | fprintf( |
| - | stderr |
| - | ,"%s already mounted or %s busy" |
| - | ,blockDevice |
| - | ,directory); |
| - | break; |
| - | case ENOENT: |
| - | { |
| - | struct stat statbuf; |
| - | if ( stat(directory, &statbuf) != 0 ) |
| - | fprintf( |
| - | stderr |
| - | ,"directory %s does not exist" |
| - | ,directory); |
| - | else if ( stat(blockDevice, &statbuf) != 0 ) |
| - | fprintf( |
| - | stderr |
| - | ,"block device %s does not exist" |
| - | ,blockDevice); |
| - | else |
| - | fprintf( |
| - | stderr |
| - | ,"%s is not mounted on %s, but the mount table says it is." |
| - | ,blockDevice |
| - | ,directory); |
| - | break; |
| - | } |
| - | case ENOTDIR: |
| - | fprintf( |
| - | stderr |
| - | ,"%s is not a directory" |
| - | ,directory); |
| - | break; |
| - | case EINVAL: |
| - | fprintf( |
| - | stderr |
| - | ,"wrong filesystem type, or bad superblock on %s" |
| - | ,blockDevice); |
| - | break; |
| - | case EMFILE: |
| - | fprintf(stderr, "mount table full"); |
| - | break; |
| - | case EIO: |
| - | fprintf( |
| - | stderr |
| - | ,"I/O error reading %s" |
| - | ,blockDevice); |
| - | break; |
| - | case ENODEV: |
| - | { |
| - | FILE * f = fopen("/proc/filesystems", "r"); |
| + | // Add NULL termination to each line |
| + | while (*filesystemType && *filesystemType != '\n') |
| + | filesystemType++; |
| + | *filesystemType = '\0'; |
| - | fprintf( |
| - | stderr |
| - | ,"filesystem type %s not in kernel.\n" |
| - | ,filesystemType); |
| - | fprintf(stderr, "Do you need to load a module?\n"); |
| - | if ( f ) { |
| - | char buf[100]; |
| + | filesystemType = buf; |
| + | filesystemType++; // hop past tab |
| - | fprintf( |
| - | stderr |
| - | ,"Here are the filesystem types the kernel" |
| - | " can mount:\n"); |
| - | while ( fgets(buf, sizeof(buf), f) != 0 ) |
| - | fprintf(stderr, "\t%s", buf); |
| - | fclose(f); |
| - | } |
| - | break; |
| - | } |
| - | case ENOTBLK: |
| - | fprintf( |
| - | stderr |
| - | ,"%s is not a block device" |
| - | ,blockDevice); |
| - | break; |
| - | case ENXIO: |
| - | fprintf( |
| - | stderr |
| - | ,"%s is not a valid block device" |
| - | ,blockDevice); |
| - | break; |
| - | default: |
| - | fputs(strerror(errno), stderr); |
| - | } |
| - | putc('\n', stderr); |
| - | return -1; |
| + | status = mount (blockDevice, directory, filesystemType, |
| + | flags | MS_MGC_VAL, string_flags); |
| + | if (status == 0) |
| + | break; |
| + | } |
| } | |
| + | fclose (f); |
| + | } else { |
| + | status = mount (blockDevice, directory, filesystemType, |
| + | flags | MS_MGC_VAL, string_flags); |
| + | } |
| + | |
| + | if (status) { |
| + | fprintf (stderr, "Mounting %s on %s failed: %s\n", |
| + | blockDevice, directory, strerror(errno)); |
| + | return (FALSE); |
| + | } |
| + | return (TRUE); |
| } | |
| - | extern int |
| - | mount_main(struct FileInfo * i, int argc, char * * argv) |
| + | extern int mount_main (int argc, char **argv) |
| { | |
| - | char string_flags[1024]; |
| - | unsigned long flags = 0; |
| - | char * filesystemType = "auto"; |
| - | int fake = 0; |
| - | int noMtab = 0; |
| - | int all = 0; |
| - | |
| - | *string_flags = '\0'; |
| - | |
| - | if ( argc == 1 ) { |
| - | FILE * mountTable; |
| - | if ( (mountTable = setmntent("/etc/mtab", "r")) ) { |
| - | struct mntent * m; |
| - | while ( (m = getmntent(mountTable)) != 0 ) { |
| - | printf( |
| - | "%s on %s type %s (%s)\n" |
| - | ,m->mnt_fsname |
| - | ,m->mnt_dir |
| - | ,m->mnt_type |
| - | ,m->mnt_opts); |
| - | } |
| - | endmntent(mountTable); |
| - | } |
| - | return 0; |
| + | char string_flags[1024]="\0"; |
| + | unsigned long flags = 0; |
| + | char *filesystemType = "auto"; |
| + | int all = 0; |
| + | int i = argc; |
| + | |
| + | if (argc == 1) { |
| + | FILE *mountTable; |
| + | if ((mountTable = setmntent ("/proc/mounts", "r"))) { |
| + | struct mntent *m; |
| + | while ((m = getmntent (mountTable)) != 0) { |
| + | char *blockDevice = m->mnt_fsname; |
| + | if (strcmp (blockDevice, "/dev/root") == 0) |
| + | blockDevice = (getfsfile ("/"))->fs_spec; |
| + | printf ("%s on %s type %s (%s)\n", blockDevice, m->mnt_dir, |
| + | m->mnt_type, m->mnt_opts); |
| + | } |
| + | endmntent (mountTable); |
| } | |
| - | |
| - | while ( argc >= 2 && argv[1][0] == '-' ) { |
| - | switch ( argv[1][1] ) { |
| - | case 'f': |
| - | fake = 1; |
| - | break; |
| - | case 'n': |
| - | noMtab = 1; |
| - | break; |
| - | case 'o': |
| - | if ( argc < 3 ) { |
| - | usage(mount_usage); |
| - | return 1; |
| - | } |
| - | parse_mount_options(argv[2], &flags, string_flags); |
| - | argc--; |
| - | argv++; |
| - | break; |
| - | case 'r': |
| - | flags |= MS_RDONLY; |
| - | break; |
| - | case 't': |
| - | if ( argc < 3 ) { |
| - | usage(mount_usage); |
| - | return 1; |
| - | } |
| - | filesystemType = argv[2]; |
| - | argc--; |
| - | argv++; |
| - | break; |
| - | case 'v': |
| - | break; |
| - | case 'w': |
| - | flags &= ~MS_RDONLY; |
| - | break; |
| - | case 'a': |
| - | all = 1; |
| - | break; |
| - | default: |
| - | usage(mount_usage); |
| - | return 1; |
| + | return( TRUE); |
| + | } |
| + | |
| + | |
| + | /* Parse options */ |
| + | while (**argv) { |
| + | if (**argv == '-') { |
| + | switch (**argv) { |
| + | case 'o': |
| + | if (++argv == 0) { |
| + | fprintf (stderr, "%s\n", mount_usage); |
| + | return( FALSE); |
| } | |
| + | parse_mount_options (*argv, &flags, string_flags); |
| argc--; | |
| argv++; | |
| - | } |
| - | |
| - | if (all == 1) { |
| - | struct mntent *m; |
| - | FILE *f = setmntent("/etc/fstab", "r"); |
| - | |
| - | if (f == NULL) { |
| - | return 1; |
| + | break; |
| + | case 'r': |
| + | flags |= MS_RDONLY; |
| + | break; |
| + | case 't': |
| + | if (++argv == 0) { |
| + | fprintf (stderr, "%s\n", mount_usage); |
| + | return( FALSE); |
| } | |
| + | filesystemType = *argv; |
| + | argc--; |
| + | argv++; |
| + | break; |
| + | case 'w': |
| + | flags &= ~MS_RDONLY; |
| + | break; |
| + | case 'a': |
| + | all = 1; |
| + | break; |
| + | case 'v': |
| + | case 'h': |
| + | case '-': |
| + | fprintf (stderr, "%s\n", mount_usage); |
| + | return( TRUE); |
| + | } |
| + | } |
| + | i--; |
| + | argv++; |
| + | } |
| - | // FIXME: Combine read routine (make new function) with unmount_all to save space. |
| + | if (all == 1) { |
| + | struct mntent *m; |
| + | FILE *f = setmntent ("/etc/fstab", "r"); |
| - | while ((m = getmntent(f)) != NULL) { |
| - | // If the file system isn't noauto, and isn't mounted on /, mount it |
| - | if ((!strstr(m->mnt_opts, "noauto")) && (m->mnt_dir[1] != '\0') |
| - | && !((m->mnt_type[0] == 's') && (m->mnt_type[1] == 'w')) |
| - | && !((m->mnt_type[0] == 'n') && (m->mnt_type[1] == 'f'))) { |
| - | mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, flags, m->mnt_opts, noMtab, fake); |
| - | } |
| - | } |
| + | if (f == NULL) { |
| + | perror("/etc/fstab"); |
| + | return( FALSE); |
| + | } |
| + | // FIXME: Combine read routine (make new function) with unmount_all |
| + | // to save space. |
| + | |
| + | while ((m = getmntent (f)) != NULL) { |
| + | // If the file system isn't noauto, and isn't mounted on /, mount |
| + | // it |
| + | if ((!strstr (m->mnt_opts, "noauto")) |
| + | && (m->mnt_dir[1] != '\0') && !((m->mnt_type[0] == 's') |
| + | && (m->mnt_type[1] == 'w')) |
| + | && !((m->mnt_type[0] == 'n') && (m->mnt_type[1] == 'f'))) { |
| + | mount_one (m->mnt_fsname, m->mnt_dir, m->mnt_type, flags, |
| + | m->mnt_opts); |
| + | } |
| + | } |
| - | endmntent(f); |
| + | endmntent (f); |
| + | } else { |
| + | if (argc >= 3) { |
| + | while (i < argc) |
| + | argv--; |
| + | while (**argv == '-') |
| + | argv++; |
| + | if (mount_one |
| + | (*argv, *(argv+1), filesystemType, flags, |
| + | string_flags) == 0) return 0; |
| + | else |
| + | return( FALSE); |
| } else { | |
| - | if ( argc >= 3 ) { |
| - | if ( mount_one( argv[1], argv[2], filesystemType, flags, string_flags, noMtab, fake) == 0 ) |
| - | return 0; |
| - | else |
| - | return 1; |
| - | } else { |
| - | usage(mount_usage); |
| - | return 1; |
| - | } |
| + | fprintf (stderr, "%s\n", mount_usage); |
| + | return( FALSE); |
| } | |
| - | return 0; |
| + | } |
| + | return( TRUE); |
| } | |
| @@ -1,38 +1,84 @@ | |
| + | /* |
| + | * Mini mv implementation for busybox |
| + | * |
| + | * Copyright (C) 1998 by Erik Andersen <[email protected]> |
| + | * |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| + | * General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| + | * |
| + | */ |
| + | |
| #include "internal.h" | |
| #include <stdio.h> | |
| + | #include <sys/types.h> |
| + | #include <sys/stat.h> |
| + | #include <fcntl.h> |
| + | #include <utime.h> |
| #include <errno.h> | |
| - | const char mv_usage[] = "mv source-file destination-file\n" |
| - | "\t\tmv source-file [source-file ...] destination-directory\n" |
| - | "\n" |
| - | "\tMove the source files to the destination.\n" |
| - | "\n"; |
| + | const char mv_usage[] = "source-file [source-file ...] destination-file\n" |
| + | "\n" "\tMove the source files to the destination.\n" "\n"; |
| + | |
| - | extern int |
| - | mv_fn(const struct FileInfo * i) |
| + | |
| + | extern int mv_main (int argc, char **argv) |
| { | |
| - | struct stat destination_stat; |
| - | char d[1024]; |
| - | struct FileInfo n; |
| - | |
| - | if ( stat(i->destination, &destination_stat) == 0 ) { |
| - | if ( i->stat.st_ino == destination_stat.st_ino |
| - | && i->stat.st_dev == destination_stat.st_dev ) |
| - | return 0; /* Move file to itself. */ |
| - | } |
| - | if ( (destination_stat.st_mode & S_IFMT) == S_IFDIR ) { |
| - | n = *i; |
| - | n.destination = join_paths(d, i->destination, basename(i->source)); |
| - | i = &n; |
| + | const char *srcName; |
| + | const char *destName; |
| + | const char *lastArg; |
| + | BOOL dirFlag; |
| + | |
| + | if (argc < 3) { |
| + | fprintf (stderr, "Usage: %s %s", *argv, mv_usage); |
| + | return (FALSE); |
| + | } |
| + | lastArg = argv[argc - 1]; |
| + | |
| + | dirFlag = isDirectory (lastArg); |
| + | |
| + | if ((argc > 3) && !dirFlag) { |
| + | fprintf (stderr, "%s: not a directory\n", lastArg); |
| + | |
| + | return (FALSE); |
| + | } |
| + | |
| + | while (argc-- > 2) { |
| + | srcName = *(++argv); |
| + | |
| + | if (access (srcName, 0) < 0) { |
| + | perror (srcName); |
| + | continue; |
| } | |
| - | if ( rename(i->source, i->destination) == 0 ) |
| - | return 0; |
| - | else if ( errno == EXDEV && is_a_directory(i->source) ) { |
| - | fprintf(stderr |
| - | ,"%s: Can't move directory across filesystems.\n" |
| - | ,i->source); |
| - | return 1; |
| + | |
| + | destName = lastArg; |
| + | |
| + | if (dirFlag) |
| + | destName = buildName (destName, srcName); |
| + | |
| + | if (rename (srcName, destName) >= 0) |
| + | continue; |
| + | |
| + | if (errno != EXDEV) { |
| + | perror (destName); |
| + | continue; |
| } | |
| - | else |
| - | return cp_fn(i); |
| + | |
| + | if (!copyFile (srcName, destName, TRUE)) |
| + | continue; |
| + | |
| + | if (unlink (srcName) < 0) |
| + | perror (srcName); |
| + | } |
| + | return (TRUE); |
| } | |
| @@ -1,20 +1,85 @@ | |
| + | /* |
| + | * Mini touch implementation for busybox |
| + | * |
| + | * Copyright (C) 1998 by Erik Andersen <[email protected]> |
| + | * |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| + | * General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| + | * |
| + | */ |
| + | |
| #include "internal.h" | |
| - | #include <sys/types.h> |
| #include <stdio.h> | |
| + | #include <sys/types.h> |
| + | #include <sys/stat.h> |
| + | #include <fcntl.h> |
| #include <utime.h> | |
| + | #include <errno.h> |
| + | |
| - | const char touch_usage[] = "touch [-c] file [file ...]\n" |
| - | "\n" |
| + | const char touch_usage[] = "touch [-c] file [file ...]\n\n" |
| "\tUpdate the last-modified date on the given file[s].\n"; | |
| - | extern int |
| - | touch_fn(const struct FileInfo * i) |
| + | |
| + | |
| + | extern int |
| + | touch_main(int argc, char **argv) |
| { | |
| - | if ( (utime(i->source, 0) != 0) && (i->create != 1) ) { |
| - | if ( fopen(i->source, "w") == NULL ) { |
| - | name_and_error(i->source); |
| - | return 1; |
| - | } |
| + | int fd; |
| + | int create=TRUE; |
| + | |
| + | if (argc < 2) { |
| + | fprintf(stderr, "Usage: %s %s", *argv, touch_usage); |
| + | exit( FALSE); |
| + | } |
| + | argc--; |
| + | argv++; |
| + | |
| + | /* Parse options */ |
| + | while (**argv == '-') { |
| + | while (*++(*argv)) switch (**argv) { |
| + | case 'c': |
| + | create = FALSE; |
| + | break; |
| + | default: |
| + | fprintf(stderr, "Unknown option: %c\n", **argv); |
| + | exit( FALSE); |
| } | |
| - | return 0; |
| + | argc--; |
| + | argv++; |
| + | } |
| + | |
| + | fd = open (*argv, (create==FALSE)? O_RDWR : O_RDWR | O_CREAT, 0644); |
| + | if (fd < 0 ) { |
| + | if (create==FALSE && errno == ENOENT) |
| + | exit( TRUE); |
| + | else { |
| + | perror("touch"); |
| + | exit( FALSE); |
| + | } |
| + | } |
| + | close( fd); |
| + | if (utime (*argv, NULL)) { |
| + | perror("touch"); |
| + | exit( FALSE); |
| + | } |
| + | else |
| + | exit( TRUE); |
| } | |
| + | |
| + | |
| + | |
| + | |
| + | |
| + | |
| @@ -1,9 +1,29 @@ | |
| /* | |
| - | 3/21/1999 Charles P. Wright <[email protected]> |
| - | searches through fstab when -a is passed |
| - | will try mounting stuff with all fses when passed -t auto |
| - | |
| - | 1999-04-17 Dave Cinege...Rewrote -t auto. Fixed ro mtab. |
| + | * Mini mount implementation for busybox |
| + | * |
| + | * Copyright (C) 1999 by Erik Andersen <[email protected]> |
| + | * |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| + | * General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| + | * |
| + | * 3/21/1999 Charles P. Wright <[email protected]> |
| + | * searches through fstab when -a is passed |
| + | * will try mounting stuff with all fses when passed -t auto |
| + | * |
| + | * 1999-04-17 Dave Cinege...Rewrote -t auto. Fixed ro mtab. |
| + | * 1999-10-07 Erik Andersen. Removed mtab usage, major adjustments, |
| + | * and some serious dieting all around. |
| */ | |
| #include "internal.h" | |
| @@ -15,416 +35,238 @@ | |
| #include <mntent.h> | |
| #include <sys/mount.h> | |
| #include <ctype.h> | |
| - | |
| - | const char mount_usage[] = "mount\n" |
| - | "\t\tmount [flags] special-device directory\n" |
| - | "\n" |
| - | "Flags:\n" |
| - | "\t-a:\tMount all file systems in fstab.\n" |
| - | "\t-f:\t\"Fake\" mount. Add entry to mount table but don't mount it.\n" |
| - | "\t-n:\tDon't write a mount table entry.\n" |
| - | "\t-o option:\tOne of many filesystem options, listed below.\n" |
| - | "\t-r:\tMount the filesystem read-only.\n" |
| - | "\t-t filesystem-type:\tSpecify the filesystem type.\n" |
| - | "\t-w:\tMount for reading and writing (default).\n" |
| - | "\n" |
| - | "Options for use with the \"-o\" flag:\n" |
| - | "\tasync / sync:\tWrites are asynchronous / synchronous.\n" |
| - | "\tdev / nodev:\tAllow use of special device files / disallow them.\n" |
| - | "\texec / noexec:\tAllow use of executable files / disallow them.\n" |
| - | "\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n" |
| - | "\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n" |
| - | "\tro / rw: Mount for read-only / read-write.\n" |
| - | "\t" |
| - | "There are EVEN MORE flags that are specific to each filesystem.\n" |
| - | "You'll have to see the written documentation for those.\n"; |
| + | #include <fstab.h> |
| + | |
| + | const char mount_usage[] = "Usage:\tmount [flags]\n" |
| + | "\tmount [flags] device directory [-o options,more-options]\n" |
| + | "\n" |
| + | "Flags:\n" |
| + | "\t-a:\tMount all file systems in fstab.\n" |
| + | "\t-o option:\tOne of many filesystem options, listed below.\n" |
| + | "\t-r:\tMount the filesystem read-only.\n" |
| + | "\t-t filesystem-type:\tSpecify the filesystem type.\n" |
| + | "\t-w:\tMount for reading and writing (default).\n" |
| + | "\n" |
| + | "Options for use with the \"-o\" flag:\n" |
| + | "\tasync / sync:\tWrites are asynchronous / synchronous.\n" |
| + | "\tdev / nodev:\tAllow use of special device files / disallow them.\n" |
| + | "\texec / noexec:\tAllow use of executable files / disallow them.\n" |
| + | "\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n" |
| + | "\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n" |
| + | "\tro / rw: Mount for read-only / read-write.\n" |
| + | "\t" |
| + | "There are EVEN MORE flags that are specific to each filesystem.\n" |
| + | "You'll have to see the written documentation for those.\n"; |
| struct mount_options { | |
| - | const char * name; |
| - | unsigned long and; |
| - | unsigned long or; |
| + | const char *name; |
| + | unsigned long and; |
| + | unsigned long or; |
| }; | |
| - | static const struct mount_options mount_options[] = { |
| - | { "async", ~MS_SYNCHRONOUS,0 }, |
| - | { "defaults", ~0, 0 }, |
| - | { "dev", ~MS_NODEV, 0 }, |
| - | { "exec", ~MS_NOEXEC, 0 }, |
| - | { "nodev", ~0, MS_NODEV }, |
| - | { "noexec", ~0, MS_NOEXEC }, |
| - | { "nosuid", ~0, MS_NOSUID }, |
| - | { "remount", ~0, MS_REMOUNT }, |
| - | { "ro", ~0, MS_RDONLY }, |
| - | { "rw", ~MS_RDONLY, 0 }, |
| - | { "suid", ~MS_NOSUID, 0 }, |
| - | { "sync", ~0, MS_SYNCHRONOUS }, |
| - | { 0, 0, 0 } |
| + | static const struct mount_options mount_options[] = { |
| + | {"async", ~MS_SYNCHRONOUS, 0}, |
| + | {"defaults", ~0, 0}, |
| + | {"dev", ~MS_NODEV, 0}, |
| + | {"exec", ~MS_NOEXEC, 0}, |
| + | {"nodev", ~0, MS_NODEV}, |
| + | {"noexec", ~0, MS_NOEXEC}, |
| + | {"nosuid", ~0, MS_NOSUID}, |
| + | {"remount", ~0, MS_REMOUNT}, |
| + | {"ro", ~0, MS_RDONLY}, |
| + | {"rw", ~MS_RDONLY, 0}, |
| + | {"suid", ~MS_NOSUID, 0}, |
| + | {"sync", ~0, MS_SYNCHRONOUS}, |
| + | {0, 0, 0} |
| }; | |
| - | static void |
| - | show_flags(unsigned long flags, char * buffer) |
| - | { |
| - | const struct mount_options * f = mount_options; |
| - | while ( f->name ) { |
| - | if ( flags & f->and ) { |
| - | int length = strlen(f->name); |
| - | memcpy(buffer, f->name, length); |
| - | buffer += length; |
| - | *buffer++ = ','; |
| - | *buffer = '\0'; |
| - | } |
| - | f++; |
| - | } |
| - | } |
| static void | |
| - | one_option( |
| - | char * option |
| - | ,unsigned long * flags |
| - | ,char * data) |
| + | parse_mount_options ( char *options, unsigned long *flags, char *data) |
| { | |
| - | const struct mount_options * f = mount_options; |
| - | |
| - | while ( f->name != 0 ) { |
| - | if ( strcasecmp(f->name, option) == 0 ) { |
| - | *flags &= f->and; |
| - | *flags |= f->or; |
| - | return; |
| - | } |
| - | f++; |
| + | printf("option=%s\n", options); |
| + | while (*options) { |
| + | char *comma = strchr (options, ','); |
| + | const struct mount_options* f = mount_options; |
| + | if (comma) |
| + | *comma = '\0'; |
| + | |
| + | printf("checking option=%s vs %s\n", options, f->name); |
| + | while (f->name != 0) { |
| + | printf("checking option=%s vs %s\n", options, f->name); |
| + | if (strcasecmp (f->name, options) == 0) { |
| + | *flags &= f->and; |
| + | *flags |= f->or; |
| + | return; |
| + | } |
| + | f++; |
| } | |
| - | if ( *data ) { |
| - | data += strlen(data); |
| - | *data++ = ','; |
| - | } |
| - | strcpy(data, option); |
| - | } |
| - | |
| - | static void |
| - | parse_mount_options( |
| - | char * options |
| - | ,unsigned long * flags |
| - | ,char * data) |
| - | { |
| - | while ( *options ) { |
| - | char * comma = strchr(options, ','); |
| - | if ( comma ) |
| - | *comma = '\0'; |
| - | one_option(options, flags, data); |
| - | if ( comma ) { |
| - | *comma = ','; |
| - | options = ++comma; |
| - | } |
| - | else |
| - | break; |
| + | if (*data) { |
| + | data += strlen (data); |
| + | *data++ = ','; |
| } | |
| + | strcpy (data, options); |
| + | if (comma) { |
| + | *comma = ','; |
| + | options = ++comma; |
| + | } else |
| + | break; |
| + | } |
| } | |
| int | |
| - | mount_one( |
| - | char * blockDevice |
| - | ,char * directory |
| - | ,char * filesystemType |
| - | ,unsigned long flags |
| - | ,char * string_flags |
| - | ,int noMtab |
| - | ,int fake) |
| + | mount_one ( |
| + | char *blockDevice, char *directory, char *filesystemType, |
| + | unsigned long flags, char *string_flags) |
| { | |
| - | int error = 0; |
| - | int status = 0; |
| - | |
| - | char buf[255]; |
| - | |
| - | if (!fake) { |
| - | if (*filesystemType == 'a') { //Will fail on real FS starting with 'a' |
| - | |
| - | FILE *f = fopen("/proc/filesystems", "r"); |
| - | |
| - | if (f == NULL) return 1; |
| - | |
| - | while (fgets(buf, sizeof(buf), f) != NULL) { |
| - | filesystemType = buf; |
| - | if (*filesystemType == '\t') { // Not a nodev filesystem |
| - | |
| - | while (*filesystemType && *filesystemType != '\n') filesystemType++; |
| - | *filesystemType = '\0'; |
| - | |
| - | filesystemType = buf; |
| - | filesystemType++; //hop past tab |
| - | |
| - | status = mount(blockDevice, directory, filesystemType, |
| - | flags|MS_MGC_VAL ,string_flags); |
| - | error = errno; |
| - | |
| - | if (status == 0) break; |
| - | } |
| - | } |
| - | fclose(f); |
| - | } else { |
| - | |
| - | status = mount( blockDevice, directory, filesystemType, |
| - | flags|MS_MGC_VAL ,string_flags); |
| - | error = errno; |
| - | } |
| - | } |
| - | |
| - | if ( status == 0 ) { |
| - | char * s = &string_flags[strlen(string_flags)]; |
| - | FILE * mountTable; |
| - | if ( s != string_flags ) { |
| - | *s++ = ','; |
| - | show_flags(flags, s); |
| - | } |
| - | if ( !noMtab && (mountTable = setmntent("/etc/mtab", "a+")) ) { |
| - | int length = strlen(directory); |
| - | struct mntent m; |
| + | int status = 0; |
| - | if ( length > 1 && directory[length - 1] == '/' ) |
| - | directory[length - 1] = '\0'; |
| + | char buf[255]; |
| - | if ( filesystemType == 0 ) { |
| - | struct mntent * p |
| - | = findMountPoint(blockDevice, "/proc/mounts"); |
| + | if (strcmp(filesystemType, "auto") == 0) { |
| + | FILE *f = fopen ("/proc/filesystems", "r"); |
| - | if ( p && p->mnt_type ) |
| - | filesystemType = p->mnt_type; |
| - | } |
| - | m.mnt_fsname = blockDevice; |
| - | m.mnt_dir = directory; |
| - | m.mnt_type = filesystemType ? filesystemType : "default"; |
| - | |
| - | if (*string_flags) { |
| - | m.mnt_opts = string_flags; |
| - | } else { |
| - | if ( (flags | MS_RDONLY) == flags ) |
| - | m.mnt_opts = "ro"; |
| - | else |
| - | m.mnt_opts = "rw"; |
| - | } |
| - | |
| - | m.mnt_freq = 0; |
| - | m.mnt_passno = 0; |
| - | addmntent(mountTable, &m); |
| - | endmntent(mountTable); |
| - | } |
| - | return 0; |
| - | } else { |
| - | fprintf(stderr, "Mount %s", blockDevice); |
| - | if ( filesystemType && *filesystemType ) |
| - | fprintf(stderr, " (type %s)", filesystemType); |
| + | if (f == NULL) |
| + | return( FALSE); |
| - | fprintf( |
| - | stderr |
| - | ," on %s: " |
| - | ,directory); |
| + | while (fgets (buf, sizeof (buf), f) != NULL) { |
| + | filesystemType = buf; |
| + | if (*filesystemType == '\t') { // Not a nodev filesystem |
| - | switch ( error ) { |
| - | case EPERM: |
| - | if (geteuid() == 0) |
| - | fprintf( |
| - | stderr |
| - | ,"mount point %s is not a directory" |
| - | ,blockDevice); |
| - | else |
| - | fprintf( |
| - | stderr |
| - | ,"must be superuser to use mount"); |
| - | break; |
| - | case EBUSY: |
| - | fprintf( |
| - | stderr |
| - | ,"%s already mounted or %s busy" |
| - | ,blockDevice |
| - | ,directory); |
| - | break; |
| - | case ENOENT: |
| - | { |
| - | struct stat statbuf; |
| - | if ( stat(directory, &statbuf) != 0 ) |
| - | fprintf( |
| - | stderr |
| - | ,"directory %s does not exist" |
| - | ,directory); |
| - | else if ( stat(blockDevice, &statbuf) != 0 ) |
| - | fprintf( |
| - | stderr |
| - | ,"block device %s does not exist" |
| - | ,blockDevice); |
| - | else |
| - | fprintf( |
| - | stderr |
| - | ,"%s is not mounted on %s, but the mount table says it is." |
| - | ,blockDevice |
| - | ,directory); |
| - | break; |
| - | } |
| - | case ENOTDIR: |
| - | fprintf( |
| - | stderr |
| - | ,"%s is not a directory" |
| - | ,directory); |
| - | break; |
| - | case EINVAL: |
| - | fprintf( |
| - | stderr |
| - | ,"wrong filesystem type, or bad superblock on %s" |
| - | ,blockDevice); |
| - | break; |
| - | case EMFILE: |
| - | fprintf(stderr, "mount table full"); |
| - | break; |
| - | case EIO: |
| - | fprintf( |
| - | stderr |
| - | ,"I/O error reading %s" |
| - | ,blockDevice); |
| - | break; |
| - | case ENODEV: |
| - | { |
| - | FILE * f = fopen("/proc/filesystems", "r"); |
| + | // Add NULL termination to each line |
| + | while (*filesystemType && *filesystemType != '\n') |
| + | filesystemType++; |
| + | *filesystemType = '\0'; |
| - | fprintf( |
| - | stderr |
| - | ,"filesystem type %s not in kernel.\n" |
| - | ,filesystemType); |
| - | fprintf(stderr, "Do you need to load a module?\n"); |
| - | if ( f ) { |
| - | char buf[100]; |
| + | filesystemType = buf; |
| + | filesystemType++; // hop past tab |
| - | fprintf( |
| - | stderr |
| - | ,"Here are the filesystem types the kernel" |
| - | " can mount:\n"); |
| - | while ( fgets(buf, sizeof(buf), f) != 0 ) |
| - | fprintf(stderr, "\t%s", buf); |
| - | fclose(f); |
| - | } |
| - | break; |
| - | } |
| - | case ENOTBLK: |
| - | fprintf( |
| - | stderr |
| - | ,"%s is not a block device" |
| - | ,blockDevice); |
| - | break; |
| - | case ENXIO: |
| - | fprintf( |
| - | stderr |
| - | ,"%s is not a valid block device" |
| - | ,blockDevice); |
| - | break; |
| - | default: |
| - | fputs(strerror(errno), stderr); |
| - | } |
| - | putc('\n', stderr); |
| - | return -1; |
| + | status = mount (blockDevice, directory, filesystemType, |
| + | flags | MS_MGC_VAL, string_flags); |
| + | if (status == 0) |
| + | break; |
| + | } |
| } | |
| + | fclose (f); |
| + | } else { |
| + | status = mount (blockDevice, directory, filesystemType, |
| + | flags | MS_MGC_VAL, string_flags); |
| + | } |
| + | |
| + | if (status) { |
| + | fprintf (stderr, "Mounting %s on %s failed: %s\n", |
| + | blockDevice, directory, strerror(errno)); |
| + | return (FALSE); |
| + | } |
| + | return (TRUE); |
| } | |
| - | extern int |
| - | mount_main(struct FileInfo * i, int argc, char * * argv) |
| + | extern int mount_main (int argc, char **argv) |
| { | |
| - | char string_flags[1024]; |
| - | unsigned long flags = 0; |
| - | char * filesystemType = "auto"; |
| - | int fake = 0; |
| - | int noMtab = 0; |
| - | int all = 0; |
| - | |
| - | *string_flags = '\0'; |
| - | |
| - | if ( argc == 1 ) { |
| - | FILE * mountTable; |
| - | if ( (mountTable = setmntent("/etc/mtab", "r")) ) { |
| - | struct mntent * m; |
| - | while ( (m = getmntent(mountTable)) != 0 ) { |
| - | printf( |
| - | "%s on %s type %s (%s)\n" |
| - | ,m->mnt_fsname |
| - | ,m->mnt_dir |
| - | ,m->mnt_type |
| - | ,m->mnt_opts); |
| - | } |
| - | endmntent(mountTable); |
| - | } |
| - | return 0; |
| + | char string_flags[1024]="\0"; |
| + | unsigned long flags = 0; |
| + | char *filesystemType = "auto"; |
| + | int all = 0; |
| + | int i = argc; |
| + | |
| + | if (argc == 1) { |
| + | FILE *mountTable; |
| + | if ((mountTable = setmntent ("/proc/mounts", "r"))) { |
| + | struct mntent *m; |
| + | while ((m = getmntent (mountTable)) != 0) { |
| + | char *blockDevice = m->mnt_fsname; |
| + | if (strcmp (blockDevice, "/dev/root") == 0) |
| + | blockDevice = (getfsfile ("/"))->fs_spec; |
| + | printf ("%s on %s type %s (%s)\n", blockDevice, m->mnt_dir, |
| + | m->mnt_type, m->mnt_opts); |
| + | } |
| + | endmntent (mountTable); |
| } | |
| - | |
| - | while ( argc >= 2 && argv[1][0] == '-' ) { |
| - | switch ( argv[1][1] ) { |
| - | case 'f': |
| - | fake = 1; |
| - | break; |
| - | case 'n': |
| - | noMtab = 1; |
| - | break; |
| - | case 'o': |
| - | if ( argc < 3 ) { |
| - | usage(mount_usage); |
| - | return 1; |
| - | } |
| - | parse_mount_options(argv[2], &flags, string_flags); |
| - | argc--; |
| - | argv++; |
| - | break; |
| - | case 'r': |
| - | flags |= MS_RDONLY; |
| - | break; |
| - | case 't': |
| - | if ( argc < 3 ) { |
| - | usage(mount_usage); |
| - | return 1; |
| - | } |
| - | filesystemType = argv[2]; |
| - | argc--; |
| - | argv++; |
| - | break; |
| - | case 'v': |
| - | break; |
| - | case 'w': |
| - | flags &= ~MS_RDONLY; |
| - | break; |
| - | case 'a': |
| - | all = 1; |
| - | break; |
| - | default: |
| - | usage(mount_usage); |
| - | return 1; |
| + | return( TRUE); |
| + | } |
| + | |
| + | |
| + | /* Parse options */ |
| + | while (**argv) { |
| + | if (**argv == '-') { |
| + | switch (**argv) { |
| + | case 'o': |
| + | if (++argv == 0) { |
| + | fprintf (stderr, "%s\n", mount_usage); |
| + | return( FALSE); |
| } | |
| + | parse_mount_options (*argv, &flags, string_flags); |
| argc--; | |
| argv++; | |
| - | } |
| - | |
| - | if (all == 1) { |
| - | struct mntent *m; |
| - | FILE *f = setmntent("/etc/fstab", "r"); |
| - | |
| - | if (f == NULL) { |
| - | return 1; |
| + | break; |
| + | case 'r': |
| + | flags |= MS_RDONLY; |
| + | break; |
| + | case 't': |
| + | if (++argv == 0) { |
| + | fprintf (stderr, "%s\n", mount_usage); |
| + | return( FALSE); |
| } | |
| + | filesystemType = *argv; |
| + | argc--; |
| + | argv++; |
| + | break; |
| + | case 'w': |
| + | flags &= ~MS_RDONLY; |
| + | break; |
| + | case 'a': |
| + | all = 1; |
| + | break; |
| + | case 'v': |
| + | case 'h': |
| + | case '-': |
| + | fprintf (stderr, "%s\n", mount_usage); |
| + | return( TRUE); |
| + | } |
| + | } |
| + | i--; |
| + | argv++; |
| + | } |
| - | // FIXME: Combine read routine (make new function) with unmount_all to save space. |
| + | if (all == 1) { |
| + | struct mntent *m; |
| + | FILE *f = setmntent ("/etc/fstab", "r"); |
| - | while ((m = getmntent(f)) != NULL) { |
| - | // If the file system isn't noauto, and isn't mounted on /, mount it |
| - | if ((!strstr(m->mnt_opts, "noauto")) && (m->mnt_dir[1] != '\0') |
| - | && !((m->mnt_type[0] == 's') && (m->mnt_type[1] == 'w')) |
| - | && !((m->mnt_type[0] == 'n') && (m->mnt_type[1] == 'f'))) { |
| - | mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, flags, m->mnt_opts, noMtab, fake); |
| - | } |
| - | } |
| + | if (f == NULL) { |
| + | perror("/etc/fstab"); |
| + | return( FALSE); |
| + | } |
| + | // FIXME: Combine read routine (make new function) with unmount_all |
| + | // to save space. |
| + | |
| + | while ((m = getmntent (f)) != NULL) { |
| + | // If the file system isn't noauto, and isn't mounted on /, mount |
| + | // it |
| + | if ((!strstr (m->mnt_opts, "noauto")) |
| + | && (m->mnt_dir[1] != '\0') && !((m->mnt_type[0] == 's') |
| + | && (m->mnt_type[1] == 'w')) |
| + | && !((m->mnt_type[0] == 'n') && (m->mnt_type[1] == 'f'))) { |
| + | mount_one (m->mnt_fsname, m->mnt_dir, m->mnt_type, flags, |
| + | m->mnt_opts); |
| + | } |
| + | } |
| - | endmntent(f); |
| + | endmntent (f); |
| + | } else { |
| + | if (argc >= 3) { |
| + | while (i < argc) |
| + | argv--; |
| + | while (**argv == '-') |
| + | argv++; |
| + | if (mount_one |
| + | (*argv, *(argv+1), filesystemType, flags, |
| + | string_flags) == 0) return 0; |
| + | else |
| + | return( FALSE); |
| } else { | |
| - | if ( argc >= 3 ) { |
| - | if ( mount_one( argv[1], argv[2], filesystemType, flags, string_flags, noMtab, fake) == 0 ) |
| - | return 0; |
| - | else |
| - | return 1; |
| - | } else { |
| - | usage(mount_usage); |
| - | return 1; |
| - | } |
| + | fprintf (stderr, "%s\n", mount_usage); |
| + | return( FALSE); |
| } | |
| - | return 0; |
| + | } |
| + | return( TRUE); |
| } | |