- 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

@ -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;
else for(;;) {
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;
for (i=0; i<res; i++) {
char c=bb_common_bufsiz1[i];
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

@ -3,12 +3,13 @@
* cksum - calculate the CRC32 checksum of a file
*
* Copyright (C) 2006 by Rob Sullivan, with ideas from code by Walter Harms
*
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */
#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,36 +18,36 @@ 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 {
fp = bb_wfopen_input((inp_stdin) ? bb_msg_standard_input : *++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];
}
filesize = length;
for (; length; length >>= 8)
crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL];
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));
} while (*(argv + 1));
return EXIT_SUCCESS;
}

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,28 +4,24 @@
*
* 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 char delim = '\t'; /* delimiter, default is tab */
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 {
int startpos;
@ -38,295 +34,268 @@ 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;
if (la->startpos > lb->startpos)
return 1;
if (la->startpos < lb->startpos)
return -1;
return 0;
}
/*
* parse_lists() - parses a list and puts 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;
int s = 0, e = 0;
/* take apart the lists, one by one (they are separated with commas */
while ((ltok = strsep(&lists, ",")) != NULL) {
/* it's actually legal to pass an empty list */
if (strlen(ltok) == 0)
continue;
/* get the start pos */
ntok = strsep(&ltok, "-");
if (ntok == NULL) {
fprintf(stderr, "Help ntok is null for starting position! What do I do?\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 */
if (s != 0)
s--;
}
/* get the end pos */
ntok = strsep(&ltok, "-");
if (ntok == NULL) {
e = NON_RANGE;
} 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");
/* if the user specified and end position of 0, that means "til the
* end of the line */
if (e == 0)
e = INT_MAX;
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 (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[nlists-1].startpos = s;
cut_lists[nlists-1].endpos = e;
}
/* make sure we got some cut positions out of all that */
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);
return (((struct cut_list *) a)->startpos -
((struct cut_list *) b)->startpos);
}
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
*/
static void cut_file(FILE *file)
static void cut_file(FILE * file)
{
char *line = NULL;
unsigned int linenum = 0; /* keep these zero-based to be consistent */
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 ((part & (OPT_CHAR_FLGS | OPT_BYTE_FLGS)))
cut_line_by_chars(line);
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;
/* cut based on fields */
else {
if (delim == '\n')
cut_file_by_lines(line, linenum);
else
cut_line_by_fields(line);
/* 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(line);
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)
{
unsigned long opt;
char *sopt, *sdopt;
char *sopt, *ltok;
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)
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");
parse_lists(sopt);
if((opt & (OPT_DELIM_FLGS))) {
if (strlen(sdopt) > 1) {
if ((opt & (CUT_OPT_DELIM_FLGS))) {
if (strlen(ltok) > 1) {
bb_error_msg_and_die("the delimiter must be a single character");
}
delim = sdopt[0];
delim = ltok[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 (!(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 only when operating on fields");
bb_error_msg_and_die
("a delimiter may be specified%s", _op_on_field);
}
}
/*
* 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
*/
{
char *ntok;
int s = 0, e = 0;
/* take apart the lists, one by one (they are separated with commas */
while ((ltok = strsep(&sopt, ",")) != NULL) {
/* it's actually legal to pass an empty list */
if (strlen(ltok) == 0)
continue;
/* get the start pos */
ntok = strsep(&ltok, "-");
if (ntok == NULL) {
bb_error_msg
("internal error: ntok is null for start pos!?\n");
} else if (strlen(ntok) == 0) {
s = BOL;
} else {
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--;
}
/* get the end pos */
ntok = strsep(&ltok, "-");
if (ntok == NULL) {
e = NON_RANGE;
} else if (strlen(ntok) == 0) {
e = EOL;
} else {
e = getval(ntok);
/* if the user specified and end position of 0, that means "til the
* end of the line */
if (e == 0)
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 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[nlists - 1].startpos = s;
cut_lists[nlists - 1].endpos = e;
}
/* make sure we got some cut positions out of all that */
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);
}
/* 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");
if(file) {
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,119 +32,45 @@
#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:"),
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 (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) {
bb_show_usage();
}
if (ifmt == 4) /* parse error */
bb_show_usage();
}
}
@ -156,18 +78,19 @@ 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];
}
/* Now we have parsed all the information except the date format
which depends on whether the clock is being set or read */
if(filename) {
if (filename) {
struct stat statbuf;
xstat(filename,&statbuf);
tm=statbuf.st_mtime;
} else time(&tm);
xstat(filename, &statbuf);
tm = statbuf.st_mtime;
} 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 {
bb_error_msg_and_die(bb_msg_invalid_date, date_str);
}
} else {
date_conv_time(&tm_time, date_str);
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;
*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,72 +24,72 @@ 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));
sa.sa_handler = dd_output_status;
sa.sa_handler = dd_output_status;
sa.sa_flags = SA_RESTART;
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, 0);
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);
}
if (fstat(ofd, &st) < 0 || S_ISREG(st.st_mode) ||
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)
@ -49,8 +51,8 @@ typedef long arith_t;
/* A value is.... */
struct valinfo {
TYPE type; /* Which kind. */
union { /* The value itself. */
TYPE type; /* Which kind. */
union { /* The value itself. */
arith_t i;
char *s;
} u;
@ -60,17 +62,17 @@ typedef struct valinfo VALUE;
/* The arguments given to the program, minus the program name. */
static char **args;
static VALUE *docolon (VALUE *sv, VALUE *pv);
static VALUE *eval (void);
static VALUE *int_value (arith_t i);
static VALUE *str_value (char *s);
static int nextarg (char *str);
static int null (VALUE *v);
static int toarith (VALUE *v);
static void freev (VALUE *v);
static void tostring (VALUE *v);
static VALUE *docolon(VALUE * sv, VALUE * pv);
static VALUE *eval(void);
static VALUE *int_value(arith_t i);
static VALUE *str_value(char *s);
static int nextarg(char *str);
static int null(VALUE * v);
static int toarith(VALUE * v);
static void freev(VALUE * v);
static void tostring(VALUE * v);
int expr_main (int argc, char **argv)
int expr_main(int argc, char **argv)
{
VALUE *v;
@ -80,25 +82,25 @@ int expr_main (int argc, char **argv)
args = argv + 1;
v = eval ();
v = eval();
if (*args)
bb_error_msg_and_die ("syntax error");
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);
puts(v->u.s);
exit (null (v));
exit(null(v));
}
/* Return a VALUE for I. */
static VALUE *int_value (arith_t i)
static VALUE *int_value(arith_t i)
{
VALUE *v;
v = xmalloc (sizeof(VALUE));
v = xmalloc(sizeof(VALUE));
v->type = integer;
v->u.i = i;
return v;
@ -106,7 +108,7 @@ static VALUE *int_value (arith_t i)
/* Return a VALUE for S. */
static VALUE *str_value (char *s)
static VALUE *str_value(char *s)
{
VALUE *v;
@ -118,28 +120,26 @@ static VALUE *str_value (char *s)
/* Free VALUE V, including structure components. */
static void freev (VALUE *v)
static void freev(VALUE * v)
{
if (v->type == string)
free (v->u.s);
free (v);
free(v->u.s);
free(v);
}
/* Return nonzero if V is a null-string or zero-number. */
static int null (VALUE *v)
static int null(VALUE * v)
{
switch (v->type) {
case integer:
return v->u.i == 0;
default: /* string: */
return v->u.s[0] == '\0' || strcmp (v->u.s, "0") == 0;
}
if (v->type == integer)
return v->u.i == 0;
else /* string: */
return v->u.s[0] == '\0' || strcmp(v->u.s, "0") == 0;
}
/* Coerce V to a string value (can't fail). */
static void tostring (VALUE *v)
static void tostring(VALUE * v)
{
if (v->type == integer) {
v->u.s = xasprintf("%" PF_REZ "d", PF_REZ_TYPE v->u.i);
@ -149,9 +149,9 @@ static void tostring (VALUE *v)
/* Coerce V to an integer value. Return 1 on success, 0 on failure. */
static int toarith (VALUE *v)
static int toarith(VALUE * v)
{
if(v->type == string) {
if (v->type == string) {
arith_t i;
char *e;
@ -160,7 +160,7 @@ static int toarith (VALUE *v)
i = STRTOL(v->u.s, &e, 10);
if ((v->u.s == e) || *e)
return 0;
free (v->u.s);
free(v->u.s);
v->u.i = i;
v->type = integer;
}
@ -170,221 +170,207 @@ 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;
return strcmp (*args, str) == 0;
return strcmp(*args, str) == 0;
}
/* The comparison operator handling functions. */
static int cmp_common (VALUE *l, VALUE *r, int op)
static int cmp_common(VALUE * l, VALUE * r, int op)
{
int cmpval;
if (l->type == string || r->type == string) {
tostring (l);
tostring (r);
cmpval = strcmp (l->u.s, r->u.s);
}
else
tostring(l);
tostring(r);
cmpval = strcmp(l->u.s, r->u.s);
} else
cmpval = l->u.i - r->u.i;
switch(op) {
case '<':
return cmpval < 0;
case ('L'+'E'):
return cmpval <= 0;
case '=':
return cmpval == 0;
case '!':
return cmpval != 0;
case '>':
return cmpval > 0;
default: /* >= */
return cmpval >= 0;
}
if (op == '<')
return cmpval < 0;
else if (op == ('L' + 'E'))
return cmpval <= 0;
else if (op == '=')
return cmpval == 0;
else if (op == '!')
return cmpval != 0;
else if (op == '>')
return cmpval > 0;
else /* >= */
return cmpval >= 0;
}
/* The arithmetic operator handling functions. */
static arith_t arithmetic_common (VALUE *l, VALUE *r, int op)
static arith_t arithmetic_common(VALUE * l, VALUE * r, int op)
{
arith_t li, ri;
arith_t li, ri;
if (!toarith (l) || !toarith (r))
bb_error_msg_and_die ("non-numeric argument");
li = l->u.i;
ri = r->u.i;
if((op == '/' || op == '%') && ri == 0)
bb_error_msg_and_die ( "division by zero");
switch(op) {
case '+':
if (!toarith(l) || !toarith(r))
bb_error_msg_and_die("non-numeric argument");
li = l->u.i;
ri = r->u.i;
if ((op == '/' || op == '%') && ri == 0)
bb_error_msg_and_die("division by zero");
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),
PV is the VALUE for the rhs (the pattern). */
static VALUE *docolon (VALUE *sv, VALUE *pv)
static VALUE *docolon(VALUE * sv, VALUE * pv)
{
VALUE *v;
regex_t re_buffer;
const int NMATCH = 2;
regmatch_t re_regs[NMATCH];
tostring (sv);
tostring (pv);
tostring(sv);
tostring(pv);
if (pv->u.s[0] == '^') {
fprintf (stderr, "\
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));
memset (re_regs, 0, sizeof (*re_regs));
if( regcomp (&re_buffer, pv->u.s, 0) != 0 )
memset(&re_buffer, 0, sizeof(re_buffer));
memset(re_regs, 0, sizeof(*re_regs));
if (regcomp(&re_buffer, pv->u.s, 0) != 0)
bb_error_msg_and_die("Invalid regular expression");
/* expr uses an anchored pattern match, so check that there was a
* match and that the match starts at offset 0. */
if (regexec (&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH &&
re_regs[0].rm_so == 0) {
if (regexec(&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH &&
re_regs[0].rm_so == 0) {
/* Were \(...\) used? */
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
v = int_value (re_regs[0].rm_eo);
}
else {
v = str_value(sv->u.s + re_regs[1].rm_so);
} else
v = int_value(re_regs[0].rm_eo);
} else {
/* Match failed -- return the right kind of null. */
if (re_buffer.re_nsub > 0)
v = str_value ("");
v = str_value("");
else
v = int_value (0);
v = int_value(0);
}
return v;
}
/* Handle bare operands and ( expr ) syntax. */
static VALUE *eval7 (void)
static VALUE *eval7(void)
{
VALUE *v;
if (!*args)
bb_error_msg_and_die ( "syntax error");
bb_error_msg_and_die("syntax error");
if (nextarg ("(")) {
if (nextarg("(")) {
args++;
v = eval ();
if (!nextarg (")"))
bb_error_msg_and_die ( "syntax error");
args++;
return v;
}
v = eval();
if (!nextarg(")"))
bb_error_msg_and_die("syntax error");
args++;
return v;
}
if (nextarg (")"))
bb_error_msg_and_die ( "syntax error");
if (nextarg(")"))
bb_error_msg_and_die("syntax error");
return str_value (*args++);
return str_value(*args++);
}
/* Handle match, substr, index, length, and quote keywords. */
static VALUE *eval6 (void)
static VALUE *eval6(void)
{
VALUE *l, *r, *v, *i1, *i2;
if (nextarg ("quote")) {
if (nextarg("quote")) {
args++;
if (!*args)
bb_error_msg_and_die ( "syntax error");
return str_value (*args++);
}
else if (nextarg ("length")) {
bb_error_msg_and_die("syntax error");
return str_value(*args++);
} else if (nextarg("length")) {
args++;
r = eval6 ();
tostring (r);
v = int_value (strlen (r->u.s));
freev (r);
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 ();
v = docolon (l, r);
freev (l);
freev (r);
l = eval6();
r = eval6();
v = docolon(l, r);
freev(l);
freev(r);
return v;
}
else if (nextarg ("index")) {
} else if (nextarg("index")) {
args++;
l = eval6 ();
r = eval6 ();
tostring (l);
tostring (r);
v = int_value (strcspn (l->u.s, r->u.s) + 1);
if (v->u.i == (arith_t) strlen (l->u.s) + 1)
l = eval6();
r = eval6();
tostring(l);
tostring(r);
v = int_value(strcspn(l->u.s, r->u.s) + 1);
if (v->u.i == (arith_t) strlen(l->u.s) + 1)
v->u.i = 0;
freev (l);
freev (r);
freev(l);
freev(r);
return v;
}
else if (nextarg ("substr")) {
} else if (nextarg("substr")) {
args++;
l = eval6 ();
i1 = eval6 ();
i2 = eval6 ();
tostring (l);
if (!toarith (i1) || !toarith (i2)
|| i1->u.i > (arith_t) strlen (l->u.s)
l = eval6();
i1 = eval6();
i2 = eval6();
tostring(l);
if (!toarith(i1) || !toarith(i2)
|| i1->u.i > (arith_t) strlen(l->u.s)
|| i1->u.i <= 0 || i2->u.i <= 0)
v = str_value ("");
v = str_value("");
else {
v = xmalloc (sizeof(VALUE));
v = xmalloc(sizeof(VALUE));
v->type = string;
v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i);
}
freev (l);
freev (i1);
freev (i2);
freev(l);
freev(i1);
freev(i2);
return v;
}
else
return eval7 ();
} else
return eval7();
}
/* Handle : operator (pattern matching).
Calls docolon to do the real work. */
static VALUE *eval5 (void)
static VALUE *eval5(void)
{
VALUE *l, *r, *v;
l = eval6 ();
while (nextarg (":")) {
l = eval6();
while (nextarg(":")) {
args++;
r = eval6 ();
v = docolon (l, r);
freev (l);
freev (r);
r = eval6();
v = docolon(l, r);
freev(l);
freev(r);
l = v;
}
return l;
@ -392,128 +378,126 @@ static VALUE *eval5 (void)
/* Handle *, /, % operators. */
static VALUE *eval4 (void)
static VALUE *eval4(void)
{
VALUE *l, *r;
int op;
arith_t val;
l = eval5 ();
l = eval5();
while (1) {
if (nextarg ("*"))
if (nextarg("*"))
op = '*';
else if (nextarg ("/"))
else if (nextarg("/"))
op = '/';
else if (nextarg ("%"))
else if (nextarg("%"))
op = '%';
else
return l;
args++;
r = eval5 ();
val = arithmetic_common (l, r, op);
freev (l);
freev (r);
l = int_value (val);
r = eval5();
val = arithmetic_common(l, r, op);
freev(l);
freev(r);
l = int_value(val);
}
}
/* Handle +, - operators. */
static VALUE *eval3 (void)
static VALUE *eval3(void)
{
VALUE *l, *r;
int op;
arith_t val;
l = eval4 ();
l = eval4();
while (1) {
if (nextarg ("+"))
if (nextarg("+"))
op = '+';
else if (nextarg ("-"))
else if (nextarg("-"))
op = '-';
else
return l;
args++;
r = eval4 ();
val = arithmetic_common (l, r, op);
freev (l);
freev (r);
l = int_value (val);
r = eval4();
val = arithmetic_common(l, r, op);
freev(l);
freev(r);
l = int_value(val);
}
}
/* Handle comparisons. */
static VALUE *eval2 (void)
static VALUE *eval2(void)
{
VALUE *l, *r;
int op;
arith_t val;
l = eval3 ();
l = eval3();
while (1) {
if (nextarg ("<"))
if (nextarg("<"))
op = '<';
else if (nextarg ("<="))
op = 'L'+'E';
else if (nextarg ("=") || nextarg ("=="))
else if (nextarg("<="))
op = 'L' + 'E';
else if (nextarg("=") || nextarg("=="))
op = '=';
else if (nextarg ("!="))
else if (nextarg("!="))
op = '!';
else if (nextarg (">="))
op = 'G'+'E';
else if (nextarg (">"))
else if (nextarg(">="))
op = 'G' + 'E';
else if (nextarg(">"))
op = '>';
else
return l;
args++;
r = eval3 ();
toarith (l);
toarith (r);
val = cmp_common (l, r, op);
freev (l);
freev (r);
l = int_value (val);
r = eval3();
toarith(l);
toarith(r);
val = cmp_common(l, r, op);
freev(l);
freev(r);
l = int_value(val);
}
}
/* Handle &. */
static VALUE *eval1 (void)
static VALUE *eval1(void)
{
VALUE *l, *r;
l = eval2 ();
while (nextarg ("&")) {
l = eval2();
while (nextarg("&")) {
args++;
r = eval2 ();
if (null (l) || null (r)) {
freev (l);
freev (r);
l = int_value (0);
}
else
freev (r);
r = eval2();
if (null(l) || null(r)) {
freev(l);
freev(r);
l = int_value(0);
} else
freev(r);
}
return l;
}
/* Handle |. */
static VALUE *eval (void)
static VALUE *eval(void)
{
VALUE *l, *r;
l = eval1 ();
while (nextarg ("|")) {
l = eval1();
while (nextarg("|")) {
args++;
r = eval1 ();
if (null (l)) {
freev (l);
r = eval1();
if (null(l)) {
freev(l);
l = r;
}
else
freev (r);
} 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)
{
@ -37,7 +38,7 @@ int tee_main(int argc, char **argv)
/* gnu tee ignores SIGPIPE in case one of the output files is a pipe
* that doesn't consume all its input. Good idea... */
signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction.*/
signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction.*/
/* Allocate an array of FILE *'s, with one extra for a sentinal. */
p = files = (FILE **)xmalloc(sizeof(FILE *) * (argc - optind + 2));

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);
}