A few minor updates. ;-)

Seriously though, read the Changelog for busybox 0.42,
which this is about to become...
 -Erik
This commit is contained in:
Erik Andersen 2000-02-07 05:29:42 +00:00
parent 50bc101b7d
commit fac10d7c59
76 changed files with 1849 additions and 1023 deletions

View File

@ -1,4 +1,41 @@
0.42 0.42
* Fairly massive restructuring of umount.c to deal with remounting
busy devices read-only. Adds a -r option to control that; it is
optionally compiled in with BB_FEATURE_REMOUNT
* Added a bunch of functions to mtab.c to interact with the
{get,set,end}mntent interface; as it turns out, those functions do
not appear to be re-entrant, and that causes a lot of problems with
the way umount was originally written.
* Makes init send TERM and KILL (instead of HUP and KILL) on reboot
to be more consistent with sysvinit
* Changes to init.c to use the new -r option to umount. Also increased
the sleep time between the time the TERM and KILL signals are sent
- Randolph Chung
* cp.c, mv.c: removed, replaced by cp_mv.c which has been
extensively rewritten from the original cp.c.
* Also added a warning message to the `mv' usage string saying that
this is not GNU mv, and it will break hard links. cp also breaks
hard links.
* ln.c: implemented `-n' switch, no-deref symlinks.
* include<sys/param.h>: and use PATH_MAX everywhere.
* busybox: File name buffer overrun guards to prevent future crashes.
- Always check exit status.
- Purge all use of `creat()', replace with `open()'.
* utility.c
- recursiveAction was overriding the value of
followLinks thus ignoring it.
- isDirectory now takes a followLinks boolean, updated all callers
- copyFile had the followLinks logic reversed.
* messages.c: New file. Put common error message strings all in
one place in an attempt to shrink the binary a little.
-Karl M. Hegbloom
* Made tar creation support in busybox tar optional. * Made tar creation support in busybox tar optional.
* You no longer _have_ to put a "-" in front of tar options. * You no longer _have_ to put a "-" in front of tar options.
* Tar could inadvertently change permissions and ownership on * Tar could inadvertently change permissions and ownership on
@ -16,11 +53,11 @@
for the kernel init chroot patch by Werner Almesberger, which for the kernel init chroot patch by Werner Almesberger, which
allows init to chroot to a new device, and umount the old one. allows init to chroot to a new device, and umount the old one.
* Fixed bug that wouldn't let one chown a symlink -- it would * Fixed bug that wouldn't let one chown a symlink -- it would
always dereference before. -beppu always dereference before. -beppu
* Fixed a bug where init could have reference already freed memory. * Fixed a bug where init could have reference already freed memory.
Found and fixed by Taketoshi Sano <kgh12351@nifty.ne.jp> Found and fixed by Taketoshi Sano <kgh12351@nifty.ne.jp>
* Several contributions from Friedrich Vedder <fwv@myrtle.lahn.de> * Several contributions from Friedrich Vedder <fwv@myrtle.lahn.de>
* added (and documented) "-n" option for head - * Added (and documented) "-n" option for head -
* Cleanup for a number of usage messages -- also * Cleanup for a number of usage messages -- also
contributed Friedrich Vedder <fwv@myrtle.lahn.de> contributed Friedrich Vedder <fwv@myrtle.lahn.de>
* Cosmetic fix to busybox.c (Don't print a comma at the * Cosmetic fix to busybox.c (Don't print a comma at the
@ -42,6 +79,11 @@
Randolph Chung <tausq@debian.org>. Randolph Chung <tausq@debian.org>.
* cp could, when copying symlinks, change permissions of the * cp could, when copying symlinks, change permissions of the
files pointed to by the symlinks. files pointed to by the symlinks.
* Several fixes from Pavel Roskin <pavel_roskin@geocities.com>:
- `chown' with 1 argument displayed the error incorrectly
- `fdflush', `length' and `printf' crashed when run without arguments
- `fdflush' tried to flush itself using *argv
- added "skip" and "seek" to dd.
-Erik Andersen -Erik Andersen

103
Makefile
View File

@ -15,71 +15,74 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# #
PROG := busybox
VERSION := 0.42
BUILDTIME := $(shell TZ=GMT date "+%Y%m%d-%H%M")
PROG=busybox # Set the following to `true' to make a debuggable build.
VERSION=0.42 # Leave this set to `false' for production use.
BUILDTIME=$(shell date "+%Y%m%d-%H%M") # eg: `make DODEBUG=true'
DODEBUG = false
# Comment out the following to make a debuggable build
# Leave this off for production use.
DODEBUG=false
# If you want a static binary, turn this on. I can't think # If you want a static binary, turn this on. I can't think
# of many situations where anybody would ever want it static, # of many situations where anybody would ever want it static,
# but... # but...
DOSTATIC=false DOSTATIC = false
#This will choke on a non-debian system # This will choke on a non-debian system
ARCH=`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'` ARCH =`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'`
GCCMAJVERSION=$(shell $(CC) --version | sed -n "s/^\([^\.]*\).*/\1/p" ) CC = gcc
GCCMINVERSION=$(shell $(CC) --version | sed -n "s/^[^\.]*\.\([^\.]*\)[\.].*/\1/p" )
GCCSUPPORTSOPTSIZE=$(shell \ GCCMAJVERSION = $(shell $(CC) --version | sed -n "s/^[^0-9]*\([0-9]\)\.\([0-9].*\)[\.].*/\1/p")
if ( test $(GCCMAJVERSION) -eq 2 ) ; then \ GCCMINVERSION = $(shell $(CC) --version | sed -n "s/^[^0-9]*\([0-9]\)\.\([0-9].*\)[\.].*/\2/p")
if ( test $(GCCMINVERSION) -ge 66 ) ; then \
echo "true"; \
else \ GCCSUPPORTSOPTSIZE = $(shell \
echo "false"; \ if ( test $(GCCMAJVERSION) -eq 2 ) ; then \
fi; \ if ( test $(GCCMINVERSION) -ge 66 ) ; then \
else \ echo "true"; \
if ( test $(GCCMAJVERSION) -gt 2 ) ; then \ else \
echo "true"; \ echo "false"; \
else \ fi; \
echo "false"; \ else \
fi; \ if ( test $(GCCMAJVERSION) -gt 2 ) ; then \
echo "true"; \
else \
echo "false"; \
fi; \
fi; ) fi; )
ifeq ($(GCCSUPPORTSOPTSIZE), true) ifeq ($(GCCSUPPORTSOPTSIZE), true)
OPTIMIZATION=-Os OPTIMIZATION = -Os
else else
OPTIMIZATION=-O2 OPTIMIZATION = -O2
endif endif
# -D_GNU_SOURCE is needed because environ is used in init.c # -D_GNU_SOURCE is needed because environ is used in init.c
ifeq ($(DODEBUG),true) ifeq ($(DODEBUG),true)
CFLAGS+=-Wall -g -D_GNU_SOURCE -DDEBUG_INIT CFLAGS += -Wall -g -D_GNU_SOURCE -DDEBUG_INIT
STRIP= STRIP =
LDFLAGS= LDFLAGS =
else else
CFLAGS+=-Wall $(OPTIMIZATION) -fomit-frame-pointer -fno-builtin -D_GNU_SOURCE CFLAGS += -Wall $(OPTIMIZATION) -fomit-frame-pointer -fno-builtin -D_GNU_SOURCE
LDFLAGS= -s LDFLAGS = -s
STRIP= strip --remove-section=.note --remove-section=.comment $(PROG) STRIP = strip --remove-section=.note --remove-section=.comment $(PROG)
#Only staticly link when _not_ debugging #Only staticly link when _not_ debugging
ifeq ($(DOSTATIC),true) ifeq ($(DOSTATIC),true)
LDFLAGS+= --static LDFLAGS += --static
endif endif
endif endif
ifndef $(PREFIX) ifndef $(PREFIX)
PREFIX=`pwd`/_install PREFIX = `pwd`/_install
endif endif
LIBRARIES= LIBRARIES =
OBJECTS=$(shell ./busybox.sh) OBJECTS = $(shell ./busybox.sh) messages.o utility.o
CFLAGS+= -DBB_VER='"$(VERSION)"' CFLAGS += -DBB_VER='"$(VERSION)"'
CFLAGS+= -DBB_BT='"$(BUILDTIME)"' CFLAGS += -DBB_BT='"$(BUILDTIME)"'
ifdef BB_INIT_SCRIPT ifdef BB_INIT_SCRIPT
CFLAGS += -DINIT_SCRIPT=${BB_INIT_SCRIPT} CFLAGS += -DINIT_SCRIPT=${BB_INIT_SCRIPT}
endif endif
@ -90,7 +93,7 @@ busybox: $(OBJECTS)
$(CC) $(LDFLAGS) -o $(PROG) $(OBJECTS) $(LIBRARIES) $(CC) $(LDFLAGS) -o $(PROG) $(OBJECTS) $(LIBRARIES)
$(STRIP) $(STRIP)
busybox.links: busybox.links: busybox.def.h
- ./busybox.mkll | sort >$@ - ./busybox.mkll | sort >$@
clean: clean:
@ -100,7 +103,7 @@ clean:
distclean: clean distclean: clean
- rm -f $(PROG) - rm -f $(PROG)
$(OBJECTS): busybox.def.h internal.h Makefile $(OBJECTS): %.o: %.c busybox.def.h internal.h Makefile messages.c
install: busybox busybox.links install: busybox busybox.links
./install.sh $(PREFIX) ./install.sh $(PREFIX)
@ -108,6 +111,18 @@ install: busybox busybox.links
dist: release dist: release
release: distclean release: distclean
(cd .. ; rm -rf busybox-$(VERSION) ; cp -a busybox busybox-$(VERSION); rm -rf busybox-$(VERSION)/CVS busybox-$(VERSION)/scripts/CVS busybox-$(VERSION)/docs/CVS busybox-$(VERSION)/.cvsignore ; tar -cvzf busybox-$(VERSION).tar.gz busybox-$(VERSION)) cd ..; \
rm -rf busybox-$(VERSION); \
cp -a busybox busybox-$(VERSION); \
\
find busybox-$(VERSION)/ -type d \
-name CVS \
-print \
| xargs rm -rf; \
\
find busybox-$(VERSION)/ -type f \
-name .cvsignore \
-print \
| xargs rm -f; \
\
tar -cvzf busybox-$(VERSION).tar.gz busybox-$(VERSION)/;

41
TODO
View File

@ -26,3 +26,44 @@ around to it some time. If you have any good ideas, please let me know.
* tr * tr
* expr (maybe?) (ash builtin?) * expr (maybe?) (ash builtin?)
Some known bugs, todo items, etc...
-----------------------
[andersen@slag busybox]$ ./busybox du /bin
6213 /bin
[andersen@slag busybox]$ du /bin
2971 /bin
[andersen@slag busybox]$ du --block-size=512 /bin
5943 /bin
-----------------------
-rw-r--r-- 1000/1000 4398 2000-01-06 21:55 uniq.c
-rw-r--r-- 1000/1000 1568 1999-10-20 18:08 update.c
-rw-r----- 0/1000 1168 2000-01-29 21:03 update.o
-rw-r--r-- 1000/1000 22820 2000-01-05 11:36 utility.c
-rw-r----- 0/1000 7372 2000-01-29 21:03 utility.o
tar: Skipping to next file header
tar: Skipping to next file header
tar: Archive - EOF not on block boundary
tar: Error is not recoverable: exiting now
#1 You are storing by id instead of name like normal tar. Did you realize this?
(or am I missing some compile option? )ctar did not do this, and I don't think
it's a good idea for LRP.
#2
ctar did not produce the EOF error like your tar does. I believe you need to
pad the end of the archive with at least 2 tarsized (512byte) blocks. (I
think???)
#3
There is no exclude file(s) option to tar. LRP's packaging system can not
function without this. Will you have the time to add this soon?

View File

@ -50,8 +50,9 @@ static const struct Applet applets[] = {
#ifdef BB_CHVT //usr/bin #ifdef BB_CHVT //usr/bin
{"chvt", chvt_main}, {"chvt", chvt_main},
#endif #endif
#ifdef BB_CP //bin #ifdef BB_CP_MV //bin
{"cp", cp_main}, {"cp", cp_mv_main},
{"mv", cp_mv_main},
#endif #endif
#ifdef BB_DATE //bin #ifdef BB_DATE //bin
{"date", date_main}, {"date", date_main},
@ -170,10 +171,7 @@ static const struct Applet applets[] = {
#ifdef BB_MT //bin #ifdef BB_MT //bin
{"mt", mt_main}, {"mt", mt_main},
#endif #endif
#ifdef BB_MV //bin #ifdef BB_NSLOOKUP //usr/bin
{"mv", mv_main},
#endif
#ifdef BB_NSLOOKUP //bin
{"nslookup", nslookup_main}, {"nslookup", nslookup_main},
#endif #endif
#ifdef BB_PING //bin #ifdef BB_PING //bin

View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
#Make busybox links list file # Make busybox links list file.
DF="busybox.def.h" DF="busybox.def.h"
MF="busybox.c" MF="busybox.c"

View File

@ -3,6 +3,9 @@
*/ */
#include "internal.h" #include "internal.h"
#define bb_need_name_too_long
#define BB_DECLARE_EXTERN
#include "messages.c"
static const char gunzip_usage[] = static const char gunzip_usage[] =
"gunzip [OPTION]... FILE\n\n" "gunzip [OPTION]... FILE\n\n"
@ -64,6 +67,7 @@ static char *license_msg[] = {
#include <signal.h> #include <signal.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h> #include <errno.h>
#include <sys/param.h> /* for PATH_MAX */
/* #include "tailor.h" */ /* #include "tailor.h" */
@ -627,8 +631,12 @@ typedef RETSIGTYPE (*sig_type) OF((int));
#endif #endif
#define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */ #define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */
#ifndef MAX_PATH_LEN #ifndef MAX_PATH_LEN /* max pathname length */
# define MAX_PATH_LEN 1024 /* max pathname length */ # ifdef PATH_MAX
# define MAX_PATH_LEN PATH_MAX
# else
# define MAX_PATH_LEN 1024
# endif
#endif #endif
#ifndef SEEK_END #ifndef SEEK_END
@ -696,8 +704,8 @@ int gunzip_main (int argc, char** argv)
int delInputFile=0; int delInputFile=0;
struct stat statBuf; struct stat statBuf;
char* delFileName; char* delFileName;
char ifname[MAX_PATH_LEN]; /* input file name */ char ifname[MAX_PATH_LEN + 1]; /* input file name */
char ofname[MAX_PATH_LEN]; /* output file name */ char ofname[MAX_PATH_LEN + 1]; /* output file name */
if (argc==1) if (argc==1)
usage(gunzip_usage); usage(gunzip_usage);
@ -764,7 +772,11 @@ int gunzip_main (int argc, char** argv)
/* Open up the input file */ /* Open up the input file */
if (*argv=='\0') if (*argv=='\0')
usage(gunzip_usage); usage(gunzip_usage);
strncpy(ifname, *argv, MAX_PATH_LEN); if (strlen(*argv) > MAX_PATH_LEN) {
fprintf(stderr, name_too_long, "gunzip");
do_exit(WARNING);
}
strcpy(ifname, *argv);
/* Open input fille */ /* Open input fille */
inFileNum=open( ifname, O_RDONLY); inFileNum=open( ifname, O_RDONLY);
@ -799,7 +811,11 @@ int gunzip_main (int argc, char** argv)
char* pos; char* pos;
/* And get to work */ /* And get to work */
strncpy(ofname, ifname, MAX_PATH_LEN-4); if (strlen(ifname) > MAX_PATH_LEN - 4) {
fprintf(stderr, name_too_long, "gunzip");
do_exit(WARNING);
}
strcpy(ofname, ifname);
pos=strstr(ofname, ".gz"); pos=strstr(ofname, ".gz");
if (pos != NULL) { if (pos != NULL) {
*pos='\0'; *pos='\0';

View File

@ -40,6 +40,7 @@
#include <utime.h> #include <utime.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <sys/param.h> /* for PATH_MAX */
#ifdef BB_FEATURE_TAR_CREATE #ifdef BB_FEATURE_TAR_CREATE
@ -1041,7 +1042,7 @@ static void saveDirectory (const char *dirName, const struct stat *statbuf)
DIR *dir; DIR *dir;
struct dirent *entry; struct dirent *entry;
int needSlash; int needSlash;
char fullName[NAME_MAX]; char fullName[PATH_MAX + 1];
/* /*
* Construct the directory name as used in the tar file by appending * Construct the directory name as used in the tar file by appending

View File

@ -50,8 +50,9 @@ static const struct Applet applets[] = {
#ifdef BB_CHVT //usr/bin #ifdef BB_CHVT //usr/bin
{"chvt", chvt_main}, {"chvt", chvt_main},
#endif #endif
#ifdef BB_CP //bin #ifdef BB_CP_MV //bin
{"cp", cp_main}, {"cp", cp_mv_main},
{"mv", cp_mv_main},
#endif #endif
#ifdef BB_DATE //bin #ifdef BB_DATE //bin
{"date", date_main}, {"date", date_main},
@ -170,10 +171,7 @@ static const struct Applet applets[] = {
#ifdef BB_MT //bin #ifdef BB_MT //bin
{"mt", mt_main}, {"mt", mt_main},
#endif #endif
#ifdef BB_MV //bin #ifdef BB_NSLOOKUP //usr/bin
{"mv", mv_main},
#endif
#ifdef BB_NSLOOKUP //bin
{"nslookup", nslookup_main}, {"nslookup", nslookup_main},
#endif #endif
#ifdef BB_PING //bin #ifdef BB_PING //bin

View File

@ -95,11 +95,6 @@
// //
// //
// //
// Don't turn BB_UTILITY off. It contains support code
// that compiles to 0 if everything else if turned off.
#define BB_UTILITY
//
//
// //
// This is where feature definitions go. Generally speaking, // This is where feature definitions go. Generally speaking,
// turning this stuff off makes things a bit smaller (and less // turning this stuff off makes things a bit smaller (and less
@ -132,7 +127,7 @@
#define BB_FEATURE_USE_INITTAB #define BB_FEATURE_USE_INITTAB
// //
//Enable init being called as /linuxrc //Enable init being called as /linuxrc
#define BB_FEATURE_LINUXRC //#define BB_FEATURE_LINUXRC
// //
// //
//Simple tail implementation (2k vs 6k for the full one). Still //Simple tail implementation (2k vs 6k for the full one). Still
@ -142,6 +137,15 @@
// Enable support for loop devices in mount // Enable support for loop devices in mount
#define BB_FEATURE_MOUNT_LOOP #define BB_FEATURE_MOUNT_LOOP
// //
// Enable support for a real /etc/mtab file instead of /proc/mounts
#ifdef BB_MOUNT
//#define BB_MTAB
#endif
//
//
// Enable support for remounting filesystems
#define BB_FEATURE_REMOUNT
//
// Enable support for creation of tar files. // Enable support for creation of tar files.
//#define BB_FEATURE_TAR_CREATE //#define BB_FEATURE_TAR_CREATE
// //

View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
#Make busybox links list file # Make busybox links list file.
DF="busybox.def.h" DF="busybox.def.h"
MF="busybox.c" MF="busybox.c"

View File

@ -21,10 +21,14 @@
* *
*/ */
#include "internal.h"
#define BB_DECLARE_EXTERN
#define bb_need_invalid_option
#include "messages.c"
#include <stdio.h> #include <stdio.h>
#include <grp.h> #include <grp.h>
#include <pwd.h> #include <pwd.h>
#include "internal.h"
static uid_t uid = -1; static uid_t uid = -1;
@ -69,7 +73,7 @@ static int fileAction(const char *fileName, struct stat* statbuf)
case CHMOD_APP: case CHMOD_APP:
/* Parse the specified modes */ /* Parse the specified modes */
if ( parse_mode(theMode, &(statbuf->st_mode)) == FALSE ) { if ( parse_mode(theMode, &(statbuf->st_mode)) == FALSE ) {
fprintf(stderr, "%s: Unknown mode: %s\n", invocationName, theMode); fprintf(stderr, "%s: unknown mode: %s\n", invocationName, theMode);
exit( FALSE); exit( FALSE);
} }
if (chmod(fileName, statbuf->st_mode) == 0) if (chmod(fileName, statbuf->st_mode) == 0)
@ -84,6 +88,7 @@ int chmod_chown_chgrp_main(int argc, char **argv)
{ {
int recursiveFlag=FALSE; int recursiveFlag=FALSE;
char *groupName; char *groupName;
char *p;
const char *appUsage; const char *appUsage;
whichApp = (strcmp(*argv, "chown")==0)? CHOWN_APP : (strcmp(*argv, "chmod")==0)? CHMOD_APP : CHGRP_APP; whichApp = (strcmp(*argv, "chown")==0)? CHOWN_APP : (strcmp(*argv, "chmod")==0)? CHMOD_APP : CHGRP_APP;
@ -103,7 +108,7 @@ int chmod_chown_chgrp_main(int argc, char **argv)
recursiveFlag = TRUE; recursiveFlag = TRUE;
break; break;
default: default:
fprintf(stderr, "Unknown option: %c\n", **argv); fprintf(stderr, invalid_option, invocationName, **argv);
usage( appUsage); usage( appUsage);
} }
argc--; argc--;
@ -117,14 +122,18 @@ int chmod_chown_chgrp_main(int argc, char **argv)
/* Find the selected group */ /* Find the selected group */
if ( whichApp==CHGRP_APP ) { if ( whichApp==CHGRP_APP ) {
groupName = *argv; groupName = *argv;
gid = my_getgrnam(groupName); gid = strtoul(groupName, &p, 10); /* maybe it's already numeric */
if (groupName == p)
gid = my_getgrnam(groupName);
if (gid == -1) if (gid == -1)
goto bad_group; goto bad_group;
} else { } else {
groupName = strchr(*argv, '.'); groupName = strchr(*argv, '.');
if (groupName) { if (groupName) {
*groupName++ = '\0'; *groupName++ = '\0';
gid = my_getgrnam(groupName); gid = strtoul(groupName, &p, 10);
if (groupName == p)
gid = my_getgrnam(groupName);
if (gid == -1) if (gid == -1)
goto bad_group; goto bad_group;
} else } else
@ -134,9 +143,11 @@ int chmod_chown_chgrp_main(int argc, char **argv)
/* Find the selected user (if appropriate) */ /* Find the selected user (if appropriate) */
if (whichApp==CHOWN_APP) { if (whichApp==CHOWN_APP) {
uid = my_getpwnam(*argv); uid = strtoul(*argv, &p, 10); /* if numeric ...*/
if (*argv == p)
uid = my_getpwnam(*argv);
if (uid == -1) { if (uid == -1) {
fprintf(stderr, "%s: Unknown user name: %s\n", invocationName, *argv); fprintf(stderr, "%s: unknown user name: %s\n", invocationName, *argv);
exit( FALSE); exit( FALSE);
} }
} }
@ -144,7 +155,7 @@ int chmod_chown_chgrp_main(int argc, char **argv)
/* Ok, ready to do the deed now */ /* Ok, ready to do the deed now */
if (argc <= 1) { if (argc <= 1) {
fprintf(stderr, "%s: too few arguments", invocationName); fprintf(stderr, "%s: too few arguments\n", invocationName);
exit( FALSE); exit( FALSE);
} }
while (argc-- > 1) { while (argc-- > 1) {
@ -154,7 +165,7 @@ int chmod_chown_chgrp_main(int argc, char **argv)
exit(TRUE); exit(TRUE);
bad_group: bad_group:
fprintf(stderr, "%s: Unknown group name: %s\n", invocationName, groupName); fprintf(stderr, "%s: unknown group name: %s\n", invocationName, groupName);
exit( FALSE); exit( FALSE);
} }

View File

@ -1,127 +0,0 @@
/*
* Mini cp implementation for busybox
*
*
* Copyright (C) 1999 by Lineo, inc.
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "internal.h"
#include <stdio.h>
#include <time.h>
#include <utime.h>
#include <dirent.h>
static const char cp_usage[] = "cp [OPTION]... SOURCE DEST\n"
" or: cp [OPTION]... SOURCE... DIRECTORY\n\n"
"Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n"
"\n"
"\t-a\tsame as -dpR\n"
"\t-d\tpreserve links\n"
"\t-p\tpreserve file attributes if possible\n"
"\t-R\tcopy directories recursively\n";
static int recursiveFlag = FALSE;
static int followLinks = FALSE;
static int preserveFlag = FALSE;
static const char *srcName;
static const char *destName;
static int destDirFlag = FALSE;
static int srcDirFlag = FALSE;
static int fileAction(const char *fileName, struct stat* statbuf)
{
char newdestName[NAME_MAX];
char* newsrcName = NULL;
strcpy(newdestName, destName);
if ( srcDirFlag == TRUE ) {
if (recursiveFlag!=TRUE ) {
fprintf(stderr, "cp: %s: omitting directory\n", srcName);
return( TRUE);
}
strcat(newdestName, strstr(fileName, srcName) + strlen(srcName));
}
if (destDirFlag==TRUE && srcDirFlag == FALSE) {
if (newdestName[strlen(newdestName)-1] != '/' ) {
strcat(newdestName, "/");
}
newsrcName = strrchr(srcName, '/');
if (newsrcName && *newsrcName != '\0')
strcat(newdestName, newsrcName);
else
strcat(newdestName, srcName);
}
return (copyFile(fileName, newdestName, preserveFlag, followLinks));
}
extern int cp_main(int argc, char **argv)
{
if (argc < 3) {
usage (cp_usage);
}
argc--;
argv++;
/* Parse any options */
while (**argv == '-') {
while (*++(*argv))
switch (**argv) {
case 'a':
followLinks = TRUE;
preserveFlag = TRUE;
recursiveFlag = TRUE;
break;
case 'd':
followLinks = TRUE;
break;
case 'p':
preserveFlag = TRUE;
break;
case 'R':
recursiveFlag = TRUE;
break;
default:
usage (cp_usage);
}
argc--;
argv++;
}
destName = argv[argc - 1];
destDirFlag = isDirectory(destName);
if ((argc > 3) && destDirFlag==FALSE) {
fprintf(stderr, "%s: not a directory\n", destName);
exit (FALSE);
}
while (argc-- > 1) {
srcName = *(argv++);
srcDirFlag = isDirectory(srcName);
if (recursiveAction(srcName, recursiveFlag, followLinks, FALSE,
fileAction, fileAction) == FALSE) {
exit( FALSE);
}
}
exit( TRUE);
}

View File

@ -20,6 +20,10 @@
*/ */
#include "internal.h" #include "internal.h"
#define BB_DECLARE_EXTERN
#define bb_need_invalid_date
#define bb_need_memory_exhausted
#include "messages.c"
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <sys/time.h> #include <sys/time.h>
@ -59,7 +63,7 @@ date_conv_time(struct tm *tm_time, const char *t_string) {
&(tm_time->tm_year)); &(tm_time->tm_year));
if(nr < 4 || nr > 5) { if(nr < 4 || nr > 5) {
fprintf(stderr, "date: invalid date `%s'\n", t_string); fprintf(stderr, invalid_date, "date", t_string);
exit( FALSE); exit( FALSE);
} }
@ -152,7 +156,7 @@ date_conv_ftime(struct tm *tm_time, const char *t_string) {
} }
fprintf(stderr, "date: invalid date `%s'\n", t_string); fprintf(stderr, invalid_date, "date", t_string);
exit( FALSE); exit( FALSE);
@ -190,7 +194,7 @@ date_main(int argc, char * * argv)
case 'u': case 'u':
utc = 1; utc = 1;
if (putenv ("TZ=UTC0") != 0) { if (putenv ("TZ=UTC0") != 0) {
fprintf(stderr,"date: memory exhausted\n"); fprintf(stderr, memory_exhausted, "date");
exit( FALSE); exit( FALSE);
} }
/* Look ma, no break. Don't fix it either. */ /* Look ma, no break. Don't fix it either. */
@ -204,10 +208,10 @@ date_main(int argc, char * * argv)
} }
} else { } else {
if ( (date_fmt == NULL) && (strcmp(*argv, "+")==0) ) if ( (date_fmt == NULL) && (strcmp(*argv, "+")==0) )
date_fmt = *argv; date_fmt=*argv;
else if (date_str == NULL) { else if (date_str == NULL) {
set_time = 1; set_time = 1;
date_str = *argv; date_str=*argv;
} else { } else {
usage ( date_usage); usage ( date_usage);
} }
@ -241,7 +245,7 @@ date_main(int argc, char * * argv)
/* Correct any day of week and day of year etc fields */ /* Correct any day of week and day of year etc fields */
tm = mktime(&tm_time); tm = mktime(&tm_time);
if (tm < 0 ) { if (tm < 0 ) {
fprintf(stderr, "date: invalid date `%s'\n", date_str); fprintf(stderr, invalid_date, "date", date_str);
exit( FALSE); exit( FALSE);
} }
@ -284,4 +288,3 @@ date_main(int argc, char * * argv)
exit( TRUE); exit( TRUE);
} }

View File

@ -40,15 +40,16 @@ typedef unsigned long long int uintmax_t;
#endif #endif
static const char dd_usage[] = static const char dd_usage[] =
"dd [if=name] [of=name] [bs=n] [count=n]\n\n" "dd [if=name] [of=name] [bs=n] [count=n] [skip=n] [seek=n]\n\n"
"Copy a file, converting and formatting according to options\n\n" "Copy a file, converting and formatting according to options\n\n"
"\tif=FILE\tread from FILE instead of stdin\n" "\tif=FILE\tread from FILE instead of stdin\n"
"\tof=FILE\twrite to FILE instead of stout\n" "\tof=FILE\twrite to FILE instead of stdout\n"
"\tbs=n\tread and write N BYTES at a time\n" "\tbs=n\tread and write n bytes at a time\n"
"\tcount=n\tcopy only n input blocks\n" "\tcount=n\tcopy only n input blocks\n"
//"\tskip=n\tskip n input blocks\n" "\tskip=n\tskip n input blocks\n"
"\tseek=n\tskip n output blocks\n"
"\n" "\n"
"BYTES may be suffixed by w (x2), k (x1024), b (x512), or m (x1024^2).\n"; "Numbers may be suffixed by w (x2), k (x1024), b (x512), or M (x1024^2)\n";
@ -61,8 +62,9 @@ extern int dd_main (int argc, char **argv)
int outFd; int outFd;
int inCc = 0; int inCc = 0;
int outCc; int outCc;
size_t blockSize = 512; long blockSize = 512;
//uintmax_t skipBlocks = 0; uintmax_t skipBlocks = 0;
uintmax_t seekBlocks = 0;
uintmax_t count = (uintmax_t)-1; uintmax_t count = (uintmax_t)-1;
uintmax_t intotal; uintmax_t intotal;
uintmax_t outTotal; uintmax_t outTotal;
@ -91,16 +93,22 @@ extern int dd_main (int argc, char **argv)
goto usage; goto usage;
} }
} }
#if 0
else if (strncmp(*argv, "skip", 4) == 0) { else if (strncmp(*argv, "skip", 4) == 0) {
skipBlocks = atoi( *argv); skipBlocks = getNum ((strchr(*argv, '='))+1);
if (skipBlocks <= 0) { if (skipBlocks <= 0) {
fprintf (stderr, "Bad skip value %d\n", skipBlocks); fprintf (stderr, "Bad skip value %s\n", *argv);
goto usage;
}
}
else if (strncmp(*argv, "seek", 4) == 0) {
seekBlocks = getNum ((strchr(*argv, '='))+1);
if (seekBlocks <= 0) {
fprintf (stderr, "Bad seek value %s\n", *argv);
goto usage; goto usage;
} }
} }
#endif
else { else {
goto usage; goto usage;
} }
@ -131,7 +139,7 @@ extern int dd_main (int argc, char **argv)
if (outFile == NULL) if (outFile == NULL)
outFd = fileno(stdout); outFd = fileno(stdout);
else else
outFd = creat (outFile, 0666); outFd = open(outFile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (outFd < 0) { if (outFd < 0) {
perror (outFile); perror (outFile);
@ -140,10 +148,11 @@ extern int dd_main (int argc, char **argv)
exit( FALSE); exit( FALSE);
} }
//lseek(inFd, skipBlocks*blockSize, SEEK_SET); lseek(inFd, skipBlocks*blockSize, SEEK_SET);
lseek(outFd, seekBlocks*blockSize, SEEK_SET);
// //
//TODO: Convert to using fullRead & fullWrite //TODO: Convert to using fullRead & fullWrite
// from utilitity.c // from utility.c
// -Erik // -Erik
while (outTotal < count * blockSize) { while (outTotal < count * blockSize) {
inCc = read (inFd, buf, blockSize); inCc = read (inFd, buf, blockSize);

View File

@ -22,17 +22,18 @@
*/ */
#include "internal.h" #include "internal.h"
#define BB_DECLARE_EXTERN
#define bb_need_name_too_long
#include "messages.c"
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h> #include <fcntl.h>
#include <dirent.h> #include <dirent.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#if 0 #include <sys/param.h> /* for PATH_MAX */
#include <unistd.h>
#include <sys/stat.h>
#endif
typedef void (Display)(size_t, char *); typedef void (Display)(long, char *);
static const char du_usage[] = static const char du_usage[] =
"du [OPTION]... [FILE]...\n\n" "du [OPTION]... [FILE]...\n\n"
@ -44,13 +45,13 @@ static int du_depth = 0;
static Display *print; static Display *print;
static void static void
print_normal(size_t size, char *filename) print_normal(long size, char *filename)
{ {
fprintf(stdout, "%-7d %s\n", (size >> 1), filename); fprintf(stdout, "%-7ld %s\n", size, filename);
} }
static void static void
print_summary(size_t size, char *filename) print_summary(long size, char *filename)
{ {
if (du_depth == 1) { if (du_depth == 1) {
print_normal(size, filename); print_normal(size, filename);
@ -59,11 +60,11 @@ print_summary(size_t size, char *filename)
/* tiny recursive du */ /* tiny recursive du */
static size_t static long
du(char *filename) du(char *filename)
{ {
struct stat statbuf; struct stat statbuf;
size_t sum; long sum;
if ((lstat(filename, &statbuf)) != 0) { if ((lstat(filename, &statbuf)) != 0) {
fprintf(stdout, "du: %s: %s\n", filename, strerror(errno)); fprintf(stdout, "du: %s: %s\n", filename, strerror(errno));
@ -80,14 +81,19 @@ du(char *filename)
dir = opendir(filename); dir = opendir(filename);
if (!dir) { return 0; } if (!dir) { return 0; }
while ((entry = readdir(dir))) { while ((entry = readdir(dir))) {
char newfile[512]; char newfile[PATH_MAX + 1];
char *name = entry->d_name; char *name = entry->d_name;
if ( (strcmp(name, "..") == 0) if ( (strcmp(name, "..") == 0)
|| (strcmp(name, ".") == 0)) || (strcmp(name, ".") == 0))
{ continue; } { continue; }
if (strlen(filename) + strlen(name) + 1 > PATH_MAX) {
fprintf(stderr, name_too_long, "du");
return 0;
}
sprintf(newfile, "%s/%s", filename, name); sprintf(newfile, "%s/%s", filename, name);
sum += du(newfile); sum += du(newfile);
} }
closedir(dir); closedir(dir);
@ -130,14 +136,14 @@ du_main(int argc, char **argv)
if (i >= argc) { if (i >= argc) {
du("."); du(".");
} else { } else {
int sum; long sum;
for ( ; i < argc; i++) { for ( ; i < argc; i++) {
sum = du(argv[i]); sum = du(argv[i]);
if ((sum) && (isDirectory(argv[i]))) { print_normal(sum, argv[i]); } if ((sum) && (isDirectory(argv[i], FALSE))) { print_normal(sum, argv[i]); }
} }
} }
exit(0); exit(0);
} }
/* $Id: du.c,v 1.9 2000/01/23 18:19:02 erik Exp $ */ /* $Id: du.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */

View File

@ -105,4 +105,4 @@ head_main(int argc, char **argv)
exit(0); exit(0);
} }
/* $Id: head.c,v 1.6 2000/01/25 18:13:53 erik Exp $ */ /* $Id: head.c,v 1.7 2000/02/07 05:29:42 erik Exp $ */

View File

@ -6,7 +6,7 @@
extern int extern int
length_main(int argc, char * * argv) length_main(int argc, char * * argv)
{ {
if ( **(argv+1) == '-' ) { if ( argc != 2 || **(argv+1) == '-' ) {
usage("length string\n"); usage("length string\n");
} }
printf("%d\n", strlen(argv[1])); printf("%d\n", strlen(argv[1]));

View File

@ -22,26 +22,32 @@
*/ */
#include "internal.h" #include "internal.h"
#define BB_DECLARE_EXTERN
#define bb_need_name_too_long
#define bb_need_not_a_directory
#include "messages.c"
#include <stdio.h> #include <stdio.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <sys/param.h> /* for PATH_MAX */
static const char ln_usage[] =
static const char ln_usage[] = "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n" "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n"
"Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n" "Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n"
"Options:\n" "Options:\n"
"\t-s\tmake symbolic links instead of hard links\n" "\t-s\tmake symbolic links instead of hard links\n"
"\t-f\tremove existing destination files\n"; "\t-f\tremove existing destination files\n"
"\t-n\tno dereference symlinks - treat like normal file\n";
static int symlinkFlag = FALSE; static int symlinkFlag = FALSE;
static int removeoldFlag = FALSE; static int removeoldFlag = FALSE;
static int followLinks = TRUE;
extern int ln_main(int argc, char **argv) extern int ln_main(int argc, char **argv)
{ {
int status; char *linkName;
static char* linkName; int linkIntoDirFlag;
if (argc < 3) { if (argc < 3) {
usage (ln_usage); usage (ln_usage);
@ -59,6 +65,9 @@ extern int ln_main(int argc, char **argv)
case 'f': case 'f':
removeoldFlag = TRUE; removeoldFlag = TRUE;
break; break;
case 'n':
followLinks = FALSE;
break;
default: default:
usage (ln_usage); usage (ln_usage);
} }
@ -66,30 +75,54 @@ extern int ln_main(int argc, char **argv)
argv++; argv++;
} }
linkName = argv[argc - 1]; linkName = argv[argc - 1];
if ((argc > 3) && !(isDirectory(linkName))) { if (strlen(linkName) > PATH_MAX) {
fprintf(stderr, "%s: not a directory\n", linkName); fprintf(stderr, name_too_long, "ln");
exit (FALSE); exit FALSE;
}
linkIntoDirFlag = isDirectory(linkName, TRUE);
if ((argc > 3) && !linkIntoDirFlag) {
fprintf(stderr, not_a_directory, "ln", linkName);
exit FALSE;
} }
while (argc-- >= 2) { while (argc-- >= 2) {
if (removeoldFlag==TRUE ) { char srcName[PATH_MAX + 1];
int nChars, status;
if (strlen(*argv) > PATH_MAX) {
fprintf(stderr, name_too_long, "ln");
exit FALSE;
}
if (followLinks == FALSE) {
strcpy(srcName, *argv);
} else {
/* Warning! This can silently truncate if > PATH_MAX, but
I don't think that there can be one > PATH_MAX anyway. */
nChars = readlink(*argv, srcName, PATH_MAX);
srcName[nChars] = '\0';
}
if (removeoldFlag == TRUE) {
status = ( unlink(linkName) && errno != ENOENT ); status = ( unlink(linkName) && errno != ENOENT );
if ( status != 0 ) { if (status != 0) {
perror(linkName); perror(linkName);
exit( FALSE); exit FALSE;
} }
} }
if ( symlinkFlag==TRUE)
status = symlink(*argv, linkName); if (symlinkFlag == TRUE)
status = symlink(*argv, linkName);
else else
status = link(*argv, linkName); status = link(*argv, linkName);
if ( status != 0 ) { if (status != 0) {
perror(linkName); perror(linkName);
exit( FALSE); exit FALSE;
} }
} }
exit( TRUE); exit TRUE;
} }

View File

@ -178,7 +178,7 @@ static char append_char(mode_t mode)
static void list_single(const char *name, struct stat *info, const char *fullname) static void list_single(const char *name, struct stat *info, const char *fullname)
{ {
char scratch[PATH_MAX]; char scratch[PATH_MAX + 1];
short len = strlen(name); short len = strlen(name);
#ifdef BB_FEATURE_LS_FILETYPES #ifdef BB_FEATURE_LS_FILETYPES
char append = append_char(info->st_mode); char append = append_char(info->st_mode);

View File

@ -22,9 +22,13 @@
*/ */
#include "internal.h" #include "internal.h"
#define bb_need_name_too_long
#define BB_DECLARE_EXTERN
#include "messages.c"
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include <sys/param.h> #include <sys/param.h> /* for PATH_MAX */
static const char mkdir_usage[] = static const char mkdir_usage[] =
"mkdir [OPTION] DIRECTORY...\n\n" "mkdir [OPTION] DIRECTORY...\n\n"
@ -40,27 +44,27 @@ static mode_t mode = 0777;
extern int mkdir_main(int argc, char **argv) extern int mkdir_main(int argc, char **argv)
{ {
int i=FALSE; int i = FALSE;
argc--; argc--;
argv++; argv++;
/* Parse any options */ /* Parse any options */
while (argc > 0 && **argv == '-') { while (argc > 0 && **argv == '-') {
while (i==FALSE && *++(*argv)) { while (i == FALSE && *++(*argv)) {
switch (**argv) { switch (**argv) {
case 'm': case 'm':
if (--argc == 0) if (--argc == 0)
usage( mkdir_usage); usage( mkdir_usage);
/* Find the specified modes */ /* Find the specified modes */
mode = 0; mode = 0;
if ( parse_mode(*(++argv), &mode) == FALSE ) { if (parse_mode(*(++argv), &mode) == FALSE ) {
fprintf(stderr, "Unknown mode: %s\n", *argv); fprintf(stderr, "Unknown mode: %s\n", *argv);
exit( FALSE); exit FALSE;
} }
/* Set the umask for this process so it doesn't /* Set the umask for this process so it doesn't
* screw up whatever the user just entered. */ * screw up whatever the user just entered. */
umask(0); umask(0);
i=TRUE; i = TRUE;
break; break;
case 'p': case 'p':
parentFlag = TRUE; parentFlag = TRUE;
@ -73,7 +77,6 @@ extern int mkdir_main(int argc, char **argv)
argv++; argv++;
} }
if (argc < 1) { if (argc < 1) {
usage( mkdir_usage); usage( mkdir_usage);
} }
@ -81,13 +84,16 @@ extern int mkdir_main(int argc, char **argv)
while (argc > 0) { while (argc > 0) {
int status; int status;
struct stat statBuf; struct stat statBuf;
char buf[NAME_MAX]; char buf[PATH_MAX + 1];
if (strlen(*argv) > PATH_MAX - 1) {
fprintf(stderr, name_too_long, "mkdir");
exit FALSE;
}
strcpy (buf, *argv); strcpy (buf, *argv);
status=stat(buf, &statBuf); status = stat(buf, &statBuf);
if (parentFlag == FALSE && status != -1 && status != ENOENT ) { if (parentFlag == FALSE && status != -1 && errno != ENOENT) {
fprintf(stderr, "%s: File exists\n", buf); fprintf(stderr, "%s: File exists\n", buf);
exit( FALSE); exit FALSE;
} }
if (parentFlag == TRUE) { if (parentFlag == TRUE) {
strcat( buf, "/"); strcat( buf, "/");
@ -96,13 +102,13 @@ extern int mkdir_main(int argc, char **argv)
else { else {
if (mkdir (buf, mode) != 0 && parentFlag == FALSE) { if (mkdir (buf, mode) != 0 && parentFlag == FALSE) {
perror(buf); perror(buf);
exit( FALSE); exit FALSE;
} }
} }
argc--; argc--;
argv++; argv++;
} }
exit( TRUE); exit TRUE;
} }

View File

@ -1,112 +0,0 @@
/*
* Mini mv implementation for busybox
*
*
* Copyright (C) 1999 by Lineo, inc.
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "internal.h"
#include <stdio.h>
#include <time.h>
#include <utime.h>
#include <dirent.h>
static const char mv_usage[] = "mv SOURCE DEST\n"
" or: mv SOURCE... DIRECTORY\n\n"
"Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n";
static const char *srcName;
static const char *destName;
static int destDirFlag = FALSE;
static int srcDirFlag = FALSE;
static int fileAction(const char *fileName, struct stat* statbuf)
{
char newdestName[NAME_MAX];
char* newsrcName = NULL;
strcpy(newdestName, destName);
if ( srcDirFlag == TRUE ) {
strcat(newdestName, strstr(fileName, srcName) + strlen(srcName));
}
if (destDirFlag==TRUE && srcDirFlag == FALSE) {
if (newdestName[strlen(newdestName)-1] != '/' ) {
strcat(newdestName, "/");
}
newsrcName = strrchr(srcName, '/');
if (newsrcName && *newsrcName != '\0')
strcat(newdestName, newsrcName);
else
strcat(newdestName, srcName);
}
return (copyFile(fileName, newdestName, TRUE, TRUE));
}
static int rmfileAction(const char *fileName, struct stat* statbuf)
{
if (unlink( fileName) < 0 ) {
perror( fileName);
return ( FALSE);
}
return ( TRUE);
}
static int rmdirAction(const char *fileName, struct stat* statbuf)
{
if (rmdir( fileName) < 0 ) {
perror( fileName);
return ( FALSE);
}
return ( TRUE);
}
extern int mv_main(int argc, char **argv)
{
if (argc < 3) {
usage (mv_usage);
}
argc--;
argv++;
destName = argv[argc - 1];
destDirFlag = isDirectory(destName);
if ((argc > 3) && destDirFlag==FALSE) {
fprintf(stderr, "%s: not a directory\n", destName);
exit (FALSE);
}
while (argc-- > 1) {
srcName = *(argv++);
srcDirFlag = isDirectory(srcName);
if (recursiveAction(srcName, TRUE, TRUE, FALSE,
fileAction, fileAction) == FALSE) {
exit( FALSE);
}
if (recursiveAction(srcName, TRUE, TRUE, TRUE,
rmfileAction, rmdirAction) == FALSE) {
exit( FALSE);
}
}
exit( TRUE);
}

View File

@ -143,7 +143,7 @@ printf_main(int argc, char** argv)
int args_used; int args_used;
exit_status = 0; exit_status = 0;
if ( **(argv+1) == '-' ) { if ( argc <= 1 || **(argv+1) == '-' ) {
usage (printf_usage); usage (printf_usage);
} }

View File

@ -23,11 +23,12 @@
#include "internal.h" #include "internal.h"
#include <stdio.h> #include <stdio.h>
#include <dirent.h> #include <dirent.h>
#include <sys/param.h>
extern int extern int
pwd_main(int argc, char * * argv) pwd_main(int argc, char * * argv)
{ {
char buf[NAME_MAX]; char buf[PATH_MAX + 1];
if ( getcwd(buf, sizeof(buf)) == NULL ) { if ( getcwd(buf, sizeof(buf)) == NULL ) {
perror("get working directory"); perror("get working directory");

View File

@ -309,4 +309,4 @@ sort_main(int argc, char **argv)
exit(0); exit(0);
} }
/* $Id: sort.c,v 1.9 2000/01/23 18:19:02 erik Exp $ */ /* $Id: sort.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */

View File

@ -33,7 +33,7 @@
and generally busyboxed, Erik Andersen <andersen@lineo.com> and generally busyboxed, Erik Andersen <andersen@lineo.com>
Removed superfluous options and associated code ("-c", "-n", "-q"). Removed superfluous options and associated code ("-c", "-n", "-q").
Removed "tail -f" suport for multiple files. Removed "tail -f" support for multiple files.
Both changes by Friedrich Vedder <fwv@myrtle.lahn.de>. Both changes by Friedrich Vedder <fwv@myrtle.lahn.de>.
*/ */

View File

@ -123,4 +123,4 @@ tee_main(int argc, char **argv)
exit(0); exit(0);
} }
/* $Id: tee.c,v 1.4 1999/12/10 08:25:07 andersen Exp $ */ /* $Id: tee.c,v 1.5 2000/02/07 05:29:42 erik Exp $ */

View File

@ -193,4 +193,4 @@ uniq_main(int argc, char **argv)
exit(0); exit(0);
} }
/* $Id: uniq.c,v 1.5 2000/01/23 18:19:02 erik Exp $ */ /* $Id: uniq.c,v 1.6 2000/02/07 05:29:42 erik Exp $ */

127
cp.c
View File

@ -1,127 +0,0 @@
/*
* Mini cp implementation for busybox
*
*
* Copyright (C) 1999 by Lineo, inc.
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "internal.h"
#include <stdio.h>
#include <time.h>
#include <utime.h>
#include <dirent.h>
static const char cp_usage[] = "cp [OPTION]... SOURCE DEST\n"
" or: cp [OPTION]... SOURCE... DIRECTORY\n\n"
"Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n"
"\n"
"\t-a\tsame as -dpR\n"
"\t-d\tpreserve links\n"
"\t-p\tpreserve file attributes if possible\n"
"\t-R\tcopy directories recursively\n";
static int recursiveFlag = FALSE;
static int followLinks = FALSE;
static int preserveFlag = FALSE;
static const char *srcName;
static const char *destName;
static int destDirFlag = FALSE;
static int srcDirFlag = FALSE;
static int fileAction(const char *fileName, struct stat* statbuf)
{
char newdestName[NAME_MAX];
char* newsrcName = NULL;
strcpy(newdestName, destName);
if ( srcDirFlag == TRUE ) {
if (recursiveFlag!=TRUE ) {
fprintf(stderr, "cp: %s: omitting directory\n", srcName);
return( TRUE);
}
strcat(newdestName, strstr(fileName, srcName) + strlen(srcName));
}
if (destDirFlag==TRUE && srcDirFlag == FALSE) {
if (newdestName[strlen(newdestName)-1] != '/' ) {
strcat(newdestName, "/");
}
newsrcName = strrchr(srcName, '/');
if (newsrcName && *newsrcName != '\0')
strcat(newdestName, newsrcName);
else
strcat(newdestName, srcName);
}
return (copyFile(fileName, newdestName, preserveFlag, followLinks));
}
extern int cp_main(int argc, char **argv)
{
if (argc < 3) {
usage (cp_usage);
}
argc--;
argv++;
/* Parse any options */
while (**argv == '-') {
while (*++(*argv))
switch (**argv) {
case 'a':
followLinks = TRUE;
preserveFlag = TRUE;
recursiveFlag = TRUE;
break;
case 'd':
followLinks = TRUE;
break;
case 'p':
preserveFlag = TRUE;
break;
case 'R':
recursiveFlag = TRUE;
break;
default:
usage (cp_usage);
}
argc--;
argv++;
}
destName = argv[argc - 1];
destDirFlag = isDirectory(destName);
if ((argc > 3) && destDirFlag==FALSE) {
fprintf(stderr, "%s: not a directory\n", destName);
exit (FALSE);
}
while (argc-- > 1) {
srcName = *(argv++);
srcDirFlag = isDirectory(srcName);
if (recursiveAction(srcName, recursiveFlag, followLinks, FALSE,
fileAction, fileAction) == FALSE) {
exit( FALSE);
}
}
exit( TRUE);
}

258
cp_mv.c Normal file
View File

@ -0,0 +1,258 @@
/*
* Mini `cp' and `mv' implementation for BusyBox.
*
*
* Copyright (C) 1999 by Lineo, inc.
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
*
* Copyright (C) 2000 by BitterSweet Enterprises, LLC. (GPL)
* Extensively modified and rewritten by Karl M. Hegbloom <karlheg@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "internal.h"
#define BB_DECLARE_EXTERN
#define bb_need_name_too_long
#define bb_need_omitting_directory
#define bb_need_not_a_directory
#include "messages.c"
#include <stdio.h>
#include <time.h>
#include <utime.h>
#include <dirent.h>
#include <sys/param.h>
#define is_cp 0
#define is_mv 1
static const char *dz; /* dollar zero, .bss */
static int dz_i; /* index, .bss */
static const char *cp_mv_usage[] = /* .rodata */
{
"cp [OPTION]... SOURCE DEST\n"
" or: cp [OPTION]... SOURCE... DIRECTORY\n\n"
"Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n"
"\n"
"\t-a\tsame as -dpR\n"
"\t-d\tpreserve links\n"
"\t-p\tpreserve file attributes if possible\n"
"\t-R\tcopy directories recursively\n"
,
"mv SOURCE DEST\n"
" or: mv SOURCE... DIRECTORY\n\n"
"Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n"
"Warning!! This is not GNU `mv'. It does not preserve hard links.\n"
};
extern int cp_mv_main(int argc, char **argv)
{
__label__ name_too_long__exit;
__label__ exit_false;
int recursiveFlag;
int followLinks;
int preserveFlag;
const char *baseSrcName;
int srcDirFlag;
char baseDestName[PATH_MAX + 1];
size_t baseDestLen;
int destDirFlag;
void fill_baseDest_buf(char *_buf, size_t *_buflen)
{
const char *srcBasename;
if ((srcBasename = strrchr(baseSrcName, '/')) == NULL)
{
srcBasename = baseSrcName;
if (_buf[*_buflen - 1] != '/')
{
if (++(*_buflen) > PATH_MAX)
goto name_too_long__exit;
strcat(_buf, "/");
}
}
if (*_buflen + strlen(srcBasename) > PATH_MAX)
goto name_too_long__exit;
strcat(_buf, srcBasename);
return;
}
int fileAction(const char *fileName, struct stat *statbuf)
{
__label__ return_false;
char destName[PATH_MAX + 1];
size_t destLen;
const char *srcBasename;
strcpy(destName, baseDestName);
destLen = strlen(destName);
if (srcDirFlag == TRUE)
{
if (recursiveFlag == FALSE)
{
fprintf(stderr, omitting_directory, "cp", baseSrcName);
return TRUE;
}
srcBasename = (strstr(fileName, baseSrcName)
+ strlen(baseSrcName));
if (destLen + strlen(srcBasename) > PATH_MAX)
{
fprintf(stderr, name_too_long, "cp");
goto return_false;
}
strcat(destName, srcBasename);
}
else if (destDirFlag == TRUE)
{
fill_baseDest_buf(&destName[0], &destLen);
}
else
{
srcBasename = baseSrcName;
}
return copyFile(fileName, destName, preserveFlag, followLinks);
return_false:
return FALSE;
}
int rmfileAction(const char *fileName, struct stat* statbuf)
{
if (unlink(fileName) < 0 ) {
perror(fileName);
return FALSE;
}
return TRUE;
}
int rmdirAction(const char *fileName, struct stat* statbuf)
{
if (rmdir(fileName) < 0 ) {
perror(fileName);
return FALSE;
}
return TRUE;
}
if ((dz = strrchr(*argv, '/')) == NULL) dz = *argv; else dz++;
if (*dz == 'c' && *(dz + 1) == 'p') dz_i = is_cp; else dz_i = is_mv;
if (argc < 3) usage(cp_mv_usage[dz_i]);
argc--;
argv++;
if (dz_i == is_cp)
{
recursiveFlag = preserveFlag = FALSE;
followLinks = TRUE;
while (**argv == '-')
{
while (*++(*argv))
{
switch (**argv)
{
case 'a':
followLinks = FALSE;
preserveFlag = TRUE;
recursiveFlag = TRUE;
break;
case 'd':
followLinks = FALSE;
break;
case 'p':
preserveFlag = TRUE;
break;
case 'R':
recursiveFlag = TRUE;
break;
default:
usage(cp_mv_usage[is_cp]);
}
}
argc--;
argv++;
}
}
else /* (dz_i == is_mv) */
{
recursiveFlag = preserveFlag = TRUE;
followLinks = FALSE;
}
if (strlen(argv[argc - 1]) > PATH_MAX)
{
fprintf(stderr, name_too_long, "cp");
goto exit_false;
}
strcpy(baseDestName, argv[argc - 1]);
baseDestLen = strlen(baseDestName);
if (baseDestLen == 0) goto exit_false;
destDirFlag = isDirectory(baseDestName, TRUE);
if ((argc > 3) && destDirFlag == FALSE)
{
fprintf(stderr, not_a_directory, "cp", baseDestName);
goto exit_false;
}
while (argc-- > 1)
{
size_t srcLen;
int flags_memo;
baseSrcName = *(argv++);
if ((srcLen = strlen(baseSrcName)) > PATH_MAX)
goto name_too_long__exit;
if (srcLen == 0) continue;
srcDirFlag = isDirectory(baseSrcName, followLinks);
if ((flags_memo = (recursiveFlag == TRUE &&
srcDirFlag == TRUE && destDirFlag == TRUE)))
{
fill_baseDest_buf(&baseDestName[0], &baseDestLen);
}
if (recursiveAction(baseSrcName,
recursiveFlag, followLinks, FALSE,
fileAction, fileAction)
== FALSE) goto exit_false;
if (dz_i == is_mv &&
recursiveAction(baseSrcName,
recursiveFlag, followLinks, TRUE,
rmfileAction, rmdirAction)
== FALSE) goto exit_false;
if (flags_memo) *(baseDestName + baseDestLen) = '\0';
}
exit TRUE;
name_too_long__exit:
fprintf(stderr, name_too_long, "cp");
exit_false:
exit FALSE;
}
// Local Variables:
// c-file-style: "k&r"
// c-basic-offset: 4
// End:

17
date.c
View File

@ -20,6 +20,10 @@
*/ */
#include "internal.h" #include "internal.h"
#define BB_DECLARE_EXTERN
#define bb_need_invalid_date
#define bb_need_memory_exhausted
#include "messages.c"
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <sys/time.h> #include <sys/time.h>
@ -59,7 +63,7 @@ date_conv_time(struct tm *tm_time, const char *t_string) {
&(tm_time->tm_year)); &(tm_time->tm_year));
if(nr < 4 || nr > 5) { if(nr < 4 || nr > 5) {
fprintf(stderr, "date: invalid date `%s'\n", t_string); fprintf(stderr, invalid_date, "date", t_string);
exit( FALSE); exit( FALSE);
} }
@ -152,7 +156,7 @@ date_conv_ftime(struct tm *tm_time, const char *t_string) {
} }
fprintf(stderr, "date: invalid date `%s'\n", t_string); fprintf(stderr, invalid_date, "date", t_string);
exit( FALSE); exit( FALSE);
@ -190,7 +194,7 @@ date_main(int argc, char * * argv)
case 'u': case 'u':
utc = 1; utc = 1;
if (putenv ("TZ=UTC0") != 0) { if (putenv ("TZ=UTC0") != 0) {
fprintf(stderr,"date: memory exhausted\n"); fprintf(stderr, memory_exhausted, "date");
exit( FALSE); exit( FALSE);
} }
/* Look ma, no break. Don't fix it either. */ /* Look ma, no break. Don't fix it either. */
@ -204,10 +208,10 @@ date_main(int argc, char * * argv)
} }
} else { } else {
if ( (date_fmt == NULL) && (strcmp(*argv, "+")==0) ) if ( (date_fmt == NULL) && (strcmp(*argv, "+")==0) )
date_fmt = *argv; date_fmt=*argv;
else if (date_str == NULL) { else if (date_str == NULL) {
set_time = 1; set_time = 1;
date_str = *argv; date_str=*argv;
} else { } else {
usage ( date_usage); usage ( date_usage);
} }
@ -241,7 +245,7 @@ date_main(int argc, char * * argv)
/* Correct any day of week and day of year etc fields */ /* Correct any day of week and day of year etc fields */
tm = mktime(&tm_time); tm = mktime(&tm_time);
if (tm < 0 ) { if (tm < 0 ) {
fprintf(stderr, "date: invalid date `%s'\n", date_str); fprintf(stderr, invalid_date, "date", date_str);
exit( FALSE); exit( FALSE);
} }
@ -284,4 +288,3 @@ date_main(int argc, char * * argv)
exit( TRUE); exit( TRUE);
} }

37
dd.c
View File

@ -40,15 +40,16 @@ typedef unsigned long long int uintmax_t;
#endif #endif
static const char dd_usage[] = static const char dd_usage[] =
"dd [if=name] [of=name] [bs=n] [count=n]\n\n" "dd [if=name] [of=name] [bs=n] [count=n] [skip=n] [seek=n]\n\n"
"Copy a file, converting and formatting according to options\n\n" "Copy a file, converting and formatting according to options\n\n"
"\tif=FILE\tread from FILE instead of stdin\n" "\tif=FILE\tread from FILE instead of stdin\n"
"\tof=FILE\twrite to FILE instead of stout\n" "\tof=FILE\twrite to FILE instead of stdout\n"
"\tbs=n\tread and write N BYTES at a time\n" "\tbs=n\tread and write n bytes at a time\n"
"\tcount=n\tcopy only n input blocks\n" "\tcount=n\tcopy only n input blocks\n"
//"\tskip=n\tskip n input blocks\n" "\tskip=n\tskip n input blocks\n"
"\tseek=n\tskip n output blocks\n"
"\n" "\n"
"BYTES may be suffixed by w (x2), k (x1024), b (x512), or m (x1024^2).\n"; "Numbers may be suffixed by w (x2), k (x1024), b (x512), or M (x1024^2)\n";
@ -61,8 +62,9 @@ extern int dd_main (int argc, char **argv)
int outFd; int outFd;
int inCc = 0; int inCc = 0;
int outCc; int outCc;
size_t blockSize = 512; long blockSize = 512;
//uintmax_t skipBlocks = 0; uintmax_t skipBlocks = 0;
uintmax_t seekBlocks = 0;
uintmax_t count = (uintmax_t)-1; uintmax_t count = (uintmax_t)-1;
uintmax_t intotal; uintmax_t intotal;
uintmax_t outTotal; uintmax_t outTotal;
@ -91,16 +93,22 @@ extern int dd_main (int argc, char **argv)
goto usage; goto usage;
} }
} }
#if 0
else if (strncmp(*argv, "skip", 4) == 0) { else if (strncmp(*argv, "skip", 4) == 0) {
skipBlocks = atoi( *argv); skipBlocks = getNum ((strchr(*argv, '='))+1);
if (skipBlocks <= 0) { if (skipBlocks <= 0) {
fprintf (stderr, "Bad skip value %d\n", skipBlocks); fprintf (stderr, "Bad skip value %s\n", *argv);
goto usage;
}
}
else if (strncmp(*argv, "seek", 4) == 0) {
seekBlocks = getNum ((strchr(*argv, '='))+1);
if (seekBlocks <= 0) {
fprintf (stderr, "Bad seek value %s\n", *argv);
goto usage; goto usage;
} }
} }
#endif
else { else {
goto usage; goto usage;
} }
@ -131,7 +139,7 @@ extern int dd_main (int argc, char **argv)
if (outFile == NULL) if (outFile == NULL)
outFd = fileno(stdout); outFd = fileno(stdout);
else else
outFd = creat (outFile, 0666); outFd = open(outFile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (outFd < 0) { if (outFd < 0) {
perror (outFile); perror (outFile);
@ -140,10 +148,11 @@ extern int dd_main (int argc, char **argv)
exit( FALSE); exit( FALSE);
} }
//lseek(inFd, skipBlocks*blockSize, SEEK_SET); lseek(inFd, skipBlocks*blockSize, SEEK_SET);
lseek(outFd, seekBlocks*blockSize, SEEK_SET);
// //
//TODO: Convert to using fullRead & fullWrite //TODO: Convert to using fullRead & fullWrite
// from utilitity.c // from utility.c
// -Erik // -Erik
while (outTotal < count * blockSize) { while (outTotal < count * blockSize) {
inCc = read (inFd, buf, blockSize); inCc = read (inFd, buf, blockSize);

34
du.c
View File

@ -22,17 +22,18 @@
*/ */
#include "internal.h" #include "internal.h"
#define BB_DECLARE_EXTERN
#define bb_need_name_too_long
#include "messages.c"
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h> #include <fcntl.h>
#include <dirent.h> #include <dirent.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#if 0 #include <sys/param.h> /* for PATH_MAX */
#include <unistd.h>
#include <sys/stat.h>
#endif
typedef void (Display)(size_t, char *); typedef void (Display)(long, char *);
static const char du_usage[] = static const char du_usage[] =
"du [OPTION]... [FILE]...\n\n" "du [OPTION]... [FILE]...\n\n"
@ -44,13 +45,13 @@ static int du_depth = 0;
static Display *print; static Display *print;
static void static void
print_normal(size_t size, char *filename) print_normal(long size, char *filename)
{ {
fprintf(stdout, "%-7d %s\n", (size >> 1), filename); fprintf(stdout, "%-7ld %s\n", size, filename);
} }
static void static void
print_summary(size_t size, char *filename) print_summary(long size, char *filename)
{ {
if (du_depth == 1) { if (du_depth == 1) {
print_normal(size, filename); print_normal(size, filename);
@ -59,11 +60,11 @@ print_summary(size_t size, char *filename)
/* tiny recursive du */ /* tiny recursive du */
static size_t static long
du(char *filename) du(char *filename)
{ {
struct stat statbuf; struct stat statbuf;
size_t sum; long sum;
if ((lstat(filename, &statbuf)) != 0) { if ((lstat(filename, &statbuf)) != 0) {
fprintf(stdout, "du: %s: %s\n", filename, strerror(errno)); fprintf(stdout, "du: %s: %s\n", filename, strerror(errno));
@ -80,14 +81,19 @@ du(char *filename)
dir = opendir(filename); dir = opendir(filename);
if (!dir) { return 0; } if (!dir) { return 0; }
while ((entry = readdir(dir))) { while ((entry = readdir(dir))) {
char newfile[512]; char newfile[PATH_MAX + 1];
char *name = entry->d_name; char *name = entry->d_name;
if ( (strcmp(name, "..") == 0) if ( (strcmp(name, "..") == 0)
|| (strcmp(name, ".") == 0)) || (strcmp(name, ".") == 0))
{ continue; } { continue; }
if (strlen(filename) + strlen(name) + 1 > PATH_MAX) {
fprintf(stderr, name_too_long, "du");
return 0;
}
sprintf(newfile, "%s/%s", filename, name); sprintf(newfile, "%s/%s", filename, name);
sum += du(newfile); sum += du(newfile);
} }
closedir(dir); closedir(dir);
@ -130,14 +136,14 @@ du_main(int argc, char **argv)
if (i >= argc) { if (i >= argc) {
du("."); du(".");
} else { } else {
int sum; long sum;
for ( ; i < argc; i++) { for ( ; i < argc; i++) {
sum = du(argv[i]); sum = du(argv[i]);
if ((sum) && (isDirectory(argv[i]))) { print_normal(sum, argv[i]); } if ((sum) && (isDirectory(argv[i], FALSE))) { print_normal(sum, argv[i]); }
} }
} }
exit(0); exit(0);
} }
/* $Id: du.c,v 1.9 2000/01/23 18:19:02 erik Exp $ */ /* $Id: du.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */

View File

@ -31,7 +31,7 @@ extern int fdflush_main(int argc, char **argv)
{ {
int value; int value;
int fd; int fd;
if ( **(argv+1) == '-' ) { if ( argc <= 1 || **(argv++) == '-' ) {
usage( "fdflush device\n"); usage( "fdflush device\n");
} }

2
find.c
View File

@ -90,7 +90,7 @@ int find_main(int argc, char **argv)
if (strcmp(*argv, "name")==0) { if (strcmp(*argv, "name")==0) {
if (argc-- > 1) { if (argc-- > 1) {
pattern = *(++argv); pattern = *(++argv);
stopit=TRUE; stopit = TRUE;
} else { } else {
usage (find_usage); usage (find_usage);
} }

View File

@ -90,7 +90,7 @@ int find_main(int argc, char **argv)
if (strcmp(*argv, "name")==0) { if (strcmp(*argv, "name")==0) {
if (argc-- > 1) { if (argc-- > 1) {
pattern = *(++argv); pattern = *(++argv);
stopit=TRUE; stopit = TRUE;
} else { } else {
usage (find_usage); usage (find_usage);
} }

View File

@ -96,6 +96,7 @@
#include <termios.h> #include <termios.h>
#include <mntent.h> #include <mntent.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/param.h> /* for PATH_MAX */
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/minix_fs.h> #include <linux/minix_fs.h>
@ -143,7 +144,7 @@ static int termios_set = 0;
/* File-name data */ /* File-name data */
#define MAX_DEPTH 50 #define MAX_DEPTH 50
static int name_depth = 0; static int name_depth = 0;
static char name_list[MAX_DEPTH][NAME_MAX+1]; static char name_list[MAX_DEPTH][PATH_MAX + 1];
static char * inode_buffer = NULL; static char * inode_buffer = NULL;
#define Inode (((struct minix_inode *) inode_buffer)-1) #define Inode (((struct minix_inode *) inode_buffer)-1)

View File

@ -3,6 +3,9 @@
*/ */
#include "internal.h" #include "internal.h"
#define bb_need_name_too_long
#define BB_DECLARE_EXTERN
#include "messages.c"
static const char gunzip_usage[] = static const char gunzip_usage[] =
"gunzip [OPTION]... FILE\n\n" "gunzip [OPTION]... FILE\n\n"
@ -64,6 +67,7 @@ static char *license_msg[] = {
#include <signal.h> #include <signal.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h> #include <errno.h>
#include <sys/param.h> /* for PATH_MAX */
/* #include "tailor.h" */ /* #include "tailor.h" */
@ -627,8 +631,12 @@ typedef RETSIGTYPE (*sig_type) OF((int));
#endif #endif
#define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */ #define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */
#ifndef MAX_PATH_LEN #ifndef MAX_PATH_LEN /* max pathname length */
# define MAX_PATH_LEN 1024 /* max pathname length */ # ifdef PATH_MAX
# define MAX_PATH_LEN PATH_MAX
# else
# define MAX_PATH_LEN 1024
# endif
#endif #endif
#ifndef SEEK_END #ifndef SEEK_END
@ -696,8 +704,8 @@ int gunzip_main (int argc, char** argv)
int delInputFile=0; int delInputFile=0;
struct stat statBuf; struct stat statBuf;
char* delFileName; char* delFileName;
char ifname[MAX_PATH_LEN]; /* input file name */ char ifname[MAX_PATH_LEN + 1]; /* input file name */
char ofname[MAX_PATH_LEN]; /* output file name */ char ofname[MAX_PATH_LEN + 1]; /* output file name */
if (argc==1) if (argc==1)
usage(gunzip_usage); usage(gunzip_usage);
@ -764,7 +772,11 @@ int gunzip_main (int argc, char** argv)
/* Open up the input file */ /* Open up the input file */
if (*argv=='\0') if (*argv=='\0')
usage(gunzip_usage); usage(gunzip_usage);
strncpy(ifname, *argv, MAX_PATH_LEN); if (strlen(*argv) > MAX_PATH_LEN) {
fprintf(stderr, name_too_long, "gunzip");
do_exit(WARNING);
}
strcpy(ifname, *argv);
/* Open input fille */ /* Open input fille */
inFileNum=open( ifname, O_RDONLY); inFileNum=open( ifname, O_RDONLY);
@ -799,7 +811,11 @@ int gunzip_main (int argc, char** argv)
char* pos; char* pos;
/* And get to work */ /* And get to work */
strncpy(ofname, ifname, MAX_PATH_LEN-4); if (strlen(ifname) > MAX_PATH_LEN - 4) {
fprintf(stderr, name_too_long, "gunzip");
do_exit(WARNING);
}
strcpy(ofname, ifname);
pos=strstr(ofname, ".gz"); pos=strstr(ofname, ".gz");
if (pos != NULL) { if (pos != NULL) {
*pos='\0'; *pos='\0';

2
head.c
View File

@ -105,4 +105,4 @@ head_main(int argc, char **argv)
exit(0); exit(0);
} }
/* $Id: head.c,v 1.6 2000/01/25 18:13:53 erik Exp $ */ /* $Id: head.c,v 1.7 2000/02/07 05:29:42 erik Exp $ */

View File

@ -1,5 +1,5 @@
/* /*
* $Id: hostname.c,v 1.5 1999/12/09 06:11:36 andersen Exp $ * $Id: hostname.c,v 1.6 2000/02/07 05:29:42 erik Exp $
* Mini hostname implementation for busybox * Mini hostname implementation for busybox
* *
* Copyright (C) 1999 by Randolph Chung <tausq@debian.org> * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>

17
init.c
View File

@ -40,6 +40,7 @@
#include <sys/reboot.h> #include <sys/reboot.h>
#include <sys/kdaemon.h> #include <sys/kdaemon.h>
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <asm/types.h>
#include <linux/serial.h> /* for serial_struct */ #include <linux/serial.h> /* for serial_struct */
#include <sys/vt.h> /* for vt_stat */ #include <sys/vt.h> /* for vt_stat */
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -123,7 +124,7 @@ int device_open(char *device, int mode)
/* Retry up to 5 times */ /* Retry up to 5 times */
for (f = 0; f < 5; f++) for (f = 0; f < 5; f++)
if ((fd = open(device, m)) >= 0) if ((fd = open(device, m, 0600)) >= 0)
break; break;
if (fd < 0) if (fd < 0)
return fd; return fd;
@ -470,19 +471,19 @@ static void shutdown_system(void)
sync(); sync();
/* Send signals to every process _except_ pid 1 */ /* Send signals to every process _except_ pid 1 */
message(CONSOLE, "Sending SIGHUP to all processes.\r\n"); message(CONSOLE, "Sending SIGTERM to all processes.\r\n");
kill(-1, SIGHUP); kill(-1, SIGTERM);
sleep(2); sleep(5);
sync(); sync();
message(CONSOLE, "Sending SIGKILL to all processes.\r\n"); message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
kill(-1, SIGKILL); kill(-1, SIGKILL);
sleep(1); sleep(5);
message(CONSOLE, "Disabling swap.\r\n"); message(CONSOLE, "Disabling swap.\r\n");
waitfor( "swapoff -a", console, FALSE); waitfor( "swapoff -a", console, FALSE);
message(CONSOLE, "Unmounting filesystems.\r\n"); message(CONSOLE, "Unmounting filesystems.\r\n");
waitfor("umount -a", console, FALSE); waitfor("umount -a -r", console, FALSE);
sync(); sync();
if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) { if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) {
/* bdflush, kupdate not needed for kernels >2.2.11 */ /* bdflush, kupdate not needed for kernels >2.2.11 */
@ -500,7 +501,7 @@ static void halt_signal(int sig)
sync(); sync();
/* allow time for last message to reach serial console */ /* allow time for last message to reach serial console */
sleep(2); sleep(5);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
if (sig == SIGUSR2) if (sig == SIGUSR2)

View File

@ -40,6 +40,7 @@
#include <sys/reboot.h> #include <sys/reboot.h>
#include <sys/kdaemon.h> #include <sys/kdaemon.h>
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <asm/types.h>
#include <linux/serial.h> /* for serial_struct */ #include <linux/serial.h> /* for serial_struct */
#include <sys/vt.h> /* for vt_stat */ #include <sys/vt.h> /* for vt_stat */
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -123,7 +124,7 @@ int device_open(char *device, int mode)
/* Retry up to 5 times */ /* Retry up to 5 times */
for (f = 0; f < 5; f++) for (f = 0; f < 5; f++)
if ((fd = open(device, m)) >= 0) if ((fd = open(device, m, 0600)) >= 0)
break; break;
if (fd < 0) if (fd < 0)
return fd; return fd;
@ -470,19 +471,19 @@ static void shutdown_system(void)
sync(); sync();
/* Send signals to every process _except_ pid 1 */ /* Send signals to every process _except_ pid 1 */
message(CONSOLE, "Sending SIGHUP to all processes.\r\n"); message(CONSOLE, "Sending SIGTERM to all processes.\r\n");
kill(-1, SIGHUP); kill(-1, SIGTERM);
sleep(2); sleep(5);
sync(); sync();
message(CONSOLE, "Sending SIGKILL to all processes.\r\n"); message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
kill(-1, SIGKILL); kill(-1, SIGKILL);
sleep(1); sleep(5);
message(CONSOLE, "Disabling swap.\r\n"); message(CONSOLE, "Disabling swap.\r\n");
waitfor( "swapoff -a", console, FALSE); waitfor( "swapoff -a", console, FALSE);
message(CONSOLE, "Unmounting filesystems.\r\n"); message(CONSOLE, "Unmounting filesystems.\r\n");
waitfor("umount -a", console, FALSE); waitfor("umount -a -r", console, FALSE);
sync(); sync();
if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) { if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) {
/* bdflush, kupdate not needed for kernels >2.2.11 */ /* bdflush, kupdate not needed for kernels >2.2.11 */
@ -500,7 +501,7 @@ static void halt_signal(int sig)
sync(); sync();
/* allow time for last message to reach serial console */ /* allow time for last message to reach serial console */
sleep(2); sleep(5);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
if (sig == SIGUSR2) if (sig == SIGUSR2)

View File

@ -67,8 +67,8 @@ _syscall2(unsigned long, create_module, const char *, name, size_t, size)
#endif #endif
static char m_filename[PATH_MAX] = "\0"; static char m_filename[PATH_MAX + 1] = "\0";
static char m_fullName[PATH_MAX] ="\0"; static char m_fullName[PATH_MAX + 1] = "\0";
static const char insmod_usage[] = static const char insmod_usage[] =
"insmod [OPTION]... MODULE [symbol=value]...\n\n" "insmod [OPTION]... MODULE [symbol=value]...\n\n"
"Loads the specified kernel modules into the kernel.\n\n" "Loads the specified kernel modules into the kernel.\n\n"
@ -101,7 +101,7 @@ extern int insmod_main(int argc, char **argv)
{ {
int len; int len;
char *tmp; char *tmp;
char m_name[PATH_MAX] ="\0"; char m_name[PATH_MAX + 1] ="\0";
FILE *fp; FILE *fp;
if (argc<=1) { if (argc<=1) {

View File

@ -1,3 +1,4 @@
/* /*
* Busybox main internal header file * Busybox main internal header file
* *
@ -20,8 +21,8 @@
* Permission has been granted to redistribute this code under the GPL. * Permission has been granted to redistribute this code under the GPL.
* *
*/ */
#ifndef _INTERNAL_H_ #ifndef _BB_INTERNAL_H_
#define _INTERNAL_H_ #define _BB_INTERNAL_H_ 1
#include "busybox.def.h" #include "busybox.def.h"
@ -37,7 +38,10 @@
#define FALSE ((int) 1) #define FALSE ((int) 1)
#define TRUE ((int) 0) #define TRUE ((int) 0)
#define PATH_LEN 1024 /* for mtab.c */
#define MTAB_GETMOUNTPT '1'
#define MTAB_GETDEVICE '2'
#define BUF_SIZE 8192 #define BUF_SIZE 8192
#define EXPAND_ALLOC 1024 #define EXPAND_ALLOC 1024
@ -55,7 +59,7 @@ struct Applet {
extern int busybox_main(int argc, char** argv); extern int busybox_main(int argc, char** argv);
extern int block_device_main(int argc, char** argv); extern int block_device_main(int argc, char** argv);
extern int cat_main(int argc, char** argv); extern int cat_main(int argc, char** argv);
extern int cp_main(int argc, char** argv); extern int cp_mv_main(int argc, char** argv);
extern int chmod_chown_chgrp_main(int argc, char** argv); extern int chmod_chown_chgrp_main(int argc, char** argv);
extern int chroot_main(int argc, char** argv); extern int chroot_main(int argc, char** argv);
extern int chvt_main(int argc, char** argv); extern int chvt_main(int argc, char** argv);
@ -105,8 +109,7 @@ extern int mnc_main(int argc, char** argv);
extern int more_main(int argc, char** argv); extern int more_main(int argc, char** argv);
extern int mount_main(int argc, char** argv); extern int mount_main(int argc, char** argv);
extern int mt_main(int argc, char** argv); extern int mt_main(int argc, char** argv);
extern int mv_main(int argc, char** argv); extern int nslookup_main(int argc, char **argv);
extern int nslookup_main(int argc, char** argv);
extern int ping_main(int argc, char **argv); extern int ping_main(int argc, char **argv);
extern int poweroff_main(int argc, char **argv); extern int poweroff_main(int argc, char **argv);
extern int printf_main(int argc, char** argv); extern int printf_main(int argc, char** argv);
@ -142,7 +145,7 @@ extern int yes_main(int argc, char** argv);
const char *modeString(int mode); const char *modeString(int mode);
const char *timeString(time_t timeVal); const char *timeString(time_t timeVal);
int isDirectory(const char *name); int isDirectory(const char *name, const int followLinks);
int isDevice(const char *name); int isDevice(const char *name);
int copyFile(const char *srcName, const char *destName, int setModes, int copyFile(const char *srcName, const char *destName, int setModes,
int followLinks); int followLinks);
@ -172,6 +175,11 @@ extern struct mntent *findMountPoint(const char *name, const char *table);
extern void write_mtab(char* blockDevice, char* directory, extern void write_mtab(char* blockDevice, char* directory,
char* filesystemType, long flags, char* string_flags); char* filesystemType, long flags, char* string_flags);
extern void erase_mtab(const char * name); extern void erase_mtab(const char * name);
extern void mtab_read(void);
extern void mtab_free(void);
extern char *mtab_first(void **iter);
extern char *mtab_next(void **iter);
extern char *mtab_getinfo(const char *match, const char which);
extern int check_wildcard_match(const char* text, const char* pattern); extern int check_wildcard_match(const char* text, const char* pattern);
extern long getNum (const char *cp); extern long getNum (const char *cp);
extern pid_t findInitPid(); extern pid_t findInitPid();
@ -226,5 +234,4 @@ static inline int clrbit(char * addr,unsigned int nr)
#endif #endif
#endif /* _INTERNAL_H_ */ #endif /* _BB_INTERNAL_H_ */

View File

@ -6,7 +6,7 @@
extern int extern int
length_main(int argc, char * * argv) length_main(int argc, char * * argv)
{ {
if ( **(argv+1) == '-' ) { if ( argc != 2 || **(argv+1) == '-' ) {
usage("length string\n"); usage("length string\n");
} }
printf("%d\n", strlen(argv[1])); printf("%d\n", strlen(argv[1]));

79
ln.c
View File

@ -22,26 +22,32 @@
*/ */
#include "internal.h" #include "internal.h"
#define BB_DECLARE_EXTERN
#define bb_need_name_too_long
#define bb_need_not_a_directory
#include "messages.c"
#include <stdio.h> #include <stdio.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <sys/param.h> /* for PATH_MAX */
static const char ln_usage[] =
static const char ln_usage[] = "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n" "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n\n"
"Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n" "Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n\n"
"Options:\n" "Options:\n"
"\t-s\tmake symbolic links instead of hard links\n" "\t-s\tmake symbolic links instead of hard links\n"
"\t-f\tremove existing destination files\n"; "\t-f\tremove existing destination files\n"
"\t-n\tno dereference symlinks - treat like normal file\n";
static int symlinkFlag = FALSE; static int symlinkFlag = FALSE;
static int removeoldFlag = FALSE; static int removeoldFlag = FALSE;
static int followLinks = TRUE;
extern int ln_main(int argc, char **argv) extern int ln_main(int argc, char **argv)
{ {
int status; char *linkName;
static char* linkName; int linkIntoDirFlag;
if (argc < 3) { if (argc < 3) {
usage (ln_usage); usage (ln_usage);
@ -59,6 +65,9 @@ extern int ln_main(int argc, char **argv)
case 'f': case 'f':
removeoldFlag = TRUE; removeoldFlag = TRUE;
break; break;
case 'n':
followLinks = FALSE;
break;
default: default:
usage (ln_usage); usage (ln_usage);
} }
@ -66,30 +75,54 @@ extern int ln_main(int argc, char **argv)
argv++; argv++;
} }
linkName = argv[argc - 1]; linkName = argv[argc - 1];
if ((argc > 3) && !(isDirectory(linkName))) { if (strlen(linkName) > PATH_MAX) {
fprintf(stderr, "%s: not a directory\n", linkName); fprintf(stderr, name_too_long, "ln");
exit (FALSE); exit FALSE;
}
linkIntoDirFlag = isDirectory(linkName, TRUE);
if ((argc > 3) && !linkIntoDirFlag) {
fprintf(stderr, not_a_directory, "ln", linkName);
exit FALSE;
} }
while (argc-- >= 2) { while (argc-- >= 2) {
if (removeoldFlag==TRUE ) { char srcName[PATH_MAX + 1];
int nChars, status;
if (strlen(*argv) > PATH_MAX) {
fprintf(stderr, name_too_long, "ln");
exit FALSE;
}
if (followLinks == FALSE) {
strcpy(srcName, *argv);
} else {
/* Warning! This can silently truncate if > PATH_MAX, but
I don't think that there can be one > PATH_MAX anyway. */
nChars = readlink(*argv, srcName, PATH_MAX);
srcName[nChars] = '\0';
}
if (removeoldFlag == TRUE) {
status = ( unlink(linkName) && errno != ENOENT ); status = ( unlink(linkName) && errno != ENOENT );
if ( status != 0 ) { if (status != 0) {
perror(linkName); perror(linkName);
exit( FALSE); exit FALSE;
} }
} }
if ( symlinkFlag==TRUE)
status = symlink(*argv, linkName); if (symlinkFlag == TRUE)
status = symlink(*argv, linkName);
else else
status = link(*argv, linkName); status = link(*argv, linkName);
if ( status != 0 ) { if (status != 0) {
perror(linkName); perror(linkName);
exit( FALSE); exit FALSE;
} }
} }
exit( TRUE); exit TRUE;
} }

2
ls.c
View File

@ -178,7 +178,7 @@ static char append_char(mode_t mode)
static void list_single(const char *name, struct stat *info, const char *fullname) static void list_single(const char *name, struct stat *info, const char *fullname)
{ {
char scratch[PATH_MAX]; char scratch[PATH_MAX + 1];
short len = strlen(name); short len = strlen(name);
#ifdef BB_FEATURE_LS_FILETYPES #ifdef BB_FEATURE_LS_FILETYPES
char append = append_char(info->st_mode); char append = append_char(info->st_mode);

64
messages.c Normal file
View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2000 by BitterSweet Enterprises, LLC.
* Written by Karl M. Hegbloom <karlheg@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/*
* Let's put all of these messages in one place, and link this in as
* a separate object module, so that there are not going to be
* multiple non-unique but very similar strings in the binary.
* Perhaps this will make it simpler to internationalize also, and
* may make the binary slightly smaller.
*/
#ifndef _BB_MESSAGES_C
#define _BB_MESSAGES_C
#define _BB_DEF_MESSAGE_PROTO(symbol) extern const char *symbol;
#define _BB_DEF_MESSAGE_INITIALIZE(symbol, string_const) const char *symbol = string_const;
#ifdef BB_DECLARE_EXTERN
# define BB_DEF_MESSAGE(symbol, string_const) _BB_DEF_MESSAGE_PROTO(symbol)
#else
# define BB_DEF_MESSAGE(symbol, string_const) _BB_DEF_MESSAGE_INITIALIZE(symbol, string_const)
#endif
#if defined bb_need_name_too_long || ! defined BB_DECLARE_EXTERN
BB_DEF_MESSAGE(name_too_long, "%s: file name too long\n")
#endif
#if defined bb_need_omitting_directory || ! defined BB_DECLARE_EXTERN
BB_DEF_MESSAGE(omitting_directory, "%s: %s: omitting directory\n")
#endif
#if defined bb_need_not_a_directory || ! defined BB_DECLARE_EXTERN
BB_DEF_MESSAGE(not_a_directory, "%s: %s: not a directory\n")
#endif
#if defined bb_need_memory_exhausted || ! defined BB_DECLARE_EXTERN
BB_DEF_MESSAGE(memory_exhausted, "%s: memory exhausted\n")
#endif
#if defined bb_need_invalid_date || ! defined BB_DECLARE_EXTERN
BB_DEF_MESSAGE(invalid_date, "%s: invalid date `%s'\n")
#endif
#if defined bb_need_invalid_option || ! defined BB_DECLARE_EXTERN
BB_DEF_MESSAGE(invalid_option, "%s: invalid option -- %c\n")
#endif
#endif /* _BB_MESSAGES_C */

34
mkdir.c
View File

@ -22,9 +22,13 @@
*/ */
#include "internal.h" #include "internal.h"
#define bb_need_name_too_long
#define BB_DECLARE_EXTERN
#include "messages.c"
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include <sys/param.h> #include <sys/param.h> /* for PATH_MAX */
static const char mkdir_usage[] = static const char mkdir_usage[] =
"mkdir [OPTION] DIRECTORY...\n\n" "mkdir [OPTION] DIRECTORY...\n\n"
@ -40,27 +44,27 @@ static mode_t mode = 0777;
extern int mkdir_main(int argc, char **argv) extern int mkdir_main(int argc, char **argv)
{ {
int i=FALSE; int i = FALSE;
argc--; argc--;
argv++; argv++;
/* Parse any options */ /* Parse any options */
while (argc > 0 && **argv == '-') { while (argc > 0 && **argv == '-') {
while (i==FALSE && *++(*argv)) { while (i == FALSE && *++(*argv)) {
switch (**argv) { switch (**argv) {
case 'm': case 'm':
if (--argc == 0) if (--argc == 0)
usage( mkdir_usage); usage( mkdir_usage);
/* Find the specified modes */ /* Find the specified modes */
mode = 0; mode = 0;
if ( parse_mode(*(++argv), &mode) == FALSE ) { if (parse_mode(*(++argv), &mode) == FALSE ) {
fprintf(stderr, "Unknown mode: %s\n", *argv); fprintf(stderr, "Unknown mode: %s\n", *argv);
exit( FALSE); exit FALSE;
} }
/* Set the umask for this process so it doesn't /* Set the umask for this process so it doesn't
* screw up whatever the user just entered. */ * screw up whatever the user just entered. */
umask(0); umask(0);
i=TRUE; i = TRUE;
break; break;
case 'p': case 'p':
parentFlag = TRUE; parentFlag = TRUE;
@ -73,7 +77,6 @@ extern int mkdir_main(int argc, char **argv)
argv++; argv++;
} }
if (argc < 1) { if (argc < 1) {
usage( mkdir_usage); usage( mkdir_usage);
} }
@ -81,13 +84,16 @@ extern int mkdir_main(int argc, char **argv)
while (argc > 0) { while (argc > 0) {
int status; int status;
struct stat statBuf; struct stat statBuf;
char buf[NAME_MAX]; char buf[PATH_MAX + 1];
if (strlen(*argv) > PATH_MAX - 1) {
fprintf(stderr, name_too_long, "mkdir");
exit FALSE;
}
strcpy (buf, *argv); strcpy (buf, *argv);
status=stat(buf, &statBuf); status = stat(buf, &statBuf);
if (parentFlag == FALSE && status != -1 && status != ENOENT ) { if (parentFlag == FALSE && status != -1 && errno != ENOENT) {
fprintf(stderr, "%s: File exists\n", buf); fprintf(stderr, "%s: File exists\n", buf);
exit( FALSE); exit FALSE;
} }
if (parentFlag == TRUE) { if (parentFlag == TRUE) {
strcat( buf, "/"); strcat( buf, "/");
@ -96,13 +102,13 @@ extern int mkdir_main(int argc, char **argv)
else { else {
if (mkdir (buf, mode) != 0 && parentFlag == FALSE) { if (mkdir (buf, mode) != 0 && parentFlag == FALSE) {
perror(buf); perror(buf);
exit( FALSE); exit FALSE;
} }
} }
argc--; argc--;
argv++; argv++;
} }
exit( TRUE); exit TRUE;
} }

View File

@ -67,8 +67,8 @@ _syscall2(unsigned long, create_module, const char *, name, size_t, size)
#endif #endif
static char m_filename[PATH_MAX] = "\0"; static char m_filename[PATH_MAX + 1] = "\0";
static char m_fullName[PATH_MAX] ="\0"; static char m_fullName[PATH_MAX + 1] = "\0";
static const char insmod_usage[] = static const char insmod_usage[] =
"insmod [OPTION]... MODULE [symbol=value]...\n\n" "insmod [OPTION]... MODULE [symbol=value]...\n\n"
"Loads the specified kernel modules into the kernel.\n\n" "Loads the specified kernel modules into the kernel.\n\n"
@ -101,7 +101,7 @@ extern int insmod_main(int argc, char **argv)
{ {
int len; int len;
char *tmp; char *tmp;
char m_name[PATH_MAX] ="\0"; char m_name[PATH_MAX + 1] ="\0";
FILE *fp; FILE *fp;
if (argc<=1) { if (argc<=1) {

24
mtab.c
View File

@ -5,21 +5,13 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <mntent.h> #include <mntent.h>
#include <fstab.h>
#include <sys/mount.h> #include <sys/mount.h>
extern const char mtab_file[]; /* Defined in utility.c */ extern const char mtab_file[]; /* Defined in utility.c */
static char *
stralloc(const char * string)
{
int length = strlen(string) + 1;
char * n = malloc(length);
memcpy(n, string, length);
return n;
}
extern void void erase_mtab(const char * name)
erase_mtab(const char * name)
{ {
struct mntent entries[20]; struct mntent entries[20];
int count = 0; int count = 0;
@ -39,10 +31,10 @@ erase_mtab(const char * name)
} }
while ( (m = getmntent(mountTable)) != 0 ) { while ( (m = getmntent(mountTable)) != 0 ) {
entries[count].mnt_fsname = stralloc(m->mnt_fsname); entries[count].mnt_fsname = strdup(m->mnt_fsname);
entries[count].mnt_dir = stralloc(m->mnt_dir); entries[count].mnt_dir = strdup(m->mnt_dir);
entries[count].mnt_type = stralloc(m->mnt_type); entries[count].mnt_type = strdup(m->mnt_type);
entries[count].mnt_opts = stralloc(m->mnt_opts); entries[count].mnt_opts = strdup(m->mnt_opts);
entries[count].mnt_freq = m->mnt_freq; entries[count].mnt_freq = m->mnt_freq;
entries[count].mnt_passno = m->mnt_passno; entries[count].mnt_passno = m->mnt_passno;
count++; count++;
@ -65,8 +57,7 @@ erase_mtab(const char * name)
perror(mtab_file); perror(mtab_file);
} }
extern void void write_mtab(char* blockDevice, char* directory,
write_mtab(char* blockDevice, char* directory,
char* filesystemType, long flags, char* string_flags) char* filesystemType, long flags, char* string_flags)
{ {
FILE *mountTable = setmntent(mtab_file, "a+"); FILE *mountTable = setmntent(mtab_file, "a+");
@ -110,4 +101,3 @@ write_mtab(char* blockDevice, char* directory,
} }
} }

112
mv.c
View File

@ -1,112 +0,0 @@
/*
* Mini mv implementation for busybox
*
*
* Copyright (C) 1999 by Lineo, inc.
* Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "internal.h"
#include <stdio.h>
#include <time.h>
#include <utime.h>
#include <dirent.h>
static const char mv_usage[] = "mv SOURCE DEST\n"
" or: mv SOURCE... DIRECTORY\n\n"
"Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n";
static const char *srcName;
static const char *destName;
static int destDirFlag = FALSE;
static int srcDirFlag = FALSE;
static int fileAction(const char *fileName, struct stat* statbuf)
{
char newdestName[NAME_MAX];
char* newsrcName = NULL;
strcpy(newdestName, destName);
if ( srcDirFlag == TRUE ) {
strcat(newdestName, strstr(fileName, srcName) + strlen(srcName));
}
if (destDirFlag==TRUE && srcDirFlag == FALSE) {
if (newdestName[strlen(newdestName)-1] != '/' ) {
strcat(newdestName, "/");
}
newsrcName = strrchr(srcName, '/');
if (newsrcName && *newsrcName != '\0')
strcat(newdestName, newsrcName);
else
strcat(newdestName, srcName);
}
return (copyFile(fileName, newdestName, TRUE, TRUE));
}
static int rmfileAction(const char *fileName, struct stat* statbuf)
{
if (unlink( fileName) < 0 ) {
perror( fileName);
return ( FALSE);
}
return ( TRUE);
}
static int rmdirAction(const char *fileName, struct stat* statbuf)
{
if (rmdir( fileName) < 0 ) {
perror( fileName);
return ( FALSE);
}
return ( TRUE);
}
extern int mv_main(int argc, char **argv)
{
if (argc < 3) {
usage (mv_usage);
}
argc--;
argv++;
destName = argv[argc - 1];
destDirFlag = isDirectory(destName);
if ((argc > 3) && destDirFlag==FALSE) {
fprintf(stderr, "%s: not a directory\n", destName);
exit (FALSE);
}
while (argc-- > 1) {
srcName = *(argv++);
srcDirFlag = isDirectory(srcName);
if (recursiveAction(srcName, TRUE, TRUE, FALSE,
fileAction, fileAction) == FALSE) {
exit( FALSE);
}
if (recursiveAction(srcName, TRUE, TRUE, TRUE,
rmfileAction, rmdirAction) == FALSE) {
exit( FALSE);
}
}
exit( TRUE);
}

View File

@ -1,5 +1,5 @@
/* /*
* $Id: hostname.c,v 1.5 1999/12/09 06:11:36 andersen Exp $ * $Id: hostname.c,v 1.6 2000/02/07 05:29:42 erik Exp $
* Mini hostname implementation for busybox * Mini hostname implementation for busybox
* *
* Copyright (C) 1999 by Randolph Chung <tausq@debian.org> * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>

View File

@ -185,4 +185,4 @@ nslookup_main(int argc, char **argv)
return 0; return 0;
} }
/* $Id: nslookup.c,v 1.2 2000/01/30 09:47:16 beppu Exp $ */ /* $Id: nslookup.c,v 1.3 2000/02/07 05:29:42 erik Exp $ */

View File

@ -1,5 +1,5 @@
/* /*
* $Id: ping.c,v 1.9 2000/01/29 06:29:32 erik Exp $ * $Id: ping.c,v 1.10 2000/02/07 05:29:42 erik Exp $
* Mini ping implementation for busybox * Mini ping implementation for busybox
* *
* Copyright (C) 1999 by Randolph Chung <tausq@debian.org> * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
@ -175,7 +175,8 @@ extern int ping_main(int argc, char **argv)
static const char* ping_usage = "ping [OPTION]... host\n\n" static const char* ping_usage = "ping [OPTION]... host\n\n"
"Send ICMP ECHO_REQUEST packets to network hosts.\n\n" "Send ICMP ECHO_REQUEST packets to network hosts.\n\n"
"Options:\n" "Options:\n"
"\t-q\t\tQuiet mode, only displays output at start and when finished.\n" "\t-q\t\tQuiet mode, only displays output at start"
"\t\t\tand when finished.\n"
"\t-c COUNT\tSend only COUNT pings.\n"; "\t-c COUNT\tSend only COUNT pings.\n";
static char *hostname = NULL; static char *hostname = NULL;

View File

@ -185,4 +185,4 @@ nslookup_main(int argc, char **argv)
return 0; return 0;
} }
/* $Id: nslookup.c,v 1.2 2000/01/30 09:47:16 beppu Exp $ */ /* $Id: nslookup.c,v 1.3 2000/02/07 05:29:42 erik Exp $ */

5
ping.c
View File

@ -1,5 +1,5 @@
/* /*
* $Id: ping.c,v 1.9 2000/01/29 06:29:32 erik Exp $ * $Id: ping.c,v 1.10 2000/02/07 05:29:42 erik Exp $
* Mini ping implementation for busybox * Mini ping implementation for busybox
* *
* Copyright (C) 1999 by Randolph Chung <tausq@debian.org> * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
@ -175,7 +175,8 @@ extern int ping_main(int argc, char **argv)
static const char* ping_usage = "ping [OPTION]... host\n\n" static const char* ping_usage = "ping [OPTION]... host\n\n"
"Send ICMP ECHO_REQUEST packets to network hosts.\n\n" "Send ICMP ECHO_REQUEST packets to network hosts.\n\n"
"Options:\n" "Options:\n"
"\t-q\t\tQuiet mode, only displays output at start and when finished.\n" "\t-q\t\tQuiet mode, only displays output at start"
"\t\t\tand when finished.\n"
"\t-c COUNT\tSend only COUNT pings.\n"; "\t-c COUNT\tSend only COUNT pings.\n";
static char *hostname = NULL; static char *hostname = NULL;

View File

@ -143,7 +143,7 @@ printf_main(int argc, char** argv)
int args_used; int args_used;
exit_status = 0; exit_status = 0;
if ( **(argv+1) == '-' ) { if ( argc <= 1 || **(argv+1) == '-' ) {
usage (printf_usage); usage (printf_usage);
} }

3
pwd.c
View File

@ -23,11 +23,12 @@
#include "internal.h" #include "internal.h"
#include <stdio.h> #include <stdio.h>
#include <dirent.h> #include <dirent.h>
#include <sys/param.h>
extern int extern int
pwd_main(int argc, char * * argv) pwd_main(int argc, char * * argv)
{ {
char buf[NAME_MAX]; char buf[PATH_MAX + 1];
if ( getcwd(buf, sizeof(buf)) == NULL ) { if ( getcwd(buf, sizeof(buf)) == NULL ) {
perror("get working directory"); perror("get working directory");

2
sort.c
View File

@ -309,4 +309,4 @@ sort_main(int argc, char **argv)
exit(0); exit(0);
} }
/* $Id: sort.c,v 1.9 2000/01/23 18:19:02 erik Exp $ */ /* $Id: sort.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */

View File

@ -65,7 +65,6 @@ static void
do_em_all() do_em_all()
{ {
struct mntent *m; struct mntent *m;
char swapName[NAME_MAX];
FILE *f = setmntent ("/etc/fstab", "r"); FILE *f = setmntent ("/etc/fstab", "r");
if (f == NULL) { if (f == NULL) {
@ -73,8 +72,8 @@ do_em_all()
exit( FALSE); exit( FALSE);
} }
while ((m = getmntent (f)) != NULL) { while ((m = getmntent (f)) != NULL) {
if (!strstr (m->mnt_type, "swap")) { if (!strstr (m->mnt_type, MNTTYPE_SWAP)) {
swap_enable_disable( swapName); swap_enable_disable( m->mnt_fsname);
} }
} }
endmntent (f); endmntent (f);

View File

@ -77,7 +77,7 @@ static int device_open(char *device, int mode)
/* Retry up to 5 times */ /* Retry up to 5 times */
for (f = 0; f < 5; f++) for (f = 0; f < 5; f++)
if ((fd = open(device, m)) >= 0) if ((fd = open(device, m, 0600)) >= 0)
break; break;
if (fd < 0) if (fd < 0)
return fd; return fd;
@ -177,9 +177,6 @@ static void doSyslogd(void)
char *q, *p = buf; char *q, *p = buf;
int readSize; int readSize;
/* Remove any preexisting socket/file */
unlink(_PATH_LOG);
/* Set up sig handlers */ /* Set up sig handlers */
signal(SIGINT, quit_signal); signal(SIGINT, quit_signal);
signal(SIGTERM, quit_signal); signal(SIGTERM, quit_signal);
@ -188,8 +185,9 @@ static void doSyslogd(void)
signal(SIGALRM, domark); signal(SIGALRM, domark);
alarm(MarkInterval); alarm(MarkInterval);
/* Remove any preexisting socket/file */
unlink(_PATH_LOG);
unlink( _PATH_LOG);
memset(&sunx, 0, sizeof(sunx)); memset(&sunx, 0, sizeof(sunx));
sunx.sun_family = AF_UNIX; /* Unix domain socket */ sunx.sun_family = AF_UNIX; /* Unix domain socket */
strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path)); strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path));
@ -200,12 +198,17 @@ static void doSyslogd(void)
addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path); addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
if ( (bind(fd, (struct sockaddr *) &sunx, addrLength)) || if ( (bind(fd, (struct sockaddr *) &sunx, addrLength)) ||
(fchmod(fd, 0666) < 0) || (listen(fd, 5)) ) (listen(fd, 5)) )
{ {
perror("Could not connect to socket " _PATH_LOG); perror("Could not connect to socket " _PATH_LOG);
exit( FALSE); exit( FALSE);
} }
umask(0);
if (chmod(_PATH_LOG, 0666) < 0) {
perror("Could not set permission on " _PATH_LOG);
exit (FALSE);
}
logMessage(LOG_SYSLOG|LOG_INFO, "syslogd started: " logMessage(LOG_SYSLOG|LOG_INFO, "syslogd started: "
"BusyBox v" BB_VER " (" BB_BT ")"); "BusyBox v" BB_VER " (" BB_BT ")");

View File

@ -77,7 +77,7 @@ static int device_open(char *device, int mode)
/* Retry up to 5 times */ /* Retry up to 5 times */
for (f = 0; f < 5; f++) for (f = 0; f < 5; f++)
if ((fd = open(device, m)) >= 0) if ((fd = open(device, m, 0600)) >= 0)
break; break;
if (fd < 0) if (fd < 0)
return fd; return fd;
@ -177,9 +177,6 @@ static void doSyslogd(void)
char *q, *p = buf; char *q, *p = buf;
int readSize; int readSize;
/* Remove any preexisting socket/file */
unlink(_PATH_LOG);
/* Set up sig handlers */ /* Set up sig handlers */
signal(SIGINT, quit_signal); signal(SIGINT, quit_signal);
signal(SIGTERM, quit_signal); signal(SIGTERM, quit_signal);
@ -188,8 +185,9 @@ static void doSyslogd(void)
signal(SIGALRM, domark); signal(SIGALRM, domark);
alarm(MarkInterval); alarm(MarkInterval);
/* Remove any preexisting socket/file */
unlink(_PATH_LOG);
unlink( _PATH_LOG);
memset(&sunx, 0, sizeof(sunx)); memset(&sunx, 0, sizeof(sunx));
sunx.sun_family = AF_UNIX; /* Unix domain socket */ sunx.sun_family = AF_UNIX; /* Unix domain socket */
strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path)); strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path));
@ -200,12 +198,17 @@ static void doSyslogd(void)
addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path); addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
if ( (bind(fd, (struct sockaddr *) &sunx, addrLength)) || if ( (bind(fd, (struct sockaddr *) &sunx, addrLength)) ||
(fchmod(fd, 0666) < 0) || (listen(fd, 5)) ) (listen(fd, 5)) )
{ {
perror("Could not connect to socket " _PATH_LOG); perror("Could not connect to socket " _PATH_LOG);
exit( FALSE); exit( FALSE);
} }
umask(0);
if (chmod(_PATH_LOG, 0666) < 0) {
perror("Could not set permission on " _PATH_LOG);
exit (FALSE);
}
logMessage(LOG_SYSLOG|LOG_INFO, "syslogd started: " logMessage(LOG_SYSLOG|LOG_INFO, "syslogd started: "
"BusyBox v" BB_VER " (" BB_BT ")"); "BusyBox v" BB_VER " (" BB_BT ")");

2
tail.c
View File

@ -33,7 +33,7 @@
and generally busyboxed, Erik Andersen <andersen@lineo.com> and generally busyboxed, Erik Andersen <andersen@lineo.com>
Removed superfluous options and associated code ("-c", "-n", "-q"). Removed superfluous options and associated code ("-c", "-n", "-q").
Removed "tail -f" suport for multiple files. Removed "tail -f" support for multiple files.
Both changes by Friedrich Vedder <fwv@myrtle.lahn.de>. Both changes by Friedrich Vedder <fwv@myrtle.lahn.de>.
*/ */

3
tar.c
View File

@ -40,6 +40,7 @@
#include <utime.h> #include <utime.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <sys/param.h> /* for PATH_MAX */
#ifdef BB_FEATURE_TAR_CREATE #ifdef BB_FEATURE_TAR_CREATE
@ -1041,7 +1042,7 @@ static void saveDirectory (const char *dirName, const struct stat *statbuf)
DIR *dir; DIR *dir;
struct dirent *entry; struct dirent *entry;
int needSlash; int needSlash;
char fullName[NAME_MAX]; char fullName[PATH_MAX + 1];
/* /*
* Construct the directory name as used in the tar file by appending * Construct the directory name as used in the tar file by appending

2
tee.c
View File

@ -123,4 +123,4 @@ tee_main(int argc, char **argv)
exit(0); exit(0);
} }
/* $Id: tee.c,v 1.4 1999/12/10 08:25:07 andersen Exp $ */ /* $Id: tee.c,v 1.5 2000/02/07 05:29:42 erik Exp $ */

28
tests/Makefile Normal file
View File

@ -0,0 +1,28 @@
all test_all: message_header cp_tests mv_tests ln_tests
clean: cp_clean mv_clean ln_clean
message_header:
@echo
@echo If tests faile due to differences in timestamps in commands that are not set
@echo to preserve timestamps, just run the tests again.
@echo
include cp_tests.mk
include mv_tests.mk
include ln_tests.mk
BBL := $(shell pushd .. >/dev/null && \
${MAKE} busybox.links >/dev/null && \
popd >/dev/null && \
cat ../busybox.links | \
sed -e 's,.*/\(.*\)$$,\1,')
../busybox:
cd .. && ${MAKE} busybox
$(BBL): ../busybox
rm -f $@
ln ../busybox $@
.PHONY: all test_all message_header

270
tests/cp_tests.mk Normal file
View File

@ -0,0 +1,270 @@
# This is a -*- makefile -*-
# GNU `cp'
GCP = /bin/cp
# BusyBox `cp'
BCP = $(shell pwd)/cp
.PHONY: cp_clean
cp_clean:
rm -rf cp_tests cp_*.{gnu,bb} cp
.PHONY: cp_tests
cp_tests: cp_clean cp
@echo;
@echo "No output from diff means busybox cp is functioning properly.";
@echo;
${BCP} || true;
@echo;
mkdir cp_tests;
@echo;
cd cp_tests; \
echo A file > afile; \
ls -l afile > ../cp_afile_afilecopy.gnu; \
${GCP} afile afilecopy; \
ls -l afile afilecopy >> ../cp_afile_afilecopy.gnu;
@echo;
rm -f cp_tests/afile*;
@echo;
cd cp_tests; \
echo A file > afile; \
ls -l afile > ../cp_afile_afilecopy.bb; \
${BCP} afile afilecopy; \
ls -l afile afilecopy >> ../cp_afile_afilecopy.bb;
@echo;
diff -u cp_afile_afilecopy.gnu cp_afile_afilecopy.bb;
@echo;
rm -f cp_tests/afile*;
@echo; echo;
cd cp_tests; \
mkdir there there1; \
cd there; \
ln -s ../afile .;
@echo;
cd cp_tests; \
echo A file > afile; \
ls -l afile > ../cp_symlink.gnu; \
${GCP} there/afile there1/; \
ls -l afile there/afile there1/afile >> ../cp_symlink.gnu;
@echo;
rm -f cp_tests/afile cp_tests/there1/afile;
@echo;
cd cp_tests; \
echo A file > afile; \
ls -l afile > ../cp_symlink.bb; \
${BCP} there/afile there1/; \
ls -l afile there/afile there1/afile >> ../cp_symlink.bb;
@echo;
diff -u cp_symlink.gnu cp_symlink.bb;
@echo;
rm -f cp_tests/afile cp_tests/there1/afile;
@echo; echo;
cd cp_tests; \
echo A file > afile; \
ls -l afile > ../cp_a_symlink.gnu; \
${GCP} -a there/afile there1/; \
ls -l afile there/afile there1/afile >> ../cp_a_symlink.gnu;
@echo;
rm -f cp_tests/afile cp_tests/there1/afile;
@echo;
cd cp_tests; \
echo A file > afile; \
ls -l afile > ../cp_a_symlink.bb; \
${BCP} -a there/afile there1/; \
ls -l afile there/afile there1/afile >> ../cp_a_symlink.bb;
@echo;
diff -u cp_a_symlink.gnu cp_a_symlink.bb;
@echo;
rm -f cp_tests/afile
rm -rf cp_tests/there{,1};
@echo; echo;
cd cp_tests; \
echo A file > there/afile; \
mkdir there/adir; \
touch there/adir/afileinadir; \
ln -s $(shell pwd) there/alink;
@echo;
cd cp_tests; \
${GCP} -a there/ there1/; \
ls -lR there/ there1/ > ../cp_a_dir_dir.gnu;
@echo;
rm -rf cp_tests/there1;
@echo;
cd cp_tests; \
${BCP} -a there/ there1/; \
ls -lR there/ there1/ > ../cp_a_dir_dir.bb;
@echo;
diff -u cp_a_dir_dir.gnu cp_a_dir_dir.bb;
@echo;
rm -rf cp_tests/there1/;
@echo; echo;
cd cp_tests; \
echo A file number one > afile1; \
echo A file number two, blah. > afile2; \
ln -s afile1 symlink1; \
mkdir there1; \
${GCP} afile1 afile2 symlink1 there1/; \
ls -lR > ../cp_files_dir.gnu;
@echo;
rm -rf cp_tests/{afile{1,2},symlink1,there1};
@echo;
cd cp_tests; \
echo A file number one > afile1; \
echo A file number two, blah. > afile2; \
ln -s afile1 symlink1; \
mkdir there1; \
${BCP} afile1 afile2 symlink1 there1/; \
ls -lR > ../cp_files_dir.bb;
@echo;
diff -u cp_files_dir.gnu cp_files_dir.bb;
@echo;
rm -rf cp_tests/{afile{1,2},symlink1,there1};
@echo; echo;
cd cp_tests; \
echo A file number one > afile1; \
echo A file number two, blah. > afile2; \
ln -s afile1 symlink1; \
mkdir there1; \
${GCP} -d afile1 afile2 symlink1 there1/; \
ls -lR > ../cp_d_files_dir.gnu;
@echo;
rm -rf cp_tests/{afile{1,2},symlink1,there1};
@echo;
cd cp_tests; \
echo A file number one > afile1; \
echo A file number two, blah. > afile2; \
ln -s afile1 symlink1; \
mkdir there1; \
${BCP} -d afile1 afile2 symlink1 there1/; \
ls -lR > ../cp_d_files_dir.bb;
@echo;
diff -u cp_d_files_dir.gnu cp_d_files_dir.bb;
@echo;
rm -rf cp_tests/{afile{1,2},symlink1,there1};
@echo; echo;
cd cp_tests; \
echo A file number one > afile1; \
echo A file number two, blah. > afile2; \
touch --date='Sat Jan 29 21:24:08 PST 2000' afile1; \
ln -s afile1 symlink1; \
mkdir there1; \
${GCP} -p afile1 afile2 symlink1 there1/; \
ls -lR > ../cp_p_files_dir.gnu;
@echo;
rm -rf cp_tests/{afile{1,2},symlink1,there1};
@echo;
cd cp_tests; \
echo A file number one > afile1; \
echo A file number two, blah. > afile2; \
touch --date='Sat Jan 29 21:24:08 PST 2000' afile1; \
ln -s afile1 symlink1; \
mkdir there1; \
${BCP} -p afile1 afile2 symlink1 there1/; \
ls -lR > ../cp_p_files_dir.bb;
@echo;
diff -u cp_p_files_dir.gnu cp_p_files_dir.bb;
@echo;
rm -rf cp_tests/{afile{1,2},symlink1,there1};
@echo; echo;
cd cp_tests; \
echo A file number one > afile1; \
echo A file number two, blah. > afile2; \
touch --date='Sat Jan 29 21:24:08 PST 2000' afile1; \
ln -s afile1 symlink1; \
mkdir there1; \
${GCP} -p -d afile1 afile2 symlink1 there1/; \
ls -lR > ../cp_pd_files_dir.gnu;
@echo;
rm -rf cp_tests/{afile{1,2},symlink1,there1};
@echo;
cd cp_tests; \
echo A file number one > afile1; \
echo A file number two, blah. > afile2; \
touch --date='Sat Jan 29 21:24:08 PST 2000' afile1; \
ln -s afile1 symlink1; \
mkdir there1; \
${BCP} -p -d afile1 afile2 symlink1 there1/; \
ls -lR > ../cp_pd_files_dir.bb;
@echo;
diff -u cp_pd_files_dir.gnu cp_pd_files_dir.bb;
@echo;
rm -rf cp_tests/{afile{1,2},symlink1,there1};
@echo; echo;
cd cp_tests; \
mkdir dir{a,b}; \
echo A file > dira/afile; \
echo A file in dirb > dirb/afileindirb; \
ln -s dira/afile dira/alinktoafile; \
mkdir dira/subdir1; \
echo Another file > dira/subdir1/anotherfile; \
ls -lR . > ../cp_a_dira_dirb.gnu; \
${GCP} -a dira dirb; \
ls -lR . >> ../cp_a_dira_dirb.gnu;
# false;
@echo;
rm -rf cp_tests/dir{a,b};
@echo;
cd cp_tests; \
mkdir dir{a,b}; \
echo A file > dira/afile; \
echo A file in dirb > dirb/afileindirb; \
ln -s dira/afile dira/alinktoafile; \
mkdir dira/subdir1; \
echo Another file > dira/subdir1/anotherfile; \
ls -lR . > ../cp_a_dira_dirb.bb; \
${BCP} -a dira dirb; \
ls -lR . >> ../cp_a_dira_dirb.bb;
@echo;
diff -u cp_a_dira_dirb.gnu cp_a_dira_dirb.bb;
# false;
@echo;
rm -rf cp_tests/dir{a,b};

66
tests/ln_tests.mk Normal file
View File

@ -0,0 +1,66 @@
# GNU `ln'
GLN = /bin/ln
# BusyBox `ln'
BLN = $(shell pwd)/ln
.PHONY: ln_clean
ln_clean:
rm -rf ln_tests ln_*.{gnu,bb} ln
.PHONY: ln_tests
ln_tests: ln_clean ln
@echo;
@echo "No output from diff means busybox ln is functioning properly.";
@echo;
${BLN} || true;
@echo;
mkdir ln_tests;
@echo;
cd ln_tests; \
echo A file > afile; \
ls -l afile > ../ln_afile_newname.gnu; \
${GLN} afile newname; \
ls -l afile newname >> ../ln_afile_newname.gnu;
@echo;
rm -f ln_tests/{afile,newname};
@echo;
cd ln_tests; \
echo A file > afile; \
ls -l afile > ../ln_afile_newname.bb; \
${BLN} afile newname; \
ls -l afile newname >> ../ln_afile_newname.bb;
@echo;
diff -u ln_afile_newname.gnu ln_afile_newname.bb
@echo;
rm -f ln_tests/{afile,newname};
@echo;
cd ln_tests; \
echo A file > afile; \
ls -l afile > ../ln_s_afile_newname.gnu; \
${GLN} -s afile newname; \
ls -l afile newname >> ../ln_s_afile_newname.gnu;
@echo;
rm -f ln_tests/{afile,newname};
@echo;
cd ln_tests; \
echo A file > afile; \
ls -l afile > ../ln_s_afile_newname.bb; \
${BLN} -s afile newname; \
ls -l afile newname >> ../ln_s_afile_newname.bb;
@echo;
diff -u ln_s_afile_newname.gnu ln_s_afile_newname.bb
@echo;
rm -f ln_tests/{afile,newname};

137
tests/mv_tests.mk Normal file
View File

@ -0,0 +1,137 @@
# GNU `mv'
GMV = /bin/mv
# BusyBox `mv'
BMV = $(shell pwd)/mv
.PHONY: mv_clean
mv_clean:
rm -rf mv_tests mv_*.{gnu,bb} mv
.PHONY: mv_tests
mv_tests: mv_clean mv
@echo;
@echo "No output from diff means busybox mv is functioning properly.";
@echo;
@echo "No such file or directory is good; it means the old file got removed.";
@echo;
${BMV} || true;
@echo;
mkdir mv_tests;
@echo;
cd mv_tests; \
echo A file > afile; \
ls -l afile > ../mv_afile_newname.gnu; \
${GMV} afile newname; \
ls -l newname >> ../mv_afile_newname.gnu;
-ls -l mv_tests/afile;
@echo;
rm -f mv_tests/{afile,newname};
@echo;
cd mv_tests; \
echo A file > afile; \
ls -l afile > ../mv_afile_newname.bb; \
${BMV} afile newname; \
ls -l newname >> ../mv_afile_newname.bb;
-ls -l mv_tests/afile;
@echo;
diff -u mv_afile_newname.gnu mv_afile_newname.bb;
@echo;
rm -f mv_tests/{afile,newname};
@echo; echo;
cd mv_tests; \
echo A file > afile; \
ln -s afile symlink; \
ls -l afile symlink > ../mv_symlink_newname.gnu; \
${GMV} symlink newname; \
ls -l afile newname >> ../mv_symlink_newname.gnu;
-ls -l mv_tests/symlink;
@echo;
rm -f mv_tests/{afile,newname};
@echo;
cd mv_tests; \
echo A file > afile; \
ln -s afile symlink; \
ls -l afile symlink > ../mv_symlink_newname.bb;\
${BMV} symlink newname; \
ls -l afile newname >> ../mv_symlink_newname.bb;
-ls -l mv_tests/symlink;
@echo;
diff -u mv_symlink_newname.gnu mv_symlink_newname.bb;
@echo;
rm -rf mv_tests/*;
@echo; echo;
cd mv_tests; \
echo A file > afile; \
ln -s afile symlink; \
mkdir newdir; \
ls -lR > ../mv_file_symlink_dir.gnu; \
${GMV} symlink afile newdir; \
ls -lR >> ../mv_file_symlink_dir.gnu;
-ls -l mv_tests/{symlink,afile};
@echo;
rm -rf mv_tests/*
@echo; echo;
cd mv_tests; \
echo A file > afile; \
ln -s afile symlink; \
mkdir newdir; \
ls -lR > ../mv_file_symlink_dir.bb; \
${BMV} symlink afile newdir; \
ls -lR >> ../mv_file_symlink_dir.bb;
-ls -l mv_tests/{symlink,afile};
@echo;
diff -u mv_file_symlink_dir.gnu mv_file_symlink_dir.bb;
@echo;
rm -rf mv_tests/*;
@echo; echo;
cd mv_tests; \
mkdir dir{a,b}; \
echo A file > dira/afile; \
echo A file in dirb > dirb/afileindirb; \
ln -s dira/afile dira/alinktoafile; \
mkdir dira/subdir1; \
echo Another file > dira/subdir1/anotherfile; \
ls -lR . > ../mv_dira_dirb.gnu; \
${GMV} dira dirb; \
ls -lR . >> ../mv_dira_dirb.gnu;
# false;
@echo;
rm -rf mv_tests/dir{a,b};
@echo;
cd mv_tests; \
mkdir dir{a,b}; \
echo A file > dira/afile; \
echo A file in dirb > dirb/afileindirb; \
ln -s dira/afile dira/alinktoafile; \
mkdir dira/subdir1; \
echo Another file > dira/subdir1/anotherfile; \
ls -lR . > ../mv_dira_dirb.bb; \
${BMV} dira dirb; \
ls -lR . >> ../mv_dira_dirb.bb;
@echo;
diff -u mv_dira_dirb.gnu mv_dira_dirb.bb;
# false;
@echo;
rm -rf mv_tests/dir{a,b};

193
umount.c
View File

@ -37,11 +37,24 @@ static const char umount_usage[] =
#else #else
"\n" "\n"
#endif #endif
#ifdef BB_FEATURE_REMOUNT
"\t-r:\tTry to remount devices as read-only if mount is busy\n"
#endif
; ;
struct _mtab_entry_t {
char *device;
char *mountpt;
struct _mtab_entry_t *next;
};
static struct _mtab_entry_t *mtab_cache = NULL;
static int useMtab = TRUE; static int useMtab = TRUE;
static int umountAll = FALSE; static int umountAll = FALSE;
static int doRemount = FALSE;
extern const char mtab_file[]; /* Defined in utility.c */ extern const char mtab_file[]; /* Defined in utility.c */
#define MIN(x,y) (x > y ? x : y) #define MIN(x,y) (x > y ? x : y)
@ -50,21 +63,10 @@ static int
do_umount(const char* name, int useMtab) do_umount(const char* name, int useMtab)
{ {
int status; int status;
struct mntent *m; char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE);
FILE *mountTable;
const char *blockDevice = NULL;
if ((mountTable = setmntent (mtab_file, "r"))) { if (blockDevice && strcmp(blockDevice, name) == 0)
while ((m = getmntent (mountTable)) != 0) { name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT);
if (strncmp(m->mnt_dir, name,
MIN(strlen(m->mnt_dir),strlen(name))) == 0)
blockDevice = m->mnt_fsname;
else if (strcmp(m->mnt_fsname, name) == 0) {
blockDevice = name;
name = m->mnt_dir;
}
}
}
status = umount(name); status = umount(name);
@ -73,57 +75,53 @@ do_umount(const char* name, int useMtab)
/* this was a loop device, delete it */ /* this was a loop device, delete it */
del_loop(blockDevice); del_loop(blockDevice);
#endif #endif
#if defined BB_MTAB #if defined BB_FEATURE_REMOUNT
if ( status != 0 && doRemount == TRUE && errno == EBUSY ) {
status = mount(blockDevice, name, NULL,
MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
if (status == 0) {
fprintf(stderr, "umount: %s busy - remounted read-only\n",
blockDevice);
/* TODO: update mtab if BB_MTAB is defined */
} else {
fprintf(stderr, "umount: Cannot remount %s read-only\n",
blockDevice);
}
}
#endif
if ( status == 0 ) { if ( status == 0 ) {
#if defined BB_MTAB
if ( useMtab==TRUE ) if ( useMtab==TRUE )
erase_mtab(name); erase_mtab(name);
return 0;
}
else
#endif #endif
return(status); return( TRUE);
}
return(FALSE);
} }
static int static int
umount_all(int useMtab) umount_all(int useMtab)
{ {
int status; int status = TRUE;
struct mntent *m; char *mountpt;
FILE *mountTable; void *iter;
if ((mountTable = setmntent (mtab_file, "r"))) { for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) {
while ((m = getmntent (mountTable)) != 0) { status=do_umount (mountpt, useMtab);
char *blockDevice = m->mnt_fsname; if (status != 0) {
#if ! defined BB_MTAB /* Don't bother retrying the umount on busy devices */
if (strcmp (blockDevice, "/dev/root") == 0) { if (errno == EBUSY) {
struct fstab* fstabItem; perror(mountpt);
fstabItem = getfsfile ("/"); continue;
if (fstabItem != NULL) {
blockDevice = fstabItem->fs_spec;
}
} }
#endif status = do_umount (mountpt, useMtab);
/* Don't umount /proc when doing umount -a */ if (status != 0) {
if (strcmp (blockDevice, "proc") == 0) printf ("Couldn't umount %s on %s: %s\n",
continue; mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), strerror(errno));
status=do_umount (m->mnt_dir, useMtab);
if (status!=0) {
/* Don't bother retrying the umount on busy devices */
if (errno==EBUSY) {
perror(m->mnt_dir);
continue;
}
status=do_umount (blockDevice, useMtab);
if (status!=0) {
printf ("Couldn't umount %s on %s (type %s): %s\n",
blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
}
} }
} }
endmntent (mountTable);
} }
return( TRUE); return (status);
} }
extern int extern int
@ -143,14 +141,19 @@ umount_main(int argc, char** argv)
case 'n': case 'n':
useMtab = FALSE; useMtab = FALSE;
break; break;
#endif
#ifdef BB_FEATURE_REMOUNT
case 'r':
doRemount = TRUE;
break;
#endif #endif
default: default:
usage( umount_usage); usage( umount_usage);
} }
} }
mtab_read();
if(umountAll==TRUE) { if (umountAll==TRUE) {
exit(umount_all(useMtab)); exit(umount_all(useMtab));
} }
if ( do_umount(*argv,useMtab) == 0 ) if ( do_umount(*argv,useMtab) == 0 )
@ -161,3 +164,87 @@ umount_main(int argc, char** argv)
} }
} }
/* These functions are here because the getmntent functions do not appear
* to be re-entrant, which leads to all sorts of problems when we try to
* use them recursively - randolph
*/
void mtab_read(void)
{
struct _mtab_entry_t *entry = NULL;
struct mntent *e;
FILE *fp;
if (mtab_cache != NULL) return;
if ((fp = setmntent(mtab_file, "r")) == NULL) {
fprintf(stderr, "Cannot open %s\n", mtab_file);
return;
}
while ((e = getmntent(fp))) {
entry = malloc(sizeof(struct _mtab_entry_t));
entry->device = strdup(e->mnt_fsname);
entry->mountpt = strdup(e->mnt_dir);
entry->next = mtab_cache;
mtab_cache = entry;
}
endmntent(fp);
}
char *mtab_getinfo(const char *match, const char which)
{
struct _mtab_entry_t *cur = mtab_cache;
while (cur) {
if (strcmp(cur->mountpt, match) == 0 ||
strcmp(cur->device, match) == 0) {
if (which == MTAB_GETMOUNTPT) {
return cur->mountpt;
} else {
#if !defined BB_MTAB
if (strcmp(cur->device, "/dev/root") == 0) {
struct fstab* fstabItem;
fstabItem = getfsfile ("/");
if (fstabItem != NULL) return fstabItem->fs_spec;
}
#endif
return cur->device;
}
}
cur = cur->next;
}
return NULL;
}
char *mtab_first(void **iter)
{
struct _mtab_entry_t *mtab_iter;
if (!iter) return NULL;
mtab_iter = mtab_cache;
*iter = (void *)mtab_iter;
return mtab_next(iter);
}
char *mtab_next(void **iter)
{
char *mp;
if (iter == NULL || *iter == NULL) return NULL;
mp = ((struct _mtab_entry_t *)(*iter))->mountpt;
*iter = (void *)((struct _mtab_entry_t *)(*iter))->next;
return mp;
}
void mtab_free(void)
{
struct _mtab_entry_t *this, *next;
this = mtab_cache;
while (this) {
next = this->next;
if (this->device) free(this->device);
if (this->mountpt) free(this->mountpt);
free(this);
this = next;
}
}

2
uniq.c
View File

@ -193,4 +193,4 @@ uniq_main(int argc, char **argv)
exit(0); exit(0);
} }
/* $Id: uniq.c,v 1.5 2000/01/23 18:19:02 erik Exp $ */ /* $Id: uniq.c,v 1.6 2000/02/07 05:29:42 erik Exp $ */

View File

@ -31,7 +31,7 @@ extern int fdflush_main(int argc, char **argv)
{ {
int value; int value;
int fd; int fd;
if ( **(argv+1) == '-' ) { if ( argc <= 1 || **(argv++) == '-' ) {
usage( "fdflush device\n"); usage( "fdflush device\n");
} }

View File

@ -96,6 +96,7 @@
#include <termios.h> #include <termios.h>
#include <mntent.h> #include <mntent.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/param.h> /* for PATH_MAX */
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/minix_fs.h> #include <linux/minix_fs.h>
@ -143,7 +144,7 @@ static int termios_set = 0;
/* File-name data */ /* File-name data */
#define MAX_DEPTH 50 #define MAX_DEPTH 50
static int name_depth = 0; static int name_depth = 0;
static char name_list[MAX_DEPTH][NAME_MAX+1]; static char name_list[MAX_DEPTH][PATH_MAX + 1];
static char * inode_buffer = NULL; static char * inode_buffer = NULL;
#define Inode (((struct minix_inode *) inode_buffer)-1) #define Inode (((struct minix_inode *) inode_buffer)-1)

View File

@ -65,7 +65,6 @@ static void
do_em_all() do_em_all()
{ {
struct mntent *m; struct mntent *m;
char swapName[NAME_MAX];
FILE *f = setmntent ("/etc/fstab", "r"); FILE *f = setmntent ("/etc/fstab", "r");
if (f == NULL) { if (f == NULL) {
@ -73,8 +72,8 @@ do_em_all()
exit( FALSE); exit( FALSE);
} }
while ((m = getmntent (f)) != NULL) { while ((m = getmntent (f)) != NULL) {
if (!strstr (m->mnt_type, "swap")) { if (!strstr (m->mnt_type, MNTTYPE_SWAP)) {
swap_enable_disable( swapName); swap_enable_disable( m->mnt_fsname);
} }
} }
endmntent (f); endmntent (f);

View File

@ -37,11 +37,24 @@ static const char umount_usage[] =
#else #else
"\n" "\n"
#endif #endif
#ifdef BB_FEATURE_REMOUNT
"\t-r:\tTry to remount devices as read-only if mount is busy\n"
#endif
; ;
struct _mtab_entry_t {
char *device;
char *mountpt;
struct _mtab_entry_t *next;
};
static struct _mtab_entry_t *mtab_cache = NULL;
static int useMtab = TRUE; static int useMtab = TRUE;
static int umountAll = FALSE; static int umountAll = FALSE;
static int doRemount = FALSE;
extern const char mtab_file[]; /* Defined in utility.c */ extern const char mtab_file[]; /* Defined in utility.c */
#define MIN(x,y) (x > y ? x : y) #define MIN(x,y) (x > y ? x : y)
@ -50,21 +63,10 @@ static int
do_umount(const char* name, int useMtab) do_umount(const char* name, int useMtab)
{ {
int status; int status;
struct mntent *m; char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE);
FILE *mountTable;
const char *blockDevice = NULL;
if ((mountTable = setmntent (mtab_file, "r"))) { if (blockDevice && strcmp(blockDevice, name) == 0)
while ((m = getmntent (mountTable)) != 0) { name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT);
if (strncmp(m->mnt_dir, name,
MIN(strlen(m->mnt_dir),strlen(name))) == 0)
blockDevice = m->mnt_fsname;
else if (strcmp(m->mnt_fsname, name) == 0) {
blockDevice = name;
name = m->mnt_dir;
}
}
}
status = umount(name); status = umount(name);
@ -73,57 +75,53 @@ do_umount(const char* name, int useMtab)
/* this was a loop device, delete it */ /* this was a loop device, delete it */
del_loop(blockDevice); del_loop(blockDevice);
#endif #endif
#if defined BB_MTAB #if defined BB_FEATURE_REMOUNT
if ( status != 0 && doRemount == TRUE && errno == EBUSY ) {
status = mount(blockDevice, name, NULL,
MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
if (status == 0) {
fprintf(stderr, "umount: %s busy - remounted read-only\n",
blockDevice);
/* TODO: update mtab if BB_MTAB is defined */
} else {
fprintf(stderr, "umount: Cannot remount %s read-only\n",
blockDevice);
}
}
#endif
if ( status == 0 ) { if ( status == 0 ) {
#if defined BB_MTAB
if ( useMtab==TRUE ) if ( useMtab==TRUE )
erase_mtab(name); erase_mtab(name);
return 0;
}
else
#endif #endif
return(status); return( TRUE);
}
return(FALSE);
} }
static int static int
umount_all(int useMtab) umount_all(int useMtab)
{ {
int status; int status = TRUE;
struct mntent *m; char *mountpt;
FILE *mountTable; void *iter;
if ((mountTable = setmntent (mtab_file, "r"))) { for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) {
while ((m = getmntent (mountTable)) != 0) { status=do_umount (mountpt, useMtab);
char *blockDevice = m->mnt_fsname; if (status != 0) {
#if ! defined BB_MTAB /* Don't bother retrying the umount on busy devices */
if (strcmp (blockDevice, "/dev/root") == 0) { if (errno == EBUSY) {
struct fstab* fstabItem; perror(mountpt);
fstabItem = getfsfile ("/"); continue;
if (fstabItem != NULL) {
blockDevice = fstabItem->fs_spec;
}
} }
#endif status = do_umount (mountpt, useMtab);
/* Don't umount /proc when doing umount -a */ if (status != 0) {
if (strcmp (blockDevice, "proc") == 0) printf ("Couldn't umount %s on %s: %s\n",
continue; mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), strerror(errno));
status=do_umount (m->mnt_dir, useMtab);
if (status!=0) {
/* Don't bother retrying the umount on busy devices */
if (errno==EBUSY) {
perror(m->mnt_dir);
continue;
}
status=do_umount (blockDevice, useMtab);
if (status!=0) {
printf ("Couldn't umount %s on %s (type %s): %s\n",
blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
}
} }
} }
endmntent (mountTable);
} }
return( TRUE); return (status);
} }
extern int extern int
@ -143,14 +141,19 @@ umount_main(int argc, char** argv)
case 'n': case 'n':
useMtab = FALSE; useMtab = FALSE;
break; break;
#endif
#ifdef BB_FEATURE_REMOUNT
case 'r':
doRemount = TRUE;
break;
#endif #endif
default: default:
usage( umount_usage); usage( umount_usage);
} }
} }
mtab_read();
if(umountAll==TRUE) { if (umountAll==TRUE) {
exit(umount_all(useMtab)); exit(umount_all(useMtab));
} }
if ( do_umount(*argv,useMtab) == 0 ) if ( do_umount(*argv,useMtab) == 0 )
@ -161,3 +164,87 @@ umount_main(int argc, char** argv)
} }
} }
/* These functions are here because the getmntent functions do not appear
* to be re-entrant, which leads to all sorts of problems when we try to
* use them recursively - randolph
*/
void mtab_read(void)
{
struct _mtab_entry_t *entry = NULL;
struct mntent *e;
FILE *fp;
if (mtab_cache != NULL) return;
if ((fp = setmntent(mtab_file, "r")) == NULL) {
fprintf(stderr, "Cannot open %s\n", mtab_file);
return;
}
while ((e = getmntent(fp))) {
entry = malloc(sizeof(struct _mtab_entry_t));
entry->device = strdup(e->mnt_fsname);
entry->mountpt = strdup(e->mnt_dir);
entry->next = mtab_cache;
mtab_cache = entry;
}
endmntent(fp);
}
char *mtab_getinfo(const char *match, const char which)
{
struct _mtab_entry_t *cur = mtab_cache;
while (cur) {
if (strcmp(cur->mountpt, match) == 0 ||
strcmp(cur->device, match) == 0) {
if (which == MTAB_GETMOUNTPT) {
return cur->mountpt;
} else {
#if !defined BB_MTAB
if (strcmp(cur->device, "/dev/root") == 0) {
struct fstab* fstabItem;
fstabItem = getfsfile ("/");
if (fstabItem != NULL) return fstabItem->fs_spec;
}
#endif
return cur->device;
}
}
cur = cur->next;
}
return NULL;
}
char *mtab_first(void **iter)
{
struct _mtab_entry_t *mtab_iter;
if (!iter) return NULL;
mtab_iter = mtab_cache;
*iter = (void *)mtab_iter;
return mtab_next(iter);
}
char *mtab_next(void **iter)
{
char *mp;
if (iter == NULL || *iter == NULL) return NULL;
mp = ((struct _mtab_entry_t *)(*iter))->mountpt;
*iter = (void *)((struct _mtab_entry_t *)(*iter))->next;
return mp;
}
void mtab_free(void)
{
struct _mtab_entry_t *this, *next;
this = mtab_cache;
while (this) {
next = this->next;
if (this->device) free(this->device);
if (this->mountpt) free(this->mountpt);
free(this);
this = next;
}
}

251
utility.c
View File

@ -25,6 +25,17 @@
*/ */
#include "internal.h" #include "internal.h"
#if defined (BB_CHMOD_CHOWN_CHGRP) \
|| defined (BB_CP_MV) \
|| defined (BB_FIND) \
|| defined (BB_LS) \
|| defined (BB_INSMOD)
/* same conditions as recursiveAction */
#define bb_need_name_too_long
#endif
#define BB_DECLARE_EXTERN
#include "messages.c"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
@ -35,6 +46,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <ctype.h> #include <ctype.h>
#include <sys/param.h> /* for PATH_MAX */
#if defined BB_FEATURE_MOUNT_LOOP #if defined BB_FEATURE_MOUNT_LOOP
#include <fcntl.h> #include <fcntl.h>
@ -58,9 +70,10 @@ const char mtab_file[] = "/etc/mtab";
extern void usage(const char *usage) extern void usage(const char *usage)
{ {
fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n", BB_VER, BB_BT); fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n",
BB_VER, BB_BT);
fprintf(stderr, "Usage: %s\n", usage); fprintf(stderr, "Usage: %s\n", usage);
exit(FALSE); exit FALSE;
} }
@ -78,9 +91,8 @@ get_kernel_revision()
{ {
FILE *file; FILE *file;
int major=0, minor=0, patch=0; int major=0, minor=0, patch=0;
char* filename="/proc/sys/kernel/osrelease";
file = fopen(filename,"r"); file = fopen("/proc/sys/kernel/osrelease", "r");
if (file == NULL) { if (file == NULL) {
/* bummer, /proc must not be mounted... */ /* bummer, /proc must not be mounted... */
return( 0); return( 0);
@ -89,28 +101,34 @@ get_kernel_revision()
fclose(file); fclose(file);
return major*65536 + minor*256 + patch; return major*65536 + minor*256 + patch;
} }
#endif /* BB_INIT || BB_PS */
#endif
#if defined (BB_CP) || defined (BB_MV) #if defined (BB_CP_MV) || defined (BB_DU) || defined (BB_LN)
/* /*
* Return TRUE if a fileName is a directory. * Return TRUE if a fileName is a directory.
* Nonexistant files return FALSE. * Nonexistant files return FALSE.
*/ */
int isDirectory(const char *name) int isDirectory(const char *fileName, const int followLinks)
{ {
struct stat statBuf; struct stat statBuf;
int status;
if (stat(name, &statBuf) < 0) if (followLinks == TRUE)
return FALSE; status = stat(fileName, &statBuf);
else
status = lstat(fileName, &statBuf);
if (status < 0)
return FALSE;
if (S_ISDIR(statBuf.st_mode)) if (S_ISDIR(statBuf.st_mode))
return TRUE; return TRUE;
return(FALSE); return FALSE;
} }
#endif
#if defined (BB_CP_MV)
/* /*
* Copy one file to another, while possibly preserving its modes, times, * Copy one file to another, while possibly preserving its modes, times,
* and modes. Returns TRUE if successful, or FALSE on a failure with an * and modes. Returns TRUE if successful, or FALSE on a failure with an
@ -120,33 +138,33 @@ int isDirectory(const char *name)
*/ */
int int
copyFile( const char *srcName, const char *destName, copyFile( const char *srcName, const char *destName,
int setModes, int followLinks) int setModes, int followLinks)
{ {
int rfd; int rfd;
int wfd; int wfd;
int rcc; int rcc;
int result; int status;
char buf[BUF_SIZE]; char buf[BUF_SIZE];
struct stat srcStatBuf; struct stat srcStatBuf;
struct stat dstStatBuf; struct stat dstStatBuf;
struct utimbuf times; struct utimbuf times;
/* Grab the source file's stats */ if (followLinks == TRUE)
if (followLinks == FALSE) status = stat(srcName, &srcStatBuf);
result = stat(srcName, &srcStatBuf);
else else
result = lstat(srcName, &srcStatBuf); status = lstat(srcName, &srcStatBuf);
if (result < 0) {
if (status < 0) {
perror(srcName); perror(srcName);
return FALSE; return FALSE;
} }
/* Grab the dest file's stats */ if (followLinks == TRUE)
if (followLinks == FALSE) status = stat(destName, &dstStatBuf);
result = stat(destName, &dstStatBuf);
else else
result = lstat(destName, &dstStatBuf); status = lstat(destName, &dstStatBuf);
if (result < 0) {
if (status < 0) {
dstStatBuf.st_ino = -1; dstStatBuf.st_ino = -1;
dstStatBuf.st_dev = -1; dstStatBuf.st_dev = -1;
} }
@ -160,45 +178,49 @@ copyFile( const char *srcName, const char *destName,
if (S_ISDIR(srcStatBuf.st_mode)) { if (S_ISDIR(srcStatBuf.st_mode)) {
//fprintf(stderr, "copying directory %s to %s\n", srcName, destName); //fprintf(stderr, "copying directory %s to %s\n", srcName, destName);
/* Make sure the directory is writable */ /* Make sure the directory is writable */
result = mkdir(destName, 0777777 ^ umask(0)); status = mkdir(destName, 0777777 ^ umask(0));
if (result < 0 && errno != EEXIST) { if (status < 0 && errno != EEXIST) {
perror(destName); perror(destName);
return (FALSE); return FALSE;
} }
} else if (S_ISLNK(srcStatBuf.st_mode)) { } else if (S_ISLNK(srcStatBuf.st_mode)) {
char *link_val; char link_val[PATH_MAX + 1];
int link_size; int link_size;
//fprintf(stderr, "copying link %s to %s\n", srcName, destName); //fprintf(stderr, "copying link %s to %s\n", srcName, destName);
link_val = (char *) alloca(PATH_MAX + 2); /* Warning: This could possibly truncate silently, to PATH_MAX chars */
link_size = readlink(srcName, link_val, PATH_MAX + 1); link_size = readlink(srcName, &link_val[0], PATH_MAX);
if (link_size < 0) { if (link_size < 0) {
perror(srcName); perror(srcName);
return (FALSE); return FALSE;
} }
link_val[link_size] = '\0'; link_val[link_size] = '\0';
link_size = symlink(link_val, destName); status = symlink(link_val, destName);
if (link_size != 0) { if (status < 0) {
perror(destName); perror(destName);
return (FALSE); return FALSE;
} }
#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
if (setModes == TRUE) { if (setModes == TRUE) {
lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid); if (lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) {
perror(destName);
return FALSE;
}
} }
#endif #endif
return TRUE;
} else if (S_ISFIFO(srcStatBuf.st_mode)) { } else if (S_ISFIFO(srcStatBuf.st_mode)) {
//fprintf(stderr, "copying fifo %s to %s\n", srcName, destName); //fprintf(stderr, "copying fifo %s to %s\n", srcName, destName);
if (mkfifo(destName, 0644)) { if (mkfifo(destName, 0644) < 0) {
perror(destName); perror(destName);
return (FALSE); return FALSE;
} }
} else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode) } else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode)
|| S_ISSOCK (srcStatBuf.st_mode)) { || S_ISSOCK (srcStatBuf.st_mode)) {
//fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName); //fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName);
if (mknod(destName, srcStatBuf.st_mode, srcStatBuf.st_rdev)) { if (mknod(destName, srcStatBuf.st_mode, srcStatBuf.st_rdev) < 0) {
perror(destName); perror(destName);
return (FALSE); return FALSE;
} }
} else if (S_ISREG(srcStatBuf.st_mode)) { } else if (S_ISREG(srcStatBuf.st_mode)) {
//fprintf(stderr, "copying regular file %s to %s\n", srcName, destName); //fprintf(stderr, "copying regular file %s to %s\n", srcName, destName);
@ -208,7 +230,7 @@ copyFile( const char *srcName, const char *destName,
return FALSE; return FALSE;
} }
wfd = creat(destName, srcStatBuf.st_mode); wfd = open(destName, O_WRONLY | O_CREAT | O_TRUNC, srcStatBuf.st_mode);
if (wfd < 0) { if (wfd < 0) {
perror(destName); perror(destName);
close(rfd); close(rfd);
@ -231,24 +253,32 @@ copyFile( const char *srcName, const char *destName,
if (setModes == TRUE) { if (setModes == TRUE) {
/* This is fine, since symlinks never get here */ /* This is fine, since symlinks never get here */
chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid); if (chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) {
chmod(destName, srcStatBuf.st_mode); perror(destName);
exit FALSE;
}
if (chmod(destName, srcStatBuf.st_mode) < 0) {
perror(destName);
exit FALSE;
}
times.actime = srcStatBuf.st_atime; times.actime = srcStatBuf.st_atime;
times.modtime = srcStatBuf.st_mtime; times.modtime = srcStatBuf.st_mtime;
utime(destName, &times); if (utime(destName, &times) < 0) {
perror(destName);
exit FALSE;
}
} }
return TRUE; return TRUE;
error_exit:
error_exit:
perror(destName); perror(destName);
close(rfd); close(rfd);
close(wfd); close(wfd);
return FALSE; return FALSE;
} }
#endif #endif /* BB_CP_MV */
@ -296,7 +326,7 @@ const char *modeString(int mode)
} }
return buf; return buf;
} }
#endif #endif /* BB_TAR || BB_LS */
#if defined BB_TAR #if defined BB_TAR
@ -324,9 +354,9 @@ const char *timeString(time_t timeVal)
return buf; return buf;
} }
#endif #endif /* BB_TAR */
#if defined BB_TAR || defined BB_CP || defined BB_MV #if defined BB_TAR || defined BB_CP_MV
/* /*
* Write all of the supplied buffer out to a file. * Write all of the supplied buffer out to a file.
* This does multiple writes as necessary. * This does multiple writes as necessary.
@ -352,7 +382,7 @@ int fullWrite(int fd, const char *buf, int len)
return total; return total;
} }
#endif #endif /* BB_TAR || BB_CP_MV */
#if defined BB_TAR || defined BB_TAIL #if defined BB_TAR || defined BB_TAIL
@ -385,10 +415,14 @@ int fullRead(int fd, char *buf, int len)
return total; return total;
} }
#endif #endif /* BB_TAR || BB_TAIL */
#if defined (BB_CHMOD_CHOWN_CHGRP) || defined (BB_CP) || defined (BB_FIND) || defined (BB_LS) || defined (BB_INSMOD) #if defined (BB_CHMOD_CHOWN_CHGRP) \
|| defined (BB_CP_MV) \
|| defined (BB_FIND) \
|| defined (BB_LS) \
|| defined (BB_INSMOD)
/* /*
* Walk down all the directories under the specified * Walk down all the directories under the specified
* location, and do something (something specified * location, and do something (something specified
@ -399,13 +433,15 @@ int fullRead(int fd, char *buf, int len)
* and so isn't sufficiently portable to take over since glibc2.1 * and so isn't sufficiently portable to take over since glibc2.1
* is so stinking huge. * is so stinking huge.
*/ */
int int recursiveAction(const char *fileName,
recursiveAction(const char *fileName, int recurse, int followLinks, int depthFirst, int recurse, int followLinks, int depthFirst,
int (*fileAction) (const char *fileName, struct stat* statbuf), int (*fileAction) (const char *fileName,
int (*dirAction) (const char *fileName, struct stat* statbuf)) struct stat* statbuf),
int (*dirAction) (const char *fileName,
struct stat* statbuf))
{ {
int status; int status;
struct stat statbuf, statbuf1; struct stat statbuf;
struct dirent *next; struct dirent *next;
if (followLinks == TRUE) if (followLinks == TRUE)
@ -414,16 +450,20 @@ recursiveAction(const char *fileName, int recurse, int followLinks, int depthFir
status = lstat(fileName, &statbuf); status = lstat(fileName, &statbuf);
if (status < 0) { if (status < 0) {
//fprintf(stderr, "status=%d followLinks=%d TRUE=%d\n", status, followLinks, TRUE); #ifdef BB_DEBUG_PRINT_SCAFFOLD
fprintf(stderr,
"status=%d followLinks=%d TRUE=%d\n",
status, followLinks, TRUE);
#endif
perror(fileName); perror(fileName);
return (FALSE); return FALSE;
} }
if ( (followLinks == FALSE) && (S_ISLNK(statbuf.st_mode)) ) { if ((followLinks == FALSE) && (S_ISLNK(statbuf.st_mode)) ) {
if (fileAction == NULL) if (fileAction == NULL)
return (TRUE); return TRUE;
else else
return (fileAction(fileName, &statbuf)); return fileAction(fileName, &statbuf);
} }
if (recurse == FALSE) { if (recurse == FALSE) {
@ -431,67 +471,65 @@ recursiveAction(const char *fileName, int recurse, int followLinks, int depthFir
if (dirAction != NULL) if (dirAction != NULL)
return (dirAction(fileName, &statbuf)); return (dirAction(fileName, &statbuf));
else else
return (TRUE); return TRUE;
} }
} }
status = lstat(fileName, &statbuf1); if (S_ISDIR(statbuf.st_mode)) {
if (status < 0) {
perror(fileName);
return (FALSE);
}
if (S_ISDIR(statbuf.st_mode) && S_ISDIR(statbuf1.st_mode)) {
DIR *dir; DIR *dir;
dir = opendir(fileName); dir = opendir(fileName);
if (!dir) { if (!dir) {
perror(fileName); perror(fileName);
return (FALSE); return FALSE;
} }
if (dirAction != NULL && depthFirst == FALSE) { if (dirAction != NULL && depthFirst == FALSE) {
status = dirAction(fileName, &statbuf); status = dirAction(fileName, &statbuf);
if (status == FALSE) { if (status == FALSE) {
perror(fileName); perror(fileName);
return (FALSE); return FALSE;
} }
} }
while ((next = readdir(dir)) != NULL) { while ((next = readdir(dir)) != NULL) {
char nextFile[NAME_MAX]; char nextFile[PATH_MAX + 1];
if ((strcmp(next->d_name, "..") == 0) if ((strcmp(next->d_name, "..") == 0)
|| (strcmp(next->d_name, ".") == 0)) { || (strcmp(next->d_name, ".") == 0)) {
continue; continue;
} }
if (strlen(fileName) + strlen(next->d_name) + 1 > PATH_MAX) {
fprintf(stderr, name_too_long, "ftw");
return FALSE;
}
sprintf(nextFile, "%s/%s", fileName, next->d_name); sprintf(nextFile, "%s/%s", fileName, next->d_name);
status = status =
recursiveAction(nextFile, TRUE, followLinks, depthFirst, recursiveAction(nextFile, TRUE, followLinks, depthFirst,
fileAction, dirAction); fileAction, dirAction);
if (status < 0) { if (status < 0) {
closedir(dir); closedir(dir);
return (FALSE); return FALSE;
} }
} }
status = closedir(dir); status = closedir(dir);
if (status < 0) { if (status < 0) {
perror(fileName); perror(fileName);
return (FALSE); return FALSE;
} }
if (dirAction != NULL && depthFirst == TRUE) { if (dirAction != NULL && depthFirst == TRUE) {
status = dirAction(fileName, &statbuf); status = dirAction(fileName, &statbuf);
if (status == FALSE) { if (status == FALSE) {
perror(fileName); perror(fileName);
return (FALSE); return FALSE;
} }
} }
} else { } else {
if (fileAction == NULL) if (fileAction == NULL)
return (TRUE); return TRUE;
else else
return (fileAction(fileName, &statbuf)); return fileAction(fileName, &statbuf);
} }
return (TRUE); return TRUE;
} }
#endif #endif /* BB_CHMOD_CHOWN_CHGRP || BB_CP_MV || BB_FIND || BB_LS || BB_INSMOD */
@ -506,25 +544,25 @@ extern int createPath (const char *name, int mode)
{ {
char *cp; char *cp;
char *cpOld; char *cpOld;
char buf[NAME_MAX]; char buf[PATH_MAX + 1];
int retVal=0; int retVal=0;
strcpy( buf, name); strcpy( buf, name);
cp = strchr (buf, '/'); cp = strchr(buf, '/');
while (cp) { while (cp) {
cpOld = cp; cpOld = cp;
cp = strchr (cp + 1, '/'); cp = strchr(cp + 1, '/');
*cpOld = '\0'; *cpOld = '\0';
retVal = mkdir (buf, cp ? 0777 : mode); retVal = mkdir(buf, cp ? 0777 : mode);
if (retVal != 0 && errno != EEXIST) { if (retVal != 0 && errno != EEXIST) {
perror( buf); perror(buf);
return( FALSE); return FALSE;
} }
*cpOld = '/'; *cpOld = '/';
} }
return( TRUE); return TRUE;
} }
#endif #endif /* BB_TAR || BB_MKDIR */
@ -624,7 +662,7 @@ parse_mode( const char* s, mode_t* theMode)
} }
#endif #endif /* BB_CHMOD_CHOWN_CHGRP || BB_MKDIR */
@ -712,7 +750,7 @@ my_getgrgid(char* group, gid_t gid)
} }
#endif #endif /* BB_CHMOD_CHOWN_CHGRP || BB_PS */
@ -804,7 +842,7 @@ int get_console_fd(char* tty_name)
} }
#endif #endif /* BB_CHVT || BB_DEALLOCVT */
#if !defined BB_REGEXP && (defined BB_GREP || defined BB_SED) #if !defined BB_REGEXP && (defined BB_GREP || defined BB_SED)
@ -883,8 +921,7 @@ extern int replace_match(char *haystack, char *needle, char *newNeedle, int igno
return FALSE; return FALSE;
} }
#endif /* ! BB_REGEXP && (BB_GREP || BB_SED) */
#endif
#if defined BB_FIND #if defined BB_FIND
@ -986,7 +1023,7 @@ check_wildcard_match(const char* text, const char* pattern)
return TRUE; return TRUE;
} }
#endif #endif /* BB_FIND */
@ -1030,7 +1067,7 @@ extern struct mntent *findMountPoint(const char *name, const char *table)
endmntent(mountTable); endmntent(mountTable);
return mountEntry; return mountEntry;
} }
#endif #endif /* BB_DF || BB_MTAB */
@ -1052,7 +1089,8 @@ extern long getNum (const char *cp)
value = value * 10 + *cp++ - '0'; value = value * 10 + *cp++ - '0';
switch (*cp++) { switch (*cp++) {
case 'm': case 'M':
case 'm': /* `tail' uses it traditionally */
value *= 1048576; value *= 1048576;
break; break;
@ -1080,7 +1118,7 @@ extern long getNum (const char *cp)
return value; return value;
} }
#endif #endif /* BB_DD || BB_TAIL */
#if defined BB_INIT || defined BB_HALT || defined BB_REBOOT #if defined BB_INIT || defined BB_HALT || defined BB_REBOOT
@ -1120,9 +1158,12 @@ findInitPid()
} }
return 0; return 0;
} }
#endif #endif /* BB_INIT || BB_HALT || BB_REBOOT */
#if defined BB_GUNZIP || defined BB_GZIP || defined BB_PRINTF || defined BB_TAIL #if defined BB_GUNZIP \
|| defined BB_GZIP \
|| defined BB_PRINTF \
|| defined BB_TAIL
extern void *xmalloc (size_t size) extern void *xmalloc (size_t size)
{ {
void *cp = malloc (size); void *cp = malloc (size);
@ -1138,7 +1179,7 @@ extern void error(char *msg)
fprintf(stderr, "\n%s\n", msg); fprintf(stderr, "\n%s\n", msg);
exit(1); exit(1);
} }
#endif #endif /* BB_GUNZIP || BB_GZIP || BB_PRINTF || BB_TAIL */
#if (__GLIBC__ < 2) && (defined BB_SYSLOGD || defined BB_INIT) #if (__GLIBC__ < 2) && (defined BB_SYSLOGD || defined BB_INIT)
extern int vdprintf(int d, const char *format, va_list ap) extern int vdprintf(int d, const char *format, va_list ap)
@ -1149,7 +1190,7 @@ extern int vdprintf(int d, const char *format, va_list ap)
len = vsprintf(buf, format, ap); len = vsprintf(buf, format, ap);
return write(d, buf, len); return write(d, buf, len);
} }
#endif #endif /* BB_SYSLOGD */
#if defined BB_FEATURE_MOUNT_LOOP #if defined BB_FEATURE_MOUNT_LOOP
extern int del_loop(const char *device) extern int del_loop(const char *device)