From 86ab8a32bd63b2f2a73bdcead8e2bb037589e175 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Fri, 2 Jun 2000 03:21:42 +0000 Subject: [PATCH] A number of additional fixed from Pavel Roskin, note some more bugs in the TODO list. Add Glenn to the Authors list for writing a mini ar for BusyBox, which is now included. -Erik --- AUTHORS | 5 +- Changelog | 7 + Makefile | 5 +- TODO | 2 + applets/busybox.c | 3 + ar.c | 277 ++++++++++++++++++++++++++++++++++ archival/ar.c | 277 ++++++++++++++++++++++++++++++++++ busybox.c | 3 + busybox.def.h | 1 + coreutils/pwd.c | 2 +- coreutils/tail.c | 2 +- coreutils/test.c | 12 +- docs/busybox.net/BusyBox.html | 30 +++- docs/busybox.pod | 26 +++- internal.h | 1 + kill.c | 3 + more.c | 4 +- procps/kill.c | 3 + procps/ps.c | 13 +- ps.c | 13 +- pwd.c | 2 +- sysklogd/syslogd.c | 8 +- syslogd.c | 8 +- tail.c | 2 +- test.c | 12 +- util-linux/more.c | 4 +- utility.c | 6 +- 27 files changed, 681 insertions(+), 50 deletions(-) create mode 100644 ar.c create mode 100644 archival/ar.c diff --git a/AUTHORS b/AUTHORS index 30ef908da..14cd785cf 100644 --- a/AUTHORS +++ b/AUTHORS @@ -32,7 +32,10 @@ Daniel Jacobowitz mktemp.c John Lombardo - dirname, tr + dirname, tr + +Glenn McGrath + ar.c Bruce Perens Original author of BusyBox. His code is still in many apps. diff --git a/Changelog b/Changelog index 31003dc77..42a4cc7ca 100644 --- a/Changelog +++ b/Changelog @@ -39,6 +39,13 @@ * Changed the way init parses /etc/inittab entries to avoid problems with commands that contain colons in them. Fix thanks to Pavel Roskin + * Fixed a warning in utility.c due to char being unsigned on Linux/PPC, + Fix thanks to Pavel Roskin + * Made "killall" complain (not error and exit) about processes that it + cannot find by name. Fix thanks to Pavel Roskin + * Fixed more and ps to have sensible terminal width defaults, thanks + to Pavel Roskin. + * Fixed all fatalError() calls lacking a "\n", thanks to Pavel Roskin. * More doc updates diff --git a/Makefile b/Makefile index f1ca4a522..6471e3490 100644 --- a/Makefile +++ b/Makefile @@ -102,11 +102,10 @@ docs/BusyBox.1: docs/busybox.pod docs/BusyBox.html: docs/busybox.pod pod2html docs/busybox.pod > docs/busybox.lineo.com/BusyBox.html - ln -s busybox.lineo.com/BusyBox.html docs/BusyBox.html + - rm -f docs/BusyBox.html + - ln -s busybox.lineo.com/BusyBox.html docs/BusyBox.html - rm -f pod2html* -clean: - busybox: $(OBJECTS) $(CC) $(LDFLAGS) -o $@ $^ $(LIBRARIES) $(STRIP) diff --git a/TODO b/TODO index c1d6f01a6..e6cb94d4b 100644 --- a/TODO +++ b/TODO @@ -40,6 +40,8 @@ Bugs that need fixing: /tmp/file in the current directory, rather then trying and failing to create a symlink named "." in the current working directory). - implement 'ls -R'. + - "cp -a sourcedir/*" (note: no dest) - produces an odd error message about + the last file in the dir, rather than saying "missing destination file". ----------- diff --git a/applets/busybox.c b/applets/busybox.c index bf0591d66..9ee5d2e3a 100644 --- a/applets/busybox.c +++ b/applets/busybox.c @@ -32,6 +32,9 @@ void *__libc_stack_end; const struct BB_applet applets[] = { +#ifdef BB_AR + {"ar", ar_main, _BB_DIR_USR_BIN}, +#endif #ifdef BB_BASENAME {"basename", basename_main, _BB_DIR_USR_BIN}, #endif diff --git a/ar.c b/ar.c new file mode 100644 index 000000000..253f3348a --- /dev/null +++ b/ar.c @@ -0,0 +1,277 @@ +/* vi: set sw=4 ts=4: */ +/* + * Mini ar implementation for busybox + * + * Copyright (C) 2000 by Glenn McGrath + * Written by Glenn McGrath 1 June 2000 + * + * Based in part on BusyBox tar, Debian dpkg-deb and GNU ar. + * + * 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 +#include +#include +#include +#include "internal.h" + +#define AR_BLOCK_SIZE 60 +#define BB_DECLARE_EXTERN +#define bb_need_io_error +#include "messages.c" + +struct ArHeader { /* Byte Offset */ + char ar_name[16]; /* 0-15 */ + char ar_date[12]; /* 16-27 */ + char ar_uid[6], ar_gid[6]; /* 28-39 */ + char ar_mode[8]; /* 40-47 */ + char ar_size[10]; /* 48-57 */ + char ar_fmag[2]; /* 58-59 */ +}; +typedef struct ArHeader ArHeader; + +struct ArInfo { + char name[17]; /* File name */ + time_t date; /* long int, No of seconds since epoch */ + uid_t uid; /* unsigned int, Numeric UID */ + gid_t gid; /* unsigned int, Numeric GID */ + mode_t mode; /* unsigned int, Unix mode */ + size_t size; /* int, Size of the file */ +}; +typedef struct ArInfo ArInfo; + +static const char ar_usage[] = "ar [optxvV] archive [filenames] \n" +#ifndef BB_FEATURE_TRIVIAL_HELP + "\nExtract or list files from an ar archive.\n\n" + "Options:\n" + "\to\t\tpreserve original dates\n" + "\tp\t\textract to stdout\n" + "\tt\t\tlist\n" + "\tx\t\textract\n" + "\tv\t\tverbosely list files processed\n" +#endif + ; + +static void displayContents(struct ArInfo *entry, int funct) +{ + /* TODO convert mode to string */ + if ((funct & 2) == 2) + printf("%i %i/%i %6i %s ", entry->mode, entry->uid, entry->gid, + entry->size, timeString(entry->date)); + printf("%s\n", entry->name); +} + +/* Converts to new typed struct */ +static int readArHeader(struct ArHeader *rawHeader, struct ArInfo *header) +{ + int count2; + int count; + + for (count = 0; count < 16; count++) { + if (rawHeader->ar_name[count] == ' ') { + for (count2 = count; count2 < 16; count2++) + if (!isspace(rawHeader->ar_name[count2])) + break; + if (count2 >= 16) + break; + } + if (rawHeader->ar_name[count] == '/') + break; + header->name[count] = rawHeader->ar_name[count]; + } + header->name[count] = '\0'; + header->date = atoi(rawHeader->ar_date); + header->uid = atoi(rawHeader->ar_uid); + header->gid = atoi(rawHeader->ar_gid); + header->mode = atoi(rawHeader->ar_mode); + header->size = atoi(rawHeader->ar_size); + return (TRUE); +} + +/* + * Copy size bytes from current position if srcFd to current position in dstFd + * taken from tarExtractRegularFile in tar.c + * could be used for ar, tar and copyFile . + */ +static int copySubFile(int srcFd, int dstFd, int copySize) +{ + int readSize, writeSize, doneSize; + char buffer[BUFSIZ]; + + while (copySize > 0) { + if (copySize > BUFSIZ) + readSize = BUFSIZ; + else + readSize = copySize; + writeSize = fullRead(srcFd, buffer, readSize); + if (writeSize <= 0) { + errorMsg(io_error, "copySubFile :", strerror(errno)); + return (FALSE); + } + doneSize = fullWrite(dstFd, buffer, writeSize); + if (doneSize <= 0) { + errorMsg(io_error, "copySubFile :", strerror(errno)); + return (FALSE); + } + copySize -= doneSize; + } + return (TRUE); +} + +/* + * Need to add checks, stat newfile before creation,change mode from 0777 + * extract to current dir + * dstStat.st_size copied from current position of file pointed to by srcFd + */ +static int extractToFile(int srcFd, const char *path, const char *name, + int size) +{ + int dstFd, temp; + struct stat tmpStat; + char *pathname = NULL; + + if ((temp = isDirectory(path, TRUE, &tmpStat)) != TRUE) { + if (!createPath(path, 0777)) { + fatalError("Cannot extract to specified path"); + return (FALSE); + } + } + temp = (strlen(path) + 16); + pathname = (char *) xmalloc(temp); + pathname = strcpy(pathname, path); + pathname = strcat(pathname, &name[0]); + dstFd = device_open(pathname, O_WRONLY | O_CREAT); + pathname = NULL; + temp = copySubFile(srcFd, dstFd, size); + close(dstFd); + return (TRUE); +} + +/* Step through the ar file entries */ +static int readArFile(char **fileNames, int argc, int funct) +{ + int arFd = 0; + int pdates = 0; + int verbose = 0; + int display = 0; + int extract = 0; + int extToStdout = 0; + int status = 0; + int found = 0; + ArHeader rawArHeader; + ArInfo arEntry; + char arVersion[8]; + char *arName; + char *selName[argc - 2]; + int i; + + if ((funct & 1) == 1) + pdates = 1; + if ((funct & 2) == 2) + verbose = 1; + if ((funct & 4) == 4) + display = 1; + if ((funct & 16) == 16) { /* extract to stdout */ + extract = 1; + extToStdout = 1; + } + if ((funct & 8) == 8) { /* extract to file */ + extract = 1; + } + arName = fileNames[2]; + for (i = 0; i < (argc - 3); i++) + selName[i] = fileNames[i + 3]; + arFd = open(arName, O_RDONLY); + if (arFd < 0) { + errorMsg("Error opening '%s': %s\n", arName, strerror(errno)); + return (FALSE); + } + if (fullRead(arFd, arVersion, 8) <= 0) { + errorMsg("ar: Unexpected EOF in archive\n"); + return (FALSE); + } + if (strncmp(arVersion, "!", 7) != 0) { + errorMsg("ar header fails check "); + return (FALSE); + } + while ((status = fullRead(arFd, (char *) &rawArHeader, AR_BLOCK_SIZE)) + == AR_BLOCK_SIZE) { + readArHeader(&rawArHeader, &arEntry); + + if (display == 1) { + displayContents(&arEntry, funct); + } + if (argc == 3) + found = 1; + else { + found = 0; + for (i = 0; i < (argc - 3); i++) { + if ((status = (strcmp(selName[i], arEntry.name))) == 0) + found = 1; + } + } + if ((extract == 1) && (found == 1)) { + if (extToStdout == 1) { + copySubFile(arFd, fileno(stdout), arEntry.size); + } else { + extractToFile(arFd, "./", arEntry.name, arEntry.size); + } + } else + lseek(arFd, arEntry.size, SEEK_CUR); + } + return (0); +} + +extern int ar_main(int argc, char **argv) +{ + int ret = 0; + char *opt_ptr; + char c; + int funct = 0; + + if (argc < 2) + usage(ar_usage); + + opt_ptr = argv[1]; + if (*opt_ptr == '-') + ++opt_ptr; + while ((c = *opt_ptr++) != '\0') { + switch (c) { + case 'o': /* preserver original dates */ + funct = funct | 1; + break; + case 'p': /* extract to stdout */ + funct = funct | 16; + break; + case 't': /* display contents */ + funct = funct | 4; + break; + case 'x': /* extract contents of archive */ + funct = funct | 8; + break; + case 'v': /* be verbose */ + funct = funct | 2; + break; + default: + usage(ar_usage); + } + } + if (funct > 3) + ret = readArFile(argv, argc, funct); + return (ret); +} diff --git a/archival/ar.c b/archival/ar.c new file mode 100644 index 000000000..253f3348a --- /dev/null +++ b/archival/ar.c @@ -0,0 +1,277 @@ +/* vi: set sw=4 ts=4: */ +/* + * Mini ar implementation for busybox + * + * Copyright (C) 2000 by Glenn McGrath + * Written by Glenn McGrath 1 June 2000 + * + * Based in part on BusyBox tar, Debian dpkg-deb and GNU ar. + * + * 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 +#include +#include +#include +#include "internal.h" + +#define AR_BLOCK_SIZE 60 +#define BB_DECLARE_EXTERN +#define bb_need_io_error +#include "messages.c" + +struct ArHeader { /* Byte Offset */ + char ar_name[16]; /* 0-15 */ + char ar_date[12]; /* 16-27 */ + char ar_uid[6], ar_gid[6]; /* 28-39 */ + char ar_mode[8]; /* 40-47 */ + char ar_size[10]; /* 48-57 */ + char ar_fmag[2]; /* 58-59 */ +}; +typedef struct ArHeader ArHeader; + +struct ArInfo { + char name[17]; /* File name */ + time_t date; /* long int, No of seconds since epoch */ + uid_t uid; /* unsigned int, Numeric UID */ + gid_t gid; /* unsigned int, Numeric GID */ + mode_t mode; /* unsigned int, Unix mode */ + size_t size; /* int, Size of the file */ +}; +typedef struct ArInfo ArInfo; + +static const char ar_usage[] = "ar [optxvV] archive [filenames] \n" +#ifndef BB_FEATURE_TRIVIAL_HELP + "\nExtract or list files from an ar archive.\n\n" + "Options:\n" + "\to\t\tpreserve original dates\n" + "\tp\t\textract to stdout\n" + "\tt\t\tlist\n" + "\tx\t\textract\n" + "\tv\t\tverbosely list files processed\n" +#endif + ; + +static void displayContents(struct ArInfo *entry, int funct) +{ + /* TODO convert mode to string */ + if ((funct & 2) == 2) + printf("%i %i/%i %6i %s ", entry->mode, entry->uid, entry->gid, + entry->size, timeString(entry->date)); + printf("%s\n", entry->name); +} + +/* Converts to new typed struct */ +static int readArHeader(struct ArHeader *rawHeader, struct ArInfo *header) +{ + int count2; + int count; + + for (count = 0; count < 16; count++) { + if (rawHeader->ar_name[count] == ' ') { + for (count2 = count; count2 < 16; count2++) + if (!isspace(rawHeader->ar_name[count2])) + break; + if (count2 >= 16) + break; + } + if (rawHeader->ar_name[count] == '/') + break; + header->name[count] = rawHeader->ar_name[count]; + } + header->name[count] = '\0'; + header->date = atoi(rawHeader->ar_date); + header->uid = atoi(rawHeader->ar_uid); + header->gid = atoi(rawHeader->ar_gid); + header->mode = atoi(rawHeader->ar_mode); + header->size = atoi(rawHeader->ar_size); + return (TRUE); +} + +/* + * Copy size bytes from current position if srcFd to current position in dstFd + * taken from tarExtractRegularFile in tar.c + * could be used for ar, tar and copyFile . + */ +static int copySubFile(int srcFd, int dstFd, int copySize) +{ + int readSize, writeSize, doneSize; + char buffer[BUFSIZ]; + + while (copySize > 0) { + if (copySize > BUFSIZ) + readSize = BUFSIZ; + else + readSize = copySize; + writeSize = fullRead(srcFd, buffer, readSize); + if (writeSize <= 0) { + errorMsg(io_error, "copySubFile :", strerror(errno)); + return (FALSE); + } + doneSize = fullWrite(dstFd, buffer, writeSize); + if (doneSize <= 0) { + errorMsg(io_error, "copySubFile :", strerror(errno)); + return (FALSE); + } + copySize -= doneSize; + } + return (TRUE); +} + +/* + * Need to add checks, stat newfile before creation,change mode from 0777 + * extract to current dir + * dstStat.st_size copied from current position of file pointed to by srcFd + */ +static int extractToFile(int srcFd, const char *path, const char *name, + int size) +{ + int dstFd, temp; + struct stat tmpStat; + char *pathname = NULL; + + if ((temp = isDirectory(path, TRUE, &tmpStat)) != TRUE) { + if (!createPath(path, 0777)) { + fatalError("Cannot extract to specified path"); + return (FALSE); + } + } + temp = (strlen(path) + 16); + pathname = (char *) xmalloc(temp); + pathname = strcpy(pathname, path); + pathname = strcat(pathname, &name[0]); + dstFd = device_open(pathname, O_WRONLY | O_CREAT); + pathname = NULL; + temp = copySubFile(srcFd, dstFd, size); + close(dstFd); + return (TRUE); +} + +/* Step through the ar file entries */ +static int readArFile(char **fileNames, int argc, int funct) +{ + int arFd = 0; + int pdates = 0; + int verbose = 0; + int display = 0; + int extract = 0; + int extToStdout = 0; + int status = 0; + int found = 0; + ArHeader rawArHeader; + ArInfo arEntry; + char arVersion[8]; + char *arName; + char *selName[argc - 2]; + int i; + + if ((funct & 1) == 1) + pdates = 1; + if ((funct & 2) == 2) + verbose = 1; + if ((funct & 4) == 4) + display = 1; + if ((funct & 16) == 16) { /* extract to stdout */ + extract = 1; + extToStdout = 1; + } + if ((funct & 8) == 8) { /* extract to file */ + extract = 1; + } + arName = fileNames[2]; + for (i = 0; i < (argc - 3); i++) + selName[i] = fileNames[i + 3]; + arFd = open(arName, O_RDONLY); + if (arFd < 0) { + errorMsg("Error opening '%s': %s\n", arName, strerror(errno)); + return (FALSE); + } + if (fullRead(arFd, arVersion, 8) <= 0) { + errorMsg("ar: Unexpected EOF in archive\n"); + return (FALSE); + } + if (strncmp(arVersion, "!", 7) != 0) { + errorMsg("ar header fails check "); + return (FALSE); + } + while ((status = fullRead(arFd, (char *) &rawArHeader, AR_BLOCK_SIZE)) + == AR_BLOCK_SIZE) { + readArHeader(&rawArHeader, &arEntry); + + if (display == 1) { + displayContents(&arEntry, funct); + } + if (argc == 3) + found = 1; + else { + found = 0; + for (i = 0; i < (argc - 3); i++) { + if ((status = (strcmp(selName[i], arEntry.name))) == 0) + found = 1; + } + } + if ((extract == 1) && (found == 1)) { + if (extToStdout == 1) { + copySubFile(arFd, fileno(stdout), arEntry.size); + } else { + extractToFile(arFd, "./", arEntry.name, arEntry.size); + } + } else + lseek(arFd, arEntry.size, SEEK_CUR); + } + return (0); +} + +extern int ar_main(int argc, char **argv) +{ + int ret = 0; + char *opt_ptr; + char c; + int funct = 0; + + if (argc < 2) + usage(ar_usage); + + opt_ptr = argv[1]; + if (*opt_ptr == '-') + ++opt_ptr; + while ((c = *opt_ptr++) != '\0') { + switch (c) { + case 'o': /* preserver original dates */ + funct = funct | 1; + break; + case 'p': /* extract to stdout */ + funct = funct | 16; + break; + case 't': /* display contents */ + funct = funct | 4; + break; + case 'x': /* extract contents of archive */ + funct = funct | 8; + break; + case 'v': /* be verbose */ + funct = funct | 2; + break; + default: + usage(ar_usage); + } + } + if (funct > 3) + ret = readArFile(argv, argc, funct); + return (ret); +} diff --git a/busybox.c b/busybox.c index bf0591d66..9ee5d2e3a 100644 --- a/busybox.c +++ b/busybox.c @@ -32,6 +32,9 @@ void *__libc_stack_end; const struct BB_applet applets[] = { +#ifdef BB_AR + {"ar", ar_main, _BB_DIR_USR_BIN}, +#endif #ifdef BB_BASENAME {"basename", basename_main, _BB_DIR_USR_BIN}, #endif diff --git a/busybox.def.h b/busybox.def.h index ea17a3982..42a63d8ee 100644 --- a/busybox.def.h +++ b/busybox.def.h @@ -7,6 +7,7 @@ // // // BusyBox Applications +#define BB_AR #define BB_BASENAME #define BB_CAT #define BB_CHMOD_CHOWN_CHGRP diff --git a/coreutils/pwd.c b/coreutils/pwd.c index 19494a96c..146ef332b 100644 --- a/coreutils/pwd.c +++ b/coreutils/pwd.c @@ -31,7 +31,7 @@ extern int pwd_main(int argc, char **argv) char buf[BUFSIZ + 1]; if (getcwd(buf, sizeof(buf)) == NULL) - fatalError("pwd: %s", strerror(errno)); + fatalError("pwd: %s\n", strerror(errno)); printf("%s\n", buf); exit(TRUE); diff --git a/coreutils/tail.c b/coreutils/tail.c index 3b3e2f56c..2027d921d 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c @@ -336,7 +336,7 @@ static int tail_file(const char *filename, off_t n_units) /* Not standard input. */ fd = open(filename, O_RDONLY); if (fd == -1) - fatalError("open error"); + perror(filename); errors = tail_lines(filename, fd, (long) n_units); close(fd); diff --git a/coreutils/test.c b/coreutils/test.c index 9b541e33e..0a16e9328 100644 --- a/coreutils/test.c +++ b/coreutils/test.c @@ -185,7 +185,7 @@ test_main(int argc, char** argv) if (strcmp(argv[0], "[") == 0) { if (strcmp(argv[--argc], "]")) - fatalError("missing ]"); + fatalError("missing ]\n"); argv[argc] = NULL; } if (strcmp(argv[1], dash_dash_help) == 0) { @@ -244,9 +244,9 @@ syntax(op, msg) char *msg; { if (op && *op) - fatalError("%s: %s", op, msg); + fatalError("%s: %s\n", op, msg); else - fatalError("%s", msg); + fatalError("%s\n", msg); } static int @@ -481,13 +481,13 @@ getn(s) r = strtol(s, &p, 10); if (errno != 0) - fatalError("%s: out of range", s); + fatalError("%s: out of range\n", s); while (isspace(*p)) p++; if (*p) - fatalError("%s: bad number", s); + fatalError("%s: bad number\n", s); return (int) r; } @@ -567,7 +567,7 @@ initialize_group_array () { ngroups = getgroups(0, NULL); if ((group_array = realloc(group_array, ngroups * sizeof(gid_t))) == NULL) - fatalError("Out of space"); + fatalError("Out of space\n"); getgroups(ngroups, group_array); } diff --git a/docs/busybox.net/BusyBox.html b/docs/busybox.net/BusyBox.html index 0741c013b..86c819198 100644 --- a/docs/busybox.net/BusyBox.html +++ b/docs/busybox.net/BusyBox.html @@ -100,8 +100,8 @@ Most BusyBox commands support the --help option to provide a te Currently defined functions include:

-basename, cat, chgrp, chmod, chown, chroot, clear, chvt, cp, cut, date, dd, -df, dirname, dmesg, du, dutmp, echo, false, fbset, fdflush, find, free, +ar, basename, cat, chgrp, chmod, chown, chroot, clear, chvt, cp, cut, date, +dd, df, dirname, dmesg, du, dutmp, echo, false, fbset, fdflush, find, free, freeramdisk, deallocvt, fsck.minix, grep, gunzip, gzip, halt, head, hostid, hostname, id, init, kill, killall, length, ln, loadacm, loadfont, loadkmap, logger, logname, ls, lsmod, makedevs, math, mkdir, mkfifo, mkfs.minix, @@ -115,6 +115,26 @@ yes, zcat, [ -------------------------------

+
ar
+

+Usage: ar [optxvV] archive [filenames] + +

+Extract or list files from an ar archive. + +

+Options: + +

+

        o               preserve original dates
+        p               extract to stdout
+        t               list
+        x               extract
+        v               verbosely list files processed
+
+

+------------------------------- +

basename

Usage: basename FILE [SUFFIX] @@ -2432,6 +2452,12 @@ HREF="mailto:john@deltanet.com">john@deltanet.com>
+

+Glenn McGrath <bug1@netconnect.com.au> + +
+

Bruce Perens <bruce@perens.com> diff --git a/docs/busybox.pod b/docs/busybox.pod index e8b5a9ed9..5b9205b60 100644 --- a/docs/busybox.pod +++ b/docs/busybox.pod @@ -55,8 +55,8 @@ terse runtime description of their behavior. Currently defined functions include: -basename, cat, chgrp, chmod, chown, chroot, clear, chvt, cp, cut, date, dd, df, -dirname, dmesg, du, dutmp, echo, false, fbset, fdflush, find, free, +ar, basename, cat, chgrp, chmod, chown, chroot, clear, chvt, cp, cut, date, dd, +df, dirname, dmesg, du, dutmp, echo, false, fbset, fdflush, find, free, freeramdisk, deallocvt, fsck.minix, grep, gunzip, gzip, halt, head, hostid, hostname, id, init, kill, killall, length, ln, loadacm, loadfont, loadkmap, logger, logname, ls, lsmod, makedevs, math, mkdir, mkfifo, mkfs.minix, mknod, @@ -69,6 +69,22 @@ uname, uniq, update, uptime, usleep, wc, whoami, yes, zcat, [ =over 4 +=item ar + +Usage: ar [optxvV] archive [filenames] + +Extract or list files from an ar archive. + +Options: + + o preserve original dates + p extract to stdout + t list + x extract + v verbosely list files processed + +------------------------------- + =item basename Usage: basename FILE [SUFFIX] @@ -1904,6 +1920,10 @@ John Lombardo =for html
+Glenn McGrath + +=for html
+ Bruce Perens =for html
@@ -1926,4 +1946,4 @@ Enrique Zanardi =cut -# $Id: busybox.pod,v 1.32 2000/06/02 03:30:50 andersen Exp $ +# $Id: busybox.pod,v 1.33 2000/06/02 03:21:37 andersen Exp $ diff --git a/internal.h b/internal.h index 909bf6473..26248621e 100644 --- a/internal.h +++ b/internal.h @@ -98,6 +98,7 @@ struct BB_applet { /* From busybox.c */ extern const struct BB_applet applets[]; +extern int ar_main(int argc, char **argv); extern int basename_main(int argc, char **argv); extern int busybox_main(int argc, char** argv); extern int block_device_main(int argc, char** argv); diff --git a/kill.c b/kill.c index 0487f6a66..1f1bee48b 100644 --- a/kill.c +++ b/kill.c @@ -234,6 +234,9 @@ extern int kill_main(int argc, char **argv) pid_t* pidList; pidList = findPidByName( *argv); + if (!pidList) + errorMsg( "%s: no process killed\n", *argv); + for(; pidList && *pidList!=0; pidList++) { if (*pidList==myPid) continue; diff --git a/more.c b/more.c index 50446861e..974149177 100644 --- a/more.c +++ b/more.c @@ -74,9 +74,9 @@ void gotsig(int sig) #if defined BB_FEATURE_AUTOWIDTH #ifdef BB_FEATURE_USE_TERMIOS -static int terminal_width = 0; +static int terminal_width = TERMINAL_WIDTH; #endif -static int terminal_height = 0; +static int terminal_height = TERMINAL_HEIGHT; #else #define terminal_width TERMINAL_WIDTH #define terminal_height TERMINAL_HEIGHT diff --git a/procps/kill.c b/procps/kill.c index 0487f6a66..1f1bee48b 100644 --- a/procps/kill.c +++ b/procps/kill.c @@ -234,6 +234,9 @@ extern int kill_main(int argc, char **argv) pid_t* pidList; pidList = findPidByName( *argv); + if (!pidList) + errorMsg( "%s: no process killed\n", *argv); + for(; pidList && *pidList!=0; pidList++) { if (*pidList==myPid) continue; diff --git a/procps/ps.c b/procps/ps.c index 0842a22c2..41b8465bd 100644 --- a/procps/ps.c +++ b/procps/ps.c @@ -40,6 +40,9 @@ #define bb_need_help #include "messages.c" +#define TERMINAL_WIDTH 79 /* not 80 in case terminal has linefold bug */ + + #if ! defined BB_FEATURE_USE_DEVPS_PATCH @@ -124,9 +127,9 @@ extern int ps_main(int argc, char **argv) int len, i, c; #ifdef BB_FEATURE_AUTOWIDTH struct winsize win = { 0, 0 }; - int terminal_width = 0; + int terminal_width = TERMINAL_WIDTH; #else -#define terminal_width 79 +#define terminal_width TERMINAL_WIDTH #endif @@ -142,7 +145,7 @@ extern int ps_main(int argc, char **argv) dir = opendir("/proc"); if (!dir) - fatalError("Can't open /proc"); + fatalError("Can't open /proc\n"); #ifdef BB_FEATURE_AUTOWIDTH ioctl(fileno(stdout), TIOCGWINSZ, &win); @@ -214,9 +217,9 @@ extern int ps_main(int argc, char **argv) char groupName[10] = ""; #ifdef BB_FEATURE_AUTOWIDTH struct winsize win = { 0, 0 }; - int terminal_width = 0; + int terminal_width = TERMINAL_WIDTH; #else -#define terminal_width 79 +#define terminal_width TERMINAL_WIDTH #endif if (argc > 1 && **(argv + 1) == '-') diff --git a/ps.c b/ps.c index 0842a22c2..41b8465bd 100644 --- a/ps.c +++ b/ps.c @@ -40,6 +40,9 @@ #define bb_need_help #include "messages.c" +#define TERMINAL_WIDTH 79 /* not 80 in case terminal has linefold bug */ + + #if ! defined BB_FEATURE_USE_DEVPS_PATCH @@ -124,9 +127,9 @@ extern int ps_main(int argc, char **argv) int len, i, c; #ifdef BB_FEATURE_AUTOWIDTH struct winsize win = { 0, 0 }; - int terminal_width = 0; + int terminal_width = TERMINAL_WIDTH; #else -#define terminal_width 79 +#define terminal_width TERMINAL_WIDTH #endif @@ -142,7 +145,7 @@ extern int ps_main(int argc, char **argv) dir = opendir("/proc"); if (!dir) - fatalError("Can't open /proc"); + fatalError("Can't open /proc\n"); #ifdef BB_FEATURE_AUTOWIDTH ioctl(fileno(stdout), TIOCGWINSZ, &win); @@ -214,9 +217,9 @@ extern int ps_main(int argc, char **argv) char groupName[10] = ""; #ifdef BB_FEATURE_AUTOWIDTH struct winsize win = { 0, 0 }; - int terminal_width = 0; + int terminal_width = TERMINAL_WIDTH; #else -#define terminal_width 79 +#define terminal_width TERMINAL_WIDTH #endif if (argc > 1 && **(argv + 1) == '-') diff --git a/pwd.c b/pwd.c index 19494a96c..146ef332b 100644 --- a/pwd.c +++ b/pwd.c @@ -31,7 +31,7 @@ extern int pwd_main(int argc, char **argv) char buf[BUFSIZ + 1]; if (getcwd(buf, sizeof(buf)) == NULL) - fatalError("pwd: %s", strerror(errno)); + fatalError("pwd: %s\n", strerror(errno)); printf("%s\n", buf); exit(TRUE); diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index faa6f15e9..9a4af4926 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -194,7 +194,7 @@ static void doSyslogd (void) /* Create the syslog file so realpath() can work. */ close (open (_PATH_LOG, O_RDWR | O_CREAT, 0644)); if (realpath (_PATH_LOG, lfile) == NULL) - fatalError ("Could not resolv path to " _PATH_LOG ": %s", strerror (errno)); + fatalError ("Could not resolv path to " _PATH_LOG ": %s\n", strerror (errno)); unlink (lfile); @@ -202,14 +202,14 @@ static void doSyslogd (void) sunx.sun_family = AF_UNIX; strncpy (sunx.sun_path, lfile, sizeof (sunx.sun_path)); if ((sock_fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) - fatalError ("Couldn't obtain descriptor for socket " _PATH_LOG ": %s", strerror (errno)); + fatalError ("Couldn't obtain descriptor for socket " _PATH_LOG ": %s\n", strerror (errno)); addrLength = sizeof (sunx.sun_family) + strlen (sunx.sun_path); if ((bind (sock_fd, (struct sockaddr *) &sunx, addrLength)) || (listen (sock_fd, 5))) - fatalError ("Could not connect to socket " _PATH_LOG ": %s", strerror (errno)); + fatalError ("Could not connect to socket " _PATH_LOG ": %s\n", strerror (errno)); if (chmod (lfile, 0666) < 0) - fatalError ("Could not set permission on " _PATH_LOG ": %s", strerror (errno)); + fatalError ("Could not set permission on " _PATH_LOG ": %s\n", strerror (errno)); FD_ZERO (&fds); FD_SET (sock_fd, &fds); diff --git a/syslogd.c b/syslogd.c index faa6f15e9..9a4af4926 100644 --- a/syslogd.c +++ b/syslogd.c @@ -194,7 +194,7 @@ static void doSyslogd (void) /* Create the syslog file so realpath() can work. */ close (open (_PATH_LOG, O_RDWR | O_CREAT, 0644)); if (realpath (_PATH_LOG, lfile) == NULL) - fatalError ("Could not resolv path to " _PATH_LOG ": %s", strerror (errno)); + fatalError ("Could not resolv path to " _PATH_LOG ": %s\n", strerror (errno)); unlink (lfile); @@ -202,14 +202,14 @@ static void doSyslogd (void) sunx.sun_family = AF_UNIX; strncpy (sunx.sun_path, lfile, sizeof (sunx.sun_path)); if ((sock_fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) - fatalError ("Couldn't obtain descriptor for socket " _PATH_LOG ": %s", strerror (errno)); + fatalError ("Couldn't obtain descriptor for socket " _PATH_LOG ": %s\n", strerror (errno)); addrLength = sizeof (sunx.sun_family) + strlen (sunx.sun_path); if ((bind (sock_fd, (struct sockaddr *) &sunx, addrLength)) || (listen (sock_fd, 5))) - fatalError ("Could not connect to socket " _PATH_LOG ": %s", strerror (errno)); + fatalError ("Could not connect to socket " _PATH_LOG ": %s\n", strerror (errno)); if (chmod (lfile, 0666) < 0) - fatalError ("Could not set permission on " _PATH_LOG ": %s", strerror (errno)); + fatalError ("Could not set permission on " _PATH_LOG ": %s\n", strerror (errno)); FD_ZERO (&fds); FD_SET (sock_fd, &fds); diff --git a/tail.c b/tail.c index 3b3e2f56c..2027d921d 100644 --- a/tail.c +++ b/tail.c @@ -336,7 +336,7 @@ static int tail_file(const char *filename, off_t n_units) /* Not standard input. */ fd = open(filename, O_RDONLY); if (fd == -1) - fatalError("open error"); + perror(filename); errors = tail_lines(filename, fd, (long) n_units); close(fd); diff --git a/test.c b/test.c index 9b541e33e..0a16e9328 100644 --- a/test.c +++ b/test.c @@ -185,7 +185,7 @@ test_main(int argc, char** argv) if (strcmp(argv[0], "[") == 0) { if (strcmp(argv[--argc], "]")) - fatalError("missing ]"); + fatalError("missing ]\n"); argv[argc] = NULL; } if (strcmp(argv[1], dash_dash_help) == 0) { @@ -244,9 +244,9 @@ syntax(op, msg) char *msg; { if (op && *op) - fatalError("%s: %s", op, msg); + fatalError("%s: %s\n", op, msg); else - fatalError("%s", msg); + fatalError("%s\n", msg); } static int @@ -481,13 +481,13 @@ getn(s) r = strtol(s, &p, 10); if (errno != 0) - fatalError("%s: out of range", s); + fatalError("%s: out of range\n", s); while (isspace(*p)) p++; if (*p) - fatalError("%s: bad number", s); + fatalError("%s: bad number\n", s); return (int) r; } @@ -567,7 +567,7 @@ initialize_group_array () { ngroups = getgroups(0, NULL); if ((group_array = realloc(group_array, ngroups * sizeof(gid_t))) == NULL) - fatalError("Out of space"); + fatalError("Out of space\n"); getgroups(ngroups, group_array); } diff --git a/util-linux/more.c b/util-linux/more.c index 50446861e..974149177 100644 --- a/util-linux/more.c +++ b/util-linux/more.c @@ -74,9 +74,9 @@ void gotsig(int sig) #if defined BB_FEATURE_AUTOWIDTH #ifdef BB_FEATURE_USE_TERMIOS -static int terminal_width = 0; +static int terminal_width = TERMINAL_WIDTH; #endif -static int terminal_height = 0; +static int terminal_height = TERMINAL_HEIGHT; #else #define terminal_width TERMINAL_WIDTH #define terminal_height TERMINAL_HEIGHT diff --git a/utility.c b/utility.c index 07e540e22..68bdc3197 100644 --- a/utility.c +++ b/utility.c @@ -1583,12 +1583,12 @@ cstring_alloc(FILE* f, int depth) char *cstring; char buffer[CSTRING_BUFFER_LENGTH]; int target = CSTRING_BUFFER_LENGTH * depth; - int i, len; - int size; + int c, i, len, size; /* fill buffer */ i = 0; - while ((buffer[i] = fgetc(f)) != EOF) { + while ((c = fgetc(f)) != EOF) { + buffer[i] = (char) c; if (buffer[i++] == 0x0a) { break; } if (i == CSTRING_BUFFER_LENGTH) { break; } }