aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog46
-rw-r--r--Makefile109
-rw-r--r--TODO41
-rw-r--r--applets/busybox.c10
-rwxr-xr-xapplets/busybox.mkll2
-rw-r--r--archival/gunzip.c28
-rw-r--r--archival/tar.c3
-rw-r--r--busybox.c10
-rw-r--r--busybox.def.h18
-rwxr-xr-xbusybox.mkll2
-rw-r--r--chmod_chown_chgrp.c29
-rw-r--r--coreutils/cp.c127
-rw-r--r--coreutils/date.c17
-rw-r--r--coreutils/dd.c37
-rw-r--r--coreutils/du.c34
-rw-r--r--coreutils/head.c2
-rw-r--r--coreutils/length.c2
-rw-r--r--coreutils/ln.c79
-rw-r--r--coreutils/ls.c2
-rw-r--r--coreutils/mkdir.c34
-rw-r--r--coreutils/mv.c112
-rw-r--r--coreutils/printf.c2
-rw-r--r--coreutils/pwd.c3
-rw-r--r--coreutils/sort.c2
-rw-r--r--coreutils/tail.c2
-rw-r--r--coreutils/tee.c2
-rw-r--r--coreutils/uniq.c2
-rw-r--r--cp.c127
-rw-r--r--cp_mv.c258
-rw-r--r--date.c17
-rw-r--r--dd.c37
-rw-r--r--du.c34
-rw-r--r--fdflush.c2
-rw-r--r--find.c2
-rw-r--r--findutils/find.c2
-rw-r--r--fsck_minix.c3
-rw-r--r--gunzip.c28
-rw-r--r--head.c2
-rw-r--r--hostname.c2
-rw-r--r--init.c17
-rw-r--r--init/init.c17
-rw-r--r--insmod.c6
-rw-r--r--internal.h25
-rw-r--r--length.c2
-rw-r--r--ln.c79
-rw-r--r--ls.c2
-rw-r--r--messages.c64
-rw-r--r--mkdir.c34
-rw-r--r--modutils/insmod.c6
-rw-r--r--mtab.c24
-rw-r--r--mv.c112
-rw-r--r--networking/hostname.c2
-rw-r--r--networking/nslookup.c2
-rw-r--r--networking/ping.c5
-rw-r--r--nslookup.c2
-rw-r--r--ping.c5
-rw-r--r--printf.c2
-rw-r--r--pwd.c3
-rw-r--r--sort.c2
-rw-r--r--swaponoff.c5
-rw-r--r--sysklogd/syslogd.c15
-rw-r--r--syslogd.c15
-rw-r--r--tail.c2
-rw-r--r--tar.c3
-rw-r--r--tee.c2
-rw-r--r--tests/Makefile28
-rw-r--r--tests/cp_tests.mk270
-rw-r--r--tests/ln_tests.mk66
-rw-r--r--tests/mv_tests.mk137
-rw-r--r--umount.c197
-rw-r--r--uniq.c2
-rw-r--r--util-linux/fdflush.c2
-rw-r--r--util-linux/fsck_minix.c3
-rw-r--r--util-linux/swaponoff.c5
-rw-r--r--util-linux/umount.c197
-rw-r--r--utility.c255
76 files changed, 1856 insertions, 1030 deletions
diff --git a/Changelog b/Changelog
index 6581b5c90..7ecc4fb66 100644
--- a/Changelog
+++ b/Changelog
@@ -1,4 +1,41 @@
10.42 10.42
2
3 * Fairly massive restructuring of umount.c to deal with remounting
4 busy devices read-only. Adds a -r option to control that; it is
5 optionally compiled in with BB_FEATURE_REMOUNT
6 * Added a bunch of functions to mtab.c to interact with the
7 {get,set,end}mntent interface; as it turns out, those functions do
8 not appear to be re-entrant, and that causes a lot of problems with
9 the way umount was originally written.
10 * Makes init send TERM and KILL (instead of HUP and KILL) on reboot
11 to be more consistent with sysvinit
12 * Changes to init.c to use the new -r option to umount. Also increased
13 the sleep time between the time the TERM and KILL signals are sent
14
15 - Randolph Chung
16
17
18 * cp.c, mv.c: removed, replaced by cp_mv.c which has been
19 extensively rewritten from the original cp.c.
20 * Also added a warning message to the `mv' usage string saying that
21 this is not GNU mv, and it will break hard links. cp also breaks
22 hard links.
23 * ln.c: implemented `-n' switch, no-deref symlinks.
24 * include<sys/param.h>: and use PATH_MAX everywhere.
25 * busybox: File name buffer overrun guards to prevent future crashes.
26 - Always check exit status.
27 - Purge all use of `creat()', replace with `open()'.
28 * utility.c
29 - recursiveAction was overriding the value of
30 followLinks thus ignoring it.
31 - isDirectory now takes a followLinks boolean, updated all callers
32 - copyFile had the followLinks logic reversed.
33 * messages.c: New file. Put common error message strings all in
34 one place in an attempt to shrink the binary a little.
35
36 -Karl M. Hegbloom
37
38
2 * Made tar creation support in busybox tar optional. 39 * Made tar creation support in busybox tar optional.
3 * You no longer _have_ to put a "-" in front of tar options. 40 * You no longer _have_ to put a "-" in front of tar options.
4 * Tar could inadvertently change permissions and ownership on 41 * Tar could inadvertently change permissions and ownership on
@@ -16,11 +53,11 @@
16 for the kernel init chroot patch by Werner Almesberger, which 53 for the kernel init chroot patch by Werner Almesberger, which
17 allows init to chroot to a new device, and umount the old one. 54 allows init to chroot to a new device, and umount the old one.
18 * Fixed bug that wouldn't let one chown a symlink -- it would 55 * Fixed bug that wouldn't let one chown a symlink -- it would
19 always dereference before. -beppu 56 always dereference before. -beppu
20 * Fixed a bug where init could have reference already freed memory. 57 * Fixed a bug where init could have reference already freed memory.
21 Found and fixed by Taketoshi Sano <kgh12351@nifty.ne.jp> 58 Found and fixed by Taketoshi Sano <kgh12351@nifty.ne.jp>
22 * Several contributions from Friedrich Vedder <fwv@myrtle.lahn.de> 59 * Several contributions from Friedrich Vedder <fwv@myrtle.lahn.de>
23 * added (and documented) "-n" option for head - 60 * Added (and documented) "-n" option for head -
24 * Cleanup for a number of usage messages -- also 61 * Cleanup for a number of usage messages -- also
25 contributed Friedrich Vedder <fwv@myrtle.lahn.de> 62 contributed Friedrich Vedder <fwv@myrtle.lahn.de>
26 * Cosmetic fix to busybox.c (Don't print a comma at the 63 * Cosmetic fix to busybox.c (Don't print a comma at the
@@ -42,6 +79,11 @@
42 Randolph Chung <tausq@debian.org>. 79 Randolph Chung <tausq@debian.org>.
43 * cp could, when copying symlinks, change permissions of the 80 * cp could, when copying symlinks, change permissions of the
44 files pointed to by the symlinks. 81 files pointed to by the symlinks.
82 * Several fixes from Pavel Roskin <pavel_roskin@geocities.com>:
83 - `chown' with 1 argument displayed the error incorrectly
84 - `fdflush', `length' and `printf' crashed when run without arguments
85 - `fdflush' tried to flush itself using *argv
86 - added "skip" and "seek" to dd.
45 87
46 88
47 -Erik Andersen 89 -Erik Andersen
diff --git a/Makefile b/Makefile
index 554dd00f5..490d3935f 100644
--- a/Makefile
+++ b/Makefile
@@ -15,71 +15,74 @@
15# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16# 16#
17 17
18PROG := busybox
19VERSION := 0.42
20BUILDTIME := $(shell TZ=GMT date "+%Y%m%d-%H%M")
18 21
19PROG=busybox 22# Set the following to `true' to make a debuggable build.
20VERSION=0.42 23# Leave this set to `false' for production use.
21BUILDTIME=$(shell date "+%Y%m%d-%H%M") 24# eg: `make DODEBUG=true'
25DODEBUG = false
22 26
23# Comment out the following to make a debuggable build
24# Leave this off for production use.
25DODEBUG=false
26# If you want a static binary, turn this on. I can't think 27# If you want a static binary, turn this on. I can't think
27# of many situations where anybody would ever want it static, 28# of many situations where anybody would ever want it static,
28# but... 29# but...
29DOSTATIC=false 30DOSTATIC = false
30 31
31#This will choke on a non-debian system 32# This will choke on a non-debian system
32ARCH=`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'` 33ARCH =`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'`
33 34
34GCCMAJVERSION=$(shell $(CC) --version | sed -n "s/^\([^\.]*\).*/\1/p" ) 35CC = gcc
35GCCMINVERSION=$(shell $(CC) --version | sed -n "s/^[^\.]*\.\([^\.]*\)[\.].*/\1/p" ) 36
36 37GCCMAJVERSION = $(shell $(CC) --version | sed -n "s/^[^0-9]*\([0-9]\)\.\([0-9].*\)[\.].*/\1/p")
37GCCSUPPORTSOPTSIZE=$(shell \ 38GCCMINVERSION = $(shell $(CC) --version | sed -n "s/^[^0-9]*\([0-9]\)\.\([0-9].*\)[\.].*/\2/p")
38if ( test $(GCCMAJVERSION) -eq 2 ) ; then \ 39
39 if ( test $(GCCMINVERSION) -ge 66 ) ; then \ 40
40 echo "true"; \ 41GCCSUPPORTSOPTSIZE = $(shell \
41 else \ 42if ( test $(GCCMAJVERSION) -eq 2 ) ; then \
42 echo "false"; \ 43 if ( test $(GCCMINVERSION) -ge 66 ) ; then \
43 fi; \ 44 echo "true"; \
44else \ 45 else \
45 if ( test $(GCCMAJVERSION) -gt 2 ) ; then \ 46 echo "false"; \
46 echo "true"; \ 47 fi; \
47 else \ 48else \
48 echo "false"; \ 49 if ( test $(GCCMAJVERSION) -gt 2 ) ; then \
49 fi; \ 50 echo "true"; \
51 else \
52 echo "false"; \
53 fi; \
50fi; ) 54fi; )
51 55
52 56
53ifeq ($(GCCSUPPORTSOPTSIZE), true) 57ifeq ($(GCCSUPPORTSOPTSIZE), true)
54 OPTIMIZATION=-Os 58 OPTIMIZATION = -Os
55else 59else
56 OPTIMIZATION=-O2 60 OPTIMIZATION = -O2
57endif 61endif
58 62
59# -D_GNU_SOURCE is needed because environ is used in init.c 63# -D_GNU_SOURCE is needed because environ is used in init.c
60ifeq ($(DODEBUG),true) 64ifeq ($(DODEBUG),true)
61 CFLAGS+=-Wall -g -D_GNU_SOURCE -DDEBUG_INIT 65 CFLAGS += -Wall -g -D_GNU_SOURCE -DDEBUG_INIT
62 STRIP= 66 STRIP =
63 LDFLAGS= 67 LDFLAGS =
64else 68else
65 CFLAGS+=-Wall $(OPTIMIZATION) -fomit-frame-pointer -fno-builtin -D_GNU_SOURCE 69 CFLAGS += -Wall $(OPTIMIZATION) -fomit-frame-pointer -fno-builtin -D_GNU_SOURCE
66 LDFLAGS= -s 70 LDFLAGS = -s
67 STRIP= strip --remove-section=.note --remove-section=.comment $(PROG) 71 STRIP = strip --remove-section=.note --remove-section=.comment $(PROG)
68 #Only staticly link when _not_ debugging 72 #Only staticly link when _not_ debugging
69 ifeq ($(DOSTATIC),true) 73 ifeq ($(DOSTATIC),true)
70 LDFLAGS+= --static 74 LDFLAGS += --static
71 endif 75 endif
72
73endif 76endif
74 77
75ifndef $(PREFIX) 78ifndef $(PREFIX)
76 PREFIX=`pwd`/_install 79 PREFIX = `pwd`/_install
77endif 80endif
78 81
79LIBRARIES= 82LIBRARIES =
80OBJECTS=$(shell ./busybox.sh) 83OBJECTS = $(shell ./busybox.sh) messages.o utility.o
81CFLAGS+= -DBB_VER='"$(VERSION)"' 84CFLAGS += -DBB_VER='"$(VERSION)"'
82CFLAGS+= -DBB_BT='"$(BUILDTIME)"' 85CFLAGS += -DBB_BT='"$(BUILDTIME)"'
83ifdef BB_INIT_SCRIPT 86ifdef BB_INIT_SCRIPT
84 CFLAGS += -DINIT_SCRIPT=${BB_INIT_SCRIPT} 87 CFLAGS += -DINIT_SCRIPT=${BB_INIT_SCRIPT}
85endif 88endif
@@ -90,7 +93,7 @@ busybox: $(OBJECTS)
90 $(CC) $(LDFLAGS) -o $(PROG) $(OBJECTS) $(LIBRARIES) 93 $(CC) $(LDFLAGS) -o $(PROG) $(OBJECTS) $(LIBRARIES)
91 $(STRIP) 94 $(STRIP)
92 95
93busybox.links: 96busybox.links: busybox.def.h
94 - ./busybox.mkll | sort >$@ 97 - ./busybox.mkll | sort >$@
95 98
96clean: 99clean:
@@ -100,7 +103,7 @@ clean:
100distclean: clean 103distclean: clean
101 - rm -f $(PROG) 104 - rm -f $(PROG)
102 105
103$(OBJECTS): busybox.def.h internal.h Makefile 106$(OBJECTS): %.o: %.c busybox.def.h internal.h Makefile messages.c
104 107
105install: busybox busybox.links 108install: busybox busybox.links
106 ./install.sh $(PREFIX) 109 ./install.sh $(PREFIX)
@@ -108,6 +111,18 @@ install: busybox busybox.links
108dist: release 111dist: release
109 112
110release: distclean 113release: distclean
111 (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)) 114 cd ..; \
112 115 rm -rf busybox-$(VERSION); \
113 116 cp -a busybox busybox-$(VERSION); \
117 \
118 find busybox-$(VERSION)/ -type d \
119 -name CVS \
120 -print \
121 | xargs rm -rf; \
122 \
123 find busybox-$(VERSION)/ -type f \
124 -name .cvsignore \
125 -print \
126 | xargs rm -f; \
127 \
128 tar -cvzf busybox-$(VERSION).tar.gz busybox-$(VERSION)/;
diff --git a/TODO b/TODO
index b951767ea..51a0d147a 100644
--- a/TODO
+++ b/TODO
@@ -26,3 +26,44 @@ around to it some time. If you have any good ideas, please let me know.
26* tr 26* tr
27* expr (maybe?) (ash builtin?) 27* expr (maybe?) (ash builtin?)
28 28
29
30
31
32Some known bugs, todo items, etc...
33
34-----------------------
35
36
37[andersen@slag busybox]$ ./busybox du /bin
386213 /bin
39[andersen@slag busybox]$ du /bin
402971 /bin
41[andersen@slag busybox]$ du --block-size=512 /bin
425943 /bin
43
44-----------------------
45
46-rw-r--r-- 1000/1000 4398 2000-01-06 21:55 uniq.c
47-rw-r--r-- 1000/1000 1568 1999-10-20 18:08 update.c
48-rw-r----- 0/1000 1168 2000-01-29 21:03 update.o
49-rw-r--r-- 1000/1000 22820 2000-01-05 11:36 utility.c
50-rw-r----- 0/1000 7372 2000-01-29 21:03 utility.o
51tar: Skipping to next file header
52tar: Skipping to next file header
53tar: Archive - EOF not on block boundary
54tar: Error is not recoverable: exiting now
55
56
57#1 You are storing by id instead of name like normal tar. Did you realize this?
58(or am I missing some compile option? )ctar did not do this, and I don't think
59it's a good idea for LRP.
60
61#2
62ctar did not produce the EOF error like your tar does. I believe you need to
63pad the end of the archive with at least 2 tarsized (512byte) blocks. (I
64think???)
65
66#3
67There is no exclude file(s) option to tar. LRP's packaging system can not
68function without this. Will you have the time to add this soon?
69
diff --git a/applets/busybox.c b/applets/busybox.c
index 7f14473e0..e2c2e0393 100644
--- a/applets/busybox.c
+++ b/applets/busybox.c
@@ -50,8 +50,9 @@ static const struct Applet applets[] = {
50#ifdef BB_CHVT //usr/bin 50#ifdef BB_CHVT //usr/bin
51 {"chvt", chvt_main}, 51 {"chvt", chvt_main},
52#endif 52#endif
53#ifdef BB_CP //bin 53#ifdef BB_CP_MV //bin
54 {"cp", cp_main}, 54 {"cp", cp_mv_main},
55 {"mv", cp_mv_main},
55#endif 56#endif
56#ifdef BB_DATE //bin 57#ifdef BB_DATE //bin
57 {"date", date_main}, 58 {"date", date_main},
@@ -170,10 +171,7 @@ static const struct Applet applets[] = {
170#ifdef BB_MT //bin 171#ifdef BB_MT //bin
171 {"mt", mt_main}, 172 {"mt", mt_main},
172#endif 173#endif
173#ifdef BB_MV //bin 174#ifdef BB_NSLOOKUP //usr/bin
174 {"mv", mv_main},
175#endif
176#ifdef BB_NSLOOKUP //bin
177 {"nslookup", nslookup_main}, 175 {"nslookup", nslookup_main},
178#endif 176#endif
179#ifdef BB_PING //bin 177#ifdef BB_PING //bin
diff --git a/applets/busybox.mkll b/applets/busybox.mkll
index be6d937cf..c4420f50d 100755
--- a/applets/busybox.mkll
+++ b/applets/busybox.mkll
@@ -1,5 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2#Make busybox links list file 2# Make busybox links list file.
3 3
4DF="busybox.def.h" 4DF="busybox.def.h"
5MF="busybox.c" 5MF="busybox.c"
diff --git a/archival/gunzip.c b/archival/gunzip.c
index fddcc7653..db7fa1dfe 100644
--- a/archival/gunzip.c
+++ b/archival/gunzip.c
@@ -3,6 +3,9 @@
3 */ 3 */
4 4
5#include "internal.h" 5#include "internal.h"
6#define bb_need_name_too_long
7#define BB_DECLARE_EXTERN
8#include "messages.c"
6 9
7static const char gunzip_usage[] = 10static const char gunzip_usage[] =
8 "gunzip [OPTION]... FILE\n\n" 11 "gunzip [OPTION]... FILE\n\n"
@@ -64,6 +67,7 @@ static char *license_msg[] = {
64#include <signal.h> 67#include <signal.h>
65#include <sys/stat.h> 68#include <sys/stat.h>
66#include <errno.h> 69#include <errno.h>
70#include <sys/param.h> /* for PATH_MAX */
67 71
68/* #include "tailor.h" */ 72/* #include "tailor.h" */
69 73
@@ -627,8 +631,12 @@ typedef RETSIGTYPE (*sig_type) OF((int));
627#endif 631#endif
628#define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */ 632#define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */
629 633
630#ifndef MAX_PATH_LEN 634#ifndef MAX_PATH_LEN /* max pathname length */
631# define MAX_PATH_LEN 1024 /* max pathname length */ 635# ifdef PATH_MAX
636# define MAX_PATH_LEN PATH_MAX
637# else
638# define MAX_PATH_LEN 1024
639# endif
632#endif 640#endif
633 641
634#ifndef SEEK_END 642#ifndef SEEK_END
@@ -696,8 +704,8 @@ int gunzip_main (int argc, char** argv)
696 int delInputFile=0; 704 int delInputFile=0;
697 struct stat statBuf; 705 struct stat statBuf;
698 char* delFileName; 706 char* delFileName;
699 char ifname[MAX_PATH_LEN]; /* input file name */ 707 char ifname[MAX_PATH_LEN + 1]; /* input file name */
700 char ofname[MAX_PATH_LEN]; /* output file name */ 708 char ofname[MAX_PATH_LEN + 1]; /* output file name */
701 709
702 if (argc==1) 710 if (argc==1)
703 usage(gunzip_usage); 711 usage(gunzip_usage);
@@ -764,7 +772,11 @@ int gunzip_main (int argc, char** argv)
764 /* Open up the input file */ 772 /* Open up the input file */
765 if (*argv=='\0') 773 if (*argv=='\0')
766 usage(gunzip_usage); 774 usage(gunzip_usage);
767 strncpy(ifname, *argv, MAX_PATH_LEN); 775 if (strlen(*argv) > MAX_PATH_LEN) {
776 fprintf(stderr, name_too_long, "gunzip");
777 do_exit(WARNING);
778 }
779 strcpy(ifname, *argv);
768 780
769 /* Open input fille */ 781 /* Open input fille */
770 inFileNum=open( ifname, O_RDONLY); 782 inFileNum=open( ifname, O_RDONLY);
@@ -799,7 +811,11 @@ int gunzip_main (int argc, char** argv)
799 char* pos; 811 char* pos;
800 812
801 /* And get to work */ 813 /* And get to work */
802 strncpy(ofname, ifname, MAX_PATH_LEN-4); 814 if (strlen(ifname) > MAX_PATH_LEN - 4) {
815 fprintf(stderr, name_too_long, "gunzip");
816 do_exit(WARNING);
817 }
818 strcpy(ofname, ifname);
803 pos=strstr(ofname, ".gz"); 819 pos=strstr(ofname, ".gz");
804 if (pos != NULL) { 820 if (pos != NULL) {
805 *pos='\0'; 821 *pos='\0';
diff --git a/archival/tar.c b/archival/tar.c
index 0fa09ffd8..6496231ae 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -40,6 +40,7 @@
40#include <utime.h> 40#include <utime.h>
41#include <sys/types.h> 41#include <sys/types.h>
42#include <sys/sysmacros.h> 42#include <sys/sysmacros.h>
43#include <sys/param.h> /* for PATH_MAX */
43 44
44 45
45#ifdef BB_FEATURE_TAR_CREATE 46#ifdef BB_FEATURE_TAR_CREATE
@@ -1041,7 +1042,7 @@ static void saveDirectory (const char *dirName, const struct stat *statbuf)
1041 DIR *dir; 1042 DIR *dir;
1042 struct dirent *entry; 1043 struct dirent *entry;
1043 int needSlash; 1044 int needSlash;
1044 char fullName[NAME_MAX]; 1045 char fullName[PATH_MAX + 1];
1045 1046
1046 /* 1047 /*
1047 * Construct the directory name as used in the tar file by appending 1048 * Construct the directory name as used in the tar file by appending
diff --git a/busybox.c b/busybox.c
index 7f14473e0..e2c2e0393 100644
--- a/busybox.c
+++ b/busybox.c
@@ -50,8 +50,9 @@ static const struct Applet applets[] = {
50#ifdef BB_CHVT //usr/bin 50#ifdef BB_CHVT //usr/bin
51 {"chvt", chvt_main}, 51 {"chvt", chvt_main},
52#endif 52#endif
53#ifdef BB_CP //bin 53#ifdef BB_CP_MV //bin
54 {"cp", cp_main}, 54 {"cp", cp_mv_main},
55 {"mv", cp_mv_main},
55#endif 56#endif
56#ifdef BB_DATE //bin 57#ifdef BB_DATE //bin
57 {"date", date_main}, 58 {"date", date_main},
@@ -170,10 +171,7 @@ static const struct Applet applets[] = {
170#ifdef BB_MT //bin 171#ifdef BB_MT //bin
171 {"mt", mt_main}, 172 {"mt", mt_main},
172#endif 173#endif
173#ifdef BB_MV //bin 174#ifdef BB_NSLOOKUP //usr/bin
174 {"mv", mv_main},
175#endif
176#ifdef BB_NSLOOKUP //bin
177 {"nslookup", nslookup_main}, 175 {"nslookup", nslookup_main},
178#endif 176#endif
179#ifdef BB_PING //bin 177#ifdef BB_PING //bin
diff --git a/busybox.def.h b/busybox.def.h
index fa192205a..306c87762 100644
--- a/busybox.def.h
+++ b/busybox.def.h
@@ -95,11 +95,6 @@
95// 95//
96// 96//
97// 97//
98// Don't turn BB_UTILITY off. It contains support code
99// that compiles to 0 if everything else if turned off.
100#define BB_UTILITY
101//
102//
103// 98//
104// This is where feature definitions go. Generally speaking, 99// This is where feature definitions go. Generally speaking,
105// turning this stuff off makes things a bit smaller (and less 100// turning this stuff off makes things a bit smaller (and less
@@ -132,7 +127,7 @@
132#define BB_FEATURE_USE_INITTAB 127#define BB_FEATURE_USE_INITTAB
133// 128//
134//Enable init being called as /linuxrc 129//Enable init being called as /linuxrc
135#define BB_FEATURE_LINUXRC 130//#define BB_FEATURE_LINUXRC
136// 131//
137// 132//
138//Simple tail implementation (2k vs 6k for the full one). Still 133//Simple tail implementation (2k vs 6k for the full one). Still
@@ -142,11 +137,20 @@
142// Enable support for loop devices in mount 137// Enable support for loop devices in mount
143#define BB_FEATURE_MOUNT_LOOP 138#define BB_FEATURE_MOUNT_LOOP
144// 139//
140// Enable support for a real /etc/mtab file instead of /proc/mounts
141#ifdef BB_MOUNT
142//#define BB_MTAB
143#endif
144//
145//
146// Enable support for remounting filesystems
147#define BB_FEATURE_REMOUNT
148//
145// Enable support for creation of tar files. 149// Enable support for creation of tar files.
146//#define BB_FEATURE_TAR_CREATE 150//#define BB_FEATURE_TAR_CREATE
147// 151//
148// Allow init to permenently chroot, and umount the old root fs 152// Allow init to permenently chroot, and umount the old root fs
149// just like an initrd does. Requires a kernel patch by Werner Almesberger. 153// just like an initrd does. Requires a kernel patch by Werner Almesberger.
150// ftp://icaftp.epfl.ch/pub/people/almesber/misc/umount-root-*.tar.gz 154// ftp://icaftp.epfl.ch/pub/people/almesber/misc/umount-root-*.tar.gz
151#ifdef BB_MOUNT 155#ifdef BB_MOUNT
152#define BB_FEATURE_INIT_CHROOT 156#define BB_FEATURE_INIT_CHROOT
diff --git a/busybox.mkll b/busybox.mkll
index be6d937cf..c4420f50d 100755
--- a/busybox.mkll
+++ b/busybox.mkll
@@ -1,5 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2#Make busybox links list file 2# Make busybox links list file.
3 3
4DF="busybox.def.h" 4DF="busybox.def.h"
5MF="busybox.c" 5MF="busybox.c"
diff --git a/chmod_chown_chgrp.c b/chmod_chown_chgrp.c
index 773f4b0c0..b4c5da936 100644
--- a/chmod_chown_chgrp.c
+++ b/chmod_chown_chgrp.c
@@ -21,10 +21,14 @@
21 * 21 *
22 */ 22 */
23 23
24#include "internal.h"
25#define BB_DECLARE_EXTERN
26#define bb_need_invalid_option
27#include "messages.c"
28
24#include <stdio.h> 29#include <stdio.h>
25#include <grp.h> 30#include <grp.h>
26#include <pwd.h> 31#include <pwd.h>
27#include "internal.h"
28 32
29 33
30static uid_t uid = -1; 34static uid_t uid = -1;
@@ -69,7 +73,7 @@ static int fileAction(const char *fileName, struct stat* statbuf)
69 case CHMOD_APP: 73 case CHMOD_APP:
70 /* Parse the specified modes */ 74 /* Parse the specified modes */
71 if ( parse_mode(theMode, &(statbuf->st_mode)) == FALSE ) { 75 if ( parse_mode(theMode, &(statbuf->st_mode)) == FALSE ) {
72 fprintf(stderr, "%s: Unknown mode: %s\n", invocationName, theMode); 76 fprintf(stderr, "%s: unknown mode: %s\n", invocationName, theMode);
73 exit( FALSE); 77 exit( FALSE);
74 } 78 }
75 if (chmod(fileName, statbuf->st_mode) == 0) 79 if (chmod(fileName, statbuf->st_mode) == 0)
@@ -84,6 +88,7 @@ int chmod_chown_chgrp_main(int argc, char **argv)
84{ 88{
85 int recursiveFlag=FALSE; 89 int recursiveFlag=FALSE;
86 char *groupName; 90 char *groupName;
91 char *p;
87 const char *appUsage; 92 const char *appUsage;
88 93
89 whichApp = (strcmp(*argv, "chown")==0)? CHOWN_APP : (strcmp(*argv, "chmod")==0)? CHMOD_APP : CHGRP_APP; 94 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)
103 recursiveFlag = TRUE; 108 recursiveFlag = TRUE;
104 break; 109 break;
105 default: 110 default:
106 fprintf(stderr, "Unknown option: %c\n", **argv); 111 fprintf(stderr, invalid_option, invocationName, **argv);
107 usage( appUsage); 112 usage( appUsage);
108 } 113 }
109 argc--; 114 argc--;
@@ -117,14 +122,18 @@ int chmod_chown_chgrp_main(int argc, char **argv)
117 /* Find the selected group */ 122 /* Find the selected group */
118 if ( whichApp==CHGRP_APP ) { 123 if ( whichApp==CHGRP_APP ) {
119 groupName = *argv; 124 groupName = *argv;
120 gid = my_getgrnam(groupName); 125 gid = strtoul(groupName, &p, 10); /* maybe it's already numeric */
126 if (groupName == p)
127 gid = my_getgrnam(groupName);
121 if (gid == -1) 128 if (gid == -1)
122 goto bad_group; 129 goto bad_group;
123 } else { 130 } else {
124 groupName = strchr(*argv, '.'); 131 groupName = strchr(*argv, '.');
125 if (groupName) { 132 if (groupName) {
126 *groupName++ = '\0'; 133 *groupName++ = '\0';
127 gid = my_getgrnam(groupName); 134 gid = strtoul(groupName, &p, 10);
135 if (groupName == p)
136 gid = my_getgrnam(groupName);
128 if (gid == -1) 137 if (gid == -1)
129 goto bad_group; 138 goto bad_group;
130 } else 139 } else
@@ -134,9 +143,11 @@ int chmod_chown_chgrp_main(int argc, char **argv)
134 143
135 /* Find the selected user (if appropriate) */ 144 /* Find the selected user (if appropriate) */
136 if (whichApp==CHOWN_APP) { 145 if (whichApp==CHOWN_APP) {
137 uid = my_getpwnam(*argv); 146 uid = strtoul(*argv, &p, 10); /* if numeric ...*/
147 if (*argv == p)
148 uid = my_getpwnam(*argv);
138 if (uid == -1) { 149 if (uid == -1) {
139 fprintf(stderr, "%s: Unknown user name: %s\n", invocationName, *argv); 150 fprintf(stderr, "%s: unknown user name: %s\n", invocationName, *argv);
140 exit( FALSE); 151 exit( FALSE);
141 } 152 }
142 } 153 }
@@ -144,7 +155,7 @@ int chmod_chown_chgrp_main(int argc, char **argv)
144 155
145 /* Ok, ready to do the deed now */ 156 /* Ok, ready to do the deed now */
146 if (argc <= 1) { 157 if (argc <= 1) {
147 fprintf(stderr, "%s: too few arguments", invocationName); 158 fprintf(stderr, "%s: too few arguments\n", invocationName);
148 exit( FALSE); 159 exit( FALSE);
149 } 160 }
150 while (argc-- > 1) { 161 while (argc-- > 1) {
@@ -154,7 +165,7 @@ int chmod_chown_chgrp_main(int argc, char **argv)
154 exit(TRUE); 165 exit(TRUE);
155 166
156bad_group: 167bad_group:
157 fprintf(stderr, "%s: Unknown group name: %s\n", invocationName, groupName); 168 fprintf(stderr, "%s: unknown group name: %s\n", invocationName, groupName);
158 exit( FALSE); 169 exit( FALSE);
159} 170}
160 171
diff --git a/coreutils/cp.c b/coreutils/cp.c
deleted file mode 100644
index e96012d50..000000000
--- a/coreutils/cp.c
+++ /dev/null
@@ -1,127 +0,0 @@
1/*
2 * Mini cp implementation for busybox
3 *
4 *
5 * Copyright (C) 1999 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include "internal.h"
25#include <stdio.h>
26#include <time.h>
27#include <utime.h>
28#include <dirent.h>
29
30static const char cp_usage[] = "cp [OPTION]... SOURCE DEST\n"
31 " or: cp [OPTION]... SOURCE... DIRECTORY\n\n"
32 "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n"
33 "\n"
34 "\t-a\tsame as -dpR\n"
35 "\t-d\tpreserve links\n"
36 "\t-p\tpreserve file attributes if possible\n"
37 "\t-R\tcopy directories recursively\n";
38
39
40static int recursiveFlag = FALSE;
41static int followLinks = FALSE;
42static int preserveFlag = FALSE;
43static const char *srcName;
44static const char *destName;
45static int destDirFlag = FALSE;
46static int srcDirFlag = FALSE;
47
48static int fileAction(const char *fileName, struct stat* statbuf)
49{
50 char newdestName[NAME_MAX];
51 char* newsrcName = NULL;
52
53 strcpy(newdestName, destName);
54 if ( srcDirFlag == TRUE ) {
55 if (recursiveFlag!=TRUE ) {
56 fprintf(stderr, "cp: %s: omitting directory\n", srcName);
57 return( TRUE);
58 }
59 strcat(newdestName, strstr(fileName, srcName) + strlen(srcName));
60 }
61
62 if (destDirFlag==TRUE && srcDirFlag == FALSE) {
63 if (newdestName[strlen(newdestName)-1] != '/' ) {
64 strcat(newdestName, "/");
65 }
66 newsrcName = strrchr(srcName, '/');
67 if (newsrcName && *newsrcName != '\0')
68 strcat(newdestName, newsrcName);
69 else
70 strcat(newdestName, srcName);
71 }
72
73 return (copyFile(fileName, newdestName, preserveFlag, followLinks));
74}
75
76extern int cp_main(int argc, char **argv)
77{
78 if (argc < 3) {
79 usage (cp_usage);
80 }
81 argc--;
82 argv++;
83
84 /* Parse any options */
85 while (**argv == '-') {
86 while (*++(*argv))
87 switch (**argv) {
88 case 'a':
89 followLinks = TRUE;
90 preserveFlag = TRUE;
91 recursiveFlag = TRUE;
92 break;
93 case 'd':
94 followLinks = TRUE;
95 break;
96 case 'p':
97 preserveFlag = TRUE;
98 break;
99 case 'R':
100 recursiveFlag = TRUE;
101 break;
102 default:
103 usage (cp_usage);
104 }
105 argc--;
106 argv++;
107 }
108
109
110 destName = argv[argc - 1];
111 destDirFlag = isDirectory(destName);
112
113 if ((argc > 3) && destDirFlag==FALSE) {
114 fprintf(stderr, "%s: not a directory\n", destName);
115 exit (FALSE);
116 }
117
118 while (argc-- > 1) {
119 srcName = *(argv++);
120 srcDirFlag = isDirectory(srcName);
121 if (recursiveAction(srcName, recursiveFlag, followLinks, FALSE,
122 fileAction, fileAction) == FALSE) {
123 exit( FALSE);
124 }
125 }
126 exit( TRUE);
127}
diff --git a/coreutils/date.c b/coreutils/date.c
index 77e7c39db..a3528921d 100644
--- a/coreutils/date.c
+++ b/coreutils/date.c
@@ -20,6 +20,10 @@
20*/ 20*/
21 21
22#include "internal.h" 22#include "internal.h"
23#define BB_DECLARE_EXTERN
24#define bb_need_invalid_date
25#define bb_need_memory_exhausted
26#include "messages.c"
23#include <stdlib.h> 27#include <stdlib.h>
24#include <errno.h> 28#include <errno.h>
25#include <sys/time.h> 29#include <sys/time.h>
@@ -59,7 +63,7 @@ date_conv_time(struct tm *tm_time, const char *t_string) {
59 &(tm_time->tm_year)); 63 &(tm_time->tm_year));
60 64
61 if(nr < 4 || nr > 5) { 65 if(nr < 4 || nr > 5) {
62 fprintf(stderr, "date: invalid date `%s'\n", t_string); 66 fprintf(stderr, invalid_date, "date", t_string);
63 exit( FALSE); 67 exit( FALSE);
64 } 68 }
65 69
@@ -152,7 +156,7 @@ date_conv_ftime(struct tm *tm_time, const char *t_string) {
152 156
153 } 157 }
154 158
155 fprintf(stderr, "date: invalid date `%s'\n", t_string); 159 fprintf(stderr, invalid_date, "date", t_string);
156 160
157 exit( FALSE); 161 exit( FALSE);
158 162
@@ -190,7 +194,7 @@ date_main(int argc, char * * argv)
190 case 'u': 194 case 'u':
191 utc = 1; 195 utc = 1;
192 if (putenv ("TZ=UTC0") != 0) { 196 if (putenv ("TZ=UTC0") != 0) {
193 fprintf(stderr,"date: memory exhausted\n"); 197 fprintf(stderr, memory_exhausted, "date");
194 exit( FALSE); 198 exit( FALSE);
195 } 199 }
196 /* Look ma, no break. Don't fix it either. */ 200 /* Look ma, no break. Don't fix it either. */
@@ -204,10 +208,10 @@ date_main(int argc, char * * argv)
204 } 208 }
205 } else { 209 } else {
206 if ( (date_fmt == NULL) && (strcmp(*argv, "+")==0) ) 210 if ( (date_fmt == NULL) && (strcmp(*argv, "+")==0) )
207 date_fmt = *argv; 211 date_fmt=*argv;
208 else if (date_str == NULL) { 212 else if (date_str == NULL) {
209 set_time = 1; 213 set_time = 1;
210 date_str = *argv; 214 date_str=*argv;
211 } else { 215 } else {
212 usage ( date_usage); 216 usage ( date_usage);
213 } 217 }
@@ -241,7 +245,7 @@ date_main(int argc, char * * argv)
241 /* Correct any day of week and day of year etc fields */ 245 /* Correct any day of week and day of year etc fields */
242 tm = mktime(&tm_time); 246 tm = mktime(&tm_time);
243 if (tm < 0 ) { 247 if (tm < 0 ) {
244 fprintf(stderr, "date: invalid date `%s'\n", date_str); 248 fprintf(stderr, invalid_date, "date", date_str);
245 exit( FALSE); 249 exit( FALSE);
246 } 250 }
247 251
@@ -284,4 +288,3 @@ date_main(int argc, char * * argv)
284 exit( TRUE); 288 exit( TRUE);
285 289
286} 290}
287
diff --git a/coreutils/dd.c b/coreutils/dd.c
index bc01eedbf..3e1024a60 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -40,15 +40,16 @@ typedef unsigned long long int uintmax_t;
40#endif 40#endif
41 41
42static const char dd_usage[] = 42static const char dd_usage[] =
43"dd [if=name] [of=name] [bs=n] [count=n]\n\n" 43"dd [if=name] [of=name] [bs=n] [count=n] [skip=n] [seek=n]\n\n"
44"Copy a file, converting and formatting according to options\n\n" 44"Copy a file, converting and formatting according to options\n\n"
45"\tif=FILE\tread from FILE instead of stdin\n" 45"\tif=FILE\tread from FILE instead of stdin\n"
46"\tof=FILE\twrite to FILE instead of stout\n" 46"\tof=FILE\twrite to FILE instead of stdout\n"
47"\tbs=n\tread and write N BYTES at a time\n" 47"\tbs=n\tread and write n bytes at a time\n"
48"\tcount=n\tcopy only n input blocks\n" 48"\tcount=n\tcopy only n input blocks\n"
49//"\tskip=n\tskip n input blocks\n" 49"\tskip=n\tskip n input blocks\n"
50"\tseek=n\tskip n output blocks\n"
50"\n" 51"\n"
51"BYTES may be suffixed by w (x2), k (x1024), b (x512), or m (x1024^2).\n"; 52"Numbers may be suffixed by w (x2), k (x1024), b (x512), or M (x1024^2)\n";
52 53
53 54
54 55
@@ -61,8 +62,9 @@ extern int dd_main (int argc, char **argv)
61 int outFd; 62 int outFd;
62 int inCc = 0; 63 int inCc = 0;
63 int outCc; 64 int outCc;
64 size_t blockSize = 512; 65 long blockSize = 512;
65 //uintmax_t skipBlocks = 0; 66 uintmax_t skipBlocks = 0;
67 uintmax_t seekBlocks = 0;
66 uintmax_t count = (uintmax_t)-1; 68 uintmax_t count = (uintmax_t)-1;
67 uintmax_t intotal; 69 uintmax_t intotal;
68 uintmax_t outTotal; 70 uintmax_t outTotal;
@@ -91,16 +93,22 @@ extern int dd_main (int argc, char **argv)
91 goto usage; 93 goto usage;
92 } 94 }
93 } 95 }
94#if 0
95 else if (strncmp(*argv, "skip", 4) == 0) { 96 else if (strncmp(*argv, "skip", 4) == 0) {
96 skipBlocks = atoi( *argv); 97 skipBlocks = getNum ((strchr(*argv, '='))+1);
97 if (skipBlocks <= 0) { 98 if (skipBlocks <= 0) {
98 fprintf (stderr, "Bad skip value %d\n", skipBlocks); 99 fprintf (stderr, "Bad skip value %s\n", *argv);
100 goto usage;
101 }
102
103 }
104 else if (strncmp(*argv, "seek", 4) == 0) {
105 seekBlocks = getNum ((strchr(*argv, '='))+1);
106 if (seekBlocks <= 0) {
107 fprintf (stderr, "Bad seek value %s\n", *argv);
99 goto usage; 108 goto usage;
100 } 109 }
101 110
102 } 111 }
103#endif
104 else { 112 else {
105 goto usage; 113 goto usage;
106 } 114 }
@@ -131,7 +139,7 @@ extern int dd_main (int argc, char **argv)
131 if (outFile == NULL) 139 if (outFile == NULL)
132 outFd = fileno(stdout); 140 outFd = fileno(stdout);
133 else 141 else
134 outFd = creat (outFile, 0666); 142 outFd = open(outFile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
135 143
136 if (outFd < 0) { 144 if (outFd < 0) {
137 perror (outFile); 145 perror (outFile);
@@ -140,10 +148,11 @@ extern int dd_main (int argc, char **argv)
140 exit( FALSE); 148 exit( FALSE);
141 } 149 }
142 150
143 //lseek(inFd, skipBlocks*blockSize, SEEK_SET); 151 lseek(inFd, skipBlocks*blockSize, SEEK_SET);
152 lseek(outFd, seekBlocks*blockSize, SEEK_SET);
144 // 153 //
145 //TODO: Convert to using fullRead & fullWrite 154 //TODO: Convert to using fullRead & fullWrite
146 // from utilitity.c 155 // from utility.c
147 // -Erik 156 // -Erik
148 while (outTotal < count * blockSize) { 157 while (outTotal < count * blockSize) {
149 inCc = read (inFd, buf, blockSize); 158 inCc = read (inFd, buf, blockSize);
diff --git a/coreutils/du.c b/coreutils/du.c
index 79b553643..e2cf3f7c0 100644
--- a/coreutils/du.c
+++ b/coreutils/du.c
@@ -22,17 +22,18 @@
22 */ 22 */
23 23
24#include "internal.h" 24#include "internal.h"
25#define BB_DECLARE_EXTERN
26#define bb_need_name_too_long
27#include "messages.c"
28
25#include <sys/types.h> 29#include <sys/types.h>
26#include <fcntl.h> 30#include <fcntl.h>
27#include <dirent.h> 31#include <dirent.h>
28#include <stdio.h> 32#include <stdio.h>
29#include <errno.h> 33#include <errno.h>
30#if 0 34#include <sys/param.h> /* for PATH_MAX */
31#include <unistd.h>
32#include <sys/stat.h>
33#endif
34 35
35typedef void (Display)(size_t, char *); 36typedef void (Display)(long, char *);
36 37
37static const char du_usage[] = 38static const char du_usage[] =
38"du [OPTION]... [FILE]...\n\n" 39"du [OPTION]... [FILE]...\n\n"
@@ -44,13 +45,13 @@ static int du_depth = 0;
44static Display *print; 45static Display *print;
45 46
46static void 47static void
47print_normal(size_t size, char *filename) 48print_normal(long size, char *filename)
48{ 49{
49 fprintf(stdout, "%-7d %s\n", (size >> 1), filename); 50 fprintf(stdout, "%-7ld %s\n", size, filename);
50} 51}
51 52
52static void 53static void
53print_summary(size_t size, char *filename) 54print_summary(long size, char *filename)
54{ 55{
55 if (du_depth == 1) { 56 if (du_depth == 1) {
56 print_normal(size, filename); 57 print_normal(size, filename);
@@ -59,11 +60,11 @@ print_summary(size_t size, char *filename)
59 60
60 61
61/* tiny recursive du */ 62/* tiny recursive du */
62static size_t 63static long
63du(char *filename) 64du(char *filename)
64{ 65{
65 struct stat statbuf; 66 struct stat statbuf;
66 size_t sum; 67 long sum;
67 68
68 if ((lstat(filename, &statbuf)) != 0) { 69 if ((lstat(filename, &statbuf)) != 0) {
69 fprintf(stdout, "du: %s: %s\n", filename, strerror(errno)); 70 fprintf(stdout, "du: %s: %s\n", filename, strerror(errno));
@@ -80,14 +81,19 @@ du(char *filename)
80 dir = opendir(filename); 81 dir = opendir(filename);
81 if (!dir) { return 0; } 82 if (!dir) { return 0; }
82 while ((entry = readdir(dir))) { 83 while ((entry = readdir(dir))) {
83 char newfile[512]; 84 char newfile[PATH_MAX + 1];
84 char *name = entry->d_name; 85 char *name = entry->d_name;
85 86
86 if ( (strcmp(name, "..") == 0) 87 if ( (strcmp(name, "..") == 0)
87 || (strcmp(name, ".") == 0)) 88 || (strcmp(name, ".") == 0))
88 { continue; } 89 { continue; }
89 90
91 if (strlen(filename) + strlen(name) + 1 > PATH_MAX) {
92 fprintf(stderr, name_too_long, "du");
93 return 0;
94 }
90 sprintf(newfile, "%s/%s", filename, name); 95 sprintf(newfile, "%s/%s", filename, name);
96
91 sum += du(newfile); 97 sum += du(newfile);
92 } 98 }
93 closedir(dir); 99 closedir(dir);
@@ -130,14 +136,14 @@ du_main(int argc, char **argv)
130 if (i >= argc) { 136 if (i >= argc) {
131 du("."); 137 du(".");
132 } else { 138 } else {
133 int sum; 139 long sum;
134 for ( ; i < argc; i++) { 140 for ( ; i < argc; i++) {
135 sum = du(argv[i]); 141 sum = du(argv[i]);
136 if ((sum) && (isDirectory(argv[i]))) { print_normal(sum, argv[i]); } 142 if ((sum) && (isDirectory(argv[i], FALSE))) { print_normal(sum, argv[i]); }
137 } 143 }
138 } 144 }
139 145
140 exit(0); 146 exit(0);
141} 147}
142 148
143/* $Id: du.c,v 1.9 2000/01/23 18:19:02 erik Exp $ */ 149/* $Id: du.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */
diff --git a/coreutils/head.c b/coreutils/head.c
index bc7f35429..b80d06580 100644
--- a/coreutils/head.c
+++ b/coreutils/head.c
@@ -105,4 +105,4 @@ head_main(int argc, char **argv)
105 exit(0); 105 exit(0);
106} 106}
107 107
108/* $Id: head.c,v 1.6 2000/01/25 18:13:53 erik Exp $ */ 108/* $Id: head.c,v 1.7 2000/02/07 05:29:42 erik Exp $ */
diff --git a/coreutils/length.c b/coreutils/length.c
index 46242b529..2c83cdfd2 100644
--- a/coreutils/length.c
+++ b/coreutils/length.c
@@ -6,7 +6,7 @@
6extern int 6extern int
7length_main(int argc, char * * argv) 7length_main(int argc, char * * argv)
8{ 8{
9 if ( **(argv+1) == '-' ) { 9 if ( argc != 2 || **(argv+1) == '-' ) {
10 usage("length string\n"); 10 usage("length string\n");
11 } 11 }
12 printf("%d\n", strlen(argv[1])); 12 printf("%d\n", strlen(argv[1]));
diff --git a/coreutils/ln.c b/coreutils/ln.c
index 60fe39438..f20b340ea 100644
--- a/coreutils/ln.c
+++ b/coreutils/ln.c
@@ -22,26 +22,32 @@
22 */ 22 */
23 23
24#include "internal.h" 24#include "internal.h"
25#define BB_DECLARE_EXTERN
26#define bb_need_name_too_long
27#define bb_need_not_a_directory
28#include "messages.c"
29
25#include <stdio.h> 30#include <stdio.h>
26#include <dirent.h> 31#include <dirent.h>
27#include <errno.h> 32#include <errno.h>
33#include <sys/param.h> /* for PATH_MAX */
28 34
29 35static const char ln_usage[] =
30static const char ln_usage[] = "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n" 36 "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n"
31"Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n" 37 "Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n"
32"Options:\n" 38 "Options:\n"
33"\t-s\tmake symbolic links instead of hard links\n" 39 "\t-s\tmake symbolic links instead of hard links\n"
34"\t-f\tremove existing destination files\n"; 40 "\t-f\tremove existing destination files\n"
35 41 "\t-n\tno dereference symlinks - treat like normal file\n";
36 42
37static int symlinkFlag = FALSE; 43static int symlinkFlag = FALSE;
38static int removeoldFlag = FALSE; 44static int removeoldFlag = FALSE;
39 45static int followLinks = TRUE;
40 46
41extern int ln_main(int argc, char **argv) 47extern int ln_main(int argc, char **argv)
42{ 48{
43 int status; 49 char *linkName;
44 static char* linkName; 50 int linkIntoDirFlag;
45 51
46 if (argc < 3) { 52 if (argc < 3) {
47 usage (ln_usage); 53 usage (ln_usage);
@@ -59,6 +65,9 @@ extern int ln_main(int argc, char **argv)
59 case 'f': 65 case 'f':
60 removeoldFlag = TRUE; 66 removeoldFlag = TRUE;
61 break; 67 break;
68 case 'n':
69 followLinks = FALSE;
70 break;
62 default: 71 default:
63 usage (ln_usage); 72 usage (ln_usage);
64 } 73 }
@@ -66,30 +75,54 @@ extern int ln_main(int argc, char **argv)
66 argv++; 75 argv++;
67 } 76 }
68 77
69
70 linkName = argv[argc - 1]; 78 linkName = argv[argc - 1];
71 79
72 if ((argc > 3) && !(isDirectory(linkName))) { 80 if (strlen(linkName) > PATH_MAX) {
73 fprintf(stderr, "%s: not a directory\n", linkName); 81 fprintf(stderr, name_too_long, "ln");
74 exit (FALSE); 82 exit FALSE;
83 }
84
85 linkIntoDirFlag = isDirectory(linkName, TRUE);
86
87 if ((argc > 3) && !linkIntoDirFlag) {
88 fprintf(stderr, not_a_directory, "ln", linkName);
89 exit FALSE;
75 } 90 }
76 91
77 while (argc-- >= 2) { 92 while (argc-- >= 2) {
78 if (removeoldFlag==TRUE ) { 93 char srcName[PATH_MAX + 1];
94 int nChars, status;
95
96 if (strlen(*argv) > PATH_MAX) {
97 fprintf(stderr, name_too_long, "ln");
98 exit FALSE;
99 }
100
101 if (followLinks == FALSE) {
102 strcpy(srcName, *argv);
103 } else {
104 /* Warning! This can silently truncate if > PATH_MAX, but
105 I don't think that there can be one > PATH_MAX anyway. */
106 nChars = readlink(*argv, srcName, PATH_MAX);
107 srcName[nChars] = '\0';
108 }
109
110 if (removeoldFlag == TRUE) {
79 status = ( unlink(linkName) && errno != ENOENT ); 111 status = ( unlink(linkName) && errno != ENOENT );
80 if ( status != 0 ) { 112 if (status != 0) {
81 perror(linkName); 113 perror(linkName);
82 exit( FALSE); 114 exit FALSE;
83 } 115 }
84 } 116 }
85 if ( symlinkFlag==TRUE) 117
86 status = symlink(*argv, linkName); 118 if (symlinkFlag == TRUE)
119 status = symlink(*argv, linkName);
87 else 120 else
88 status = link(*argv, linkName); 121 status = link(*argv, linkName);
89 if ( status != 0 ) { 122 if (status != 0) {
90 perror(linkName); 123 perror(linkName);
91 exit( FALSE); 124 exit FALSE;
92 } 125 }
93 } 126 }
94 exit( TRUE); 127 exit TRUE;
95} 128}
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 78193e7c1..450ea1814 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -178,7 +178,7 @@ static char append_char(mode_t mode)
178 178
179static void list_single(const char *name, struct stat *info, const char *fullname) 179static void list_single(const char *name, struct stat *info, const char *fullname)
180{ 180{
181 char scratch[PATH_MAX]; 181 char scratch[PATH_MAX + 1];
182 short len = strlen(name); 182 short len = strlen(name);
183#ifdef BB_FEATURE_LS_FILETYPES 183#ifdef BB_FEATURE_LS_FILETYPES
184 char append = append_char(info->st_mode); 184 char append = append_char(info->st_mode);
diff --git a/coreutils/mkdir.c b/coreutils/mkdir.c
index 017ef9b08..8e3f51bfb 100644
--- a/coreutils/mkdir.c
+++ b/coreutils/mkdir.c
@@ -22,9 +22,13 @@
22 */ 22 */
23 23
24#include "internal.h" 24#include "internal.h"
25#define bb_need_name_too_long
26#define BB_DECLARE_EXTERN
27#include "messages.c"
28
25#include <stdio.h> 29#include <stdio.h>
26#include <errno.h> 30#include <errno.h>
27#include <sys/param.h> 31#include <sys/param.h> /* for PATH_MAX */
28 32
29static const char mkdir_usage[] = 33static const char mkdir_usage[] =
30"mkdir [OPTION] DIRECTORY...\n\n" 34"mkdir [OPTION] DIRECTORY...\n\n"
@@ -40,27 +44,27 @@ static mode_t mode = 0777;
40 44
41extern int mkdir_main(int argc, char **argv) 45extern int mkdir_main(int argc, char **argv)
42{ 46{
43 int i=FALSE; 47 int i = FALSE;
44 argc--; 48 argc--;
45 argv++; 49 argv++;
46 50
47 /* Parse any options */ 51 /* Parse any options */
48 while (argc > 0 && **argv == '-') { 52 while (argc > 0 && **argv == '-') {
49 while (i==FALSE && *++(*argv)) { 53 while (i == FALSE && *++(*argv)) {
50 switch (**argv) { 54 switch (**argv) {
51 case 'm': 55 case 'm':
52 if (--argc == 0) 56 if (--argc == 0)
53 usage( mkdir_usage); 57 usage( mkdir_usage);
54 /* Find the specified modes */ 58 /* Find the specified modes */
55 mode = 0; 59 mode = 0;
56 if ( parse_mode(*(++argv), &mode) == FALSE ) { 60 if (parse_mode(*(++argv), &mode) == FALSE ) {
57 fprintf(stderr, "Unknown mode: %s\n", *argv); 61 fprintf(stderr, "Unknown mode: %s\n", *argv);
58 exit( FALSE); 62 exit FALSE;
59 } 63 }
60 /* Set the umask for this process so it doesn't 64 /* Set the umask for this process so it doesn't
61 * screw up whatever the user just entered. */ 65 * screw up whatever the user just entered. */
62 umask(0); 66 umask(0);
63 i=TRUE; 67 i = TRUE;
64 break; 68 break;
65 case 'p': 69 case 'p':
66 parentFlag = TRUE; 70 parentFlag = TRUE;
@@ -73,7 +77,6 @@ extern int mkdir_main(int argc, char **argv)
73 argv++; 77 argv++;
74 } 78 }
75 79
76
77 if (argc < 1) { 80 if (argc < 1) {
78 usage( mkdir_usage); 81 usage( mkdir_usage);
79 } 82 }
@@ -81,13 +84,16 @@ extern int mkdir_main(int argc, char **argv)
81 while (argc > 0) { 84 while (argc > 0) {
82 int status; 85 int status;
83 struct stat statBuf; 86 struct stat statBuf;
84 char buf[NAME_MAX]; 87 char buf[PATH_MAX + 1];
85 88 if (strlen(*argv) > PATH_MAX - 1) {
89 fprintf(stderr, name_too_long, "mkdir");
90 exit FALSE;
91 }
86 strcpy (buf, *argv); 92 strcpy (buf, *argv);
87 status=stat(buf, &statBuf); 93 status = stat(buf, &statBuf);
88 if (parentFlag == FALSE && status != -1 && status != ENOENT ) { 94 if (parentFlag == FALSE && status != -1 && errno != ENOENT) {
89 fprintf(stderr, "%s: File exists\n", buf); 95 fprintf(stderr, "%s: File exists\n", buf);
90 exit( FALSE); 96 exit FALSE;
91 } 97 }
92 if (parentFlag == TRUE) { 98 if (parentFlag == TRUE) {
93 strcat( buf, "/"); 99 strcat( buf, "/");
@@ -96,13 +102,13 @@ extern int mkdir_main(int argc, char **argv)
96 else { 102 else {
97 if (mkdir (buf, mode) != 0 && parentFlag == FALSE) { 103 if (mkdir (buf, mode) != 0 && parentFlag == FALSE) {
98 perror(buf); 104 perror(buf);
99 exit( FALSE); 105 exit FALSE;
100 } 106 }
101 } 107 }
102 argc--; 108 argc--;
103 argv++; 109 argv++;
104 } 110 }
105 exit( TRUE); 111 exit TRUE;
106} 112}
107 113
108 114
diff --git a/coreutils/mv.c b/coreutils/mv.c
deleted file mode 100644
index 467a360de..000000000
--- a/coreutils/mv.c
+++ /dev/null
@@ -1,112 +0,0 @@
1/*
2 * Mini mv implementation for busybox
3 *
4 *
5 * Copyright (C) 1999 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include "internal.h"
25#include <stdio.h>
26#include <time.h>
27#include <utime.h>
28#include <dirent.h>
29
30static const char mv_usage[] = "mv SOURCE DEST\n"
31" or: mv SOURCE... DIRECTORY\n\n"
32"Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n";
33
34
35static const char *srcName;
36static const char *destName;
37static int destDirFlag = FALSE;
38static int srcDirFlag = FALSE;
39
40static int fileAction(const char *fileName, struct stat* statbuf)
41{
42 char newdestName[NAME_MAX];
43 char* newsrcName = NULL;
44
45 strcpy(newdestName, destName);
46 if ( srcDirFlag == TRUE ) {
47 strcat(newdestName, strstr(fileName, srcName) + strlen(srcName));
48 }
49
50 if (destDirFlag==TRUE && srcDirFlag == FALSE) {
51 if (newdestName[strlen(newdestName)-1] != '/' ) {
52 strcat(newdestName, "/");
53 }
54 newsrcName = strrchr(srcName, '/');
55 if (newsrcName && *newsrcName != '\0')
56 strcat(newdestName, newsrcName);
57 else
58 strcat(newdestName, srcName);
59 }
60
61 return (copyFile(fileName, newdestName, TRUE, TRUE));
62}
63
64static int rmfileAction(const char *fileName, struct stat* statbuf)
65{
66 if (unlink( fileName) < 0 ) {
67 perror( fileName);
68 return ( FALSE);
69 }
70 return ( TRUE);
71}
72
73static int rmdirAction(const char *fileName, struct stat* statbuf)
74{
75 if (rmdir( fileName) < 0 ) {
76 perror( fileName);
77 return ( FALSE);
78 }
79 return ( TRUE);
80}
81
82
83extern int mv_main(int argc, char **argv)
84{
85 if (argc < 3) {
86 usage (mv_usage);
87 }
88 argc--;
89 argv++;
90
91 destName = argv[argc - 1];
92 destDirFlag = isDirectory(destName);
93
94 if ((argc > 3) && destDirFlag==FALSE) {
95 fprintf(stderr, "%s: not a directory\n", destName);
96 exit (FALSE);
97 }
98
99 while (argc-- > 1) {
100 srcName = *(argv++);
101 srcDirFlag = isDirectory(srcName);
102 if (recursiveAction(srcName, TRUE, TRUE, FALSE,
103 fileAction, fileAction) == FALSE) {
104 exit( FALSE);
105 }
106 if (recursiveAction(srcName, TRUE, TRUE, TRUE,
107 rmfileAction, rmdirAction) == FALSE) {
108 exit( FALSE);
109 }
110 }
111 exit( TRUE);
112}
diff --git a/coreutils/printf.c b/coreutils/printf.c
index 5be3a67cb..5fd5ea303 100644
--- a/coreutils/printf.c
+++ b/coreutils/printf.c
@@ -143,7 +143,7 @@ printf_main(int argc, char** argv)
143 int args_used; 143 int args_used;
144 144
145 exit_status = 0; 145 exit_status = 0;
146 if ( **(argv+1) == '-' ) { 146 if ( argc <= 1 || **(argv+1) == '-' ) {
147 usage (printf_usage); 147 usage (printf_usage);
148 } 148 }
149 149
diff --git a/coreutils/pwd.c b/coreutils/pwd.c
index c5ce6ff89..bacabd77a 100644
--- a/coreutils/pwd.c
+++ b/coreutils/pwd.c
@@ -23,11 +23,12 @@
23#include "internal.h" 23#include "internal.h"
24#include <stdio.h> 24#include <stdio.h>
25#include <dirent.h> 25#include <dirent.h>
26#include <sys/param.h>
26 27
27extern int 28extern int
28pwd_main(int argc, char * * argv) 29pwd_main(int argc, char * * argv)
29{ 30{
30 char buf[NAME_MAX]; 31 char buf[PATH_MAX + 1];
31 32
32 if ( getcwd(buf, sizeof(buf)) == NULL ) { 33 if ( getcwd(buf, sizeof(buf)) == NULL ) {
33 perror("get working directory"); 34 perror("get working directory");
diff --git a/coreutils/sort.c b/coreutils/sort.c
index 4df5627ac..d529ce722 100644
--- a/coreutils/sort.c
+++ b/coreutils/sort.c
@@ -309,4 +309,4 @@ sort_main(int argc, char **argv)
309 exit(0); 309 exit(0);
310} 310}
311 311
312/* $Id: sort.c,v 1.9 2000/01/23 18:19:02 erik Exp $ */ 312/* $Id: sort.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */
diff --git a/coreutils/tail.c b/coreutils/tail.c
index 5198892b6..0ab8f11b0 100644
--- a/coreutils/tail.c
+++ b/coreutils/tail.c
@@ -33,7 +33,7 @@
33 and generally busyboxed, Erik Andersen <andersen@lineo.com> 33 and generally busyboxed, Erik Andersen <andersen@lineo.com>
34 34
35 Removed superfluous options and associated code ("-c", "-n", "-q"). 35 Removed superfluous options and associated code ("-c", "-n", "-q").
36 Removed "tail -f" suport for multiple files. 36 Removed "tail -f" support for multiple files.
37 Both changes by Friedrich Vedder <fwv@myrtle.lahn.de>. 37 Both changes by Friedrich Vedder <fwv@myrtle.lahn.de>.
38 38
39 */ 39 */
diff --git a/coreutils/tee.c b/coreutils/tee.c
index 8d1ca6efd..4c5c691c6 100644
--- a/coreutils/tee.c
+++ b/coreutils/tee.c
@@ -123,4 +123,4 @@ tee_main(int argc, char **argv)
123 exit(0); 123 exit(0);
124} 124}
125 125
126/* $Id: tee.c,v 1.4 1999/12/10 08:25:07 andersen Exp $ */ 126/* $Id: tee.c,v 1.5 2000/02/07 05:29:42 erik Exp $ */
diff --git a/coreutils/uniq.c b/coreutils/uniq.c
index a7bff54ec..965d290c2 100644
--- a/coreutils/uniq.c
+++ b/coreutils/uniq.c
@@ -193,4 +193,4 @@ uniq_main(int argc, char **argv)
193 exit(0); 193 exit(0);
194} 194}
195 195
196/* $Id: uniq.c,v 1.5 2000/01/23 18:19:02 erik Exp $ */ 196/* $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
index e96012d50..000000000
--- a/cp.c
+++ /dev/null
@@ -1,127 +0,0 @@
1/*
2 * Mini cp implementation for busybox
3 *
4 *
5 * Copyright (C) 1999 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include "internal.h"
25#include <stdio.h>
26#include <time.h>
27#include <utime.h>
28#include <dirent.h>
29
30static const char cp_usage[] = "cp [OPTION]... SOURCE DEST\n"
31 " or: cp [OPTION]... SOURCE... DIRECTORY\n\n"
32 "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n"
33 "\n"
34 "\t-a\tsame as -dpR\n"
35 "\t-d\tpreserve links\n"
36 "\t-p\tpreserve file attributes if possible\n"
37 "\t-R\tcopy directories recursively\n";
38
39
40static int recursiveFlag = FALSE;
41static int followLinks = FALSE;
42static int preserveFlag = FALSE;
43static const char *srcName;
44static const char *destName;
45static int destDirFlag = FALSE;
46static int srcDirFlag = FALSE;
47
48static int fileAction(const char *fileName, struct stat* statbuf)
49{
50 char newdestName[NAME_MAX];
51 char* newsrcName = NULL;
52
53 strcpy(newdestName, destName);
54 if ( srcDirFlag == TRUE ) {
55 if (recursiveFlag!=TRUE ) {
56 fprintf(stderr, "cp: %s: omitting directory\n", srcName);
57 return( TRUE);
58 }
59 strcat(newdestName, strstr(fileName, srcName) + strlen(srcName));
60 }
61
62 if (destDirFlag==TRUE && srcDirFlag == FALSE) {
63 if (newdestName[strlen(newdestName)-1] != '/' ) {
64 strcat(newdestName, "/");
65 }
66 newsrcName = strrchr(srcName, '/');
67 if (newsrcName && *newsrcName != '\0')
68 strcat(newdestName, newsrcName);
69 else
70 strcat(newdestName, srcName);
71 }
72
73 return (copyFile(fileName, newdestName, preserveFlag, followLinks));
74}
75
76extern int cp_main(int argc, char **argv)
77{
78 if (argc < 3) {
79 usage (cp_usage);
80 }
81 argc--;
82 argv++;
83
84 /* Parse any options */
85 while (**argv == '-') {
86 while (*++(*argv))
87 switch (**argv) {
88 case 'a':
89 followLinks = TRUE;
90 preserveFlag = TRUE;
91 recursiveFlag = TRUE;
92 break;
93 case 'd':
94 followLinks = TRUE;
95 break;
96 case 'p':
97 preserveFlag = TRUE;
98 break;
99 case 'R':
100 recursiveFlag = TRUE;
101 break;
102 default:
103 usage (cp_usage);
104 }
105 argc--;
106 argv++;
107 }
108
109
110 destName = argv[argc - 1];
111 destDirFlag = isDirectory(destName);
112
113 if ((argc > 3) && destDirFlag==FALSE) {
114 fprintf(stderr, "%s: not a directory\n", destName);
115 exit (FALSE);
116 }
117
118 while (argc-- > 1) {
119 srcName = *(argv++);
120 srcDirFlag = isDirectory(srcName);
121 if (recursiveAction(srcName, recursiveFlag, followLinks, FALSE,
122 fileAction, fileAction) == FALSE) {
123 exit( FALSE);
124 }
125 }
126 exit( TRUE);
127}
diff --git a/cp_mv.c b/cp_mv.c
new file mode 100644
index 000000000..2ba8662b9
--- /dev/null
+++ b/cp_mv.c
@@ -0,0 +1,258 @@
1/*
2 * Mini `cp' and `mv' implementation for BusyBox.
3 *
4 *
5 * Copyright (C) 1999 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7 *
8 * Copyright (C) 2000 by BitterSweet Enterprises, LLC. (GPL)
9 * Extensively modified and rewritten by Karl M. Hegbloom <karlheg@debian.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#include "internal.h"
28#define BB_DECLARE_EXTERN
29#define bb_need_name_too_long
30#define bb_need_omitting_directory
31#define bb_need_not_a_directory
32#include "messages.c"
33
34#include <stdio.h>
35#include <time.h>
36#include <utime.h>
37#include <dirent.h>
38#include <sys/param.h>
39
40#define is_cp 0
41#define is_mv 1
42static const char *dz; /* dollar zero, .bss */
43static int dz_i; /* index, .bss */
44static const char *cp_mv_usage[] = /* .rodata */
45{
46 "cp [OPTION]... SOURCE DEST\n"
47 " or: cp [OPTION]... SOURCE... DIRECTORY\n\n"
48 "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n"
49 "\n"
50 "\t-a\tsame as -dpR\n"
51 "\t-d\tpreserve links\n"
52 "\t-p\tpreserve file attributes if possible\n"
53 "\t-R\tcopy directories recursively\n"
54 ,
55 "mv SOURCE DEST\n"
56 " or: mv SOURCE... DIRECTORY\n\n"
57 "Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n"
58 "Warning!! This is not GNU `mv'. It does not preserve hard links.\n"
59};
60
61extern int cp_mv_main(int argc, char **argv)
62{
63 __label__ name_too_long__exit;
64 __label__ exit_false;
65
66 int recursiveFlag;
67 int followLinks;
68 int preserveFlag;
69
70 const char *baseSrcName;
71 int srcDirFlag;
72
73 char baseDestName[PATH_MAX + 1];
74 size_t baseDestLen;
75 int destDirFlag;
76
77 void fill_baseDest_buf(char *_buf, size_t *_buflen)
78 {
79 const char *srcBasename;
80 if ((srcBasename = strrchr(baseSrcName, '/')) == NULL)
81 {
82 srcBasename = baseSrcName;
83 if (_buf[*_buflen - 1] != '/')
84 {
85 if (++(*_buflen) > PATH_MAX)
86 goto name_too_long__exit;
87 strcat(_buf, "/");
88 }
89 }
90 if (*_buflen + strlen(srcBasename) > PATH_MAX)
91 goto name_too_long__exit;
92 strcat(_buf, srcBasename);
93 return;
94 }
95
96 int fileAction(const char *fileName, struct stat *statbuf)
97 {
98 __label__ return_false;
99 char destName[PATH_MAX + 1];
100 size_t destLen;
101 const char *srcBasename;
102
103 strcpy(destName, baseDestName);
104 destLen = strlen(destName);
105
106 if (srcDirFlag == TRUE)
107 {
108 if (recursiveFlag == FALSE)
109 {
110 fprintf(stderr, omitting_directory, "cp", baseSrcName);
111 return TRUE;
112 }
113 srcBasename = (strstr(fileName, baseSrcName)
114 + strlen(baseSrcName));
115 if (destLen + strlen(srcBasename) > PATH_MAX)
116 {
117 fprintf(stderr, name_too_long, "cp");
118 goto return_false;
119 }
120 strcat(destName, srcBasename);
121 }
122 else if (destDirFlag == TRUE)
123 {
124 fill_baseDest_buf(&destName[0], &destLen);
125 }
126 else
127 {
128 srcBasename = baseSrcName;
129 }
130 return copyFile(fileName, destName, preserveFlag, followLinks);
131
132 return_false:
133 return FALSE;
134 }
135
136 int rmfileAction(const char *fileName, struct stat* statbuf)
137 {
138 if (unlink(fileName) < 0 ) {
139 perror(fileName);
140 return FALSE;
141 }
142 return TRUE;
143 }
144
145 int rmdirAction(const char *fileName, struct stat* statbuf)
146 {
147 if (rmdir(fileName) < 0 ) {
148 perror(fileName);
149 return FALSE;
150 }
151 return TRUE;
152 }
153
154 if ((dz = strrchr(*argv, '/')) == NULL) dz = *argv; else dz++;
155 if (*dz == 'c' && *(dz + 1) == 'p') dz_i = is_cp; else dz_i = is_mv;
156 if (argc < 3) usage(cp_mv_usage[dz_i]);
157 argc--;
158 argv++;
159
160 if (dz_i == is_cp)
161 {
162 recursiveFlag = preserveFlag = FALSE;
163 followLinks = TRUE;
164 while (**argv == '-')
165 {
166 while (*++(*argv))
167 {
168 switch (**argv)
169 {
170 case 'a':
171 followLinks = FALSE;
172 preserveFlag = TRUE;
173 recursiveFlag = TRUE;
174 break;
175 case 'd':
176 followLinks = FALSE;
177 break;
178 case 'p':
179 preserveFlag = TRUE;
180 break;
181 case 'R':
182 recursiveFlag = TRUE;
183 break;
184 default:
185 usage(cp_mv_usage[is_cp]);
186 }
187 }
188 argc--;
189 argv++;
190 }
191 }
192 else /* (dz_i == is_mv) */
193 {
194 recursiveFlag = preserveFlag = TRUE;
195 followLinks = FALSE;
196 }
197
198 if (strlen(argv[argc - 1]) > PATH_MAX)
199 {
200 fprintf(stderr, name_too_long, "cp");
201 goto exit_false;
202 }
203 strcpy(baseDestName, argv[argc - 1]);
204 baseDestLen = strlen(baseDestName);
205 if (baseDestLen == 0) goto exit_false;
206
207 destDirFlag = isDirectory(baseDestName, TRUE);
208 if ((argc > 3) && destDirFlag == FALSE)
209 {
210 fprintf(stderr, not_a_directory, "cp", baseDestName);
211 goto exit_false;
212 }
213
214 while (argc-- > 1)
215 {
216 size_t srcLen;
217 int flags_memo;
218
219 baseSrcName = *(argv++);
220
221 if ((srcLen = strlen(baseSrcName)) > PATH_MAX)
222 goto name_too_long__exit;
223
224 if (srcLen == 0) continue;
225
226 srcDirFlag = isDirectory(baseSrcName, followLinks);
227
228 if ((flags_memo = (recursiveFlag == TRUE &&
229 srcDirFlag == TRUE && destDirFlag == TRUE)))
230 {
231 fill_baseDest_buf(&baseDestName[0], &baseDestLen);
232 }
233 if (recursiveAction(baseSrcName,
234 recursiveFlag, followLinks, FALSE,
235 fileAction, fileAction)
236 == FALSE) goto exit_false;
237
238 if (dz_i == is_mv &&
239 recursiveAction(baseSrcName,
240 recursiveFlag, followLinks, TRUE,
241 rmfileAction, rmdirAction)
242 == FALSE) goto exit_false;
243
244 if (flags_memo) *(baseDestName + baseDestLen) = '\0';
245 }
246
247 exit TRUE;
248
249 name_too_long__exit:
250 fprintf(stderr, name_too_long, "cp");
251 exit_false:
252 exit FALSE;
253}
254
255// Local Variables:
256// c-file-style: "k&r"
257// c-basic-offset: 4
258// End:
diff --git a/date.c b/date.c
index 77e7c39db..a3528921d 100644
--- a/date.c
+++ b/date.c
@@ -20,6 +20,10 @@
20*/ 20*/
21 21
22#include "internal.h" 22#include "internal.h"
23#define BB_DECLARE_EXTERN
24#define bb_need_invalid_date
25#define bb_need_memory_exhausted
26#include "messages.c"
23#include <stdlib.h> 27#include <stdlib.h>
24#include <errno.h> 28#include <errno.h>
25#include <sys/time.h> 29#include <sys/time.h>
@@ -59,7 +63,7 @@ date_conv_time(struct tm *tm_time, const char *t_string) {
59 &(tm_time->tm_year)); 63 &(tm_time->tm_year));
60 64
61 if(nr < 4 || nr > 5) { 65 if(nr < 4 || nr > 5) {
62 fprintf(stderr, "date: invalid date `%s'\n", t_string); 66 fprintf(stderr, invalid_date, "date", t_string);
63 exit( FALSE); 67 exit( FALSE);
64 } 68 }
65 69
@@ -152,7 +156,7 @@ date_conv_ftime(struct tm *tm_time, const char *t_string) {
152 156
153 } 157 }
154 158
155 fprintf(stderr, "date: invalid date `%s'\n", t_string); 159 fprintf(stderr, invalid_date, "date", t_string);
156 160
157 exit( FALSE); 161 exit( FALSE);
158 162
@@ -190,7 +194,7 @@ date_main(int argc, char * * argv)
190 case 'u': 194 case 'u':
191 utc = 1; 195 utc = 1;
192 if (putenv ("TZ=UTC0") != 0) { 196 if (putenv ("TZ=UTC0") != 0) {
193 fprintf(stderr,"date: memory exhausted\n"); 197 fprintf(stderr, memory_exhausted, "date");
194 exit( FALSE); 198 exit( FALSE);
195 } 199 }
196 /* Look ma, no break. Don't fix it either. */ 200 /* Look ma, no break. Don't fix it either. */
@@ -204,10 +208,10 @@ date_main(int argc, char * * argv)
204 } 208 }
205 } else { 209 } else {
206 if ( (date_fmt == NULL) && (strcmp(*argv, "+")==0) ) 210 if ( (date_fmt == NULL) && (strcmp(*argv, "+")==0) )
207 date_fmt = *argv; 211 date_fmt=*argv;
208 else if (date_str == NULL) { 212 else if (date_str == NULL) {
209 set_time = 1; 213 set_time = 1;
210 date_str = *argv; 214 date_str=*argv;
211 } else { 215 } else {
212 usage ( date_usage); 216 usage ( date_usage);
213 } 217 }
@@ -241,7 +245,7 @@ date_main(int argc, char * * argv)
241 /* Correct any day of week and day of year etc fields */ 245 /* Correct any day of week and day of year etc fields */
242 tm = mktime(&tm_time); 246 tm = mktime(&tm_time);
243 if (tm < 0 ) { 247 if (tm < 0 ) {
244 fprintf(stderr, "date: invalid date `%s'\n", date_str); 248 fprintf(stderr, invalid_date, "date", date_str);
245 exit( FALSE); 249 exit( FALSE);
246 } 250 }
247 251
@@ -284,4 +288,3 @@ date_main(int argc, char * * argv)
284 exit( TRUE); 288 exit( TRUE);
285 289
286} 290}
287
diff --git a/dd.c b/dd.c
index bc01eedbf..3e1024a60 100644
--- a/dd.c
+++ b/dd.c
@@ -40,15 +40,16 @@ typedef unsigned long long int uintmax_t;
40#endif 40#endif
41 41
42static const char dd_usage[] = 42static const char dd_usage[] =
43"dd [if=name] [of=name] [bs=n] [count=n]\n\n" 43"dd [if=name] [of=name] [bs=n] [count=n] [skip=n] [seek=n]\n\n"
44"Copy a file, converting and formatting according to options\n\n" 44"Copy a file, converting and formatting according to options\n\n"
45"\tif=FILE\tread from FILE instead of stdin\n" 45"\tif=FILE\tread from FILE instead of stdin\n"
46"\tof=FILE\twrite to FILE instead of stout\n" 46"\tof=FILE\twrite to FILE instead of stdout\n"
47"\tbs=n\tread and write N BYTES at a time\n" 47"\tbs=n\tread and write n bytes at a time\n"
48"\tcount=n\tcopy only n input blocks\n" 48"\tcount=n\tcopy only n input blocks\n"
49//"\tskip=n\tskip n input blocks\n" 49"\tskip=n\tskip n input blocks\n"
50"\tseek=n\tskip n output blocks\n"
50"\n" 51"\n"
51"BYTES may be suffixed by w (x2), k (x1024), b (x512), or m (x1024^2).\n"; 52"Numbers may be suffixed by w (x2), k (x1024), b (x512), or M (x1024^2)\n";
52 53
53 54
54 55
@@ -61,8 +62,9 @@ extern int dd_main (int argc, char **argv)
61 int outFd; 62 int outFd;
62 int inCc = 0; 63 int inCc = 0;
63 int outCc; 64 int outCc;
64 size_t blockSize = 512; 65 long blockSize = 512;
65 //uintmax_t skipBlocks = 0; 66 uintmax_t skipBlocks = 0;
67 uintmax_t seekBlocks = 0;
66 uintmax_t count = (uintmax_t)-1; 68 uintmax_t count = (uintmax_t)-1;
67 uintmax_t intotal; 69 uintmax_t intotal;
68 uintmax_t outTotal; 70 uintmax_t outTotal;
@@ -91,16 +93,22 @@ extern int dd_main (int argc, char **argv)
91 goto usage; 93 goto usage;
92 } 94 }
93 } 95 }
94#if 0
95 else if (strncmp(*argv, "skip", 4) == 0) { 96 else if (strncmp(*argv, "skip", 4) == 0) {
96 skipBlocks = atoi( *argv); 97 skipBlocks = getNum ((strchr(*argv, '='))+1);
97 if (skipBlocks <= 0) { 98 if (skipBlocks <= 0) {
98 fprintf (stderr, "Bad skip value %d\n", skipBlocks); 99 fprintf (stderr, "Bad skip value %s\n", *argv);
100 goto usage;
101 }
102
103 }
104 else if (strncmp(*argv, "seek", 4) == 0) {
105 seekBlocks = getNum ((strchr(*argv, '='))+1);
106 if (seekBlocks <= 0) {
107 fprintf (stderr, "Bad seek value %s\n", *argv);
99 goto usage; 108 goto usage;
100 } 109 }
101 110
102 } 111 }
103#endif
104 else { 112 else {
105 goto usage; 113 goto usage;
106 } 114 }
@@ -131,7 +139,7 @@ extern int dd_main (int argc, char **argv)
131 if (outFile == NULL) 139 if (outFile == NULL)
132 outFd = fileno(stdout); 140 outFd = fileno(stdout);
133 else 141 else
134 outFd = creat (outFile, 0666); 142 outFd = open(outFile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
135 143
136 if (outFd < 0) { 144 if (outFd < 0) {
137 perror (outFile); 145 perror (outFile);
@@ -140,10 +148,11 @@ extern int dd_main (int argc, char **argv)
140 exit( FALSE); 148 exit( FALSE);
141 } 149 }
142 150
143 //lseek(inFd, skipBlocks*blockSize, SEEK_SET); 151 lseek(inFd, skipBlocks*blockSize, SEEK_SET);
152 lseek(outFd, seekBlocks*blockSize, SEEK_SET);
144 // 153 //
145 //TODO: Convert to using fullRead & fullWrite 154 //TODO: Convert to using fullRead & fullWrite
146 // from utilitity.c 155 // from utility.c
147 // -Erik 156 // -Erik
148 while (outTotal < count * blockSize) { 157 while (outTotal < count * blockSize) {
149 inCc = read (inFd, buf, blockSize); 158 inCc = read (inFd, buf, blockSize);
diff --git a/du.c b/du.c
index 79b553643..e2cf3f7c0 100644
--- a/du.c
+++ b/du.c
@@ -22,17 +22,18 @@
22 */ 22 */
23 23
24#include "internal.h" 24#include "internal.h"
25#define BB_DECLARE_EXTERN
26#define bb_need_name_too_long
27#include "messages.c"
28
25#include <sys/types.h> 29#include <sys/types.h>
26#include <fcntl.h> 30#include <fcntl.h>
27#include <dirent.h> 31#include <dirent.h>
28#include <stdio.h> 32#include <stdio.h>
29#include <errno.h> 33#include <errno.h>
30#if 0 34#include <sys/param.h> /* for PATH_MAX */
31#include <unistd.h>
32#include <sys/stat.h>
33#endif
34 35
35typedef void (Display)(size_t, char *); 36typedef void (Display)(long, char *);
36 37
37static const char du_usage[] = 38static const char du_usage[] =
38"du [OPTION]... [FILE]...\n\n" 39"du [OPTION]... [FILE]...\n\n"
@@ -44,13 +45,13 @@ static int du_depth = 0;
44static Display *print; 45static Display *print;
45 46
46static void 47static void
47print_normal(size_t size, char *filename) 48print_normal(long size, char *filename)
48{ 49{
49 fprintf(stdout, "%-7d %s\n", (size >> 1), filename); 50 fprintf(stdout, "%-7ld %s\n", size, filename);
50} 51}
51 52
52static void 53static void
53print_summary(size_t size, char *filename) 54print_summary(long size, char *filename)
54{ 55{
55 if (du_depth == 1) { 56 if (du_depth == 1) {
56 print_normal(size, filename); 57 print_normal(size, filename);
@@ -59,11 +60,11 @@ print_summary(size_t size, char *filename)
59 60
60 61
61/* tiny recursive du */ 62/* tiny recursive du */
62static size_t 63static long
63du(char *filename) 64du(char *filename)
64{ 65{
65 struct stat statbuf; 66 struct stat statbuf;
66 size_t sum; 67 long sum;
67 68
68 if ((lstat(filename, &statbuf)) != 0) { 69 if ((lstat(filename, &statbuf)) != 0) {
69 fprintf(stdout, "du: %s: %s\n", filename, strerror(errno)); 70 fprintf(stdout, "du: %s: %s\n", filename, strerror(errno));
@@ -80,14 +81,19 @@ du(char *filename)
80 dir = opendir(filename); 81 dir = opendir(filename);
81 if (!dir) { return 0; } 82 if (!dir) { return 0; }
82 while ((entry = readdir(dir))) { 83 while ((entry = readdir(dir))) {
83 char newfile[512]; 84 char newfile[PATH_MAX + 1];
84 char *name = entry->d_name; 85 char *name = entry->d_name;
85 86
86 if ( (strcmp(name, "..") == 0) 87 if ( (strcmp(name, "..") == 0)
87 || (strcmp(name, ".") == 0)) 88 || (strcmp(name, ".") == 0))
88 { continue; } 89 { continue; }
89 90
91 if (strlen(filename) + strlen(name) + 1 > PATH_MAX) {
92 fprintf(stderr, name_too_long, "du");
93 return 0;
94 }
90 sprintf(newfile, "%s/%s", filename, name); 95 sprintf(newfile, "%s/%s", filename, name);
96
91 sum += du(newfile); 97 sum += du(newfile);
92 } 98 }
93 closedir(dir); 99 closedir(dir);
@@ -130,14 +136,14 @@ du_main(int argc, char **argv)
130 if (i >= argc) { 136 if (i >= argc) {
131 du("."); 137 du(".");
132 } else { 138 } else {
133 int sum; 139 long sum;
134 for ( ; i < argc; i++) { 140 for ( ; i < argc; i++) {
135 sum = du(argv[i]); 141 sum = du(argv[i]);
136 if ((sum) && (isDirectory(argv[i]))) { print_normal(sum, argv[i]); } 142 if ((sum) && (isDirectory(argv[i], FALSE))) { print_normal(sum, argv[i]); }
137 } 143 }
138 } 144 }
139 145
140 exit(0); 146 exit(0);
141} 147}
142 148
143/* $Id: du.c,v 1.9 2000/01/23 18:19:02 erik Exp $ */ 149/* $Id: du.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */
diff --git a/fdflush.c b/fdflush.c
index 51b0c2bac..a244e8def 100644
--- a/fdflush.c
+++ b/fdflush.c
@@ -31,7 +31,7 @@ extern int fdflush_main(int argc, char **argv)
31{ 31{
32 int value; 32 int value;
33 int fd; 33 int fd;
34 if ( **(argv+1) == '-' ) { 34 if ( argc <= 1 || **(argv++) == '-' ) {
35 usage( "fdflush device\n"); 35 usage( "fdflush device\n");
36 } 36 }
37 37
diff --git a/find.c b/find.c
index 47ce21ec4..50872b7f1 100644
--- a/find.c
+++ b/find.c
@@ -90,7 +90,7 @@ int find_main(int argc, char **argv)
90 if (strcmp(*argv, "name")==0) { 90 if (strcmp(*argv, "name")==0) {
91 if (argc-- > 1) { 91 if (argc-- > 1) {
92 pattern = *(++argv); 92 pattern = *(++argv);
93 stopit=TRUE; 93 stopit = TRUE;
94 } else { 94 } else {
95 usage (find_usage); 95 usage (find_usage);
96 } 96 }
diff --git a/findutils/find.c b/findutils/find.c
index 47ce21ec4..50872b7f1 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -90,7 +90,7 @@ int find_main(int argc, char **argv)
90 if (strcmp(*argv, "name")==0) { 90 if (strcmp(*argv, "name")==0) {
91 if (argc-- > 1) { 91 if (argc-- > 1) {
92 pattern = *(++argv); 92 pattern = *(++argv);
93 stopit=TRUE; 93 stopit = TRUE;
94 } else { 94 } else {
95 usage (find_usage); 95 usage (find_usage);
96 } 96 }
diff --git a/fsck_minix.c b/fsck_minix.c
index d31de20a8..09111c5dc 100644
--- a/fsck_minix.c
+++ b/fsck_minix.c
@@ -96,6 +96,7 @@
96#include <termios.h> 96#include <termios.h>
97#include <mntent.h> 97#include <mntent.h>
98#include <sys/stat.h> 98#include <sys/stat.h>
99#include <sys/param.h> /* for PATH_MAX */
99 100
100#include <linux/fs.h> 101#include <linux/fs.h>
101#include <linux/minix_fs.h> 102#include <linux/minix_fs.h>
@@ -143,7 +144,7 @@ static int termios_set = 0;
143/* File-name data */ 144/* File-name data */
144#define MAX_DEPTH 50 145#define MAX_DEPTH 50
145static int name_depth = 0; 146static int name_depth = 0;
146static char name_list[MAX_DEPTH][NAME_MAX+1]; 147static char name_list[MAX_DEPTH][PATH_MAX + 1];
147 148
148static char * inode_buffer = NULL; 149static char * inode_buffer = NULL;
149#define Inode (((struct minix_inode *) inode_buffer)-1) 150#define Inode (((struct minix_inode *) inode_buffer)-1)
diff --git a/gunzip.c b/gunzip.c
index fddcc7653..db7fa1dfe 100644
--- a/gunzip.c
+++ b/gunzip.c
@@ -3,6 +3,9 @@
3 */ 3 */
4 4
5#include "internal.h" 5#include "internal.h"
6#define bb_need_name_too_long
7#define BB_DECLARE_EXTERN
8#include "messages.c"
6 9
7static const char gunzip_usage[] = 10static const char gunzip_usage[] =
8 "gunzip [OPTION]... FILE\n\n" 11 "gunzip [OPTION]... FILE\n\n"
@@ -64,6 +67,7 @@ static char *license_msg[] = {
64#include <signal.h> 67#include <signal.h>
65#include <sys/stat.h> 68#include <sys/stat.h>
66#include <errno.h> 69#include <errno.h>
70#include <sys/param.h> /* for PATH_MAX */
67 71
68/* #include "tailor.h" */ 72/* #include "tailor.h" */
69 73
@@ -627,8 +631,12 @@ typedef RETSIGTYPE (*sig_type) OF((int));
627#endif 631#endif
628#define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */ 632#define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */
629 633
630#ifndef MAX_PATH_LEN 634#ifndef MAX_PATH_LEN /* max pathname length */
631# define MAX_PATH_LEN 1024 /* max pathname length */ 635# ifdef PATH_MAX
636# define MAX_PATH_LEN PATH_MAX
637# else
638# define MAX_PATH_LEN 1024
639# endif
632#endif 640#endif
633 641
634#ifndef SEEK_END 642#ifndef SEEK_END
@@ -696,8 +704,8 @@ int gunzip_main (int argc, char** argv)
696 int delInputFile=0; 704 int delInputFile=0;
697 struct stat statBuf; 705 struct stat statBuf;
698 char* delFileName; 706 char* delFileName;
699 char ifname[MAX_PATH_LEN]; /* input file name */ 707 char ifname[MAX_PATH_LEN + 1]; /* input file name */
700 char ofname[MAX_PATH_LEN]; /* output file name */ 708 char ofname[MAX_PATH_LEN + 1]; /* output file name */
701 709
702 if (argc==1) 710 if (argc==1)
703 usage(gunzip_usage); 711 usage(gunzip_usage);
@@ -764,7 +772,11 @@ int gunzip_main (int argc, char** argv)
764 /* Open up the input file */ 772 /* Open up the input file */
765 if (*argv=='\0') 773 if (*argv=='\0')
766 usage(gunzip_usage); 774 usage(gunzip_usage);
767 strncpy(ifname, *argv, MAX_PATH_LEN); 775 if (strlen(*argv) > MAX_PATH_LEN) {
776 fprintf(stderr, name_too_long, "gunzip");
777 do_exit(WARNING);
778 }
779 strcpy(ifname, *argv);
768 780
769 /* Open input fille */ 781 /* Open input fille */
770 inFileNum=open( ifname, O_RDONLY); 782 inFileNum=open( ifname, O_RDONLY);
@@ -799,7 +811,11 @@ int gunzip_main (int argc, char** argv)
799 char* pos; 811 char* pos;
800 812
801 /* And get to work */ 813 /* And get to work */
802 strncpy(ofname, ifname, MAX_PATH_LEN-4); 814 if (strlen(ifname) > MAX_PATH_LEN - 4) {
815 fprintf(stderr, name_too_long, "gunzip");
816 do_exit(WARNING);
817 }
818 strcpy(ofname, ifname);
803 pos=strstr(ofname, ".gz"); 819 pos=strstr(ofname, ".gz");
804 if (pos != NULL) { 820 if (pos != NULL) {
805 *pos='\0'; 821 *pos='\0';
diff --git a/head.c b/head.c
index bc7f35429..b80d06580 100644
--- a/head.c
+++ b/head.c
@@ -105,4 +105,4 @@ head_main(int argc, char **argv)
105 exit(0); 105 exit(0);
106} 106}
107 107
108/* $Id: head.c,v 1.6 2000/01/25 18:13:53 erik Exp $ */ 108/* $Id: head.c,v 1.7 2000/02/07 05:29:42 erik Exp $ */
diff --git a/hostname.c b/hostname.c
index 20e174187..68a560950 100644
--- a/hostname.c
+++ b/hostname.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: hostname.c,v 1.5 1999/12/09 06:11:36 andersen Exp $ 2 * $Id: hostname.c,v 1.6 2000/02/07 05:29:42 erik Exp $
3 * Mini hostname implementation for busybox 3 * Mini hostname implementation for busybox
4 * 4 *
5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> 5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
diff --git a/init.c b/init.c
index d88b64ba2..2b1d21336 100644
--- a/init.c
+++ b/init.c
@@ -40,6 +40,7 @@
40#include <sys/reboot.h> 40#include <sys/reboot.h>
41#include <sys/kdaemon.h> 41#include <sys/kdaemon.h>
42#include <sys/sysmacros.h> 42#include <sys/sysmacros.h>
43#include <asm/types.h>
43#include <linux/serial.h> /* for serial_struct */ 44#include <linux/serial.h> /* for serial_struct */
44#include <sys/vt.h> /* for vt_stat */ 45#include <sys/vt.h> /* for vt_stat */
45#include <sys/ioctl.h> 46#include <sys/ioctl.h>
@@ -123,7 +124,7 @@ int device_open(char *device, int mode)
123 124
124 /* Retry up to 5 times */ 125 /* Retry up to 5 times */
125 for (f = 0; f < 5; f++) 126 for (f = 0; f < 5; f++)
126 if ((fd = open(device, m)) >= 0) 127 if ((fd = open(device, m, 0600)) >= 0)
127 break; 128 break;
128 if (fd < 0) 129 if (fd < 0)
129 return fd; 130 return fd;
@@ -470,19 +471,19 @@ static void shutdown_system(void)
470 sync(); 471 sync();
471 472
472 /* Send signals to every process _except_ pid 1 */ 473 /* Send signals to every process _except_ pid 1 */
473 message(CONSOLE, "Sending SIGHUP to all processes.\r\n"); 474 message(CONSOLE, "Sending SIGTERM to all processes.\r\n");
474 kill(-1, SIGHUP); 475 kill(-1, SIGTERM);
475 sleep(2); 476 sleep(5);
476 sync(); 477 sync();
477 478
478 message(CONSOLE, "Sending SIGKILL to all processes.\r\n"); 479 message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
479 kill(-1, SIGKILL); 480 kill(-1, SIGKILL);
480 sleep(1); 481 sleep(5);
481 482
482 message(CONSOLE, "Disabling swap.\r\n"); 483 message(CONSOLE, "Disabling swap.\r\n");
483 waitfor( "swapoff -a", console, FALSE); 484 waitfor( "swapoff -a", console, FALSE);
484 message(CONSOLE, "Unmounting filesystems.\r\n"); 485 message(CONSOLE, "Unmounting filesystems.\r\n");
485 waitfor("umount -a", console, FALSE); 486 waitfor("umount -a -r", console, FALSE);
486 sync(); 487 sync();
487 if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) { 488 if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) {
488 /* bdflush, kupdate not needed for kernels >2.2.11 */ 489 /* bdflush, kupdate not needed for kernels >2.2.11 */
@@ -500,7 +501,7 @@ static void halt_signal(int sig)
500 sync(); 501 sync();
501 502
502 /* allow time for last message to reach serial console */ 503 /* allow time for last message to reach serial console */
503 sleep(2); 504 sleep(5);
504 505
505#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) 506#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
506 if (sig == SIGUSR2) 507 if (sig == SIGUSR2)
diff --git a/init/init.c b/init/init.c
index d88b64ba2..2b1d21336 100644
--- a/init/init.c
+++ b/init/init.c
@@ -40,6 +40,7 @@
40#include <sys/reboot.h> 40#include <sys/reboot.h>
41#include <sys/kdaemon.h> 41#include <sys/kdaemon.h>
42#include <sys/sysmacros.h> 42#include <sys/sysmacros.h>
43#include <asm/types.h>
43#include <linux/serial.h> /* for serial_struct */ 44#include <linux/serial.h> /* for serial_struct */
44#include <sys/vt.h> /* for vt_stat */ 45#include <sys/vt.h> /* for vt_stat */
45#include <sys/ioctl.h> 46#include <sys/ioctl.h>
@@ -123,7 +124,7 @@ int device_open(char *device, int mode)
123 124
124 /* Retry up to 5 times */ 125 /* Retry up to 5 times */
125 for (f = 0; f < 5; f++) 126 for (f = 0; f < 5; f++)
126 if ((fd = open(device, m)) >= 0) 127 if ((fd = open(device, m, 0600)) >= 0)
127 break; 128 break;
128 if (fd < 0) 129 if (fd < 0)
129 return fd; 130 return fd;
@@ -470,19 +471,19 @@ static void shutdown_system(void)
470 sync(); 471 sync();
471 472
472 /* Send signals to every process _except_ pid 1 */ 473 /* Send signals to every process _except_ pid 1 */
473 message(CONSOLE, "Sending SIGHUP to all processes.\r\n"); 474 message(CONSOLE, "Sending SIGTERM to all processes.\r\n");
474 kill(-1, SIGHUP); 475 kill(-1, SIGTERM);
475 sleep(2); 476 sleep(5);
476 sync(); 477 sync();
477 478
478 message(CONSOLE, "Sending SIGKILL to all processes.\r\n"); 479 message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
479 kill(-1, SIGKILL); 480 kill(-1, SIGKILL);
480 sleep(1); 481 sleep(5);
481 482
482 message(CONSOLE, "Disabling swap.\r\n"); 483 message(CONSOLE, "Disabling swap.\r\n");
483 waitfor( "swapoff -a", console, FALSE); 484 waitfor( "swapoff -a", console, FALSE);
484 message(CONSOLE, "Unmounting filesystems.\r\n"); 485 message(CONSOLE, "Unmounting filesystems.\r\n");
485 waitfor("umount -a", console, FALSE); 486 waitfor("umount -a -r", console, FALSE);
486 sync(); 487 sync();
487 if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) { 488 if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) {
488 /* bdflush, kupdate not needed for kernels >2.2.11 */ 489 /* bdflush, kupdate not needed for kernels >2.2.11 */
@@ -500,7 +501,7 @@ static void halt_signal(int sig)
500 sync(); 501 sync();
501 502
502 /* allow time for last message to reach serial console */ 503 /* allow time for last message to reach serial console */
503 sleep(2); 504 sleep(5);
504 505
505#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) 506#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
506 if (sig == SIGUSR2) 507 if (sig == SIGUSR2)
diff --git a/insmod.c b/insmod.c
index 9cb635f40..31cb11261 100644
--- a/insmod.c
+++ b/insmod.c
@@ -67,8 +67,8 @@ _syscall2(unsigned long, create_module, const char *, name, size_t, size)
67#endif 67#endif
68 68
69 69
70static char m_filename[PATH_MAX] = "\0"; 70static char m_filename[PATH_MAX + 1] = "\0";
71static char m_fullName[PATH_MAX] ="\0"; 71static char m_fullName[PATH_MAX + 1] = "\0";
72static const char insmod_usage[] = 72static const char insmod_usage[] =
73 "insmod [OPTION]... MODULE [symbol=value]...\n\n" 73 "insmod [OPTION]... MODULE [symbol=value]...\n\n"
74 "Loads the specified kernel modules into the kernel.\n\n" 74 "Loads the specified kernel modules into the kernel.\n\n"
@@ -101,7 +101,7 @@ extern int insmod_main(int argc, char **argv)
101{ 101{
102 int len; 102 int len;
103 char *tmp; 103 char *tmp;
104 char m_name[PATH_MAX] ="\0"; 104 char m_name[PATH_MAX + 1] ="\0";
105 FILE *fp; 105 FILE *fp;
106 106
107 if (argc<=1) { 107 if (argc<=1) {
diff --git a/internal.h b/internal.h
index 1686054a8..79e6a039a 100644
--- a/internal.h
+++ b/internal.h
@@ -1,3 +1,4 @@
1
1/* 2/*
2 * Busybox main internal header file 3 * Busybox main internal header file
3 * 4 *
@@ -20,8 +21,8 @@
20 * Permission has been granted to redistribute this code under the GPL. 21 * Permission has been granted to redistribute this code under the GPL.
21 * 22 *
22 */ 23 */
23#ifndef _INTERNAL_H_ 24#ifndef _BB_INTERNAL_H_
24#define _INTERNAL_H_ 25#define _BB_INTERNAL_H_ 1
25 26
26#include "busybox.def.h" 27#include "busybox.def.h"
27 28
@@ -37,7 +38,10 @@
37#define FALSE ((int) 1) 38#define FALSE ((int) 1)
38#define TRUE ((int) 0) 39#define TRUE ((int) 0)
39 40
40#define PATH_LEN 1024 41/* for mtab.c */
42#define MTAB_GETMOUNTPT '1'
43#define MTAB_GETDEVICE '2'
44
41#define BUF_SIZE 8192 45#define BUF_SIZE 8192
42#define EXPAND_ALLOC 1024 46#define EXPAND_ALLOC 1024
43 47
@@ -55,7 +59,7 @@ struct Applet {
55extern int busybox_main(int argc, char** argv); 59extern int busybox_main(int argc, char** argv);
56extern int block_device_main(int argc, char** argv); 60extern int block_device_main(int argc, char** argv);
57extern int cat_main(int argc, char** argv); 61extern int cat_main(int argc, char** argv);
58extern int cp_main(int argc, char** argv); 62extern int cp_mv_main(int argc, char** argv);
59extern int chmod_chown_chgrp_main(int argc, char** argv); 63extern int chmod_chown_chgrp_main(int argc, char** argv);
60extern int chroot_main(int argc, char** argv); 64extern int chroot_main(int argc, char** argv);
61extern int chvt_main(int argc, char** argv); 65extern int chvt_main(int argc, char** argv);
@@ -105,8 +109,7 @@ extern int mnc_main(int argc, char** argv);
105extern int more_main(int argc, char** argv); 109extern int more_main(int argc, char** argv);
106extern int mount_main(int argc, char** argv); 110extern int mount_main(int argc, char** argv);
107extern int mt_main(int argc, char** argv); 111extern int mt_main(int argc, char** argv);
108extern int mv_main(int argc, char** argv); 112extern int nslookup_main(int argc, char **argv);
109extern int nslookup_main(int argc, char** argv);
110extern int ping_main(int argc, char **argv); 113extern int ping_main(int argc, char **argv);
111extern int poweroff_main(int argc, char **argv); 114extern int poweroff_main(int argc, char **argv);
112extern int printf_main(int argc, char** argv); 115extern int printf_main(int argc, char** argv);
@@ -142,7 +145,7 @@ extern int yes_main(int argc, char** argv);
142 145
143const char *modeString(int mode); 146const char *modeString(int mode);
144const char *timeString(time_t timeVal); 147const char *timeString(time_t timeVal);
145int isDirectory(const char *name); 148int isDirectory(const char *name, const int followLinks);
146int isDevice(const char *name); 149int isDevice(const char *name);
147int copyFile(const char *srcName, const char *destName, int setModes, 150int copyFile(const char *srcName, const char *destName, int setModes,
148 int followLinks); 151 int followLinks);
@@ -172,6 +175,11 @@ extern struct mntent *findMountPoint(const char *name, const char *table);
172extern void write_mtab(char* blockDevice, char* directory, 175extern void write_mtab(char* blockDevice, char* directory,
173 char* filesystemType, long flags, char* string_flags); 176 char* filesystemType, long flags, char* string_flags);
174extern void erase_mtab(const char * name); 177extern void erase_mtab(const char * name);
178extern void mtab_read(void);
179extern void mtab_free(void);
180extern char *mtab_first(void **iter);
181extern char *mtab_next(void **iter);
182extern char *mtab_getinfo(const char *match, const char which);
175extern int check_wildcard_match(const char* text, const char* pattern); 183extern int check_wildcard_match(const char* text, const char* pattern);
176extern long getNum (const char *cp); 184extern long getNum (const char *cp);
177extern pid_t findInitPid(); 185extern pid_t findInitPid();
@@ -226,5 +234,4 @@ static inline int clrbit(char * addr,unsigned int nr)
226#endif 234#endif
227 235
228 236
229#endif /* _INTERNAL_H_ */ 237#endif /* _BB_INTERNAL_H_ */
230
diff --git a/length.c b/length.c
index 46242b529..2c83cdfd2 100644
--- a/length.c
+++ b/length.c
@@ -6,7 +6,7 @@
6extern int 6extern int
7length_main(int argc, char * * argv) 7length_main(int argc, char * * argv)
8{ 8{
9 if ( **(argv+1) == '-' ) { 9 if ( argc != 2 || **(argv+1) == '-' ) {
10 usage("length string\n"); 10 usage("length string\n");
11 } 11 }
12 printf("%d\n", strlen(argv[1])); 12 printf("%d\n", strlen(argv[1]));
diff --git a/ln.c b/ln.c
index 60fe39438..f20b340ea 100644
--- a/ln.c
+++ b/ln.c
@@ -22,26 +22,32 @@
22 */ 22 */
23 23
24#include "internal.h" 24#include "internal.h"
25#define BB_DECLARE_EXTERN
26#define bb_need_name_too_long
27#define bb_need_not_a_directory
28#include "messages.c"
29
25#include <stdio.h> 30#include <stdio.h>
26#include <dirent.h> 31#include <dirent.h>
27#include <errno.h> 32#include <errno.h>
33#include <sys/param.h> /* for PATH_MAX */
28 34
29 35static const char ln_usage[] =
30static const char ln_usage[] = "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n" 36 "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n"
31"Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n" 37 "Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n"
32"Options:\n" 38 "Options:\n"
33"\t-s\tmake symbolic links instead of hard links\n" 39 "\t-s\tmake symbolic links instead of hard links\n"
34"\t-f\tremove existing destination files\n"; 40 "\t-f\tremove existing destination files\n"
35 41 "\t-n\tno dereference symlinks - treat like normal file\n";
36 42
37static int symlinkFlag = FALSE; 43static int symlinkFlag = FALSE;
38static int removeoldFlag = FALSE; 44static int removeoldFlag = FALSE;
39 45static int followLinks = TRUE;
40 46
41extern int ln_main(int argc, char **argv) 47extern int ln_main(int argc, char **argv)
42{ 48{
43 int status; 49 char *linkName;
44 static char* linkName; 50 int linkIntoDirFlag;
45 51
46 if (argc < 3) { 52 if (argc < 3) {
47 usage (ln_usage); 53 usage (ln_usage);
@@ -59,6 +65,9 @@ extern int ln_main(int argc, char **argv)
59 case 'f': 65 case 'f':
60 removeoldFlag = TRUE; 66 removeoldFlag = TRUE;
61 break; 67 break;
68 case 'n':
69 followLinks = FALSE;
70 break;
62 default: 71 default:
63 usage (ln_usage); 72 usage (ln_usage);
64 } 73 }
@@ -66,30 +75,54 @@ extern int ln_main(int argc, char **argv)
66 argv++; 75 argv++;
67 } 76 }
68 77
69
70 linkName = argv[argc - 1]; 78 linkName = argv[argc - 1];
71 79
72 if ((argc > 3) && !(isDirectory(linkName))) { 80 if (strlen(linkName) > PATH_MAX) {
73 fprintf(stderr, "%s: not a directory\n", linkName); 81 fprintf(stderr, name_too_long, "ln");
74 exit (FALSE); 82 exit FALSE;
83 }
84
85 linkIntoDirFlag = isDirectory(linkName, TRUE);
86
87 if ((argc > 3) && !linkIntoDirFlag) {
88 fprintf(stderr, not_a_directory, "ln", linkName);
89 exit FALSE;
75 } 90 }
76 91
77 while (argc-- >= 2) { 92 while (argc-- >= 2) {
78 if (removeoldFlag==TRUE ) { 93 char srcName[PATH_MAX + 1];
94 int nChars, status;
95
96 if (strlen(*argv) > PATH_MAX) {
97 fprintf(stderr, name_too_long, "ln");
98 exit FALSE;
99 }
100
101 if (followLinks == FALSE) {
102 strcpy(srcName, *argv);
103 } else {
104 /* Warning! This can silently truncate if > PATH_MAX, but
105 I don't think that there can be one > PATH_MAX anyway. */
106 nChars = readlink(*argv, srcName, PATH_MAX);
107 srcName[nChars] = '\0';
108 }
109
110 if (removeoldFlag == TRUE) {
79 status = ( unlink(linkName) && errno != ENOENT ); 111 status = ( unlink(linkName) && errno != ENOENT );
80 if ( status != 0 ) { 112 if (status != 0) {
81 perror(linkName); 113 perror(linkName);
82 exit( FALSE); 114 exit FALSE;
83 } 115 }
84 } 116 }
85 if ( symlinkFlag==TRUE) 117
86 status = symlink(*argv, linkName); 118 if (symlinkFlag == TRUE)
119 status = symlink(*argv, linkName);
87 else 120 else
88 status = link(*argv, linkName); 121 status = link(*argv, linkName);
89 if ( status != 0 ) { 122 if (status != 0) {
90 perror(linkName); 123 perror(linkName);
91 exit( FALSE); 124 exit FALSE;
92 } 125 }
93 } 126 }
94 exit( TRUE); 127 exit TRUE;
95} 128}
diff --git a/ls.c b/ls.c
index 78193e7c1..450ea1814 100644
--- a/ls.c
+++ b/ls.c
@@ -178,7 +178,7 @@ static char append_char(mode_t mode)
178 178
179static void list_single(const char *name, struct stat *info, const char *fullname) 179static void list_single(const char *name, struct stat *info, const char *fullname)
180{ 180{
181 char scratch[PATH_MAX]; 181 char scratch[PATH_MAX + 1];
182 short len = strlen(name); 182 short len = strlen(name);
183#ifdef BB_FEATURE_LS_FILETYPES 183#ifdef BB_FEATURE_LS_FILETYPES
184 char append = append_char(info->st_mode); 184 char append = append_char(info->st_mode);
diff --git a/messages.c b/messages.c
new file mode 100644
index 000000000..bfbf3175b
--- /dev/null
+++ b/messages.c
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 2000 by BitterSweet Enterprises, LLC.
3 * Written by Karl M. Hegbloom <karlheg@debian.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21/*
22 * Let's put all of these messages in one place, and link this in as
23 * a separate object module, so that there are not going to be
24 * multiple non-unique but very similar strings in the binary.
25 * Perhaps this will make it simpler to internationalize also, and
26 * may make the binary slightly smaller.
27 */
28#ifndef _BB_MESSAGES_C
29#define _BB_MESSAGES_C
30
31#define _BB_DEF_MESSAGE_PROTO(symbol) extern const char *symbol;
32#define _BB_DEF_MESSAGE_INITIALIZE(symbol, string_const) const char *symbol = string_const;
33
34#ifdef BB_DECLARE_EXTERN
35# define BB_DEF_MESSAGE(symbol, string_const) _BB_DEF_MESSAGE_PROTO(symbol)
36#else
37# define BB_DEF_MESSAGE(symbol, string_const) _BB_DEF_MESSAGE_INITIALIZE(symbol, string_const)
38#endif
39
40#if defined bb_need_name_too_long || ! defined BB_DECLARE_EXTERN
41BB_DEF_MESSAGE(name_too_long, "%s: file name too long\n")
42#endif
43
44#if defined bb_need_omitting_directory || ! defined BB_DECLARE_EXTERN
45BB_DEF_MESSAGE(omitting_directory, "%s: %s: omitting directory\n")
46#endif
47
48#if defined bb_need_not_a_directory || ! defined BB_DECLARE_EXTERN
49BB_DEF_MESSAGE(not_a_directory, "%s: %s: not a directory\n")
50#endif
51
52#if defined bb_need_memory_exhausted || ! defined BB_DECLARE_EXTERN
53BB_DEF_MESSAGE(memory_exhausted, "%s: memory exhausted\n")
54#endif
55
56#if defined bb_need_invalid_date || ! defined BB_DECLARE_EXTERN
57BB_DEF_MESSAGE(invalid_date, "%s: invalid date `%s'\n")
58#endif
59
60#if defined bb_need_invalid_option || ! defined BB_DECLARE_EXTERN
61BB_DEF_MESSAGE(invalid_option, "%s: invalid option -- %c\n")
62#endif
63
64#endif /* _BB_MESSAGES_C */
diff --git a/mkdir.c b/mkdir.c
index 017ef9b08..8e3f51bfb 100644
--- a/mkdir.c
+++ b/mkdir.c
@@ -22,9 +22,13 @@
22 */ 22 */
23 23
24#include "internal.h" 24#include "internal.h"
25#define bb_need_name_too_long
26#define BB_DECLARE_EXTERN
27#include "messages.c"
28
25#include <stdio.h> 29#include <stdio.h>
26#include <errno.h> 30#include <errno.h>
27#include <sys/param.h> 31#include <sys/param.h> /* for PATH_MAX */
28 32
29static const char mkdir_usage[] = 33static const char mkdir_usage[] =
30"mkdir [OPTION] DIRECTORY...\n\n" 34"mkdir [OPTION] DIRECTORY...\n\n"
@@ -40,27 +44,27 @@ static mode_t mode = 0777;
40 44
41extern int mkdir_main(int argc, char **argv) 45extern int mkdir_main(int argc, char **argv)
42{ 46{
43 int i=FALSE; 47 int i = FALSE;
44 argc--; 48 argc--;
45 argv++; 49 argv++;
46 50
47 /* Parse any options */ 51 /* Parse any options */
48 while (argc > 0 && **argv == '-') { 52 while (argc > 0 && **argv == '-') {
49 while (i==FALSE && *++(*argv)) { 53 while (i == FALSE && *++(*argv)) {
50 switch (**argv) { 54 switch (**argv) {
51 case 'm': 55 case 'm':
52 if (--argc == 0) 56 if (--argc == 0)
53 usage( mkdir_usage); 57 usage( mkdir_usage);
54 /* Find the specified modes */ 58 /* Find the specified modes */
55 mode = 0; 59 mode = 0;
56 if ( parse_mode(*(++argv), &mode) == FALSE ) { 60 if (parse_mode(*(++argv), &mode) == FALSE ) {
57 fprintf(stderr, "Unknown mode: %s\n", *argv); 61 fprintf(stderr, "Unknown mode: %s\n", *argv);
58 exit( FALSE); 62 exit FALSE;
59 } 63 }
60 /* Set the umask for this process so it doesn't 64 /* Set the umask for this process so it doesn't
61 * screw up whatever the user just entered. */ 65 * screw up whatever the user just entered. */
62 umask(0); 66 umask(0);
63 i=TRUE; 67 i = TRUE;
64 break; 68 break;
65 case 'p': 69 case 'p':
66 parentFlag = TRUE; 70 parentFlag = TRUE;
@@ -73,7 +77,6 @@ extern int mkdir_main(int argc, char **argv)
73 argv++; 77 argv++;
74 } 78 }
75 79
76
77 if (argc < 1) { 80 if (argc < 1) {
78 usage( mkdir_usage); 81 usage( mkdir_usage);
79 } 82 }
@@ -81,13 +84,16 @@ extern int mkdir_main(int argc, char **argv)
81 while (argc > 0) { 84 while (argc > 0) {
82 int status; 85 int status;
83 struct stat statBuf; 86 struct stat statBuf;
84 char buf[NAME_MAX]; 87 char buf[PATH_MAX + 1];
85 88 if (strlen(*argv) > PATH_MAX - 1) {
89 fprintf(stderr, name_too_long, "mkdir");
90 exit FALSE;
91 }
86 strcpy (buf, *argv); 92 strcpy (buf, *argv);
87 status=stat(buf, &statBuf); 93 status = stat(buf, &statBuf);
88 if (parentFlag == FALSE && status != -1 && status != ENOENT ) { 94 if (parentFlag == FALSE && status != -1 && errno != ENOENT) {
89 fprintf(stderr, "%s: File exists\n", buf); 95 fprintf(stderr, "%s: File exists\n", buf);
90 exit( FALSE); 96 exit FALSE;
91 } 97 }
92 if (parentFlag == TRUE) { 98 if (parentFlag == TRUE) {
93 strcat( buf, "/"); 99 strcat( buf, "/");
@@ -96,13 +102,13 @@ extern int mkdir_main(int argc, char **argv)
96 else { 102 else {
97 if (mkdir (buf, mode) != 0 && parentFlag == FALSE) { 103 if (mkdir (buf, mode) != 0 && parentFlag == FALSE) {
98 perror(buf); 104 perror(buf);
99 exit( FALSE); 105 exit FALSE;
100 } 106 }
101 } 107 }
102 argc--; 108 argc--;
103 argv++; 109 argv++;
104 } 110 }
105 exit( TRUE); 111 exit TRUE;
106} 112}
107 113
108 114
diff --git a/modutils/insmod.c b/modutils/insmod.c
index 9cb635f40..31cb11261 100644
--- a/modutils/insmod.c
+++ b/modutils/insmod.c
@@ -67,8 +67,8 @@ _syscall2(unsigned long, create_module, const char *, name, size_t, size)
67#endif 67#endif
68 68
69 69
70static char m_filename[PATH_MAX] = "\0"; 70static char m_filename[PATH_MAX + 1] = "\0";
71static char m_fullName[PATH_MAX] ="\0"; 71static char m_fullName[PATH_MAX + 1] = "\0";
72static const char insmod_usage[] = 72static const char insmod_usage[] =
73 "insmod [OPTION]... MODULE [symbol=value]...\n\n" 73 "insmod [OPTION]... MODULE [symbol=value]...\n\n"
74 "Loads the specified kernel modules into the kernel.\n\n" 74 "Loads the specified kernel modules into the kernel.\n\n"
@@ -101,7 +101,7 @@ extern int insmod_main(int argc, char **argv)
101{ 101{
102 int len; 102 int len;
103 char *tmp; 103 char *tmp;
104 char m_name[PATH_MAX] ="\0"; 104 char m_name[PATH_MAX + 1] ="\0";
105 FILE *fp; 105 FILE *fp;
106 106
107 if (argc<=1) { 107 if (argc<=1) {
diff --git a/mtab.c b/mtab.c
index 98e42a383..41d88184b 100644
--- a/mtab.c
+++ b/mtab.c
@@ -5,21 +5,13 @@
5#include <string.h> 5#include <string.h>
6#include <stdio.h> 6#include <stdio.h>
7#include <mntent.h> 7#include <mntent.h>
8#include <fstab.h>
8#include <sys/mount.h> 9#include <sys/mount.h>
9 10
10extern const char mtab_file[]; /* Defined in utility.c */ 11extern const char mtab_file[]; /* Defined in utility.c */
11 12
12static char *
13stralloc(const char * string)
14{
15 int length = strlen(string) + 1;
16 char * n = malloc(length);
17 memcpy(n, string, length);
18 return n;
19}
20 13
21extern void 14void erase_mtab(const char * name)
22erase_mtab(const char * name)
23{ 15{
24 struct mntent entries[20]; 16 struct mntent entries[20];
25 int count = 0; 17 int count = 0;
@@ -39,10 +31,10 @@ erase_mtab(const char * name)
39 } 31 }
40 32
41 while ( (m = getmntent(mountTable)) != 0 ) { 33 while ( (m = getmntent(mountTable)) != 0 ) {
42 entries[count].mnt_fsname = stralloc(m->mnt_fsname); 34 entries[count].mnt_fsname = strdup(m->mnt_fsname);
43 entries[count].mnt_dir = stralloc(m->mnt_dir); 35 entries[count].mnt_dir = strdup(m->mnt_dir);
44 entries[count].mnt_type = stralloc(m->mnt_type); 36 entries[count].mnt_type = strdup(m->mnt_type);
45 entries[count].mnt_opts = stralloc(m->mnt_opts); 37 entries[count].mnt_opts = strdup(m->mnt_opts);
46 entries[count].mnt_freq = m->mnt_freq; 38 entries[count].mnt_freq = m->mnt_freq;
47 entries[count].mnt_passno = m->mnt_passno; 39 entries[count].mnt_passno = m->mnt_passno;
48 count++; 40 count++;
@@ -65,8 +57,7 @@ erase_mtab(const char * name)
65 perror(mtab_file); 57 perror(mtab_file);
66} 58}
67 59
68extern void 60void write_mtab(char* blockDevice, char* directory,
69write_mtab(char* blockDevice, char* directory,
70 char* filesystemType, long flags, char* string_flags) 61 char* filesystemType, long flags, char* string_flags)
71{ 62{
72 FILE *mountTable = setmntent(mtab_file, "a+"); 63 FILE *mountTable = setmntent(mtab_file, "a+");
@@ -110,4 +101,3 @@ write_mtab(char* blockDevice, char* directory,
110 } 101 }
111} 102}
112 103
113
diff --git a/mv.c b/mv.c
deleted file mode 100644
index 467a360de..000000000
--- a/mv.c
+++ /dev/null
@@ -1,112 +0,0 @@
1/*
2 * Mini mv implementation for busybox
3 *
4 *
5 * Copyright (C) 1999 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include "internal.h"
25#include <stdio.h>
26#include <time.h>
27#include <utime.h>
28#include <dirent.h>
29
30static const char mv_usage[] = "mv SOURCE DEST\n"
31" or: mv SOURCE... DIRECTORY\n\n"
32"Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n";
33
34
35static const char *srcName;
36static const char *destName;
37static int destDirFlag = FALSE;
38static int srcDirFlag = FALSE;
39
40static int fileAction(const char *fileName, struct stat* statbuf)
41{
42 char newdestName[NAME_MAX];
43 char* newsrcName = NULL;
44
45 strcpy(newdestName, destName);
46 if ( srcDirFlag == TRUE ) {
47 strcat(newdestName, strstr(fileName, srcName) + strlen(srcName));
48 }
49
50 if (destDirFlag==TRUE && srcDirFlag == FALSE) {
51 if (newdestName[strlen(newdestName)-1] != '/' ) {
52 strcat(newdestName, "/");
53 }
54 newsrcName = strrchr(srcName, '/');
55 if (newsrcName && *newsrcName != '\0')
56 strcat(newdestName, newsrcName);
57 else
58 strcat(newdestName, srcName);
59 }
60
61 return (copyFile(fileName, newdestName, TRUE, TRUE));
62}
63
64static int rmfileAction(const char *fileName, struct stat* statbuf)
65{
66 if (unlink( fileName) < 0 ) {
67 perror( fileName);
68 return ( FALSE);
69 }
70 return ( TRUE);
71}
72
73static int rmdirAction(const char *fileName, struct stat* statbuf)
74{
75 if (rmdir( fileName) < 0 ) {
76 perror( fileName);
77 return ( FALSE);
78 }
79 return ( TRUE);
80}
81
82
83extern int mv_main(int argc, char **argv)
84{
85 if (argc < 3) {
86 usage (mv_usage);
87 }
88 argc--;
89 argv++;
90
91 destName = argv[argc - 1];
92 destDirFlag = isDirectory(destName);
93
94 if ((argc > 3) && destDirFlag==FALSE) {
95 fprintf(stderr, "%s: not a directory\n", destName);
96 exit (FALSE);
97 }
98
99 while (argc-- > 1) {
100 srcName = *(argv++);
101 srcDirFlag = isDirectory(srcName);
102 if (recursiveAction(srcName, TRUE, TRUE, FALSE,
103 fileAction, fileAction) == FALSE) {
104 exit( FALSE);
105 }
106 if (recursiveAction(srcName, TRUE, TRUE, TRUE,
107 rmfileAction, rmdirAction) == FALSE) {
108 exit( FALSE);
109 }
110 }
111 exit( TRUE);
112}
diff --git a/networking/hostname.c b/networking/hostname.c
index 20e174187..68a560950 100644
--- a/networking/hostname.c
+++ b/networking/hostname.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: hostname.c,v 1.5 1999/12/09 06:11:36 andersen Exp $ 2 * $Id: hostname.c,v 1.6 2000/02/07 05:29:42 erik Exp $
3 * Mini hostname implementation for busybox 3 * Mini hostname implementation for busybox
4 * 4 *
5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> 5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
diff --git a/networking/nslookup.c b/networking/nslookup.c
index 82d3b3690..969d0b19b 100644
--- a/networking/nslookup.c
+++ b/networking/nslookup.c
@@ -185,4 +185,4 @@ nslookup_main(int argc, char **argv)
185 return 0; 185 return 0;
186} 186}
187 187
188/* $Id: nslookup.c,v 1.2 2000/01/30 09:47:16 beppu Exp $ */ 188/* $Id: nslookup.c,v 1.3 2000/02/07 05:29:42 erik Exp $ */
diff --git a/networking/ping.c b/networking/ping.c
index 5b680195a..3ffbdc553 100644
--- a/networking/ping.c
+++ b/networking/ping.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ping.c,v 1.9 2000/01/29 06:29:32 erik Exp $ 2 * $Id: ping.c,v 1.10 2000/02/07 05:29:42 erik Exp $
3 * Mini ping implementation for busybox 3 * Mini ping implementation for busybox
4 * 4 *
5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> 5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
@@ -175,7 +175,8 @@ extern int ping_main(int argc, char **argv)
175static const char* ping_usage = "ping [OPTION]... host\n\n" 175static const char* ping_usage = "ping [OPTION]... host\n\n"
176"Send ICMP ECHO_REQUEST packets to network hosts.\n\n" 176"Send ICMP ECHO_REQUEST packets to network hosts.\n\n"
177"Options:\n" 177"Options:\n"
178"\t-q\t\tQuiet mode, only displays output at start and when finished.\n" 178"\t-q\t\tQuiet mode, only displays output at start"
179"\t\t\tand when finished.\n"
179"\t-c COUNT\tSend only COUNT pings.\n"; 180"\t-c COUNT\tSend only COUNT pings.\n";
180 181
181static char *hostname = NULL; 182static char *hostname = NULL;
diff --git a/nslookup.c b/nslookup.c
index 82d3b3690..969d0b19b 100644
--- a/nslookup.c
+++ b/nslookup.c
@@ -185,4 +185,4 @@ nslookup_main(int argc, char **argv)
185 return 0; 185 return 0;
186} 186}
187 187
188/* $Id: nslookup.c,v 1.2 2000/01/30 09:47:16 beppu Exp $ */ 188/* $Id: nslookup.c,v 1.3 2000/02/07 05:29:42 erik Exp $ */
diff --git a/ping.c b/ping.c
index 5b680195a..3ffbdc553 100644
--- a/ping.c
+++ b/ping.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ping.c,v 1.9 2000/01/29 06:29:32 erik Exp $ 2 * $Id: ping.c,v 1.10 2000/02/07 05:29:42 erik Exp $
3 * Mini ping implementation for busybox 3 * Mini ping implementation for busybox
4 * 4 *
5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> 5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
@@ -175,7 +175,8 @@ extern int ping_main(int argc, char **argv)
175static const char* ping_usage = "ping [OPTION]... host\n\n" 175static const char* ping_usage = "ping [OPTION]... host\n\n"
176"Send ICMP ECHO_REQUEST packets to network hosts.\n\n" 176"Send ICMP ECHO_REQUEST packets to network hosts.\n\n"
177"Options:\n" 177"Options:\n"
178"\t-q\t\tQuiet mode, only displays output at start and when finished.\n" 178"\t-q\t\tQuiet mode, only displays output at start"
179"\t\t\tand when finished.\n"
179"\t-c COUNT\tSend only COUNT pings.\n"; 180"\t-c COUNT\tSend only COUNT pings.\n";
180 181
181static char *hostname = NULL; 182static char *hostname = NULL;
diff --git a/printf.c b/printf.c
index 5be3a67cb..5fd5ea303 100644
--- a/printf.c
+++ b/printf.c
@@ -143,7 +143,7 @@ printf_main(int argc, char** argv)
143 int args_used; 143 int args_used;
144 144
145 exit_status = 0; 145 exit_status = 0;
146 if ( **(argv+1) == '-' ) { 146 if ( argc <= 1 || **(argv+1) == '-' ) {
147 usage (printf_usage); 147 usage (printf_usage);
148 } 148 }
149 149
diff --git a/pwd.c b/pwd.c
index c5ce6ff89..bacabd77a 100644
--- a/pwd.c
+++ b/pwd.c
@@ -23,11 +23,12 @@
23#include "internal.h" 23#include "internal.h"
24#include <stdio.h> 24#include <stdio.h>
25#include <dirent.h> 25#include <dirent.h>
26#include <sys/param.h>
26 27
27extern int 28extern int
28pwd_main(int argc, char * * argv) 29pwd_main(int argc, char * * argv)
29{ 30{
30 char buf[NAME_MAX]; 31 char buf[PATH_MAX + 1];
31 32
32 if ( getcwd(buf, sizeof(buf)) == NULL ) { 33 if ( getcwd(buf, sizeof(buf)) == NULL ) {
33 perror("get working directory"); 34 perror("get working directory");
diff --git a/sort.c b/sort.c
index 4df5627ac..d529ce722 100644
--- a/sort.c
+++ b/sort.c
@@ -309,4 +309,4 @@ sort_main(int argc, char **argv)
309 exit(0); 309 exit(0);
310} 310}
311 311
312/* $Id: sort.c,v 1.9 2000/01/23 18:19:02 erik Exp $ */ 312/* $Id: sort.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */
diff --git a/swaponoff.c b/swaponoff.c
index 8eaf9797c..3c02bdd42 100644
--- a/swaponoff.c
+++ b/swaponoff.c
@@ -65,7 +65,6 @@ static void
65do_em_all() 65do_em_all()
66{ 66{
67 struct mntent *m; 67 struct mntent *m;
68 char swapName[NAME_MAX];
69 FILE *f = setmntent ("/etc/fstab", "r"); 68 FILE *f = setmntent ("/etc/fstab", "r");
70 69
71 if (f == NULL) { 70 if (f == NULL) {
@@ -73,8 +72,8 @@ do_em_all()
73 exit( FALSE); 72 exit( FALSE);
74 } 73 }
75 while ((m = getmntent (f)) != NULL) { 74 while ((m = getmntent (f)) != NULL) {
76 if (!strstr (m->mnt_type, "swap")) { 75 if (!strstr (m->mnt_type, MNTTYPE_SWAP)) {
77 swap_enable_disable( swapName); 76 swap_enable_disable( m->mnt_fsname);
78 } 77 }
79 } 78 }
80 endmntent (f); 79 endmntent (f);
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 0be9ded06..29ede13db 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -77,7 +77,7 @@ static int device_open(char *device, int mode)
77 77
78 /* Retry up to 5 times */ 78 /* Retry up to 5 times */
79 for (f = 0; f < 5; f++) 79 for (f = 0; f < 5; f++)
80 if ((fd = open(device, m)) >= 0) 80 if ((fd = open(device, m, 0600)) >= 0)
81 break; 81 break;
82 if (fd < 0) 82 if (fd < 0)
83 return fd; 83 return fd;
@@ -177,9 +177,6 @@ static void doSyslogd(void)
177 char *q, *p = buf; 177 char *q, *p = buf;
178 int readSize; 178 int readSize;
179 179
180 /* Remove any preexisting socket/file */
181 unlink(_PATH_LOG);
182
183 /* Set up sig handlers */ 180 /* Set up sig handlers */
184 signal(SIGINT, quit_signal); 181 signal(SIGINT, quit_signal);
185 signal(SIGTERM, quit_signal); 182 signal(SIGTERM, quit_signal);
@@ -188,8 +185,9 @@ static void doSyslogd(void)
188 signal(SIGALRM, domark); 185 signal(SIGALRM, domark);
189 alarm(MarkInterval); 186 alarm(MarkInterval);
190 187
188 /* Remove any preexisting socket/file */
189 unlink(_PATH_LOG);
191 190
192 unlink( _PATH_LOG);
193 memset(&sunx, 0, sizeof(sunx)); 191 memset(&sunx, 0, sizeof(sunx));
194 sunx.sun_family = AF_UNIX; /* Unix domain socket */ 192 sunx.sun_family = AF_UNIX; /* Unix domain socket */
195 strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path)); 193 strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path));
@@ -200,12 +198,17 @@ static void doSyslogd(void)
200 198
201 addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path); 199 addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
202 if ( (bind(fd, (struct sockaddr *) &sunx, addrLength)) || 200 if ( (bind(fd, (struct sockaddr *) &sunx, addrLength)) ||
203 (fchmod(fd, 0666) < 0) || (listen(fd, 5)) ) 201 (listen(fd, 5)) )
204 { 202 {
205 perror("Could not connect to socket " _PATH_LOG); 203 perror("Could not connect to socket " _PATH_LOG);
206 exit( FALSE); 204 exit( FALSE);
207 } 205 }
208 206
207 umask(0);
208 if (chmod(_PATH_LOG, 0666) < 0) {
209 perror("Could not set permission on " _PATH_LOG);
210 exit (FALSE);
211 }
209 212
210 logMessage(LOG_SYSLOG|LOG_INFO, "syslogd started: " 213 logMessage(LOG_SYSLOG|LOG_INFO, "syslogd started: "
211 "BusyBox v" BB_VER " (" BB_BT ")"); 214 "BusyBox v" BB_VER " (" BB_BT ")");
diff --git a/syslogd.c b/syslogd.c
index 0be9ded06..29ede13db 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -77,7 +77,7 @@ static int device_open(char *device, int mode)
77 77
78 /* Retry up to 5 times */ 78 /* Retry up to 5 times */
79 for (f = 0; f < 5; f++) 79 for (f = 0; f < 5; f++)
80 if ((fd = open(device, m)) >= 0) 80 if ((fd = open(device, m, 0600)) >= 0)
81 break; 81 break;
82 if (fd < 0) 82 if (fd < 0)
83 return fd; 83 return fd;
@@ -177,9 +177,6 @@ static void doSyslogd(void)
177 char *q, *p = buf; 177 char *q, *p = buf;
178 int readSize; 178 int readSize;
179 179
180 /* Remove any preexisting socket/file */
181 unlink(_PATH_LOG);
182
183 /* Set up sig handlers */ 180 /* Set up sig handlers */
184 signal(SIGINT, quit_signal); 181 signal(SIGINT, quit_signal);
185 signal(SIGTERM, quit_signal); 182 signal(SIGTERM, quit_signal);
@@ -188,8 +185,9 @@ static void doSyslogd(void)
188 signal(SIGALRM, domark); 185 signal(SIGALRM, domark);
189 alarm(MarkInterval); 186 alarm(MarkInterval);
190 187
188 /* Remove any preexisting socket/file */
189 unlink(_PATH_LOG);
191 190
192 unlink( _PATH_LOG);
193 memset(&sunx, 0, sizeof(sunx)); 191 memset(&sunx, 0, sizeof(sunx));
194 sunx.sun_family = AF_UNIX; /* Unix domain socket */ 192 sunx.sun_family = AF_UNIX; /* Unix domain socket */
195 strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path)); 193 strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path));
@@ -200,12 +198,17 @@ static void doSyslogd(void)
200 198
201 addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path); 199 addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
202 if ( (bind(fd, (struct sockaddr *) &sunx, addrLength)) || 200 if ( (bind(fd, (struct sockaddr *) &sunx, addrLength)) ||
203 (fchmod(fd, 0666) < 0) || (listen(fd, 5)) ) 201 (listen(fd, 5)) )
204 { 202 {
205 perror("Could not connect to socket " _PATH_LOG); 203 perror("Could not connect to socket " _PATH_LOG);
206 exit( FALSE); 204 exit( FALSE);
207 } 205 }
208 206
207 umask(0);
208 if (chmod(_PATH_LOG, 0666) < 0) {
209 perror("Could not set permission on " _PATH_LOG);
210 exit (FALSE);
211 }
209 212
210 logMessage(LOG_SYSLOG|LOG_INFO, "syslogd started: " 213 logMessage(LOG_SYSLOG|LOG_INFO, "syslogd started: "
211 "BusyBox v" BB_VER " (" BB_BT ")"); 214 "BusyBox v" BB_VER " (" BB_BT ")");
diff --git a/tail.c b/tail.c
index 5198892b6..0ab8f11b0 100644
--- a/tail.c
+++ b/tail.c
@@ -33,7 +33,7 @@
33 and generally busyboxed, Erik Andersen <andersen@lineo.com> 33 and generally busyboxed, Erik Andersen <andersen@lineo.com>
34 34
35 Removed superfluous options and associated code ("-c", "-n", "-q"). 35 Removed superfluous options and associated code ("-c", "-n", "-q").
36 Removed "tail -f" suport for multiple files. 36 Removed "tail -f" support for multiple files.
37 Both changes by Friedrich Vedder <fwv@myrtle.lahn.de>. 37 Both changes by Friedrich Vedder <fwv@myrtle.lahn.de>.
38 38
39 */ 39 */
diff --git a/tar.c b/tar.c
index 0fa09ffd8..6496231ae 100644
--- a/tar.c
+++ b/tar.c
@@ -40,6 +40,7 @@
40#include <utime.h> 40#include <utime.h>
41#include <sys/types.h> 41#include <sys/types.h>
42#include <sys/sysmacros.h> 42#include <sys/sysmacros.h>
43#include <sys/param.h> /* for PATH_MAX */
43 44
44 45
45#ifdef BB_FEATURE_TAR_CREATE 46#ifdef BB_FEATURE_TAR_CREATE
@@ -1041,7 +1042,7 @@ static void saveDirectory (const char *dirName, const struct stat *statbuf)
1041 DIR *dir; 1042 DIR *dir;
1042 struct dirent *entry; 1043 struct dirent *entry;
1043 int needSlash; 1044 int needSlash;
1044 char fullName[NAME_MAX]; 1045 char fullName[PATH_MAX + 1];
1045 1046
1046 /* 1047 /*
1047 * Construct the directory name as used in the tar file by appending 1048 * Construct the directory name as used in the tar file by appending
diff --git a/tee.c b/tee.c
index 8d1ca6efd..4c5c691c6 100644
--- a/tee.c
+++ b/tee.c
@@ -123,4 +123,4 @@ tee_main(int argc, char **argv)
123 exit(0); 123 exit(0);
124} 124}
125 125
126/* $Id: tee.c,v 1.4 1999/12/10 08:25:07 andersen Exp $ */ 126/* $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
index 000000000..015634460
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,28 @@
1all test_all: message_header cp_tests mv_tests ln_tests
2
3clean: cp_clean mv_clean ln_clean
4
5message_header:
6 @echo
7 @echo If tests faile due to differences in timestamps in commands that are not set
8 @echo to preserve timestamps, just run the tests again.
9 @echo
10
11include cp_tests.mk
12include mv_tests.mk
13include ln_tests.mk
14
15BBL := $(shell pushd .. >/dev/null && \
16 ${MAKE} busybox.links >/dev/null && \
17 popd >/dev/null && \
18 cat ../busybox.links | \
19 sed -e 's,.*/\(.*\)$$,\1,')
20
21../busybox:
22 cd .. && ${MAKE} busybox
23
24$(BBL): ../busybox
25 rm -f $@
26 ln ../busybox $@
27
28.PHONY: all test_all message_header
diff --git a/tests/cp_tests.mk b/tests/cp_tests.mk
new file mode 100644
index 000000000..e14262ac1
--- /dev/null
+++ b/tests/cp_tests.mk
@@ -0,0 +1,270 @@
1# This is a -*- makefile -*-
2
3# GNU `cp'
4GCP = /bin/cp
5# BusyBox `cp'
6BCP = $(shell pwd)/cp
7
8.PHONY: cp_clean
9cp_clean:
10 rm -rf cp_tests cp_*.{gnu,bb} cp
11
12.PHONY: cp_tests
13cp_tests: cp_clean cp
14 @echo;
15 @echo "No output from diff means busybox cp is functioning properly.";
16
17 @echo;
18 ${BCP} || true;
19
20 @echo;
21 mkdir cp_tests;
22
23 @echo;
24 cd cp_tests; \
25 echo A file > afile; \
26 ls -l afile > ../cp_afile_afilecopy.gnu; \
27 ${GCP} afile afilecopy; \
28 ls -l afile afilecopy >> ../cp_afile_afilecopy.gnu;
29
30 @echo;
31 rm -f cp_tests/afile*;
32
33 @echo;
34 cd cp_tests; \
35 echo A file > afile; \
36 ls -l afile > ../cp_afile_afilecopy.bb; \
37 ${BCP} afile afilecopy; \
38 ls -l afile afilecopy >> ../cp_afile_afilecopy.bb;
39
40 @echo;
41 diff -u cp_afile_afilecopy.gnu cp_afile_afilecopy.bb;
42
43 @echo;
44 rm -f cp_tests/afile*;
45
46 @echo; echo;
47 cd cp_tests; \
48 mkdir there there1; \
49 cd there; \
50 ln -s ../afile .;
51
52 @echo;
53 cd cp_tests; \
54 echo A file > afile; \
55 ls -l afile > ../cp_symlink.gnu; \
56 ${GCP} there/afile there1/; \
57 ls -l afile there/afile there1/afile >> ../cp_symlink.gnu;
58
59 @echo;
60 rm -f cp_tests/afile cp_tests/there1/afile;
61
62 @echo;
63 cd cp_tests; \
64 echo A file > afile; \
65 ls -l afile > ../cp_symlink.bb; \
66 ${BCP} there/afile there1/; \
67 ls -l afile there/afile there1/afile >> ../cp_symlink.bb;
68
69 @echo;
70 diff -u cp_symlink.gnu cp_symlink.bb;
71
72 @echo;
73 rm -f cp_tests/afile cp_tests/there1/afile;
74
75 @echo; echo;
76 cd cp_tests; \
77 echo A file > afile; \
78 ls -l afile > ../cp_a_symlink.gnu; \
79 ${GCP} -a there/afile there1/; \
80 ls -l afile there/afile there1/afile >> ../cp_a_symlink.gnu;
81
82 @echo;
83 rm -f cp_tests/afile cp_tests/there1/afile;
84
85 @echo;
86 cd cp_tests; \
87 echo A file > afile; \
88 ls -l afile > ../cp_a_symlink.bb; \
89 ${BCP} -a there/afile there1/; \
90 ls -l afile there/afile there1/afile >> ../cp_a_symlink.bb;
91
92 @echo;
93 diff -u cp_a_symlink.gnu cp_a_symlink.bb;
94
95 @echo;
96 rm -f cp_tests/afile
97 rm -rf cp_tests/there{,1};
98
99 @echo; echo;
100 cd cp_tests; \
101 echo A file > there/afile; \
102 mkdir there/adir; \
103 touch there/adir/afileinadir; \
104 ln -s $(shell pwd) there/alink;
105
106 @echo;
107 cd cp_tests; \
108 ${GCP} -a there/ there1/; \
109 ls -lR there/ there1/ > ../cp_a_dir_dir.gnu;
110
111 @echo;
112 rm -rf cp_tests/there1;
113
114 @echo;
115 cd cp_tests; \
116 ${BCP} -a there/ there1/; \
117 ls -lR there/ there1/ > ../cp_a_dir_dir.bb;
118
119 @echo;
120 diff -u cp_a_dir_dir.gnu cp_a_dir_dir.bb;
121
122 @echo;
123 rm -rf cp_tests/there1/;
124
125 @echo; echo;
126 cd cp_tests; \
127 echo A file number one > afile1; \
128 echo A file number two, blah. > afile2; \
129 ln -s afile1 symlink1; \
130 mkdir there1; \
131 ${GCP} afile1 afile2 symlink1 there1/; \
132 ls -lR > ../cp_files_dir.gnu;
133
134 @echo;
135 rm -rf cp_tests/{afile{1,2},symlink1,there1};
136
137 @echo;
138 cd cp_tests; \
139 echo A file number one > afile1; \
140 echo A file number two, blah. > afile2; \
141 ln -s afile1 symlink1; \
142 mkdir there1; \
143 ${BCP} afile1 afile2 symlink1 there1/; \
144 ls -lR > ../cp_files_dir.bb;
145
146 @echo;
147 diff -u cp_files_dir.gnu cp_files_dir.bb;
148
149 @echo;
150 rm -rf cp_tests/{afile{1,2},symlink1,there1};
151
152 @echo; echo;
153 cd cp_tests; \
154 echo A file number one > afile1; \
155 echo A file number two, blah. > afile2; \
156 ln -s afile1 symlink1; \
157 mkdir there1; \
158 ${GCP} -d afile1 afile2 symlink1 there1/; \
159 ls -lR > ../cp_d_files_dir.gnu;
160
161 @echo;
162 rm -rf cp_tests/{afile{1,2},symlink1,there1};
163
164 @echo;
165 cd cp_tests; \
166 echo A file number one > afile1; \
167 echo A file number two, blah. > afile2; \
168 ln -s afile1 symlink1; \
169 mkdir there1; \
170 ${BCP} -d afile1 afile2 symlink1 there1/; \
171 ls -lR > ../cp_d_files_dir.bb;
172
173 @echo;
174 diff -u cp_d_files_dir.gnu cp_d_files_dir.bb;
175
176 @echo;
177 rm -rf cp_tests/{afile{1,2},symlink1,there1};
178
179 @echo; echo;
180 cd cp_tests; \
181 echo A file number one > afile1; \
182 echo A file number two, blah. > afile2; \
183 touch --date='Sat Jan 29 21:24:08 PST 2000' afile1; \
184 ln -s afile1 symlink1; \
185 mkdir there1; \
186 ${GCP} -p afile1 afile2 symlink1 there1/; \
187 ls -lR > ../cp_p_files_dir.gnu;
188
189 @echo;
190 rm -rf cp_tests/{afile{1,2},symlink1,there1};
191
192 @echo;
193 cd cp_tests; \
194 echo A file number one > afile1; \
195 echo A file number two, blah. > afile2; \
196 touch --date='Sat Jan 29 21:24:08 PST 2000' afile1; \
197 ln -s afile1 symlink1; \
198 mkdir there1; \
199 ${BCP} -p afile1 afile2 symlink1 there1/; \
200 ls -lR > ../cp_p_files_dir.bb;
201
202 @echo;
203 diff -u cp_p_files_dir.gnu cp_p_files_dir.bb;
204
205 @echo;
206 rm -rf cp_tests/{afile{1,2},symlink1,there1};
207
208 @echo; echo;
209 cd cp_tests; \
210 echo A file number one > afile1; \
211 echo A file number two, blah. > afile2; \
212 touch --date='Sat Jan 29 21:24:08 PST 2000' afile1; \
213 ln -s afile1 symlink1; \
214 mkdir there1; \
215 ${GCP} -p -d afile1 afile2 symlink1 there1/; \
216 ls -lR > ../cp_pd_files_dir.gnu;
217
218 @echo;
219 rm -rf cp_tests/{afile{1,2},symlink1,there1};
220
221 @echo;
222 cd cp_tests; \
223 echo A file number one > afile1; \
224 echo A file number two, blah. > afile2; \
225 touch --date='Sat Jan 29 21:24:08 PST 2000' afile1; \
226 ln -s afile1 symlink1; \
227 mkdir there1; \
228 ${BCP} -p -d afile1 afile2 symlink1 there1/; \
229 ls -lR > ../cp_pd_files_dir.bb;
230
231 @echo;
232 diff -u cp_pd_files_dir.gnu cp_pd_files_dir.bb;
233
234 @echo;
235 rm -rf cp_tests/{afile{1,2},symlink1,there1};
236
237 @echo; echo;
238 cd cp_tests; \
239 mkdir dir{a,b}; \
240 echo A file > dira/afile; \
241 echo A file in dirb > dirb/afileindirb; \
242 ln -s dira/afile dira/alinktoafile; \
243 mkdir dira/subdir1; \
244 echo Another file > dira/subdir1/anotherfile; \
245 ls -lR . > ../cp_a_dira_dirb.gnu; \
246 ${GCP} -a dira dirb; \
247 ls -lR . >> ../cp_a_dira_dirb.gnu;
248
249 # false;
250 @echo;
251 rm -rf cp_tests/dir{a,b};
252
253 @echo;
254 cd cp_tests; \
255 mkdir dir{a,b}; \
256 echo A file > dira/afile; \
257 echo A file in dirb > dirb/afileindirb; \
258 ln -s dira/afile dira/alinktoafile; \
259 mkdir dira/subdir1; \
260 echo Another file > dira/subdir1/anotherfile; \
261 ls -lR . > ../cp_a_dira_dirb.bb; \
262 ${BCP} -a dira dirb; \
263 ls -lR . >> ../cp_a_dira_dirb.bb;
264
265 @echo;
266 diff -u cp_a_dira_dirb.gnu cp_a_dira_dirb.bb;
267
268 # false;
269 @echo;
270 rm -rf cp_tests/dir{a,b};
diff --git a/tests/ln_tests.mk b/tests/ln_tests.mk
new file mode 100644
index 000000000..5925edd4f
--- /dev/null
+++ b/tests/ln_tests.mk
@@ -0,0 +1,66 @@
1
2# GNU `ln'
3GLN = /bin/ln
4# BusyBox `ln'
5BLN = $(shell pwd)/ln
6
7.PHONY: ln_clean
8ln_clean:
9 rm -rf ln_tests ln_*.{gnu,bb} ln
10
11.PHONY: ln_tests
12ln_tests: ln_clean ln
13 @echo;
14 @echo "No output from diff means busybox ln is functioning properly.";
15
16 @echo;
17 ${BLN} || true;
18
19 @echo;
20 mkdir ln_tests;
21
22 @echo;
23 cd ln_tests; \
24 echo A file > afile; \
25 ls -l afile > ../ln_afile_newname.gnu; \
26 ${GLN} afile newname; \
27 ls -l afile newname >> ../ln_afile_newname.gnu;
28
29 @echo;
30 rm -f ln_tests/{afile,newname};
31
32 @echo;
33 cd ln_tests; \
34 echo A file > afile; \
35 ls -l afile > ../ln_afile_newname.bb; \
36 ${BLN} afile newname; \
37 ls -l afile newname >> ../ln_afile_newname.bb;
38
39 @echo;
40 diff -u ln_afile_newname.gnu ln_afile_newname.bb
41
42 @echo;
43 rm -f ln_tests/{afile,newname};
44
45 @echo;
46 cd ln_tests; \
47 echo A file > afile; \
48 ls -l afile > ../ln_s_afile_newname.gnu; \
49 ${GLN} -s afile newname; \
50 ls -l afile newname >> ../ln_s_afile_newname.gnu;
51
52 @echo;
53 rm -f ln_tests/{afile,newname};
54
55 @echo;
56 cd ln_tests; \
57 echo A file > afile; \
58 ls -l afile > ../ln_s_afile_newname.bb; \
59 ${BLN} -s afile newname; \
60 ls -l afile newname >> ../ln_s_afile_newname.bb;
61
62 @echo;
63 diff -u ln_s_afile_newname.gnu ln_s_afile_newname.bb
64
65 @echo;
66 rm -f ln_tests/{afile,newname};
diff --git a/tests/mv_tests.mk b/tests/mv_tests.mk
new file mode 100644
index 000000000..3a9012538
--- /dev/null
+++ b/tests/mv_tests.mk
@@ -0,0 +1,137 @@
1
2# GNU `mv'
3GMV = /bin/mv
4# BusyBox `mv'
5BMV = $(shell pwd)/mv
6
7.PHONY: mv_clean
8mv_clean:
9 rm -rf mv_tests mv_*.{gnu,bb} mv
10
11.PHONY: mv_tests
12mv_tests: mv_clean mv
13 @echo;
14 @echo "No output from diff means busybox mv is functioning properly.";
15 @echo;
16 @echo "No such file or directory is good; it means the old file got removed.";
17 @echo;
18 ${BMV} || true;
19
20 @echo;
21 mkdir mv_tests;
22
23 @echo;
24 cd mv_tests; \
25 echo A file > afile; \
26 ls -l afile > ../mv_afile_newname.gnu; \
27 ${GMV} afile newname; \
28 ls -l newname >> ../mv_afile_newname.gnu;
29 -ls -l mv_tests/afile;
30
31 @echo;
32 rm -f mv_tests/{afile,newname};
33
34 @echo;
35 cd mv_tests; \
36 echo A file > afile; \
37 ls -l afile > ../mv_afile_newname.bb; \
38 ${BMV} afile newname; \
39 ls -l newname >> ../mv_afile_newname.bb;
40 -ls -l mv_tests/afile;
41
42 @echo;
43 diff -u mv_afile_newname.gnu mv_afile_newname.bb;
44
45 @echo;
46 rm -f mv_tests/{afile,newname};
47
48 @echo; echo;
49 cd mv_tests; \
50 echo A file > afile; \
51 ln -s afile symlink; \
52 ls -l afile symlink > ../mv_symlink_newname.gnu; \
53 ${GMV} symlink newname; \
54 ls -l afile newname >> ../mv_symlink_newname.gnu;
55 -ls -l mv_tests/symlink;
56
57 @echo;
58 rm -f mv_tests/{afile,newname};
59
60 @echo;
61 cd mv_tests; \
62 echo A file > afile; \
63 ln -s afile symlink; \
64 ls -l afile symlink > ../mv_symlink_newname.bb;\
65 ${BMV} symlink newname; \
66 ls -l afile newname >> ../mv_symlink_newname.bb;
67 -ls -l mv_tests/symlink;
68
69 @echo;
70 diff -u mv_symlink_newname.gnu mv_symlink_newname.bb;
71
72 @echo;
73 rm -rf mv_tests/*;
74
75 @echo; echo;
76 cd mv_tests; \
77 echo A file > afile; \
78 ln -s afile symlink; \
79 mkdir newdir; \
80 ls -lR > ../mv_file_symlink_dir.gnu; \
81 ${GMV} symlink afile newdir; \
82 ls -lR >> ../mv_file_symlink_dir.gnu;
83 -ls -l mv_tests/{symlink,afile};
84
85 @echo;
86 rm -rf mv_tests/*
87
88 @echo; echo;
89 cd mv_tests; \
90 echo A file > afile; \
91 ln -s afile symlink; \
92 mkdir newdir; \
93 ls -lR > ../mv_file_symlink_dir.bb; \
94 ${BMV} symlink afile newdir; \
95 ls -lR >> ../mv_file_symlink_dir.bb;
96 -ls -l mv_tests/{symlink,afile};
97
98 @echo;
99 diff -u mv_file_symlink_dir.gnu mv_file_symlink_dir.bb;
100
101 @echo;
102 rm -rf mv_tests/*;
103
104 @echo; echo;
105 cd mv_tests; \
106 mkdir dir{a,b}; \
107 echo A file > dira/afile; \
108 echo A file in dirb > dirb/afileindirb; \
109 ln -s dira/afile dira/alinktoafile; \
110 mkdir dira/subdir1; \
111 echo Another file > dira/subdir1/anotherfile; \
112 ls -lR . > ../mv_dira_dirb.gnu; \
113 ${GMV} dira dirb; \
114 ls -lR . >> ../mv_dira_dirb.gnu;
115
116 # false;
117 @echo;
118 rm -rf mv_tests/dir{a,b};
119
120 @echo;
121 cd mv_tests; \
122 mkdir dir{a,b}; \
123 echo A file > dira/afile; \
124 echo A file in dirb > dirb/afileindirb; \
125 ln -s dira/afile dira/alinktoafile; \
126 mkdir dira/subdir1; \
127 echo Another file > dira/subdir1/anotherfile; \
128 ls -lR . > ../mv_dira_dirb.bb; \
129 ${BMV} dira dirb; \
130 ls -lR . >> ../mv_dira_dirb.bb;
131
132 @echo;
133 diff -u mv_dira_dirb.gnu mv_dira_dirb.bb;
134
135 # false;
136 @echo;
137 rm -rf mv_tests/dir{a,b};
diff --git a/umount.c b/umount.c
index 68b27e385..b65caf76e 100644
--- a/umount.c
+++ b/umount.c
@@ -37,11 +37,24 @@ static const char umount_usage[] =
37#else 37#else
38"\n" 38"\n"
39#endif 39#endif
40#ifdef BB_FEATURE_REMOUNT
41"\t-r:\tTry to remount devices as read-only if mount is busy\n"
42#endif
40; 43;
41 44
45struct _mtab_entry_t {
46 char *device;
47 char *mountpt;
48 struct _mtab_entry_t *next;
49};
50
51static struct _mtab_entry_t *mtab_cache = NULL;
52
53
42 54
43static int useMtab = TRUE; 55static int useMtab = TRUE;
44static int umountAll = FALSE; 56static int umountAll = FALSE;
57static int doRemount = FALSE;
45extern const char mtab_file[]; /* Defined in utility.c */ 58extern const char mtab_file[]; /* Defined in utility.c */
46 59
47#define MIN(x,y) (x > y ? x : y) 60#define MIN(x,y) (x > y ? x : y)
@@ -50,21 +63,10 @@ static int
50do_umount(const char* name, int useMtab) 63do_umount(const char* name, int useMtab)
51{ 64{
52 int status; 65 int status;
53 struct mntent *m; 66 char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE);
54 FILE *mountTable; 67
55 const char *blockDevice = NULL; 68 if (blockDevice && strcmp(blockDevice, name) == 0)
56 69 name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT);
57 if ((mountTable = setmntent (mtab_file, "r"))) {
58 while ((m = getmntent (mountTable)) != 0) {
59 if (strncmp(m->mnt_dir, name,
60 MIN(strlen(m->mnt_dir),strlen(name))) == 0)
61 blockDevice = m->mnt_fsname;
62 else if (strcmp(m->mnt_fsname, name) == 0) {
63 blockDevice = name;
64 name = m->mnt_dir;
65 }
66 }
67 }
68 70
69 status = umount(name); 71 status = umount(name);
70 72
@@ -73,57 +75,53 @@ do_umount(const char* name, int useMtab)
73 /* this was a loop device, delete it */ 75 /* this was a loop device, delete it */
74 del_loop(blockDevice); 76 del_loop(blockDevice);
75#endif 77#endif
76#if defined BB_MTAB 78#if defined BB_FEATURE_REMOUNT
79 if ( status != 0 && doRemount == TRUE && errno == EBUSY ) {
80 status = mount(blockDevice, name, NULL,
81 MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
82 if (status == 0) {
83 fprintf(stderr, "umount: %s busy - remounted read-only\n",
84 blockDevice);
85 /* TODO: update mtab if BB_MTAB is defined */
86 } else {
87 fprintf(stderr, "umount: Cannot remount %s read-only\n",
88 blockDevice);
89 }
90 }
91#endif
77 if ( status == 0 ) { 92 if ( status == 0 ) {
93#if defined BB_MTAB
78 if ( useMtab==TRUE ) 94 if ( useMtab==TRUE )
79 erase_mtab(name); 95 erase_mtab(name);
80 return 0;
81 }
82 else
83#endif 96#endif
84 return(status); 97 return( TRUE);
98 }
99 return(FALSE);
85} 100}
86 101
87static int 102static int
88umount_all(int useMtab) 103umount_all(int useMtab)
89{ 104{
90 int status; 105 int status = TRUE;
91 struct mntent *m; 106 char *mountpt;
92 FILE *mountTable; 107 void *iter;
93 108
94 if ((mountTable = setmntent (mtab_file, "r"))) { 109 for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) {
95 while ((m = getmntent (mountTable)) != 0) { 110 status=do_umount (mountpt, useMtab);
96 char *blockDevice = m->mnt_fsname; 111 if (status != 0) {
97#if ! defined BB_MTAB 112 /* Don't bother retrying the umount on busy devices */
98 if (strcmp (blockDevice, "/dev/root") == 0) { 113 if (errno == EBUSY) {
99 struct fstab* fstabItem; 114 perror(mountpt);
100 fstabItem = getfsfile ("/"); 115 continue;
101 if (fstabItem != NULL) {
102 blockDevice = fstabItem->fs_spec;
103 }
104 } 116 }
105#endif 117 status = do_umount (mountpt, useMtab);
106 /* Don't umount /proc when doing umount -a */ 118 if (status != 0) {
107 if (strcmp (blockDevice, "proc") == 0) 119 printf ("Couldn't umount %s on %s: %s\n",
108 continue; 120 mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), strerror(errno));
109
110 status=do_umount (m->mnt_dir, useMtab);
111 if (status!=0) {
112 /* Don't bother retrying the umount on busy devices */
113 if (errno==EBUSY) {
114 perror(m->mnt_dir);
115 continue;
116 }
117 status=do_umount (blockDevice, useMtab);
118 if (status!=0) {
119 printf ("Couldn't umount %s on %s (type %s): %s\n",
120 blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
121 }
122 } 121 }
123 } 122 }
124 endmntent (mountTable);
125 } 123 }
126 return( TRUE); 124 return (status);
127} 125}
128 126
129extern int 127extern int
@@ -144,13 +142,18 @@ umount_main(int argc, char** argv)
144 useMtab = FALSE; 142 useMtab = FALSE;
145 break; 143 break;
146#endif 144#endif
145#ifdef BB_FEATURE_REMOUNT
146 case 'r':
147 doRemount = TRUE;
148 break;
149#endif
147 default: 150 default:
148 usage( umount_usage); 151 usage( umount_usage);
149 } 152 }
150 } 153 }
151 154
152 155 mtab_read();
153 if(umountAll==TRUE) { 156 if (umountAll==TRUE) {
154 exit(umount_all(useMtab)); 157 exit(umount_all(useMtab));
155 } 158 }
156 if ( do_umount(*argv,useMtab) == 0 ) 159 if ( do_umount(*argv,useMtab) == 0 )
@@ -161,3 +164,87 @@ umount_main(int argc, char** argv)
161 } 164 }
162} 165}
163 166
167
168
169/* These functions are here because the getmntent functions do not appear
170 * to be re-entrant, which leads to all sorts of problems when we try to
171 * use them recursively - randolph
172 */
173void mtab_read(void)
174{
175 struct _mtab_entry_t *entry = NULL;
176 struct mntent *e;
177 FILE *fp;
178
179 if (mtab_cache != NULL) return;
180
181 if ((fp = setmntent(mtab_file, "r")) == NULL) {
182 fprintf(stderr, "Cannot open %s\n", mtab_file);
183 return;
184 }
185 while ((e = getmntent(fp))) {
186 entry = malloc(sizeof(struct _mtab_entry_t));
187 entry->device = strdup(e->mnt_fsname);
188 entry->mountpt = strdup(e->mnt_dir);
189 entry->next = mtab_cache;
190 mtab_cache = entry;
191 }
192 endmntent(fp);
193}
194
195char *mtab_getinfo(const char *match, const char which)
196{
197 struct _mtab_entry_t *cur = mtab_cache;
198 while (cur) {
199 if (strcmp(cur->mountpt, match) == 0 ||
200 strcmp(cur->device, match) == 0) {
201 if (which == MTAB_GETMOUNTPT) {
202 return cur->mountpt;
203 } else {
204#if !defined BB_MTAB
205 if (strcmp(cur->device, "/dev/root") == 0) {
206 struct fstab* fstabItem;
207 fstabItem = getfsfile ("/");
208 if (fstabItem != NULL) return fstabItem->fs_spec;
209 }
210#endif
211 return cur->device;
212 }
213 }
214 cur = cur->next;
215 }
216 return NULL;
217}
218
219char *mtab_first(void **iter)
220{
221 struct _mtab_entry_t *mtab_iter;
222 if (!iter) return NULL;
223 mtab_iter = mtab_cache;
224 *iter = (void *)mtab_iter;
225 return mtab_next(iter);
226}
227
228char *mtab_next(void **iter)
229{
230 char *mp;
231 if (iter == NULL || *iter == NULL) return NULL;
232 mp = ((struct _mtab_entry_t *)(*iter))->mountpt;
233 *iter = (void *)((struct _mtab_entry_t *)(*iter))->next;
234 return mp;
235}
236
237void mtab_free(void)
238{
239 struct _mtab_entry_t *this, *next;
240
241 this = mtab_cache;
242 while (this) {
243 next = this->next;
244 if (this->device) free(this->device);
245 if (this->mountpt) free(this->mountpt);
246 free(this);
247 this = next;
248 }
249}
250
diff --git a/uniq.c b/uniq.c
index a7bff54ec..965d290c2 100644
--- a/uniq.c
+++ b/uniq.c
@@ -193,4 +193,4 @@ uniq_main(int argc, char **argv)
193 exit(0); 193 exit(0);
194} 194}
195 195
196/* $Id: uniq.c,v 1.5 2000/01/23 18:19:02 erik Exp $ */ 196/* $Id: uniq.c,v 1.6 2000/02/07 05:29:42 erik Exp $ */
diff --git a/util-linux/fdflush.c b/util-linux/fdflush.c
index 51b0c2bac..a244e8def 100644
--- a/util-linux/fdflush.c
+++ b/util-linux/fdflush.c
@@ -31,7 +31,7 @@ extern int fdflush_main(int argc, char **argv)
31{ 31{
32 int value; 32 int value;
33 int fd; 33 int fd;
34 if ( **(argv+1) == '-' ) { 34 if ( argc <= 1 || **(argv++) == '-' ) {
35 usage( "fdflush device\n"); 35 usage( "fdflush device\n");
36 } 36 }
37 37
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c
index d31de20a8..09111c5dc 100644
--- a/util-linux/fsck_minix.c
+++ b/util-linux/fsck_minix.c
@@ -96,6 +96,7 @@
96#include <termios.h> 96#include <termios.h>
97#include <mntent.h> 97#include <mntent.h>
98#include <sys/stat.h> 98#include <sys/stat.h>
99#include <sys/param.h> /* for PATH_MAX */
99 100
100#include <linux/fs.h> 101#include <linux/fs.h>
101#include <linux/minix_fs.h> 102#include <linux/minix_fs.h>
@@ -143,7 +144,7 @@ static int termios_set = 0;
143/* File-name data */ 144/* File-name data */
144#define MAX_DEPTH 50 145#define MAX_DEPTH 50
145static int name_depth = 0; 146static int name_depth = 0;
146static char name_list[MAX_DEPTH][NAME_MAX+1]; 147static char name_list[MAX_DEPTH][PATH_MAX + 1];
147 148
148static char * inode_buffer = NULL; 149static char * inode_buffer = NULL;
149#define Inode (((struct minix_inode *) inode_buffer)-1) 150#define Inode (((struct minix_inode *) inode_buffer)-1)
diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c
index 8eaf9797c..3c02bdd42 100644
--- a/util-linux/swaponoff.c
+++ b/util-linux/swaponoff.c
@@ -65,7 +65,6 @@ static void
65do_em_all() 65do_em_all()
66{ 66{
67 struct mntent *m; 67 struct mntent *m;
68 char swapName[NAME_MAX];
69 FILE *f = setmntent ("/etc/fstab", "r"); 68 FILE *f = setmntent ("/etc/fstab", "r");
70 69
71 if (f == NULL) { 70 if (f == NULL) {
@@ -73,8 +72,8 @@ do_em_all()
73 exit( FALSE); 72 exit( FALSE);
74 } 73 }
75 while ((m = getmntent (f)) != NULL) { 74 while ((m = getmntent (f)) != NULL) {
76 if (!strstr (m->mnt_type, "swap")) { 75 if (!strstr (m->mnt_type, MNTTYPE_SWAP)) {
77 swap_enable_disable( swapName); 76 swap_enable_disable( m->mnt_fsname);
78 } 77 }
79 } 78 }
80 endmntent (f); 79 endmntent (f);
diff --git a/util-linux/umount.c b/util-linux/umount.c
index 68b27e385..b65caf76e 100644
--- a/util-linux/umount.c
+++ b/util-linux/umount.c
@@ -37,11 +37,24 @@ static const char umount_usage[] =
37#else 37#else
38"\n" 38"\n"
39#endif 39#endif
40#ifdef BB_FEATURE_REMOUNT
41"\t-r:\tTry to remount devices as read-only if mount is busy\n"
42#endif
40; 43;
41 44
45struct _mtab_entry_t {
46 char *device;
47 char *mountpt;
48 struct _mtab_entry_t *next;
49};
50
51static struct _mtab_entry_t *mtab_cache = NULL;
52
53
42 54
43static int useMtab = TRUE; 55static int useMtab = TRUE;
44static int umountAll = FALSE; 56static int umountAll = FALSE;
57static int doRemount = FALSE;
45extern const char mtab_file[]; /* Defined in utility.c */ 58extern const char mtab_file[]; /* Defined in utility.c */
46 59
47#define MIN(x,y) (x > y ? x : y) 60#define MIN(x,y) (x > y ? x : y)
@@ -50,21 +63,10 @@ static int
50do_umount(const char* name, int useMtab) 63do_umount(const char* name, int useMtab)
51{ 64{
52 int status; 65 int status;
53 struct mntent *m; 66 char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE);
54 FILE *mountTable; 67
55 const char *blockDevice = NULL; 68 if (blockDevice && strcmp(blockDevice, name) == 0)
56 69 name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT);
57 if ((mountTable = setmntent (mtab_file, "r"))) {
58 while ((m = getmntent (mountTable)) != 0) {
59 if (strncmp(m->mnt_dir, name,
60 MIN(strlen(m->mnt_dir),strlen(name))) == 0)
61 blockDevice = m->mnt_fsname;
62 else if (strcmp(m->mnt_fsname, name) == 0) {
63 blockDevice = name;
64 name = m->mnt_dir;
65 }
66 }
67 }
68 70
69 status = umount(name); 71 status = umount(name);
70 72
@@ -73,57 +75,53 @@ do_umount(const char* name, int useMtab)
73 /* this was a loop device, delete it */ 75 /* this was a loop device, delete it */
74 del_loop(blockDevice); 76 del_loop(blockDevice);
75#endif 77#endif
76#if defined BB_MTAB 78#if defined BB_FEATURE_REMOUNT
79 if ( status != 0 && doRemount == TRUE && errno == EBUSY ) {
80 status = mount(blockDevice, name, NULL,
81 MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
82 if (status == 0) {
83 fprintf(stderr, "umount: %s busy - remounted read-only\n",
84 blockDevice);
85 /* TODO: update mtab if BB_MTAB is defined */
86 } else {
87 fprintf(stderr, "umount: Cannot remount %s read-only\n",
88 blockDevice);
89 }
90 }
91#endif
77 if ( status == 0 ) { 92 if ( status == 0 ) {
93#if defined BB_MTAB
78 if ( useMtab==TRUE ) 94 if ( useMtab==TRUE )
79 erase_mtab(name); 95 erase_mtab(name);
80 return 0;
81 }
82 else
83#endif 96#endif
84 return(status); 97 return( TRUE);
98 }
99 return(FALSE);
85} 100}
86 101
87static int 102static int
88umount_all(int useMtab) 103umount_all(int useMtab)
89{ 104{
90 int status; 105 int status = TRUE;
91 struct mntent *m; 106 char *mountpt;
92 FILE *mountTable; 107 void *iter;
93 108
94 if ((mountTable = setmntent (mtab_file, "r"))) { 109 for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) {
95 while ((m = getmntent (mountTable)) != 0) { 110 status=do_umount (mountpt, useMtab);
96 char *blockDevice = m->mnt_fsname; 111 if (status != 0) {
97#if ! defined BB_MTAB 112 /* Don't bother retrying the umount on busy devices */
98 if (strcmp (blockDevice, "/dev/root") == 0) { 113 if (errno == EBUSY) {
99 struct fstab* fstabItem; 114 perror(mountpt);
100 fstabItem = getfsfile ("/"); 115 continue;
101 if (fstabItem != NULL) {
102 blockDevice = fstabItem->fs_spec;
103 }
104 } 116 }
105#endif 117 status = do_umount (mountpt, useMtab);
106 /* Don't umount /proc when doing umount -a */ 118 if (status != 0) {
107 if (strcmp (blockDevice, "proc") == 0) 119 printf ("Couldn't umount %s on %s: %s\n",
108 continue; 120 mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), strerror(errno));
109
110 status=do_umount (m->mnt_dir, useMtab);
111 if (status!=0) {
112 /* Don't bother retrying the umount on busy devices */
113 if (errno==EBUSY) {
114 perror(m->mnt_dir);
115 continue;
116 }
117 status=do_umount (blockDevice, useMtab);
118 if (status!=0) {
119 printf ("Couldn't umount %s on %s (type %s): %s\n",
120 blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
121 }
122 } 121 }
123 } 122 }
124 endmntent (mountTable);
125 } 123 }
126 return( TRUE); 124 return (status);
127} 125}
128 126
129extern int 127extern int
@@ -144,13 +142,18 @@ umount_main(int argc, char** argv)
144 useMtab = FALSE; 142 useMtab = FALSE;
145 break; 143 break;
146#endif 144#endif
145#ifdef BB_FEATURE_REMOUNT
146 case 'r':
147 doRemount = TRUE;
148 break;
149#endif
147 default: 150 default:
148 usage( umount_usage); 151 usage( umount_usage);
149 } 152 }
150 } 153 }
151 154
152 155 mtab_read();
153 if(umountAll==TRUE) { 156 if (umountAll==TRUE) {
154 exit(umount_all(useMtab)); 157 exit(umount_all(useMtab));
155 } 158 }
156 if ( do_umount(*argv,useMtab) == 0 ) 159 if ( do_umount(*argv,useMtab) == 0 )
@@ -161,3 +164,87 @@ umount_main(int argc, char** argv)
161 } 164 }
162} 165}
163 166
167
168
169/* These functions are here because the getmntent functions do not appear
170 * to be re-entrant, which leads to all sorts of problems when we try to
171 * use them recursively - randolph
172 */
173void mtab_read(void)
174{
175 struct _mtab_entry_t *entry = NULL;
176 struct mntent *e;
177 FILE *fp;
178
179 if (mtab_cache != NULL) return;
180
181 if ((fp = setmntent(mtab_file, "r")) == NULL) {
182 fprintf(stderr, "Cannot open %s\n", mtab_file);
183 return;
184 }
185 while ((e = getmntent(fp))) {
186 entry = malloc(sizeof(struct _mtab_entry_t));
187 entry->device = strdup(e->mnt_fsname);
188 entry->mountpt = strdup(e->mnt_dir);
189 entry->next = mtab_cache;
190 mtab_cache = entry;
191 }
192 endmntent(fp);
193}
194
195char *mtab_getinfo(const char *match, const char which)
196{
197 struct _mtab_entry_t *cur = mtab_cache;
198 while (cur) {
199 if (strcmp(cur->mountpt, match) == 0 ||
200 strcmp(cur->device, match) == 0) {
201 if (which == MTAB_GETMOUNTPT) {
202 return cur->mountpt;
203 } else {
204#if !defined BB_MTAB
205 if (strcmp(cur->device, "/dev/root") == 0) {
206 struct fstab* fstabItem;
207 fstabItem = getfsfile ("/");
208 if (fstabItem != NULL) return fstabItem->fs_spec;
209 }
210#endif
211 return cur->device;
212 }
213 }
214 cur = cur->next;
215 }
216 return NULL;
217}
218
219char *mtab_first(void **iter)
220{
221 struct _mtab_entry_t *mtab_iter;
222 if (!iter) return NULL;
223 mtab_iter = mtab_cache;
224 *iter = (void *)mtab_iter;
225 return mtab_next(iter);
226}
227
228char *mtab_next(void **iter)
229{
230 char *mp;
231 if (iter == NULL || *iter == NULL) return NULL;
232 mp = ((struct _mtab_entry_t *)(*iter))->mountpt;
233 *iter = (void *)((struct _mtab_entry_t *)(*iter))->next;
234 return mp;
235}
236
237void mtab_free(void)
238{
239 struct _mtab_entry_t *this, *next;
240
241 this = mtab_cache;
242 while (this) {
243 next = this->next;
244 if (this->device) free(this->device);
245 if (this->mountpt) free(this->mountpt);
246 free(this);
247 this = next;
248 }
249}
250
diff --git a/utility.c b/utility.c
index 191701bed..a27aaa2ae 100644
--- a/utility.c
+++ b/utility.c
@@ -25,6 +25,17 @@
25 */ 25 */
26 26
27#include "internal.h" 27#include "internal.h"
28#if defined (BB_CHMOD_CHOWN_CHGRP) \
29 || defined (BB_CP_MV) \
30 || defined (BB_FIND) \
31 || defined (BB_LS) \
32 || defined (BB_INSMOD)
33/* same conditions as recursiveAction */
34#define bb_need_name_too_long
35#endif
36#define BB_DECLARE_EXTERN
37#include "messages.c"
38
28#include <stdio.h> 39#include <stdio.h>
29#include <string.h> 40#include <string.h>
30#include <errno.h> 41#include <errno.h>
@@ -35,6 +46,7 @@
35#include <sys/stat.h> 46#include <sys/stat.h>
36#include <unistd.h> 47#include <unistd.h>
37#include <ctype.h> 48#include <ctype.h>
49#include <sys/param.h> /* for PATH_MAX */
38 50
39#if defined BB_FEATURE_MOUNT_LOOP 51#if defined BB_FEATURE_MOUNT_LOOP
40#include <fcntl.h> 52#include <fcntl.h>
@@ -58,9 +70,10 @@ const char mtab_file[] = "/etc/mtab";
58 70
59extern void usage(const char *usage) 71extern void usage(const char *usage)
60{ 72{
61 fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n", BB_VER, BB_BT); 73 fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n",
74 BB_VER, BB_BT);
62 fprintf(stderr, "Usage: %s\n", usage); 75 fprintf(stderr, "Usage: %s\n", usage);
63 exit(FALSE); 76 exit FALSE;
64} 77}
65 78
66 79
@@ -78,9 +91,8 @@ get_kernel_revision()
78{ 91{
79 FILE *file; 92 FILE *file;
80 int major=0, minor=0, patch=0; 93 int major=0, minor=0, patch=0;
81 char* filename="/proc/sys/kernel/osrelease";
82 94
83 file = fopen(filename,"r"); 95 file = fopen("/proc/sys/kernel/osrelease", "r");
84 if (file == NULL) { 96 if (file == NULL) {
85 /* bummer, /proc must not be mounted... */ 97 /* bummer, /proc must not be mounted... */
86 return( 0); 98 return( 0);
@@ -89,28 +101,34 @@ get_kernel_revision()
89 fclose(file); 101 fclose(file);
90 return major*65536 + minor*256 + patch; 102 return major*65536 + minor*256 + patch;
91} 103}
104#endif /* BB_INIT || BB_PS */
92 105
93#endif
94 106
95 107
96 108#if defined (BB_CP_MV) || defined (BB_DU) || defined (BB_LN)
97#if defined (BB_CP) || defined (BB_MV)
98/* 109/*
99 * Return TRUE if a fileName is a directory. 110 * Return TRUE if a fileName is a directory.
100 * Nonexistant files return FALSE. 111 * Nonexistant files return FALSE.
101 */ 112 */
102int isDirectory(const char *name) 113int isDirectory(const char *fileName, const int followLinks)
103{ 114{
104 struct stat statBuf; 115 struct stat statBuf;
116 int status;
105 117
106 if (stat(name, &statBuf) < 0) 118 if (followLinks == TRUE)
107 return FALSE; 119 status = stat(fileName, &statBuf);
120 else
121 status = lstat(fileName, &statBuf);
122
123 if (status < 0)
124 return FALSE;
108 if (S_ISDIR(statBuf.st_mode)) 125 if (S_ISDIR(statBuf.st_mode))
109 return TRUE; 126 return TRUE;
110 return(FALSE); 127 return FALSE;
111} 128}
129#endif
112 130
113 131#if defined (BB_CP_MV)
114/* 132/*
115 * Copy one file to another, while possibly preserving its modes, times, 133 * Copy one file to another, while possibly preserving its modes, times,
116 * and modes. Returns TRUE if successful, or FALSE on a failure with an 134 * and modes. Returns TRUE if successful, or FALSE on a failure with an
@@ -120,33 +138,33 @@ int isDirectory(const char *name)
120 */ 138 */
121int 139int
122copyFile( const char *srcName, const char *destName, 140copyFile( const char *srcName, const char *destName,
123 int setModes, int followLinks) 141 int setModes, int followLinks)
124{ 142{
125 int rfd; 143 int rfd;
126 int wfd; 144 int wfd;
127 int rcc; 145 int rcc;
128 int result; 146 int status;
129 char buf[BUF_SIZE]; 147 char buf[BUF_SIZE];
130 struct stat srcStatBuf; 148 struct stat srcStatBuf;
131 struct stat dstStatBuf; 149 struct stat dstStatBuf;
132 struct utimbuf times; 150 struct utimbuf times;
133 151
134 /* Grab the source file's stats */ 152 if (followLinks == TRUE)
135 if (followLinks == FALSE) 153 status = stat(srcName, &srcStatBuf);
136 result = stat(srcName, &srcStatBuf);
137 else 154 else
138 result = lstat(srcName, &srcStatBuf); 155 status = lstat(srcName, &srcStatBuf);
139 if (result < 0) { 156
157 if (status < 0) {
140 perror(srcName); 158 perror(srcName);
141 return FALSE; 159 return FALSE;
142 } 160 }
143 161
144 /* Grab the dest file's stats */ 162 if (followLinks == TRUE)
145 if (followLinks == FALSE) 163 status = stat(destName, &dstStatBuf);
146 result = stat(destName, &dstStatBuf); 164 else
147 else 165 status = lstat(destName, &dstStatBuf);
148 result = lstat(destName, &dstStatBuf); 166
149 if (result < 0) { 167 if (status < 0) {
150 dstStatBuf.st_ino = -1; 168 dstStatBuf.st_ino = -1;
151 dstStatBuf.st_dev = -1; 169 dstStatBuf.st_dev = -1;
152 } 170 }
@@ -160,45 +178,49 @@ copyFile( const char *srcName, const char *destName,
160 if (S_ISDIR(srcStatBuf.st_mode)) { 178 if (S_ISDIR(srcStatBuf.st_mode)) {
161 //fprintf(stderr, "copying directory %s to %s\n", srcName, destName); 179 //fprintf(stderr, "copying directory %s to %s\n", srcName, destName);
162 /* Make sure the directory is writable */ 180 /* Make sure the directory is writable */
163 result = mkdir(destName, 0777777 ^ umask(0)); 181 status = mkdir(destName, 0777777 ^ umask(0));
164 if (result < 0 && errno != EEXIST) { 182 if (status < 0 && errno != EEXIST) {
165 perror(destName); 183 perror(destName);
166 return (FALSE); 184 return FALSE;
167 } 185 }
168 } else if (S_ISLNK(srcStatBuf.st_mode)) { 186 } else if (S_ISLNK(srcStatBuf.st_mode)) {
169 char *link_val; 187 char link_val[PATH_MAX + 1];
170 int link_size; 188 int link_size;
171 189
172 //fprintf(stderr, "copying link %s to %s\n", srcName, destName); 190 //fprintf(stderr, "copying link %s to %s\n", srcName, destName);
173 link_val = (char *) alloca(PATH_MAX + 2); 191 /* Warning: This could possibly truncate silently, to PATH_MAX chars */
174 link_size = readlink(srcName, link_val, PATH_MAX + 1); 192 link_size = readlink(srcName, &link_val[0], PATH_MAX);
175 if (link_size < 0) { 193 if (link_size < 0) {
176 perror(srcName); 194 perror(srcName);
177 return (FALSE); 195 return FALSE;
178 } 196 }
179 link_val[link_size] = '\0'; 197 link_val[link_size] = '\0';
180 link_size = symlink(link_val, destName); 198 status = symlink(link_val, destName);
181 if (link_size != 0) { 199 if (status < 0) {
182 perror(destName); 200 perror(destName);
183 return (FALSE); 201 return FALSE;
184 } 202 }
185#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) 203#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
186 if (setModes == TRUE) { 204 if (setModes == TRUE) {
187 lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid); 205 if (lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) {
206 perror(destName);
207 return FALSE;
208 }
188 } 209 }
189#endif 210#endif
211 return TRUE;
190 } else if (S_ISFIFO(srcStatBuf.st_mode)) { 212 } else if (S_ISFIFO(srcStatBuf.st_mode)) {
191 //fprintf(stderr, "copying fifo %s to %s\n", srcName, destName); 213 //fprintf(stderr, "copying fifo %s to %s\n", srcName, destName);
192 if (mkfifo(destName, 0644)) { 214 if (mkfifo(destName, 0644) < 0) {
193 perror(destName); 215 perror(destName);
194 return (FALSE); 216 return FALSE;
195 } 217 }
196 } else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode) 218 } else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode)
197 || S_ISSOCK (srcStatBuf.st_mode)) { 219 || S_ISSOCK (srcStatBuf.st_mode)) {
198 //fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName); 220 //fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName);
199 if (mknod(destName, srcStatBuf.st_mode, srcStatBuf.st_rdev)) { 221 if (mknod(destName, srcStatBuf.st_mode, srcStatBuf.st_rdev) < 0) {
200 perror(destName); 222 perror(destName);
201 return (FALSE); 223 return FALSE;
202 } 224 }
203 } else if (S_ISREG(srcStatBuf.st_mode)) { 225 } else if (S_ISREG(srcStatBuf.st_mode)) {
204 //fprintf(stderr, "copying regular file %s to %s\n", srcName, destName); 226 //fprintf(stderr, "copying regular file %s to %s\n", srcName, destName);
@@ -208,7 +230,7 @@ copyFile( const char *srcName, const char *destName,
208 return FALSE; 230 return FALSE;
209 } 231 }
210 232
211 wfd = creat(destName, srcStatBuf.st_mode); 233 wfd = open(destName, O_WRONLY | O_CREAT | O_TRUNC, srcStatBuf.st_mode);
212 if (wfd < 0) { 234 if (wfd < 0) {
213 perror(destName); 235 perror(destName);
214 close(rfd); 236 close(rfd);
@@ -231,24 +253,32 @@ copyFile( const char *srcName, const char *destName,
231 253
232 if (setModes == TRUE) { 254 if (setModes == TRUE) {
233 /* This is fine, since symlinks never get here */ 255 /* This is fine, since symlinks never get here */
234 chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid); 256 if (chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) {
235 chmod(destName, srcStatBuf.st_mode); 257 perror(destName);
258 exit FALSE;
259 }
260 if (chmod(destName, srcStatBuf.st_mode) < 0) {
261 perror(destName);
262 exit FALSE;
263 }
236 times.actime = srcStatBuf.st_atime; 264 times.actime = srcStatBuf.st_atime;
237 times.modtime = srcStatBuf.st_mtime; 265 times.modtime = srcStatBuf.st_mtime;
238 utime(destName, &times); 266 if (utime(destName, &times) < 0) {
267 perror(destName);
268 exit FALSE;
269 }
239 } 270 }
240 271
241 return TRUE; 272 return TRUE;
242 273
243 274 error_exit:
244 error_exit:
245 perror(destName); 275 perror(destName);
246 close(rfd); 276 close(rfd);
247 close(wfd); 277 close(wfd);
248 278
249 return FALSE; 279 return FALSE;
250} 280}
251#endif 281#endif /* BB_CP_MV */
252 282
253 283
254 284
@@ -296,7 +326,7 @@ const char *modeString(int mode)
296 } 326 }
297 return buf; 327 return buf;
298} 328}
299#endif 329#endif /* BB_TAR || BB_LS */
300 330
301 331
302#if defined BB_TAR 332#if defined BB_TAR
@@ -324,9 +354,9 @@ const char *timeString(time_t timeVal)
324 354
325 return buf; 355 return buf;
326} 356}
327#endif 357#endif /* BB_TAR */
328 358
329#if defined BB_TAR || defined BB_CP || defined BB_MV 359#if defined BB_TAR || defined BB_CP_MV
330/* 360/*
331 * Write all of the supplied buffer out to a file. 361 * Write all of the supplied buffer out to a file.
332 * This does multiple writes as necessary. 362 * This does multiple writes as necessary.
@@ -352,7 +382,7 @@ int fullWrite(int fd, const char *buf, int len)
352 382
353 return total; 383 return total;
354} 384}
355#endif 385#endif /* BB_TAR || BB_CP_MV */
356 386
357 387
358#if defined BB_TAR || defined BB_TAIL 388#if defined BB_TAR || defined BB_TAIL
@@ -385,10 +415,14 @@ int fullRead(int fd, char *buf, int len)
385 415
386 return total; 416 return total;
387} 417}
388#endif 418#endif /* BB_TAR || BB_TAIL */
389 419
390 420
391#if defined (BB_CHMOD_CHOWN_CHGRP) || defined (BB_CP) || defined (BB_FIND) || defined (BB_LS) || defined (BB_INSMOD) 421#if defined (BB_CHMOD_CHOWN_CHGRP) \
422 || defined (BB_CP_MV) \
423 || defined (BB_FIND) \
424 || defined (BB_LS) \
425 || defined (BB_INSMOD)
392/* 426/*
393 * Walk down all the directories under the specified 427 * Walk down all the directories under the specified
394 * location, and do something (something specified 428 * location, and do something (something specified
@@ -399,13 +433,15 @@ int fullRead(int fd, char *buf, int len)
399 * and so isn't sufficiently portable to take over since glibc2.1 433 * and so isn't sufficiently portable to take over since glibc2.1
400 * is so stinking huge. 434 * is so stinking huge.
401 */ 435 */
402int 436int recursiveAction(const char *fileName,
403recursiveAction(const char *fileName, int recurse, int followLinks, int depthFirst, 437 int recurse, int followLinks, int depthFirst,
404 int (*fileAction) (const char *fileName, struct stat* statbuf), 438 int (*fileAction) (const char *fileName,
405 int (*dirAction) (const char *fileName, struct stat* statbuf)) 439 struct stat* statbuf),
440 int (*dirAction) (const char *fileName,
441 struct stat* statbuf))
406{ 442{
407 int status; 443 int status;
408 struct stat statbuf, statbuf1; 444 struct stat statbuf;
409 struct dirent *next; 445 struct dirent *next;
410 446
411 if (followLinks == TRUE) 447 if (followLinks == TRUE)
@@ -414,16 +450,20 @@ recursiveAction(const char *fileName, int recurse, int followLinks, int depthFir
414 status = lstat(fileName, &statbuf); 450 status = lstat(fileName, &statbuf);
415 451
416 if (status < 0) { 452 if (status < 0) {
417 //fprintf(stderr, "status=%d followLinks=%d TRUE=%d\n", status, followLinks, TRUE); 453#ifdef BB_DEBUG_PRINT_SCAFFOLD
454 fprintf(stderr,
455 "status=%d followLinks=%d TRUE=%d\n",
456 status, followLinks, TRUE);
457#endif
418 perror(fileName); 458 perror(fileName);
419 return (FALSE); 459 return FALSE;
420 } 460 }
421 461
422 if ( (followLinks == FALSE) && (S_ISLNK(statbuf.st_mode)) ) { 462 if ((followLinks == FALSE) && (S_ISLNK(statbuf.st_mode)) ) {
423 if (fileAction == NULL) 463 if (fileAction == NULL)
424 return (TRUE); 464 return TRUE;
425 else 465 else
426 return (fileAction(fileName, &statbuf)); 466 return fileAction(fileName, &statbuf);
427 } 467 }
428 468
429 if (recurse == FALSE) { 469 if (recurse == FALSE) {
@@ -431,67 +471,65 @@ recursiveAction(const char *fileName, int recurse, int followLinks, int depthFir
431 if (dirAction != NULL) 471 if (dirAction != NULL)
432 return (dirAction(fileName, &statbuf)); 472 return (dirAction(fileName, &statbuf));
433 else 473 else
434 return (TRUE); 474 return TRUE;
435 } 475 }
436 }
437
438 status = lstat(fileName, &statbuf1);
439 if (status < 0) {
440 perror(fileName);
441 return (FALSE);
442 } 476 }
443 477
444 if (S_ISDIR(statbuf.st_mode) && S_ISDIR(statbuf1.st_mode)) { 478 if (S_ISDIR(statbuf.st_mode)) {
445 DIR *dir; 479 DIR *dir;
446 dir = opendir(fileName); 480 dir = opendir(fileName);
447 if (!dir) { 481 if (!dir) {
448 perror(fileName); 482 perror(fileName);
449 return (FALSE); 483 return FALSE;
450 } 484 }
451 if (dirAction != NULL && depthFirst == FALSE) { 485 if (dirAction != NULL && depthFirst == FALSE) {
452 status = dirAction(fileName, &statbuf); 486 status = dirAction(fileName, &statbuf);
453 if (status == FALSE) { 487 if (status == FALSE) {
454 perror(fileName); 488 perror(fileName);
455 return (FALSE); 489 return FALSE;
456 } 490 }
457 } 491 }
458 while ((next = readdir(dir)) != NULL) { 492 while ((next = readdir(dir)) != NULL) {
459 char nextFile[NAME_MAX]; 493 char nextFile[PATH_MAX + 1];
460 if ((strcmp(next->d_name, "..") == 0) 494 if ((strcmp(next->d_name, "..") == 0)
461 || (strcmp(next->d_name, ".") == 0)) { 495 || (strcmp(next->d_name, ".") == 0)) {
462 continue; 496 continue;
463 } 497 }
498 if (strlen(fileName) + strlen(next->d_name) + 1 > PATH_MAX) {
499 fprintf(stderr, name_too_long, "ftw");
500 return FALSE;
501 }
464 sprintf(nextFile, "%s/%s", fileName, next->d_name); 502 sprintf(nextFile, "%s/%s", fileName, next->d_name);
465 status = 503 status =
466 recursiveAction(nextFile, TRUE, followLinks, depthFirst, 504 recursiveAction(nextFile, TRUE, followLinks, depthFirst,
467 fileAction, dirAction); 505 fileAction, dirAction);
468 if (status < 0) { 506 if (status < 0) {
469 closedir(dir); 507 closedir(dir);
470 return (FALSE); 508 return FALSE;
471 } 509 }
472 } 510 }
473 status = closedir(dir); 511 status = closedir(dir);
474 if (status < 0) { 512 if (status < 0) {
475 perror(fileName); 513 perror(fileName);
476 return (FALSE); 514 return FALSE;
477 } 515 }
478 if (dirAction != NULL && depthFirst == TRUE) { 516 if (dirAction != NULL && depthFirst == TRUE) {
479 status = dirAction(fileName, &statbuf); 517 status = dirAction(fileName, &statbuf);
480 if (status == FALSE) { 518 if (status == FALSE) {
481 perror(fileName); 519 perror(fileName);
482 return (FALSE); 520 return FALSE;
483 } 521 }
484 } 522 }
485 } else { 523 } else {
486 if (fileAction == NULL) 524 if (fileAction == NULL)
487 return (TRUE); 525 return TRUE;
488 else 526 else
489 return (fileAction(fileName, &statbuf)); 527 return fileAction(fileName, &statbuf);
490 } 528 }
491 return (TRUE); 529 return TRUE;
492} 530}
493 531
494#endif 532#endif /* BB_CHMOD_CHOWN_CHGRP || BB_CP_MV || BB_FIND || BB_LS || BB_INSMOD */
495 533
496 534
497 535
@@ -506,25 +544,25 @@ extern int createPath (const char *name, int mode)
506{ 544{
507 char *cp; 545 char *cp;
508 char *cpOld; 546 char *cpOld;
509 char buf[NAME_MAX]; 547 char buf[PATH_MAX + 1];
510 int retVal=0; 548 int retVal=0;
511 549
512 strcpy( buf, name); 550 strcpy( buf, name);
513 cp = strchr (buf, '/'); 551 cp = strchr(buf, '/');
514 while (cp) { 552 while (cp) {
515 cpOld = cp; 553 cpOld = cp;
516 cp = strchr (cp + 1, '/'); 554 cp = strchr(cp + 1, '/');
517 *cpOld = '\0'; 555 *cpOld = '\0';
518 retVal = mkdir (buf, cp ? 0777 : mode); 556 retVal = mkdir(buf, cp ? 0777 : mode);
519 if (retVal != 0 && errno != EEXIST) { 557 if (retVal != 0 && errno != EEXIST) {
520 perror( buf); 558 perror(buf);
521 return( FALSE); 559 return FALSE;
522 } 560 }
523 *cpOld = '/'; 561 *cpOld = '/';
524 } 562 }
525 return( TRUE); 563 return TRUE;
526} 564}
527#endif 565#endif /* BB_TAR || BB_MKDIR */
528 566
529 567
530 568
@@ -624,7 +662,7 @@ parse_mode( const char* s, mode_t* theMode)
624} 662}
625 663
626 664
627#endif 665#endif /* BB_CHMOD_CHOWN_CHGRP || BB_MKDIR */
628 666
629 667
630 668
@@ -712,7 +750,7 @@ my_getgrgid(char* group, gid_t gid)
712} 750}
713 751
714 752
715#endif 753#endif /* BB_CHMOD_CHOWN_CHGRP || BB_PS */
716 754
717 755
718 756
@@ -804,7 +842,7 @@ int get_console_fd(char* tty_name)
804} 842}
805 843
806 844
807#endif 845#endif /* BB_CHVT || BB_DEALLOCVT */
808 846
809 847
810#if !defined BB_REGEXP && (defined BB_GREP || defined BB_SED) 848#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
883 return FALSE; 921 return FALSE;
884} 922}
885 923
886 924#endif /* ! BB_REGEXP && (BB_GREP || BB_SED) */
887#endif
888 925
889 926
890#if defined BB_FIND 927#if defined BB_FIND
@@ -986,7 +1023,7 @@ check_wildcard_match(const char* text, const char* pattern)
986 1023
987 return TRUE; 1024 return TRUE;
988} 1025}
989#endif 1026#endif /* BB_FIND */
990 1027
991 1028
992 1029
@@ -1030,7 +1067,7 @@ extern struct mntent *findMountPoint(const char *name, const char *table)
1030 endmntent(mountTable); 1067 endmntent(mountTable);
1031 return mountEntry; 1068 return mountEntry;
1032} 1069}
1033#endif 1070#endif /* BB_DF || BB_MTAB */
1034 1071
1035 1072
1036 1073
@@ -1052,7 +1089,8 @@ extern long getNum (const char *cp)
1052 value = value * 10 + *cp++ - '0'; 1089 value = value * 10 + *cp++ - '0';
1053 1090
1054 switch (*cp++) { 1091 switch (*cp++) {
1055 case 'm': 1092 case 'M':
1093 case 'm': /* `tail' uses it traditionally */
1056 value *= 1048576; 1094 value *= 1048576;
1057 break; 1095 break;
1058 1096
@@ -1080,7 +1118,7 @@ extern long getNum (const char *cp)
1080 1118
1081 return value; 1119 return value;
1082} 1120}
1083#endif 1121#endif /* BB_DD || BB_TAIL */
1084 1122
1085 1123
1086#if defined BB_INIT || defined BB_HALT || defined BB_REBOOT 1124#if defined BB_INIT || defined BB_HALT || defined BB_REBOOT
@@ -1120,9 +1158,12 @@ findInitPid()
1120 } 1158 }
1121 return 0; 1159 return 0;
1122} 1160}
1123#endif 1161#endif /* BB_INIT || BB_HALT || BB_REBOOT */
1124 1162
1125#if defined BB_GUNZIP || defined BB_GZIP || defined BB_PRINTF || defined BB_TAIL 1163#if defined BB_GUNZIP \
1164 || defined BB_GZIP \
1165 || defined BB_PRINTF \
1166 || defined BB_TAIL
1126extern void *xmalloc (size_t size) 1167extern void *xmalloc (size_t size)
1127{ 1168{
1128 void *cp = malloc (size); 1169 void *cp = malloc (size);
@@ -1138,7 +1179,7 @@ extern void error(char *msg)
1138 fprintf(stderr, "\n%s\n", msg); 1179 fprintf(stderr, "\n%s\n", msg);
1139 exit(1); 1180 exit(1);
1140} 1181}
1141#endif 1182#endif /* BB_GUNZIP || BB_GZIP || BB_PRINTF || BB_TAIL */
1142 1183
1143#if (__GLIBC__ < 2) && (defined BB_SYSLOGD || defined BB_INIT) 1184#if (__GLIBC__ < 2) && (defined BB_SYSLOGD || defined BB_INIT)
1144extern int vdprintf(int d, const char *format, va_list ap) 1185extern 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)
1149 len = vsprintf(buf, format, ap); 1190 len = vsprintf(buf, format, ap);
1150 return write(d, buf, len); 1191 return write(d, buf, len);
1151} 1192}
1152#endif 1193#endif /* BB_SYSLOGD */
1153 1194
1154#if defined BB_FEATURE_MOUNT_LOOP 1195#if defined BB_FEATURE_MOUNT_LOOP
1155extern int del_loop(const char *device) 1196extern int del_loop(const char *device)