- pull from busybox_scratch: r15829:15850

Various fixes, cleanups and shrinkage:
saves 952 Bytes:
   text    data     bss     dec     hex filename
1087742   15853  790632 1894227  1ce753 ../busybox/busybox.old
1086790   15853  790632 1893275  1ce39b busybox
via:
# scripts/bloat-o-meter ../busybox/busybox_unstripped.old busybox_unstripped 
function                                             old     new   delta
ipcrm_main                                           756     822     +66
getval                                                 -      61     +61
maybe_set_utc                                          -      40     +40
udhcpc_main                                         2896    2912     +16
md5_hash_block                                       428     437      +9
opt                                                    8      16      +8
qgravechar                                           106     110      +4
make_bitmap                                          292     295      +3
inflate_unzip                                       2056    2059      +3
add_partition                                       1412    1414      +2
__parsespent                                         156     158      +2
qrealloc                                              41      42      +1
format                                                 -       1      +1
catv_main                                            313     314      +1
watch_main                                           293     292      -1
varunset                                              81      80      -1
part                                                   1       -      -1
check_if_skip                                        837     836      -1
start_stop_daemon_main                               840     837      -3
create_lost_and_found                                175     172      -3
supress_non_delimited_lines                            4       -      -4
static.l                                               4       -      -4
static.c                                               5       1      -4
bsd_sum_file                                         237     233      -4
eval2                                                338     332      -6
arithmetic_common                                    166     158      -8
cmpfunc                                               22       5     -17
cksum_main                                           294     275     -19
cmp_main                                             465     439     -26
dd_main                                             1535    1508     -27
rmmod_main                                           376     333     -43
cut_file                                             727     644     -83
ipcs_main                                           3809    3721     -88
cut_main                                             722     614    -108
date_main                                           1443    1263    -180
remove_ids                                           222       -    -222
------------------------------------------------------------------------------
(add/remove: 3/4 grow/shrink: 11/18 up/down: 217/-853)       Total: -636 bytes
This commit is contained in:
Bernhard Reutner-Fischer 2006-08-28 23:31:54 +00:00
parent 6ce8dae1d5
commit 73561cc75a
20 changed files with 1164 additions and 1285 deletions

View File

@ -278,6 +278,7 @@ endif # CONFIG_FEATURE_FULL_LIBBUSYBOX
APPLET_SRC:=$(APPLET_SRC-y)
APPLETS_DEFINE:=$(APPLETS_DEFINE-y)
else # CONFIG_BUILD_AT_ONCE
APPLET_SRC:=
# no --combine, build archives out of the individual .o
# This was the old way the binary was built.
libbusybox-obj:=archival/libunarchive/libunarchive.a \

View File

