From fdd51033480e6d93af274bfd0df25b14aaea6c3b Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Wed, 2 Aug 2000 18:48:26 +0000 Subject: [PATCH] Merge in two patches from Dave Cinege: the first is a cleanup of tar --exclude the second changes mount so mtab works more as it should, and also allows mount to use the traditional short form (i.e. 'mount / -o remount,rw' now works. While inside tar, I changed it to use getopt... -Erik --- applets/usage.c | 4 +-- archival/tar.c | 94 +++++++++++++++++++++++------------------------------- docs/busybox.pod | 4 +-- docs/busybox.sgml | 8 ++--- mount.c | 88 +++++++++++++++++++++++++++++++------------------- tar.c | 94 +++++++++++++++++++++++------------------------------- usage.c | 4 +-- util-linux/mount.c | 88 +++++++++++++++++++++++++++++++------------------- utility.c | 8 ++--- 9 files changed, 206 insertions(+), 186 deletions(-) diff --git a/applets/usage.c b/applets/usage.c index 1e2eb64..6c3f597 100644 --- a/applets/usage.c +++ b/applets/usage.c @@ -1053,7 +1053,7 @@ const char tar_usage[] = "tar -[xtvO] " #endif #if defined BB_FEATURE_TAR_EXCLUDE - "[-X File(s)] " + "[--exclude File] " #endif "[-f tarFile] [FILE(s)] ...\n" #ifndef BB_FEATURE_TRIVIAL_HELP @@ -1069,7 +1069,7 @@ const char tar_usage[] = "\tf\t\tname of tarfile or \"-\" for stdin\n" "\tO\t\textract to stdout\n" #if defined BB_FEATURE_TAR_EXCLUDE - "\tX\t\tfile(s) to exclude\n" + "\texclude\t\tfile to exclude\n" #endif "\nInformative output:\n" "\tv\t\tverbosely list files processed\n" diff --git a/archival/tar.c b/archival/tar.c index 3227ce5..cab53aa 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -148,85 +148,65 @@ extern int tar_main(int argc, char **argv) int createFlag = FALSE; int verboseFlag = FALSE; int tostdoutFlag = FALSE; - int stopIt; + int opt; if (argc <= 1) usage(tar_usage); - /* Parse any options */ - while (--argc > 0 && strspn(*(++argv), "-cxt") >0 ) { - stopIt=FALSE; - while (stopIt==FALSE && *argv && **argv) { - switch (**argv) { - case 'f': - if (--argc == 0) { - fatalError( "Option requires an argument: No file specified\n"); - } - if (*tarName != '-') - fatalError( "Only one 'f' option allowed\n"); - tarName = *(++argv); - if (tarName == NULL) - fatalError( "Option requires an argument: No file specified\n"); - if (!strcmp(tarName, "-") && createFlag == TRUE) - tostdoutFlag = TRUE; - stopIt=TRUE; - break; - - case 't': - if (extractFlag == TRUE || createFlag == TRUE) + /* do normal option parsing */ + while ((opt = getopt(argc, argv, "cxtvOf:-:")) > 0) { + switch (opt) { + case 'c': + if (extractFlag == TRUE || listFlag == TRUE) goto flagError; - listFlag = TRUE; + createFlag = TRUE; break; - case 'x': if (listFlag == TRUE || createFlag == TRUE) goto flagError; extractFlag = TRUE; break; - case 'c': - if (extractFlag == TRUE || listFlag == TRUE) + case 't': + if (extractFlag == TRUE || createFlag == TRUE) goto flagError; - createFlag = TRUE; + listFlag = TRUE; break; - case 'v': verboseFlag = TRUE; break; - case 'O': tostdoutFlag = TRUE; tarName = "-"; + break; + case 'f': + if (*tarName != '-') + fatalError( "Only one 'f' option allowed\n"); + tarName = optarg; + if (!strcmp(tarName, "-") && createFlag == TRUE) + tostdoutFlag = TRUE; break; case '-': #if defined BB_FEATURE_TAR_EXCLUDE - if (strcmp(*argv, "-exclude")==0) { - if (--argc == 0) { - fatalError( "Option requires an argument: No file specified\n"); - } + if (strcmp(optarg, "exclude")==0) { + if (argv[optind]==NULL) + fatalError( "option `--exclude' requires an argument\n"); excludeList=realloc( excludeList, sizeof(char**) * (excludeListSize+2)); - excludeList[excludeListSize] = *(++argv); + excludeList[excludeListSize] = argv[optind]; /* Remove leading "/"s */ if (*excludeList[excludeListSize] =='/') { excludeList[excludeListSize] = (excludeList[excludeListSize])+1; } - if (excludeList[excludeListSize++] == NULL) - fatalError( "Option requires an argument: No file specified\n"); /* Tack a NULL onto the end of the list */ excludeList[excludeListSize] = NULL; - stopIt=TRUE; + optind++; break; } #endif - if (strcmp(*argv, "-help")==0) { - usage(tar_usage); - } - break; - + fatalError( "Unknown tar flag '%s'\n" + "Try `tar --help' for more information\n", optarg); default: fatalError( "Unknown tar flag '%c'\n" "Try `tar --help' for more information\n", **argv); - } - ++(*argv); } } @@ -238,7 +218,7 @@ extern int tar_main(int argc, char **argv) #ifndef BB_FEATURE_TAR_CREATE fatalError( "This version of tar was not compiled with tar creation support.\n"); #else - exit(writeTarFile(tarName, tostdoutFlag, verboseFlag, argc, argv, excludeList)); + exit(writeTarFile(tarName, tostdoutFlag, verboseFlag, argc-optind, &argv[optind], excludeList)); #endif } if (listFlag == TRUE || extractFlag == TRUE) { @@ -603,18 +583,20 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, } } /* List contents if we are supposed to do that */ - if (verboseFlag == TRUE || listFlag == TRUE) { + if (verboseFlag == TRUE && listFlag != TRUE) { /* Now the normal listing */ - printf("%s", header.name); + FILE *vbFd = stdout; + if (tostdoutFlag == TRUE) // If the archive goes to stdout, verbose to stderr + vbFd = stderr; + fprintf(vbFd, "%s\n", header.name); } + if (verboseFlag == TRUE && listFlag == TRUE) { - /* If this is a link, say so */ - if (header.type==LNKTYPE) + printf("%s", header.name); + if (header.type==LNKTYPE) /* If this is a link, say so */ printf(" link to %s", header.linkname); else if (header.type==SYMTYPE) printf(" -> %s", header.linkname); - } - if (verboseFlag == TRUE || listFlag == TRUE) { printf("\n"); } @@ -745,7 +727,7 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st #endif const unsigned char *cp = (const unsigned char *) &header; ssize_t size = sizeof(struct TarHeader); - + memset( &header, 0, size); if (*fileName=='/') { @@ -848,8 +830,12 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st write(tbInfo->tarFd, "\0", 1); } /* Now do the verbose thing (or not) */ - if (tbInfo->verboseFlag==TRUE) - fprintf(stdout, "%s\n", header.name); + if (tbInfo->verboseFlag==TRUE) { + FILE *vbFd = stdout; + if (tbInfo->tarFd == fileno(stdout)) // If the archive goes to stdout, verbose to stderr + vbFd = stderr; + fprintf(vbFd, "%s\n", header.name); + } return ( TRUE); } diff --git a/docs/busybox.pod b/docs/busybox.pod index d429853..cdbe3e0 100644 --- a/docs/busybox.pod +++ b/docs/busybox.pod @@ -1634,7 +1634,7 @@ File selection: f name of tarfile or "-" for stdin O extract to stdout - --exclude file to exclude + exclude file to exclude Informative output: @@ -2044,4 +2044,4 @@ Enrique Zanardi =cut -# $Id: busybox.pod,v 1.59 2000/07/21 21:32:12 andersen Exp $ +# $Id: busybox.pod,v 1.60 2000/08/02 18:48:25 andersen Exp $ diff --git a/docs/busybox.sgml b/docs/busybox.sgml index f65abda..560bd61 100644 --- a/docs/busybox.sgml +++ b/docs/busybox.sgml @@ -2901,10 +2901,10 @@ - f FILE Use FILE for tarfile (or stdin if '-') - O Extract to stdout - --exclude FILE Exclude FILE - v List files processed + f FILE Use FILE for tarfile (or stdin if '-') + O Extract to stdout + exclude FILE File to exclude + v List files processed diff --git a/mount.c b/mount.c index 6e95cdc..9f25e05 100644 --- a/mount.c +++ b/mount.c @@ -34,6 +34,13 @@ * * 2000-01-12 Ben Collins , Borrowed utils-linux's * mount to add loop support. + * + * 2000-04-30 Dave Cinege + * Rewrote fstab while loop and lower mount section. Can now do + * single mounts from fstab. Can override fstab options for single + * mount. Common mount_one call for single mounts and 'all'. Fixed + * mtab updating and stale entries. Removed 'remount' default. + * */ #include "internal.h" @@ -147,6 +154,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, #if defined BB_MTAB if (useMtab == TRUE) { + erase_mtab(specialfile); // Clean any stale entries write_mtab(specialfile, dir, filesystemtype, flags, mtab_opts); } #endif @@ -318,6 +326,8 @@ extern int mount_main(int argc, char **argv) int fakeIt = FALSE; int useMtab = TRUE; int i; + int rc = FALSE; + int fstabmount = FALSE; #if defined BB_FEATURE_USE_DEVPS_PATCH if (argc == 1) { @@ -435,56 +445,70 @@ extern int mount_main(int argc, char **argv) argv++; } - if (all == TRUE) { + if (all == TRUE || directory == NULL) { struct mntent *m; FILE *f = setmntent("/etc/fstab", "r"); + fstabmount = TRUE; if (f == NULL) fatalError( "\nCannot read /etc/fstab: %s\n", strerror (errno)); while ((m = getmntent(f)) != NULL) { - // If the filesystem isn't noauto, - // and isn't swap or nfs, then mount it - if ((!strstr(m->mnt_opts, "noauto")) && - (!strstr(m->mnt_type, "swap")) && - (!strstr(m->mnt_type, "nfs"))) { + if (all == FALSE && directory == NULL && ( + (strcmp(device, m->mnt_fsname) != 0) && + (strcmp(device, m->mnt_dir) != 0) ) ) { + continue; + } + + if (all == TRUE && ( // If we're mounting 'all' + (strstr(m->mnt_opts, "noauto")) || // and the file system isn't noauto, + (strstr(m->mnt_type, "swap")) || // and isn't swap or nfs, then mount it + (strstr(m->mnt_type, "nfs")) ) ) { + continue; + } + + if (all == TRUE || flags == 0) { // Allow single mount to override fstab flags flags = 0; *string_flags = '\0'; parse_mount_options(m->mnt_opts, &flags, string_flags); - if (mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, - flags, string_flags, useMtab, fakeIt, - extra_opts, FALSE)==FALSE) - { - /* Try again, but this time try a remount */ - mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, - flags|MS_REMOUNT, string_flags, useMtab, fakeIt, - extra_opts, TRUE); - } } - } - endmntent(f); - } else { - if (device && directory) { + + device = strdup(m->mnt_fsname); + directory = strdup(m->mnt_dir); + filesystemType = strdup(m->mnt_type); +singlemount: #ifdef BB_NFSMOUNT if (strchr(device, ':') != NULL) filesystemType = "nfs"; if (strcmp(filesystemType, "nfs") == 0) { - int ret; - ret = nfsmount (device, directory, &flags, - &extra_opts, &string_flags, 1); - if (ret != 0) - fatalError("nfsmount failed: %s\n", strerror(errno)); - } + rc = nfsmount (device, directory, &flags, &extra_opts, &string_flags, 1) + if ( rc != 0) { + fatalError("nfsmount failed: %s\n", strerror(errno)); + rc = FALSE; + } + } else #endif - exit(mount_one(device, directory, filesystemType, - flags, string_flags, useMtab, fakeIt, - extra_opts, TRUE)); - } else { - goto goodbye; + rc = mount_one(device, directory, filesystemType, flags, + string_flags, useMtab, fakeIt, extra_opts, TRUE); + + if (all == FALSE) + break; + + rc = TRUE; // Always return 0 for 'all' } + if (fstabmount == TRUE) + endmntent(f); + + if (all == FALSE && fstabmount == TRUE && directory == NULL) + fprintf(stderr, "Can't find %s in /etc/fstab\n", device); + + exit(rc); } - exit(TRUE); + + goto singlemount; + + exit(FALSE); - goodbye: +goodbye: usage(mount_usage); } diff --git a/tar.c b/tar.c index 3227ce5..cab53aa 100644 --- a/tar.c +++ b/tar.c @@ -148,85 +148,65 @@ extern int tar_main(int argc, char **argv) int createFlag = FALSE; int verboseFlag = FALSE; int tostdoutFlag = FALSE; - int stopIt; + int opt; if (argc <= 1) usage(tar_usage); - /* Parse any options */ - while (--argc > 0 && strspn(*(++argv), "-cxt") >0 ) { - stopIt=FALSE; - while (stopIt==FALSE && *argv && **argv) { - switch (**argv) { - case 'f': - if (--argc == 0) { - fatalError( "Option requires an argument: No file specified\n"); - } - if (*tarName != '-') - fatalError( "Only one 'f' option allowed\n"); - tarName = *(++argv); - if (tarName == NULL) - fatalError( "Option requires an argument: No file specified\n"); - if (!strcmp(tarName, "-") && createFlag == TRUE) - tostdoutFlag = TRUE; - stopIt=TRUE; - break; - - case 't': - if (extractFlag == TRUE || createFlag == TRUE) + /* do normal option parsing */ + while ((opt = getopt(argc, argv, "cxtvOf:-:")) > 0) { + switch (opt) { + case 'c': + if (extractFlag == TRUE || listFlag == TRUE) goto flagError; - listFlag = TRUE; + createFlag = TRUE; break; - case 'x': if (listFlag == TRUE || createFlag == TRUE) goto flagError; extractFlag = TRUE; break; - case 'c': - if (extractFlag == TRUE || listFlag == TRUE) + case 't': + if (extractFlag == TRUE || createFlag == TRUE) goto flagError; - createFlag = TRUE; + listFlag = TRUE; break; - case 'v': verboseFlag = TRUE; break; - case 'O': tostdoutFlag = TRUE; tarName = "-"; + break; + case 'f': + if (*tarName != '-') + fatalError( "Only one 'f' option allowed\n"); + tarName = optarg; + if (!strcmp(tarName, "-") && createFlag == TRUE) + tostdoutFlag = TRUE; break; case '-': #if defined BB_FEATURE_TAR_EXCLUDE - if (strcmp(*argv, "-exclude")==0) { - if (--argc == 0) { - fatalError( "Option requires an argument: No file specified\n"); - } + if (strcmp(optarg, "exclude")==0) { + if (argv[optind]==NULL) + fatalError( "option `--exclude' requires an argument\n"); excludeList=realloc( excludeList, sizeof(char**) * (excludeListSize+2)); - excludeList[excludeListSize] = *(++argv); + excludeList[excludeListSize] = argv[optind]; /* Remove leading "/"s */ if (*excludeList[excludeListSize] =='/') { excludeList[excludeListSize] = (excludeList[excludeListSize])+1; } - if (excludeList[excludeListSize++] == NULL) - fatalError( "Option requires an argument: No file specified\n"); /* Tack a NULL onto the end of the list */ excludeList[excludeListSize] = NULL; - stopIt=TRUE; + optind++; break; } #endif - if (strcmp(*argv, "-help")==0) { - usage(tar_usage); - } - break; - + fatalError( "Unknown tar flag '%s'\n" + "Try `tar --help' for more information\n", optarg); default: fatalError( "Unknown tar flag '%c'\n" "Try `tar --help' for more information\n", **argv); - } - ++(*argv); } } @@ -238,7 +218,7 @@ extern int tar_main(int argc, char **argv) #ifndef BB_FEATURE_TAR_CREATE fatalError( "This version of tar was not compiled with tar creation support.\n"); #else - exit(writeTarFile(tarName, tostdoutFlag, verboseFlag, argc, argv, excludeList)); + exit(writeTarFile(tarName, tostdoutFlag, verboseFlag, argc-optind, &argv[optind], excludeList)); #endif } if (listFlag == TRUE || extractFlag == TRUE) { @@ -603,18 +583,20 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, } } /* List contents if we are supposed to do that */ - if (verboseFlag == TRUE || listFlag == TRUE) { + if (verboseFlag == TRUE && listFlag != TRUE) { /* Now the normal listing */ - printf("%s", header.name); + FILE *vbFd = stdout; + if (tostdoutFlag == TRUE) // If the archive goes to stdout, verbose to stderr + vbFd = stderr; + fprintf(vbFd, "%s\n", header.name); } + if (verboseFlag == TRUE && listFlag == TRUE) { - /* If this is a link, say so */ - if (header.type==LNKTYPE) + printf("%s", header.name); + if (header.type==LNKTYPE) /* If this is a link, say so */ printf(" link to %s", header.linkname); else if (header.type==SYMTYPE) printf(" -> %s", header.linkname); - } - if (verboseFlag == TRUE || listFlag == TRUE) { printf("\n"); } @@ -745,7 +727,7 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st #endif const unsigned char *cp = (const unsigned char *) &header; ssize_t size = sizeof(struct TarHeader); - + memset( &header, 0, size); if (*fileName=='/') { @@ -848,8 +830,12 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st write(tbInfo->tarFd, "\0", 1); } /* Now do the verbose thing (or not) */ - if (tbInfo->verboseFlag==TRUE) - fprintf(stdout, "%s\n", header.name); + if (tbInfo->verboseFlag==TRUE) { + FILE *vbFd = stdout; + if (tbInfo->tarFd == fileno(stdout)) // If the archive goes to stdout, verbose to stderr + vbFd = stderr; + fprintf(vbFd, "%s\n", header.name); + } return ( TRUE); } diff --git a/usage.c b/usage.c index 1e2eb64..6c3f597 100644 --- a/usage.c +++ b/usage.c @@ -1053,7 +1053,7 @@ const char tar_usage[] = "tar -[xtvO] " #endif #if defined BB_FEATURE_TAR_EXCLUDE - "[-X File(s)] " + "[--exclude File] " #endif "[-f tarFile] [FILE(s)] ...\n" #ifndef BB_FEATURE_TRIVIAL_HELP @@ -1069,7 +1069,7 @@ const char tar_usage[] = "\tf\t\tname of tarfile or \"-\" for stdin\n" "\tO\t\textract to stdout\n" #if defined BB_FEATURE_TAR_EXCLUDE - "\tX\t\tfile(s) to exclude\n" + "\texclude\t\tfile to exclude\n" #endif "\nInformative output:\n" "\tv\t\tverbosely list files processed\n" diff --git a/util-linux/mount.c b/util-linux/mount.c index 6e95cdc..9f25e05 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -34,6 +34,13 @@ * * 2000-01-12 Ben Collins , Borrowed utils-linux's * mount to add loop support. + * + * 2000-04-30 Dave Cinege + * Rewrote fstab while loop and lower mount section. Can now do + * single mounts from fstab. Can override fstab options for single + * mount. Common mount_one call for single mounts and 'all'. Fixed + * mtab updating and stale entries. Removed 'remount' default. + * */ #include "internal.h" @@ -147,6 +154,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, #if defined BB_MTAB if (useMtab == TRUE) { + erase_mtab(specialfile); // Clean any stale entries write_mtab(specialfile, dir, filesystemtype, flags, mtab_opts); } #endif @@ -318,6 +326,8 @@ extern int mount_main(int argc, char **argv) int fakeIt = FALSE; int useMtab = TRUE; int i; + int rc = FALSE; + int fstabmount = FALSE; #if defined BB_FEATURE_USE_DEVPS_PATCH if (argc == 1) { @@ -435,56 +445,70 @@ extern int mount_main(int argc, char **argv) argv++; } - if (all == TRUE) { + if (all == TRUE || directory == NULL) { struct mntent *m; FILE *f = setmntent("/etc/fstab", "r"); + fstabmount = TRUE; if (f == NULL) fatalError( "\nCannot read /etc/fstab: %s\n", strerror (errno)); while ((m = getmntent(f)) != NULL) { - // If the filesystem isn't noauto, - // and isn't swap or nfs, then mount it - if ((!strstr(m->mnt_opts, "noauto")) && - (!strstr(m->mnt_type, "swap")) && - (!strstr(m->mnt_type, "nfs"))) { + if (all == FALSE && directory == NULL && ( + (strcmp(device, m->mnt_fsname) != 0) && + (strcmp(device, m->mnt_dir) != 0) ) ) { + continue; + } + + if (all == TRUE && ( // If we're mounting 'all' + (strstr(m->mnt_opts, "noauto")) || // and the file system isn't noauto, + (strstr(m->mnt_type, "swap")) || // and isn't swap or nfs, then mount it + (strstr(m->mnt_type, "nfs")) ) ) { + continue; + } + + if (all == TRUE || flags == 0) { // Allow single mount to override fstab flags flags = 0; *string_flags = '\0'; parse_mount_options(m->mnt_opts, &flags, string_flags); - if (mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, - flags, string_flags, useMtab, fakeIt, - extra_opts, FALSE)==FALSE) - { - /* Try again, but this time try a remount */ - mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, - flags|MS_REMOUNT, string_flags, useMtab, fakeIt, - extra_opts, TRUE); - } } - } - endmntent(f); - } else { - if (device && directory) { + + device = strdup(m->mnt_fsname); + directory = strdup(m->mnt_dir); + filesystemType = strdup(m->mnt_type); +singlemount: #ifdef BB_NFSMOUNT if (strchr(device, ':') != NULL) filesystemType = "nfs"; if (strcmp(filesystemType, "nfs") == 0) { - int ret; - ret = nfsmount (device, directory, &flags, - &extra_opts, &string_flags, 1); - if (ret != 0) - fatalError("nfsmount failed: %s\n", strerror(errno)); - } + rc = nfsmount (device, directory, &flags, &extra_opts, &string_flags, 1) + if ( rc != 0) { + fatalError("nfsmount failed: %s\n", strerror(errno)); + rc = FALSE; + } + } else #endif - exit(mount_one(device, directory, filesystemType, - flags, string_flags, useMtab, fakeIt, - extra_opts, TRUE)); - } else { - goto goodbye; + rc = mount_one(device, directory, filesystemType, flags, + string_flags, useMtab, fakeIt, extra_opts, TRUE); + + if (all == FALSE) + break; + + rc = TRUE; // Always return 0 for 'all' } + if (fstabmount == TRUE) + endmntent(f); + + if (all == FALSE && fstabmount == TRUE && directory == NULL) + fprintf(stderr, "Can't find %s in /etc/fstab\n", device); + + exit(rc); } - exit(TRUE); + + goto singlemount; + + exit(FALSE); - goodbye: +goodbye: usage(mount_usage); } diff --git a/utility.c b/utility.c index 422d569..bc5a5bd 100644 --- a/utility.c +++ b/utility.c @@ -68,11 +68,11 @@ #if defined BB_MOUNT || defined BB_UMOUNT || defined BB_DF -# if defined BB_FEATURE_USE_PROCFS -const char mtab_file[] = "/proc/mounts"; -# else -# if defined BB_MTAB +# if defined BB_MTAB const char mtab_file[] = "/etc/mtab"; +# else +# if defined BB_FEATURE_USE_PROCFS +const char mtab_file[] = "/proc/mounts"; # else # if defined BB_FEATURE_USE_DEVPS_PATCH const char mtab_file[] = "/dev/mtab"; -- 2.7.4