- 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:
parent
6ce8dae1d5
commit
73561cc75a
20 changed files with 1164 additions and 1285 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
487
coreutils/cut.c
487
coreutils/cut.c
|
@ -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(<ok, "-");
|
||||
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(<ok, "-");
|
||||
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, <ok);
|
||||
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(<ok, "-");
|
||||
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(<ok, "-");
|
||||
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;
|
||||
}
|
||||
|
|
260
coreutils/date.c
260
coreutils/date.c
|
@ -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) {
|
||||
|
|
128
coreutils/dd.c
128
coreutils/dd.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
402
coreutils/expr.c
402
coreutils/expr.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue