A few minor updates. ;-)
authorErik Andersen <andersen@codepoet.org>
Mon, 7 Feb 2000 05:29:42 +0000 (05:29 -0000)
committerErik Andersen <andersen@codepoet.org>
Mon, 7 Feb 2000 05:29:42 +0000 (05:29 -0000)
Seriously though, read the Changelog for busybox 0.42,
which this is about to become...
 -Erik

76 files changed:
Changelog
Makefile
TODO
applets/busybox.c
applets/busybox.mkll
archival/gunzip.c
archival/tar.c
busybox.c
busybox.def.h
busybox.mkll
chmod_chown_chgrp.c
coreutils/cp.c [deleted file]
coreutils/date.c
coreutils/dd.c
coreutils/du.c
coreutils/head.c
coreutils/length.c
coreutils/ln.c
coreutils/ls.c
coreutils/mkdir.c
coreutils/mv.c [deleted file]
coreutils/printf.c
coreutils/pwd.c
coreutils/sort.c
coreutils/tail.c
coreutils/tee.c
coreutils/uniq.c
cp.c [deleted file]
cp_mv.c [new file with mode: 0644]
date.c
dd.c
du.c
fdflush.c
find.c
findutils/find.c
fsck_minix.c
gunzip.c
head.c
hostname.c
init.c
init/init.c
insmod.c
internal.h
length.c
ln.c
ls.c
messages.c [new file with mode: 0644]
mkdir.c
modutils/insmod.c
mtab.c
mv.c [deleted file]
networking/hostname.c
networking/nslookup.c
networking/ping.c
nslookup.c
ping.c
printf.c
pwd.c
sort.c
swaponoff.c
sysklogd/syslogd.c
syslogd.c
tail.c
tar.c
tee.c
tests/Makefile [new file with mode: 0644]
tests/cp_tests.mk [new file with mode: 0644]
tests/ln_tests.mk [new file with mode: 0644]
tests/mv_tests.mk [new file with mode: 0644]
umount.c
uniq.c
util-linux/fdflush.c
util-linux/fsck_minix.c
util-linux/swaponoff.c
util-linux/umount.c
utility.c

index 6581b5c9080549c3b05d378de5a6ac4cd4c50892..7ecc4fb66809a8f4218f2783c236ddd3a9b23d2f 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -1,4 +1,41 @@
 0.42
+
+        * Fairly massive restructuring of umount.c to deal with remounting 
+         busy devices read-only. Adds a -r option to control that; it is 
+         optionally compiled in with BB_FEATURE_REMOUNT
+        * Added a bunch of functions to mtab.c to interact with the
+          {get,set,end}mntent interface; as it turns out, those functions do
+         not appear to be re-entrant, and that causes a lot of problems with
+         the way umount was originally written.
+        * Makes init send TERM and KILL (instead of HUP and KILL) on reboot
+         to be more consistent with sysvinit
+        * Changes to init.c to use the new -r option to umount. Also increased
+         the sleep time between the time the TERM and KILL signals are sent
+
+        - Randolph Chung
+
+
+       * cp.c, mv.c: removed, replaced by cp_mv.c which has been
+           extensively rewritten from the original cp.c.
+       * Also added a warning message to the `mv' usage string saying that
+           this is not GNU mv, and it will break hard links. cp also breaks
+           hard links.
+       * ln.c: implemented `-n' switch, no-deref symlinks.
+       * include<sys/param.h>: and use PATH_MAX everywhere.
+       * busybox: File name buffer overrun guards to prevent future crashes.
+           - Always check exit status.
+           - Purge all use of `creat()', replace with `open()'.
+       * utility.c 
+           - recursiveAction was overriding the value of 
+               followLinks thus ignoring it.
+           - isDirectory now takes a followLinks boolean, updated all callers
+           - copyFile had the followLinks logic reversed.
+       * messages.c: New file. Put common error message strings all in
+           one place in an attempt to shrink the binary a little.
+
+       -Karl M. Hegbloom
+
+
        * Made tar creation support in busybox tar optional.
        * You no longer _have_ to put a "-" in front of tar options.
        * Tar could inadvertently change permissions and ownership on
            for the kernel init chroot patch by Werner Almesberger, which 
            allows init to chroot to a new device, and umount the old one.
        * Fixed bug that wouldn't let one chown a symlink -- it would
-         always dereference before.  -beppu
+           always dereference before.  -beppu
        * Fixed a bug where init could have reference already freed memory.
            Found and fixed by Taketoshi Sano <kgh12351@nifty.ne.jp>
        * Several contributions from Friedrich Vedder <fwv@myrtle.lahn.de>