@ -14,49 +14,55 @@
int catv_main(int argc, char **argv)
{
int retval = EXIT_SUCCESS, fd, flags;
int retval = EXIT_SUCCESS, fd;
unsigned long flags;
flags = bb_getopt_ulflags(argc, argv, "etv");
flags ^= 4;
// Loop through files.
#define CATV_OPT_e (1<<0)
#define CATV_OPT_t (1<<1)
#define CATV_OPT_v (1<<2)
flags ^= CATV_OPT_v;
argv += optind;
do {
// Read from stdin if there's nothing else to do.
/* Read from stdin if there's nothing else to do. */
fd = 0;
if (*argv && 0>(fd = xopen(*argv, O_RDONLY))) retval = EXIT_FAILURE;
if (*argv && 0 > (fd = xopen(*argv, O_RDONLY)))
retval = EXIT_FAILURE;
else for (;;) {
int i, res;
res = read(fd, bb_common_bufsiz1, sizeof(bb_common_bufsiz1));
if (res < 0) retval = EXIT_FAILURE;
if (res <1) break;
if (res < 0)
retval = EXIT_FAILURE;
if (res < 1)
break;
for (i = 0; i < res; i++) {
char c = bb_common_bufsiz1[i];
if (c > 126 && (flags & 4)) {
if (c > 126 && (flags & CATV_OPT_v)) {
if (c == 127) {
printf("^?");
bb_printf("^?");
continue;
} else {
printf("M-");
bb_printf("M-");
c -= 128;
}
}
if (c < 32) {
if (c == 10) {
if (flags & 1) putchar('$');
} else if (flags & (c==9 ? 2 : 4)) {
printf("^%c", c+'@');
if (flags & CATV_OPT_e)
putchar('$');
} else if (flags & (c==9 ? CATV_OPT_t : CATV_OPT_v)) {
bb_printf("^%c", c+'@');
continue;
}
}
putchar(c);
}
}
if (ENABLE_FEATURE_CLEAN_UP && fd) close(fd);
if (ENABLE_FEATURE_CLEAN_UP && fd)
close(fd);
} while (*++argv);
return retval;

View File

@ -8,7 +8,8 @@
#include "busybox.h"
int cksum_main(int argc, char **argv) {
int cksum_main(int argc, char **argv)
{
uint32_t *crc32_table = crc32_filltable(1);
@ -17,7 +18,7 @@ int cksum_main(int argc, char **argv) {
long length, filesize;
int bytes_read;
char *cp;
RESERVE_CONFIG_BUFFER(buf, BUFSIZ);
int inp_stdin = (argc == optind) ? 1 : 0;
do {
@ -26,8 +27,8 @@ int cksum_main(int argc, char **argv) {
crc = 0;
length = 0;
while ((bytes_read = fread(buf, 1, BUFSIZ, fp)) > 0) {
cp = buf;
while ((bytes_read = fread(bb_common_bufsiz1, 1, BUFSIZ, fp)) > 0) {
cp = bb_common_bufsiz1;
length += bytes_read;
while (bytes_read--)
crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL];
@ -40,11 +41,11 @@ int cksum_main(int argc, char **argv) {
crc ^= 0xffffffffL;
if (inp_stdin) {
printf("%"PRIu32" %li\n", crc, filesize);
bb_printf("%" PRIu32 " %li\n", crc, filesize);
break;
}
printf("%"PRIu32" %li %s\n", crc, filesize, *argv);
bb_printf("%" PRIu32 " %li %s\n", crc, filesize, *argv);
fclose(fp);
} while (*(argv + 1));

View File

@ -23,7 +23,7 @@
#include "busybox.h"
static FILE *cmp_xfopen_input(const char *filename)
static FILE *cmp_xfopen_input(const char * const filename)
{
FILE *fp;
@ -40,32 +40,28 @@ static const char fmt_differ[] = "%s %s differ: char %d, line %d\n";
static const char fmt_l_opt[] = "%.0s%.0s%d %3o %3o\n";
static const char opt_chars[] = "sl";
enum {
OPT_s = 1,
OPT_l = 2
};
#define CMP_OPT_s (1<<0)
#define CMP_OPT_l (1<<1)
int cmp_main(int argc, char **argv)
{
FILE *fp1, *fp2, *outfile = stdout;
const char *filename1, *filename2;
const char *filename1, *filename2 = "-";
const char *fmt;
int c1, c2, char_pos, line_pos;
int opt_flags;
int exit_val = 0;
int c1, c2, char_pos = 0, line_pos = 1;
unsigned opt;
int retval = 0;
bb_default_error_retval = 2; /* 1 is returned if files are different. */
opt_flags = bb_getopt_ulflags(argc, argv, opt_chars);
opt = bb_getopt_ulflags(argc, argv, opt_chars);
if ((opt_flags == 3) || (((unsigned int)(--argc - optind)) > 1)) {
if ((opt & (CMP_OPT_s|CMP_OPT_l))
|| (((unsigned int)(--argc - optind)) > 1))
bb_show_usage();
}
fp1 = cmp_xfopen_input(filename1 = *(argv += optind));
filename2 = "-";
if (*++argv) {
filename2 = *argv;
}
@ -79,19 +75,17 @@ int cmp_main(int argc, char **argv)
return 0;
}
fmt = fmt_differ;
if (opt_flags == OPT_l) {
if (opt & CMP_OPT_l)
fmt = fmt_l_opt;
}
else
fmt = fmt_differ;
char_pos = 0;
line_pos = 1;
do {
c1 = getc(fp1);
c2 = getc(fp2);
++char_pos;
if (c1 != c2) { /* Remember -- a read error may have occurred. */
exit_val = 1; /* But assume the files are different for now. */
if (c1 != c2) { /* Remember: a read error may have occurred. */
retval = 1; /* But assume the files are different for now. */
if (c2 == EOF) {
/* We know that fp1 isn't at EOF or in an error state. But to
* save space below, things are setup to expect an EOF in fp1
@ -109,13 +103,14 @@ int cmp_main(int argc, char **argv)
* make sure we fflush before writing to stderr. */
xfflush_stdout();
}
if (opt_flags != OPT_s) {
if (opt_flags == OPT_l) {
if (!opt & CMP_OPT_s) {
if (opt & CMP_OPT_l) {
line_pos = c1; /* line_pos is unused in the -l case. */
}
bb_fprintf(outfile, fmt, filename1, filename2, char_pos, line_pos, c2);
if (opt_flags) { /* This must be -l since not -s. */
/* If we encountered and EOF, the while check will catch it. */
if (opt) { /* This must be -l since not -s. */
/* If we encountered an EOF,
* the while check will catch it. */
continue;
}
}
@ -129,5 +124,5 @@ int cmp_main(int argc, char **argv)
xferror(fp1, filename1);
xferror(fp2, filename2);
bb_fflush_stdout_and_exit(exit_val);
bb_fflush_stdout_and_exit(retval);
}

View File

@ -4,27 +4,23 @@
*
* Copyright (C) 1999,2000,2001 by Lineo, inc.
* Written by Mark Whitley <markw@codepoet.org>
* debloated by Bernhard Fischer
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include "busybox.h"
/* option vars */
static const char optstring[] = "b:c:f:d:sn";
#define OPT_BYTE_FLGS 1
#define OPT_CHAR_FLGS 2
#define OPT_FIELDS_FLGS 4
#define OPT_DELIM_FLGS 8
#define OPT_SUPRESS_FLGS 16
static char part; /* (b)yte, (c)har, (f)ields */
static unsigned int supress_non_delimited_lines;
static const char *const optstring = "b:c:f:d:sn";
#define CUT_OPT_BYTE_FLGS (1<<0)
#define CUT_OPT_CHAR_FLGS (1<<1)
#define CUT_OPT_FIELDS_FLGS (1<<2)
#define CUT_OPT_DELIM_FLGS (1<<3)
#define CUT_OPT_SUPPRESS_FLGS (1<<4)
static unsigned long opt;
static char delim = '\t'; /* delimiter, default is tab */
struct cut_list {
@ -38,37 +34,191 @@ enum {
NON_RANGE = -1
};
static struct cut_list *cut_lists = NULL; /* growable array holding a series of lists */
static unsigned int nlists = 0; /* number of elements in above list */
/* growable array holding a series of lists */
static struct cut_list *cut_lists;
static unsigned int nlists; /* number of elements in above list */
static int cmpfunc(const void *a, const void *b)
{
struct cut_list *la = (struct cut_list *)a;
struct cut_list *lb = (struct cut_list *)b;
return (((struct cut_list *) a)->startpos -
((struct cut_list *) b)->startpos);
if (la->startpos > lb->startpos)
return 1;
if (la->startpos < lb->startpos)
return -1;
return 0;
}
static void cut_file(FILE * file)
{
char *line = NULL;
unsigned int linenum = 0; /* keep these zero-based to be consistent */
/* go through every line in the file */
while ((line = bb_get_chomped_line_from_file(file)) != NULL) {
/* set up a list so we can keep track of what's been printed */
char * printed = xzalloc(strlen(line) * sizeof(char));
char * orig_line = line;
unsigned int cl_pos = 0;
int spos;
/* cut based on chars/bytes XXX: only works when sizeof(char) == byte */
if ((opt & (CUT_OPT_CHAR_FLGS | CUT_OPT_BYTE_FLGS))) {
/* print the chars specified in each cut list */
for (; cl_pos < nlists; cl_pos++) {
spos = cut_lists[cl_pos].startpos;
while (spos < strlen(line)) {
if (!printed[spos]) {
printed[spos] = 'X';
putchar(line[spos]);
}
spos++;
if (spos > cut_lists[cl_pos].endpos
|| cut_lists[cl_pos].endpos == NON_RANGE)
break;
}
}
} else if (delim == '\n') { /* cut by lines */
spos = cut_lists[cl_pos].startpos;
/* get out if we have no more lists to process or if the lines
* are lower than what we're interested in */
if (linenum < spos || cl_pos >= nlists)
goto next_line;
/* if the line we're looking for is lower than the one we were
* passed, it means we displayed it already, so move on */
while (spos < linenum) {
spos++;
/* go to the next list if we're at the end of this one */
if (spos > cut_lists[cl_pos].endpos
|| cut_lists[cl_pos].endpos == NON_RANGE) {
cl_pos++;
/* get out if there's no more lists to process */
if (cl_pos >= nlists)
goto next_line;
spos = cut_lists[cl_pos].startpos;
/* get out if the current line is lower than the one
* we just became interested in */
if (linenum < spos)
goto next_line;
}
}
/* If we made it here, it means we've found the line we're
* looking for, so print it */
puts(line);
goto next_line;
} else { /* cut by fields */
int ndelim = -1; /* zero-based / one-based problem */
int nfields_printed = 0;
char *field = NULL;
const char delimiter[2] = { delim, 0 };
/* does this line contain any delimiters? */
if (strchr(line, delim) == NULL) {
if (!(opt & CUT_OPT_SUPPRESS_FLGS))
puts(line);
goto next_line;
}
/* process each list on this line, for as long as we've got
* a line to process */
for (; cl_pos < nlists && line; cl_pos++) {
spos = cut_lists[cl_pos].startpos;
do {
/* find the field we're looking for */
while (line && ndelim < spos) {
field = strsep(&line, delimiter);
ndelim++;
}
/* we found it, and it hasn't been printed yet */
if (field && ndelim == spos && !printed[ndelim]) {
/* if this isn't our first time through, we need to
* print the delimiter after the last field that was
* printed */
if (nfields_printed > 0)
putchar(delim);
fputs(field, stdout);
printed[ndelim] = 'X';
nfields_printed++; /* shouldn't overflow.. */
}
spos++;
/* keep going as long as we have a line to work with,
* this is a list, and we're not at the end of that
* list */
} while (spos <= cut_lists[cl_pos].endpos && line
&& cut_lists[cl_pos].endpos != NON_RANGE);
}
}
/* if we printed anything at all, we need to finish it with a
* newline cuz we were handed a chomped line */
putchar('\n');
next_line:
linenum++;
free(printed);
free(orig_line);
}
}
static int getval(char *ntok)
{
char *junk;
int i = strtoul(ntok, &junk, 10);
if (*junk != '\0' || i < 0)
bb_error_msg_and_die("invalid byte or field list");
return i;
}
static const char * const _op_on_field = " only when operating on fields";
int cut_main(int argc, char **argv)
{
char *sopt, *ltok;
bb_opt_complementally = "b--bcf:c--bcf:f--bcf";
opt =
bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, &ltok);
if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS)))
bb_error_msg_and_die
("expected a list of bytes, characters, or fields");
if (opt & BB_GETOPT_ERROR)
bb_error_msg_and_die("only one type of list may be specified");
if ((opt & (CUT_OPT_DELIM_FLGS))) {
if (strlen(ltok) > 1) {
bb_error_msg_and_die("the delimiter must be a single character");
}
delim = ltok[0];
}
/* non-field (char or byte) cutting has some special handling */
if (!(opt & CUT_OPT_FIELDS_FLGS)) {
if (opt & CUT_OPT_SUPPRESS_FLGS) {
bb_error_msg_and_die
("suppressing non-delimited lines makes sense%s",
_op_on_field);
}
if (delim != '\t') {
bb_error_msg_and_die
("a delimiter may be specified%s", _op_on_field);
}
}
/*
* parse_lists() - parses a list and puts values into startpos and endpos.
* parse list and put values into startpos and endpos.
* valid list formats: N, N-, N-M, -M
* more than one list can be separated by commas
*/
static void parse_lists(char *lists)
{
char *ltok = NULL;
char *ntok = NULL;
char *junk;
char *ntok;
int s = 0, e = 0;
/* take apart the lists, one by one (they are separated with commas */
while ((ltok = strsep(&lists, ",")) != NULL) {
while ((ltok = strsep(&sopt, ",")) != NULL) {
/* it's actually legal to pass an empty list */
if (strlen(ltok) == 0)
@ -77,16 +227,14 @@ static void parse_lists(char *lists)
/* get the start pos */
ntok = strsep(&ltok, "-");
if (ntok == NULL) {
fprintf(stderr, "Help ntok is null for starting position! What do I do?\n");
bb_error_msg
("internal error: ntok is null for start pos!?\n");
} else if (strlen(ntok) == 0) {
s = BOL;
} else {
s = strtoul(ntok, &junk, 10);
if(*junk != '\0' || s < 0)
bb_error_msg_and_die("invalid byte or field list");
/* account for the fact that arrays are zero based, while the user
* expects the first char on the line to be char # 1 */
s = getval(ntok);
/* account for the fact that arrays are zero based, while
* the user expects the first char on the line to be char #1 */
if (s != 0)
s--;
}
@ -98,24 +246,24 @@ static void parse_lists(char *lists)
} else if (strlen(ntok) == 0) {
e = EOL;
} else {
e = strtoul(ntok, &junk, 10);
if(*junk != '\0' || e < 0)
bb_error_msg_and_die("invalid byte or field list");
e = getval(ntok);
/* if the user specified and end position of 0, that means "til the
* end of the line */
if (e == 0)
e = INT_MAX;
e = EOL;
e--; /* again, arrays are zero based, lines are 1 based */
if (e == s)
e = NON_RANGE;
}
/* if there's something left to tokenize, the user past an invalid list */
/* if there's something left to tokenize, the user passed
* an invalid list */
if (ltok)
bb_error_msg_and_die("invalid byte or field list");
/* add the new list */
cut_lists = xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists));
cut_lists =
xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists));
cut_lists[nlists - 1].startpos = s;
cut_lists[nlists - 1].endpos = e;
}
@ -124,209 +272,30 @@ static void parse_lists(char *lists)
if (nlists == 0)
bb_error_msg_and_die("missing list of positions");
/* now that the lists are parsed, we need to sort them to make life easier
* on us when it comes time to print the chars / fields / lines */
qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc);
}
static void cut_line_by_chars(const char *line)
{
int c, l;
/* set up a list so we can keep track of what's been printed */
char *printed = xzalloc(strlen(line));
/* print the chars specified in each cut list */
for (c = 0; c < nlists; c++) {
l = cut_lists[c].startpos;
while (l < strlen(line)) {
if (!printed[l]) {
putchar(line[l]);
printed[l] = 'X';
}
l++;
if (cut_lists[c].endpos == NON_RANGE || l > cut_lists[c].endpos)
break;
}
}
putchar('\n'); /* cuz we were handed a chomped line */
free(printed);
}
static void cut_line_by_fields(char *line)
{
int c, f;
int ndelim = -1; /* zero-based / one-based problem */
int nfields_printed = 0;
char *field = NULL;
char d[2] = { delim, 0 };
char *printed;
/* test the easy case first: does this line contain any delimiters? */
if (strchr(line, delim) == NULL) {
if (!supress_non_delimited_lines)
puts(line);
return;
}
/* set up a list so we can keep track of what's been printed */
printed = xzalloc(strlen(line));
/* process each list on this line, for as long as we've got a line to process */
for (c = 0; c < nlists && line; c++) {
f = cut_lists[c].startpos;
do {
/* find the field we're looking for */
while (line && ndelim < f) {
field = strsep(&line, d);
ndelim++;
}
/* we found it, and it hasn't been printed yet */
if (field && ndelim == f && !printed[ndelim]) {
/* if this isn't our first time through, we need to print the
* delimiter after the last field that was printed */
if (nfields_printed > 0)
putchar(delim);
fputs(field, stdout);
printed[ndelim] = 'X';
nfields_printed++;
}
f++;
/* keep going as long as we have a line to work with, this is a
* list, and we're not at the end of that list */
} while (line && cut_lists[c].endpos != NON_RANGE && f <= cut_lists[c].endpos);
}
/* if we printed anything at all, we need to finish it with a newline cuz
* we were handed a chomped line */
putchar('\n');
free(printed);
}
static void cut_file_by_lines(const char *line, unsigned int linenum)
{
static int c = 0;
static int l = -1;
/* I can't initialize this above cuz the "initializer isn't
* constant" *sigh* */
if (l == -1)
l = cut_lists[c].startpos;
/* get out if we have no more lists to process or if the lines are lower
* than what we're interested in */
if (c >= nlists || linenum < l)
return;
/* if the line we're looking for is lower than the one we were passed, it
* means we displayed it already, so move on */
while (l < linenum) {
l++;
/* move on to the next list if we're at the end of this one */
if (cut_lists[c].endpos == NON_RANGE || l > cut_lists[c].endpos) {
c++;
/* get out if there's no more lists to process */
if (c >= nlists)
return;
l = cut_lists[c].startpos;
/* get out if the current line is lower than the one we just became
* interested in */
if (linenum < l)
return;
}
}
/* If we made it here, it means we've found the line we're looking for, so print it */
puts(line);
}
/*
* snippy-snip
/* now that the lists are parsed, we need to sort them to make life
* easier on us when it comes time to print the chars / fields / lines
*/
static void cut_file(FILE *file)
{
char *line = NULL;
unsigned int linenum = 0; /* keep these zero-based to be consistent */
/* go through every line in the file */
while ((line = bb_get_chomped_line_from_file(file)) != NULL) {
/* cut based on chars/bytes XXX: only works when sizeof(char) == byte */
if ((part & (OPT_CHAR_FLGS | OPT_BYTE_FLGS)))
cut_line_by_chars(line);
/* cut based on fields */
else {
if (delim == '\n')
cut_file_by_lines(line, linenum);
else
cut_line_by_fields(line);
}
linenum++;
free(line);
}
}
int cut_main(int argc, char **argv)
{
unsigned long opt;
char *sopt, *sdopt;
bb_opt_complementally = "b--bcf:c--bcf:f--bcf";
opt = bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, &sdopt);
part = opt & (OPT_BYTE_FLGS|OPT_CHAR_FLGS|OPT_FIELDS_FLGS);
if(part == 0)
bb_error_msg_and_die("you must specify a list of bytes, characters, or fields");
if(opt & BB_GETOPT_ERROR)
bb_error_msg_and_die("only one type of list may be specified");
parse_lists(sopt);
if((opt & (OPT_DELIM_FLGS))) {
if (strlen(sdopt) > 1) {
bb_error_msg_and_die("the delimiter must be a single character");
}
delim = sdopt[0];
}
supress_non_delimited_lines = opt & OPT_SUPRESS_FLGS;
/* non-field (char or byte) cutting has some special handling */
if (part != OPT_FIELDS_FLGS) {
if (supress_non_delimited_lines) {
bb_error_msg_and_die("suppressing non-delimited lines makes sense"
" only when operating on fields");
}
if (delim != '\t') {
bb_error_msg_and_die("a delimiter may be specified only when operating on fields");
}
qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc);
}
/* argv[(optind)..(argc-1)] should be names of file to process. If no
* files were specified or '-' was specified, take input from stdin.
* Otherwise, we process all the files specified. */
if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) {
if (argv[optind] == NULL
|| (argv[optind][0] == '-' && argv[optind][1] == '\0')) {
cut_file(stdin);
}
else {
int i;
} else {
FILE *file;
for (i = optind; i < argc; i++) {
file = bb_wfopen(argv[i], "r");
for (; optind < argc; optind++) {
file = bb_wfopen(argv[optind], "r");
if (file) {
cut_file(file);
fclose(file);
}
}
}
if (ENABLE_FEATURE_CLEAN_UP)
free(cut_lists);
return EXIT_SUCCESS;
}

View File

@ -5,14 +5,17 @@
* by Matthew Grant <grantma@anathoth.gen.nz>
*
* iso-format handling added by Robert Griebl <griebl@gmx.de>
* bugfixes and cleanup by Bernhard Fischer
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
#include "busybox.h"
/* This 'date' command supports only 2 time setting formats,
all the GNU strftime stuff (its in libc, lets use it),
setting time using UTC and displaying int, as well as
an RFC 822 complient date output for shell scripting
setting time using UTC and displaying it, as well as
an RFC 2822 compliant date output for shell scripting
mail commands */
/* Input parsing code is always bulky - used heavy duty libc stuff as
@ -20,13 +23,6 @@
/* Default input handling to save surprising some people */
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include "busybox.h"
#define DATE_OPT_RFC2822 0x01
#define DATE_OPT_SET 0x02
@ -36,118 +32,44 @@
#define DATE_OPT_TIMESPEC 0x20
#define DATE_OPT_HINT 0x40
static struct tm *date_conv_time(struct tm *tm_time, const char *t_string)
static void maybe_set_utc(int opt)
{
int nr;
char *cp;
nr = sscanf(t_string, "%2d%2d%2d%2d%d", &(tm_time->tm_mon),
&(tm_time->tm_mday), &(tm_time->tm_hour), &(tm_time->tm_min),
&(tm_time->tm_year));
if (nr < 4 || nr > 5) {
bb_error_msg_and_die(bb_msg_invalid_date, t_string);
}
cp = strchr(t_string, '.');
if (cp) {
nr = sscanf(cp + 1, "%2d", &(tm_time->tm_sec));
if (nr != 1) {
bb_error_msg_and_die(bb_msg_invalid_date, t_string);
}
}
/* correct for century - minor Y2K problem here? */
if (tm_time->tm_year >= 1900) {
tm_time->tm_year -= 1900;
}
/* adjust date */
tm_time->tm_mon -= 1;
return (tm_time);
}
/* The new stuff for LRP */
static struct tm *date_conv_ftime(struct tm *tm_time, const char *t_string)
{
struct tm t;
/* Parse input and assign appropriately to tm_time */
if (t = *tm_time, sscanf(t_string, "%d:%d:%d", &t.tm_hour, &t.tm_min,
&t.tm_sec) == 3) {
/* no adjustments needed */
} else if (t = *tm_time, sscanf(t_string, "%d:%d", &t.tm_hour,
&t.tm_min) == 2) {
/* no adjustments needed */
} else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d:%d", &t.tm_mon,
&t.tm_mday, &t.tm_hour,
&t.tm_min, &t.tm_sec) == 5) {
/* Adjust dates from 1-12 to 0-11 */
t.tm_mon -= 1;
} else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d", &t.tm_mon,
&t.tm_mday,
&t.tm_hour, &t.tm_min) == 4) {
/* Adjust dates from 1-12 to 0-11 */
t.tm_mon -= 1;
} else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d:%d", &t.tm_year,
&t.tm_mon, &t.tm_mday,
&t.tm_hour, &t.tm_min,
&t.tm_sec) == 6) {
t.tm_year -= 1900; /* Adjust years */
t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
} else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d", &t.tm_year,
&t.tm_mon, &t.tm_mday,
&t.tm_hour, &t.tm_min) == 5) {
t.tm_year -= 1900; /* Adjust years */
t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
} else {
bb_error_msg_and_die(bb_msg_invalid_date, t_string);
}
*tm_time = t;
return (tm_time);
if ((opt & DATE_OPT_UTC) && putenv("TZ=UTC0") != 0)
bb_error_msg_and_die(bb_msg_memory_exhausted);
}
int date_main(int argc, char **argv)
{
time_t tm;
struct tm tm_time;
unsigned long opt;
int ifmt = -1;
char *date_str = NULL;
char *date_fmt = NULL;
int set_time;
int utc;
time_t tm;
unsigned long opt;
struct tm tm_time;
char *filename = NULL;
int ifmt = 0;
char *isofmt_arg;
char *hintfmt_arg;
bb_opt_complementally = "?:d--s:s--d";
bb_opt_complementally = "?:d--s:s--d"
USE_FEATURE_DATE_ISOFMT(":R--I:I--R");
opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:"
USE_FEATURE_DATE_ISOFMT("I::D:"),
&date_str, &date_str, &filename
USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg));
set_time = opt & DATE_OPT_SET;
utc = opt & DATE_OPT_UTC;
if (utc && putenv("TZ=UTC0") != 0) {
bb_error_msg_and_die(bb_msg_memory_exhausted);
}
maybe_set_utc(opt);
if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) {
if (!isofmt_arg) {
ifmt = 1;
ifmt = 0; /* default is date */
} else {
char *isoformats[]={"date","hours","minutes","seconds"};
for(ifmt = 4; ifmt;)
if(!strcmp(isofmt_arg,isoformats[--ifmt]))
const char * const isoformats[] =
{"date", "hours", "minutes", "seconds"};
for (ifmt = 0; ifmt < 4; ifmt++)
if (!strcmp(isofmt_arg, isoformats[ifmt])) {
break;
}
if (!ifmt) {
if (ifmt == 4) /* parse error */
bb_show_usage();
}
}
@ -156,7 +78,7 @@ int date_main(int argc, char **argv)
if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) {
date_fmt = &argv[optind][1]; /* Skip over the '+' */
} else if (date_str == NULL) {
set_time = 1;
opt |= DATE_OPT_SET;
date_str = argv[optind];
}
@ -167,7 +89,8 @@ int date_main(int argc, char **argv)
struct stat statbuf;
xstat(filename, &statbuf);
tm = statbuf.st_mtime;
} else time(&tm);
} else
time(&tm);
memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
/* Zero out fields - take her back to midnight! */
if (date_str != NULL) {
@ -179,9 +102,64 @@ int date_main(int argc, char **argv)
if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) {
strptime(date_str, hintfmt_arg, &tm_time);
} else if (strchr(date_str, ':') != NULL) {
date_conv_ftime(&tm_time, date_str);
/* Parse input and assign appropriately to tm_time */
if (sscanf(date_str, "%d:%d:%d", &tm_time.tm_hour, &tm_time.tm_min,
&tm_time.tm_sec) == 3) {
/* no adjustments needed */
} else if (sscanf(date_str, "%d:%d", &tm_time.tm_hour,
&tm_time.tm_min) == 2) {
/* no adjustments needed */
} else if (sscanf(date_str, "%d.%d-%d:%d:%d", &tm_time.tm_mon,
&tm_time.tm_mday, &tm_time.tm_hour,
&tm_time.tm_min, &tm_time.tm_sec) == 5) {
/* Adjust dates from 1-12 to 0-11 */
tm_time.tm_mon -= 1;
} else if (sscanf(date_str, "%d.%d-%d:%d", &tm_time.tm_mon,
&tm_time.tm_mday,
&tm_time.tm_hour, &tm_time.tm_min) == 4) {
/* Adjust dates from 1-12 to 0-11 */
tm_time.tm_mon -= 1;
} else if (sscanf(date_str, "%d.%d.%d-%d:%d:%d", &tm_time.tm_year,
&tm_time.tm_mon, &tm_time.tm_mday,
&tm_time.tm_hour, &tm_time.tm_min,
&tm_time.tm_sec) == 6) {
tm_time.tm_year -= 1900; /* Adjust years */
tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
} else if (sscanf(date_str, "%d.%d.%d-%d:%d", &tm_time.tm_year,
&tm_time.tm_mon, &tm_time.tm_mday,
&tm_time.tm_hour, &tm_time.tm_min) == 5) {
tm_time.tm_year -= 1900; /* Adjust years */
tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
} else {
date_conv_time(&tm_time, date_str);
bb_error_msg_and_die(bb_msg_invalid_date, date_str);
}
} else {
int nr;
char *cp;
nr = sscanf(date_str, "%2d%2d%2d%2d%d", &tm_time.tm_mon,
&tm_time.tm_mday, &tm_time.tm_hour, &tm_time.tm_min,
&tm_time.tm_year);
if (nr < 4 || nr > 5) {
bb_error_msg_and_die(bb_msg_invalid_date, date_str);
}
cp = strchr(date_str, '.');
if (cp) {
nr = sscanf(cp + 1, "%2d", &tm_time.tm_sec);
if (nr != 1) {
bb_error_msg_and_die(bb_msg_invalid_date, date_str);
}
}
/* correct for century - minor Y2K problem here? */
if (tm_time.tm_year >= 1900) {
tm_time.tm_year -= 1900;
}
/* adjust date */
tm_time.tm_mon -= 1;
}
/* Correct any day of week and day of year etc. fields */
@ -190,12 +168,10 @@ int date_main(int argc, char **argv)
if (tm < 0) {
bb_error_msg_and_die(bb_msg_invalid_date, date_str);
}
if (utc && putenv("TZ=UTC0") != 0) {
bb_error_msg_and_die(bb_msg_memory_exhausted);
}
maybe_set_utc(opt);
/* if setting time, set it */
if (set_time && stime(&tm) < 0) {
if ((opt & DATE_OPT_SET) && stime(&tm) < 0) {
bb_perror_msg("cannot set date");
}
}
@ -203,33 +179,43 @@ int date_main(int argc, char **argv)
/* Display output */
/* Deal with format string */
if (date_fmt == NULL) {
/* Start with the default case */
date_fmt = (opt & DATE_OPT_RFC2822 ?
(utc ? "%a, %d %b %Y %H:%M:%S GMT" :
"%a, %d %b %Y %H:%M:%S %z") :
"%a %b %e %H:%M:%S %Z %Y");
if (ENABLE_FEATURE_DATE_ISOFMT) {
if (ifmt == 4)
date_fmt = utc ? "%Y-%m-%dT%H:%M:%SZ" : "%Y-%m-%dT%H:%M:%S%z";
else if (ifmt == 3)
date_fmt = utc ? "%Y-%m-%dT%H:%MZ" : "%Y-%m-%dT%H:%M%z";
else if (ifmt == 2)
date_fmt = utc ? "%Y-%m-%dT%HZ" : "%Y-%m-%dT%H%z";
else if (ifmt == 1)
date_fmt = "%Y-%m-%d";
int i;
date_fmt = xzalloc(32);
if (ENABLE_FEATURE_DATE_ISOFMT && ifmt >= 0) {
strcpy(date_fmt, "%Y-%m-%d");
if (ifmt > 0) {
i = 8;
date_fmt[i++] = 'T';
date_fmt[i++] = '%';
date_fmt[i++] = 'H';
if (ifmt > 1) {
date_fmt[i++] = ':';
date_fmt[i++] = '%';
date_fmt[i++] = 'M';
}
if (ifmt > 2) {
date_fmt[i++] = ':';
date_fmt[i++] = '%';
date_fmt[i++] = 'S';
}
format_utc:
date_fmt[i++] = '%';
date_fmt[i] = (opt & DATE_OPT_UTC) ? 'Z' : 'z';
}
} else if (opt & DATE_OPT_RFC2822) {
strcpy(date_fmt, "%a, %d %b %Y %H:%M:%S ");
i = 22;
goto format_utc;
} else /* default case */
date_fmt = "%a %b %e %H:%M:%S %Z %Y";
}
if (*date_fmt == '\0') {
/* With no format string, just print a blank line */
*bb_common_bufsiz1 = 0;
} else {
/* Handle special conversions */
if (strncmp(date_fmt, "%f", 2) == 0) {

View File

@ -9,6 +9,7 @@
*/
#include "busybox.h"
#include <signal.h> /* For FEATURE_DD_SIGNAL_HANDLING */
static const struct suffix_mult dd_suffixes[] = {
{ "c", 1 },
@ -23,30 +24,30 @@ static const struct suffix_mult dd_suffixes[] = {
{ NULL, 0 }
};
static size_t out_full;
static size_t out_part;
static size_t in_full;
static size_t in_part;
static size_t out_full, out_part, in_full, in_part;
static void dd_output_status(int cur_signal)
static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal)
{
fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n",
bb_fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n",
(long)in_full, (long)in_part,
(long)out_full, (long)out_part);
}
int dd_main(int argc, char **argv)
{
#define sync_flag (1<<0)
#define noerror (1<<1)
#define trunc_flag (1<<2)
#define twobufs_flag (1<<3)
int flags = trunc_flag;
size_t count = -1, oc = 0, ibs = 512, obs = 512;
ssize_t n;
off_t seek = 0, skip = 0;
int sync_flag = FALSE, noerror = FALSE, trunc_flag = TRUE, twobufs_flag = 0,
oflag, ifd, ofd, i;
int oflag, ifd, ofd;
const char *infile = NULL, *outfile = NULL;
char *ibuf, *obuf;
if (ENABLE_FEATURE_DD_SIGNAL_HANDLING)
{
if (ENABLE_FEATURE_DD_SIGNAL_HANDLING) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
@ -56,39 +57,39 @@ int dd_main(int argc, char **argv)
sigaction(SIGUSR1, &sa, 0);
}
for (i = 1; i < argc; i++) {
if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[i], 4)) {
ibs = bb_xparse_number(argv[i]+4, dd_suffixes);
twobufs_flag++;
} else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[i], 4)) {
obs = bb_xparse_number(argv[i]+4, dd_suffixes);
twobufs_flag++;
} else if (!strncmp("bs=", argv[i], 3)) {
ibs = obs = bb_xparse_number(argv[i]+3, dd_suffixes);
} else if (!strncmp("count=", argv[i], 6))
count = bb_xparse_number(argv[i]+6, dd_suffixes);
else if (!strncmp("seek=", argv[i], 5))
seek = bb_xparse_number(argv[i]+5, dd_suffixes);
else if (!strncmp("skip=", argv[i], 5))
skip = bb_xparse_number(argv[i]+5, dd_suffixes);
else if (!strncmp("if=", argv[i], 3))
infile = argv[i]+3;
else if (!strncmp("of=", argv[i], 3))
outfile = argv[i]+3;
else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[i], 5)) {
ibuf = argv[i]+5;
for (n = 1; n < argc; n++) {
if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[n], 4)) {
ibs = bb_xparse_number(argv[n]+4, dd_suffixes);
flags |= twobufs_flag;
} else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[n], 4)) {
obs = bb_xparse_number(argv[n]+4, dd_suffixes);
flags |= twobufs_flag;
} else if (!strncmp("bs=", argv[n], 3))
ibs = obs = bb_xparse_number(argv[n]+3, dd_suffixes);
else if (!strncmp("count=", argv[n], 6))
count = bb_xparse_number(argv[n]+6, dd_suffixes);
else if (!strncmp("seek=", argv[n], 5))
seek = bb_xparse_number(argv[n]+5, dd_suffixes);
else if (!strncmp("skip=", argv[n], 5))
skip = bb_xparse_number(argv[n]+5, dd_suffixes);
else if (!strncmp("if=", argv[n], 3))
infile = argv[n]+3;
else if (!strncmp("of=", argv[n], 3))
outfile = argv[n]+3;
else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[n], 5)) {
ibuf = argv[n]+5;
while (1) {
if (!strncmp("notrunc", ibuf, 7)) {
trunc_flag = FALSE;
flags ^= trunc_flag;
ibuf += 7;
} else if (!strncmp("sync", ibuf, 4)) {
sync_flag = TRUE;
flags |= sync_flag;
ibuf += 4;
} else if (!strncmp("noerror", ibuf, 7)) {
noerror = TRUE;
flags |= noerror;
ibuf += 7;
} else {
bb_error_msg_and_die(bb_msg_invalid_arg, argv[i]+5, "conv");
bb_error_msg_and_die(bb_msg_invalid_arg, argv[n]+5, "conv");
}
if (ibuf[0] == '\0') break;
if (ibuf[0] == ',') ibuf++;
@ -98,12 +99,14 @@ int dd_main(int argc, char **argv)
}
ibuf = xmalloc(ibs);
if (twobufs_flag) obuf = xmalloc(obs);
else obuf = ibuf;
if (flags & twobufs_flag)
obuf = xmalloc(obs);
else
obuf = ibuf;
if (infile != NULL) {
if (infile != NULL)
ifd = xopen(infile, O_RDONLY);
} else {
else {
ifd = STDIN_FILENO;
infile = bb_msg_standard_input;
}
@ -111,20 +114,18 @@ int dd_main(int argc, char **argv)
if (outfile != NULL) {
oflag = O_WRONLY | O_CREAT;
if (!seek && trunc_flag) {
if (!seek && (flags & trunc_flag))
oflag |= O_TRUNC;
}
ofd = xopen3(outfile, oflag, 0666);
if (seek && trunc_flag) {
if (seek && (flags & trunc_flag)) {
if (ftruncate(ofd, seek * obs) < 0) {
struct stat st;
if (fstat(ofd, &st) < 0 || S_ISREG(st.st_mode) ||
S_ISDIR (st.st_mode)) {
bb_perror_msg_and_die("%s", outfile);
}
S_ISDIR(st.st_mode))
goto die_outfile;
}
}
} else {
@ -145,44 +146,42 @@ int dd_main(int argc, char **argv)
}
if (seek) {
if (lseek(ofd, seek * obs, SEEK_CUR) < 0) {
bb_perror_msg_and_die("%s", outfile);
}
if (lseek(ofd, seek * obs, SEEK_CUR) < 0)
goto die_outfile;
}
while (in_full + in_part != count) {
if (noerror) {
if (flags & noerror) {
/* Pre-zero the buffer when doing the noerror thing */
memset(ibuf, '\0', ibs);
}
n = safe_read(ifd, ibuf, ibs);
if (n == 0) {
if (n == 0)
break;
}
if (n < 0) {
if (noerror) {
if (flags & noerror) {
n = ibs;
bb_perror_msg("%s", infile);
} else {
} else
bb_perror_msg_and_die("%s", infile);
}
}
if ((size_t)n == ibs) {
if ((size_t)n == ibs)
in_full++;
} else {
else {
in_part++;
if (sync_flag) {
memset(ibuf + n, '\0', ibs - n);
n = ibs;
}
}
if (twobufs_flag) {
if (flags & twobufs_flag) {
char *tmp = ibuf;
while (n) {
size_t d = obs - oc;
if (d > n) d = n;
if (d > n)
d = n;
memcpy(obuf + oc, tmp, d);
n -= d;
tmp += d;
@ -195,8 +194,10 @@ int dd_main(int argc, char **argv)
}
} else {
xwrite(ofd, ibuf, n);
if (n == ibs) out_full++;
else out_part++;
if (n == ibs)
out_full++;
else
out_part++;
}
}
@ -209,6 +210,7 @@ int dd_main(int argc, char **argv)
}
if (close (ofd) < 0) {
die_outfile:
bb_perror_msg_and_die("%s", outfile);
}

View File

@ -23,11 +23,6 @@
* 4) Fixed busybox bug #1284 involving long overflow with human_readable.
*/
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include "busybox.h"
#ifdef CONFIG_FEATURE_HUMAN_READABLE
@ -57,7 +52,7 @@ static int one_file_system;
static dev_t dir_dev;
static void print(long size, char *filename)
static void print(long size, const char * const filename)
{
/* TODO - May not want to defer error checking here. */
#ifdef CONFIG_FEATURE_HUMAN_READABLE
@ -73,7 +68,7 @@ static void print(long size, char *filename)
}
/* tiny recursive du */
static long du(char *filename)
static long du(const char * const filename)
{
struct stat statbuf;
long sum;

View File

@ -37,11 +37,13 @@ typedef enum valtype TYPE;
#if ENABLE_EXPR_MATH_SUPPORT_64
typedef int64_t arith_t;
#define PF_REZ "ll"
#define PF_REZ_TYPE (long long)
#define STRTOL(s, e, b) strtoll(s, e, b)
#else
typedef long arith_t;
#define PF_REZ "l"
#define PF_REZ_TYPE (long)
#define STRTOL(s, e, b) strtol(s, e, b)
@ -85,7 +87,7 @@ int expr_main (int argc, char **argv)
bb_error_msg_and_die("syntax error");
if (v->type == integer)
printf ("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i);
bb_printf("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i);
else
puts(v->u.s);
@ -129,13 +131,11 @@ static void freev (VALUE *v)
static int null(VALUE * v)
{
switch (v->type) {
case integer:
if (v->type == integer)
return v->u.i == 0;
default: /* string: */
else /* string: */
return v->u.s[0] == '\0' || strcmp(v->u.s, "0") == 0;
}
}
/* Coerce V to a string value (can't fail). */
@ -170,8 +170,7 @@ static int toarith (VALUE *v)
/* Return nonzero if the next token matches STR exactly.
STR must not be NULL. */
static int
nextarg (char *str)
static int nextarg(char *str)
{
if (*args == NULL)
return 0;
@ -188,24 +187,21 @@ static int cmp_common (VALUE *l, VALUE *r, int op)
tostring(l);
tostring(r);
cmpval = strcmp(l->u.s, r->u.s);
}
else
} else
cmpval = l->u.i - r->u.i;
switch(op) {
case '<':
if (op == '<')
return cmpval < 0;
case ('L'+'E'):
else if (op == ('L' + 'E'))
return cmpval <= 0;
case '=':
else if (op == '=')
return cmpval == 0;
case '!':
else if (op == '!')
return cmpval != 0;
case '>':
else if (op == '>')
return cmpval > 0;
default: /* >= */
else /* >= */
return cmpval >= 0;
}
}
/* The arithmetic operator handling functions. */
@ -219,19 +215,17 @@ static arith_t arithmetic_common (VALUE *l, VALUE *r, int op)
ri = r->u.i;
if ((op == '/' || op == '%') && ri == 0)
bb_error_msg_and_die("division by zero");
switch(op) {
case '+':
if (op == '+')
return li + ri;
case '-':
else if (op == '-')
return li - ri;
case '*':
else if (op == '*')
return li * ri;
case '/':
else if (op == '/')
return li / ri;
default:
else
return li % ri;
}
}
/* Do the : operator.
SV is the VALUE for the lhs (the string),
@ -250,8 +244,7 @@ static VALUE *docolon (VALUE *sv, VALUE *pv)
if (pv->u.s[0] == '^') {
fprintf(stderr, "\
warning: unportable BRE: `%s': using `^' as the first character\n\
of a basic regular expression is not portable; it is being ignored",
pv->u.s);
of a basic regular expression is not portable; it is being ignored", pv->u.s);
}
memset(&re_buffer, 0, sizeof(re_buffer));
@ -267,11 +260,9 @@ of a basic regular expression is not portable; it is being ignored",
if (re_buffer.re_nsub > 0) {
sv->u.s[re_regs[1].rm_eo] = '\0';
v = str_value(sv->u.s + re_regs[1].rm_so);
}
else
} else
v = int_value(re_regs[0].rm_eo);
}
else {
} else {
/* Match failed -- return the right kind of null. */
if (re_buffer.re_nsub > 0)
v = str_value("");
@ -316,16 +307,14 @@ static VALUE *eval6 (void)
if (!*args)
bb_error_msg_and_die("syntax error");
return str_value(*args++);
}
else if (nextarg ("length")) {
} else if (nextarg("length")) {
args++;
r = eval6();
tostring(r);
v = int_value(strlen(r->u.s));
freev(r);
return v;
}
else if (nextarg ("match")) {
} else if (nextarg("match")) {
args++;
l = eval6();
r = eval6();
@ -333,8 +322,7 @@ static VALUE *eval6 (void)
freev(l);
freev(r);
return v;
}
else if (nextarg ("index")) {
} else if (nextarg("index")) {
args++;
l = eval6();
r = eval6();
@ -346,8 +334,7 @@ static VALUE *eval6 (void)
freev(l);
freev(r);
return v;
}
else if (nextarg ("substr")) {
} else if (nextarg("substr")) {
args++;
l = eval6();
i1 = eval6();
@ -366,8 +353,7 @@ static VALUE *eval6 (void)
freev(i1);
freev(i2);
return v;
}
else
} else
return eval7();
}
@ -491,8 +477,7 @@ static VALUE *eval1 (void)
freev(l);
freev(r);
l = int_value(0);
}
else
} else
freev(r);
}
return l;
@ -511,8 +496,7 @@ static VALUE *eval (void)
if (null(l)) {
freev(l);
l = r;
}
else
} else
freev(r);
}
return l;

