diff --git a/Changelog b/Changelog index 6c68d844d..878b9c698 100644 --- a/Changelog +++ b/Changelog @@ -1,5 +1,6 @@ 0.41 - * New App: wc -- contributed by Edward Betts + * New Apps: wc, hostid, logname, tty, whoami, yes -- all contributed + by Edward Betts * Fixed a bug in both cp and mv preventing 'cp foo/README bar' type commands (file in a directory to another directory) from working. @@ -13,6 +14,18 @@ * Added -o loop option for mount, and support in umount for loop devices. Support is toggled by MOUNT_LOOP feature -- Ben Collins + * Several fixes from Marco Pantaleoni + * compile in fullWrite() not only if BB_TAR is defined, but also + if BB_CP or BB_MV are (fullWrite() is referenced by copyFile()) + * add some compiler optimizations to further reduce executable size + (as a side note, on my machines the largest code is generated by + gcc 2.95.2 with -Os ! The smallest by plain gcc 2.7.2.3 with -O2 + -m386 ...) + * Compile no longer fails if busybox.def.h defines BB_FEATURE_LINUXRC + but not BB_INIT. (init_main used to be referenced, but not compiled) + * Fixed a bug in setting TERM for serial console support. TERM now + defaults to "ansi" for serial consoles. + * Fixed a bug in handling the CONSOLE env. variable for serial consoles. -Erik Andersen diff --git a/Makefile b/Makefile index d0779c5c0..91d4bd1c4 100644 --- a/Makefile +++ b/Makefile @@ -33,10 +33,11 @@ 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" ) +GCCEGCS=$(shell $(CC) --version | sed -n "s/.*\(egcs\).*/\1/p" ) GCCSUPPORTSOPTSIZE=$(shell \ if ( test $(GCCMAJVERSION) -eq 2 ) ; then \ - if ( test $(GCCMINVERSION) -ge 91 ) ; then \ + if ( test $(GCCMINVERSION) -ge 66 ) ; then \ echo "true"; \ else \ echo "false"; \ @@ -49,11 +50,26 @@ else \ fi; \ fi; ) +GCCISEGCS=$(shell \ +if ( test "x$(GCCEGCS)" == "xegcs" ) ; then \ + echo "true"; \ + else \ + echo "false"; \ + fi; ) + +EGCSEXTREMEFLAGS = -m386 -mcpu=i386 -march=i386 -malign-jumps=1 -malign-loops=1 -malign-functions=1 +GCCEXTREMEFLAGS = -m386 -malign-jumps=1 -malign-loops=1 -malign-functions=1 + +ifeq ($(GCCISEGCS), true) + EXTREMEFLAGS = $(EGCSEXTREMEFLAGS) +else + EXTREMEFLAGS = $(GCCEXTREMEFLAGS) +endif ifeq ($(GCCSUPPORTSOPTSIZE), true) - OPTIMIZATION=-Os + OPTIMIZATION=-Os $(EXTREMEFLAGS) else - OPTIMIZATION=-O2 + OPTIMIZATION=-O2 $(EXTREMEFLAGS) endif # -D_GNU_SOURCE is needed because environ is used in init.c diff --git a/TODO b/TODO index 4d209bb46..b951767ea 100644 --- a/TODO +++ b/TODO @@ -6,6 +6,11 @@ around to it some time. If you have any good ideas, please let me know. * login/sulogin/passwd/getty/etc are part of tinylogin, and so are not needed or wanted in busybox (or else I'd have to link in libcrypt). +* Networking apps are probably going to be split out some time soon into a + separate package (named perhaps tiny-netkit?). This currently includes + hostid, hostname, mnc, and ping. + + -Erik ----------- diff --git a/applets/busybox.c b/applets/busybox.c index a00f90be0..67485de8d 100644 --- a/applets/busybox.c +++ b/applets/busybox.c @@ -3,8 +3,18 @@ #include #include +#ifndef BB_INIT +#undef BB_FEATURE_LINUXRC +#endif + static int been_there_done_that = 0; +/* It has been alledged that doing such things can + * help reduce binary size when staticly linking, + * of course with glibc, this is unlikely as long + * as we use things like printf -- perhaps a printf + * replacement may be in order + */ #if 0 void exit (int status) __attribute__ ((noreturn)); void exit (int status) { _exit(status); }; @@ -91,6 +101,9 @@ static const struct Applet applets[] = { #ifdef BB_HEAD //bin {"head", head_main}, #endif +#ifdef BB_HOSTID //usr/bin + {"hostid", hostid_main}, +#endif #ifdef BB_HOSTNAME //bin {"hostname", hostname_main}, #endif @@ -209,6 +222,9 @@ static const struct Applet applets[] = { #ifdef BB_LOGGER //usr/bin {"logger", logger_main}, #endif +#ifdef BB_LOGNAME //usr/bin + {"logname", logname_main}, +#endif #ifdef BB_SWAPONOFF //sbin {"swapon", swap_on_off_main}, {"swapoff", swap_on_off_main}, @@ -229,8 +245,8 @@ static const struct Applet applets[] = { {"true", true_main}, {"false", false_main}, #endif -#ifdef BB_WC //usr/bin - {"wc", wc_main}, +#ifdef BB_TTY //usr/bin + {"tty", tty_main}, #endif #ifdef BB_UNAME //bin {"uname", uname_main}, @@ -244,6 +260,15 @@ static const struct Applet applets[] = { #ifdef BB_UPDATE //sbin {"update", update_main}, #endif +#ifdef BB_WC //usr/bin + {"wc", wc_main}, +#endif +#ifdef BB_WHOAMI //usr/bin + {"whoami", whoami_main}, +#endif +#ifdef BB_YES //usr/bin + {"yes", yes_main}, +#endif #ifdef BB_GUNZIP //bin {"zcat", gunzip_main}, {"gunzip", gunzip_main}, diff --git a/busybox.c b/busybox.c index a00f90be0..67485de8d 100644 --- a/busybox.c +++ b/busybox.c @@ -3,8 +3,18 @@ #include #include +#ifndef BB_INIT +#undef BB_FEATURE_LINUXRC +#endif + static int been_there_done_that = 0; +/* It has been alledged that doing such things can + * help reduce binary size when staticly linking, + * of course with glibc, this is unlikely as long + * as we use things like printf -- perhaps a printf + * replacement may be in order + */ #if 0 void exit (int status) __attribute__ ((noreturn)); void exit (int status) { _exit(status); }; @@ -91,6 +101,9 @@ static const struct Applet applets[] = { #ifdef BB_HEAD //bin {"head", head_main}, #endif +#ifdef BB_HOSTID //usr/bin + {"hostid", hostid_main}, +#endif #ifdef BB_HOSTNAME //bin {"hostname", hostname_main}, #endif @@ -209,6 +222,9 @@ static const struct Applet applets[] = { #ifdef BB_LOGGER //usr/bin {"logger", logger_main}, #endif +#ifdef BB_LOGNAME //usr/bin + {"logname", logname_main}, +#endif #ifdef BB_SWAPONOFF //sbin {"swapon", swap_on_off_main}, {"swapoff", swap_on_off_main}, @@ -229,8 +245,8 @@ static const struct Applet applets[] = { {"true", true_main}, {"false", false_main}, #endif -#ifdef BB_WC //usr/bin - {"wc", wc_main}, +#ifdef BB_TTY //usr/bin + {"tty", tty_main}, #endif #ifdef BB_UNAME //bin {"uname", uname_main}, @@ -244,6 +260,15 @@ static const struct Applet applets[] = { #ifdef BB_UPDATE //sbin {"update", update_main}, #endif +#ifdef BB_WC //usr/bin + {"wc", wc_main}, +#endif +#ifdef BB_WHOAMI //usr/bin + {"whoami", whoami_main}, +#endif +#ifdef BB_YES //usr/bin + {"yes", yes_main}, +#endif #ifdef BB_GUNZIP //bin {"zcat", gunzip_main}, {"gunzip", gunzip_main}, diff --git a/busybox.def.h b/busybox.def.h index 099eba96c..b8d7b9730 100644 --- a/busybox.def.h +++ b/busybox.def.h @@ -10,10 +10,12 @@ #define BB_CAT #define BB_CHMOD_CHOWN_CHGRP #define BB_CHROOT +#define BB_CHVT #define BB_CLEAR #define BB_CP #define BB_DATE #define BB_DD +#define BB_DEALLOCVT #define BB_DF #define BB_DMESG //#define BB_DUTMP @@ -23,12 +25,12 @@ #define BB_FIND #define BB_FREE #define BB_FSCK_MINIX -#define BB_MKFS_MINIX -#define BB_CHVT -#define BB_DEALLOCVT #define BB_GREP +#define BB_GUNZIP +#define BB_GZIP //#define BB_HALT #define BB_HEAD +//#define BB_HOSTID #define BB_HOSTNAME #define BB_INIT // Don't turn BB_INSMOD on. It doesn't work. @@ -41,9 +43,11 @@ //#define BB_LOADFONT //#define BB_LOADKMAP //#define BB_LOGGER +#define BB_LOGNAME #define BB_LS #define BB_LSMOD //#define BB_MAKEDEVS +#define BB_MKFS_MINIX //#define BB_MATH #define BB_MKDIR //#define BB_MKFIFO @@ -61,13 +65,13 @@ //#define BB_PRINTF #define BB_PS #define BB_PWD -#define BB_REGEXP #define BB_REBOOT +#define BB_REGEXP #define BB_RM #define BB_RMDIR //#define BB_RMMOD -//#define BB_SFDISK #define BB_SED +//#define BB_SFDISK #define BB_SLEEP #define BB_SORT #define BB_SWAPONOFF @@ -78,13 +82,14 @@ #define BB_TEE #define BB_TOUCH #define BB_TRUE_FALSE +#define BB_TTY #define BB_WC +#define BB_WHOAMI #define BB_UMOUNT #define BB_UNIQ -#define BB_UPDATE #define BB_UNAME -#define BB_GZIP -#define BB_GUNZIP +#define BB_UPDATE +#define BB_YES // End of Applications List // // diff --git a/coreutils/hostid.c b/coreutils/hostid.c new file mode 100644 index 000000000..f8d5862ae --- /dev/null +++ b/coreutils/hostid.c @@ -0,0 +1,28 @@ +/* + * Mini hostid implementation for busybox + * + * Copyright (C) 2000 Edward Betts . + * + * 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 + +extern int hostid_main(int argc, char **argv) { + printf ("%lx\n", gethostid()); + exit( TRUE); +} diff --git a/coreutils/logname.c b/coreutils/logname.c new file mode 100644 index 000000000..5c8275ab4 --- /dev/null +++ b/coreutils/logname.c @@ -0,0 +1,40 @@ +/* + * Mini logname implementation for busybox + * + * Copyright (C) 2000 Edward Betts . + * + * 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 + +static const char logname_usage[] = "logname\n\n" +"Print the name of the current user.\n"; + +extern int logname_main(int argc, char **argv) { + char *cp; + + if (argc > 1) usage (logname_usage); + + cp = getlogin (); + if (cp) { + puts (cp); + exit (TRUE); + } + fprintf (stderr, "%s: no login name\n", argv[0]); + exit (FALSE); +} diff --git a/coreutils/tty.c b/coreutils/tty.c new file mode 100644 index 000000000..83abaffb5 --- /dev/null +++ b/coreutils/tty.c @@ -0,0 +1,42 @@ +/* + * Mini tty implementation for busybox + * + * Copyright (C) 2000 Edward Betts . + * + * 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 +#include + +static const char tty_usage[] = "tty\n\n" +"Print the file name of the terminal connected to standard input.\n" +"\t-s\tprint nothing, only return an exit status\n"; + +extern int tty_main(int argc, char **argv) { + char *tty; + + if (argc > 1) { + if (argv[1][0] != '-' || argv[1][1] != 's') usage (tty_usage); + } + else { + tty = ttyname (0); + if (tty) puts (tty); + else puts ("not a tty"); + } + exit (isatty (0) ? TRUE : FALSE); +} diff --git a/coreutils/wc.c b/coreutils/wc.c new file mode 100644 index 000000000..a1e2fca56 --- /dev/null +++ b/coreutils/wc.c @@ -0,0 +1,162 @@ +/* + * Mini wc implementation for busybox + * + * by Edward Betts + * + * 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 + +static const char wc_usage[] = "wc [OPTION]... [FILE]...\n\n" +"Print line, word, and byte counts for each FILE, and a total line if\n" +"more than one FILE is specified. With no FILE, read standard input.\n" +"\t-c\tprint the byte counts\n" +"\t-l\tprint the newline counts\n" +"\t-L\tprint the length of the longest line\n" +"\t-L\tprint the length of the longest line\n" +"\t-w\tprint the word counts\n"; + +static int total_lines, total_words, total_chars, max_length; +static int print_lines, print_words, print_chars, print_length; + +void print_counts (int lines, int words, int chars, int length, + const char *name) { + char const *space = ""; + if (print_lines) { + printf ("%7d", lines); + space = " "; + } + if (print_words) { + printf ("%s%7d", space, words); + space = " "; + } + if (print_chars) { + printf ("%s%7d", space, chars); + space = " "; + } + if (print_length) + printf ("%s%7d", space, length); + if (*name) + printf (" %s", name); + putchar ('\n'); +} + +static void wc_file(FILE *file, const char *name) +{ + int lines, words, chars, length; + int in_word = 0, linepos = 0; + int c; + lines = words = chars = length = 0; + while ((c = getc(file)) != EOF) { + chars++; + switch (c) { + case '\n': + lines++; + case '\r': + case '\f': + if (linepos > length) + length = linepos; + linepos = 0; + goto word_separator; + case '\t': + linepos += 8 - (linepos % 8); + goto word_separator; + case ' ': + linepos++; + case '\v': + word_separator: + if (in_word) { + in_word = 0; + words++; + } + break; + default: + linepos++; + in_word = 1; + break; + } + } + if (linepos > length) + length = linepos; + if (in_word) + words++; + print_counts (lines, words, chars, length, name); + total_lines += lines; + total_words += words; + total_chars += chars; + if (length > max_length) + max_length = length; + fclose(file); + fflush(stdout); +} + +int wc_main(int argc, char **argv) { + FILE *file; + total_lines = total_words = total_chars = max_length = 0; + print_lines = print_words = print_chars = print_length = 0; + + while (--argc && **(++argv) == '-') { + while (*++(*argv)) + switch (**argv) { + case 'c': + print_chars = 1; + break; + case 'l': + print_lines = 1; + break; + case 'L': + print_length = 1; + break; + case 'w': + print_words = 1; + break; + default: + usage (wc_usage); + } + } + + if (!print_lines && !print_words && !print_chars && !print_length) + print_lines = print_words = print_chars = 1; + + if (argc == 0) { + wc_file(stdin, ""); + exit(TRUE); + } + else if (argc == 1) { + file = fopen(*argv, "r"); + if (file == NULL) { + perror(*argv); + exit(FALSE); + } + wc_file(file, *argv); + } + else { + while (argc-- > 0 && *argv != '\0' && strlen(*argv)) { + file = fopen(*argv, "r"); + if (file == NULL) { + perror(*argv); + exit(FALSE); + } + wc_file(file, *argv); + argv++; + } + print_counts (total_lines, total_words, total_chars, + max_length, "total"); + } + exit(TRUE); +} diff --git a/coreutils/whoami.c b/coreutils/whoami.c new file mode 100644 index 000000000..7fd5d01b2 --- /dev/null +++ b/coreutils/whoami.c @@ -0,0 +1,44 @@ +/* + * Mini whoami implementation for busybox + * + * Copyright (C) 2000 Edward Betts . + * + * 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 +#include + +static const char whoami_usage[] = "whoami\n\n" +"Print the user name associated with the current effective user id.\n" +"Same as id -un.\n"; + +extern int whoami_main(int argc, char **argv) { + struct passwd *pw; + uid_t uid; + + if (argc > 1) usage (whoami_usage); + + uid = geteuid (); + pw = getpwuid (uid); + if (pw) { + puts (pw->pw_name); + exit (TRUE); + } + fprintf (stderr, "%s: cannot find username for UID %u\n", argv[0], (unsigned) uid); + exit (FALSE); +} diff --git a/coreutils/yes.c b/coreutils/yes.c new file mode 100644 index 000000000..96d6257d0 --- /dev/null +++ b/coreutils/yes.c @@ -0,0 +1,41 @@ +/* + * Mini yes implementation for busybox + * + * Copyright (C) 2000 Edward Betts . + * + * 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 + +extern int yes_main(int argc, char **argv) { + int i; + if (argc == 1) + while (1) + if (puts ("y") == EOF) { + perror ("yes"); + exit(FALSE); + } + + while (1) + for (i = 1; i < argc; i++) + if (fputs (argv[i], stdout) == EOF || putchar (i == argc - 1 ? '\n' : ' ') == EOF) { + perror ("yes"); + exit(FALSE); + } + exit(TRUE); +} diff --git a/docs/CommandList b/docs/CommandList index 8c0a01e23..32d2134d8 100644 --- a/docs/CommandList +++ b/docs/CommandList @@ -515,11 +515,14 @@ ________________________________________________________________________________ -mknod (Segmentation Fault when executing this command) - - (No embedix information available for this command.) +mknod NAME TYPE MAJOR MINOR +Make block or character special files. +TYPEs include: + b: Make a block (buffered) device. + c or u: Make a character (un-buffered) device. + p: Make a named pipe. Major and minor are ignored for named pipes. diff --git a/hostid.c b/hostid.c new file mode 100644 index 000000000..f8d5862ae --- /dev/null +++ b/hostid.c @@ -0,0 +1,28 @@ +/* + * Mini hostid implementation for busybox + * + * Copyright (C) 2000 Edward Betts . + * + * 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 + +extern int hostid_main(int argc, char **argv) { + printf ("%lx\n", gethostid()); + exit( TRUE); +} diff --git a/init.c b/init.c index b4ab1c751..913436353 100644 --- a/init.c +++ b/init.c @@ -106,11 +106,11 @@ struct initActionTag { initAction* initActionList = NULL; -static char *console = _PATH_CONSOLE; static char *secondConsole = VT_SECONDARY; static char *log = VT_LOG; static int kernelVersion = 0; -static char *termType = NULL; +static char termType[32] = "TERM=ansi"; +static char console[32] = _PATH_CONSOLE; /* try to open up the specified device */ @@ -258,41 +258,37 @@ static void console_init() struct serial_struct sr; char *s; - if ((s = getenv("CONSOLE")) != NULL) { - termType = s; - } else { - termType = "TERM=vt100"; + if ((s = getenv("TERM")) != NULL) { + snprintf(termType,sizeof(termType)-1,"TERM=%s",s); } if ((s = getenv("CONSOLE")) != NULL) { - console = s; + snprintf(console, sizeof(console)-1, "%s",s); } #if #cpu(sparc) /* sparc kernel supports console=tty[ab] parameter which is also * passed to init, so catch it here */ - else if ((s = getenv("console")) != NULL) { + else if ((s = getenv("console")) != NULL) {*/ /* remap tty[ab] to /dev/ttyS[01] */ if (strcmp( s, "ttya" )==0) - console = SERIAL_CON0; + snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0); else if (strcmp( s, "ttyb" )==0) - console = SERIAL_CON1; + snprintf(console, sizeof(console)-1, "%s", SERIAL_CON1); } #endif else { struct vt_stat vt; - static char the_console[13]; - console = the_console; /* 2.2 kernels: identify the real console backend and try to use it */ if (ioctl(0, TIOCGSERIAL, &sr) == 0) { /* this is a serial console */ - snprintf( the_console, sizeof the_console, "/dev/ttyS%d", sr.line ); + snprintf(console, sizeof(console)-1, "/dev/ttyS%d", sr.line); } else if (ioctl(0, VT_GETSTATE, &vt) == 0) { /* this is linux virtual tty */ - snprintf( the_console, sizeof the_console, "/dev/tty%d", vt.v_active ); + snprintf(console, sizeof(console)-1, "/dev/tty%d", vt.v_active); } else { - console = _PATH_CONSOLE; + snprintf(console, sizeof(console)-1, "%s", _PATH_CONSOLE); tried_devcons++; } } @@ -301,25 +297,25 @@ static void console_init() /* Can't open selected console -- try /dev/console */ if (!tried_devcons) { tried_devcons++; - console = _PATH_CONSOLE; + snprintf(console, sizeof(console)-1, "%s", _PATH_CONSOLE); continue; } /* Can't open selected console -- try vt1 */ if (!tried_vtprimary) { tried_vtprimary++; - console = VT_PRIMARY; + snprintf(console, sizeof(console)-1, "%s", VT_PRIMARY); continue; } break; } - if (fd < 0) + if (fd < 0) { /* Perhaps we should panic here? */ - console = "/dev/null"; - else { + snprintf(console, sizeof(console)-1, "/dev/null"); + } else { /* check for serial console and disable logging to tty3 & running a * shell to tty2 */ if (ioctl(0,TIOCGSERIAL,&sr) == 0) { - message(LOG|CONSOLE, "serial console detected. Disabling virtual terminals.\r\n", console ); + message(LOG|CONSOLE, "serial console detected. Disabling virtual terminals.\r\n" ); log = NULL; secondConsole = NULL; } @@ -337,15 +333,14 @@ static pid_t run(char* command, char* cmd[255]; static const char press_enter[] = "\nPlease press Enter to activate this console. "; - static char * environment[] = { + char* environment[] = { "HOME=/", "PATH=/usr/bin:/bin:/usr/sbin:/sbin", "SHELL=/bin/sh", - 0, + termType, "USER=root", 0 }; - environment[3]=termType; if ((pid = fork()) == 0) { @@ -389,24 +384,23 @@ static pid_t run(char* command, } /* Log the process name and args */ - message(LOG|CONSOLE, "Starting pid %d, console %s: '", + message(LOG, "Starting pid %d, console %s: '", shell_pgid, terminal, command); /* Convert command (char*) into cmd (char**, one word per string) */ for (tmpCmd=command, i=0; (tmpCmd=strsep(&command, " \t")) != NULL;) { if (*tmpCmd != '\0') { cmd[i] = tmpCmd; - message(LOG|CONSOLE, "%s ", tmpCmd); + message(LOG, "%s ", tmpCmd); tmpCmd++; i++; } } cmd[i] = NULL; - message(LOG|CONSOLE, "'\r\n"); + message(LOG, "'\r\n"); /* Now run it. The new program will take over this PID, * so nothing further in init.c should be run. */ - //execvp(cmd[0], cmd); execve(cmd[0], cmd, environment); /* We're still here? Some error happened. */ @@ -541,8 +535,8 @@ void new_initAction (initActionEnum action, } else strncpy(newAction->console, console, 255); newAction->pid = 0; - message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n", - newAction->process, newAction->action, newAction->console); +// message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n", +// newAction->process, newAction->action, newAction->console); } void delete_initAction (initAction *action) @@ -673,6 +667,9 @@ extern int init_main(int argc, char **argv) usage( "init\n\nInit is the parent of all processes.\n\n" "This version of init is designed to be run only by the kernel\n"); } + /* Fix up argv[0] to be certain we claim to be init */ + strncpy(argv[0], "init", strlen(argv[0])); + /* Set up sig handlers -- be sure to * clear all of these in run() */ signal(SIGUSR1, halt_signal); diff --git a/init/init.c b/init/init.c index b4ab1c751..913436353 100644 --- a/init/init.c +++ b/init/init.c @@ -106,11 +106,11 @@ struct initActionTag { initAction* initActionList = NULL; -static char *console = _PATH_CONSOLE; static char *secondConsole = VT_SECONDARY; static char *log = VT_LOG; static int kernelVersion = 0; -static char *termType = NULL; +static char termType[32] = "TERM=ansi"; +static char console[32] = _PATH_CONSOLE; /* try to open up the specified device */ @@ -258,41 +258,37 @@ static void console_init() struct serial_struct sr; char *s; - if ((s = getenv("CONSOLE")) != NULL) { - termType = s; - } else { - termType = "TERM=vt100"; + if ((s = getenv("TERM")) != NULL) { + snprintf(termType,sizeof(termType)-1,"TERM=%s",s); } if ((s = getenv("CONSOLE")) != NULL) { - console = s; + snprintf(console, sizeof(console)-1, "%s",s); } #if #cpu(sparc) /* sparc kernel supports console=tty[ab] parameter which is also * passed to init, so catch it here */ - else if ((s = getenv("console")) != NULL) { + else if ((s = getenv("console")) != NULL) {*/ /* remap tty[ab] to /dev/ttyS[01] */ if (strcmp( s, "ttya" )==0) - console = SERIAL_CON0; + snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0); else if (strcmp( s, "ttyb" )==0) - console = SERIAL_CON1; + snprintf(console, sizeof(console)-1, "%s", SERIAL_CON1); } #endif else { struct vt_stat vt; - static char the_console[13]; - console = the_console; /* 2.2 kernels: identify the real console backend and try to use it */ if (ioctl(0, TIOCGSERIAL, &sr) == 0) { /* this is a serial console */ - snprintf( the_console, sizeof the_console, "/dev/ttyS%d", sr.line ); + snprintf(console, sizeof(console)-1, "/dev/ttyS%d", sr.line); } else if (ioctl(0, VT_GETSTATE, &vt) == 0) { /* this is linux virtual tty */ - snprintf( the_console, sizeof the_console, "/dev/tty%d", vt.v_active ); + snprintf(console, sizeof(console)-1, "/dev/tty%d", vt.v_active); } else { - console = _PATH_CONSOLE; + snprintf(console, sizeof(console)-1, "%s", _PATH_CONSOLE); tried_devcons++; } } @@ -301,25 +297,25 @@ static void console_init() /* Can't open selected console -- try /dev/console */ if (!tried_devcons) { tried_devcons++; - console = _PATH_CONSOLE; + snprintf(console, sizeof(console)-1, "%s", _PATH_CONSOLE); continue; } /* Can't open selected console -- try vt1 */ if (!tried_vtprimary) { tried_vtprimary++; - console = VT_PRIMARY; + snprintf(console, sizeof(console)-1, "%s", VT_PRIMARY); continue; } break; } - if (fd < 0) + if (fd < 0) { /* Perhaps we should panic here? */ - console = "/dev/null"; - else { + snprintf(console, sizeof(console)-1, "/dev/null"); + } else { /* check for serial console and disable logging to tty3 & running a * shell to tty2 */ if (ioctl(0,TIOCGSERIAL,&sr) == 0) { - message(LOG|CONSOLE, "serial console detected. Disabling virtual terminals.\r\n", console ); + message(LOG|CONSOLE, "serial console detected. Disabling virtual terminals.\r\n" ); log = NULL; secondConsole = NULL; } @@ -337,15 +333,14 @@ static pid_t run(char* command, char* cmd[255]; static const char press_enter[] = "\nPlease press Enter to activate this console. "; - static char * environment[] = { + char* environment[] = { "HOME=/", "PATH=/usr/bin:/bin:/usr/sbin:/sbin", "SHELL=/bin/sh", - 0, + termType, "USER=root", 0 }; - environment[3]=termType; if ((pid = fork()) == 0) { @@ -389,24 +384,23 @@ static pid_t run(char* command, } /* Log the process name and args */ - message(LOG|CONSOLE, "Starting pid %d, console %s: '", + message(LOG, "Starting pid %d, console %s: '", shell_pgid, terminal, command); /* Convert command (char*) into cmd (char**, one word per string) */ for (tmpCmd=command, i=0; (tmpCmd=strsep(&command, " \t")) != NULL;) { if (*tmpCmd != '\0') { cmd[i] = tmpCmd; - message(LOG|CONSOLE, "%s ", tmpCmd); + message(LOG, "%s ", tmpCmd); tmpCmd++; i++; } } cmd[i] = NULL; - message(LOG|CONSOLE, "'\r\n"); + message(LOG, "'\r\n"); /* Now run it. The new program will take over this PID, * so nothing further in init.c should be run. */ - //execvp(cmd[0], cmd); execve(cmd[0], cmd, environment); /* We're still here? Some error happened. */ @@ -541,8 +535,8 @@ void new_initAction (initActionEnum action, } else strncpy(newAction->console, console, 255); newAction->pid = 0; - message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n", - newAction->process, newAction->action, newAction->console); +// message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n", +// newAction->process, newAction->action, newAction->console); } void delete_initAction (initAction *action) @@ -673,6 +667,9 @@ extern int init_main(int argc, char **argv) usage( "init\n\nInit is the parent of all processes.\n\n" "This version of init is designed to be run only by the kernel\n"); } + /* Fix up argv[0] to be certain we claim to be init */ + strncpy(argv[0], "init", strlen(argv[0])); + /* Set up sig handlers -- be sure to * clear all of these in run() */ signal(SIGUSR1, halt_signal); diff --git a/internal.h b/internal.h index 49cfcf05c..e57096d4a 100644 --- a/internal.h +++ b/internal.h @@ -54,7 +54,6 @@ struct Applet { extern int busybox_main(int argc, char** argv); extern int block_device_main(int argc, char** argv); extern int cat_main(int argc, char** argv); -extern int more_main(int argc, char** argv); extern int cp_main(int argc, char** argv); extern int chmod_chown_chgrp_main(int argc, char** argv); extern int chroot_main(int argc, char** argv); @@ -75,17 +74,23 @@ extern int fsck_minix_main(int argc, char **argv); extern int find_main(int argc, char** argv); extern int free_main(int argc, char** argv); extern int grep_main(int argc, char** argv); +extern int gunzip_main (int argc, char** argv); +extern int gzip_main(int argc, char** argv); extern int halt_main(int argc, char** argv); extern int head_main(int argc, char** argv); +extern int hostid_main(int argc, char** argv); extern int hostname_main(int argc, char** argv); extern int init_main(int argc, char** argv); extern int insmod_main(int argc, char** argv); extern int kill_main(int argc, char** argv); extern int length_main(int argc, char** argv); extern int ln_main(int argc, char** argv); +extern int loadacm_main(int argc, char** argv); extern int loadfont_main(int argc, char** argv); extern int loadkmap_main(int argc, char** argv); extern int losetup_main(int argc, char** argv); +extern int logger_main(int argc, char **argv); +extern int logname_main(int argc, char **argv); extern int ls_main(int argc, char** argv); extern int lsmod_main(int argc, char** argv); extern int makedevs_main(int argc, char** argv); @@ -96,6 +101,7 @@ extern int mkfs_minix_main(int argc, char **argv); extern int mknod_main(int argc, char** argv); extern int mkswap_main(int argc, char** argv); extern int mnc_main(int argc, char** argv); +extern int more_main(int argc, char** argv); extern int mount_main(int argc, char** argv); extern int mt_main(int argc, char** argv); extern int mv_main(int argc, char** argv); @@ -108,31 +114,28 @@ extern int reboot_main(int argc, char** argv); extern int rm_main(int argc, char** argv); extern int rmdir_main(int argc, char **argv); extern int rmmod_main(int argc, char** argv); -extern int scan_partitions_main(int argc, char** argv); -extern int sh_main(int argc, char** argv); -extern int sfdisk_main(int argc, char** argv); extern int sed_main(int argc, char** argv); +extern int sfdisk_main(int argc, char** argv); extern int sleep_main(int argc, char** argv); extern int sort_main(int argc, char** argv); extern int swap_on_off_main(int argc, char** argv); extern int sync_main(int argc, char** argv); extern int syslogd_main(int argc, char **argv); -extern int logger_main(int argc, char **argv); -extern int tar_main(int argc, char** argv); extern int tail_main(int argc, char** argv); +extern int tar_main(int argc, char** argv); extern int tee_main(int argc, char** argv); extern int touch_main(int argc, char** argv); -extern int tput_main(int argc, char** argv); extern int true_main(int argc, char** argv); +extern int tput_main(int argc, char** argv); extern int tryopen_main(int argc, char** argv); -extern int wc_main(int argc, char** argv); +extern int tty_main(int argc, char** argv); extern int umount_main(int argc, char** argv); +extern int uname_main(int argc, char** argv); extern int uniq_main(int argc, char** argv); extern int update_main(int argc, char** argv); -extern int uname_main(int argc, char** argv); -extern int gunzip_main (int argc, char** argv); -extern int gzip_main(int argc, char** argv); -extern int loadacm_main(int argc, char** argv); +extern int wc_main(int argc, char** argv); +extern int whoami_main(int argc, char** argv); +extern int yes_main(int argc, char** argv); const char *modeString(int mode); @@ -204,6 +207,11 @@ static inline int clrbit(char * addr,unsigned int nr) #endif /* inline bitops junk */ +#ifndef RB_POWER_OFF +/* Stop system and switch power off if possable. */ +#define RB_POWER_OFF 0x4321fedc +#endif + #endif /* _INTERNAL_H_ */ diff --git a/logname.c b/logname.c new file mode 100644 index 000000000..5c8275ab4 --- /dev/null +++ b/logname.c @@ -0,0 +1,40 @@ +/* + * Mini logname implementation for busybox + * + * Copyright (C) 2000 Edward Betts . + * + * 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 + +static const char logname_usage[] = "logname\n\n" +"Print the name of the current user.\n"; + +extern int logname_main(int argc, char **argv) { + char *cp; + + if (argc > 1) usage (logname_usage); + + cp = getlogin (); + if (cp) { + puts (cp); + exit (TRUE); + } + fprintf (stderr, "%s: no login name\n", argv[0]); + exit (FALSE); +} diff --git a/mount.c b/mount.c index 8777a3be4..713e5e850 100644 --- a/mount.c +++ b/mount.c @@ -24,11 +24,13 @@ * 1999-04-17 Dave Cinege...Rewrote -t auto. Fixed ro mtab. * * 1999-10-07 Erik Andersen , . - * Rewrote of a lot of code. Removed mtab usage (I plan on + * Rewrite of a lot of code. Removed mtab usage (I plan on * putting it back as a compile-time option some time), * major adjustments to option parsing, and some serious * dieting all around. * + * 1999-11-06 mtab suppport is back - andersee + * * 2000-01-12 Ben Collins , Borrowed utils-linux's * mount to add loop support. */ diff --git a/tty.c b/tty.c new file mode 100644 index 000000000..83abaffb5 --- /dev/null +++ b/tty.c @@ -0,0 +1,42 @@ +/* + * Mini tty implementation for busybox + * + * Copyright (C) 2000 Edward Betts . + * + * 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 +#include + +static const char tty_usage[] = "tty\n\n" +"Print the file name of the terminal connected to standard input.\n" +"\t-s\tprint nothing, only return an exit status\n"; + +extern int tty_main(int argc, char **argv) { + char *tty; + + if (argc > 1) { + if (argv[1][0] != '-' || argv[1][1] != 's') usage (tty_usage); + } + else { + tty = ttyname (0); + if (tty) puts (tty); + else puts ("not a tty"); + } + exit (isatty (0) ? TRUE : FALSE); +} diff --git a/util-linux/mount.c b/util-linux/mount.c index 8777a3be4..713e5e850 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -24,11 +24,13 @@ * 1999-04-17 Dave Cinege...Rewrote -t auto. Fixed ro mtab. * * 1999-10-07 Erik Andersen , . - * Rewrote of a lot of code. Removed mtab usage (I plan on + * Rewrite of a lot of code. Removed mtab usage (I plan on * putting it back as a compile-time option some time), * major adjustments to option parsing, and some serious * dieting all around. * + * 1999-11-06 mtab suppport is back - andersee + * * 2000-01-12 Ben Collins , Borrowed utils-linux's * mount to add loop support. */ diff --git a/utility.c b/utility.c index c18cb4b27..ade47bde0 100644 --- a/utility.c +++ b/utility.c @@ -317,7 +317,9 @@ const char *timeString(time_t timeVal) return buf; } +#endif +#if defined BB_TAR || defined BB_CP || defined BB_MV /* * Write all of the supplied buffer out to a file. * This does multiple writes as necessary. diff --git a/wc.c b/wc.c new file mode 100644 index 000000000..a1e2fca56 --- /dev/null +++ b/wc.c @@ -0,0 +1,162 @@ +/* + * Mini wc implementation for busybox + * + * by Edward Betts + * + * 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 + +static const char wc_usage[] = "wc [OPTION]... [FILE]...\n\n" +"Print line, word, and byte counts for each FILE, and a total line if\n" +"more than one FILE is specified. With no FILE, read standard input.\n" +"\t-c\tprint the byte counts\n" +"\t-l\tprint the newline counts\n" +"\t-L\tprint the length of the longest line\n" +"\t-L\tprint the length of the longest line\n" +"\t-w\tprint the word counts\n"; + +static int total_lines, total_words, total_chars, max_length; +static int print_lines, print_words, print_chars, print_length; + +void print_counts (int lines, int words, int chars, int length, + const char *name) { + char const *space = ""; + if (print_lines) { + printf ("%7d", lines); + space = " "; + } + if (print_words) { + printf ("%s%7d", space, words); + space = " "; + } + if (print_chars) { + printf ("%s%7d", space, chars); + space = " "; + } + if (print_length) + printf ("%s%7d", space, length); + if (*name) + printf (" %s", name); + putchar ('\n'); +} + +static void wc_file(FILE *file, const char *name) +{ + int lines, words, chars, length; + int in_word = 0, linepos = 0; + int c; + lines = words = chars = length = 0; + while ((c = getc(file)) != EOF) { + chars++; + switch (c) { + case '\n': + lines++; + case '\r': + case '\f': + if (linepos > length) + length = linepos; + linepos = 0; + goto word_separator; + case '\t': + linepos += 8 - (linepos % 8); + goto word_separator; + case ' ': + linepos++; + case '\v': + word_separator: + if (in_word) { + in_word = 0; + words++; + } + break; + default: + linepos++; + in_word = 1; + break; + } + } + if (linepos > length) + length = linepos; + if (in_word) + words++; + print_counts (lines, words, chars, length, name); + total_lines += lines; + total_words += words; + total_chars += chars; + if (length > max_length) + max_length = length; + fclose(file); + fflush(stdout); +} + +int wc_main(int argc, char **argv) { + FILE *file; + total_lines = total_words = total_chars = max_length = 0; + print_lines = print_words = print_chars = print_length = 0; + + while (--argc && **(++argv) == '-') { + while (*++(*argv)) + switch (**argv) { + case 'c': + print_chars = 1; + break; + case 'l': + print_lines = 1; + break; + case 'L': + print_length = 1; + break; + case 'w': + print_words = 1; + break; + default: + usage (wc_usage); + } + } + + if (!print_lines && !print_words && !print_chars && !print_length) + print_lines = print_words = print_chars = 1; + + if (argc == 0) { + wc_file(stdin, ""); + exit(TRUE); + } + else if (argc == 1) { + file = fopen(*argv, "r"); + if (file == NULL) { + perror(*argv); + exit(FALSE); + } + wc_file(file, *argv); + } + else { + while (argc-- > 0 && *argv != '\0' && strlen(*argv)) { + file = fopen(*argv, "r"); + if (file == NULL) { + perror(*argv); + exit(FALSE); + } + wc_file(file, *argv); + argv++; + } + print_counts (total_lines, total_words, total_chars, + max_length, "total"); + } + exit(TRUE); +} diff --git a/whoami.c b/whoami.c new file mode 100644 index 000000000..7fd5d01b2 --- /dev/null +++ b/whoami.c @@ -0,0 +1,44 @@ +/* + * Mini whoami implementation for busybox + * + * Copyright (C) 2000 Edward Betts . + * + * 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 +#include + +static const char whoami_usage[] = "whoami\n\n" +"Print the user name associated with the current effective user id.\n" +"Same as id -un.\n"; + +extern int whoami_main(int argc, char **argv) { + struct passwd *pw; + uid_t uid; + + if (argc > 1) usage (whoami_usage); + + uid = geteuid (); + pw = getpwuid (uid); + if (pw) { + puts (pw->pw_name); + exit (TRUE); + } + fprintf (stderr, "%s: cannot find username for UID %u\n", argv[0], (unsigned) uid); + exit (FALSE); +} diff --git a/yes.c b/yes.c new file mode 100644 index 000000000..96d6257d0 --- /dev/null +++ b/yes.c @@ -0,0 +1,41 @@ +/* + * Mini yes implementation for busybox + * + * Copyright (C) 2000 Edward Betts . + * + * 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 + +extern int yes_main(int argc, char **argv) { + int i; + if (argc == 1) + while (1) + if (puts ("y") == EOF) { + perror ("yes"); + exit(FALSE); + } + + while (1) + for (i = 1; i < argc; i++) + if (fputs (argv[i], stdout) == EOF || putchar (i == argc - 1 ? '\n' : ' ') == EOF) { + perror ("yes"); + exit(FALSE); + } + exit(TRUE); +}