-       * added (and documented) "-n" option for head - 
+       * Added (and documented) "-n" option for head - 
        * Cleanup for a number of usage messages -- also 
            contributed Friedrich Vedder <fwv@myrtle.lahn.de>
        * Cosmetic fix to busybox.c (Don't print a comma at the
            Randolph Chung <tausq@debian.org>.
        * cp could, when copying symlinks, change permissions of the
            files pointed to by the symlinks.
+       * Several fixes from Pavel Roskin <pavel_roskin@geocities.com>:
+           - `chown' with 1 argument displayed the error incorrectly
+           - `fdflush', `length' and `printf' crashed when run without arguments
+           - `fdflush' tried to flush itself using *argv
+           - added "skip" and "seek" to dd.
 
 
        -Erik Andersen
index 554dd00f55453fdc750587e2fca5d9d3b7e2499b..490d3935f4b7ae83df3c37384c004d7ef6495a9c 100644 (file)
--- a/Makefile
+++ b/Makefile
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 #
 
+PROG      := busybox
+VERSION   := 0.42
+BUILDTIME := $(shell TZ=GMT date "+%Y%m%d-%H%M")
 
-PROG=busybox
-VERSION=0.42
-BUILDTIME=$(shell date "+%Y%m%d-%H%M")
+# Set the following to `true' to make a debuggable build.
+# Leave this set to `false' for production use.
+# eg: `make DODEBUG=true'
+DODEBUG = false
 
-# Comment out the following to make a debuggable build
-# Leave this off for production use.
-DODEBUG=false
 # If you want a static binary, turn this on.  I can't think
 # of many situations where anybody would ever want it static, 
 # but...
-DOSTATIC=false
-
-#This will choke on a non-debian system
-ARCH=`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'`
-
-GCCMAJVERSION=$(shell $(CC) --version | sed -n "s/^\([^\.]*\).*/\1/p" )
-GCCMINVERSION=$(shell $(CC) --version | sed -n "s/^[^\.]*\.\([^\.]*\)[\.].*/\1/p" )
-
-GCCSUPPORTSOPTSIZE=$(shell \
-if ( test $(GCCMAJVERSION) -eq 2 ) ; then \
-    if ( test $(GCCMINVERSION) -ge 66 ) ; then \
-       echo "true"; \
-    else \
-       echo "false"; \
-    fi; \
-else \
-    if ( test $(GCCMAJVERSION) -gt 2 ) ; then \
-       echo "true"; \
-    else \
-       echo "false"; \
-    fi; \
+DOSTATIC = false
+
+# This will choke on a non-debian system
+ARCH =`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'`
+
+CC = gcc
+
+GCCMAJVERSION = $(shell $(CC) --version | sed -n "s/^[^0-9]*\([0-9]\)\.\([0-9].*\)[\.].*/\1/p")
+GCCMINVERSION = $(shell $(CC) --version | sed -n "s/^[^0-9]*\([0-9]\)\.\([0-9].*\)[\.].*/\2/p")
+
+
+GCCSUPPORTSOPTSIZE = $(shell                   \
+if ( test $(GCCMAJVERSION) -eq 2 ) ; then      \
+    if ( test $(GCCMINVERSION) -ge 66 ) ; then \
+       echo "true";                            \
+    else                                       \
+       echo "false";                           \
+    fi;                                                \
+else                                           \
+    if ( test $(GCCMAJVERSION) -gt 2 ) ; then  \
+       echo "true";                            \
+    else                                       \
+       echo "false";                           \
+    fi;                                                \
 fi; )
 
 
 ifeq ($(GCCSUPPORTSOPTSIZE), true)
-    OPTIMIZATION=-Os
+    OPTIMIZATION = -Os
 else
-    OPTIMIZATION=-O2
+    OPTIMIZATION = -O2
 endif
 
 # -D_GNU_SOURCE is needed because environ is used in init.c
 ifeq ($(DODEBUG),true)
-    CFLAGS+=-Wall -g -D_GNU_SOURCE -DDEBUG_INIT
-    STRIP=
-    LDFLAGS=
+    CFLAGS += -Wall -g -D_GNU_SOURCE -DDEBUG_INIT
+    STRIP   =
+    LDFLAGS =
 else
-    CFLAGS+=-Wall $(OPTIMIZATION) -fomit-frame-pointer -fno-builtin -D_GNU_SOURCE
-    LDFLAGS= -s
-    STRIP= strip --remove-section=.note --remove-section=.comment $(PROG)
+    CFLAGS  += -Wall $(OPTIMIZATION) -fomit-frame-pointer -fno-builtin -D_GNU_SOURCE
+    LDFLAGS  = -s
+    STRIP    = strip --remove-section=.note --remove-section=.comment $(PROG)
     #Only staticly link when _not_ debugging 
     ifeq ($(DOSTATIC),true)
-       LDFLAGS+= --static
+       LDFLAGS += --static
     endif
-    
 endif
 
 ifndef $(PREFIX)
-    PREFIX=`pwd`/_install
+    PREFIX = `pwd`/_install
 endif
 
-LIBRARIES=
-OBJECTS=$(shell ./busybox.sh)
-CFLAGS+= -DBB_VER='"$(VERSION)"'
-CFLAGS+= -DBB_BT='"$(BUILDTIME)"'
+LIBRARIES =
+OBJECTS   = $(shell ./busybox.sh) messages.o utility.o
+CFLAGS    += -DBB_VER='"$(VERSION)"'
+CFLAGS    += -DBB_BT='"$(BUILDTIME)"'
 ifdef BB_INIT_SCRIPT
     CFLAGS += -DINIT_SCRIPT=${BB_INIT_SCRIPT}
 endif
@@ -90,7 +93,7 @@ busybox: $(OBJECTS)
        $(CC) $(LDFLAGS) -o $(PROG) $(OBJECTS) $(LIBRARIES)
        $(STRIP)
 
-busybox.links:
+busybox.links: busybox.def.h
        - ./busybox.mkll | sort >$@
 
 clean:
@@ -100,7 +103,7 @@ clean:
 distclean: clean
        - rm -f $(PROG)
 
-$(OBJECTS):  busybox.def.h internal.h Makefile
+$(OBJECTS): %.o: %.c busybox.def.h internal.h Makefile messages.c 
 
 install: busybox busybox.links
        ./install.sh $(PREFIX)
@@ -108,6 +111,18 @@ install: busybox busybox.links
 dist: release
 
 release: distclean
-       (cd .. ; rm -rf busybox-$(VERSION) ; cp -a busybox busybox-$(VERSION); rm -rf busybox-$(VERSION)/CVS busybox-$(VERSION)/scripts/CVS busybox-$(VERSION)/docs/CVS busybox-$(VERSION)/.cvsignore ; tar -cvzf busybox-$(VERSION).tar.gz busybox-$(VERSION)) 
-
-
+       cd ..;                                  \
+       rm -rf busybox-$(VERSION);              \
+       cp -a busybox busybox-$(VERSION);       \
+                                               \
+       find busybox-$(VERSION)/ -type d        \
+                                -name CVS      \
+                                -print         \
+               | xargs rm -rf;                 \
+                                               \
+       find busybox-$(VERSION)/ -type f        \
+                                -name .cvsignore \
+                                -print         \
+               | xargs rm -f;                  \
+                                               \
+       tar -cvzf busybox-$(VERSION).tar.gz busybox-$(VERSION)/;
diff --git a/TODO b/TODO
index b951767eac6ef7fcb5996dd5661b70752f160443..51a0d147aa685a91deaf4ba1dc65a0dddb5dbf9d 100644 (file)
--- a/TODO
+++ b/TODO
@@ -26,3 +26,44 @@ around to it some time. If you have any good ideas, please let me know.
 * tr
 * expr (maybe?)  (ash builtin?)
 
+
+
+
+Some known bugs, todo items, etc...
+
+-----------------------
+
+
+[andersen@slag busybox]$ ./busybox du /bin
+6213    /bin
+[andersen@slag busybox]$ du /bin
+2971    /bin
+[andersen@slag busybox]$ du --block-size=512 /bin
+5943    /bin
+
+-----------------------
+
+-rw-r--r-- 1000/1000      4398 2000-01-06 21:55 uniq.c
+-rw-r--r-- 1000/1000      1568 1999-10-20 18:08 update.c
+-rw-r----- 0/1000         1168 2000-01-29 21:03 update.o
+-rw-r--r-- 1000/1000     22820 2000-01-05 11:36 utility.c
+-rw-r----- 0/1000         7372 2000-01-29 21:03 utility.o
+tar: Skipping to next file header
+tar: Skipping to next file header
+tar: Archive - EOF not on block boundary
+tar: Error is not recoverable: exiting now
+
+
+#1 You are storing by id instead of name like normal tar. Did you realize this?
+(or am I missing some compile option? )ctar did not do this, and I don't think
+it's a good idea for LRP.
+
+#2
+ctar did not produce the EOF error like your tar does. I believe you need to
+pad the end of the archive with at least 2 tarsized (512byte) blocks. (I
+think???)
+
+#3
+There is no exclude file(s) option to tar. LRP's packaging system can not
+function without this. Will you have the time to add this soon?
+
index 7f14473e06b329036c8d9dadad4325765a288f20..e2c2e0393133237113b7aabc279dd65285a3f0a0 100644 (file)
@@ -50,8 +50,9 @@ static const struct Applet applets[] = {
 #ifdef BB_CHVT                 //usr/bin
     {"chvt", chvt_main},
 #endif
-#ifdef BB_CP                   //bin
-    {"cp", cp_main},
+#ifdef BB_CP_MV                        //bin
+    {"cp", cp_mv_main},
+    {"mv", cp_mv_main},
 #endif
 #ifdef BB_DATE                 //bin
     {"date", date_main},
@@ -170,10 +171,7 @@ static const struct Applet applets[] = {
 #ifdef BB_MT                   //bin
     {"mt", mt_main},
 #endif
-#ifdef BB_MV                   //bin
-    {"mv", mv_main},
-#endif
-#ifdef BB_NSLOOKUP             //bin
+#ifdef BB_NSLOOKUP             //usr/bin
     {"nslookup", nslookup_main},
 #endif
 #ifdef BB_PING                  //bin
index be6d937cfb8b06ea3739ff354c663ae7b472b7f5..c4420f50d52636bf1295cc6ebbf868ef785a7dc0 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
-#Make busybox links list file
+# Make busybox links list file.
 
 DF="busybox.def.h"
 MF="busybox.c"
index fddcc76538925b3c8fe0218126afb442ac95e369..db7fa1dfe48f448f5de8e7b484fabcfe44167ec8 100644 (file)
@@ -3,6 +3,9 @@
    */
 
 #include "internal.h"
+#define bb_need_name_too_long
+#define BB_DECLARE_EXTERN
+#include "messages.c"
 
 static const char gunzip_usage[] =
     "gunzip [OPTION]... FILE\n\n"
@@ -64,6 +67,7 @@ static char  *license_msg[] = {
 #include <signal.h>
 #include <sys/stat.h>
 #include <errno.h>
+#include <sys/param.h>         /* for PATH_MAX */
 
 /* #include "tailor.h" */
 
@@ -627,8 +631,12 @@ typedef RETSIGTYPE (*sig_type) OF((int));
 #endif
 #define RW_USER (S_IRUSR | S_IWUSR)  /* creation mode for open() */
 
-#ifndef MAX_PATH_LEN
-#  define MAX_PATH_LEN   1024 /* max pathname length */
+#ifndef MAX_PATH_LEN /* max pathname length */
+#  ifdef PATH_MAX
+#    define MAX_PATH_LEN   PATH_MAX
+#  else
+#    define MAX_PATH_LEN   1024
+#  endif
 #endif
 
 #ifndef SEEK_END
@@ -696,8 +704,8 @@ int gunzip_main (int argc, char** argv)
     int delInputFile=0;
     struct stat statBuf;
     char* delFileName; 
-    char ifname[MAX_PATH_LEN]; /* input file name */
-    char ofname[MAX_PATH_LEN]; /* output file name */
+    char ifname[MAX_PATH_LEN + 1]; /* input file name */
+    char ofname[MAX_PATH_LEN + 1]; /* output file name */
 
     if (argc==1)
        usage(gunzip_usage);
@@ -764,7 +772,11 @@ int gunzip_main (int argc, char** argv)
        /* Open up the input file */
        if (*argv=='\0')
            usage(gunzip_usage);
-       strncpy(ifname, *argv, MAX_PATH_LEN);
+       if (strlen(*argv) > MAX_PATH_LEN) {
+           fprintf(stderr, name_too_long, "gunzip");
+           do_exit(WARNING);
+       }
+       strcpy(ifname, *argv);
 
        /* Open input fille */
        inFileNum=open( ifname, O_RDONLY);
@@ -799,7 +811,11 @@ int gunzip_main (int argc, char** argv)
        char* pos;
 
        /* And get to work */
-       strncpy(ofname, ifname, MAX_PATH_LEN-4);
+       if (strlen(ifname) > MAX_PATH_LEN - 4) {
+           fprintf(stderr, name_too_long, "gunzip");
+           do_exit(WARNING);
+       }
+       strcpy(ofname, ifname);
        pos=strstr(ofname, ".gz");
        if (pos != NULL) {
            *pos='\0';
index 0fa09ffd86834ad95df1da6f1e30e25e0c18927c..6496231ae029076c68fb8cb4b7f197c4a89d1c62 100644 (file)
@@ -40,6 +40,7 @@
 #include <utime.h>
 #include <sys/types.h>
 #include <sys/sysmacros.h>
+#include <sys/param.h>         /* for PATH_MAX */
 
 
 #ifdef BB_FEATURE_TAR_CREATE
@@ -1041,7 +1042,7 @@ static void saveDirectory (const char *dirName, const struct stat *statbuf)
     DIR *dir;
     struct dirent *entry;
     int needSlash;
-    char fullName[NAME_MAX];
+    char fullName[PATH_MAX + 1];
 
     /* 
      * Construct the directory name as used in the tar file by appending
index 7f14473e06b329036c8d9dadad4325765a288f20..e2c2e0393133237113b7aabc279dd65285a3f0a0 100644 (file)
--- a/busybox.c
+++ b/busybox.c
@@ -50,8 +50,9 @@ static const struct Applet applets[] = {
 #ifdef BB_CHVT                 //usr/bin
     {"chvt", chvt_main},
 #endif
-#ifdef BB_CP                   //bin
-    {"cp", cp_main},
+#ifdef BB_CP_MV                        //bin
+    {"cp", cp_mv_main},
+    {"mv", cp_mv_main},
 #endif
 #ifdef BB_DATE                 //bin
     {"date", date_main},
@@ -170,10 +171,7 @@ static const struct Applet applets[] = {
 #ifdef BB_MT                   //bin
     {"mt", mt_main},
 #endif
-#ifdef BB_MV                   //bin
-    {"mv", mv_main},
-#endif
-#ifdef BB_NSLOOKUP             //bin
+#ifdef BB_NSLOOKUP             //usr/bin
     {"nslookup", nslookup_main},
 #endif
 #ifdef BB_PING                  //bin
index fa192205aa8a8b37d96d1f277979142593de8ab3..306c877624fbbe4a4a9de54ef56dce7d7d44f65e 100644 (file)
 //
 //
 //
-// Don't turn BB_UTILITY off.  It contains support code 
-// that compiles to 0 if everything else if turned off.
-#define BB_UTILITY
-//
-//
 //
 // This is where feature definitions go.  Generally speaking,
 // turning this stuff off makes things a bit smaller (and less 
 #define BB_FEATURE_USE_INITTAB
 //
 //Enable init being called as /linuxrc
-#define BB_FEATURE_LINUXRC
+//#define BB_FEATURE_LINUXRC
 //
 //
 //Simple tail implementation (2k vs 6k for the full one).  Still
 // Enable support for loop devices in mount
 #define BB_FEATURE_MOUNT_LOOP
 //
+// Enable support for a real /etc/mtab file instead of /proc/mounts
+#ifdef BB_MOUNT
+//#define BB_MTAB
+#endif
+//
+//
+// Enable support for remounting filesystems
+#define BB_FEATURE_REMOUNT
+//
 // Enable support for creation of tar files.
 //#define BB_FEATURE_TAR_CREATE
 //
 // Allow init to permenently chroot, and umount the old root fs
-// just like an initrd does.  Requires a kernel patch by Werner Almesberger.
+// just like an initrd does.  Requires a kernel patch by Werner Almesberger. 
 // ftp://icaftp.epfl.ch/pub/people/almesber/misc/umount-root-*.tar.gz
 #ifdef BB_MOUNT
 #define BB_FEATURE_INIT_CHROOT
index be6d937cfb8b06ea3739ff354c663ae7b472b7f5..c4420f50d52636bf1295cc6ebbf868ef785a7dc0 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
-#Make busybox links list file
+# Make busybox links list file.
 
 DF="busybox.def.h"
 MF="busybox.c"
index 773f4b0c0a87b7f267f0dee6be99d7c6c2210c7d..b4c5da9360f412da14241ef7112de8e10a527278 100644 (file)
  *
  */
 
+#include "internal.h"
+#define BB_DECLARE_EXTERN
+#define bb_need_invalid_option
+#include "messages.c"
+
 #include <stdio.h>
 #include <grp.h>
 #include <pwd.h>
-#include "internal.h"
 
 
 static uid_t uid = -1;
@@ -69,7 +73,7 @@ static int fileAction(const char *fileName, struct stat* statbuf)
        case CHMOD_APP:
            /* Parse the specified modes */
            if ( parse_mode(theMode, &(statbuf->st_mode)) == FALSE ) {
-               fprintf(stderr, "%s: Unknown mode: %s\n", invocationName, theMode);
+               fprintf(stderr, "%s: unknown mode: %s\n", invocationName, theMode);
                exit( FALSE);
            }
            if (chmod(fileName, statbuf->st_mode) == 0)
@@ -84,6 +88,7 @@ int chmod_chown_chgrp_main(int argc, char **argv)
 {
     int recursiveFlag=FALSE;
     char *groupName;
+    char *p;
     const char *appUsage;
 
     whichApp = (strcmp(*argv, "chown")==0)? CHOWN_APP : (strcmp(*argv, "chmod")==0)? CHMOD_APP : CHGRP_APP; 
@@ -103,7 +108,7 @@ int chmod_chown_chgrp_main(int argc, char **argv)
                recursiveFlag = TRUE;
                break;
            default:
-               fprintf(stderr, "Unknown option: %c\n", **argv);
+               fprintf(stderr, invalid_option, invocationName, **argv);
                usage( appUsage);
        }
        argc--;
@@ -117,14 +122,18 @@ int chmod_chown_chgrp_main(int argc, char **argv)
        /* Find the selected group */
        if ( whichApp==CHGRP_APP ) {
            groupName = *argv;
-           gid = my_getgrnam(groupName);
+           gid = strtoul(groupName, &p, 10); /* maybe it's already numeric */
+           if (groupName == p)
+               gid = my_getgrnam(groupName);
            if (gid == -1)
                goto bad_group;
        } else {
            groupName = strchr(*argv, '.');
            if (groupName) {
                *groupName++ = '\0';
-               gid = my_getgrnam(groupName);
+               gid = strtoul(groupName, &p, 10);
+               if (groupName == p)
+                   gid = my_getgrnam(groupName);
                if (gid == -1)
                    goto bad_group;
            } else
@@ -134,9 +143,11 @@ int chmod_chown_chgrp_main(int argc, char **argv)
 
        /* Find the selected user (if appropriate)  */
        if (whichApp==CHOWN_APP) {
-           uid = my_getpwnam(*argv);
+           uid = strtoul(*argv, &p, 10); /* if numeric ...*/
+           if (*argv == p)
+               uid = my_getpwnam(*argv);
            if (uid == -1) {
-               fprintf(stderr, "%s: Unknown user name: %s\n", invocationName, *argv);
+               fprintf(stderr, "%s: unknown user name: %s\n", invocationName, *argv);
                exit( FALSE);
            }
        }
@@ -144,7 +155,7 @@ int chmod_chown_chgrp_main(int argc, char **argv)
     
     /* Ok, ready to do the deed now */
     if (argc <= 1) {
-       fprintf(stderr, "%s: too few arguments", invocationName);
+       fprintf(stderr, "%s: too few arguments\n", invocationName);
        exit( FALSE);
     }
     while (argc-- > 1) {
@@ -154,7 +165,7 @@ int chmod_chown_chgrp_main(int argc, char **argv)
     exit(TRUE);
 
 bad_group:
-    fprintf(stderr, "%s: Unknown group name: %s\n", invocationName, groupName);
+    fprintf(stderr, "%s: unknown group name: %s\n", invocationName, groupName);
     exit( FALSE);
 }
 
diff --git a/coreutils/cp.c b/coreutils/cp.c
deleted file mode 100644 (file)
index e96012d..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Mini cp implementation for busybox
- *
- *
- * Copyright (C) 1999 by Lineo, inc.
- * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
- *
- * 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 <time.h>
-#include <utime.h>
-#include <dirent.h>
-
-static const char cp_usage[] = "cp [OPTION]... SOURCE DEST\n"
-    "   or: cp [OPTION]... SOURCE... DIRECTORY\n\n"
-    "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n"
-    "\n"
-    "\t-a\tsame as -dpR\n"
-    "\t-d\tpreserve links\n"
-    "\t-p\tpreserve file attributes if possible\n"
-    "\t-R\tcopy directories recursively\n";
-
-
-static int recursiveFlag = FALSE;
-static int followLinks = FALSE;
-static int preserveFlag = FALSE;
-static const char *srcName;
-static const char *destName;
-static int destDirFlag = FALSE;
-static int srcDirFlag = FALSE;
-
-static int fileAction(const char *fileName, struct stat* statbuf)
-{
-    char newdestName[NAME_MAX];
-    char* newsrcName = NULL;
-
-    strcpy(newdestName, destName);
-    if ( srcDirFlag == TRUE ) {
-       if (recursiveFlag!=TRUE ) {
-           fprintf(stderr, "cp: %s: omitting directory\n", srcName);
-           return( TRUE);
-       }
-       strcat(newdestName, strstr(fileName, srcName) + strlen(srcName));
-    } 
-    
-    if (destDirFlag==TRUE && srcDirFlag == FALSE) {
-       if (newdestName[strlen(newdestName)-1] != '/' ) {
-           strcat(newdestName, "/");
-       }
-       newsrcName = strrchr(srcName, '/');
-       if (newsrcName && *newsrcName != '\0')
-           strcat(newdestName, newsrcName);
-       else
-           strcat(newdestName, srcName);
-    }
-    
-    return (copyFile(fileName, newdestName, preserveFlag, followLinks));
-}
-
-extern int cp_main(int argc, char **argv)
-{
-    if (argc < 3) {
-       usage (cp_usage);
-    }
-    argc--;
-    argv++;
-
-    /* Parse any options */
-    while (**argv == '-') {
-       while (*++(*argv))
-           switch (**argv) {
-           case 'a':
-               followLinks = TRUE;
-               preserveFlag = TRUE;
-               recursiveFlag = TRUE;
-               break;
-           case 'd':
-               followLinks = TRUE;
-               break;
-           case 'p':
-               preserveFlag = TRUE;
-               break;
-           case 'R':
-               recursiveFlag = TRUE;
-               break;
-           default:
-               usage (cp_usage);
-           }
-       argc--;
-       argv++;
-    }
-
-
-    destName = argv[argc - 1];
-    destDirFlag = isDirectory(destName);
-
-    if ((argc > 3) && destDirFlag==FALSE) {
-       fprintf(stderr, "%s: not a directory\n", destName);
-       exit (FALSE);
-    }
-
-    while (argc-- > 1) {
-       srcName = *(argv++);
-       srcDirFlag = isDirectory(srcName);
-       if (recursiveAction(srcName, recursiveFlag, followLinks, FALSE,
-                              fileAction, fileAction) == FALSE) {
-           exit( FALSE);
-       }
-    }
-    exit( TRUE);
-}
index 77e7c39db7461b85dd2325e8291f2f848ed0099c..a3528921db88fec3e687f58772faea67a3f48baf 100644 (file)
 */
 
 #include "internal.h"
+#define BB_DECLARE_EXTERN
+#define bb_need_invalid_date
+#define bb_need_memory_exhausted
+#include "messages.c"
 #include <stdlib.h>
 #include <errno.h>
 #include <sys/time.h>
@@ -59,7 +63,7 @@ date_conv_time(struct tm *tm_time, const char *t_string) {
             &(tm_time->tm_year));
 
   if(nr < 4 || nr > 5) {
-    fprintf(stderr, "date: invalid date `%s'\n", t_string);
+    fprintf(stderr, invalid_date, "date", t_string);
     exit( FALSE);
   }
 
@@ -152,7 +156,7 @@ date_conv_ftime(struct tm *tm_time, const char *t_string) {
 
   }
 
-  fprintf(stderr, "date: invalid date `%s'\n", t_string);
+  fprintf(stderr, invalid_date, "date", t_string);
 
   exit( FALSE);
 
@@ -190,7 +194,7 @@ date_main(int argc, char * * argv)
            case 'u':
                utc = 1;
                if (putenv ("TZ=UTC0") != 0) {
-                   fprintf(stderr,"date: memory exhausted\n");
+                   fprintf(stderr, memory_exhausted, "date");
                    exit( FALSE);
                }
                /* Look ma, no break.  Don't fix it either. */
@@ -204,10 +208,10 @@ date_main(int argc, char * * argv)
            }
        } else {
            if ( (date_fmt == NULL) && (strcmp(*argv, "+")==0) )
-               date_fmt = *argv;
+               date_fmt=*argv;
            else if (date_str == NULL) {
                set_time = 1;
-               date_str = *argv;
+               date_str=*argv;
            } else { 
                usage ( date_usage);
            }
@@ -241,7 +245,7 @@ date_main(int argc, char * * argv)
     /* Correct any day of week and day of year etc fields */
     tm = mktime(&tm_time);
     if (tm < 0 ) {
-      fprintf(stderr, "date: invalid date `%s'\n", date_str);
+      fprintf(stderr, invalid_date, "date", date_str);
       exit( FALSE);
     }
 
@@ -284,4 +288,3 @@ date_main(int argc, char * * argv)
   exit( TRUE);
 
 }
-
index bc01eedbfaab9e4dfc5df26387ac05ae3dcdc3b9..3e1024a609b4288ae8d291576780424f222b3fe0 100644 (file)
@@ -40,15 +40,16 @@ typedef unsigned long long int uintmax_t;
 #endif
 
 static const char dd_usage[] =
-"dd [if=name] [of=name] [bs=n] [count=n]\n\n"
+"dd [if=name] [of=name] [bs=n] [count=n] [skip=n] [seek=n]\n\n"
 "Copy a file, converting and formatting according to options\n\n"
 "\tif=FILE\tread from FILE instead of stdin\n"
-"\tof=FILE\twrite to FILE instead of stout\n"
-"\tbs=n\tread and write N BYTES at a time\n"
+"\tof=FILE\twrite to FILE instead of stdout\n"
+"\tbs=n\tread and write n bytes at a time\n"
 "\tcount=n\tcopy only n input blocks\n"
-//"\tskip=n\tskip n input blocks\n"
+"\tskip=n\tskip n input blocks\n"
+"\tseek=n\tskip n output blocks\n"
 "\n"
-"BYTES may be suffixed by w (x2), k (x1024), b (x512), or m (x1024^2).\n";
+"Numbers may be suffixed by w (x2), k (x1024), b (x512), or M (x1024^2)\n";
 
 
 
@@ -61,8 +62,9 @@ extern int dd_main (int argc, char **argv)
     int outFd;
     int inCc = 0;
     int outCc;
-    size_t blockSize = 512;
-    //uintmax_t skipBlocks = 0;
+    long blockSize = 512;
+    uintmax_t skipBlocks = 0;
+    uintmax_t seekBlocks = 0;
     uintmax_t count = (uintmax_t)-1;
     uintmax_t intotal;
     uintmax_t outTotal;
@@ -91,16 +93,22 @@ extern int dd_main (int argc, char **argv)
                goto usage;
            }
        }
-#if 0
        else if (strncmp(*argv, "skip", 4) == 0) {
-           skipBlocks = atoi( *argv); 
+           skipBlocks = getNum ((strchr(*argv, '='))+1);
            if (skipBlocks <= 0) {
-               fprintf (stderr, "Bad skip value %d\n", skipBlocks);
+               fprintf (stderr, "Bad skip value %s\n", *argv);
+               goto usage;
+           }
+
+       }
+       else if (strncmp(*argv, "seek", 4) == 0) {
+           seekBlocks = getNum ((strchr(*argv, '='))+1);
+           if (seekBlocks <= 0) {
+               fprintf (stderr, "Bad seek value %s\n", *argv);
                goto usage;
            }
 
        }
-#endif
        else {
            goto usage;
        }
@@ -131,7 +139,7 @@ extern int dd_main (int argc, char **argv)
     if (outFile == NULL)
        outFd = fileno(stdout);
     else
-       outFd = creat (outFile, 0666);
+       outFd = open(outFile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
 
     if (outFd < 0) {
        perror (outFile);
@@ -140,10 +148,11 @@ extern int dd_main (int argc, char **argv)
        exit( FALSE);
     }
 
-    //lseek(inFd, skipBlocks*blockSize, SEEK_SET);
+    lseek(inFd, skipBlocks*blockSize, SEEK_SET);
+    lseek(outFd, seekBlocks*blockSize, SEEK_SET);
     //
     //TODO: Convert to using fullRead & fullWrite
-    // from utilitity.c
+    // from utility.c
     //  -Erik
     while (outTotal < count * blockSize) {
        inCc = read (inFd, buf, blockSize);
index 79b553643efcfdb6fbf1dd5057e1b605c5c38679..e2cf3f7c09408d4d96b4219aee50d48d40626693 100644 (file)
  */
 
 #include "internal.h"
+#define BB_DECLARE_EXTERN
+#define bb_need_name_too_long
+#include "messages.c"
+
 #include <sys/types.h>
 #include <fcntl.h>
 #include <dirent.h>
 #include <stdio.h>
 #include <errno.h>
-#if 0
-#include <unistd.h>
-#include <sys/stat.h>
-#endif
+#include <sys/param.h>         /* for PATH_MAX */
 
-typedef void (Display)(size_t, char *);
+typedef void (Display)(long, char *);
 
 static const char du_usage[] =
 "du [OPTION]... [FILE]...\n\n"
@@ -44,13 +45,13 @@ static int  du_depth = 0;
 static Display *print;
 
 static void
-print_normal(size_t size, char *filename)
+print_normal(long size, char *filename)
 {
-    fprintf(stdout, "%-7d %s\n", (size >> 1), filename);
+    fprintf(stdout, "%-7ld %s\n", size, filename);
 }
 
 static void
-print_summary(size_t size, char *filename)
+print_summary(long size, char *filename)
 {
     if (du_depth == 1) { 
        print_normal(size, filename); 
@@ -59,11 +60,11 @@ print_summary(size_t size, char *filename)
 
 
 /* tiny recursive du */
-static size_t
+static long
 du(char *filename)
 {
     struct stat statbuf;
-    size_t     sum;
+    long       sum;
 
     if ((lstat(filename, &statbuf)) != 0) { 
        fprintf(stdout, "du: %s: %s\n", filename, strerror(errno));
@@ -80,14 +81,19 @@ du(char *filename)
        dir = opendir(filename);
        if (!dir) { return 0; }
        while ((entry = readdir(dir))) {
-           char newfile[512];
+           char newfile[PATH_MAX + 1];
            char *name = entry->d_name;
 
            if (  (strcmp(name, "..") == 0)
               || (strcmp(name, ".")  == 0)) 
            { continue; }
 
+           if (strlen(filename) + strlen(name) + 1 > PATH_MAX) {
+             fprintf(stderr, name_too_long, "du");
+             return 0;
+           }
            sprintf(newfile, "%s/%s", filename, name);
+
            sum += du(newfile);
        }
        closedir(dir);
@@ -130,14 +136,14 @@ du_main(int argc, char **argv)
     if (i >= argc) {
        du(".");
     } else {
-       int sum;
+       long sum;
        for ( ; i < argc; i++) {
            sum = du(argv[i]);
-           if ((sum) && (isDirectory(argv[i]))) { print_normal(sum, argv[i]); }
+           if ((sum) && (isDirectory(argv[i], FALSE))) { print_normal(sum, argv[i]); }
        }
     }
 
     exit(0);
 }
 
-/* $Id: du.c,v 1.9 2000/01/23 18:19:02 erik Exp $ */
+/* $Id: du.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */
index bc7f35429d155d9483ba5155dd8a840900529d29..b80d065801e899980140ea18785595015f768cc8 100644 (file)
@@ -105,4 +105,4 @@ head_main(int argc, char **argv)
     exit(0);
 }
 
-/* $Id: head.c,v 1.6 2000/01/25 18:13:53 erik Exp $ */
+/* $Id: head.c,v 1.7 2000/02/07 05:29:42 erik Exp $ */
index 46242b529eb7f5d9b37092b37c948f15179cf50e..2c83cdfd2d44d40125cf6931a5ec421895c01adb 100644 (file)
@@ -6,7 +6,7 @@
 extern int
 length_main(int argc, char * * argv)
 {
-    if ( **(argv+1) == '-' ) {
+    if ( argc != 2 || **(argv+1) == '-' ) {
        usage("length string\n");
     }
     printf("%d\n", strlen(argv[1]));
index 60fe394386a8a7f7a3441da9e4f6ba8cb0dab6e2..f20b340eac1498570f872711e98aa6614e6033b2 100644 (file)
  */
 
 #include "internal.h"
+#define BB_DECLARE_EXTERN
+#define bb_need_name_too_long
+#define bb_need_not_a_directory
+#include "messages.c"
+
 #include <stdio.h>
 #include <dirent.h>
 #include <errno.h>
+#include <sys/param.h>         /* for PATH_MAX */
 
-
-static const char ln_usage[] = "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n"
-"Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n"
-"Options:\n"
-"\t-s\tmake symbolic links instead of hard links\n"
-"\t-f\tremove existing destination files\n";
-
+static const char ln_usage[] =
+    "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n"
+    "Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n"
+    "Options:\n"
+    "\t-s\tmake symbolic links instead of hard links\n"
+    "\t-f\tremove existing destination files\n"
+    "\t-n\tno dereference symlinks - treat like normal file\n";
 
 static int symlinkFlag = FALSE;
 static int removeoldFlag = FALSE;
-
+static int followLinks = TRUE;
 
 extern int ln_main(int argc, char **argv)
 {
-    int status;
-    static char* linkName;
+    char *linkName;
+    int linkIntoDirFlag;
 
     if (argc < 3) {
        usage (ln_usage);
@@ -59,6 +65,9 @@ extern int ln_main(int argc, char **argv)
            case 'f':
                removeoldFlag = TRUE;
                break;
+           case 'n':
+               followLinks = FALSE;
+               break;
            default:
                usage (ln_usage);
            }
@@ -66,30 +75,54 @@ extern int ln_main(int argc, char **argv)
        argv++;
     }
 
-
     linkName = argv[argc - 1];
 
-    if ((argc > 3) && !(isDirectory(linkName))) {
-       fprintf(stderr, "%s: not a directory\n", linkName);
-       exit (FALSE);
+    if (strlen(linkName) > PATH_MAX) {
+       fprintf(stderr, name_too_long, "ln");
+       exit FALSE;
+    }
+
+    linkIntoDirFlag = isDirectory(linkName, TRUE);
+
+    if ((argc > 3) && !linkIntoDirFlag) {
+       fprintf(stderr, not_a_directory, "ln", linkName);
+       exit FALSE;
     }
 
     while (argc-- >= 2) {
-       if (removeoldFlag==TRUE ) {
+       char srcName[PATH_MAX + 1];
+       int nChars, status;
+
+       if (strlen(*argv) > PATH_MAX) {
+           fprintf(stderr, name_too_long, "ln");
+           exit FALSE;
+       }
+
+       if (followLinks == FALSE) {
+           strcpy(srcName, *argv);
+       } else {
+           /* Warning!  This can silently truncate if > PATH_MAX, but
+           I don't think that there can be one > PATH_MAX anyway. */
+           nChars = readlink(*argv, srcName, PATH_MAX);
+           srcName[nChars] = '\0';
+       }
+
+       if (removeoldFlag == TRUE) {
            status = ( unlink(linkName) && errno != ENOENT );
-           if ( status != 0 ) {
+           if (status != 0) {
                perror(linkName);
-               exit( FALSE);
+               exit FALSE;
            }
        }
-       if ( symlinkFlag==TRUE)
-               status = symlink(*argv, linkName);
+
+       if (symlinkFlag == TRUE)
+           status = symlink(*argv, linkName);
        else
-               status = link(*argv, linkName);
-       if ( status != 0 ) {
+           status = link(*argv, linkName);
+       if (status != 0) {
            perror(linkName);
-           exit( FALSE);
+           exit FALSE;
        }
     }
-    exit( TRUE);
+    exit TRUE;
 }
index 78193e7c150e21018b85cc90f7520d20e19af29c..450ea18147c6fa36941594dc0d0bc16706d922cb 100644 (file)
@@ -178,7 +178,7 @@ static char append_char(mode_t mode)
 
 static void list_single(const char *name, struct stat *info, const char *fullname)
 {
-       char scratch[PATH_MAX];
+       char scratch[PATH_MAX + 1];
        short len = strlen(name);
 #ifdef BB_FEATURE_LS_FILETYPES
        char append = append_char(info->st_mode);
index 017ef9b08083c3c56f3e4217bc8bc2eb5a905d23..8e3f51bfb9ea724c49fa1f545dbfdc8f03710084 100644 (file)
  */
 
 #include "internal.h"
+#define bb_need_name_too_long
+#define BB_DECLARE_EXTERN
+#include "messages.c"
+
 #include <stdio.h>
 #include <errno.h>
-#include <sys/param.h>
+#include <sys/param.h>         /* for PATH_MAX */
 
 static const char mkdir_usage[] =
 "mkdir [OPTION] DIRECTORY...\n\n"
@@ -40,27 +44,27 @@ static mode_t mode = 0777;
 
 extern int mkdir_main(int argc, char **argv)
 {
-    int i=FALSE;
+    int i = FALSE;
     argc--;
     argv++;
 
     /* Parse any options */
     while (argc > 0 && **argv == '-') {
-       while (i==FALSE && *++(*argv)) {
+       while (i == FALSE && *++(*argv)) {
            switch (**argv) {
            case 'm':
                if (--argc == 0)
                    usage( mkdir_usage);
                /* Find the specified modes */
                mode = 0;
-               if ( parse_mode(*(++argv), &mode) == FALSE ) {
+               if (parse_mode(*(++argv), &mode) == FALSE ) {
                    fprintf(stderr, "Unknown mode: %s\n", *argv);
-                   exit( FALSE);
+                   exit FALSE;
                }
                /* Set the umask for this process so it doesn't 
                 * screw up whatever the user just entered. */
                umask(0);
-               i=TRUE;
+               i = TRUE;
                break;
            case 'p':
                parentFlag = TRUE;
@@ -73,7 +77,6 @@ extern int mkdir_main(int argc, char **argv)
        argv++;
     }
 
-
     if (argc < 1) {
        usage( mkdir_usage);
     }
@@ -81,13 +84,16 @@ extern int mkdir_main(int argc, char **argv)
     while (argc > 0) {
        int status;
        struct stat statBuf;
-       char buf[NAME_MAX];
-
+       char buf[PATH_MAX + 1];
+       if (strlen(*argv) > PATH_MAX - 1) {
+           fprintf(stderr, name_too_long, "mkdir");
+           exit FALSE;
+       }
        strcpy (buf, *argv);
-       status=stat(buf, &statBuf);
-       if (parentFlag == FALSE && status != -1 && status != ENOENT ) {
+       status = stat(buf, &statBuf);
+       if (parentFlag == FALSE && status != -1 && errno != ENOENT) {
            fprintf(stderr, "%s: File exists\n", buf);
-           exit( FALSE);
+           exit FALSE;
        }
        if (parentFlag == TRUE) {
            strcat( buf, "/");
@@ -96,13 +102,13 @@ extern int mkdir_main(int argc, char **argv)
        else { 
            if (mkdir (buf, mode) != 0 && parentFlag == FALSE) {
                perror(buf);
-               exit( FALSE);
+               exit FALSE;
            }
        }
        argc--;
        argv++;
     }
-    exit( TRUE);
+    exit TRUE;
 }
 
 
diff --git a/coreutils/mv.c b/coreutils/mv.c
deleted file mode 100644 (file)
index 467a360..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Mini mv implementation for busybox
- *
- *
- * Copyright (C) 1999 by Lineo, inc.
- * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
- *
- * 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 <time.h>
-#include <utime.h>
-#include <dirent.h>
-
-static const char mv_usage[] = "mv SOURCE DEST\n"
-"   or: mv SOURCE... DIRECTORY\n\n"
-"Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n";
-
-
-static const char *srcName;
-static const char *destName;
-static int destDirFlag = FALSE;
-static int srcDirFlag = FALSE;
-
-static int fileAction(const char *fileName, struct stat* statbuf)
-{
-    char newdestName[NAME_MAX];
-    char* newsrcName = NULL;
-
-    strcpy(newdestName, destName);
-    if ( srcDirFlag == TRUE ) {
-       strcat(newdestName, strstr(fileName, srcName) + strlen(srcName));
-    } 
-    
-    if (destDirFlag==TRUE && srcDirFlag == FALSE) {
-       if (newdestName[strlen(newdestName)-1] != '/' ) {
-           strcat(newdestName, "/");
-       }
-       newsrcName = strrchr(srcName, '/');
-       if (newsrcName && *newsrcName != '\0')
-           strcat(newdestName, newsrcName);
-       else
-           strcat(newdestName, srcName);
-    }
-    
-    return (copyFile(fileName, newdestName, TRUE, TRUE));
-}
-
-static int rmfileAction(const char *fileName, struct stat* statbuf)
-{
-    if (unlink( fileName) < 0 ) {
-       perror( fileName);
-       return ( FALSE);
-    }
-    return ( TRUE);
-}
-
-static int rmdirAction(const char *fileName, struct stat* statbuf)
-{
-    if (rmdir( fileName) < 0 ) {
-       perror( fileName);
-       return ( FALSE);
-    }
-    return ( TRUE);
-}
-
-
-extern int mv_main(int argc, char **argv)
-{
-    if (argc < 3) {
-       usage (mv_usage);
-    }
-    argc--;
-    argv++;
-
-    destName = argv[argc - 1];
-    destDirFlag = isDirectory(destName);
-
-    if ((argc > 3) && destDirFlag==FALSE) {
-       fprintf(stderr, "%s: not a directory\n", destName);
-       exit (FALSE);
-    }
-
-    while (argc-- > 1) {
-       srcName = *(argv++);
-       srcDirFlag = isDirectory(srcName);
-       if (recursiveAction(srcName, TRUE, TRUE, FALSE,
-                              fileAction, fileAction) == FALSE) {
-           exit( FALSE);
-       }
-       if (recursiveAction(srcName, TRUE, TRUE, TRUE,
-                              rmfileAction, rmdirAction) == FALSE) {
-           exit( FALSE);
-       }
-    }
-    exit( TRUE);
-}
index 5be3a67cb696340b192ecb0d9efcbcc48df23df1..5fd5ea30318a2cfbac8997599b3ad3135aca90a3 100644 (file)
@@ -143,7 +143,7 @@ printf_main(int argc, char** argv)
   int args_used;
 
   exit_status = 0;
-  if ( **(argv+1) == '-' ) {
+  if ( argc <= 1 || **(argv+1) == '-' ) {
     usage (printf_usage);
   }
 
index c5ce6ff891bca5c65717d47e9e1365079154982c..bacabd77a0bbc3ed4fd76817bfbd099609ea4ae0 100644 (file)
 #include "internal.h"
 #include <stdio.h>
 #include <dirent.h>
+#include <sys/param.h>
 
 extern int
 pwd_main(int argc, char * * argv)
 {
-       char            buf[NAME_MAX];
+       char            buf[PATH_MAX + 1];
 
        if ( getcwd(buf, sizeof(buf)) == NULL ) {
                perror("get working directory");
index 4df5627acc4c287baaf7127d1b0088caa859de23..d529ce722e179d3e8c85d82a4213684fc9e99bcd 100644 (file)
@@ -309,4 +309,4 @@ sort_main(int argc, char **argv)
     exit(0);
 }
 
-/* $Id: sort.c,v 1.9 2000/01/23 18:19:02 erik Exp $ */
+/* $Id: sort.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */
index 5198892b63df48a85f9ec0d0cc1c48f7b5d35fdf..0ab8f11b01b2a962395e39de242d5671dc72cdf3 100644 (file)
@@ -33,7 +33,7 @@
     and generally busyboxed, Erik Andersen <andersen@lineo.com>
 
    Removed superfluous options and associated code ("-c", "-n", "-q").
-   Removed "tail -f" suport for multiple files.
+   Removed "tail -f" support for multiple files.
    Both changes by Friedrich Vedder <fwv@myrtle.lahn.de>.
 
  */
index 8d1ca6efd49e7dd21467ecca03776df384ad5258..4c5c691c6426d5993e9a6d7e2687a52a06659c21 100644 (file)
@@ -123,4 +123,4 @@ tee_main(int argc, char **argv)
     exit(0);
 }
 
-/* $Id: tee.c,v 1.4 1999/12/10 08:25:07 andersen Exp $ */
+/* $Id: tee.c,v 1.5 2000/02/07 05:29:42 erik Exp $ */
index a7bff54ecc1e75ce829e7450a005e2ea0048155c..965d290c2ff9003e4d72707601ffb15ae36e0a4e 100644 (file)
@@ -193,4 +193,4 @@ uniq_main(int argc, char **argv)
     exit(0);
 }
 
-/* $Id: uniq.c,v 1.5 2000/01/23 18:19:02 erik Exp $ */
+/* $Id: uniq.c,v 1.6 2000/02/07 05:29:42 erik Exp $ */
diff --git a/cp.c b/cp.c
deleted file mode 100644 (file)
index e96012d..0000000
--- a/cp.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Mini cp implementation for busybox
- *
- *
- * Copyright (C) 1999 by Lineo, inc.
- * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
- *
- * 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 <time.h>
-#include <utime.h>
-#include <dirent.h>
-
-static const char cp_usage[] = "cp [OPTION]... SOURCE DEST\n"
-    "   or: cp [OPTION]... SOURCE... DIRECTORY\n\n"
-    "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n"
-    "\n"
-    "\t-a\tsame as -dpR\n"
-    "\t-d\tpreserve links\n"
-    "\t-p\tpreserve file attributes if possible\n"
-    "\t-R\tcopy directories recursively\n";
-
-
-static int recursiveFlag = FALSE;
-static int followLinks = FALSE;
-static int preserveFlag = FALSE;
-static const char *srcName;
-static const char *destName;
-static int destDirFlag = FALSE;
-static int srcDirFlag = FALSE;
-
-static int fileAction(const char *fileName, struct stat* statbuf)
-{
-    char newdestName[NAME_MAX];
-    char* newsrcName = NULL;
-
-    strcpy(newdestName, destName);
-    if ( srcDirFlag == TRUE ) {
-       if (recursiveFlag!=TRUE ) {
-           fprintf(stderr, "cp: %s: omitting directory\n", srcName);
-           return( TRUE);
-       }
-       strcat(newdestName, strstr(fileName, srcName) + strlen(srcName));
-    } 
-    
-    if (destDirFlag==TRUE && srcDirFlag == FALSE) {
-       if (newdestName[strlen(newdestName)-1] != '/' ) {
-           strcat(newdestName, "/");
-       }
-       newsrcName = strrchr(srcName, '/');
-       if (newsrcName && *newsrcName != '\0')
-           strcat(newdestName, newsrcName);
-       else
-           strcat(newdestName, srcName);
-    }
-    
-    return (copyFile(fileName, newdestName, preserveFlag, followLinks));
-}
-
-extern int cp_main(int argc, char **argv)
-{
-    if (argc < 3) {
-       usage (cp_usage);
-    }
-    argc--;
-    argv++;
-
-    /* Parse any options */
-    while (**argv == '-') {
-       while (*++(*argv))
-           switch (**argv) {
-           case 'a':
-               followLinks = TRUE;
-               preserveFlag = TRUE;
-               recursiveFlag = TRUE;
-               break;
-           case 'd':
-               followLinks = TRUE;
-               break;
-           case 'p':
-               preserveFlag = TRUE;
-               break;
-           case 'R':
-               recursiveFlag = TRUE;
-               break;
-           default:
-               usage (cp_usage);
-           }
-       argc--;
-       argv++;
-    }
-
-
-    destName = argv[argc - 1];
-    destDirFlag = isDirectory(destName);
-
-    if ((argc > 3) && destDirFlag==FALSE) {
-       fprintf(stderr, "%s: not a directory\n", destName);
-       exit (FALSE);
-    }
-
-    while (argc-- > 1) {
-       srcName = *(argv++);
-       srcDirFlag = isDirectory(srcName);
-       if (recursiveAction(srcName, recursiveFlag, followLinks, FALSE,
-                              fileAction, fileAction) == FALSE) {
-           exit( FALSE);
-       }
-    }
-    exit( TRUE);
-}
diff --git a/cp_mv.c b/cp_mv.c
new file mode 100644 (file)
index 0000000..2ba8662
--- /dev/null
+++ b/cp_mv.c
@@ -0,0 +1,258 @@
+/*
+ * Mini `cp' and `mv' implementation for BusyBox.
+ *
+ *
+ * Copyright (C) 1999 by Lineo, inc.
+ * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
+ *
+ * Copyright (C) 2000 by BitterSweet Enterprises, LLC. (GPL)
+ * Extensively modified and rewritten by  Karl M. Hegbloom <karlheg@debian.org>
+ *
+ * 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"
+#define BB_DECLARE_EXTERN
+#define bb_need_name_too_long
+#define bb_need_omitting_directory
+#define bb_need_not_a_directory
+#include "messages.c"
+
+#include <stdio.h>
+#include <time.h>
+#include <utime.h>
+#include <dirent.h>
+#include <sys/param.h>
+
+#define is_cp 0
+#define is_mv 1
+static const char *dz;         /* dollar zero, .bss */
+static int dz_i;               /* index,       .bss */
+static const char *cp_mv_usage[] =     /* .rodata */
+{
+     "cp [OPTION]... SOURCE DEST\n"
+     "   or: cp [OPTION]... SOURCE... DIRECTORY\n\n"
+     "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n"
+     "\n"
+     "\t-a\tsame as -dpR\n"
+     "\t-d\tpreserve links\n"
+     "\t-p\tpreserve file attributes if possible\n"
+     "\t-R\tcopy directories recursively\n"
+     ,
+     "mv SOURCE DEST\n"
+     "   or: mv SOURCE... DIRECTORY\n\n"
+     "Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n"
+     "Warning!!  This is not GNU `mv'.  It does not preserve hard links.\n"
+};
+
+extern int cp_mv_main(int argc, char **argv)
+{
+    __label__ name_too_long__exit;
+    __label__ exit_false;
+
+    int         recursiveFlag;
+    int         followLinks;
+    int         preserveFlag;
+
+    const char *baseSrcName;
+    int         srcDirFlag;
+
+    char        baseDestName[PATH_MAX + 1];
+    size_t      baseDestLen;
+    int         destDirFlag;
+
+    void fill_baseDest_buf(char *_buf, size_t *_buflen)
+       {
+           const char *srcBasename;
+           if ((srcBasename = strrchr(baseSrcName, '/')) == NULL)
+           {
+               srcBasename = baseSrcName;
+               if (_buf[*_buflen - 1] != '/')
+               {
+                   if (++(*_buflen) > PATH_MAX)
+                       goto name_too_long__exit;
+                   strcat(_buf, "/");
+               }
+           }
+           if (*_buflen + strlen(srcBasename) > PATH_MAX)
+               goto name_too_long__exit;
+           strcat(_buf, srcBasename);
+           return;
+       }
+
+    int fileAction(const char *fileName, struct stat *statbuf)
+       {
+           __label__   return_false;
+           char        destName[PATH_MAX + 1];
+           size_t      destLen;
+           const char *srcBasename;
+           
+           strcpy(destName, baseDestName);
+           destLen = strlen(destName);
+           
+           if (srcDirFlag == TRUE)
+           {
+               if (recursiveFlag == FALSE)
+               {
+                   fprintf(stderr, omitting_directory, "cp", baseSrcName);
+                   return TRUE;
+               }
+               srcBasename = (strstr(fileName, baseSrcName)
+                              + strlen(baseSrcName));
+               if (destLen + strlen(srcBasename) > PATH_MAX)
+               {
+                   fprintf(stderr, name_too_long, "cp");
+                   goto return_false;
+               }
+               strcat(destName, srcBasename);
+           }
+           else if (destDirFlag == TRUE)
+           {
+               fill_baseDest_buf(&destName[0], &destLen);
+           }
+           else
+           {
+               srcBasename = baseSrcName;
+           }
+           return copyFile(fileName, destName, preserveFlag, followLinks);
+           
+       return_false:
+           return FALSE;
+       }
+
+    int rmfileAction(const char *fileName, struct stat* statbuf)
+        {
+             if (unlink(fileName) < 0 ) {
+                  perror(fileName);
+                  return FALSE;
+             }
+             return TRUE;
+        }
+
+    int rmdirAction(const char *fileName, struct stat* statbuf)
+        {
+             if (rmdir(fileName) < 0 ) {
+                  perror(fileName);
+                  return FALSE;
+             }
+             return TRUE;
+        }
+
+    if ((dz = strrchr(*argv, '/')) == NULL) dz = *argv; else dz++;
+    if (*dz == 'c' && *(dz + 1) == 'p') dz_i = is_cp; else dz_i = is_mv;
+    if (argc < 3) usage(cp_mv_usage[dz_i]);
+    argc--;
+    argv++;
+
+    if (dz_i == is_cp)
+    {
+       recursiveFlag = preserveFlag = FALSE;
+       followLinks = TRUE;
+       while (**argv == '-')
+       {
+           while (*++(*argv))
+           {
+               switch (**argv)
+               {
+               case 'a':
+                   followLinks   = FALSE;
+                   preserveFlag  = TRUE;
+                   recursiveFlag = TRUE;
+                   break;
+               case 'd':
+                   followLinks   = FALSE;
+                   break;
+               case 'p':
+                   preserveFlag  = TRUE;
+                   break;
+               case 'R':
+                   recursiveFlag = TRUE;
+                   break;
+               default:
+                   usage(cp_mv_usage[is_cp]);
+               }
+           }
+           argc--;
+           argv++;
+       }
+    }
+    else /* (dz_i == is_mv) */
+    {
+       recursiveFlag = preserveFlag = TRUE;
+       followLinks = FALSE;
+    }
+
+    if (strlen(argv[argc - 1]) > PATH_MAX)
+    {
+       fprintf(stderr, name_too_long, "cp");
+       goto exit_false;
+    }
+    strcpy(baseDestName, argv[argc - 1]);
+    baseDestLen = strlen(baseDestName);
+    if (baseDestLen == 0) goto exit_false;
+
+    destDirFlag = isDirectory(baseDestName, TRUE);
+    if ((argc > 3) && destDirFlag == FALSE)
+    {
+       fprintf(stderr, not_a_directory, "cp", baseDestName);
+       goto exit_false;
+    }
+
+    while (argc-- > 1)
+    {
+       size_t srcLen;
+       int    flags_memo;
+
+       baseSrcName = *(argv++);
+
+       if ((srcLen = strlen(baseSrcName)) > PATH_MAX)
+           goto name_too_long__exit;
+
+       if (srcLen == 0) continue;
+
+       srcDirFlag = isDirectory(baseSrcName, followLinks);
+
+       if ((flags_memo = (recursiveFlag == TRUE &&
+                          srcDirFlag == TRUE && destDirFlag == TRUE)))
+       {
+           fill_baseDest_buf(&baseDestName[0], &baseDestLen);
+       }
+       if (recursiveAction(baseSrcName,
+                           recursiveFlag, followLinks, FALSE,
+                           fileAction, fileAction)
+           == FALSE) goto exit_false;
+
+       if (dz_i == is_mv &&
+           recursiveAction(baseSrcName,
+                           recursiveFlag, followLinks, TRUE,
+                           rmfileAction, rmdirAction)
+           == FALSE) goto exit_false;
+
+       if (flags_memo) *(baseDestName + baseDestLen) = '\0';
+    }
+
+    exit TRUE;
+
+ name_too_long__exit:
+    fprintf(stderr, name_too_long, "cp");
+ exit_false:
+    exit FALSE;
+}
+
+// Local Variables:
+// c-file-style: "k&r"
+// c-basic-offset: 4
+// End:
diff --git a/date.c b/date.c
index 77e7c39db7461b85dd2325e8291f2f848ed0099c..a3528921db88fec3e687f58772faea67a3f48baf 100644 (file)
--- a/date.c
+++ b/date.c
 */
 
 #include "internal.h"
+#define BB_DECLARE_EXTERN
+#define bb_need_invalid_date
+#define bb_need_memory_exhausted
+#include "messages.c"
 #include <stdlib.h>
 #include <errno.h>
 #include <sys/time.h>
@@ -59,7 +63,7 @@ date_conv_time(struct tm *tm_time, const char *t_string) {
             &(tm_time->tm_year));
 
   if(nr < 4 || nr > 5) {
-    fprintf(stderr, "date: invalid date `%s'\n", t_string);
+    fprintf(stderr, invalid_date, "date", t_string);
     exit( FALSE);
   }
 
@@ -152,7 +156,7 @@ date_conv_ftime(struct tm *tm_time, const char *t_string) {
 
   }
 
-  fprintf(stderr, "date: invalid date `%s'\n", t_string);
+  fprintf(stderr, invalid_date, "date", t_string);
 
   exit( FALSE);
 
@@ -190,7 +194,7 @@ date_main(int argc, char * * argv)
            case 'u':
                utc = 1;
                if (putenv ("TZ=UTC0") != 0) {
-                   fprintf(stderr,"date: memory exhausted\n");
+                   fprintf(stderr, memory_exhausted, "date");
                    exit( FALSE);
                }
                /* Look ma, no break.  Don't fix it either. */
@@ -204,10 +208,10 @@ date_main(int argc, char * * argv)
            }
        } else {
            if ( (date_fmt == NULL) && (strcmp(*argv, "+")==0) )
-               date_fmt = *argv;
+               date_fmt=*argv;
            else if (date_str == NULL) {
                set_time = 1;
-               date_str = *argv;
+               date_str=*argv;
            } else { 
                usage ( date_usage);
            }
@@ -241,7 +245,7 @@ date_main(int argc, char * * argv)
     /* Correct any day of week and day of year etc fields */
     tm = mktime(&tm_time);
     if (tm < 0 ) {
-      fprintf(stderr, "date: invalid date `%s'\n", date_str);
+      fprintf(stderr, invalid_date, "date", date_str);
       exit( FALSE);
     }
 
@@ -284,4 +288,3 @@ date_main(int argc, char * * argv)
   exit( TRUE);
 
 }
-
diff --git a/dd.c b/dd.c
index bc01eedbfaab9e4dfc5df26387ac05ae3dcdc3b9..3e1024a609b4288ae8d291576780424f222b3fe0 100644 (file)
--- a/dd.c
+++ b/dd.c
@@ -40,15 +40,16 @@ typedef unsigned long long int uintmax_t;
 #endif
 
 static const char dd_usage[] =
-"dd [if=name] [of=name] [bs=n] [count=n]\n\n"
+"dd [if=name] [of=name] [bs=n] [count=n] [skip=n] [seek=n]\n\n"
 "Copy a file, converting and formatting according to options\n\n"
 "\tif=FILE\tread from FILE instead of stdin\n"
-"\tof=FILE\twrite to FILE instead of stout\n"
-"\tbs=n\tread and write N BYTES at a time\n"
+"\tof=FILE\twrite to FILE instead of stdout\n"
+"\tbs=n\tread and write n bytes at a time\n"
 "\tcount=n\tcopy only n input blocks\n"
-//"\tskip=n\tskip n input blocks\n"
+"\tskip=n\tskip n input blocks\n"
+"\tseek=n\tskip n output blocks\n"
 "\n"
-"BYTES may be suffixed by w (x2), k (x1024), b (x512), or m (x1024^2).\n";
+"Numbers may be suffixed by w (x2), k (x1024), b (x512), or M (x1024^2)\n";
 
 
 
@@ -61,8 +62,9 @@ extern int dd_main (int argc, char **argv)
     int outFd;
     int inCc = 0;
     int outCc;
-    size_t blockSize = 512;
-    //uintmax_t skipBlocks = 0;
+    long blockSize = 512;
+    uintmax_t skipBlocks = 0;
+    uintmax_t seekBlocks = 0;
     uintmax_t count = (uintmax_t)-1;
     uintmax_t intotal;
     uintmax_t outTotal;
@@ -91,16 +93,22 @@ extern int dd_main (int argc, char **argv)
                goto usage;
            }
        }
-#if 0
        else if (strncmp(*argv, "skip", 4) == 0) {
-           skipBlocks = atoi( *argv); 
+           skipBlocks = getNum ((strchr(*argv, '='))+1);
            if (skipBlocks <= 0) {
-               fprintf (stderr, "Bad skip value %d\n", skipBlocks);
+               fprintf (stderr, "Bad skip value %s\n", *argv);
+               goto usage;
+           }
+
+       }
+       else if (strncmp(*argv, "seek", 4) == 0) {
+           seekBlocks = getNum ((strchr(*argv, '='))+1);
+           if (seekBlocks <= 0) {
+               fprintf (stderr, "Bad seek value %s\n", *argv);
                goto usage;
            }
 
        }
-#endif
        else {
            goto usage;
        }
@@ -131,7 +139,7 @@ extern int dd_main (int argc, char **argv)
     if (outFile == NULL)
        outFd = fileno(stdout);
     else
-       outFd = creat (outFile, 0666);
+       outFd = open(outFile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
 
     if (outFd < 0) {
        perror (outFile);
@@ -140,10 +148,11 @@ extern int dd_main (int argc, char **argv)
        exit( FALSE);
     }
 
-    //lseek(inFd, skipBlocks*blockSize, SEEK_SET);
+    lseek(inFd, skipBlocks*blockSize, SEEK_SET);
+    lseek(outFd, seekBlocks*blockSize, SEEK_SET);
     //
     //TODO: Convert to using fullRead & fullWrite
-    // from utilitity.c
+    // from utility.c
     //  -Erik
     while (outTotal < count * blockSize) {
        inCc = read (inFd, buf, blockSize);
diff --git a/du.c b/du.c
index 79b553643efcfdb6fbf1dd5057e1b605c5c38679..e2cf3f7c09408d4d96b4219aee50d48d40626693 100644 (file)
--- a/du.c
+++ b/du.c
  */
 
 #include "internal.h"
+#define BB_DECLARE_EXTERN
+#define bb_need_name_too_long
+#include "messages.c"
+
 #include <sys/types.h>
 #include <fcntl.h>
 #include <dirent.h>
 #include <stdio.h>
 #include <errno.h>
-#if 0
-#include <unistd.h>
-#include <sys/stat.h>
-#endif
+#include <sys/param.h>         /* for PATH_MAX */
 
-typedef void (Display)(size_t, char *);
+typedef void (Display)(long, char *);
 
 static const char du_usage[] =
 "du [OPTION]... [FILE]...\n\n"
@@ -44,13 +45,13 @@ static int  du_depth = 0;
 static Display *print;
 
 static void
-print_normal(size_t size, char *filename)
+print_normal(long size, char *filename)
 {
-    fprintf(stdout, "%-7d %s\n", (size >> 1), filename);
+    fprintf(stdout, "%-7ld %s\n", size, filename);
 }
 
 static void
-print_summary(size_t size, char *filename)
+print_summary(long size, char *filename)
 {
     if (du_depth == 1) { 
        print_normal(size, filename); 
@@ -59,11 +60,11 @@ print_summary(size_t size, char *filename)
 
 
 /* tiny recursive du */
-static size_t
+static long
 du(char *filename)
 {
     struct stat statbuf;
-    size_t     sum;
+    long       sum;
 
     if ((lstat(filename, &statbuf)) != 0) { 
        fprintf(stdout, "du: %s: %s\n", filename, strerror(errno));
@@ -80,14 +81,19 @@ du(char *filename)
        dir = opendir(filename);
        if (!dir) { return 0; }
        while ((entry = readdir(dir))) {
-           char newfile[512];
+           char newfile[PATH_MAX + 1];
            char *name = entry->d_name;
 
            if (  (strcmp(name, "..") == 0)
               || (strcmp(name, ".")  == 0)) 
            { continue; }
 
+           if (strlen(filename) + strlen(name) + 1 > PATH_MAX) {
+             fprintf(stderr, name_too_long, "du");
+             return 0;
+           }
            sprintf(newfile, "%s/%s", filename, name);
+
            sum += du(newfile);
        }
        closedir(dir);
@@ -130,14 +136,14 @@ du_main(int argc, char **argv)
     if (i >= argc) {
        du(".");
     } else {
-       int sum;
+       long sum;
        for ( ; i < argc; i++) {
            sum = du(argv[i]);
-           if ((sum) && (isDirectory(argv[i]))) { print_normal(sum, argv[i]); }
+           if ((sum) && (isDirectory(argv[i], FALSE))) { print_normal(sum, argv[i]); }
        }
     }
 
     exit(0);
 }
 
-/* $Id: du.c,v 1.9 2000/01/23 18:19:02 erik Exp $ */
+/* $Id: du.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */
index 51b0c2baca4260f57eeb6c99dd24be183bae0c5c..a244e8def4e94f9d53986729504a60e466b42d40 100644 (file)
--- a/fdflush.c
+++ b/fdflush.c
@@ -31,7 +31,7 @@ extern int fdflush_main(int argc, char **argv)
 {
     int        value;
     int        fd;
-    if ( **(argv+1) == '-' ) {
+    if ( argc <= 1 || **(argv++) == '-' ) {
        usage( "fdflush device\n");
     }
 
diff --git a/find.c b/find.c
index 47ce21ec4f6d4fb36d61eaa5d6c69b8346cfe960..50872b7f180d95f2b551f9813074a9e9b84930e9 100644 (file)
--- a/find.c
+++ b/find.c
@@ -90,7 +90,7 @@ int find_main(int argc, char **argv)
                if (strcmp(*argv, "name")==0) {
                    if (argc-- > 1) {
                        pattern = *(++argv);
-                       stopit=TRUE;
+                       stopit = TRUE;
                    } else {
                        usage (find_usage);
                    }
index 47ce21ec4f6d4fb36d61eaa5d6c69b8346cfe960..50872b7f180d95f2b551f9813074a9e9b84930e9 100644 (file)
@@ -90,7 +90,7 @@ int find_main(int argc, char **argv)
                if (strcmp(*argv, "name")==0) {
                    if (argc-- > 1) {
                        pattern = *(++argv);
-                       stopit=TRUE;
+                       stopit = TRUE;
                    } else {
                        usage (find_usage);
                    }
index d31de20a89697502c8c77e9e0cd99860ae195268..09111c5dce1cc2a795fcaa8946de93d409272ac4 100644 (file)
@@ -96,6 +96,7 @@
 #include <termios.h>
 #include <mntent.h>
 #include <sys/stat.h>
+#include <sys/param.h>         /* for PATH_MAX */
 
 #include <linux/fs.h>
 #include <linux/minix_fs.h>
@@ -143,7 +144,7 @@ static int termios_set = 0;
 /* File-name data */
 #define MAX_DEPTH 50
 static int name_depth = 0;
-static char name_list[MAX_DEPTH][NAME_MAX+1];
+static char name_list[MAX_DEPTH][PATH_MAX + 1];
 
 static char * inode_buffer = NULL;
 #define Inode (((struct minix_inode *) inode_buffer)-1)
index fddcc76538925b3c8fe0218126afb442ac95e369..db7fa1dfe48f448f5de8e7b484fabcfe44167ec8 100644 (file)
--- a/gunzip.c
+++ b/gunzip.c
@@ -3,6 +3,9 @@
    */
 
 #include "internal.h"
+#define bb_need_name_too_long
+#define BB_DECLARE_EXTERN
+#include "messages.c"
 
 static const char gunzip_usage[] =
     "gunzip [OPTION]... FILE\n\n"
@@ -64,6 +67,7 @@ static char  *license_msg[] = {
 #include <signal.h>
 #include <sys/stat.h>
 #include <errno.h>
+#include <sys/param.h>         /* for PATH_MAX */
 
 /* #include "tailor.h" */
 
@@ -627,8 +631,12 @@ typedef RETSIGTYPE (*sig_type) OF((int));
 #endif
 #define RW_USER (S_IRUSR | S_IWUSR)  /* creation mode for open() */
 
-#ifndef MAX_PATH_LEN
-#  define MAX_PATH_LEN   1024 /* max pathname length */
+#ifndef MAX_PATH_LEN /* max pathname length */
+#  ifdef PATH_MAX
+#    define MAX_PATH_LEN   PATH_MAX
+#  else
+#    define MAX_PATH_LEN   1024
+#  endif
 #endif
 
 #ifndef SEEK_END
@@ -696,8 +704,8 @@ int gunzip_main (int argc, char** argv)
     int delInputFile=0;
     struct stat statBuf;
     char* delFileName; 
-    char ifname[MAX_PATH_LEN]; /* input file name */
-    char ofname[MAX_PATH_LEN]; /* output file name */
+    char ifname[MAX_PATH_LEN + 1]; /* input file name */
+    char ofname[MAX_PATH_LEN + 1]; /* output file name */
 
     if (argc==1)
        usage(gunzip_usage);
@@ -764,7 +772,11 @@ int gunzip_main (int argc, char** argv)
        /* Open up the input file */
        if (*argv=='\0')
            usage(gunzip_usage);
-       strncpy(ifname, *argv, MAX_PATH_LEN);
+       if (strlen(*argv) > MAX_PATH_LEN) {
+           fprintf(stderr, name_too_long, "gunzip");
+           do_exit(WARNING);
+       }
+       strcpy(ifname, *argv);
 
        /* Open input fille */
        inFileNum=open( ifname, O_RDONLY);
@@ -799,7 +811,11 @@ int gunzip_main (int argc, char** argv)
        char* pos;
 
        /* And get to work */
-       strncpy(ofname, ifname, MAX_PATH_LEN-4);
+       if (strlen(ifname) > MAX_PATH_LEN - 4) {
+           fprintf(stderr, name_too_long, "gunzip");
+           do_exit(WARNING);
+       }
+       strcpy(ofname, ifname);
        pos=strstr(ofname, ".gz");
        if (pos != NULL) {
            *pos='\0';
diff --git a/head.c b/head.c
index bc7f35429d155d9483ba5155dd8a840900529d29..b80d065801e899980140ea18785595015f768cc8 100644 (file)
--- a/head.c
+++ b/head.c
@@ -105,4 +105,4 @@ head_main(int argc, char **argv)
     exit(0);
 }
 
-/* $Id: head.c,v 1.6 2000/01/25 18:13:53 erik Exp $ */
+/* $Id: head.c,v 1.7 2000/02/07 05:29:42 erik Exp $ */
index 20e1741870c0e7f9983fd15c48b635082b452344..68a56095076081a78198474568a79fb957fb5efa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: hostname.c,v 1.5 1999/12/09 06:11:36 andersen Exp $
+ * $Id: hostname.c,v 1.6 2000/02/07 05:29:42 erik Exp $
  * Mini hostname implementation for busybox
  *
  * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
diff --git a/init.c b/init.c
index d88b64ba2e413027dde7534d30c8680d645a7d26..2b1d21336f251710c6589b78c7bd4319b60be3cf 100644 (file)
--- a/init.c
+++ b/init.c
@@ -40,6 +40,7 @@
 #include <sys/reboot.h>
 #include <sys/kdaemon.h>
 #include <sys/sysmacros.h>
+#include <asm/types.h>
 #include <linux/serial.h>      /* for serial_struct */
 #include <sys/vt.h>            /* for vt_stat */
 #include <sys/ioctl.h>
@@ -123,7 +124,7 @@ int device_open(char *device, int mode)
 
     /* Retry up to 5 times */
     for (f = 0; f < 5; f++)
-       if ((fd = open(device, m)) >= 0)
+       if ((fd = open(device, m, 0600)) >= 0)
            break;
     if (fd < 0)
        return fd;
@@ -470,19 +471,19 @@ static void shutdown_system(void)
     sync();
 
     /* Send signals to every process _except_ pid 1 */
-    message(CONSOLE, "Sending SIGHUP to all processes.\r\n");
-    kill(-1, SIGHUP);
-    sleep(2);
+    message(CONSOLE, "Sending SIGTERM to all processes.\r\n");
+    kill(-1, SIGTERM);
+    sleep(5);
     sync();
 
     message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
     kill(-1, SIGKILL);
-    sleep(1);
+    sleep(5);
 
     message(CONSOLE, "Disabling swap.\r\n");
-    waitfor( "swapoff -a", console, FALSE);
+       waitfor( "swapoff -a", console, FALSE);
     message(CONSOLE, "Unmounting filesystems.\r\n");
-    waitfor("umount -a", console, FALSE);
+       waitfor("umount -a -r", console, FALSE);
     sync();
     if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) {
        /* bdflush, kupdate not needed for kernels >2.2.11 */
@@ -500,7 +501,7 @@ static void halt_signal(int sig)
     sync();
 
     /* allow time for last message to reach serial console */
-    sleep(2);
+    sleep(5);
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
     if (sig == SIGUSR2)
index d88b64ba2e413027dde7534d30c8680d645a7d26..2b1d21336f251710c6589b78c7bd4319b60be3cf 100644 (file)
@@ -40,6 +40,7 @@
 #include <sys/reboot.h>
 #include <sys/kdaemon.h>
 #include <sys/sysmacros.h>
+#include <asm/types.h>
 #include <linux/serial.h>      /* for serial_struct */
 #include <sys/vt.h>            /* for vt_stat */
 #include <sys/ioctl.h>
@@ -123,7 +124,7 @@ int device_open(char *device, int mode)
 
     /* Retry up to 5 times */
     for (f = 0; f < 5; f++)
-       if ((fd = open(device, m)) >= 0)
+       if ((fd = open(device, m, 0600)) >= 0)
            break;
     if (fd < 0)
        return fd;
@@ -470,19 +471,19 @@ static void shutdown_system(void)
     sync();
 
     /* Send signals to every process _except_ pid 1 */
-    message(CONSOLE, "Sending SIGHUP to all processes.\r\n");
-    kill(-1, SIGHUP);
-    sleep(2);
+    message(CONSOLE, "Sending SIGTERM to all processes.\r\n");
+    kill(-1, SIGTERM);
+    sleep(5);
     sync();
 
     message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
     kill(-1, SIGKILL);
-    sleep(1);
+    sleep(5);
 
     message(CONSOLE, "Disabling swap.\r\n");
-    waitfor( "swapoff -a", console, FALSE);
+       waitfor( "swapoff -a", console, FALSE);
     message(CONSOLE, "Unmounting filesystems.\r\n");
-    waitfor("umount -a", console, FALSE);
+       waitfor("umount -a -r", console, FALSE);
     sync();
     if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) {
        /* bdflush, kupdate not needed for kernels >2.2.11 */
@@ -500,7 +501,7 @@ static void halt_signal(int sig)
     sync();
 
     /* allow time for last message to reach serial console */
-    sleep(2);
+    sleep(5);
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
     if (sig == SIGUSR2)
index 9cb635f40385d7a77a61bc9a077640175bed9997..31cb1126193617bb75f0967cb22fd17688397cf7 100644 (file)
--- a/insmod.c
+++ b/insmod.c
@@ -67,8 +67,8 @@ _syscall2(unsigned long, create_module, const char *, name, size_t, size)
 #endif
 
 
-static char m_filename[PATH_MAX] = "\0";
-static char m_fullName[PATH_MAX] ="\0";
+static char m_filename[PATH_MAX + 1] = "\0";
+static char m_fullName[PATH_MAX + 1] = "\0";
 static const char insmod_usage[] =
     "insmod [OPTION]... MODULE [symbol=value]...\n\n"
     "Loads the specified kernel modules into the kernel.\n\n"
@@ -101,7 +101,7 @@ extern int insmod_main(int argc, char **argv)
 {
     int len;
     char *tmp;
-    char m_name[PATH_MAX] ="\0";
+    char m_name[PATH_MAX + 1] ="\0";
     FILE *fp;
 
     if (argc<=1) {
index 1686054a8ba382361e46b59d48f5870813c22ee6..79e6a039ad61fc4d1760872fce0fa43659c52f74 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * Busybox main internal header file
  *
@@ -20,8 +21,8 @@
  * Permission has been granted to redistribute this code under the GPL.
  *
  */
-#ifndef        _INTERNAL_H_
-#define        _INTERNAL_H_
+#ifndef        _BB_INTERNAL_H_
+#define        _BB_INTERNAL_H_    1
 
 #include "busybox.def.h"
 
 #define FALSE   ((int) 1)
 #define TRUE    ((int) 0)
 
-#define PATH_LEN        1024
+/* for mtab.c */
+#define MTAB_GETMOUNTPT '1'
+#define MTAB_GETDEVICE  '2'
+
 #define BUF_SIZE        8192
 #define EXPAND_ALLOC    1024
 
@@ -55,7 +59,7 @@ struct Applet {
 extern int busybox_main(int argc, char** argv);
 extern int block_device_main(int argc, char** argv);
 extern int cat_main(int argc, char** argv);
-extern int cp_main(int argc, char** argv);
+extern int cp_mv_main(int argc, char** argv);
 extern int chmod_chown_chgrp_main(int argc, char** argv);
 extern int chroot_main(int argc, char** argv);
 extern int chvt_main(int argc, char** argv);
@@ -105,8 +109,7 @@ extern int mnc_main(int argc, char** argv);
 extern int more_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 nslookup_main(int argc, char** argv);
+extern int nslookup_main(int argc, char **argv);
 extern int ping_main(int argc, char **argv);
 extern int poweroff_main(int argc, char **argv);
 extern int printf_main(int argc, char** argv);
@@ -142,7 +145,7 @@ extern int yes_main(int argc, char** argv);
 
 const char *modeString(int mode);
 const char *timeString(time_t timeVal);
-int isDirectory(const char *name);
+int isDirectory(const char *name, const int followLinks);
 int isDevice(const char *name);
 int copyFile(const char *srcName, const char *destName, int setModes,
                int followLinks);
@@ -172,6 +175,11 @@ extern struct mntent *findMountPoint(const char *name, const char *table);
 extern void write_mtab(char* blockDevice, char* directory, 
        char* filesystemType, long flags, char* string_flags);
 extern void erase_mtab(const char * name);
+extern void mtab_read(void);
+extern void mtab_free(void);
+extern char *mtab_first(void **iter);
+extern char *mtab_next(void **iter);
+extern char *mtab_getinfo(const char *match, const char which);
 extern int check_wildcard_match(const char* text, const char* pattern);
 extern long getNum (const char *cp);
 extern pid_t findInitPid();
@@ -226,5 +234,4 @@ static inline int clrbit(char * addr,unsigned int nr)
 #endif
 
 
-#endif /* _INTERNAL_H_ */
-
+#endif /* _BB_INTERNAL_H_ */
index 46242b529eb7f5d9b37092b37c948f15179cf50e..2c83cdfd2d44d40125cf6931a5ec421895c01adb 100644 (file)
--- a/length.c
+++ b/length.c
@@ -6,7 +6,7 @@
 extern int
 length_main(int argc, char * * argv)
 {
-    if ( **(argv+1) == '-' ) {
+    if ( argc != 2 || **(argv+1) == '-' ) {
        usage("length string\n");
     }
     printf("%d\n", strlen(argv[1]));
diff --git a/ln.c b/ln.c
index 60fe394386a8a7f7a3441da9e4f6ba8cb0dab6e2..f20b340eac1498570f872711e98aa6614e6033b2 100644 (file)
--- a/ln.c
+++ b/ln.c
  */
 
 #include "internal.h"
+#define BB_DECLARE_EXTERN
+#define bb_need_name_too_long
+#define bb_need_not_a_directory
+#include "messages.c"
+
 #include <stdio.h>
 #include <dirent.h>
 #include <errno.h>
+#include <sys/param.h>         /* for PATH_MAX */
 
-
-static const char ln_usage[] = "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n"
-"Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n"
-"Options:\n"
-"\t-s\tmake symbolic links instead of hard links\n"
-"\t-f\tremove existing destination files\n";
-
+static const char ln_usage[] =
+    "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n"
+    "Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n"
+    "Options:\n"
+    "\t-s\tmake symbolic links instead of hard links\n"
+    "\t-f\tremove existing destination files\n"
+    "\t-n\tno dereference symlinks - treat like normal file\n";
 
 static int symlinkFlag = FALSE;
 static int removeoldFlag = FALSE;
-
+static int followLinks = TRUE;
 
 extern int ln_main(int argc, char **argv)
 {
-    int status;
-    static char* linkName;
+    char *linkName;
+    int linkIntoDirFlag;
 
     if (argc < 3) {
        usage (ln_usage);
@@ -59,6 +65,9 @@ extern int ln_main(int argc, char **argv)
            case 'f':
                removeoldFlag = TRUE;
                break;
+           case 'n':
+               followLinks = FALSE;
+               break;
            default:
                usage (ln_usage);
            }
@@ -66,30 +75,54 @@ extern int ln_main(int argc, char **argv)
        argv++;
     }
 
-
     linkName = argv[argc - 1];
 
-    if ((argc > 3) && !(isDirectory(linkName))) {
-       fprintf(stderr, "%s: not a directory\n", linkName);
-       exit (FALSE);
+    if (strlen(linkName) > PATH_MAX) {
+       fprintf(stderr, name_too_long, "ln");
+       exit FALSE;
+    }
+
+    linkIntoDirFlag = isDirectory(linkName, TRUE);
+
+    if ((argc > 3) && !linkIntoDirFlag) {
+       fprintf(stderr, not_a_directory, "ln", linkName);
+       exit FALSE;
     }
 
     while (argc-- >= 2) {
-       if (removeoldFlag==TRUE ) {
+       char srcName[PATH_MAX + 1];
+       int nChars, status;
+
+       if (strlen(*argv) > PATH_MAX) {
+           fprintf(stderr, name_too_long, "ln");
+           exit FALSE;
+       }
+
+       if (followLinks == FALSE) {
+           strcpy(srcName, *argv);
+       } else {
+           /* Warning!  This can silently truncate if > PATH_MAX, but
+           I don't think that there can be one > PATH_MAX anyway. */
+           nChars = readlink(*argv, srcName, PATH_MAX);
+           srcName[nChars] = '\0';
+       }
+
+       if (removeoldFlag == TRUE) {
            status = ( unlink(linkName) && errno != ENOENT );
-           if ( status != 0 ) {
+           if (status != 0) {
                perror(linkName);
-               exit( FALSE);
+               exit FALSE;
            }
        }
-       if ( symlinkFlag==TRUE)
-               status = symlink(*argv, linkName);
+
+       if (symlinkFlag == TRUE)
+           status = symlink(*argv, linkName);
        else
-               status = link(*argv, linkName);
-       if ( status != 0 ) {
+           status = link(*argv, linkName);
+       if (status != 0) {
            perror(linkName);
-           exit( FALSE);
+           exit FALSE;
        }
     }
-    exit( TRUE);
+    exit TRUE;
 }
diff --git a/ls.c b/ls.c
index 78193e7c150e21018b85cc90f7520d20e19af29c..450ea18147c6fa36941594dc0d0bc16706d922cb 100644 (file)
--- a/ls.c
+++ b/ls.c
@@ -178,7 +178,7 @@ static char append_char(mode_t mode)
 
 static void list_single(const char *name, struct stat *info, const char *fullname)
 {
-       char scratch[PATH_MAX];
+       char scratch[PATH_MAX + 1];
        short len = strlen(name);
 #ifdef BB_FEATURE_LS_FILETYPES
        char append = append_char(info->st_mode);
diff --git a/messages.c b/messages.c
new file mode 100644 (file)
index 0000000..bfbf317
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2000 by BitterSweet Enterprises, LLC.
+ * Written by Karl M. Hegbloom <karlheg@debian.org>
+ *
+ * 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
+ *
+ */
+
+/*
+ *  Let's put all of these messages in one place, and link this in as
+ *  a separate object module, so that there are not going to be
+ *  multiple non-unique but very similar strings in the binary.
+ *  Perhaps this will make it simpler to internationalize also, and
+ *  may make the binary slightly smaller.
+ */
+#ifndef _BB_MESSAGES_C
+#define _BB_MESSAGES_C
+
+#define _BB_DEF_MESSAGE_PROTO(symbol)                   extern const char *symbol;
+#define _BB_DEF_MESSAGE_INITIALIZE(symbol, string_const) const char *symbol = string_const;
+
+#ifdef BB_DECLARE_EXTERN
+#  define BB_DEF_MESSAGE(symbol, string_const) _BB_DEF_MESSAGE_PROTO(symbol)
+#else
+#  define BB_DEF_MESSAGE(symbol, string_const) _BB_DEF_MESSAGE_INITIALIZE(symbol, string_const)
+#endif
+
+#if defined bb_need_name_too_long || ! defined BB_DECLARE_EXTERN
+BB_DEF_MESSAGE(name_too_long, "%s: file name too long\n")
+#endif
+
+#if defined bb_need_omitting_directory || ! defined BB_DECLARE_EXTERN
+BB_DEF_MESSAGE(omitting_directory, "%s: %s: omitting directory\n")
+#endif
+
+#if defined bb_need_not_a_directory || ! defined BB_DECLARE_EXTERN
+BB_DEF_MESSAGE(not_a_directory, "%s: %s: not a directory\n")
+#endif
+
+#if defined bb_need_memory_exhausted || ! defined BB_DECLARE_EXTERN
+BB_DEF_MESSAGE(memory_exhausted, "%s: memory exhausted\n")
+#endif
+
+#if defined bb_need_invalid_date || ! defined BB_DECLARE_EXTERN
+BB_DEF_MESSAGE(invalid_date, "%s: invalid date `%s'\n")
+#endif
+
+#if defined bb_need_invalid_option || ! defined BB_DECLARE_EXTERN
+BB_DEF_MESSAGE(invalid_option, "%s: invalid option -- %c\n")
+#endif
+
+#endif /* _BB_MESSAGES_C */
diff --git a/mkdir.c b/mkdir.c
index 017ef9b08083c3c56f3e4217bc8bc2eb5a905d23..8e3f51bfb9ea724c49fa1f545dbfdc8f03710084 100644 (file)
--- a/mkdir.c
+++ b/mkdir.c
  */
 
 #include "internal.h"
+#define bb_need_name_too_long
+#define BB_DECLARE_EXTERN
+#include "messages.c"
+
 #include <stdio.h>
 #include <errno.h>
-#include <sys/param.h>
+#include <sys/param.h>         /* for PATH_MAX */
 
 static const char mkdir_usage[] =
 "mkdir [OPTION] DIRECTORY...\n\n"
@@ -40,27 +44,27 @@ static mode_t mode = 0777;
 
 extern int mkdir_main(int argc, char **argv)
 {
-    int i=FALSE;
+    int i = FALSE;
     argc--;
     argv++;
 
     /* Parse any options */
     while (argc > 0 && **argv == '-') {
-       while (i==FALSE && *++(*argv)) {
+       while (i == FALSE && *++(*argv)) {
            switch (**argv) {
            case 'm':
                if (--argc == 0)
                    usage( mkdir_usage);
                /* Find the specified modes */
                mode = 0;
-               if ( parse_mode(*(++argv), &mode) == FALSE ) {
+               if (parse_mode(*(++argv), &mode) == FALSE ) {
                    fprintf(stderr, "Unknown mode: %s\n", *argv);
-                   exit( FALSE);
+                   exit FALSE;
                }
                /* Set the umask for this process so it doesn't 
                 * screw up whatever the user just entered. */
                umask(0);
-               i=TRUE;
+               i = TRUE;
                break;
            case 'p':
                parentFlag = TRUE;
@@ -73,7 +77,6 @@ extern int mkdir_main(int argc, char **argv)
        argv++;
     }
 
-
     if (argc < 1) {
        usage( mkdir_usage);
     }
@@ -81,13 +84,16 @@ extern int mkdir_main(int argc, char **argv)
     while (argc > 0) {
        int status;
        struct stat statBuf;
-       char buf[NAME_MAX];
-
+       char buf[PATH_MAX + 1];
+       if (strlen(*argv) > PATH_MAX - 1) {
+           fprintf(stderr, name_too_long, "mkdir");
+           exit FALSE;
+       }
        strcpy (buf, *argv);
-       status=stat(buf, &statBuf);
-       if (parentFlag == FALSE && status != -1 && status != ENOENT ) {
+       status = stat(buf, &statBuf);
+       if (parentFlag == FALSE && status != -1 && errno != ENOENT) {
            fprintf(stderr, "%s: File exists\n", buf);
-           exit( FALSE);
+           exit FALSE;
        }
        if (parentFlag == TRUE) {
            strcat( buf, "/");
@@ -96,13 +102,13 @@ extern int mkdir_main(int argc, char **argv)
        else { 
            if (mkdir (buf, mode) != 0 && parentFlag == FALSE) {
                perror(buf);
-               exit( FALSE);
+               exit FALSE;
            }
        }
        argc--;
        argv++;
     }
-    exit( TRUE);
+    exit TRUE;
 }
 
 
index 9cb635f40385d7a77a61bc9a077640175bed9997..31cb1126193617bb75f0967cb22fd17688397cf7 100644 (file)
@@ -67,8 +67,8 @@ _syscall2(unsigned long, create_module, const char *, name, size_t, size)
 #endif
 
 
-static char m_filename[PATH_MAX] = "\0";
-static char m_fullName[PATH_MAX] ="\0";
+static char m_filename[PATH_MAX + 1] = "\0";
+static char m_fullName[PATH_MAX + 1] = "\0";
 static const char insmod_usage[] =
     "insmod [OPTION]... MODULE [symbol=value]...\n\n"
     "Loads the specified kernel modules into the kernel.\n\n"
@@ -101,7 +101,7 @@ extern int insmod_main(int argc, char **argv)
 {
     int len;
     char *tmp;
-    char m_name[PATH_MAX] ="\0";
+    char m_name[PATH_MAX + 1] ="\0";
     FILE *fp;
 
     if (argc<=1) {
diff --git a/mtab.c b/mtab.c
index 98e42a383c8249c89dfad18980841197159c335f..41d88184bde2b4ada84855a4e5d264c7830e0c32 100644 (file)
--- a/mtab.c
+++ b/mtab.c
@@ -5,21 +5,13 @@
 #include <string.h>
 #include <stdio.h>
 #include <mntent.h>
+#include <fstab.h>
 #include <sys/mount.h>
 
 extern const char mtab_file[]; /* Defined in utility.c */
 
-static char *
-stralloc(const char * string)
-{
-       int     length = strlen(string) + 1;
-       char *  n = malloc(length);
-       memcpy(n, string, length);
-       return n;
-}
 
-extern void
-erase_mtab(const char * name)
+void erase_mtab(const char * name)
 {
        struct mntent   entries[20];
        int     count = 0;
@@ -39,10 +31,10 @@ erase_mtab(const char * name)
        }
 
        while ( (m = getmntent(mountTable)) != 0 ) {
-               entries[count].mnt_fsname = stralloc(m->mnt_fsname);
-               entries[count].mnt_dir = stralloc(m->mnt_dir);
-               entries[count].mnt_type = stralloc(m->mnt_type);
-               entries[count].mnt_opts = stralloc(m->mnt_opts);
+               entries[count].mnt_fsname = strdup(m->mnt_fsname);
+               entries[count].mnt_dir = strdup(m->mnt_dir);
+               entries[count].mnt_type = strdup(m->mnt_type);
+               entries[count].mnt_opts = strdup(m->mnt_opts);
                entries[count].mnt_freq = m->mnt_freq;
                entries[count].mnt_passno = m->mnt_passno;
                count++;
@@ -65,8 +57,7 @@ erase_mtab(const char * name)
                perror(mtab_file);
 }
 
-extern void 
-write_mtab(char* blockDevice, char* directory, 
+void write_mtab(char* blockDevice, char* directory, 
        char* filesystemType, long flags, char* string_flags)
 {
        FILE *mountTable = setmntent(mtab_file, "a+");
@@ -110,4 +101,3 @@ write_mtab(char* blockDevice, char* directory,
     }
 }
 
-
diff --git a/mv.c b/mv.c
deleted file mode 100644 (file)
index 467a360..0000000
--- a/mv.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Mini mv implementation for busybox
- *
- *
- * Copyright (C) 1999 by Lineo, inc.
- * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
- *
- * 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 <time.h>
-#include <utime.h>
-#include <dirent.h>
-
-static const char mv_usage[] = "mv SOURCE DEST\n"
-"   or: mv SOURCE... DIRECTORY\n\n"
-"Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n";
-
-
-static const char *srcName;
-static const char *destName;
-static int destDirFlag = FALSE;
-static int srcDirFlag = FALSE;
-
-static int fileAction(const char *fileName, struct stat* statbuf)
-{
-    char newdestName[NAME_MAX];
-    char* newsrcName = NULL;
-
-    strcpy(newdestName, destName);
-    if ( srcDirFlag == TRUE ) {
-       strcat(newdestName, strstr(fileName, srcName) + strlen(srcName));
-    } 
-    
-    if (destDirFlag==TRUE && srcDirFlag == FALSE) {
-       if (newdestName[strlen(newdestName)-1] != '/' ) {
-           strcat(newdestName, "/");
-       }
-       newsrcName = strrchr(srcName, '/');
-       if (newsrcName && *newsrcName != '\0')
-           strcat(newdestName, newsrcName);
-       else
-           strcat(newdestName, srcName);
-    }
-    
-    return (copyFile(fileName, newdestName, TRUE, TRUE));
-}
-
-static int rmfileAction(const char *fileName, struct stat* statbuf)
-{
-    if (unlink( fileName) < 0 ) {
-       perror( fileName);
-       return ( FALSE);
-    }
-    return ( TRUE);
-}
-
-static int rmdirAction(const char *fileName, struct stat* statbuf)
-{
-    if (rmdir( fileName) < 0 ) {
-       perror( fileName);
-       return ( FALSE);
-    }
-    return ( TRUE);
-}
-
-
-extern int mv_main(int argc, char **argv)
-{
-    if (argc < 3) {
-       usage (mv_usage);
-    }
-    argc--;
-    argv++;
-
-    destName = argv[argc - 1];
-    destDirFlag = isDirectory(destName);
-
-    if ((argc > 3) && destDirFlag==FALSE) {
-       fprintf(stderr, "%s: not a directory\n", destName);
-       exit (FALSE);
-    }
-
-    while (argc-- > 1) {
-       srcName = *(argv++);
-       srcDirFlag = isDirectory(srcName);
-       if (recursiveAction(srcName, TRUE, TRUE, FALSE,
-                              fileAction, fileAction) == FALSE) {
-           exit( FALSE);
-       }
-       if (recursiveAction(srcName, TRUE, TRUE, TRUE,
-                              rmfileAction, rmdirAction) == FALSE) {
-           exit( FALSE);
-       }
-    }
-    exit( TRUE);
-}
index 20e1741870c0e7f9983fd15c48b635082b452344..68a56095076081a78198474568a79fb957fb5efa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: hostname.c,v 1.5 1999/12/09 06:11:36 andersen Exp $
+ * $Id: hostname.c,v 1.6 2000/02/07 05:29:42 erik Exp $
  * Mini hostname implementation for busybox
  *
  * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
index 82d3b3690a83a3f29ac409dcdebc51a04a7b8df1..969d0b19b00a0c1e332433b660bfb3e15313b017 100644 (file)
@@ -185,4 +185,4 @@ nslookup_main(int argc, char **argv)
     return 0;
 }
 
-/* $Id: nslookup.c,v 1.2 2000/01/30 09:47:16 beppu Exp $ */
+/* $Id: nslookup.c,v 1.3 2000/02/07 05:29:42 erik Exp $ */
index 5b680195ac0981911988dab910216684f952c37c..3ffbdc553500dd649cb27d78ae54761cfb01a012 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ping.c,v 1.9 2000/01/29 06:29:32 erik Exp $
+ * $Id: ping.c,v 1.10 2000/02/07 05:29:42 erik Exp $
  * Mini ping implementation for busybox
  *
  * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
@@ -175,7 +175,8 @@ extern int ping_main(int argc, char **argv)
 static const char* ping_usage = "ping [OPTION]... host\n\n"
 "Send ICMP ECHO_REQUEST packets to network hosts.\n\n"
 "Options:\n"
-"\t-q\t\tQuiet mode, only displays output at start and when finished.\n"
+"\t-q\t\tQuiet mode, only displays output at start"
+"\t\t\tand when finished.\n"
 "\t-c COUNT\tSend only COUNT pings.\n";
 
 static char *hostname = NULL;
index 82d3b3690a83a3f29ac409dcdebc51a04a7b8df1..969d0b19b00a0c1e332433b660bfb3e15313b017 100644 (file)
@@ -185,4 +185,4 @@ nslookup_main(int argc, char **argv)
     return 0;
 }
 
-/* $Id: nslookup.c,v 1.2 2000/01/30 09:47:16 beppu Exp $ */
+/* $Id: nslookup.c,v 1.3 2000/02/07 05:29:42 erik Exp $ */
diff --git a/ping.c b/ping.c
index 5b680195ac0981911988dab910216684f952c37c..3ffbdc553500dd649cb27d78ae54761cfb01a012 100644 (file)
--- a/ping.c
+++ b/ping.c
@@ -1,5 +1,5 @@
 /*
- * $Id: ping.c,v 1.9 2000/01/29 06:29:32 erik Exp $
+ * $Id: ping.c,v 1.10 2000/02/07 05:29:42 erik Exp $
  * Mini ping implementation for busybox
  *
  * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
@@ -175,7 +175,8 @@ extern int ping_main(int argc, char **argv)
 static const char* ping_usage = "ping [OPTION]... host\n\n"
 "Send ICMP ECHO_REQUEST packets to network hosts.\n\n"
 "Options:\n"
-"\t-q\t\tQuiet mode, only displays output at start and when finished.\n"
+"\t-q\t\tQuiet mode, only displays output at start"
+"\t\t\tand when finished.\n"
 "\t-c COUNT\tSend only COUNT pings.\n";
 
 static char *hostname = NULL;
index 5be3a67cb696340b192ecb0d9efcbcc48df23df1..5fd5ea30318a2cfbac8997599b3ad3135aca90a3 100644 (file)
--- a/printf.c
+++ b/printf.c
@@ -143,7 +143,7 @@ printf_main(int argc, char** argv)
   int args_used;
 
   exit_status = 0;
-  if ( **(argv+1) == '-' ) {
+  if ( argc <= 1 || **(argv+1) == '-' ) {
     usage (printf_usage);
   }
 
diff --git a/pwd.c b/pwd.c
index c5ce6ff891bca5c65717d47e9e1365079154982c..bacabd77a0bbc3ed4fd76817bfbd099609ea4ae0 100644 (file)
--- a/pwd.c
+++ b/pwd.c
 #include "internal.h"
 #include <stdio.h>
 #include <dirent.h>
+#include <sys/param.h>
 
 extern int
 pwd_main(int argc, char * * argv)
 {
-       char            buf[NAME_MAX];
+       char            buf[PATH_MAX + 1];
 
        if ( getcwd(buf, sizeof(buf)) == NULL ) {
                perror("get working directory");
diff --git a/sort.c b/sort.c
index 4df5627acc4c287baaf7127d1b0088caa859de23..d529ce722e179d3e8c85d82a4213684fc9e99bcd 100644 (file)
--- a/sort.c
+++ b/sort.c
@@ -309,4 +309,4 @@ sort_main(int argc, char **argv)
     exit(0);
 }
 
-/* $Id: sort.c,v 1.9 2000/01/23 18:19:02 erik Exp $ */
+/* $Id: sort.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */
index 8eaf9797cbedde35de72f3e179b5c1c6084608fc..3c02bdd42d1baf1efefc1fc926e95cd177213acf 100644 (file)
@@ -65,7 +65,6 @@ static void
 do_em_all()
 {
        struct mntent *m;
-       char swapName[NAME_MAX];
        FILE *f = setmntent ("/etc/fstab", "r");
 
        if (f == NULL) {
@@ -73,8 +72,8 @@ do_em_all()
            exit( FALSE); 
        }
        while ((m = getmntent (f)) != NULL) {
-           if (!strstr (m->mnt_type, "swap")) {
-                   swap_enable_disable( swapName);
+           if (!strstr (m->mnt_type, MNTTYPE_SWAP)) {
+                   swap_enable_disable( m->mnt_fsname);
            }
        }
        endmntent (f);
index 0be9ded06cac9c589efb2ffb182867b5fd2b97b3..29ede13db84fe1a1924b2cce72f6e3be5dcc1186 100644 (file)
@@ -77,7 +77,7 @@ static int device_open(char *device, int mode)
 
     /* Retry up to 5 times */
     for (f = 0; f < 5; f++)
-       if ((fd = open(device, m)) >= 0)
+       if ((fd = open(device, m, 0600)) >= 0)
            break;
     if (fd < 0)
        return fd;
@@ -177,9 +177,6 @@ static void doSyslogd(void)
     char *q, *p = buf;
     int readSize;
 
-    /* Remove any preexisting socket/file */
-    unlink(_PATH_LOG);
-
     /* Set up sig handlers */
     signal(SIGINT,  quit_signal);
     signal(SIGTERM, quit_signal);
@@ -188,8 +185,9 @@ static void doSyslogd(void)
     signal(SIGALRM, domark);
     alarm(MarkInterval);
 
+    /* Remove any preexisting socket/file */
+    unlink(_PATH_LOG);
 
-    unlink( _PATH_LOG);
     memset(&sunx, 0, sizeof(sunx));
     sunx.sun_family = AF_UNIX; /* Unix domain socket */
     strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path));
@@ -200,12 +198,17 @@ static void doSyslogd(void)
 
     addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
     if ( (bind(fd, (struct sockaddr *) &sunx, addrLength)) ||
-           (fchmod(fd, 0666) < 0) || (listen(fd, 5)) ) 
+           (listen(fd, 5)) ) 
     {
        perror("Could not connect to socket " _PATH_LOG);
        exit( FALSE);
     }
     
+    umask(0);
+    if (chmod(_PATH_LOG, 0666) < 0) {
+        perror("Could not set permission on " _PATH_LOG);
+        exit (FALSE);
+    }
     
     logMessage(LOG_SYSLOG|LOG_INFO, "syslogd started: "
            "BusyBox v" BB_VER " (" BB_BT ")");
index 0be9ded06cac9c589efb2ffb182867b5fd2b97b3..29ede13db84fe1a1924b2cce72f6e3be5dcc1186 100644 (file)
--- a/syslogd.c
+++ b/syslogd.c
@@ -77,7 +77,7 @@ static int device_open(char *device, int mode)
 
     /* Retry up to 5 times */
     for (f = 0; f < 5; f++)
-       if ((fd = open(device, m)) >= 0)
+       if ((fd = open(device, m, 0600)) >= 0)
            break;
     if (fd < 0)
        return fd;
@@ -177,9 +177,6 @@ static void doSyslogd(void)
     char *q, *p = buf;
     int readSize;
 
-    /* Remove any preexisting socket/file */
-    unlink(_PATH_LOG);
-
     /* Set up sig handlers */
     signal(SIGINT,  quit_signal);
     signal(SIGTERM, quit_signal);
@@ -188,8 +185,9 @@ static void doSyslogd(void)
     signal(SIGALRM, domark);
     alarm(MarkInterval);
 
+    /* Remove any preexisting socket/file */
+    unlink(_PATH_LOG);
 
-    unlink( _PATH_LOG);
     memset(&sunx, 0, sizeof(sunx));
     sunx.sun_family = AF_UNIX; /* Unix domain socket */
     strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path));
@@ -200,12 +198,17 @@ static void doSyslogd(void)
 
     addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
     if ( (bind(fd, (struct sockaddr *) &sunx, addrLength)) ||
-           (fchmod(fd, 0666) < 0) || (listen(fd, 5)) ) 
+           (listen(fd, 5)) ) 
     {
        perror("Could not connect to socket " _PATH_LOG);
        exit( FALSE);
     }
     
+    umask(0);
+    if (chmod(_PATH_LOG, 0666) < 0) {
+        perror("Could not set permission on " _PATH_LOG);
+        exit (FALSE);
+    }
     
     logMessage(LOG_SYSLOG|LOG_INFO, "syslogd started: "
            "BusyBox v" BB_VER " (" BB_BT ")");
diff --git a/tail.c b/tail.c
index 5198892b63df48a85f9ec0d0cc1c48f7b5d35fdf..0ab8f11b01b2a962395e39de242d5671dc72cdf3 100644 (file)
--- a/tail.c
+++ b/tail.c
@@ -33,7 +33,7 @@
     and generally busyboxed, Erik Andersen <andersen@lineo.com>
 
    Removed superfluous options and associated code ("-c", "-n", "-q").
-   Removed "tail -f" suport for multiple files.
+   Removed "tail -f" support for multiple files.
    Both changes by Friedrich Vedder <fwv@myrtle.lahn.de>.
 
  */
diff --git a/tar.c b/tar.c
index 0fa09ffd86834ad95df1da6f1e30e25e0c18927c..6496231ae029076c68fb8cb4b7f197c4a89d1c62 100644 (file)
--- a/tar.c
+++ b/tar.c
@@ -40,6 +40,7 @@
 #include <utime.h>
 #include <sys/types.h>
 #include <sys/sysmacros.h>
+#include <sys/param.h>         /* for PATH_MAX */
 
 
 #ifdef BB_FEATURE_TAR_CREATE
@@ -1041,7 +1042,7 @@ static void saveDirectory (const char *dirName, const struct stat *statbuf)
     DIR *dir;
     struct dirent *entry;
     int needSlash;
-    char fullName[NAME_MAX];
+    char fullName[PATH_MAX + 1];
 
     /* 
      * Construct the directory name as used in the tar file by appending
diff --git a/tee.c b/tee.c
index 8d1ca6efd49e7dd21467ecca03776df384ad5258..4c5c691c6426d5993e9a6d7e2687a52a06659c21 100644 (file)
--- a/tee.c
+++ b/tee.c
@@ -123,4 +123,4 @@ tee_main(int argc, char **argv)
     exit(0);
 }
 
-/* $Id: tee.c,v 1.4 1999/12/10 08:25:07 andersen Exp $ */
+/* $Id: tee.c,v 1.5 2000/02/07 05:29:42 erik Exp $ */
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644 (file)
index 0000000..0156344
--- /dev/null
@@ -0,0 +1,28 @@
+all test_all: message_header cp_tests mv_tests ln_tests
+
+clean: cp_clean mv_clean ln_clean
+
+message_header:
+       @echo
+       @echo If tests faile due to differences in timestamps in commands that are not set
+       @echo to preserve timestamps, just run the tests again.
+       @echo
+
+include cp_tests.mk
+include mv_tests.mk
+include ln_tests.mk
+
+BBL := $(shell pushd .. >/dev/null &&          \
+                ${MAKE} busybox.links >/dev/null && \
+              popd >/dev/null &&               \
+              cat ../busybox.links |           \
+                sed -e 's,.*/\(.*\)$$,\1,')
+
+../busybox:
+       cd .. && ${MAKE} busybox
+
+$(BBL): ../busybox
+       rm -f $@
+       ln ../busybox $@
+
+.PHONY: all test_all message_header
diff --git a/tests/cp_tests.mk b/tests/cp_tests.mk
new file mode 100644 (file)
index 0000000..e14262a
--- /dev/null
@@ -0,0 +1,270 @@
+# This is a -*- makefile -*-
+
+# GNU `cp'
+GCP = /bin/cp
+# BusyBox `cp'
+BCP = $(shell pwd)/cp
+
+.PHONY: cp_clean
+cp_clean:
+       rm -rf cp_tests cp_*.{gnu,bb} cp
+
+.PHONY: cp_tests
+cp_tests: cp_clean cp
+       @echo;
+       @echo "No output from diff means busybox cp is functioning properly.";
+
+       @echo;
+       ${BCP} || true;
+
+       @echo;
+       mkdir cp_tests;
+
+       @echo;
+       cd cp_tests;                            \
+        echo A file > afile;                   \
+        ls -l afile > ../cp_afile_afilecopy.gnu; \
+        ${GCP} afile afilecopy;                \
+        ls -l afile afilecopy >> ../cp_afile_afilecopy.gnu;
+
+       @echo;
+       rm -f cp_tests/afile*;
+
+       @echo;
+       cd cp_tests;                            \
+        echo A file > afile;                   \
+        ls -l afile > ../cp_afile_afilecopy.bb; \
+        ${BCP} afile afilecopy;                \
+        ls -l afile afilecopy >> ../cp_afile_afilecopy.bb;
+
+       @echo;
+       diff -u cp_afile_afilecopy.gnu cp_afile_afilecopy.bb;
+
+       @echo;
+       rm -f cp_tests/afile*;
+
+       @echo; echo;
+       cd cp_tests;                            \
+        mkdir there there1;                    \
+        cd there;                              \
+         ln -s ../afile .;
+
+       @echo;
+       cd cp_tests;                            \
+        echo A file > afile;                   \
+        ls -l afile > ../cp_symlink.gnu;       \
+        ${GCP} there/afile there1/;            \
+        ls -l afile there/afile there1/afile >> ../cp_symlink.gnu;
+
+       @echo;
+       rm -f cp_tests/afile cp_tests/there1/afile;
+
+       @echo;
+       cd cp_tests;                            \
+        echo A file > afile;                   \
+        ls -l afile > ../cp_symlink.bb;        \
+        ${BCP} there/afile there1/;            \
+        ls -l afile there/afile there1/afile >> ../cp_symlink.bb;
+
+       @echo;
+       diff -u cp_symlink.gnu cp_symlink.bb;
+
+       @echo;
+       rm -f cp_tests/afile cp_tests/there1/afile;
+
+       @echo; echo;
+       cd cp_tests;                            \
+        echo A file > afile;                   \
+        ls -l afile > ../cp_a_symlink.gnu;     \
+        ${GCP} -a there/afile there1/;         \
+        ls -l afile there/afile there1/afile >> ../cp_a_symlink.gnu;
+
+       @echo;
+       rm -f cp_tests/afile cp_tests/there1/afile;
+
+       @echo;
+       cd cp_tests;                            \
+        echo A file > afile;                   \
+        ls -l afile > ../cp_a_symlink.bb;      \
+        ${BCP} -a there/afile there1/;         \
+        ls -l afile there/afile there1/afile >> ../cp_a_symlink.bb;
+
+       @echo;
+       diff -u cp_a_symlink.gnu cp_a_symlink.bb;
+
+       @echo;
+       rm -f cp_tests/afile
+       rm -rf cp_tests/there{,1};
+
+       @echo; echo;
+       cd cp_tests;                            \
+        echo A file > there/afile;             \
+        mkdir there/adir;                      \
+        touch there/adir/afileinadir;          \
+        ln -s $(shell pwd) there/alink;
+
+       @echo;
+       cd cp_tests;                            \
+        ${GCP} -a there/ there1/;              \
+        ls -lR there/ there1/ > ../cp_a_dir_dir.gnu;
+
+       @echo;
+       rm -rf cp_tests/there1;
+
+       @echo;
+       cd cp_tests;                            \
+        ${BCP} -a there/ there1/;              \
+        ls -lR there/ there1/ > ../cp_a_dir_dir.bb;
+
+       @echo;
+       diff -u cp_a_dir_dir.gnu cp_a_dir_dir.bb;
+
+       @echo;
+       rm -rf cp_tests/there1/;
+
+       @echo; echo;
+       cd cp_tests;                            \
+        echo A file number one > afile1;       \
+        echo A file number two, blah. > afile2; \
+        ln -s afile1 symlink1;                 \
+        mkdir there1;                          \
+        ${GCP} afile1 afile2 symlink1 there1/; \
+        ls -lR > ../cp_files_dir.gnu;
+
+       @echo;
+       rm -rf cp_tests/{afile{1,2},symlink1,there1};
+
+       @echo;
+       cd cp_tests;                            \
+        echo A file number one > afile1;       \
+        echo A file number two, blah. > afile2; \
+        ln -s afile1 symlink1;                 \
+        mkdir there1;                          \
+        ${BCP} afile1 afile2 symlink1 there1/; \
+        ls -lR > ../cp_files_dir.bb;
+
+       @echo;
+       diff -u cp_files_dir.gnu cp_files_dir.bb;
+
+       @echo;
+       rm -rf cp_tests/{afile{1,2},symlink1,there1};
+
+       @echo; echo;
+       cd cp_tests;                            \
+        echo A file number one > afile1;       \
+        echo A file number two, blah. > afile2; \
+        ln -s afile1 symlink1;                 \
+        mkdir there1;                          \
+        ${GCP} -d afile1 afile2 symlink1 there1/; \
+        ls -lR > ../cp_d_files_dir.gnu;
+
+       @echo;
+       rm -rf cp_tests/{afile{1,2},symlink1,there1};
+
+       @echo;
+       cd cp_tests;                            \
+        echo A file number one > afile1;       \
+        echo A file number two, blah. > afile2; \
+        ln -s afile1 symlink1;                 \
+        mkdir there1;                          \
+        ${BCP} -d afile1 afile2 symlink1 there1/; \
+        ls -lR > ../cp_d_files_dir.bb;
+
+       @echo;
+       diff -u cp_d_files_dir.gnu cp_d_files_dir.bb;
+
+       @echo;
+       rm -rf cp_tests/{afile{1,2},symlink1,there1};
+
+       @echo; echo;
+       cd cp_tests;                            \
+        echo A file number one > afile1;       \
+        echo A file number two, blah. > afile2; \
+        touch --date='Sat Jan 29 21:24:08 PST 2000' afile1; \
+        ln -s afile1 symlink1;                 \
+        mkdir there1;                          \
+        ${GCP} -p afile1 afile2 symlink1 there1/; \
+        ls -lR > ../cp_p_files_dir.gnu;
+
+       @echo;
+       rm -rf cp_tests/{afile{1,2},symlink1,there1};
+
+       @echo;
+       cd cp_tests;                            \
+        echo A file number one > afile1;       \
+        echo A file number two, blah. > afile2; \
+        touch --date='Sat Jan 29 21:24:08 PST 2000' afile1; \
+        ln -s afile1 symlink1;                 \
+        mkdir there1;                          \
+        ${BCP} -p afile1 afile2 symlink1 there1/; \
+        ls -lR > ../cp_p_files_dir.bb;
+
+       @echo;
+       diff -u cp_p_files_dir.gnu cp_p_files_dir.bb;
+
+       @echo;
+       rm -rf cp_tests/{afile{1,2},symlink1,there1};
+
+       @echo; echo;
+       cd cp_tests;                            \
+        echo A file number one > afile1;       \
+        echo A file number two, blah. > afile2; \
+        touch --date='Sat Jan 29 21:24:08 PST 2000' afile1; \
+        ln -s afile1 symlink1;                 \
+        mkdir there1;                          \
+        ${GCP} -p -d afile1 afile2 symlink1 there1/; \
+        ls -lR > ../cp_pd_files_dir.gnu;
+
+       @echo;
+       rm -rf cp_tests/{afile{1,2},symlink1,there1};
+
+       @echo;
+       cd cp_tests;                            \
+        echo A file number one > afile1;       \
+        echo A file number two, blah. > afile2; \
+        touch --date='Sat Jan 29 21:24:08 PST 2000' afile1; \
+        ln -s afile1 symlink1;                 \
+        mkdir there1;                          \
+        ${BCP} -p -d afile1 afile2 symlink1 there1/; \
+        ls -lR > ../cp_pd_files_dir.bb;
+
+       @echo;
+       diff -u cp_pd_files_dir.gnu cp_pd_files_dir.bb;
+
+       @echo;
+       rm -rf cp_tests/{afile{1,2},symlink1,there1};
+
+       @echo; echo;
+       cd cp_tests;                            \
+        mkdir dir{a,b};                        \
+        echo A file > dira/afile;              \
+        echo A file in dirb > dirb/afileindirb; \
+        ln -s dira/afile dira/alinktoafile;    \
+        mkdir dira/subdir1;                    \
+        echo Another file > dira/subdir1/anotherfile; \
+        ls -lR . > ../cp_a_dira_dirb.gnu;      \
+        ${GCP} -a dira dirb;                   \
+        ls -lR . >> ../cp_a_dira_dirb.gnu;
+
+       # false;
+       @echo;
+       rm -rf cp_tests/dir{a,b};
+
+       @echo;
+       cd cp_tests;                            \
+        mkdir dir{a,b};                        \
+        echo A file > dira/afile;              \
+        echo A file in dirb > dirb/afileindirb; \
+        ln -s dira/afile dira/alinktoafile;    \
+        mkdir dira/subdir1;                    \
+        echo Another file > dira/subdir1/anotherfile; \
+        ls -lR . > ../cp_a_dira_dirb.bb;       \
+        ${BCP} -a dira dirb;                   \
+        ls -lR . >> ../cp_a_dira_dirb.bb;
+
+       @echo;
+       diff -u cp_a_dira_dirb.gnu cp_a_dira_dirb.bb;
+
+       # false;
+       @echo;
+       rm -rf cp_tests/dir{a,b};
diff --git a/tests/ln_tests.mk b/tests/ln_tests.mk
new file mode 100644 (file)
index 0000000..5925edd
--- /dev/null
@@ -0,0 +1,66 @@
+
+# GNU `ln'
+GLN = /bin/ln
+# BusyBox `ln'
+BLN = $(shell pwd)/ln
+
+.PHONY: ln_clean
+ln_clean:
+       rm -rf ln_tests ln_*.{gnu,bb} ln
+
+.PHONY: ln_tests
+ln_tests: ln_clean ln
+       @echo;
+       @echo "No output from diff means busybox ln is functioning properly.";
+
+       @echo;
+       ${BLN} || true;
+
+       @echo;
+       mkdir ln_tests;
+
+       @echo;
+       cd ln_tests;                            \
+        echo A file > afile;                   \
+        ls -l afile > ../ln_afile_newname.gnu; \
+        ${GLN} afile newname;                  \
+        ls -l afile newname >> ../ln_afile_newname.gnu;
+
+       @echo;
+       rm -f ln_tests/{afile,newname};
+
+       @echo;
+       cd ln_tests;                            \
+        echo A file > afile;                   \
+        ls -l afile > ../ln_afile_newname.bb;  \
+        ${BLN} afile newname;                  \
+        ls -l afile newname >> ../ln_afile_newname.bb;
+
+       @echo;
+       diff -u ln_afile_newname.gnu ln_afile_newname.bb
+
+       @echo;
+       rm -f ln_tests/{afile,newname};
+
+       @echo;
+       cd ln_tests;                            \
+        echo A file > afile;                   \
+        ls -l afile > ../ln_s_afile_newname.gnu;       \
+        ${GLN} -s afile newname;               \
+        ls -l afile newname >> ../ln_s_afile_newname.gnu;
+
+       @echo;
+       rm -f ln_tests/{afile,newname};
+
+       @echo;
+       cd ln_tests;                            \
+        echo A file > afile;                   \
+        ls -l afile > ../ln_s_afile_newname.bb;        \
+        ${BLN} -s afile newname;               \
+        ls -l afile newname >> ../ln_s_afile_newname.bb;
+
+       @echo;
+       diff -u ln_s_afile_newname.gnu ln_s_afile_newname.bb
+
+       @echo;
+       rm -f ln_tests/{afile,newname};
diff --git a/tests/mv_tests.mk b/tests/mv_tests.mk
new file mode 100644 (file)
index 0000000..3a90125
--- /dev/null
@@ -0,0 +1,137 @@
+
+# GNU `mv'
+GMV = /bin/mv
+# BusyBox `mv'
+BMV = $(shell pwd)/mv
+
+.PHONY: mv_clean
+mv_clean:
+       rm -rf mv_tests mv_*.{gnu,bb} mv
+
+.PHONY: mv_tests
+mv_tests: mv_clean mv
+       @echo;
+       @echo "No output from diff means busybox mv is functioning properly.";
+       @echo;
+       @echo "No such file or directory is good; it means the old file got removed.";
+       @echo;
+       ${BMV} || true;
+
+       @echo;
+       mkdir mv_tests;
+
+       @echo;
+       cd mv_tests;                            \
+        echo A file > afile;                   \
+        ls -l afile > ../mv_afile_newname.gnu; \
+        ${GMV} afile newname;                  \
+        ls -l newname >> ../mv_afile_newname.gnu;
+       -ls -l mv_tests/afile;
+
+       @echo;
+       rm -f mv_tests/{afile,newname};
+
+       @echo;
+       cd mv_tests;                            \
+        echo A file > afile;                   \
+        ls -l afile > ../mv_afile_newname.bb;  \
+        ${BMV} afile newname;                  \
+        ls -l newname >> ../mv_afile_newname.bb;
+       -ls -l mv_tests/afile;
+
+       @echo;
+       diff -u mv_afile_newname.gnu mv_afile_newname.bb;
+
+       @echo;
+       rm -f mv_tests/{afile,newname};
+
+       @echo; echo;
+       cd mv_tests;                            \
+        echo A file > afile;                   \
+        ln -s afile symlink;                   \
+        ls -l afile symlink > ../mv_symlink_newname.gnu; \
+        ${GMV} symlink newname;                \
+        ls -l afile newname >> ../mv_symlink_newname.gnu;
+       -ls -l mv_tests/symlink;
+
+       @echo;
+       rm -f mv_tests/{afile,newname};
+
+       @echo;
+       cd mv_tests;                            \
+        echo A file > afile;                   \
+        ln -s afile symlink;                   \
+        ls -l afile symlink > ../mv_symlink_newname.bb;\
+        ${BMV} symlink newname;                \
+        ls -l afile newname >> ../mv_symlink_newname.bb;
+       -ls -l mv_tests/symlink;
+
+       @echo;
+       diff -u mv_symlink_newname.gnu mv_symlink_newname.bb;
+
+       @echo;
+       rm -rf mv_tests/*;
+
+       @echo; echo;
+       cd mv_tests;                            \
+        echo A file > afile;                   \
+        ln -s afile symlink;                   \
+        mkdir newdir;                          \
+        ls -lR > ../mv_file_symlink_dir.gnu;   \
+        ${GMV} symlink afile newdir;           \
+        ls -lR >> ../mv_file_symlink_dir.gnu;
+       -ls -l mv_tests/{symlink,afile};
+
+       @echo;
+       rm -rf mv_tests/*
+
+       @echo; echo;
+       cd mv_tests;                            \
+        echo A file > afile;                   \
+        ln -s afile symlink;                   \
+        mkdir newdir;                          \
+        ls -lR > ../mv_file_symlink_dir.bb;    \
+        ${BMV} symlink afile newdir;           \
+        ls -lR >> ../mv_file_symlink_dir.bb;
+       -ls -l mv_tests/{symlink,afile};
+
+       @echo;
+       diff -u mv_file_symlink_dir.gnu mv_file_symlink_dir.bb;
+
+       @echo;
+       rm -rf mv_tests/*;
+
+       @echo; echo;
+       cd mv_tests;                            \
+        mkdir dir{a,b};                        \
+        echo A file > dira/afile;              \
+        echo A file in dirb > dirb/afileindirb; \
+        ln -s dira/afile dira/alinktoafile;    \
+        mkdir dira/subdir1;                    \
+        echo Another file > dira/subdir1/anotherfile; \
+        ls -lR . > ../mv_dira_dirb.gnu;        \
+        ${GMV} dira dirb;                      \
+        ls -lR . >> ../mv_dira_dirb.gnu;
+
+       # false;
+       @echo;
+       rm -rf mv_tests/dir{a,b};
+
+       @echo;
+       cd mv_tests;                            \
+        mkdir dir{a,b};                        \
+        echo A file > dira/afile;              \
+        echo A file in dirb > dirb/afileindirb; \
+        ln -s dira/afile dira/alinktoafile;    \
+        mkdir dira/subdir1;                    \
+        echo Another file > dira/subdir1/anotherfile; \
+        ls -lR . > ../mv_dira_dirb.bb;         \
+        ${BMV} dira dirb;                      \
+        ls -lR . >> ../mv_dira_dirb.bb;
+
+       @echo;
+       diff -u mv_dira_dirb.gnu mv_dira_dirb.bb;
+
+       # false;
+       @echo;
+       rm -rf mv_tests/dir{a,b};
index 68b27e385d62fb1eb86435a7aa93b204ed142a8e..b65caf76e21eb049c9e59c463bbabc4320ca1c1a 100644 (file)
--- a/umount.c
+++ b/umount.c
@@ -37,11 +37,24 @@ static const char umount_usage[] =
 #else
 "\n"
 #endif
+#ifdef BB_FEATURE_REMOUNT
+"\t-r:\tTry to remount devices as read-only if mount is busy\n"
+#endif
 ;
 
+struct _mtab_entry_t {
+  char *device;
+  char *mountpt;
+  struct _mtab_entry_t *next;
+};
+
+static struct _mtab_entry_t *mtab_cache = NULL;
+
+
 
 static int useMtab = TRUE;
 static int umountAll = FALSE;
+static int doRemount = FALSE;
 extern const char mtab_file[]; /* Defined in utility.c */
 
 #define MIN(x,y) (x > y ? x : y)
@@ -50,21 +63,10 @@ static int
 do_umount(const char* name, int useMtab)
 {
     int status;
-    struct mntent *m;
-    FILE *mountTable;
-    const char *blockDevice = NULL;
-
-    if ((mountTable = setmntent (mtab_file, "r"))) {
-       while ((m = getmntent (mountTable)) != 0) {
-           if (strncmp(m->mnt_dir, name,
-                       MIN(strlen(m->mnt_dir),strlen(name))) == 0)
-               blockDevice = m->mnt_fsname;
-           else if (strcmp(m->mnt_fsname, name) == 0) {
-               blockDevice = name;
-               name = m->mnt_dir;
-           }
-       }
-    }
+    char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE);
+
+    if (blockDevice && strcmp(blockDevice, name) == 0)
+        name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT);
 
     status = umount(name);
 
@@ -73,57 +75,53 @@ do_umount(const char* name, int useMtab)
        /* this was a loop device, delete it */
        del_loop(blockDevice);
 #endif
-#if defined BB_MTAB
+#if defined BB_FEATURE_REMOUNT
+    if ( status != 0 && doRemount == TRUE && errno == EBUSY ) {
+        status = mount(blockDevice, name, NULL, 
+                       MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
+       if (status == 0) {
+           fprintf(stderr, "umount: %s busy - remounted read-only\n", 
+                    blockDevice);
+           /* TODO: update mtab if BB_MTAB is defined */
+       } else {
+           fprintf(stderr, "umount: Cannot remount %s read-only\n",
+                    blockDevice);
+       }
+    }
+#endif
     if ( status == 0 ) {
+#if defined BB_MTAB
        if ( useMtab==TRUE )
            erase_mtab(name);
-       return 0;
-    }
-    else
 #endif
-       return(status);
+       return( TRUE);
+    }
+    return(FALSE);
 }
 
 static int
 umount_all(int useMtab)
 {
-       int status;
-       struct mntent *m;
-        FILE *mountTable;
-
-        if ((mountTable = setmntent (mtab_file, "r"))) {
-            while ((m = getmntent (mountTable)) != 0) {
-                char *blockDevice = m->mnt_fsname;
-#if ! defined BB_MTAB
-               if (strcmp (blockDevice, "/dev/root") == 0) {
-                   struct fstab* fstabItem;
-                   fstabItem = getfsfile ("/");
-                   if (fstabItem != NULL) {
-                       blockDevice = fstabItem->fs_spec;
-                   }
+       int status = TRUE;
+       char *mountpt;
+       void *iter;
+
+       for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) {
+            status=do_umount (mountpt, useMtab);
+            if (status != 0) {
+                /* Don't bother retrying the umount on busy devices */
+               if (errno == EBUSY) {
+                   perror(mountpt);
+                  continue;
                }
-#endif
-               /* Don't umount /proc when doing umount -a */
-                if (strcmp (blockDevice, "proc") == 0)
-                   continue;
-
-               status=do_umount (m->mnt_dir, useMtab);
-               if (status!=0) {
-                   /* Don't bother retrying the umount on busy devices */
-                   if (errno==EBUSY) {
-                       perror(m->mnt_dir); 
-                       continue;
-                   }
-                   status=do_umount (blockDevice, useMtab);
-                   if (status!=0) {
-                       printf ("Couldn't umount %s on %s (type %s): %s\n", 
-                               blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
-                   }
+               status = do_umount (mountpt, useMtab);
+               if (status != 0) {
+                    printf ("Couldn't umount %s on %s: %s\n", 
+                        mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), strerror(errno));
                }
             }
-            endmntent (mountTable);
         }
-        return( TRUE);
+        return (status);
 }
 
 extern int
@@ -143,14 +141,19 @@ umount_main(int argc, char** argv)
            case 'n':
                useMtab = FALSE;
                break;
+#endif
+#ifdef BB_FEATURE_REMOUNT
+           case 'r':
+               doRemount = TRUE;
+               break;
 #endif
            default:
                usage( umount_usage);
        }
     }
 
-
-    if(umountAll==TRUE) {
+    mtab_read();
+    if (umountAll==TRUE) {
        exit(umount_all(useMtab));
     }
     if ( do_umount(*argv,useMtab) == 0 )
@@ -161,3 +164,87 @@ umount_main(int argc, char** argv)
     }
 }
 
+
+
+/* These functions are here because the getmntent functions do not appear
+ * to be re-entrant, which leads to all sorts of problems when we try to
+ * use them recursively - randolph
+ */
+void mtab_read(void)
+{
+    struct _mtab_entry_t *entry = NULL;
+    struct mntent *e;
+    FILE *fp;
+  
+    if (mtab_cache != NULL) return;
+    if ((fp = setmntent(mtab_file, "r")) == NULL) {
+        fprintf(stderr, "Cannot open %s\n", mtab_file);
+       return;
+    }
+    while ((e = getmntent(fp))) {
+        entry = malloc(sizeof(struct _mtab_entry_t));
+       entry->device = strdup(e->mnt_fsname);
+       entry->mountpt = strdup(e->mnt_dir);
+       entry->next = mtab_cache;
+       mtab_cache = entry;
+    }
+    endmntent(fp);
+}
+
+char *mtab_getinfo(const char *match, const char which)
+{
+    struct _mtab_entry_t *cur = mtab_cache;
+    while (cur) {
+        if (strcmp(cur->mountpt, match) == 0 ||
+           strcmp(cur->device, match) == 0) {
+           if (which == MTAB_GETMOUNTPT) {
+               return cur->mountpt;
+           } else {
+#if !defined BB_MTAB
+                if (strcmp(cur->device, "/dev/root") == 0) {
+                    struct fstab* fstabItem;
+                   fstabItem = getfsfile ("/");
+                   if (fstabItem != NULL) return fstabItem->fs_spec;
+               }
+#endif
+               return cur->device;  
+           }
+       }
+        cur = cur->next;
+    }
+    return NULL;
+}
+
+char *mtab_first(void **iter)
+{
+    struct _mtab_entry_t *mtab_iter;
+    if (!iter) return NULL;
+    mtab_iter = mtab_cache;
+    *iter = (void *)mtab_iter;
+    return mtab_next(iter);
+}
+
+char *mtab_next(void **iter)
+{
+    char *mp;
+    if (iter == NULL || *iter == NULL) return NULL;
+    mp = ((struct _mtab_entry_t *)(*iter))->mountpt;
+    *iter = (void *)((struct _mtab_entry_t *)(*iter))->next;
+    return mp;
+}
+
+void mtab_free(void)
+{
+    struct _mtab_entry_t *this, *next;
+
+    this = mtab_cache;
+    while (this) {
+      next = this->next;
+      if (this->device) free(this->device);
+      if (this->mountpt) free(this->mountpt);
+      free(this);
+      this = next;
+    }
+}
+
diff --git a/uniq.c b/uniq.c
index a7bff54ecc1e75ce829e7450a005e2ea0048155c..965d290c2ff9003e4d72707601ffb15ae36e0a4e 100644 (file)
--- a/uniq.c
+++ b/uniq.c
@@ -193,4 +193,4 @@ uniq_main(int argc, char **argv)
     exit(0);
 }
 
-/* $Id: uniq.c,v 1.5 2000/01/23 18:19:02 erik Exp $ */
+/* $Id: uniq.c,v 1.6 2000/02/07 05:29:42 erik Exp $ */
index 51b0c2baca4260f57eeb6c99dd24be183bae0c5c..a244e8def4e94f9d53986729504a60e466b42d40 100644 (file)
@@ -31,7 +31,7 @@ extern int fdflush_main(int argc, char **argv)
 {
     int        value;
     int        fd;
-    if ( **(argv+1) == '-' ) {
+    if ( argc <= 1 || **(argv++) == '-' ) {
        usage( "fdflush device\n");
     }
 
index d31de20a89697502c8c77e9e0cd99860ae195268..09111c5dce1cc2a795fcaa8946de93d409272ac4 100644 (file)
@@ -96,6 +96,7 @@
 #include <termios.h>
 #include <mntent.h>
 #include <sys/stat.h>
+#include <sys/param.h>         /* for PATH_MAX */
 
 #include <linux/fs.h>
 #include <linux/minix_fs.h>
@@ -143,7 +144,7 @@ static int termios_set = 0;
 /* File-name data */
 #define MAX_DEPTH 50
 static int name_depth = 0;
-static char name_list[MAX_DEPTH][NAME_MAX+1];
+static char name_list[MAX_DEPTH][PATH_MAX + 1];
 
 static char * inode_buffer = NULL;
 #define Inode (((struct minix_inode *) inode_buffer)-1)
index 8eaf9797cbedde35de72f3e179b5c1c6084608fc..3c02bdd42d1baf1efefc1fc926e95cd177213acf 100644 (file)
@@ -65,7 +65,6 @@ static void
 do_em_all()
 {
        struct mntent *m;
-       char swapName[NAME_MAX];
        FILE *f = setmntent ("/etc/fstab", "r");
 
        if (f == NULL) {
@@ -73,8 +72,8 @@ do_em_all()
            exit( FALSE); 
        }
        while ((m = getmntent (f)) != NULL) {
-           if (!strstr (m->mnt_type, "swap")) {
-                   swap_enable_disable( swapName);
+           if (!strstr (m->mnt_type, MNTTYPE_SWAP)) {
+                   swap_enable_disable( m->mnt_fsname);
            }
        }
        endmntent (f);
index 68b27e385d62fb1eb86435a7aa93b204ed142a8e..b65caf76e21eb049c9e59c463bbabc4320ca1c1a 100644 (file)
@@ -37,11 +37,24 @@ static const char umount_usage[] =
 #else
 "\n"
 #endif
+#ifdef BB_FEATURE_REMOUNT
+"\t-r:\tTry to remount devices as read-only if mount is busy\n"
+#endif
 ;
 
+struct _mtab_entry_t {
+  char *device;
+  char *mountpt;
+  struct _mtab_entry_t *next;
+};
+
+static struct _mtab_entry_t *mtab_cache = NULL;
+
+
 
 static int useMtab = TRUE;
 static int umountAll = FALSE;
+static int doRemount = FALSE;
 extern const char mtab_file[]; /* Defined in utility.c */
 
 #define MIN(x,y) (x > y ? x : y)
@@ -50,21 +63,10 @@ static int
 do_umount(const char* name, int useMtab)
 {
     int status;
-    struct mntent *m;
-    FILE *mountTable;
-    const char *blockDevice = NULL;
-
-    if ((mountTable = setmntent (mtab_file, "r"))) {
-       while ((m = getmntent (mountTable)) != 0) {
-           if (strncmp(m->mnt_dir, name,
-                       MIN(strlen(m->mnt_dir),strlen(name))) == 0)
-               blockDevice = m->mnt_fsname;
-           else if (strcmp(m->mnt_fsname, name) == 0) {
-               blockDevice = name;
-               name = m->mnt_dir;
-           }
-       }
-    }
+    char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE);
+
+    if (blockDevice && strcmp(blockDevice, name) == 0)
+        name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT);
 
     status = umount(name);
 
@@ -73,57 +75,53 @@ do_umount(const char* name, int useMtab)
        /* this was a loop device, delete it */
        del_loop(blockDevice);
 #endif
-#if defined BB_MTAB
+#if defined BB_FEATURE_REMOUNT
+    if ( status != 0 && doRemount == TRUE && errno == EBUSY ) {
+        status = mount(blockDevice, name, NULL, 
+                       MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
+       if (status == 0) {
+           fprintf(stderr, "umount: %s busy - remounted read-only\n", 
+                    blockDevice);
+           /* TODO: update mtab if BB_MTAB is defined */
+       } else {
+           fprintf(stderr, "umount: Cannot remount %s read-only\n",
+                    blockDevice);
+       }
+    }
+#endif
     if ( status == 0 ) {
+#if defined BB_MTAB
        if ( useMtab==TRUE )
            erase_mtab(name);
-       return 0;
-    }
-    else
 #endif
-       return(status);
+       return( TRUE);
+    }
+    return(FALSE);
 }
 
 static int
 umount_all(int useMtab)
 {
-       int status;
-       struct mntent *m;
-        FILE *mountTable;
-
-        if ((mountTable = setmntent (mtab_file, "r"))) {
-            while ((m = getmntent (mountTable)) != 0) {
-                char *blockDevice = m->mnt_fsname;
-#if ! defined BB_MTAB
-               if (strcmp (blockDevice, "/dev/root") == 0) {
-                   struct fstab* fstabItem;
-                   fstabItem = getfsfile ("/");
-                   if (fstabItem != NULL) {
-                       blockDevice = fstabItem->fs_spec;
-                   }
+       int status = TRUE;
+       char *mountpt;
+       void *iter;
+
+       for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) {
+            status=do_umount (mountpt, useMtab);
+            if (status != 0) {
+                /* Don't bother retrying the umount on busy devices */
+               if (errno == EBUSY) {
+                   perror(mountpt);
+                  continue;
                }
-#endif
-               /* Don't umount /proc when doing umount -a */
-                if (strcmp (blockDevice, "proc") == 0)
-                   continue;
-
-               status=do_umount (m->mnt_dir, useMtab);
-               if (status!=0) {
-                   /* Don't bother retrying the umount on busy devices */
-                   if (errno==EBUSY) {
-                       perror(m->mnt_dir); 
-                       continue;
-                   }
-                   status=do_umount (blockDevice, useMtab);
-                   if (status!=0) {
-                       printf ("Couldn't umount %s on %s (type %s): %s\n", 
-                               blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
-                   }
+               status = do_umount (mountpt, useMtab);
+               if (status != 0) {
+                    printf ("Couldn't umount %s on %s: %s\n", 
+                        mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), strerror(errno));
                }
             }
-            endmntent (mountTable);
         }
-        return( TRUE);
+        return (status);
 }
 
 extern int
@@ -143,14 +141,19 @@ umount_main(int argc, char** argv)
            case 'n':
                useMtab = FALSE;
                break;
+#endif
+#ifdef BB_FEATURE_REMOUNT
+           case 'r':
+               doRemount = TRUE;
+               break;
 #endif
            default:
                usage( umount_usage);
        }
     }
 
-
-    if(umountAll==TRUE) {
+    mtab_read();
+    if (umountAll==TRUE) {
        exit(umount_all(useMtab));
     }
     if ( do_umount(*argv,useMtab) == 0 )
@@ -161,3 +164,87 @@ umount_main(int argc, char** argv)
     }
 }
 
+
+
+/* These functions are here because the getmntent functions do not appear
+ * to be re-entrant, which leads to all sorts of problems when we try to
+ * use them recursively - randolph
+ */
+void mtab_read(void)
+{
+    struct _mtab_entry_t *entry = NULL;
+    struct mntent *e;
+    FILE *fp;
+  
+    if (mtab_cache != NULL) return;
+    if ((fp = setmntent(mtab_file, "r")) == NULL) {
+        fprintf(stderr, "Cannot open %s\n", mtab_file);
+       return;
+    }
+    while ((e = getmntent(fp))) {
+        entry = malloc(sizeof(struct _mtab_entry_t));
+       entry->device = strdup(e->mnt_fsname);
+       entry->mountpt = strdup(e->mnt_dir);
+       entry->next = mtab_cache;
+       mtab_cache = entry;
+    }
+    endmntent(fp);
+}
+
+char *mtab_getinfo(const char *match, const char which)
+{
+    struct _mtab_entry_t *cur = mtab_cache;
+    while (cur) {
+        if (strcmp(cur->mountpt, match) == 0 ||
+           strcmp(cur->device, match) == 0) {
+           if (which == MTAB_GETMOUNTPT) {
+               return cur->mountpt;
+           } else {
+#if !defined BB_MTAB
+                if (strcmp(cur->device, "/dev/root") == 0) {
+                    struct fstab* fstabItem;
+                   fstabItem = getfsfile ("/");
+                   if (fstabItem != NULL) return fstabItem->fs_spec;
+               }
+#endif
+               return cur->device;  
+           }
+       }
+        cur = cur->next;
+    }
+    return NULL;
+}
+
+char *mtab_first(void **iter)
+{
+    struct _mtab_entry_t *mtab_iter;
+    if (!iter) return NULL;
+    mtab_iter = mtab_cache;
+    *iter = (void *)mtab_iter;
+    return mtab_next(iter);
+}
+
+char *mtab_next(void **iter)
+{
+    char *mp;
+    if (iter == NULL || *iter == NULL) return NULL;
+    mp = ((struct _mtab_entry_t *)(*iter))->mountpt;
+    *iter = (void *)((struct _mtab_entry_t *)(*iter))->next;
+    return mp;
+}
+
+void mtab_free(void)
+{
+    struct _mtab_entry_t *this, *next;
+
+    this = mtab_cache;
+    while (this) {
+      next = this->next;
+      if (this->device) free(this->device);
+      if (this->mountpt) free(this->mountpt);
+      free(this);
+      this = next;
+    }
+}
+
index 191701bedf7fb9be274f98dc15f9ab4680c6bc92..a27aaa2ae005743bb2b5a8cb6ef439253a340281 100644 (file)
--- a/utility.c
+++ b/utility.c
  */
 
 #include "internal.h"
+#if defined (BB_CHMOD_CHOWN_CHGRP) \
+ || defined (BB_CP_MV)            \
+ || defined (BB_FIND)             \
+ || defined (BB_LS)               \
+ || defined (BB_INSMOD)
+/* same conditions as recursiveAction */
+#define bb_need_name_too_long
+#endif
+#define BB_DECLARE_EXTERN
+#include "messages.c"
+
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
@@ -35,6 +46,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <ctype.h>
+#include <sys/param.h>         /* for PATH_MAX */
 
 #if defined BB_FEATURE_MOUNT_LOOP
 #include <fcntl.h>
@@ -58,9 +70,10 @@ const char mtab_file[] = "/etc/mtab";
 
 extern void usage(const char *usage)
 {
-    fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n", BB_VER, BB_BT);
+    fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n",
+           BB_VER, BB_BT);
     fprintf(stderr, "Usage: %s\n", usage);
-    exit(FALSE);
+    exit FALSE;
 }
 
 
@@ -78,9 +91,8 @@ get_kernel_revision()
 {
   FILE *file;
   int major=0, minor=0, patch=0;
-  char* filename="/proc/sys/kernel/osrelease";
 
-  file = fopen(filename,"r");
+  file = fopen("/proc/sys/kernel/osrelease", "r");
   if (file == NULL) {
     /* bummer, /proc must not be mounted... */
     return( 0);
@@ -89,28 +101,34 @@ get_kernel_revision()
   fclose(file);
   return major*65536 + minor*256 + patch;
 }
+#endif /* BB_INIT || BB_PS */
 
-#endif
 
 
-
-#if defined (BB_CP) || defined (BB_MV)
+#if defined (BB_CP_MV) || defined (BB_DU) || defined (BB_LN)
 /*
  * Return TRUE if a fileName is a directory.
  * Nonexistant files return FALSE.
  */
-int isDirectory(const char *name)
+int isDirectory(const char *fileName, const int followLinks)
 {
     struct stat statBuf;
+    int status;
 
-    if (stat(name, &statBuf) < 0)
-       return FALSE;
+    if (followLinks == TRUE)
+      status = stat(fileName, &statBuf);
+    else
+      status = lstat(fileName, &statBuf);
+
+    if (status < 0)
+      return FALSE;
     if (S_ISDIR(statBuf.st_mode))
-       return TRUE;
-    return(FALSE);
+      return TRUE;
+    return FALSE;
 }
+#endif
 
-
+#if defined (BB_CP_MV)
 /*
  * Copy one file to another, while possibly preserving its modes, times,
  * and modes.  Returns TRUE if successful, or FALSE on a failure with an
@@ -120,33 +138,33 @@ int isDirectory(const char *name)
  */
 int
 copyFile( const char *srcName, const char *destName, 
-        int setModes, int followLinks)
+         int setModes, int followLinks)
 {
     int rfd;
     int wfd;
     int rcc;
-    int result;
+    int status;
     char buf[BUF_SIZE];
     struct stat srcStatBuf;
     struct stat dstStatBuf;
     struct utimbuf times;
 
-    /* Grab the source file's stats */
-    if (followLinks == FALSE)
-       result = stat(srcName, &srcStatBuf);
+    if (followLinks == TRUE)
+       status = stat(srcName, &srcStatBuf);
     else 
-       result = lstat(srcName, &srcStatBuf);
-    if (result < 0) {
+       status = lstat(srcName, &srcStatBuf);
+
+    if (status < 0) {
        perror(srcName);
        return FALSE;
     }
 
-    /* Grab the dest file's stats */
-    if (followLinks == FALSE)
-       result = stat(destName, &dstStatBuf);
-    else 
-       result = lstat(destName, &dstStatBuf);
-    if (result < 0) {
+    if (followLinks == TRUE)   
+       status = stat(destName, &dstStatBuf);
+    else
+       status = lstat(destName, &dstStatBuf);
+
+    if (status < 0) {
        dstStatBuf.st_ino = -1;
        dstStatBuf.st_dev = -1;
     }
@@ -160,45 +178,49 @@ copyFile( const char *srcName, const char *destName,
     if (S_ISDIR(srcStatBuf.st_mode)) {
        //fprintf(stderr, "copying directory %s to %s\n", srcName, destName);
        /* Make sure the directory is writable */
-       result = mkdir(destName, 0777777 ^ umask(0));
-       if (result < 0 && errno != EEXIST) {
+       status = mkdir(destName, 0777777 ^ umask(0));
+       if (status < 0 && errno != EEXIST) {
            perror(destName);
-           return (FALSE);
+           return FALSE;
        }
     } else if (S_ISLNK(srcStatBuf.st_mode)) {
-       char *link_val;
+       char link_val[PATH_MAX + 1];
        int link_size;
 
        //fprintf(stderr, "copying link %s to %s\n", srcName, destName);
-       link_val = (char *) alloca(PATH_MAX + 2);
-       link_size = readlink(srcName, link_val, PATH_MAX + 1);
+       /* Warning: This could possibly truncate silently, to PATH_MAX chars */
+       link_size = readlink(srcName, &link_val[0], PATH_MAX);
        if (link_size < 0) {
            perror(srcName);
-           return (FALSE);
+           return FALSE;
        }
        link_val[link_size] = '\0';
-       link_size = symlink(link_val, destName);
-       if (link_size != 0) {
+       status = symlink(link_val, destName);
+       if (status < 0) {
            perror(destName);
-           return (FALSE);
+           return FALSE;
        }
 #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
        if (setModes == TRUE) {
-           lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid);
+           if (lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) {
+             perror(destName);
+             return FALSE;
+           }
        }
 #endif
+       return TRUE;
     } else if (S_ISFIFO(srcStatBuf.st_mode)) {
        //fprintf(stderr, "copying fifo %s to %s\n", srcName, destName);
-       if (mkfifo(destName, 0644)) {
+       if (mkfifo(destName, 0644) < 0) {
            perror(destName);
-           return (FALSE);
+           return FALSE;
        }
     } else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode) 
-           || S_ISSOCK (srcStatBuf.st_mode)) {
+               || S_ISSOCK (srcStatBuf.st_mode)) {
        //fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName);
-       if (mknod(destName, srcStatBuf.st_mode, srcStatBuf.st_rdev)) {
+       if (mknod(destName, srcStatBuf.st_mode, srcStatBuf.st_rdev) < 0) {
            perror(destName);
-           return (FALSE);
+           return FALSE;
        }
     } else if (S_ISREG(srcStatBuf.st_mode)) {
        //fprintf(stderr, "copying regular file %s to %s\n", srcName, destName);
@@ -208,7 +230,7 @@ copyFile( const char *srcName, const char *destName,
            return FALSE;
        }
 
-       wfd = creat(destName, srcStatBuf.st_mode);
+       wfd = open(destName, O_WRONLY | O_CREAT | O_TRUNC, srcStatBuf.st_mode);
        if (wfd < 0) {
            perror(destName);
            close(rfd);
@@ -231,24 +253,32 @@ copyFile( const char *srcName, const char *destName,
 
     if (setModes == TRUE) {
        /* This is fine, since symlinks never get here */
-       chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid);
-       chmod(destName, srcStatBuf.st_mode);
+       if (chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) {
+         perror(destName);
+         exit FALSE;
+       }
+       if (chmod(destName, srcStatBuf.st_mode) < 0) {
+         perror(destName);
+         exit FALSE;
+       }
        times.actime = srcStatBuf.st_atime;
        times.modtime = srcStatBuf.st_mtime;
-       utime(destName, &times);
+       if (utime(destName, &times) < 0) {
+         perror(destName);
+         exit FALSE;
+       }
     }
 
     return TRUE;
 
-
-  error_exit:
+ error_exit:
     perror(destName);
     close(rfd);
     close(wfd);
 
     return FALSE;
 }
-#endif
+#endif /* BB_CP_MV */
 
 
 
@@ -296,7 +326,7 @@ const char *modeString(int mode)
     }
     return buf;
 }
-#endif
+#endif /* BB_TAR || BB_LS */
 
 
 #if defined BB_TAR
@@ -324,9 +354,9 @@ const char *timeString(time_t timeVal)
 
     return buf;
 }
-#endif
+#endif /* BB_TAR */
 
-#if defined BB_TAR || defined BB_CP || defined BB_MV
+#if defined BB_TAR || defined BB_CP_MV
 /*
  * Write all of the supplied buffer out to a file.
  * This does multiple writes as necessary.
@@ -352,7 +382,7 @@ int fullWrite(int fd, const char *buf, int len)
 
     return total;
 }
-#endif
+#endif /* BB_TAR || BB_CP_MV */
 
 
 #if defined BB_TAR || defined BB_TAIL
@@ -385,10 +415,14 @@ int fullRead(int fd, char *buf, int len)
 
     return total;
 }
-#endif
+#endif /* BB_TAR || BB_TAIL */
 
 
-#if defined (BB_CHMOD_CHOWN_CHGRP) || defined (BB_CP) || defined (BB_FIND) || defined (BB_LS) || defined (BB_INSMOD)
+#if defined (BB_CHMOD_CHOWN_CHGRP) \
+ || defined (BB_CP_MV)            \
+ || defined (BB_FIND)             \
+ || defined (BB_LS)               \
+ || defined (BB_INSMOD)
 /*
  * Walk down all the directories under the specified 
  * location, and do something (something specified
@@ -399,13 +433,15 @@ int fullRead(int fd, char *buf, int len)
  * and so isn't sufficiently portable to take over since glibc2.1
  * is so stinking huge.
  */
-int
-recursiveAction(const char *fileName, int recurse, int followLinks, int depthFirst,
-               int (*fileAction) (const char *fileName, struct stat* statbuf),
-               int (*dirAction) (const char *fileName, struct stat* statbuf))
+int recursiveAction(const char *fileName,
+                   int recurse, int followLinks, int depthFirst,
+                   int (*fileAction) (const char *fileName,
+                                      struct stat* statbuf),
+                   int (*dirAction) (const char *fileName,
+                                     struct stat* statbuf))
 {
     int status;
-    struct stat statbuf, statbuf1;
+    struct stat statbuf;
     struct dirent *next;
 
     if (followLinks == TRUE)
@@ -414,16 +450,20 @@ recursiveAction(const char *fileName, int recurse, int followLinks, int depthFir
        status = lstat(fileName, &statbuf);
 
     if (status < 0) {
-       //fprintf(stderr, "status=%d followLinks=%d TRUE=%d\n", status, followLinks, TRUE);
+#ifdef BB_DEBUG_PRINT_SCAFFOLD
+      fprintf(stderr,
+             "status=%d followLinks=%d TRUE=%d\n",
+             status, followLinks, TRUE);
+#endif
        perror(fileName);
-       return (FALSE);
+       return FALSE;
     }
 
-    if ( (followLinks == FALSE) && (S_ISLNK(statbuf.st_mode)) ) {
+    if ((followLinks == FALSE) && (S_ISLNK(statbuf.st_mode)) ) {
        if (fileAction == NULL)
-           return (TRUE);
+           return TRUE;
        else
-           return (fileAction(fileName, &statbuf));
+           return fileAction(fileName, &statbuf);
     }
 
     if (recurse == FALSE) {
@@ -431,67 +471,65 @@ recursiveAction(const char *fileName, int recurse, int followLinks, int depthFir
            if (dirAction != NULL)
                return (dirAction(fileName, &statbuf));
            else
-               return (TRUE);
-       } 
-    }
-    
-    status = lstat(fileName, &statbuf1);
-    if (status < 0) {
-       perror(fileName);
-       return (FALSE);
+               return TRUE;
+       }
     }
 
-    if (S_ISDIR(statbuf.st_mode) && S_ISDIR(statbuf1.st_mode)) {
+    if (S_ISDIR(statbuf.st_mode)) {
        DIR *dir;
        dir = opendir(fileName);
        if (!dir) {
            perror(fileName);
-           return (FALSE);
+           return FALSE;
        }
        if (dirAction != NULL && depthFirst == FALSE) {
            status = dirAction(fileName, &statbuf);
            if (status == FALSE) {
                perror(fileName);
-               return (FALSE);
+               return FALSE;
            }
        }
        while ((next = readdir(dir)) != NULL) {
-           char nextFile[NAME_MAX];
+           char nextFile[PATH_MAX + 1];
            if ((strcmp(next->d_name, "..") == 0)
-               || (strcmp(next->d_name, ".") == 0)) {
+                || (strcmp(next->d_name, ".") == 0)) {
                continue;
            }
+           if (strlen(fileName) + strlen(next->d_name) + 1 > PATH_MAX) {
+               fprintf(stderr, name_too_long, "ftw");
+               return FALSE;
+           }
            sprintf(nextFile, "%s/%s", fileName, next->d_name);
            status =
                recursiveAction(nextFile, TRUE, followLinks, depthFirst, 
-                       fileAction, dirAction);
+                               fileAction, dirAction);
            if (status < 0) {
                closedir(dir);
-               return (FALSE);
+               return FALSE;
            }
        }
        status = closedir(dir);
        if (status < 0) {
            perror(fileName);
-           return (FALSE);
+           return FALSE;
        }
        if (dirAction != NULL && depthFirst == TRUE) {
            status = dirAction(fileName, &statbuf);
            if (status == FALSE) {
                perror(fileName);
-               return (FALSE);
+               return FALSE;
            }
        }
     } else {
        if (fileAction == NULL)
-           return (TRUE);
+           return TRUE;
        else
-           return (fileAction(fileName, &statbuf));
+           return fileAction(fileName, &statbuf);
     }
-    return (TRUE);
+    return TRUE;
 }
 
-#endif
+#endif /* BB_CHMOD_CHOWN_CHGRP || BB_CP_MV || BB_FIND || BB_LS || BB_INSMOD */
 
 
 
@@ -506,25 +544,25 @@ extern int createPath (const char *name, int mode)
 {
     char *cp;
     char *cpOld;
-    char buf[NAME_MAX];
+    char buf[PATH_MAX + 1];
     int retVal=0;
 
     strcpy( buf, name);
-    cp = strchr (buf, '/');
+    cp = strchr(buf, '/');
     while (cp) {
        cpOld = cp;
-       cp = strchr (cp + 1, '/');
+       cp = strchr(cp + 1, '/');
        *cpOld = '\0';
-       retVal = mkdir (buf, cp ? 0777 : mode);
+       retVal = mkdir(buf, cp ? 0777 : mode);
        if (retVal != 0 && errno != EEXIST) {
-           perror( buf);
-           return( FALSE);
+           perror(buf);
+           return FALSE;
        }
        *cpOld = '/';
     }
-    return( TRUE);
+    return TRUE;
 }
-#endif
+#endif /* BB_TAR || BB_MKDIR */
 
 
 
@@ -624,7 +662,7 @@ parse_mode( const char* s, mode_t* theMode)
 }
 
 
-#endif
+#endif /* BB_CHMOD_CHOWN_CHGRP || BB_MKDIR */
 
 
 
@@ -712,7 +750,7 @@ my_getgrgid(char* group, gid_t gid)
 }
 
 
-#endif
+#endif /* BB_CHMOD_CHOWN_CHGRP || BB_PS */
 
 
 
@@ -804,7 +842,7 @@ int get_console_fd(char* tty_name)
 }
 
 
-#endif
+#endif /* BB_CHVT || BB_DEALLOCVT */
 
 
 #if !defined BB_REGEXP && (defined BB_GREP || defined BB_SED)  
@@ -883,8 +921,7 @@ extern int replace_match(char *haystack, char *needle, char *newNeedle, int igno
        return FALSE;
 }
 
-
-#endif
+#endif /* ! BB_REGEXP && (BB_GREP || BB_SED) */
 
 
 #if defined BB_FIND
@@ -986,7 +1023,7 @@ check_wildcard_match(const char* text, const char* pattern)
 
     return TRUE;
 }
-#endif
+#endif /* BB_FIND */
 
 
 
@@ -1030,7 +1067,7 @@ extern struct mntent *findMountPoint(const char *name, const char *table)
     endmntent(mountTable);
     return mountEntry;
 }
-#endif
+#endif /* BB_DF || BB_MTAB */
 
 
 
@@ -1052,7 +1089,8 @@ extern long getNum (const char *cp)
        value = value * 10 + *cp++ - '0';
 
     switch (*cp++) {
-    case 'm':
+    case 'M':
+    case 'm': /* `tail' uses it traditionally */
        value *= 1048576;
        break;
 
@@ -1080,7 +1118,7 @@ extern long getNum (const char *cp)
 
     return value;
 }
-#endif
+#endif /* BB_DD || BB_TAIL */
 
 
 #if defined BB_INIT || defined BB_HALT || defined BB_REBOOT 
@@ -1120,9 +1158,12 @@ findInitPid()
     }
     return 0;
 }
-#endif
+#endif /* BB_INIT || BB_HALT || BB_REBOOT */
 
-#if defined BB_GUNZIP || defined BB_GZIP || defined BB_PRINTF || defined BB_TAIL
+#if defined BB_GUNZIP \
+ || defined BB_GZIP   \
+ || defined BB_PRINTF \
+ || defined BB_TAIL
 extern void *xmalloc (size_t size)
 {
     void *cp = malloc (size);
@@ -1138,7 +1179,7 @@ extern void error(char *msg)
     fprintf(stderr, "\n%s\n", msg);
     exit(1);
 }
-#endif
+#endif /* BB_GUNZIP || BB_GZIP || BB_PRINTF || BB_TAIL */
 
 #if (__GLIBC__ < 2) && (defined BB_SYSLOGD || defined BB_INIT)
 extern int vdprintf(int d, const char *format, va_list ap)
@@ -1149,7 +1190,7 @@ extern int vdprintf(int d, const char *format, va_list ap)
     len = vsprintf(buf, format, ap);
     return write(d, buf, len);
 }
-#endif
+#endif /* BB_SYSLOGD */
 
 #if defined BB_FEATURE_MOUNT_LOOP
 extern int del_loop(const char *device)