View File

@ -13,12 +13,6 @@
* Licensed under the GPL v2, see the file LICENSE in this tarball.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "busybox.h"
/* 1 if any of the files read were the standard input */
@ -38,14 +32,15 @@ static int bsd_sum_file(const char *file, int print_name)
int checksum = 0; /* The checksum mod 2^16. */
uintmax_t total_bytes = 0; /* The number of bytes. */
int ch; /* Each character read. */
int ret = 0;
if (IS_STDIN(file)) {
fp = stdin;
have_read_stdin = 1;
have_read_stdin++;
} else {
fp = bb_wfopen(file, "r");
if (fp == NULL)
return 0;
goto out;
}
while ((ch = getc(fp)) != EOF) {
@ -58,21 +53,21 @@ static int bsd_sum_file(const char *file, int print_name)
if (ferror(fp)) {
bb_perror_msg(file);
bb_fclose_nonstdin(fp);
return 0;
goto out;
}
if (bb_fclose_nonstdin(fp) == EOF) {
bb_perror_msg(file);
return 0;
goto out;
}
ret++;
printf("%05d %5ju ", checksum, (total_bytes+1023)/1024);
if (print_name > 1)
puts(file);
else
printf("\n");
return 1;
out:
return ret;
}
/* Calculate and print the checksum and the size in 512-byte blocks

View File

@ -42,15 +42,6 @@ static const struct suffix_mult tail_suffixes[] = {
static int status;
static void tail_xprint_header(const char *fmt, const char *filename)
{
/* If we get an output error, there is really no sense in continuing. */
if (dprintf(STDOUT_FILENO, fmt, filename) < 0) {
bb_perror_nomsg_and_die();
}
}
/* len should probably be size_t */
static void tail_xbb_full_write(const char *buf, size_t len)
{
/* If we get a write error, there is really no sense in continuing. */
@ -58,6 +49,20 @@ static void tail_xbb_full_write(const char *buf, size_t len)
bb_perror_nomsg_and_die();
}
static void tail_xprint_header(const char *fmt, const char *filename)
{
#if defined __GLIBC__
if (dprintf(STDOUT_FILENO, fmt, filename) < 0) {
bb_perror_nomsg_and_die();
}
#else
int hdr_len = strlen(fmt) + strlen(filename);
char *hdr = xzalloc(hdr_len);
sprintf(hdr, filename, filename);
tail_xbb_full_write(hdr, hdr_len);
#endif
}
static ssize_t tail_read(int fd, char *buf, size_t count)
{
ssize_t r;

View File

@ -11,6 +11,7 @@
/* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */
#include "busybox.h"
#include <signal.h>
int tee_main(int argc, char **argv)
{

View File

@ -3,6 +3,7 @@
* Mini watch implementation for busybox
*
* Copyright (C) 2001 by Michael Habermann <mhabermann@gmx.de>
* Copyrigjt (C) Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
@ -10,14 +11,9 @@
/* BB_AUDIT SUSv3 N/A */
/* BB_AUDIT GNU defects -- only option -n is supported. */
/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
*
* Removed dependency on date_main(), added proper error checking, and
* reduced size.
*/
#include "busybox.h"
int watch_main(int argc, char **argv)
{
int width, len;
@ -26,19 +22,18 @@ int watch_main(int argc, char **argv)
if (argc < 2) bb_show_usage();
get_terminal_width_height(1, &width, 0);
get_terminal_width_height(STDOUT_FILENO, &width, 0);
header = xzalloc(width--);
/* don't use getopt, because it permutes the arguments */
++argv;
if ((argc > 3) && !strcmp(*argv, "-n")) {
if ((argc > 3) && argv[0][0] == '-' && argv[0][1] == 'n') {
period = bb_xgetularg10_bnd(argv[1], 1, UINT_MAX);
argv += 2;
}
watched_argv = argv;
/* create header */
len = snprintf(header, width, "Every %ds:", period);
while (*argv && len<width)
snprintf(header+len, width-len, " %s", *(argv++));
@ -50,11 +45,13 @@ int watch_main(int argc, char **argv)
time(&t);
thyme = ctime(&t);
len = strlen(thyme);
if (len < width) header[width-len] = 0;
printf("\033[H\033[J%s %s\n", header, thyme);
if (len < width)
header[width-len] = 0;
bb_printf("\033[H\033[J%s %s\n", header, thyme);
waitpid(xspawn(watched_argv),0,0);
sleep(period);
}
if (ENABLE_FEATURE_CLEAN_UP)
free(header);
}

View File

@ -60,10 +60,6 @@
#define PATH_MAX 256
#endif
#ifdef DMALLOC
#include <dmalloc.h>
#endif
/* Some useful definitions */
#undef FALSE
#define FALSE ((int) 0)
@ -211,7 +207,9 @@ extern int bb_fprintf(FILE * __restrict stream, const char * __restrict format,
extern int bb_printf(const char * __restrict format, ...)
__attribute__ ((format (printf, 1, 2)));
//#warning rename to xferror_filename?
#if ENABLE_NITPICK
#warning rename to xferror_filename?
#endif
extern void xferror(FILE *fp, const char *fn);
extern void xferror_stdout(void);
extern void xfflush_stdout(void);
@ -265,7 +263,9 @@ extern long bb_xgetlarg_bnd_sfx(const char *arg, int base,
extern long bb_xgetlarg10_sfx(const char *arg, const struct suffix_mult *suffixes);
//#warning pitchable now?
#if ENABLE_NITPICK
#warning pitchable now?
#endif
extern unsigned long bb_xparse_number(const char *numstr,
const struct suffix_mult *suffixes);
@ -330,7 +330,9 @@ char *concat_path_file(const char *path, const char *filename);
char *concat_subpath_file(const char *path, const char *filename);
char *last_char_is(const char *s, int c);
//#warning yuk!
#if ENABLE_NITPICK
#warning yuk!
#endif
char *fgets_str(FILE *file, const char *terminating_string);
extern int uncompress(int fd_in, int fd_out);
@ -344,7 +346,9 @@ extern int xconnect(struct sockaddr_in *s_addr);
extern unsigned short bb_lookup_port(const char *port, const char *protocol, unsigned short default_port);
extern void bb_lookup_host(struct sockaddr_in *s_in, const char *host);
//#warning wrap this?
#if ENABLE_NITPICK
#warning wrap this?
#endif
char *dirname (char *path);
int bb_make_directory (char *path, long mode, int flags);
@ -456,8 +460,10 @@ extern int bb_default_error_retval;
# define FB_0 "/dev/fb0"
#endif
//#warning put these in .o files
#if ENABLE_NITPICK
#warning put these in .o files
#endif
/* The following devices are the same on devfs and non-devfs systems. */
#define CURRENT_TTY "/dev/tty"
#define CONSOLE_DEV "/dev/console"
@ -581,4 +587,8 @@ extern const char BB_BANNER[];
#undef isupper
#undef isxdigit
#ifdef DMALLOC
#include <dmalloc.h>
#endif
#endif /* __LIBBUSYBOX_H__ */

View File

@ -10,8 +10,6 @@
#define ARCHIVE_NOPRESERVE_OWN 32
#define ARCHIVE_NOPRESERVE_PERM 64
#include <sys/types.h>
#include <stdio.h>
#include "libbb.h"
typedef struct file_headers_s {

View File

@ -1426,12 +1426,12 @@ USE_FEATURE_DATE_ISOFMT( \
#define ipcrm_trivial_usage \
"[-[MQS] key] [-[mqs] id]"
#define ipcrm_full_usage \
"The upper-case options MQS are used to remove a shared memory\n" \
"segment by an shmkey value. The lower-case options mqs are used\n" \
"The upper-case options MQS are used to remove a shared memory segment by a\n" \
"segment by a shmkey value. The lower-case options mqs are used\n" \
"to remove a segment by shmid value.\n" \
"\t-m | -M\tRemove the memory segment after the last detach\n" \
"\t-q | -Q\tRemove the message queue\n" \
"\t-s | -S\tRemove the semaphore"
"\t-[mM]\tRemove the memory segment after the last detach\n" \
"\t-[qQ]\tRemove the message queue\n" \
"\t-[sS]\tRemove the semaphore"
#define ipcs_trivial_usage \
"[[-smq] -i shmid] | [[-asmq] [-tclup]]"

View File

@ -16,8 +16,12 @@
* succeeded. */
#ifndef DMALLOC
/* dmalloc provides variants of these that do abort() on failure.
* Since dmalloc's prototypes overwrite the impls here as they are
* included after these prototypes in libbb.h, all is well.
*/
#ifdef L_xmalloc
// Die if we can't allocate size bytes of memory.
/* Die if we can't allocate size bytes of memory. */
void *xmalloc(size_t size)
{
void *ptr = malloc(size);
@ -28,9 +32,9 @@ void *xmalloc(size_t size)
#endif
#ifdef L_xrealloc
// Die if we can't resize previously allocated memory. (This returns a pointer
// to the new memory, which may or may not be the same as the old memory.
// It'll copy the contents to a new chunk and free the old one if necessary.)
/* Die if we can't resize previously allocated memory. (This returns a pointer
* to the new memory, which may or may not be the same as the old memory.
* It'll copy the contents to a new chunk and free the old one if necessary.) */
void *xrealloc(void *ptr, size_t size)
{
ptr = realloc(ptr, size);
@ -39,9 +43,11 @@ void *xrealloc(void *ptr, size_t size)
return ptr;
}
#endif
#endif /* DMALLOC */
#ifdef L_xzalloc
// Die if we can't allocate and zero size bytes of memory.
/* Die if we can't allocate and zero size bytes of memory. */
void *xzalloc(size_t size)
{
void *ptr = xmalloc(size);
@ -50,10 +56,8 @@ void *xzalloc(size_t size)
}
#endif
#endif /* DMALLOC */
#ifdef L_xstrdup
// Die if we can't copy a string to freshly allocated memory.
/* Die if we can't copy a string to freshly allocated memory. */
char * xstrdup(const char *s)
{
char *t;
@ -71,8 +75,9 @@ char * xstrdup(const char *s)
#endif
#ifdef L_xstrndup
// Die if we can't allocate n+1 bytes (space for the null terminator) and copy
// the (possibly truncated to length n) string into it.
/* Die if we can't allocate n+1 bytes (space for the null terminator) and copy
* the (possibly truncated to length n) string into it.
*/
char * xstrndup(const char *s, int n)
{
char *t;
@ -87,8 +92,9 @@ char * xstrndup(const char *s, int n)
#endif
#ifdef L_xfopen
// Die if we can't open a file and return a FILE * to it.
// Notice we haven't got xfread(), This is for use with fscanf() and friends.
/* Die if we can't open a file and return a FILE * to it.
* Notice we haven't got xfread(), This is for use with fscanf() and friends.
*/
FILE *xfopen(const char *path, const char *mode)
{
FILE *fp;
@ -99,7 +105,7 @@ FILE *xfopen(const char *path, const char *mode)
#endif
#ifdef L_xopen
// Die if we can't open an existing file and return an fd.
/* Die if we can't open an existing file and return an fd. */
int xopen(const char *pathname, int flags)
{
if (ENABLE_DEBUG && (flags && O_CREAT))
@ -110,7 +116,7 @@ int xopen(const char *pathname, int flags)
#endif
#ifdef L_xopen3
// Die if we can't open a new file and return an fd.
/* Die if we can't open a new file and return an fd. */
int xopen3(const char *pathname, int flags, int mode)
{
int ret;
@ -124,7 +130,7 @@ int xopen3(const char *pathname, int flags, int mode)
#endif
#ifdef L_xread
// Die with an error message if we can't read the entire buffer.
/* Die with an error message if we can't read the entire buffer. */
void xread(int fd, void *buf, size_t count)
{
while (count) {
@ -139,7 +145,7 @@ void xread(int fd, void *buf, size_t count)
#endif
#ifdef L_xwrite
// Die with an error message if we can't write the entire buffer.
/* Die with an error message if we can't write the entire buffer. */
void xwrite(int fd, void *buf, size_t count)
{
while (count) {
@ -154,7 +160,7 @@ void xwrite(int fd, void *buf, size_t count)
#endif
#ifdef L_xlseek
// Die with an error message if we can't lseek to the right spot.
/* Die with an error message if we can't lseek to the right spot. */
void xlseek(int fd, off_t offset, int whence)
{
if (offset != lseek(fd, offset, whence)) bb_error_msg_and_die("lseek");
@ -162,7 +168,7 @@ void xlseek(int fd, off_t offset, int whence)
#endif
#ifdef L_xread_char
// Die with an error message if we can't read one character.
/* Die with an error message if we can't read one character. */
unsigned char xread_char(int fd)
{
char tmp;
@ -174,7 +180,7 @@ unsigned char xread_char(int fd)
#endif
#ifdef L_xferror
// Die with supplied error message if this FILE * has ferror set.
/* Die with supplied error message if this FILE * has ferror set. */
void xferror(FILE *fp, const char *fn)
{
if (ferror(fp)) {
@ -184,7 +190,7 @@ void xferror(FILE *fp, const char *fn)
#endif
#ifdef L_xferror_stdout
// Die with an error message if stdout has ferror set.
/* Die with an error message if stdout has ferror set. */
void xferror_stdout(void)
{
xferror(stdout, bb_msg_standard_output);
@ -192,7 +198,7 @@ void xferror_stdout(void)
#endif
#ifdef L_xfflush_stdout
// Die with an error message if we have trouble flushing stdout.
/* Die with an error message if we have trouble flushing stdout. */
void xfflush_stdout(void)
{
if (fflush(stdout)) {
@ -202,24 +208,25 @@ void xfflush_stdout(void)
#endif
#ifdef L_spawn
// This does a fork/exec in one call, using vfork(). Return PID of new child,
// -1 for failure. Runs argv[0], searching path if that has no / in it.
/* This does a fork/exec in one call, using vfork(). Return PID of new child,
* -1 for failure. Runs argv[0], searching path if that has no / in it.
*/
pid_t spawn(char **argv)
{
static int failed;
pid_t pid;
void *app = ENABLE_FEATURE_SH_STANDALONE_SHELL ? find_applet_by_name(argv[0]) : 0;
// Be nice to nommu machines.
/* Be nice to nommu machines. */
failed = 0;
pid = vfork();
if (pid < 0) return pid;
if (!pid) {
execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : *argv, argv);
// We're sharing a stack with blocked parent, let parent know we failed
// and then exit to unblock parent (but don't run atexit() stuff, which
// would screw up parent.)
/* We're sharing a stack with blocked parent, let parent know we failed
* and then exit to unblock parent (but don't run atexit() stuff, which
would screw up parent.) */
failed = -1;
_exit(0);
@ -229,7 +236,7 @@ pid_t spawn(char **argv)
#endif
#ifdef L_xspawn
// Die with an error message if we can't spawn a child process.
/* Die with an error message if we can't spawn a child process. */
pid_t xspawn(char **argv)
{
pid_t pid = spawn(argv);
@ -239,7 +246,7 @@ pid_t xspawn(char **argv)
#endif
#ifdef L_wait4
// Wait for the specified child PID to exit, returning child's error return.
/* Wait for the specified child PID to exit, returning child's error return. */
int wait4pid(int pid)
{
int status;
@ -252,9 +259,9 @@ int wait4pid(int pid)
#endif
#ifdef L_itoa
// Convert unsigned integer to ascii, writing into supplied buffer. A
// truncated result is always null terminated (unless buflen is 0), and
// contains the first few digits of the result ala strncpy.
/* Convert unsigned integer to ascii, writing into supplied buffer. A
* truncated result is always null terminated (unless buflen is 0), and
* contains the first few digits of the result ala strncpy. */
void utoa_to_buf(unsigned n, char *buf, unsigned buflen)
{
int i, out = 0;
@ -272,7 +279,7 @@ void utoa_to_buf(unsigned n, char *buf, unsigned buflen)
}
}
// Convert signed integer to ascii, like utoa_to_buf()
/* Convert signed integer to ascii, like utoa_to_buf() */
void itoa_to_buf(int n, char *buf, unsigned buflen)
{
if (buflen && n<0) {
@ -283,16 +290,16 @@ void itoa_to_buf(int n, char *buf, unsigned buflen)
utoa_to_buf((unsigned)n, buf, buflen);
}
// The following two functions use a static buffer, so calling either one a
// second time will overwrite previous results.
//
// The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes.
// Int should always be 32 bits on any remotely Unix-like system, see
// http://www.unix.org/whitepapers/64bit.html for the reasons why.
/* The following two functions use a static buffer, so calling either one a
* second time will overwrite previous results.
*
* The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes.
* Int should always be 32 bits on any remotely Unix-like system, see
* http://www.unix.org/whitepapers/64bit.html for the reasons why.
*/
static char local_buf[12];
// Convert unsigned integer to ascii using a static buffer (returned).
/* Convert unsigned integer to ascii using a static buffer (returned). */
char *utoa(unsigned n)
{
utoa_to_buf(n, local_buf, sizeof(local_buf));
@ -300,7 +307,7 @@ char *utoa(unsigned n)
return local_buf;
}
// Convert signed integer to ascii using a static buffer (returned).
/* Convert signed integer to ascii using a static buffer (returned). */
char *itoa(int n)
{
itoa_to_buf(n, local_buf, sizeof(local_buf));
@ -310,15 +317,15 @@ char *itoa(int n)
#endif
#ifdef L_setuid
// Die with an error message if we can't set gid. (Because resource limits may
// limit this user to a given number of processes, and if that fills up the
// setgid() will fail and we'll _still_be_root_, which is bad.)
/* Die with an error message if we can't set gid. (Because resource limits may
* limit this user to a given number of processes, and if that fills up the
* setgid() will fail and we'll _still_be_root_, which is bad.) */
void xsetgid(gid_t gid)
{
if (setgid(gid)) bb_error_msg_and_die("setgid");
}
// Die with an error message if we cant' set uid. (See xsetgid() for why.)
/* Die with an error message if we cant' set uid. (See xsetgid() for why.) */
void xsetuid(uid_t uid)
{
if (setuid(uid)) bb_error_msg_and_die("setuid");
@ -326,31 +333,31 @@ void xsetuid(uid_t uid)
#endif
#ifdef L_fdlength
// Return how long the file at fd is, if there's any way to determine it.
/* Return how long the file at fd is, if there's any way to determine it. */
off_t fdlength(int fd)
{
off_t bottom = 0, top = 0, pos;
long size;
// If the ioctl works for this, return it.
/* If the ioctl works for this, return it. */
if (ioctl(fd, BLKGETSIZE, &size) >= 0) return size*512;
// If not, do a binary search for the last location we can read. (Some
// block devices don't do BLKGETSIZE right.)
/* If not, do a binary search for the last location we can read. (Some
* block devices don't do BLKGETSIZE right.) */
do {
char temp;
pos = bottom + (top - bottom) / 2;;
// If we can read from the current location, it's bigger.
/* If we can read from the current location, it's bigger. */
if (lseek(fd, pos, 0)>=0 && safe_read(fd, &temp, 1)==1) {
if (bottom == top) bottom = top = (top+1) * 2;
else bottom = pos;
// If we can't, it's smaller.
/* If we can't, it's smaller. */
} else {
if (bottom == top) {
@ -366,8 +373,8 @@ off_t fdlength(int fd)
#endif
#ifdef L_xasprintf
// Die with an error message if we can't malloc() enough space and do an
// sprintf() into that space.
/* Die with an error message if we can't malloc() enough space and do an
* sprintf() into that space. */
char *xasprintf(const char *format, ...)
{
va_list p;
@ -396,8 +403,8 @@ char *xasprintf(const char *format, ...)
#endif
#ifdef L_xprint_and_close_file
// Die with an error message if we can't copy an entire FILE * to stdout, then
// close that file.
/* Die with an error message if we can't copy an entire FILE * to stdout, then
* close that file. */
void xprint_and_close_file(FILE *file)
{
// copyfd outputs error messages for us.
@ -408,7 +415,7 @@ void xprint_and_close_file(FILE *file)
#endif
#ifdef L_xchdir
// Die if we can't chdir to a new path.
/* Die if we can't chdir to a new path. */
void xchdir(const char *path)
{
if (chdir(path))
@ -417,7 +424,7 @@ void xchdir(const char *path)
#endif
#ifdef L_warn_opendir
// Print a warning message if opendir() fails, but don't die.
/* Print a warning message if opendir() fails, but don't die. */
DIR *warn_opendir(const char *path)
{
DIR *dp;
@ -431,7 +438,7 @@ DIR *warn_opendir(const char *path)
#endif
#ifdef L_xopendir
// Die with an error message if opendir() fails.
/* Die with an error message if opendir() fails. */
DIR *xopendir(const char *path)
{
DIR *dp;
@ -444,7 +451,7 @@ DIR *xopendir(const char *path)
#ifdef L_xdaemon
#ifndef BB_NOMMU
// Die with an error message if we can't daemonize.
/* Die with an error message if we can't daemonize. */
void xdaemon(int nochdir, int noclose)
{
if (daemon(nochdir, noclose)) bb_perror_msg_and_die("daemon");
@ -453,7 +460,7 @@ void xdaemon(int nochdir, int noclose)
#endif
#ifdef L_xsocket
// Die with an error message if we can't open a new socket.
/* Die with an error message if we can't open a new socket. */
int xsocket(int domain, int type, int protocol)
{
int r = socket(domain, type, protocol);
@ -465,7 +472,7 @@ int xsocket(int domain, int type, int protocol)
#endif
#ifdef L_xbind
// Die with an error message if we can't bind a socket to an address.
/* Die with an error message if we can't bind a socket to an address. */
void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
{
if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind");
@ -473,7 +480,7 @@ void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
#endif
#ifdef L_xlisten
// Die with an error message if we can't listen for connections on a socket.
/* Die with an error message if we can't listen for connections on a socket. */
void xlisten(int s, int backlog)
{
if (listen(s, backlog)) bb_perror_msg_and_die("listen");

View File

@ -49,6 +49,7 @@ find $srcdir/../ \
-e '\<algorithic\>' \
-e '\<deamon\>' \
-e '\<derefernce\>' \
-e '\<acomadate\>' \
| sed -e "s:^$srcdir/\.\./::g" > src.typos
testing "Common typos" "cat src.typos" "" "" ""
rm -f src.typos

View File

@ -1,56 +1,22 @@
/* vi: set sw=4 ts=4: */
/*
* ipcrm.c -- utility to allow removal of IPC objects and data structures.
* ipcrm.c - utility to allow removal of IPC objects and data structures.
*
* 01 Sept 2004 - Rodney Radford <rradford@mindspring.com>
* Adapted for busybox from util-linux-2.12a.
*
* 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
*
* --- Pre-busybox history from util-linux-2.12a ------------------------
*
* 1999-04-02 frank zago
* - can now remove several id's in the same call
*
* 1999-02-22 Arkadiusz Miÿkiewicz <misiek@pld.ORG.PL>
* - added Native Language Support
*
* Original author - krishna balasubramanian 1993
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "busybox.h"
#include <sys/types.h>
/* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */
/* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/sem.h>
/* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */
/* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */
/* for getopt */
#include <unistd.h>
/* for tolower and isupper */
#include <ctype.h>
#include "busybox.h"
#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* union semun is defined by including <sys/sem.h> */
#else
@ -63,16 +29,18 @@ union semun {
};
#endif
#ifndef CONFIG_IPCRM_DROP_LEGACY
typedef enum type_id {
SHM,
SEM,
MSG
} type_id;
static int
remove_ids(type_id type, int argc, char **argv) {
static int remove_ids(type_id type, int argc, char **argv)
{
int id;
int ret = 0; /* for gcc */
int ret = 0; /* silence gcc */
char *end;
int nb_errors = 0;
union semun arg;
@ -84,26 +52,18 @@ remove_ids(type_id type, int argc, char **argv) {
id = strtoul(argv[0], &end, 10);
if (*end != 0) {
bb_printf ("invalid id: %s\n", argv[0]);
bb_error_msg("invalid id: %s", argv[0]);
nb_errors++;
} else {
switch(type) {
case SEM:
if (type == SEM)
ret = semctl(id, 0, IPC_RMID, arg);
break;
case MSG:
else if (type == MSG)
ret = msgctl(id, IPC_RMID, NULL);
break;
case SHM:
else if (type == SHM)
ret = shmctl(id, IPC_RMID, NULL);
break;
}
if (ret) {
bb_printf ("cannot remove id %s (%s)\n",
argv[0], strerror(errno));
bb_perror_msg("cannot remove id %s", argv[0]);
nb_errors++;
}
}
@ -113,114 +73,105 @@ remove_ids(type_id type, int argc, char **argv) {
return (nb_errors);
}
static int deprecated_main(int argc, char **argv)
{
if (argc < 3) {
bb_show_usage();
bb_fflush_stdout_and_exit(1);
}
if (!strcmp(argv[1], "shm")) {
if (remove_ids(SHM, argc-2, &argv[2]))
bb_fflush_stdout_and_exit(1);
}
else if (!strcmp(argv[1], "msg")) {
if (remove_ids(MSG, argc-2, &argv[2]))
bb_fflush_stdout_and_exit(1);
}
else if (!strcmp(argv[1], "sem")) {
if (remove_ids(SEM, argc-2, &argv[2]))
bb_fflush_stdout_and_exit(1);
}
else {
bb_printf ("unknown resource type: %s\n", argv[1]);
bb_show_usage();
bb_fflush_stdout_and_exit(1);
}
bb_printf ("resource(s) deleted\n");
return 0;
}
#endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */
int ipcrm_main(int argc, char **argv)
{
int c;
int error = 0;
char *prog = argv[0];
/* if the command is executed without parameters, do nothing */
if (argc == 1)
return 0;
#ifndef CONFIG_IPCRM_DROP_LEGACY
/* check to see if the command is being invoked in the old way if so
then run the old code */
if (strcmp(argv[1], "shm") == 0 ||
strcmp(argv[1], "msg") == 0 ||
strcmp(argv[1], "sem") == 0)
return deprecated_main(argc, argv);
then run the old code. Valid commands are msg, shm, sem. */
{
type_id what = 0; /* silence gcc */
char w;
if ((((w=argv[1][0]) == 'm' && argv[1][1] == 's' && argv[1][2] == 'g')
|| (argv[1][0] == 's'
&& ((w=argv[1][1]) == 'h' || w == 'e')
&& argv[1][2] == 'm'))
&& argv[1][3] == '\0') {
if (argc < 3)
bb_show_usage();
if (w == 'h')
what = SHM;
else if (w == 'm')
what = MSG;
else if (w == 'e')
what = SEM;
if (remove_ids(what, argc-2, &argv[2]))
bb_fflush_stdout_and_exit(1);
bb_printf("resource(s) deleted\n");
return 0;
}
}
#endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */
/* process new syntax to conform with SYSV ipcrm */
while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) {
int result;
int id = 0;
int iskey = isupper(c);
int iskey = (isupper)(c);
/* needed to delete semaphores */
union semun arg;
arg.val = 0;
if ((c == '?') || (c == 'h'))
{
if ((c == '?') || (c == 'h')) {
bb_show_usage();
return 0;
}
/* we don't need case information any more */
c = tolower(c);
/* make sure the option is in range */
/* make sure the option is in range: allowed are q, m, s */
if (c != 'q' && c != 'm' && c != 's') {
bb_show_usage();
error++;
return error;
}
if (iskey) {
/* keys are in hex or decimal */
key_t key = strtoul(optarg, NULL, 0);
if (key == IPC_PRIVATE) {
error++;
bb_fprintf(stderr, "%s: illegal key (%s)\n",
prog, optarg);
bb_error_msg("illegal key (%s)", optarg);
continue;
}
/* convert key to id */
id = ((c == 'q') ? msgget(key, 0) :
(c == 'm') ? shmget(key, 0, 0) :
semget(key, 0, 0));
(c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0));
if (id < 0) {
char *errmsg;
const char * const what = "key";
error++;
switch (errno) {
case EACCES:
errmsg = "permission denied for key";
errmsg = "permission denied for";
break;
case EIDRM:
errmsg = "already removed key";
errmsg = "already removed";
break;
case ENOENT:
errmsg = "invalid key";
errmsg = "invalid";
break;
default:
errmsg = "unknown error in key";
errmsg = "unknown error in";
break;
}
bb_fprintf(stderr, "%s: %s (%s)\n",
prog, errmsg, optarg);
bb_error_msg("%s %s (%s)", errmsg, what, optarg);
continue;
}
} else {
@ -232,34 +183,27 @@ int ipcrm_main(int argc, char **argv)
(c == 'm') ? shmctl(id, IPC_RMID, NULL) :
semctl(id, 0, IPC_RMID, arg));
if (result < 0) {
if (result) {
char *errmsg;
const char * const what = iskey ? "key" : "id";
error++;
switch (errno) {
case EACCES:
case EPERM:
errmsg = iskey
? "permission denied for key"
: "permission denied for id";
errmsg = "permission denied for";
break;
case EINVAL:
errmsg = iskey
? "invalid key"
: "invalid id";
errmsg = "invalid";
break;
case EIDRM:
errmsg = iskey
? "already removed key"
: "already removed id";
errmsg = "already removed";
break;
default:
errmsg = iskey
? "unknown error in key"
: "unknown error in id";
errmsg = "unknown error in";
break;
}
bb_fprintf(stderr, "%s: %s (%s)\n",
prog, errmsg, optarg);
bb_error_msg("%s %s (%s)", errmsg, what, optarg);
continue;
}
}

View File

@ -8,9 +8,7 @@
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include "busybox.h"
#include <errno.h>
#include <time.h>
#include <pwd.h>
@ -25,7 +23,7 @@
#include <sys/msg.h>
#include <sys/shm.h>
#include "busybox.h"
/*-------------------------------------------------------------------*/
/* SHM_DEST and SHM_LOCKED are defined in kernel headers,
@ -98,8 +96,10 @@ union semun {
#define TIME 4
#define PID 5
static char format;
static void print_perms (int id, struct ipc_perm *ipcp) {
static void print_perms(int id, struct ipc_perm *ipcp)
{
struct passwd *pw;
struct group *gr;
@ -125,7 +125,7 @@ static void print_perms (int id, struct ipc_perm *ipcp) {
}
static void do_shm (char format)
static void do_shm(void)
{
int maxid, shmid, id;
struct shmid_ds shmseg;
@ -192,7 +192,8 @@ static void do_shm (char format)
default:
bb_printf("------ Shared Memory Segments --------\n"
"%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n",
"key","shmid","owner","perms","bytes","nattch","status");
"key", "shmid", "owner", "perms", "bytes", "nattch",
"status");
break;
}
@ -224,8 +225,7 @@ static void do_shm (char format)
bb_printf("%-10d %-10.10s", shmid, pw->pw_name);
else
bb_printf("%-10d %-10d", shmid, ipcp->uid);
bb_printf (" %-10d %-10d\n",
shmseg.shm_cpid, shmseg.shm_lpid);
bb_printf(" %-10d %-10d\n", shmseg.shm_cpid, shmseg.shm_lpid);
break;
default:
@ -234,8 +234,7 @@ static void do_shm (char format)
bb_printf("%-10d %-10.10s", shmid, pw->pw_name);
else
bb_printf("%-10d %-10d", shmid, ipcp->uid);
bb_printf ("%-10o %-10lu %-10ld %-6s %-6s\n",
ipcp->mode & 0777,
bb_printf("%-10o %-10lu %-10ld %-6s %-6s\n", ipcp->mode & 0777,
/*
* earlier: int, Austin has size_t
*/
@ -250,11 +249,10 @@ static void do_shm (char format)
break;
}
}
return;
}
static void do_sem (char format)
static void do_sem(void)
{
int maxid, semid, id;
struct semid_ds semary;
@ -283,17 +281,14 @@ static void do_sem (char format)
"semaphore max value = %d\n",
seminfo.semmni,
seminfo.semmsl,
seminfo.semmns,
seminfo.semopm,
seminfo.semvmx);
seminfo.semmns, seminfo.semopm, seminfo.semvmx);
return;
case STATUS:
bb_printf("------ Semaphore Status --------\n"
"used arrays = %d\n"
"allocated semaphores = %d\n",
seminfo.semusz,
seminfo.semaem);
seminfo.semusz, seminfo.semaem);
return;
case CREATOR:
@ -334,6 +329,7 @@ static void do_sem (char format)
bb_printf("%-8d %-10.10s", semid, pw->pw_name);
else
bb_printf("%-8d %-10d", semid, ipcp->uid);
/* ctime uses static buffer: use separate calls */
bb_printf(" %-26.24s", semary.sem_otime
? ctime(&semary.sem_otime) : "Not set");
bb_printf(" %-26.24s\n", semary.sem_ctime
@ -348,8 +344,7 @@ static void do_sem (char format)
bb_printf("%-10d %-10.9s", semid, pw->pw_name);
else
bb_printf("%-10d %-9d", semid, ipcp->uid);
bb_printf ("%-10o %-10ld\n",
ipcp->mode & 0777,
bb_printf("%-10o %-10ld\n", ipcp->mode & 0777,
/*
* glibc-2.1.3 and earlier has unsigned short;
* glibc-2.1.91 has variation between
@ -363,7 +358,7 @@ static void do_sem (char format)
}
static void do_msg (char format)
static void do_msg(void)
{
int maxid, msqid, id;
struct msqid_ds msgque;
@ -385,9 +380,7 @@ static void do_msg (char format)
"max queues system wide = %d\n"
"max size of message (bytes) = %d\n"
"default max size of queue (bytes) = %d\n",
msginfo.msgmni,
msginfo.msgmax,
msginfo.msgmnb);
msginfo.msgmni, msginfo.msgmax, msginfo.msgmnb);
return;
case STATUS:
@ -395,9 +388,7 @@ static void do_msg (char format)
"allocated queues = %d\n"
"used headers = %d\n"
"used space = %d bytes\n",
msginfo.msgpool,
msginfo.msgmap,
msginfo.msgtql);
msginfo.msgpool, msginfo.msgmap, msginfo.msgtql);
return;
case CREATOR:
@ -452,8 +443,7 @@ static void do_msg (char format)
bb_printf("%-8d %-10.10s", msqid, pw->pw_name);
else
bb_printf("%-8d %-10d", msqid, ipcp->uid);
bb_printf (" %5d %5d\n",
msgque.msg_lspid, msgque.msg_lrpid);
bb_printf(" %5d %5d\n", msgque.msg_lspid, msgque.msg_lrpid);
break;
default:
@ -462,20 +452,17 @@ static void do_msg (char format)
bb_printf("%-10d %-10.10s", msqid, pw->pw_name);
else
bb_printf("%-10d %-10d", msqid, ipcp->uid);
bb_printf (" %-10o %-12ld %-12ld\n",
ipcp->mode & 0777,
bb_printf(" %-10o %-12ld %-12ld\n", ipcp->mode & 0777,
/*
* glibc-2.1.3 and earlier has unsigned short;
* glibc-2.1.91 has variation between
* unsigned short, unsigned long
* Austin has msgqnum_t
*/
(long) msgque.msg_cbytes,
(long) msgque.msg_qnum);
(long) msgque.msg_cbytes, (long) msgque.msg_qnum);
break;
}
}
return;
}
@ -485,27 +472,24 @@ static void print_shm (int shmid)
struct ipc_perm *ipcp = &shmds.shm_perm;
if (shmctl(shmid, IPC_STAT, &shmds) == -1) {
perror ("shmctl ");
bb_perror_msg("shmctl");
return;
}
bb_printf("\nShared memory Segment shmid=%d\n"
"uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n"
"mode=%#o\taccess_perms=%#o\n"
"bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n"
"att_time=%-26.24s\n"
"det_time=%-26.24s\n"
"change_time=%-26.24s\n"
"\n",
"bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n",
shmid,
ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
ipcp->mode, ipcp->mode & 0777,
(long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid,
(long) shmds.shm_nattch,
shmds.shm_atime ? ctime (&shmds.shm_atime) : "Not set",
shmds.shm_dtime ? ctime (&shmds.shm_dtime) : "Not set",
ctime (&shmds.shm_ctime));
return;
(long) shmds.shm_nattch);
bb_printf("att_time=%-26.24s\n",
shmds.shm_atime ? ctime(&shmds.shm_atime) : "Not set");
bb_printf("det_time=%-26.24s\n",
shmds.shm_dtime ? ctime(&shmds.shm_dtime) : "Not set");
bb_printf("change_time=%-26.24s\n\n", ctime(&shmds.shm_ctime));
}
@ -515,19 +499,14 @@ static void print_msg (int msqid)
struct ipc_perm *ipcp = &buf.msg_perm;
if (msgctl(msqid, IPC_STAT, &buf) == -1) {
perror ("msgctl ");
bb_perror_msg("msgctl");
return;
}
bb_printf("\nMessage Queue msqid=%d\n"
"uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n"
"cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n"
"send_time=%-26.24s\n"
"rcv_time=%-26.24s\n"
"change_time=%-26.24s\n"
"\n",
msqid,
ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode,
"cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n",
msqid, ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode,
/*
* glibc-2.1.3 and earlier has unsigned short;
* glibc-2.1.91 has variation between
@ -535,11 +514,14 @@ static void print_msg (int msqid)
* Austin has msgqnum_t (for msg_qbytes)
*/
(long) buf.msg_cbytes, (long) buf.msg_qbytes,
(long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid,
buf.msg_stime ? ctime (&buf.msg_stime) : "Not set",
buf.msg_rtime ? ctime (&buf.msg_rtime) : "Not set",
(long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid);
bb_printf("send_time=%-26.24s\n",
buf.msg_stime ? ctime(&buf.msg_stime) : "Not set");
bb_printf("rcv_time=%-26.24s\n",
buf.msg_rtime ? ctime(&buf.msg_rtime) : "Not set");
bb_printf("change_time=%-26.24s\n\n",
buf.msg_ctime ? ctime(&buf.msg_ctime) : "Not set");
return;
}
static void print_sem(int semid)
@ -550,8 +532,8 @@ static void print_sem (int semid)
unsigned int i;
arg.buf = &semds;
if (semctl (semid, 0, IPC_STAT, arg) < 0) {
perror ("semctl ");
if (semctl(semid, 0, IPC_STAT, arg)) {
bb_perror_msg("semctl");
return;
}
@ -559,57 +541,60 @@ static void print_sem (int semid)
"uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n"
"mode=%#o, access_perms=%#o\n"
"nsems = %ld\n"
"otime = %-26.24s\n"
"ctime = %-26.24s\n"
"%-10s %-10s %-10s %-10s %-10s\n",
"otime = %-26.24s\n",
semid,
ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
ipcp->mode, ipcp->mode & 0777,
(long) semds.sem_nsems,
semds.sem_otime ? ctime (&semds.sem_otime) : "Not set",
semds.sem_otime ? ctime(&semds.sem_otime) : "Not set");
bb_printf("ctime = %-26.24s\n"
"%-10s %-10s %-10s %-10s %-10s\n",
ctime(&semds.sem_ctime),
"semnum", "value", "ncount", "zcount", "pid");
arg.val = 0;
for (i = 0; i < semds.sem_nsems; i++) {
int val, ncnt, zcnt, pid;
val = semctl(semid, i, GETVAL, arg);
ncnt = semctl(semid, i, GETNCNT, arg);
zcnt = semctl(semid, i, GETZCNT, arg);
pid = semctl(semid, i, GETPID, arg);
if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) {
perror ("semctl ");
bb_fflush_stdout_and_exit (1);
bb_perror_msg_and_die("semctl");
}
bb_printf ("%-10d %-10d %-10d %-10d %-10d\n",
i, val, ncnt, zcnt, pid);
bb_printf("%-10d %-10d %-10d %-10d %-10d\n", i, val, ncnt, zcnt, pid);
}
bb_printf("\n");
return;
}
int ipcs_main (int argc, char **argv) {
int opt, msg = 0, sem = 0, shm = 0, id=0, print=0;
char format = 0;
char options[] = "atclupsmqi:ih?";
int ipcs_main(int argc, char **argv)
{
int opt, id = 0;
unsigned flags = 0;
#define flag_print (1<<0)
#define flag_msg (1<<1)
#define flag_sem (1<<2)
#define flag_shm (1<<3)
const char *const options = "atclupsmqi:ih?";
while ((opt = getopt(argc, argv, options)) != -1) {
switch (opt) {
case 'i':
id = atoi(optarg);
print = 1;
flags |= flag_print;
break;
case 'a':
msg = shm = sem = 1;
flags |= flag_msg | flag_sem | flag_shm;
break;
case 'q':
msg = 1;
flags |= flag_msg;
break;
case 's':
sem = 1;
flags |= flag_sem;
break;
case 'm':
shm = 1;
flags |= flag_shm;
break;
case 't':
format = TIME;
@ -629,43 +614,40 @@ int ipcs_main (int argc, char **argv) {
case 'h':
case '?':
bb_show_usage();
bb_fflush_stdout_and_exit (0);
}
}
if (print) {
if (shm) {
if (flags & flag_print) {
if (flags & flag_shm) {
print_shm(id);
bb_fflush_stdout_and_exit(0);
}
if (sem) {
if (flags & flag_sem) {
print_sem(id);
bb_fflush_stdout_and_exit(0);
}
if (msg) {
if (flags & flag_msg) {
print_msg(id);
bb_fflush_stdout_and_exit(0);
}
bb_show_usage();
bb_fflush_stdout_and_exit (0);
}
if ( !shm && !msg && !sem)
msg = sem = shm = 1;
if (!(flags & (flag_shm | flag_msg | flag_sem)))
flags |= flag_msg | flag_shm | flag_sem;
bb_printf("\n");
if (shm) {
do_shm (format);
if (flags & flag_shm) {
do_shm();
bb_printf("\n");
}
if (sem) {
do_sem (format);
if (flags & flag_sem) {
do_sem();
bb_printf("\n");
}
if (msg) {
do_msg (format);
if (flags & flag_msg) {
do_msg();
bb_printf("\n");
}
return 0;
return EXIT_SUCCESS;
}