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

103
Makefile
View File

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

41
TODO
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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,
// turning this stuff off makes things a bit smaller (and less
@ -132,7 +127,7 @@
#define BB_FEATURE_USE_INITTAB
//
//Enable init being called as /linuxrc
#define BB_FEATURE_LINUXRC
//#define BB_FEATURE_LINUXRC
//
//
//Simple tail implementation (2k vs 6k for the full one). Still
@ -142,11 +137,20 @@
// Enable support for loop devices in mount
#define BB_FEATURE_MOUNT_LOOP
//
// Enable support for a real /etc/mtab file instead of /proc/mounts
#ifdef BB_MOUNT
//#define BB_MTAB
#endif
//
//
// Enable support for remounting filesystems
#define BB_FEATURE_REMOUNT
//
// Enable support for creation of tar files.
//#define BB_FEATURE_TAR_CREATE
//
// Allow init to permenently chroot, and umount the old root fs
// just like an initrd does. Requires a kernel patch by Werner Almesberger.
// just like an initrd does. Requires a kernel patch by Werner Almesberger.
// ftp://icaftp.epfl.ch/pub/people/almesber/misc/umount-root-*.tar.gz
#ifdef BB_MOUNT
#define BB_FEATURE_INIT_CHROOT

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

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)
{
char scratch[PATH_MAX];
char scratch[PATH_MAX + 1];
short len = strlen(name);
#ifdef BB_FEATURE_LS_FILETYPES
char append = append_char(info->st_mode);

View File

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

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;
exit_status = 0;
if ( **(argv+1) == '-' ) {
if ( argc <= 1 || **(argv+1) == '-' ) {
usage (printf_usage);
}

View File

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

View File

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

View File

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

View File

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

View File

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

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

37
dd.c
View File

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

34
du.c
View File

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

View File

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

2
find.c
View File

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

View File

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

View File

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

View File

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

2
head.c
View File

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

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
*
* Copyright (C) 1999 by Randolph Chung <tausq@debian.org>

17
init.c
View File

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

View File

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

View File

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

View File

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

View File

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

79
ln.c
View File

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

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)
{
char scratch[PATH_MAX];
char scratch[PATH_MAX + 1];
short len = strlen(name);
#ifdef BB_FEATURE_LS_FILETYPES
char append = append_char(info->st_mode);

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

View File

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

24
mtab.c
View File

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

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
*
* Copyright (C) 1999 by Randolph Chung <tausq@debian.org>

View File

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

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
*
* Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
@ -175,7 +175,8 @@ extern int ping_main(int argc, char **argv)
static const char* ping_usage = "ping [OPTION]... host\n\n"
"Send ICMP ECHO_REQUEST packets to network hosts.\n\n"
"Options:\n"
"\t-q\t\tQuiet mode, only displays output at start and when finished.\n"
"\t-q\t\tQuiet mode, only displays output at start"
"\t\t\tand when finished.\n"
"\t-c COUNT\tSend only COUNT pings.\n";
static char *hostname = NULL;

View File

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

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
*
* Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
@ -175,7 +175,8 @@ extern int ping_main(int argc, char **argv)
static const char* ping_usage = "ping [OPTION]... host\n\n"
"Send ICMP ECHO_REQUEST packets to network hosts.\n\n"
"Options:\n"
"\t-q\t\tQuiet mode, only displays output at start and when finished.\n"
"\t-q\t\tQuiet mode, only displays output at start"
"\t\t\tand when finished.\n"
"\t-c COUNT\tSend only COUNT pings.\n";
static char *hostname = NULL;

View File

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

3
pwd.c
View File

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

2
sort.c
View File

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

View File

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

View File

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

View File

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

2
tail.c
View File

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

3
tar.c
View File

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

2
tee.c
View File

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

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

2
uniq.c
View File

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

View File

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

View File

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

View File

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

View File

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

255
utility.c
View File

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