0.42
+
+ * Fairly massive restructuring of umount.c to deal with remounting
+ busy devices read-only. Adds a -r option to control that; it is
+ optionally compiled in with BB_FEATURE_REMOUNT
+ * Added a bunch of functions to mtab.c to interact with the
+ {get,set,end}mntent interface; as it turns out, those functions do
+ not appear to be re-entrant, and that causes a lot of problems with
+ the way umount was originally written.
+ * Makes init send TERM and KILL (instead of HUP and KILL) on reboot
+ to be more consistent with sysvinit
+ * Changes to init.c to use the new -r option to umount. Also increased
+ the sleep time between the time the TERM and KILL signals are sent
+
+ - Randolph Chung
+
+
+ * cp.c, mv.c: removed, replaced by cp_mv.c which has been
+ extensively rewritten from the original cp.c.
+ * Also added a warning message to the `mv' usage string saying that
+ this is not GNU mv, and it will break hard links. cp also breaks
+ hard links.
+ * ln.c: implemented `-n' switch, no-deref symlinks.
+ * include<sys/param.h>: and use PATH_MAX everywhere.
+ * busybox: File name buffer overrun guards to prevent future crashes.
+ - Always check exit status.
+ - Purge all use of `creat()', replace with `open()'.
+ * utility.c
+ - recursiveAction was overriding the value of
+ followLinks thus ignoring it.
+ - isDirectory now takes a followLinks boolean, updated all callers
+ - copyFile had the followLinks logic reversed.
+ * messages.c: New file. Put common error message strings all in
+ one place in an attempt to shrink the binary a little.
+
+ -Karl M. Hegbloom
+
+
* Made tar creation support in busybox tar optional.
* You no longer _have_ to put a "-" in front of tar options.
* Tar could inadvertently change permissions and ownership on
for the kernel init chroot patch by Werner Almesberger, which
allows init to chroot to a new device, and umount the old one.
* Fixed bug that wouldn't let one chown a symlink -- it would
- always dereference before. -beppu
+ always dereference before. -beppu
* Fixed a bug where init could have reference already freed memory.
Found and fixed by Taketoshi Sano <kgh12351@nifty.ne.jp>
* Several contributions from Friedrich Vedder <fwv@myrtle.lahn.de>
- * added (and documented) "-n" option for head -
+ * Added (and documented) "-n" option for head -
* Cleanup for a number of usage messages -- also
contributed Friedrich Vedder <fwv@myrtle.lahn.de>
* Cosmetic fix to busybox.c (Don't print a comma at the
Randolph Chung <tausq@debian.org>.
* cp could, when copying symlinks, change permissions of the
files pointed to by the symlinks.
+ * Several fixes from Pavel Roskin <pavel_roskin@geocities.com>:
+ - `chown' with 1 argument displayed the error incorrectly
+ - `fdflush', `length' and `printf' crashed when run without arguments
+ - `fdflush' tried to flush itself using *argv
+ - added "skip" and "seek" to dd.
-Erik Andersen
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
+PROG := busybox
+VERSION := 0.42
+BUILDTIME := $(shell TZ=GMT date "+%Y%m%d-%H%M")
-PROG=busybox
-VERSION=0.42
-BUILDTIME=$(shell date "+%Y%m%d-%H%M")
+# Set the following to `true' to make a debuggable build.
+# Leave this set to `false' for production use.
+# eg: `make DODEBUG=true'
+DODEBUG = false
-# Comment out the following to make a debuggable build
-# Leave this off for production use.
-DODEBUG=false
# If you want a static binary, turn this on. I can't think
# of many situations where anybody would ever want it static,
# but...
-DOSTATIC=false
-
-#This will choke on a non-debian system
-ARCH=`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'`
-
-GCCMAJVERSION=$(shell $(CC) --version | sed -n "s/^\([^\.]*\).*/\1/p" )
-GCCMINVERSION=$(shell $(CC) --version | sed -n "s/^[^\.]*\.\([^\.]*\)[\.].*/\1/p" )
-
-GCCSUPPORTSOPTSIZE=$(shell \
-if ( test $(GCCMAJVERSION) -eq 2 ) ; then \
- if ( test $(GCCMINVERSION) -ge 66 ) ; then \
- echo "true"; \
- else \
- echo "false"; \
- fi; \
-else \
- if ( test $(GCCMAJVERSION) -gt 2 ) ; then \
- echo "true"; \
- else \
- echo "false"; \
- fi; \
+DOSTATIC = false
+
+# This will choke on a non-debian system
+ARCH =`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'`
+
+CC = gcc
+
+GCCMAJVERSION = $(shell $(CC) --version | sed -n "s/^[^0-9]*\([0-9]\)\.\([0-9].*\)[\.].*/\1/p")
+GCCMINVERSION = $(shell $(CC) --version | sed -n "s/^[^0-9]*\([0-9]\)\.\([0-9].*\)[\.].*/\2/p")
+
+
+GCCSUPPORTSOPTSIZE = $(shell \
+if ( test $(GCCMAJVERSION) -eq 2 ) ; then \
+ if ( test $(GCCMINVERSION) -ge 66 ) ; then \
+ echo "true"; \
+ else \
+ echo "false"; \
+ fi; \
+else \
+ if ( test $(GCCMAJVERSION) -gt 2 ) ; then \
+ echo "true"; \
+ else \
+ echo "false"; \
+ fi; \
fi; )
ifeq ($(GCCSUPPORTSOPTSIZE), true)
- OPTIMIZATION=-Os
+ OPTIMIZATION = -Os
else
- OPTIMIZATION=-O2
+ OPTIMIZATION = -O2
endif
# -D_GNU_SOURCE is needed because environ is used in init.c
ifeq ($(DODEBUG),true)
- CFLAGS+=-Wall -g -D_GNU_SOURCE -DDEBUG_INIT
- STRIP=
- LDFLAGS=
+ CFLAGS += -Wall -g -D_GNU_SOURCE -DDEBUG_INIT
+ STRIP =
+ LDFLAGS =
else
- CFLAGS+=-Wall $(OPTIMIZATION) -fomit-frame-pointer -fno-builtin -D_GNU_SOURCE
- LDFLAGS= -s
- STRIP= strip --remove-section=.note --remove-section=.comment $(PROG)
+ CFLAGS += -Wall $(OPTIMIZATION) -fomit-frame-pointer -fno-builtin -D_GNU_SOURCE
+ LDFLAGS = -s
+ STRIP = strip --remove-section=.note --remove-section=.comment $(PROG)
#Only staticly link when _not_ debugging
ifeq ($(DOSTATIC),true)
- LDFLAGS+= --static
+ LDFLAGS += --static
endif
-
endif
ifndef $(PREFIX)
- PREFIX=`pwd`/_install
+ PREFIX = `pwd`/_install
endif
-LIBRARIES=
-OBJECTS=$(shell ./busybox.sh)
-CFLAGS+= -DBB_VER='"$(VERSION)"'
-CFLAGS+= -DBB_BT='"$(BUILDTIME)"'
+LIBRARIES =
+OBJECTS = $(shell ./busybox.sh) messages.o utility.o
+CFLAGS += -DBB_VER='"$(VERSION)"'
+CFLAGS += -DBB_BT='"$(BUILDTIME)"'
ifdef BB_INIT_SCRIPT
CFLAGS += -DINIT_SCRIPT=${BB_INIT_SCRIPT}
endif
$(CC) $(LDFLAGS) -o $(PROG) $(OBJECTS) $(LIBRARIES)
$(STRIP)
-busybox.links:
+busybox.links: busybox.def.h
- ./busybox.mkll | sort >$@
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)
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)/;
* 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?
+
#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},
#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
#!/bin/sh
-#Make busybox links list file
+# Make busybox links list file.
DF="busybox.def.h"
MF="busybox.c"
*/
#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"
#include <signal.h>
#include <sys/stat.h>
#include <errno.h>
+#include <sys/param.h> /* for PATH_MAX */
/* #include "tailor.h" */
#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
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);
/* 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);
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';
#include <utime.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
+#include <sys/param.h> /* for PATH_MAX */
#ifdef BB_FEATURE_TAR_CREATE
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
#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},
#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
//
//
//
-// Don't turn BB_UTILITY off. It contains support code
-// that compiles to 0 if everything else if turned off.
-#define BB_UTILITY
-//
-//
//
// This is where feature definitions go. Generally speaking,
// turning this stuff off makes things a bit smaller (and less
#define BB_FEATURE_USE_INITTAB
//
//Enable init being called as /linuxrc
-#define BB_FEATURE_LINUXRC
+//#define BB_FEATURE_LINUXRC
//
//
//Simple tail implementation (2k vs 6k for the full one). Still
// Enable support for loop devices in mount
#define BB_FEATURE_MOUNT_LOOP
//
+// Enable support for a real /etc/mtab file instead of /proc/mounts
+#ifdef BB_MOUNT
+//#define BB_MTAB
+#endif
+//
+//
+// Enable support for remounting filesystems
+#define BB_FEATURE_REMOUNT
+//
// Enable support for creation of tar files.
//#define BB_FEATURE_TAR_CREATE
//
// Allow init to permenently chroot, and umount the old root fs
-// just like an initrd does. Requires a kernel patch by Werner Almesberger.
+// just like an initrd does. Requires a kernel patch by Werner Almesberger.
// ftp://icaftp.epfl.ch/pub/people/almesber/misc/umount-root-*.tar.gz
#ifdef BB_MOUNT
#define BB_FEATURE_INIT_CHROOT
#!/bin/sh
-#Make busybox links list file
+# Make busybox links list file.
DF="busybox.def.h"
MF="busybox.c"
*
*/
+#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;
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)
{
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;
recursiveFlag = TRUE;
break;
default:
- fprintf(stderr, "Unknown option: %c\n", **argv);
+ fprintf(stderr, invalid_option, invocationName, **argv);
usage( appUsage);
}
argc--;
/* 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
/* 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);
}
}
/* 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) {
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);
}
+++ /dev/null
-/*
- * 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);
-}
*/
#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>
&(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);
}
}
- fprintf(stderr, "date: invalid date `%s'\n", t_string);
+ fprintf(stderr, invalid_date, "date", t_string);
exit( FALSE);
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. */
}
} 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);
}
/* 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);
}
exit( TRUE);
}
-
#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";
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;
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;
}
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);
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);
*/
#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"
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);
/* 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));
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);
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 $ */
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 $ */
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]));
*/
#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);
case 'f':
removeoldFlag = TRUE;
break;
+ case 'n':
+ followLinks = FALSE;
+ break;
default:
usage (ln_usage);
}
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;
}
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);
*/
#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"
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;
argv++;
}
-
if (argc < 1) {
usage( mkdir_usage);
}
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, "/");
else {
if (mkdir (buf, mode) != 0 && parentFlag == FALSE) {
perror(buf);
- exit( FALSE);
+ exit FALSE;
}
}
argc--;
argv++;
}
- exit( TRUE);
+ exit TRUE;
}
+++ /dev/null
-/*
- * 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);
-}
int args_used;
exit_status = 0;
- if ( **(argv+1) == '-' ) {
+ if ( argc <= 1 || **(argv+1) == '-' ) {
usage (printf_usage);
}
#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");
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 $ */
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>.
*/
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 $ */
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 $ */
+++ /dev/null
-/*
- * 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);
-}
--- /dev/null
+/*
+ * 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:
*/
#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>
&(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);
}
}
- fprintf(stderr, "date: invalid date `%s'\n", t_string);
+ fprintf(stderr, invalid_date, "date", t_string);
exit( FALSE);
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. */
}
} 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);
}
/* 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);
}
exit( TRUE);
}
-
#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";
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;
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;
}
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);
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);
*/
#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"
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);
/* 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));
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);
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 $ */
{
int value;
int fd;
- if ( **(argv+1) == '-' ) {
+ if ( argc <= 1 || **(argv++) == '-' ) {
usage( "fdflush device\n");
}
if (strcmp(*argv, "name")==0) {
if (argc-- > 1) {
pattern = *(++argv);
- stopit=TRUE;
+ stopit = TRUE;
} else {
usage (find_usage);
}
if (strcmp(*argv, "name")==0) {
if (argc-- > 1) {
pattern = *(++argv);
- stopit=TRUE;
+ stopit = TRUE;
} else {
usage (find_usage);
}
#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>
/* 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)
*/
#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"
#include <signal.h>
#include <sys/stat.h>
#include <errno.h>
+#include <sys/param.h> /* for PATH_MAX */
/* #include "tailor.h" */
#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
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);
/* 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);
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';
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 $ */
/*
- * $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>
#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>
/* 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;
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 */
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)
#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>
/* 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;
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 */
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)
#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"
{
int len;
char *tmp;
- char m_name[PATH_MAX] ="\0";
+ char m_name[PATH_MAX + 1] ="\0";
FILE *fp;
if (argc<=1) {
+
/*
* Busybox main internal header file
*
* Permission has been granted to redistribute this code under the GPL.
*
*/
-#ifndef _INTERNAL_H_
-#define _INTERNAL_H_
+#ifndef _BB_INTERNAL_H_
+#define _BB_INTERNAL_H_ 1
#include "busybox.def.h"
#define FALSE ((int) 1)
#define TRUE ((int) 0)
-#define PATH_LEN 1024
+/* for mtab.c */
+#define MTAB_GETMOUNTPT '1'
+#define MTAB_GETDEVICE '2'
+
#define BUF_SIZE 8192
#define EXPAND_ALLOC 1024
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);
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);
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);
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();
#endif
-#endif /* _INTERNAL_H_ */
-
+#endif /* _BB_INTERNAL_H_ */
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]));
*/
#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);
case 'f':
removeoldFlag = TRUE;
break;
+ case 'n':
+ followLinks = FALSE;
+ break;
default:
usage (ln_usage);
}
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;
}
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);
--- /dev/null
+/*
+ * 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 */
*/
#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"
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;
argv++;
}
-
if (argc < 1) {
usage( mkdir_usage);
}
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, "/");
else {
if (mkdir (buf, mode) != 0 && parentFlag == FALSE) {
perror(buf);
- exit( FALSE);
+ exit FALSE;
}
}
argc--;
argv++;
}
- exit( TRUE);
+ exit TRUE;
}
#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"
{
int len;
char *tmp;
- char m_name[PATH_MAX] ="\0";
+ char m_name[PATH_MAX + 1] ="\0";
FILE *fp;
if (argc<=1) {
#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;
}
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++;
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+");
}
}
-
+++ /dev/null
-/*
- * 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);
-}
/*
- * $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>
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 $ */
/*
- * $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>
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;
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 $ */
/*
- * $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>
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;
int args_used;
exit_status = 0;
- if ( **(argv+1) == '-' ) {
+ if ( argc <= 1 || **(argv+1) == '-' ) {
usage (printf_usage);
}
#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");
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 $ */
do_em_all()
{
struct mntent *m;
- char swapName[NAME_MAX];
FILE *f = setmntent ("/etc/fstab", "r");
if (f == NULL) {
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);
/* 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;
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);
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));
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 ")");
/* 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;
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);
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));
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 ")");
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>.
*/
#include <utime.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
+#include <sys/param.h> /* for PATH_MAX */
#ifdef BB_FEATURE_TAR_CREATE
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
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 $ */
--- /dev/null
+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
--- /dev/null
+# 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};
--- /dev/null
+
+# 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};
--- /dev/null
+
+# 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};
#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)
do_umount(const char* name, int useMtab)
{
int status;
- struct mntent *m;
- FILE *mountTable;
- const char *blockDevice = NULL;
-
- if ((mountTable = setmntent (mtab_file, "r"))) {
- while ((m = getmntent (mountTable)) != 0) {
- if (strncmp(m->mnt_dir, name,
- MIN(strlen(m->mnt_dir),strlen(name))) == 0)
- blockDevice = m->mnt_fsname;
- else if (strcmp(m->mnt_fsname, name) == 0) {
- blockDevice = name;
- name = m->mnt_dir;
- }
- }
- }
+ char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE);
+
+ if (blockDevice && strcmp(blockDevice, name) == 0)
+ name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT);
status = umount(name);
/* this was a loop device, delete it */
del_loop(blockDevice);
#endif
-#if defined BB_MTAB
+#if defined BB_FEATURE_REMOUNT
+ if ( status != 0 && doRemount == TRUE && errno == EBUSY ) {
+ status = mount(blockDevice, name, NULL,
+ MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
+ if (status == 0) {
+ fprintf(stderr, "umount: %s busy - remounted read-only\n",
+ blockDevice);
+ /* TODO: update mtab if BB_MTAB is defined */
+ } else {
+ fprintf(stderr, "umount: Cannot remount %s read-only\n",
+ blockDevice);
+ }
+ }
+#endif
if ( status == 0 ) {
+#if defined BB_MTAB
if ( useMtab==TRUE )
erase_mtab(name);
- return 0;
- }
- else
#endif
- return(status);
+ return( TRUE);
+ }
+ return(FALSE);
}
static int
umount_all(int useMtab)
{
- int status;
- struct mntent *m;
- FILE *mountTable;
-
- if ((mountTable = setmntent (mtab_file, "r"))) {
- while ((m = getmntent (mountTable)) != 0) {
- char *blockDevice = m->mnt_fsname;
-#if ! defined BB_MTAB
- if (strcmp (blockDevice, "/dev/root") == 0) {
- struct fstab* fstabItem;
- fstabItem = getfsfile ("/");
- if (fstabItem != NULL) {
- blockDevice = fstabItem->fs_spec;
- }
+ int status = TRUE;
+ char *mountpt;
+ void *iter;
+
+ for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) {
+ status=do_umount (mountpt, useMtab);
+ if (status != 0) {
+ /* Don't bother retrying the umount on busy devices */
+ if (errno == EBUSY) {
+ perror(mountpt);
+ continue;
}
-#endif
- /* Don't umount /proc when doing umount -a */
- if (strcmp (blockDevice, "proc") == 0)
- continue;
-
- status=do_umount (m->mnt_dir, useMtab);
- if (status!=0) {
- /* Don't bother retrying the umount on busy devices */
- if (errno==EBUSY) {
- perror(m->mnt_dir);
- continue;
- }
- status=do_umount (blockDevice, useMtab);
- if (status!=0) {
- printf ("Couldn't umount %s on %s (type %s): %s\n",
- blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
- }
+ status = do_umount (mountpt, useMtab);
+ if (status != 0) {
+ printf ("Couldn't umount %s on %s: %s\n",
+ mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), strerror(errno));
}
}
- endmntent (mountTable);
}
- return( TRUE);
+ return (status);
}
extern int
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 )
}
}
+
+
+/* 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;
+ }
+}
+
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 $ */
{
int value;
int fd;
- if ( **(argv+1) == '-' ) {
+ if ( argc <= 1 || **(argv++) == '-' ) {
usage( "fdflush device\n");
}
#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>
/* 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)
do_em_all()
{
struct mntent *m;
- char swapName[NAME_MAX];
FILE *f = setmntent ("/etc/fstab", "r");
if (f == NULL) {
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);
#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)
do_umount(const char* name, int useMtab)
{
int status;
- struct mntent *m;
- FILE *mountTable;
- const char *blockDevice = NULL;
-
- if ((mountTable = setmntent (mtab_file, "r"))) {
- while ((m = getmntent (mountTable)) != 0) {
- if (strncmp(m->mnt_dir, name,
- MIN(strlen(m->mnt_dir),strlen(name))) == 0)
- blockDevice = m->mnt_fsname;
- else if (strcmp(m->mnt_fsname, name) == 0) {
- blockDevice = name;
- name = m->mnt_dir;
- }
- }
- }
+ char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE);
+
+ if (blockDevice && strcmp(blockDevice, name) == 0)
+ name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT);
status = umount(name);
/* this was a loop device, delete it */
del_loop(blockDevice);
#endif
-#if defined BB_MTAB
+#if defined BB_FEATURE_REMOUNT
+ if ( status != 0 && doRemount == TRUE && errno == EBUSY ) {
+ status = mount(blockDevice, name, NULL,
+ MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
+ if (status == 0) {
+ fprintf(stderr, "umount: %s busy - remounted read-only\n",
+ blockDevice);
+ /* TODO: update mtab if BB_MTAB is defined */
+ } else {
+ fprintf(stderr, "umount: Cannot remount %s read-only\n",
+ blockDevice);
+ }
+ }
+#endif
if ( status == 0 ) {
+#if defined BB_MTAB
if ( useMtab==TRUE )
erase_mtab(name);
- return 0;
- }
- else
#endif
- return(status);
+ return( TRUE);
+ }
+ return(FALSE);
}
static int
umount_all(int useMtab)
{
- int status;
- struct mntent *m;
- FILE *mountTable;
-
- if ((mountTable = setmntent (mtab_file, "r"))) {
- while ((m = getmntent (mountTable)) != 0) {
- char *blockDevice = m->mnt_fsname;
-#if ! defined BB_MTAB
- if (strcmp (blockDevice, "/dev/root") == 0) {
- struct fstab* fstabItem;
- fstabItem = getfsfile ("/");
- if (fstabItem != NULL) {
- blockDevice = fstabItem->fs_spec;
- }
+ int status = TRUE;
+ char *mountpt;
+ void *iter;
+
+ for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) {
+ status=do_umount (mountpt, useMtab);
+ if (status != 0) {
+ /* Don't bother retrying the umount on busy devices */
+ if (errno == EBUSY) {
+ perror(mountpt);
+ continue;
}
-#endif
- /* Don't umount /proc when doing umount -a */
- if (strcmp (blockDevice, "proc") == 0)
- continue;
-
- status=do_umount (m->mnt_dir, useMtab);
- if (status!=0) {
- /* Don't bother retrying the umount on busy devices */
- if (errno==EBUSY) {
- perror(m->mnt_dir);
- continue;
- }
- status=do_umount (blockDevice, useMtab);
- if (status!=0) {
- printf ("Couldn't umount %s on %s (type %s): %s\n",
- blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
- }
+ status = do_umount (mountpt, useMtab);
+ if (status != 0) {
+ printf ("Couldn't umount %s on %s: %s\n",
+ mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), strerror(errno));
}
}
- endmntent (mountTable);
}
- return( TRUE);
+ return (status);
}
extern int
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 )
}
}
+
+
+/* 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;
+ }
+}
+
*/
#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>
#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>
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;
}
{
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);
fclose(file);
return major*65536 + minor*256 + patch;
}
+#endif /* BB_INIT || BB_PS */
-#endif
-
-#if defined (BB_CP) || defined (BB_MV)
+#if defined (BB_CP_MV) || defined (BB_DU) || defined (BB_LN)
/*
* Return TRUE if a fileName is a directory.
* Nonexistant files return FALSE.
*/
-int isDirectory(const char *name)
+int isDirectory(const char *fileName, const int followLinks)
{
struct stat statBuf;
+ int status;
- if (stat(name, &statBuf) < 0)
- return FALSE;
+ if (followLinks == TRUE)
+ status = stat(fileName, &statBuf);
+ else
+ status = lstat(fileName, &statBuf);
+
+ if (status < 0)
+ return FALSE;
if (S_ISDIR(statBuf.st_mode))
- return TRUE;
- return(FALSE);
+ return TRUE;
+ return FALSE;
}
+#endif
-
+#if defined (BB_CP_MV)
/*
* Copy one file to another, while possibly preserving its modes, times,
* and modes. Returns TRUE if successful, or FALSE on a failure with an
*/
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;
}
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);
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);
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, ×);
+ if (utime(destName, ×) < 0) {
+ perror(destName);
+ exit FALSE;
+ }
}
return TRUE;
-
- error_exit:
+ error_exit:
perror(destName);
close(rfd);
close(wfd);
return FALSE;
}
-#endif
+#endif /* BB_CP_MV */
}
return buf;
}
-#endif
+#endif /* BB_TAR || BB_LS */
#if defined BB_TAR
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.
return total;
}
-#endif
+#endif /* BB_TAR || BB_CP_MV */
#if defined BB_TAR || defined BB_TAIL
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
* 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)
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) {
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 */
{
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 */
}
-#endif
+#endif /* BB_CHMOD_CHOWN_CHGRP || BB_MKDIR */
}
-#endif
+#endif /* BB_CHMOD_CHOWN_CHGRP || BB_PS */
}
-#endif
+#endif /* BB_CHVT || BB_DEALLOCVT */
#if !defined BB_REGEXP && (defined BB_GREP || defined BB_SED)
return FALSE;
}
-
-#endif
+#endif /* ! BB_REGEXP && (BB_GREP || BB_SED) */
#if defined BB_FIND
return TRUE;
}
-#endif
+#endif /* BB_FIND */
endmntent(mountTable);
return mountEntry;
}
-#endif
+#endif /* BB_DF || BB_MTAB */
value = value * 10 + *cp++ - '0';
switch (*cp++) {
- case 'm':
+ case 'M':
+ case 'm': /* `tail' uses it traditionally */
value *= 1048576;
break;
return value;
}
-#endif
+#endif /* BB_DD || BB_TAIL */
#if defined BB_INIT || defined BB_HALT || defined BB_REBOOT
}
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);
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)
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)