- 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
1
Makefile
1
Makefile
@ -278,6 +278,7 @@ endif # CONFIG_FEATURE_FULL_LIBBUSYBOX
|
|||||||
APPLET_SRC:=$(APPLET_SRC-y)
|
APPLET_SRC:=$(APPLET_SRC-y)
|
||||||
APPLETS_DEFINE:=$(APPLETS_DEFINE-y)
|
APPLETS_DEFINE:=$(APPLETS_DEFINE-y)
|
||||||
else # CONFIG_BUILD_AT_ONCE
|
else # CONFIG_BUILD_AT_ONCE
|
||||||
|
APPLET_SRC:=
|
||||||
# no --combine, build archives out of the individual .o
|
# no --combine, build archives out of the individual .o
|
||||||
# This was the old way the binary was built.
|
# This was the old way the binary was built.
|
||||||
libbusybox-obj:=archival/libunarchive/libunarchive.a \
|
libbusybox-obj:=archival/libunarchive/libunarchive.a \
|
||||||
|
@ -14,49 +14,55 @@
|
|||||||
|
|
||||||
int catv_main(int argc, char **argv)
|
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 = bb_getopt_ulflags(argc, argv, "etv");
|
||||||
flags ^= 4;
|
#define CATV_OPT_e (1<<0)
|
||||||
|
#define CATV_OPT_t (1<<1)
|
||||||
// Loop through files.
|
#define CATV_OPT_v (1<<2)
|
||||||
|
flags ^= CATV_OPT_v;
|
||||||
|
|
||||||
argv += optind;
|
argv += optind;
|
||||||
do {
|
do {
|
||||||
// Read from stdin if there's nothing else to do.
|
/* Read from stdin if there's nothing else to do. */
|
||||||
|
|
||||||
fd = 0;
|
fd = 0;
|
||||||
if (*argv && 0>(fd = xopen(*argv, O_RDONLY))) retval = EXIT_FAILURE;
|
if (*argv && 0 > (fd = xopen(*argv, O_RDONLY)))
|
||||||
else for(;;) {
|
retval = EXIT_FAILURE;
|
||||||
|
else for (;;) {
|
||||||
int i, res;
|
int i, res;
|
||||||
|
|
||||||
res = read(fd, bb_common_bufsiz1, sizeof(bb_common_bufsiz1));
|
res = read(fd, bb_common_bufsiz1, sizeof(bb_common_bufsiz1));
|
||||||
if (res < 0) retval = EXIT_FAILURE;
|
if (res < 0)
|
||||||
if (res <1) break;
|
retval = EXIT_FAILURE;
|
||||||
for (i=0; i<res; i++) {
|
if (res < 1)
|
||||||
char c=bb_common_bufsiz1[i];
|
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) {
|
if (c == 127) {
|
||||||
printf("^?");
|
bb_printf("^?");
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
printf("M-");
|
bb_printf("M-");
|
||||||
c -= 128;
|
c -= 128;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c < 32) {
|
if (c < 32) {
|
||||||
if (c == 10) {
|
if (c == 10) {
|
||||||
if (flags & 1) putchar('$');
|
if (flags & CATV_OPT_e)
|
||||||
} else if (flags & (c==9 ? 2 : 4)) {
|
putchar('$');
|
||||||
printf("^%c", c+'@');
|
} else if (flags & (c==9 ? CATV_OPT_t : CATV_OPT_v)) {
|
||||||
|
bb_printf("^%c", c+'@');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
putchar(c);
|
putchar(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ENABLE_FEATURE_CLEAN_UP && fd) close(fd);
|
if (ENABLE_FEATURE_CLEAN_UP && fd)
|
||||||
|
close(fd);
|
||||||
} while (*++argv);
|
} while (*++argv);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -3,12 +3,13 @@
|
|||||||
* cksum - calculate the CRC32 checksum of a file
|
* cksum - calculate the CRC32 checksum of a file
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 by Rob Sullivan, with ideas from code by Walter Harms
|
* 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. */
|
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */
|
||||||
|
|
||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
|
|
||||||
int cksum_main(int argc, char **argv) {
|
int cksum_main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
|
||||||
uint32_t *crc32_table = crc32_filltable(1);
|
uint32_t *crc32_table = crc32_filltable(1);
|
||||||
|
|
||||||
@ -17,36 +18,36 @@ int cksum_main(int argc, char **argv) {
|
|||||||
long length, filesize;
|
long length, filesize;
|
||||||
int bytes_read;
|
int bytes_read;
|
||||||
char *cp;
|
char *cp;
|
||||||
RESERVE_CONFIG_BUFFER(buf, BUFSIZ);
|
|
||||||
int inp_stdin = (argc == optind) ? 1 : 0;
|
int inp_stdin = (argc == optind) ? 1 : 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
fp = bb_wfopen_input((inp_stdin) ? bb_msg_standard_input : *++argv);
|
fp = bb_wfopen_input((inp_stdin) ? bb_msg_standard_input : *++argv);
|
||||||
|
|
||||||
crc = 0;
|
crc = 0;
|
||||||
length = 0;
|
length = 0;
|
||||||
|
|
||||||
while ((bytes_read = fread(buf, 1, BUFSIZ, fp)) > 0) {
|
while ((bytes_read = fread(bb_common_bufsiz1, 1, BUFSIZ, fp)) > 0) {
|
||||||
cp = buf;
|
cp = bb_common_bufsiz1;
|
||||||
length += bytes_read;
|
length += bytes_read;
|
||||||
while (bytes_read--)
|
while (bytes_read--)
|
||||||
crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL];
|
crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL];
|
||||||
}
|
}
|
||||||
|
|
||||||
filesize = length;
|
filesize = length;
|
||||||
|
|
||||||
for (; length; length >>= 8)
|
for (; length; length >>= 8)
|
||||||
crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL];
|
crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL];
|
||||||
crc ^= 0xffffffffL;
|
crc ^= 0xffffffffL;
|
||||||
|
|
||||||
if (inp_stdin) {
|
if (inp_stdin) {
|
||||||
printf("%"PRIu32" %li\n", crc, filesize);
|
bb_printf("%" PRIu32 " %li\n", crc, filesize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%"PRIu32" %li %s\n", crc, filesize, *argv);
|
bb_printf("%" PRIu32 " %li %s\n", crc, filesize, *argv);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
} while (*(argv+1));
|
} while (*(argv + 1));
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
|
|
||||||
static FILE *cmp_xfopen_input(const char *filename)
|
static FILE *cmp_xfopen_input(const char * const filename)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
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 fmt_l_opt[] = "%.0s%.0s%d %3o %3o\n";
|
||||||
|
|
||||||
static const char opt_chars[] = "sl";
|
static const char opt_chars[] = "sl";
|
||||||
|
#define CMP_OPT_s (1<<0)
|
||||||
enum {
|
#define CMP_OPT_l (1<<1)
|
||||||
OPT_s = 1,
|
|
||||||
OPT_l = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
int cmp_main(int argc, char **argv)
|
int cmp_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
FILE *fp1, *fp2, *outfile = stdout;
|
FILE *fp1, *fp2, *outfile = stdout;
|
||||||
const char *filename1, *filename2;
|
const char *filename1, *filename2 = "-";
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
int c1, c2, char_pos, line_pos;
|
int c1, c2, char_pos = 0, line_pos = 1;
|
||||||
int opt_flags;
|
unsigned opt;
|
||||||
int exit_val = 0;
|
int retval = 0;
|
||||||
|
|
||||||
bb_default_error_retval = 2; /* 1 is returned if files are different. */
|
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();
|
bb_show_usage();
|
||||||
}
|
|
||||||
|
|
||||||
fp1 = cmp_xfopen_input(filename1 = *(argv += optind));
|
fp1 = cmp_xfopen_input(filename1 = *(argv += optind));
|
||||||
|
|
||||||
filename2 = "-";
|
|
||||||
if (*++argv) {
|
if (*++argv) {
|
||||||
filename2 = *argv;
|
filename2 = *argv;
|
||||||
}
|
}
|
||||||
@ -79,19 +75,17 @@ int cmp_main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt = fmt_differ;
|
if (opt & CMP_OPT_l)
|
||||||
if (opt_flags == OPT_l) {
|
|
||||||
fmt = fmt_l_opt;
|
fmt = fmt_l_opt;
|
||||||
}
|
else
|
||||||
|
fmt = fmt_differ;
|
||||||
|
|
||||||
char_pos = 0;
|
|
||||||
line_pos = 1;
|
|
||||||
do {
|
do {
|
||||||
c1 = getc(fp1);
|
c1 = getc(fp1);
|
||||||
c2 = getc(fp2);
|
c2 = getc(fp2);
|
||||||
++char_pos;
|
++char_pos;
|
||||||
if (c1 != c2) { /* Remember -- a read error may have occurred. */
|
if (c1 != c2) { /* Remember: a read error may have occurred. */
|
||||||
exit_val = 1; /* But assume the files are different for now. */
|
retval = 1; /* But assume the files are different for now. */
|
||||||
if (c2 == EOF) {
|
if (c2 == EOF) {
|
||||||
/* We know that fp1 isn't at EOF or in an error state. But to
|
/* 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
|
* 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. */
|
* make sure we fflush before writing to stderr. */
|
||||||
xfflush_stdout();
|
xfflush_stdout();
|
||||||
}
|
}
|
||||||
if (opt_flags != OPT_s) {
|
if (!opt & CMP_OPT_s) {
|
||||||
if (opt_flags == OPT_l) {
|
if (opt & CMP_OPT_l) {
|
||||||
line_pos = c1; /* line_pos is unused in the -l case. */
|
line_pos = c1; /* line_pos is unused in the -l case. */
|
||||||
}
|
}
|
||||||
bb_fprintf(outfile, fmt, filename1, filename2, char_pos, line_pos, c2);
|
bb_fprintf(outfile, fmt, filename1, filename2, char_pos, line_pos, c2);
|
||||||
if (opt_flags) { /* This must be -l since not -s. */
|
if (opt) { /* This must be -l since not -s. */
|
||||||
/* If we encountered and EOF, the while check will catch it. */
|
/* If we encountered an EOF,
|
||||||
|
* the while check will catch it. */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,5 +124,5 @@ int cmp_main(int argc, char **argv)
|
|||||||
xferror(fp1, filename1);
|
xferror(fp1, filename1);
|
||||||
xferror(fp2, filename2);
|
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.
|
* Copyright (C) 1999,2000,2001 by Lineo, inc.
|
||||||
* Written by Mark Whitley <markw@codepoet.org>
|
* Written by Mark Whitley <markw@codepoet.org>
|
||||||
|
* debloated by Bernhard Fischer
|
||||||
*
|
*
|
||||||
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
|
* 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"
|
#include "busybox.h"
|
||||||
|
|
||||||
|
|
||||||
/* option vars */
|
/* option vars */
|
||||||
static const char optstring[] = "b:c:f:d:sn";
|
static const char *const optstring = "b:c:f:d:sn";
|
||||||
#define OPT_BYTE_FLGS 1
|
|
||||||
#define OPT_CHAR_FLGS 2
|
#define CUT_OPT_BYTE_FLGS (1<<0)
|
||||||
#define OPT_FIELDS_FLGS 4
|
#define CUT_OPT_CHAR_FLGS (1<<1)
|
||||||
#define OPT_DELIM_FLGS 8
|
#define CUT_OPT_FIELDS_FLGS (1<<2)
|
||||||
#define OPT_SUPRESS_FLGS 16
|
#define CUT_OPT_DELIM_FLGS (1<<3)
|
||||||
static char part; /* (b)yte, (c)har, (f)ields */
|
#define CUT_OPT_SUPPRESS_FLGS (1<<4)
|
||||||
static unsigned int supress_non_delimited_lines;
|
static unsigned long opt;
|
||||||
static char delim = '\t'; /* delimiter, default is tab */
|
|
||||||
|
static char delim = '\t'; /* delimiter, default is tab */
|
||||||
|
|
||||||
struct cut_list {
|
struct cut_list {
|
||||||
int startpos;
|
int startpos;
|
||||||
@ -38,295 +34,268 @@ enum {
|
|||||||
NON_RANGE = -1
|
NON_RANGE = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cut_list *cut_lists = NULL; /* growable array holding a series of lists */
|
/* growable array holding a series of lists */
|
||||||
static unsigned int nlists = 0; /* number of elements in above list */
|
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)
|
static int cmpfunc(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
struct cut_list *la = (struct cut_list *)a;
|
return (((struct cut_list *) a)->startpos -
|
||||||
struct cut_list *lb = (struct cut_list *)b;
|
((struct cut_list *) b)->startpos);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cut_file(FILE * file)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
char *line = NULL;
|
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 */
|
/* go through every line in the file */
|
||||||
while ((line = bb_get_chomped_line_from_file(file)) != NULL) {
|
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 */
|
/* cut based on chars/bytes XXX: only works when sizeof(char) == byte */
|
||||||
if ((part & (OPT_CHAR_FLGS | OPT_BYTE_FLGS)))
|
if ((opt & (CUT_OPT_CHAR_FLGS | CUT_OPT_BYTE_FLGS))) {
|
||||||
cut_line_by_chars(line);
|
/* 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 */
|
/* get out if we have no more lists to process or if the lines
|
||||||
else {
|
* are lower than what we're interested in */
|
||||||
if (delim == '\n')
|
if (linenum < spos || cl_pos >= nlists)
|
||||||
cut_file_by_lines(line, linenum);
|
goto next_line;
|
||||||
else
|
|
||||||
cut_line_by_fields(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++;
|
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)
|
int cut_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
unsigned long opt;
|
char *sopt, *ltok;
|
||||||
char *sopt, *sdopt;
|
|
||||||
|
|
||||||
bb_opt_complementally = "b--bcf:c--bcf:f--bcf";
|
bb_opt_complementally = "b--bcf:c--bcf:f--bcf";
|
||||||
opt = bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, &sdopt);
|
opt =
|
||||||
part = opt & (OPT_BYTE_FLGS|OPT_CHAR_FLGS|OPT_FIELDS_FLGS);
|
bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, <ok);
|
||||||
if(part == 0)
|
if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS)))
|
||||||
bb_error_msg_and_die("you must specify a list of bytes, characters, or fields");
|
bb_error_msg_and_die
|
||||||
if(opt & BB_GETOPT_ERROR)
|
("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");
|
bb_error_msg_and_die("only one type of list may be specified");
|
||||||
parse_lists(sopt);
|
|
||||||
if((opt & (OPT_DELIM_FLGS))) {
|
if ((opt & (CUT_OPT_DELIM_FLGS))) {
|
||||||
if (strlen(sdopt) > 1) {
|
if (strlen(ltok) > 1) {
|
||||||
bb_error_msg_and_die("the delimiter must be a single character");
|
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 */
|
/* non-field (char or byte) cutting has some special handling */
|
||||||
if (part != OPT_FIELDS_FLGS) {
|
if (!(opt & CUT_OPT_FIELDS_FLGS)) {
|
||||||
if (supress_non_delimited_lines) {
|
if (opt & CUT_OPT_SUPPRESS_FLGS) {
|
||||||
bb_error_msg_and_die("suppressing non-delimited lines makes sense"
|
bb_error_msg_and_die
|
||||||
" only when operating on fields");
|
("suppressing non-delimited lines makes sense%s",
|
||||||
|
_op_on_field);
|
||||||
}
|
}
|
||||||
if (delim != '\t') {
|
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
|
/* argv[(optind)..(argc-1)] should be names of file to process. If no
|
||||||
* files were specified or '-' was specified, take input from stdin.
|
* files were specified or '-' was specified, take input from stdin.
|
||||||
* Otherwise, we process all the files specified. */
|
* 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);
|
cut_file(stdin);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
int i;
|
|
||||||
FILE *file;
|
FILE *file;
|
||||||
for (i = optind; i < argc; i++) {
|
|
||||||
file = bb_wfopen(argv[i], "r");
|
for (; optind < argc; optind++) {
|
||||||
if(file) {
|
file = bb_wfopen(argv[optind], "r");
|
||||||
|
if (file) {
|
||||||
cut_file(file);
|
cut_file(file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ENABLE_FEATURE_CLEAN_UP)
|
||||||
|
free(cut_lists);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
260
coreutils/date.c
260
coreutils/date.c
@ -5,14 +5,17 @@
|
|||||||
* by Matthew Grant <grantma@anathoth.gen.nz>
|
* by Matthew Grant <grantma@anathoth.gen.nz>
|
||||||
*
|
*
|
||||||
* iso-format handling added by Robert Griebl <griebl@gmx.de>
|
* 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.
|
* 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,
|
/* This 'date' command supports only 2 time setting formats,
|
||||||
all the GNU strftime stuff (its in libc, lets use it),
|
all the GNU strftime stuff (its in libc, lets use it),
|
||||||
setting time using UTC and displaying int, as well as
|
setting time using UTC and displaying it, as well as
|
||||||
an RFC 822 complient date output for shell scripting
|
an RFC 2822 compliant date output for shell scripting
|
||||||
mail commands */
|
mail commands */
|
||||||
|
|
||||||
/* Input parsing code is always bulky - used heavy duty libc stuff as
|
/* Input parsing code is always bulky - used heavy duty libc stuff as
|
||||||
@ -20,13 +23,6 @@
|
|||||||
|
|
||||||
/* Default input handling to save surprising some people */
|
/* 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_RFC2822 0x01
|
||||||
#define DATE_OPT_SET 0x02
|
#define DATE_OPT_SET 0x02
|
||||||
@ -36,119 +32,45 @@
|
|||||||
#define DATE_OPT_TIMESPEC 0x20
|
#define DATE_OPT_TIMESPEC 0x20
|
||||||
#define DATE_OPT_HINT 0x40
|
#define DATE_OPT_HINT 0x40
|
||||||
|
|
||||||
|
static void maybe_set_utc(int opt)
|
||||||
static struct tm *date_conv_time(struct tm *tm_time, const char *t_string)
|
|
||||||
{
|
{
|
||||||
int nr;
|
if ((opt & DATE_OPT_UTC) && putenv("TZ=UTC0") != 0)
|
||||||
char *cp;
|
bb_error_msg_and_die(bb_msg_memory_exhausted);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int date_main(int argc, char **argv)
|
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_str = NULL;
|
||||||
char *date_fmt = NULL;
|
char *date_fmt = NULL;
|
||||||
int set_time;
|
|
||||||
int utc;
|
|
||||||
time_t tm;
|
|
||||||
unsigned long opt;
|
|
||||||
struct tm tm_time;
|
|
||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
|
|
||||||
int ifmt = 0;
|
|
||||||
char *isofmt_arg;
|
char *isofmt_arg;
|
||||||
char *hintfmt_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:"
|
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
|
&date_str, &date_str, &filename
|
||||||
USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg));
|
USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg));
|
||||||
set_time = opt & DATE_OPT_SET;
|
maybe_set_utc(opt);
|
||||||
utc = opt & DATE_OPT_UTC;
|
|
||||||
if (utc && putenv("TZ=UTC0") != 0) {
|
|
||||||
bb_error_msg_and_die(bb_msg_memory_exhausted);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) {
|
if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) {
|
||||||
if (!isofmt_arg) {
|
if (!isofmt_arg) {
|
||||||
ifmt = 1;
|
ifmt = 0; /* default is date */
|
||||||
} else {
|
} else {
|
||||||
char *isoformats[]={"date","hours","minutes","seconds"};
|
const char * const isoformats[] =
|
||||||
for(ifmt = 4; ifmt;)
|
{"date", "hours", "minutes", "seconds"};
|
||||||
if(!strcmp(isofmt_arg,isoformats[--ifmt]))
|
|
||||||
|
for (ifmt = 0; ifmt < 4; ifmt++)
|
||||||
|
if (!strcmp(isofmt_arg, isoformats[ifmt])) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!ifmt) {
|
if (ifmt == 4) /* parse error */
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,18 +78,19 @@ int date_main(int argc, char **argv)
|
|||||||
if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) {
|
if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) {
|
||||||
date_fmt = &argv[optind][1]; /* Skip over the '+' */
|
date_fmt = &argv[optind][1]; /* Skip over the '+' */
|
||||||
} else if (date_str == NULL) {
|
} else if (date_str == NULL) {
|
||||||
set_time = 1;
|
opt |= DATE_OPT_SET;
|
||||||
date_str = argv[optind];
|
date_str = argv[optind];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now we have parsed all the information except the date format
|
/* Now we have parsed all the information except the date format
|
||||||
which depends on whether the clock is being set or read */
|
which depends on whether the clock is being set or read */
|
||||||
|
|
||||||
if(filename) {
|
if (filename) {
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
xstat(filename,&statbuf);
|
xstat(filename, &statbuf);
|
||||||
tm=statbuf.st_mtime;
|
tm = statbuf.st_mtime;
|
||||||
} else time(&tm);
|
} else
|
||||||
|
time(&tm);
|
||||||
memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
|
memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
|
||||||
/* Zero out fields - take her back to midnight! */
|
/* Zero out fields - take her back to midnight! */
|
||||||
if (date_str != NULL) {
|
if (date_str != NULL) {
|
||||||
@ -179,9 +102,64 @@ int date_main(int argc, char **argv)
|
|||||||
if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) {
|
if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) {
|
||||||
strptime(date_str, hintfmt_arg, &tm_time);
|
strptime(date_str, hintfmt_arg, &tm_time);
|
||||||
} else if (strchr(date_str, ':') != NULL) {
|
} 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 {
|
} 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 */
|
/* 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) {
|
if (tm < 0) {
|
||||||
bb_error_msg_and_die(bb_msg_invalid_date, date_str);
|
bb_error_msg_and_die(bb_msg_invalid_date, date_str);
|
||||||
}
|
}
|
||||||
if (utc && putenv("TZ=UTC0") != 0) {
|
maybe_set_utc(opt);
|
||||||
bb_error_msg_and_die(bb_msg_memory_exhausted);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if setting time, set it */
|
/* 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");
|
bb_perror_msg("cannot set date");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,33 +179,43 @@ int date_main(int argc, char **argv)
|
|||||||
/* Display output */
|
/* Display output */
|
||||||
|
|
||||||
/* Deal with format string */
|
/* Deal with format string */
|
||||||
|
|
||||||
if (date_fmt == NULL) {
|
if (date_fmt == NULL) {
|
||||||
/* Start with the default case */
|
int i;
|
||||||
|
date_fmt = xzalloc(32);
|
||||||
date_fmt = (opt & DATE_OPT_RFC2822 ?
|
if (ENABLE_FEATURE_DATE_ISOFMT && ifmt >= 0) {
|
||||||
(utc ? "%a, %d %b %Y %H:%M:%S GMT" :
|
strcpy(date_fmt, "%Y-%m-%d");
|
||||||
"%a, %d %b %Y %H:%M:%S %z") :
|
if (ifmt > 0) {
|
||||||
"%a %b %e %H:%M:%S %Z %Y");
|
i = 8;
|
||||||
|
date_fmt[i++] = 'T';
|
||||||
if (ENABLE_FEATURE_DATE_ISOFMT) {
|
date_fmt[i++] = '%';
|
||||||
if (ifmt == 4)
|
date_fmt[i++] = 'H';
|
||||||
date_fmt = utc ? "%Y-%m-%dT%H:%M:%SZ" : "%Y-%m-%dT%H:%M:%S%z";
|
if (ifmt > 1) {
|
||||||
else if (ifmt == 3)
|
date_fmt[i++] = ':';
|
||||||
date_fmt = utc ? "%Y-%m-%dT%H:%MZ" : "%Y-%m-%dT%H:%M%z";
|
date_fmt[i++] = '%';
|
||||||
else if (ifmt == 2)
|
date_fmt[i++] = 'M';
|
||||||
date_fmt = utc ? "%Y-%m-%dT%HZ" : "%Y-%m-%dT%H%z";
|
}
|
||||||
else if (ifmt == 1)
|
if (ifmt > 2) {
|
||||||
date_fmt = "%Y-%m-%d";
|
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') {
|
if (*date_fmt == '\0') {
|
||||||
|
|
||||||
/* With no format string, just print a blank line */
|
/* With no format string, just print a blank line */
|
||||||
|
*bb_common_bufsiz1 = 0;
|
||||||
*bb_common_bufsiz1=0;
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Handle special conversions */
|
/* Handle special conversions */
|
||||||
|
|
||||||
if (strncmp(date_fmt, "%f", 2) == 0) {
|
if (strncmp(date_fmt, "%f", 2) == 0) {
|
||||||
|
128
coreutils/dd.c
128
coreutils/dd.c
@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
|
#include <signal.h> /* For FEATURE_DD_SIGNAL_HANDLING */
|
||||||
|
|
||||||
static const struct suffix_mult dd_suffixes[] = {
|
static const struct suffix_mult dd_suffixes[] = {
|
||||||
{ "c", 1 },
|
{ "c", 1 },
|
||||||
@ -23,72 +24,72 @@ static const struct suffix_mult dd_suffixes[] = {
|
|||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static size_t out_full;
|
static size_t out_full, out_part, in_full, in_part;
|
||||||
static size_t out_part;
|
|
||||||
static size_t in_full;
|
|
||||||
static size_t 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)in_full, (long)in_part,
|
||||||
(long)out_full, (long)out_part);
|
(long)out_full, (long)out_part);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dd_main(int argc, char **argv)
|
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;
|
size_t count = -1, oc = 0, ibs = 512, obs = 512;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
off_t seek = 0, skip = 0;
|
off_t seek = 0, skip = 0;
|
||||||
int sync_flag = FALSE, noerror = FALSE, trunc_flag = TRUE, twobufs_flag = 0,
|
int oflag, ifd, ofd;
|
||||||
oflag, ifd, ofd, i;
|
|
||||||
const char *infile = NULL, *outfile = NULL;
|
const char *infile = NULL, *outfile = NULL;
|
||||||
char *ibuf, *obuf;
|
char *ibuf, *obuf;
|
||||||
|
|
||||||
if (ENABLE_FEATURE_DD_SIGNAL_HANDLING)
|
if (ENABLE_FEATURE_DD_SIGNAL_HANDLING) {
|
||||||
{
|
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
|
||||||
memset(&sa, 0, sizeof(sa));
|
memset(&sa, 0, sizeof(sa));
|
||||||
sa.sa_handler = dd_output_status;
|
sa.sa_handler = dd_output_status;
|
||||||
sa.sa_flags = SA_RESTART;
|
sa.sa_flags = SA_RESTART;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sigaction(SIGUSR1, &sa, 0);
|
sigaction(SIGUSR1, &sa, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
for (n = 1; n < argc; n++) {
|
||||||
if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[i], 4)) {
|
if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[n], 4)) {
|
||||||
ibs = bb_xparse_number(argv[i]+4, dd_suffixes);
|
ibs = bb_xparse_number(argv[n]+4, dd_suffixes);
|
||||||
twobufs_flag++;
|
flags |= twobufs_flag;
|
||||||
} else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[i], 4)) {
|
} else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[n], 4)) {
|
||||||
obs = bb_xparse_number(argv[i]+4, dd_suffixes);
|
obs = bb_xparse_number(argv[n]+4, dd_suffixes);
|
||||||
twobufs_flag++;
|
flags |= twobufs_flag;
|
||||||
} else if (!strncmp("bs=", argv[i], 3)) {
|
} else if (!strncmp("bs=", argv[n], 3))
|
||||||
ibs = obs = bb_xparse_number(argv[i]+3, dd_suffixes);
|
ibs = obs = bb_xparse_number(argv[n]+3, dd_suffixes);
|
||||||
} else if (!strncmp("count=", argv[i], 6))
|
else if (!strncmp("count=", argv[n], 6))
|
||||||
count = bb_xparse_number(argv[i]+6, dd_suffixes);
|
count = bb_xparse_number(argv[n]+6, dd_suffixes);
|
||||||
else if (!strncmp("seek=", argv[i], 5))
|
else if (!strncmp("seek=", argv[n], 5))
|
||||||
seek = bb_xparse_number(argv[i]+5, dd_suffixes);
|
seek = bb_xparse_number(argv[n]+5, dd_suffixes);
|
||||||
else if (!strncmp("skip=", argv[i], 5))
|
else if (!strncmp("skip=", argv[n], 5))
|
||||||
skip = bb_xparse_number(argv[i]+5, dd_suffixes);
|
skip = bb_xparse_number(argv[n]+5, dd_suffixes);
|
||||||
else if (!strncmp("if=", argv[i], 3))
|
else if (!strncmp("if=", argv[n], 3))
|
||||||
infile = argv[i]+3;
|
infile = argv[n]+3;
|
||||||
else if (!strncmp("of=", argv[i], 3))
|
else if (!strncmp("of=", argv[n], 3))
|
||||||
outfile = argv[i]+3;
|
outfile = argv[n]+3;
|
||||||
else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[i], 5)) {
|
else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[n], 5)) {
|
||||||
ibuf = argv[i]+5;
|
ibuf = argv[n]+5;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!strncmp("notrunc", ibuf, 7)) {
|
if (!strncmp("notrunc", ibuf, 7)) {
|
||||||
trunc_flag = FALSE;
|
flags ^= trunc_flag;
|
||||||
ibuf += 7;
|
ibuf += 7;
|
||||||
} else if (!strncmp("sync", ibuf, 4)) {
|
} else if (!strncmp("sync", ibuf, 4)) {
|
||||||
sync_flag = TRUE;
|
flags |= sync_flag;
|
||||||
ibuf += 4;
|
ibuf += 4;
|
||||||
} else if (!strncmp("noerror", ibuf, 7)) {
|
} else if (!strncmp("noerror", ibuf, 7)) {
|
||||||
noerror = TRUE;
|
flags |= noerror;
|
||||||
ibuf += 7;
|
ibuf += 7;
|
||||||
} else {
|
} 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] == '\0') break;
|
||||||
if (ibuf[0] == ',') ibuf++;
|
if (ibuf[0] == ',') ibuf++;
|
||||||
@ -98,12 +99,14 @@ int dd_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
ibuf = xmalloc(ibs);
|
ibuf = xmalloc(ibs);
|
||||||
|
|
||||||
if (twobufs_flag) obuf = xmalloc(obs);
|
if (flags & twobufs_flag)
|
||||||
else obuf = ibuf;
|
obuf = xmalloc(obs);
|
||||||
|
else
|
||||||
|
obuf = ibuf;
|
||||||
|
|
||||||
if (infile != NULL) {
|
if (infile != NULL)
|
||||||
ifd = xopen(infile, O_RDONLY);
|
ifd = xopen(infile, O_RDONLY);
|
||||||
} else {
|
else {
|
||||||
ifd = STDIN_FILENO;
|
ifd = STDIN_FILENO;
|
||||||
infile = bb_msg_standard_input;
|
infile = bb_msg_standard_input;
|
||||||
}
|
}
|
||||||
@ -111,20 +114,18 @@ int dd_main(int argc, char **argv)
|
|||||||
if (outfile != NULL) {
|
if (outfile != NULL) {
|
||||||
oflag = O_WRONLY | O_CREAT;
|
oflag = O_WRONLY | O_CREAT;
|
||||||
|
|
||||||
if (!seek && trunc_flag) {
|
if (!seek && (flags & trunc_flag))
|
||||||
oflag |= O_TRUNC;
|
oflag |= O_TRUNC;
|
||||||
}
|
|
||||||
|
|
||||||
ofd = xopen3(outfile, oflag, 0666);
|
ofd = xopen3(outfile, oflag, 0666);
|
||||||
|
|
||||||
if (seek && trunc_flag) {
|
if (seek && (flags & trunc_flag)) {
|
||||||
if (ftruncate(ofd, seek * obs) < 0) {
|
if (ftruncate(ofd, seek * obs) < 0) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) ||
|
if (fstat(ofd, &st) < 0 || S_ISREG(st.st_mode) ||
|
||||||
S_ISDIR (st.st_mode)) {
|
S_ISDIR(st.st_mode))
|
||||||
bb_perror_msg_and_die("%s", outfile);
|
goto die_outfile;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -145,44 +146,42 @@ int dd_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (seek) {
|
if (seek) {
|
||||||
if (lseek(ofd, seek * obs, SEEK_CUR) < 0) {
|
if (lseek(ofd, seek * obs, SEEK_CUR) < 0)
|
||||||
bb_perror_msg_and_die("%s", outfile);
|
goto die_outfile;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (in_full + in_part != count) {
|
while (in_full + in_part != count) {
|
||||||
if (noerror) {
|
if (flags & noerror) {
|
||||||
/* Pre-zero the buffer when doing the noerror thing */
|
/* Pre-zero the buffer when doing the noerror thing */
|
||||||
memset(ibuf, '\0', ibs);
|
memset(ibuf, '\0', ibs);
|
||||||
}
|
}
|
||||||
|
|
||||||
n = safe_read(ifd, ibuf, ibs);
|
n = safe_read(ifd, ibuf, ibs);
|
||||||
if (n == 0) {
|
if (n == 0)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (noerror) {
|
if (flags & noerror) {
|
||||||
n = ibs;
|
n = ibs;
|
||||||
bb_perror_msg("%s", infile);
|
bb_perror_msg("%s", infile);
|
||||||
} else {
|
} else
|
||||||
bb_perror_msg_and_die("%s", infile);
|
bb_perror_msg_and_die("%s", infile);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((size_t)n == ibs) {
|
if ((size_t)n == ibs)
|
||||||
in_full++;
|
in_full++;
|
||||||
} else {
|
else {
|
||||||
in_part++;
|
in_part++;
|
||||||
if (sync_flag) {
|
if (sync_flag) {
|
||||||
memset(ibuf + n, '\0', ibs - n);
|
memset(ibuf + n, '\0', ibs - n);
|
||||||
n = ibs;
|
n = ibs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (twobufs_flag) {
|
if (flags & twobufs_flag) {
|
||||||
char *tmp = ibuf;
|
char *tmp = ibuf;
|
||||||
while (n) {
|
while (n) {
|
||||||
size_t d = obs - oc;
|
size_t d = obs - oc;
|
||||||
|
|
||||||
if (d > n) d = n;
|
if (d > n)
|
||||||
|
d = n;
|
||||||
memcpy(obuf + oc, tmp, d);
|
memcpy(obuf + oc, tmp, d);
|
||||||
n -= d;
|
n -= d;
|
||||||
tmp += d;
|
tmp += d;
|
||||||
@ -195,8 +194,10 @@ int dd_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
xwrite(ofd, ibuf, n);
|
xwrite(ofd, ibuf, n);
|
||||||
if (n == ibs) out_full++;
|
if (n == ibs)
|
||||||
else out_part++;
|
out_full++;
|
||||||
|
else
|
||||||
|
out_part++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,6 +210,7 @@ int dd_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (close (ofd) < 0) {
|
if (close (ofd) < 0) {
|
||||||
|
die_outfile:
|
||||||
bb_perror_msg_and_die("%s", outfile);
|
bb_perror_msg_and_die("%s", outfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,11 +23,6 @@
|
|||||||
* 4) Fixed busybox bug #1284 involving long overflow with human_readable.
|
* 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"
|
#include "busybox.h"
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_HUMAN_READABLE
|
#ifdef CONFIG_FEATURE_HUMAN_READABLE
|
||||||
@ -57,7 +52,7 @@ static int one_file_system;
|
|||||||
static dev_t dir_dev;
|
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. */
|
/* TODO - May not want to defer error checking here. */
|
||||||
#ifdef CONFIG_FEATURE_HUMAN_READABLE
|
#ifdef CONFIG_FEATURE_HUMAN_READABLE
|
||||||
@ -73,7 +68,7 @@ static void print(long size, char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* tiny recursive du */
|
/* tiny recursive du */
|
||||||
static long du(char *filename)
|
static long du(const char * const filename)
|
||||||
{
|
{
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
long sum;
|
long sum;
|
||||||
|
402
coreutils/expr.c
402
coreutils/expr.c
@ -37,11 +37,13 @@ typedef enum valtype TYPE;
|
|||||||
|
|
||||||
#if ENABLE_EXPR_MATH_SUPPORT_64
|
#if ENABLE_EXPR_MATH_SUPPORT_64
|
||||||
typedef int64_t arith_t;
|
typedef int64_t arith_t;
|
||||||
|
|
||||||
#define PF_REZ "ll"
|
#define PF_REZ "ll"
|
||||||
#define PF_REZ_TYPE (long long)
|
#define PF_REZ_TYPE (long long)
|
||||||
#define STRTOL(s, e, b) strtoll(s, e, b)
|
#define STRTOL(s, e, b) strtoll(s, e, b)
|
||||||
#else
|
#else
|
||||||
typedef long arith_t;
|
typedef long arith_t;
|
||||||
|
|
||||||
#define PF_REZ "l"
|
#define PF_REZ "l"
|
||||||
#define PF_REZ_TYPE (long)
|
#define PF_REZ_TYPE (long)
|
||||||
#define STRTOL(s, e, b) strtol(s, e, b)
|
#define STRTOL(s, e, b) strtol(s, e, b)
|
||||||
@ -49,8 +51,8 @@ typedef long arith_t;
|
|||||||
|
|
||||||
/* A value is.... */
|
/* A value is.... */
|
||||||
struct valinfo {
|
struct valinfo {
|
||||||
TYPE type; /* Which kind. */
|
TYPE type; /* Which kind. */
|
||||||
union { /* The value itself. */
|
union { /* The value itself. */
|
||||||
arith_t i;
|
arith_t i;
|
||||||
char *s;
|
char *s;
|
||||||
} u;
|
} u;
|
||||||
@ -60,17 +62,17 @@ typedef struct valinfo VALUE;
|
|||||||
/* The arguments given to the program, minus the program name. */
|
/* The arguments given to the program, minus the program name. */
|
||||||
static char **args;
|
static char **args;
|
||||||
|
|
||||||
static VALUE *docolon (VALUE *sv, VALUE *pv);
|
static VALUE *docolon(VALUE * sv, VALUE * pv);
|
||||||
static VALUE *eval (void);
|
static VALUE *eval(void);
|
||||||
static VALUE *int_value (arith_t i);
|
static VALUE *int_value(arith_t i);
|
||||||
static VALUE *str_value (char *s);
|
static VALUE *str_value(char *s);
|
||||||
static int nextarg (char *str);
|
static int nextarg(char *str);
|
||||||
static int null (VALUE *v);
|
static int null(VALUE * v);
|
||||||
static int toarith (VALUE *v);
|
static int toarith(VALUE * v);
|
||||||
static void freev (VALUE *v);
|
static void freev(VALUE * v);
|
||||||
static void tostring (VALUE *v);
|
static void tostring(VALUE * v);
|
||||||
|
|
||||||
int expr_main (int argc, char **argv)
|
int expr_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
VALUE *v;
|
VALUE *v;
|
||||||
|
|
||||||
@ -80,25 +82,25 @@ int expr_main (int argc, char **argv)
|
|||||||
|
|
||||||
args = argv + 1;
|
args = argv + 1;
|
||||||
|
|
||||||
v = eval ();
|
v = eval();
|
||||||
if (*args)
|
if (*args)
|
||||||
bb_error_msg_and_die ("syntax error");
|
bb_error_msg_and_die("syntax error");
|
||||||
|
|
||||||
if (v->type == integer)
|
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
|
else
|
||||||
puts (v->u.s);
|
puts(v->u.s);
|
||||||
|
|
||||||
exit (null (v));
|
exit(null(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return a VALUE for I. */
|
/* Return a VALUE for I. */
|
||||||
|
|
||||||
static VALUE *int_value (arith_t i)
|
static VALUE *int_value(arith_t i)
|
||||||
{
|
{
|
||||||
VALUE *v;
|
VALUE *v;
|
||||||
|
|
||||||
v = xmalloc (sizeof(VALUE));
|
v = xmalloc(sizeof(VALUE));
|
||||||
v->type = integer;
|
v->type = integer;
|
||||||
v->u.i = i;
|
v->u.i = i;
|
||||||
return v;
|
return v;
|
||||||
@ -106,7 +108,7 @@ static VALUE *int_value (arith_t i)
|
|||||||
|
|
||||||
/* Return a VALUE for S. */
|
/* Return a VALUE for S. */
|
||||||
|
|
||||||
static VALUE *str_value (char *s)
|
static VALUE *str_value(char *s)
|
||||||
{
|
{
|
||||||
VALUE *v;
|
VALUE *v;
|
||||||
|
|
||||||
@ -118,28 +120,26 @@ static VALUE *str_value (char *s)
|
|||||||
|
|
||||||
/* Free VALUE V, including structure components. */
|
/* Free VALUE V, including structure components. */
|
||||||
|
|
||||||
static void freev (VALUE *v)
|
static void freev(VALUE * v)
|
||||||
{
|
{
|
||||||
if (v->type == string)
|
if (v->type == string)
|
||||||
free (v->u.s);
|
free(v->u.s);
|
||||||
free (v);
|
free(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return nonzero if V is a null-string or zero-number. */
|
/* Return nonzero if V is a null-string or zero-number. */
|
||||||
|
|
||||||
static int null (VALUE *v)
|
static int null(VALUE * v)
|
||||||
{
|
{
|
||||||
switch (v->type) {
|
if (v->type == integer)
|
||||||
case integer:
|
return v->u.i == 0;
|
||||||
return v->u.i == 0;
|
else /* string: */
|
||||||
default: /* string: */
|
return v->u.s[0] == '\0' || strcmp(v->u.s, "0") == 0;
|
||||||
return v->u.s[0] == '\0' || strcmp (v->u.s, "0") == 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Coerce V to a string value (can't fail). */
|
/* Coerce V to a string value (can't fail). */
|
||||||
|
|
||||||
static void tostring (VALUE *v)
|
static void tostring(VALUE * v)
|
||||||
{
|
{
|
||||||
if (v->type == integer) {
|
if (v->type == integer) {
|
||||||
v->u.s = xasprintf("%" PF_REZ "d", PF_REZ_TYPE v->u.i);
|
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. */
|
/* 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;
|
arith_t i;
|
||||||
char *e;
|
char *e;
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ static int toarith (VALUE *v)
|
|||||||
i = STRTOL(v->u.s, &e, 10);
|
i = STRTOL(v->u.s, &e, 10);
|
||||||
if ((v->u.s == e) || *e)
|
if ((v->u.s == e) || *e)
|
||||||
return 0;
|
return 0;
|
||||||
free (v->u.s);
|
free(v->u.s);
|
||||||
v->u.i = i;
|
v->u.i = i;
|
||||||
v->type = integer;
|
v->type = integer;
|
||||||
}
|
}
|
||||||
@ -170,221 +170,207 @@ static int toarith (VALUE *v)
|
|||||||
/* Return nonzero if the next token matches STR exactly.
|
/* Return nonzero if the next token matches STR exactly.
|
||||||
STR must not be NULL. */
|
STR must not be NULL. */
|
||||||
|
|
||||||
static int
|
static int nextarg(char *str)
|
||||||
nextarg (char *str)
|
|
||||||
{
|
{
|
||||||
if (*args == NULL)
|
if (*args == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
return strcmp (*args, str) == 0;
|
return strcmp(*args, str) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The comparison operator handling functions. */
|
/* 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;
|
int cmpval;
|
||||||
|
|
||||||
if (l->type == string || r->type == string) {
|
if (l->type == string || r->type == string) {
|
||||||
tostring (l);
|
tostring(l);
|
||||||
tostring (r);
|
tostring(r);
|
||||||
cmpval = strcmp (l->u.s, r->u.s);
|
cmpval = strcmp(l->u.s, r->u.s);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
cmpval = l->u.i - r->u.i;
|
cmpval = l->u.i - r->u.i;
|
||||||
switch(op) {
|
if (op == '<')
|
||||||
case '<':
|
return cmpval < 0;
|
||||||
return cmpval < 0;
|
else if (op == ('L' + 'E'))
|
||||||
case ('L'+'E'):
|
return cmpval <= 0;
|
||||||
return cmpval <= 0;
|
else if (op == '=')
|
||||||
case '=':
|
return cmpval == 0;
|
||||||
return cmpval == 0;
|
else if (op == '!')
|
||||||
case '!':
|
return cmpval != 0;
|
||||||
return cmpval != 0;
|
else if (op == '>')
|
||||||
case '>':
|
return cmpval > 0;
|
||||||
return cmpval > 0;
|
else /* >= */
|
||||||
default: /* >= */
|
return cmpval >= 0;
|
||||||
return cmpval >= 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The arithmetic operator handling functions. */
|
/* 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))
|
if (!toarith(l) || !toarith(r))
|
||||||
bb_error_msg_and_die ("non-numeric argument");
|
bb_error_msg_and_die("non-numeric argument");
|
||||||
li = l->u.i;
|
li = l->u.i;
|
||||||
ri = r->u.i;
|
ri = r->u.i;
|
||||||
if((op == '/' || op == '%') && ri == 0)
|
if ((op == '/' || op == '%') && ri == 0)
|
||||||
bb_error_msg_and_die ( "division by zero");
|
bb_error_msg_and_die("division by zero");
|
||||||
switch(op) {
|
if (op == '+')
|
||||||
case '+':
|
|
||||||
return li + ri;
|
return li + ri;
|
||||||
case '-':
|
else if (op == '-')
|
||||||
return li - ri;
|
return li - ri;
|
||||||
case '*':
|
else if (op == '*')
|
||||||
return li * ri;
|
return li * ri;
|
||||||
case '/':
|
else if (op == '/')
|
||||||
return li / ri;
|
return li / ri;
|
||||||
default:
|
else
|
||||||
return li % ri;
|
return li % ri;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the : operator.
|
/* Do the : operator.
|
||||||
SV is the VALUE for the lhs (the string),
|
SV is the VALUE for the lhs (the string),
|
||||||
PV is the VALUE for the rhs (the pattern). */
|
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;
|
VALUE *v;
|
||||||
regex_t re_buffer;
|
regex_t re_buffer;
|
||||||
const int NMATCH = 2;
|
const int NMATCH = 2;
|
||||||
regmatch_t re_regs[NMATCH];
|
regmatch_t re_regs[NMATCH];
|
||||||
|
|
||||||
tostring (sv);
|
tostring(sv);
|
||||||
tostring (pv);
|
tostring(pv);
|
||||||
|
|
||||||
if (pv->u.s[0] == '^') {
|
if (pv->u.s[0] == '^') {
|
||||||
fprintf (stderr, "\
|
fprintf(stderr, "\
|
||||||
warning: unportable BRE: `%s': using `^' as the first character\n\
|
warning: unportable BRE: `%s': using `^' as the first character\n\
|
||||||
of a basic regular expression is not portable; it is being ignored",
|
of a basic regular expression is not portable; it is being ignored", pv->u.s);
|
||||||
pv->u.s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset (&re_buffer, 0, sizeof (re_buffer));
|
memset(&re_buffer, 0, sizeof(re_buffer));
|
||||||
memset (re_regs, 0, sizeof (*re_regs));
|
memset(re_regs, 0, sizeof(*re_regs));
|
||||||
if( regcomp (&re_buffer, pv->u.s, 0) != 0 )
|
if (regcomp(&re_buffer, pv->u.s, 0) != 0)
|
||||||
bb_error_msg_and_die("Invalid regular expression");
|
bb_error_msg_and_die("Invalid regular expression");
|
||||||
|
|
||||||
/* expr uses an anchored pattern match, so check that there was a
|
/* expr uses an anchored pattern match, so check that there was a
|
||||||
* match and that the match starts at offset 0. */
|
* match and that the match starts at offset 0. */
|
||||||
if (regexec (&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH &&
|
if (regexec(&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH &&
|
||||||
re_regs[0].rm_so == 0) {
|
re_regs[0].rm_so == 0) {
|
||||||
/* Were \(...\) used? */
|
/* Were \(...\) used? */
|
||||||
if (re_buffer.re_nsub > 0) {
|
if (re_buffer.re_nsub > 0) {
|
||||||
sv->u.s[re_regs[1].rm_eo] = '\0';
|
sv->u.s[re_regs[1].rm_eo] = '\0';
|
||||||
v = str_value (sv->u.s + re_regs[1].rm_so);
|
v = str_value(sv->u.s + re_regs[1].rm_so);
|
||||||
}
|
} else
|
||||||
else
|
v = int_value(re_regs[0].rm_eo);
|
||||||
v = int_value (re_regs[0].rm_eo);
|
} else {
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Match failed -- return the right kind of null. */
|
/* Match failed -- return the right kind of null. */
|
||||||
if (re_buffer.re_nsub > 0)
|
if (re_buffer.re_nsub > 0)
|
||||||
v = str_value ("");
|
v = str_value("");
|
||||||
else
|
else
|
||||||
v = int_value (0);
|
v = int_value(0);
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle bare operands and ( expr ) syntax. */
|
/* Handle bare operands and ( expr ) syntax. */
|
||||||
|
|
||||||
static VALUE *eval7 (void)
|
static VALUE *eval7(void)
|
||||||
{
|
{
|
||||||
VALUE *v;
|
VALUE *v;
|
||||||
|
|
||||||
if (!*args)
|
if (!*args)
|
||||||
bb_error_msg_and_die ( "syntax error");
|
bb_error_msg_and_die("syntax error");
|
||||||
|
|
||||||
if (nextarg ("(")) {
|
if (nextarg("(")) {
|
||||||
args++;
|
args++;
|
||||||
v = eval ();
|
v = eval();
|
||||||
if (!nextarg (")"))
|
if (!nextarg(")"))
|
||||||
bb_error_msg_and_die ( "syntax error");
|
bb_error_msg_and_die("syntax error");
|
||||||
args++;
|
args++;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextarg (")"))
|
if (nextarg(")"))
|
||||||
bb_error_msg_and_die ( "syntax error");
|
bb_error_msg_and_die("syntax error");
|
||||||
|
|
||||||
return str_value (*args++);
|
return str_value(*args++);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle match, substr, index, length, and quote keywords. */
|
/* Handle match, substr, index, length, and quote keywords. */
|
||||||
|
|
||||||
static VALUE *eval6 (void)
|
static VALUE *eval6(void)
|
||||||
{
|
{
|
||||||
VALUE *l, *r, *v, *i1, *i2;
|
VALUE *l, *r, *v, *i1, *i2;
|
||||||
|
|
||||||
if (nextarg ("quote")) {
|
if (nextarg("quote")) {
|
||||||
args++;
|
args++;
|
||||||
if (!*args)
|
if (!*args)
|
||||||
bb_error_msg_and_die ( "syntax error");
|
bb_error_msg_and_die("syntax error");
|
||||||
return str_value (*args++);
|
return str_value(*args++);
|
||||||
}
|
} else if (nextarg("length")) {
|
||||||
else if (nextarg ("length")) {
|
|
||||||
args++;
|
args++;
|
||||||
r = eval6 ();
|
r = eval6();
|
||||||
tostring (r);
|
tostring(r);
|
||||||
v = int_value (strlen (r->u.s));
|
v = int_value(strlen(r->u.s));
|
||||||
freev (r);
|
freev(r);
|
||||||
return v;
|
return v;
|
||||||
}
|
} else if (nextarg("match")) {
|
||||||
else if (nextarg ("match")) {
|
|
||||||
args++;
|
args++;
|
||||||
l = eval6 ();
|
l = eval6();
|
||||||
r = eval6 ();
|
r = eval6();
|
||||||
v = docolon (l, r);
|
v = docolon(l, r);
|
||||||
freev (l);
|
freev(l);
|
||||||
freev (r);
|
freev(r);
|
||||||
return v;
|
return v;
|
||||||
}
|
} else if (nextarg("index")) {
|
||||||
else if (nextarg ("index")) {
|
|
||||||
args++;
|
args++;
|
||||||
l = eval6 ();
|
l = eval6();
|
||||||
r = eval6 ();
|
r = eval6();
|
||||||
tostring (l);
|
tostring(l);
|
||||||
tostring (r);
|
tostring(r);
|
||||||
v = int_value (strcspn (l->u.s, r->u.s) + 1);
|
v = int_value(strcspn(l->u.s, r->u.s) + 1);
|
||||||
if (v->u.i == (arith_t) strlen (l->u.s) + 1)
|
if (v->u.i == (arith_t) strlen(l->u.s) + 1)
|
||||||
v->u.i = 0;
|
v->u.i = 0;
|
||||||
freev (l);
|
freev(l);
|
||||||
freev (r);
|
freev(r);
|
||||||
return v;
|
return v;
|
||||||
}
|
} else if (nextarg("substr")) {
|
||||||
else if (nextarg ("substr")) {
|
|
||||||
args++;
|
args++;
|
||||||
l = eval6 ();
|
l = eval6();
|
||||||
i1 = eval6 ();
|
i1 = eval6();
|
||||||
i2 = eval6 ();
|
i2 = eval6();
|
||||||
tostring (l);
|
tostring(l);
|
||||||
if (!toarith (i1) || !toarith (i2)
|
if (!toarith(i1) || !toarith(i2)
|
||||||
|| i1->u.i > (arith_t) strlen (l->u.s)
|
|| i1->u.i > (arith_t) strlen(l->u.s)
|
||||||
|| i1->u.i <= 0 || i2->u.i <= 0)
|
|| i1->u.i <= 0 || i2->u.i <= 0)
|
||||||
v = str_value ("");
|
v = str_value("");
|
||||||
else {
|
else {
|
||||||
v = xmalloc (sizeof(VALUE));
|
v = xmalloc(sizeof(VALUE));
|
||||||
v->type = string;
|
v->type = string;
|
||||||
v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i);
|
v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i);
|
||||||
}
|
}
|
||||||
freev (l);
|
freev(l);
|
||||||
freev (i1);
|
freev(i1);
|
||||||
freev (i2);
|
freev(i2);
|
||||||
return v;
|
return v;
|
||||||
}
|
} else
|
||||||
else
|
return eval7();
|
||||||
return eval7 ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle : operator (pattern matching).
|
/* Handle : operator (pattern matching).
|
||||||
Calls docolon to do the real work. */
|
Calls docolon to do the real work. */
|
||||||
|
|
||||||
static VALUE *eval5 (void)
|
static VALUE *eval5(void)
|
||||||
{
|
{
|
||||||
VALUE *l, *r, *v;
|
VALUE *l, *r, *v;
|
||||||
|
|
||||||
l = eval6 ();
|
l = eval6();
|
||||||
while (nextarg (":")) {
|
while (nextarg(":")) {
|
||||||
args++;
|
args++;
|
||||||
r = eval6 ();
|
r = eval6();
|
||||||
v = docolon (l, r);
|
v = docolon(l, r);
|
||||||
freev (l);
|
freev(l);
|
||||||
freev (r);
|
freev(r);
|
||||||
l = v;
|
l = v;
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
@ -392,128 +378,126 @@ static VALUE *eval5 (void)
|
|||||||
|
|
||||||
/* Handle *, /, % operators. */
|
/* Handle *, /, % operators. */
|
||||||
|
|
||||||
static VALUE *eval4 (void)
|
static VALUE *eval4(void)
|
||||||
{
|
{
|
||||||
VALUE *l, *r;
|
VALUE *l, *r;
|
||||||
int op;
|
int op;
|
||||||
arith_t val;
|
arith_t val;
|
||||||
|
|
||||||
l = eval5 ();
|
l = eval5();
|
||||||
while (1) {
|
while (1) {
|
||||||
if (nextarg ("*"))
|
if (nextarg("*"))
|
||||||
op = '*';
|
op = '*';
|
||||||
else if (nextarg ("/"))
|
else if (nextarg("/"))
|
||||||
op = '/';
|
op = '/';
|
||||||
else if (nextarg ("%"))
|
else if (nextarg("%"))
|
||||||
op = '%';
|
op = '%';
|
||||||
else
|
else
|
||||||
return l;
|
return l;
|
||||||
args++;
|
args++;
|
||||||
r = eval5 ();
|
r = eval5();
|
||||||
val = arithmetic_common (l, r, op);
|
val = arithmetic_common(l, r, op);
|
||||||
freev (l);
|
freev(l);
|
||||||
freev (r);
|
freev(r);
|
||||||
l = int_value (val);
|
l = int_value(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle +, - operators. */
|
/* Handle +, - operators. */
|
||||||
|
|
||||||
static VALUE *eval3 (void)
|
static VALUE *eval3(void)
|
||||||
{
|
{
|
||||||
VALUE *l, *r;
|
VALUE *l, *r;
|
||||||
int op;
|
int op;
|
||||||
arith_t val;
|
arith_t val;
|
||||||
|
|
||||||
l = eval4 ();
|
l = eval4();
|
||||||
while (1) {
|
while (1) {
|
||||||
if (nextarg ("+"))
|
if (nextarg("+"))
|
||||||
op = '+';
|
op = '+';
|
||||||
else if (nextarg ("-"))
|
else if (nextarg("-"))
|
||||||
op = '-';
|
op = '-';
|
||||||
else
|
else
|
||||||
return l;
|
return l;
|
||||||
args++;
|
args++;
|
||||||
r = eval4 ();
|
r = eval4();
|
||||||
val = arithmetic_common (l, r, op);
|
val = arithmetic_common(l, r, op);
|
||||||
freev (l);
|
freev(l);
|
||||||
freev (r);
|
freev(r);
|
||||||
l = int_value (val);
|
l = int_value(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle comparisons. */
|
/* Handle comparisons. */
|
||||||
|
|
||||||
static VALUE *eval2 (void)
|
static VALUE *eval2(void)
|
||||||
{
|
{
|
||||||
VALUE *l, *r;
|
VALUE *l, *r;
|
||||||
int op;
|
int op;
|
||||||
arith_t val;
|
arith_t val;
|
||||||
|
|
||||||
l = eval3 ();
|
l = eval3();
|
||||||
while (1) {
|
while (1) {
|
||||||
if (nextarg ("<"))
|
if (nextarg("<"))
|
||||||
op = '<';
|
op = '<';
|
||||||
else if (nextarg ("<="))
|
else if (nextarg("<="))
|
||||||
op = 'L'+'E';
|
op = 'L' + 'E';
|
||||||
else if (nextarg ("=") || nextarg ("=="))
|
else if (nextarg("=") || nextarg("=="))
|
||||||
op = '=';
|
op = '=';
|
||||||
else if (nextarg ("!="))
|
else if (nextarg("!="))
|
||||||
op = '!';
|
op = '!';
|
||||||
else if (nextarg (">="))
|
else if (nextarg(">="))
|
||||||
op = 'G'+'E';
|
op = 'G' + 'E';
|
||||||
else if (nextarg (">"))
|
else if (nextarg(">"))
|
||||||
op = '>';
|
op = '>';
|
||||||
else
|
else
|
||||||
return l;
|
return l;
|
||||||
args++;
|
args++;
|
||||||
r = eval3 ();
|
r = eval3();
|
||||||
toarith (l);
|
toarith(l);
|
||||||
toarith (r);
|
toarith(r);
|
||||||
val = cmp_common (l, r, op);
|
val = cmp_common(l, r, op);
|
||||||
freev (l);
|
freev(l);
|
||||||
freev (r);
|
freev(r);
|
||||||
l = int_value (val);
|
l = int_value(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle &. */
|
/* Handle &. */
|
||||||
|
|
||||||
static VALUE *eval1 (void)
|
static VALUE *eval1(void)
|
||||||
{
|
{
|
||||||
VALUE *l, *r;
|
VALUE *l, *r;
|
||||||
|
|
||||||
l = eval2 ();
|
l = eval2();
|
||||||
while (nextarg ("&")) {
|
while (nextarg("&")) {
|
||||||
args++;
|
args++;
|
||||||
r = eval2 ();
|
r = eval2();
|
||||||
if (null (l) || null (r)) {
|
if (null(l) || null(r)) {
|
||||||
freev (l);
|
freev(l);
|
||||||
freev (r);
|
freev(r);
|
||||||
l = int_value (0);
|
l = int_value(0);
|
||||||
}
|
} else
|
||||||
else
|
freev(r);
|
||||||
freev (r);
|
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle |. */
|
/* Handle |. */
|
||||||
|
|
||||||
static VALUE *eval (void)
|
static VALUE *eval(void)
|
||||||
{
|
{
|
||||||
VALUE *l, *r;
|
VALUE *l, *r;
|
||||||
|
|
||||||
l = eval1 ();
|
l = eval1();
|
||||||
while (nextarg ("|")) {
|
while (nextarg("|")) {
|
||||||
args++;
|
args++;
|
||||||
r = eval1 ();
|
r = eval1();
|
||||||
if (null (l)) {
|
if (null(l)) {
|
||||||
freev (l);
|
freev(l);
|
||||||
l = r;
|
l = r;
|
||||||
}
|
} else
|
||||||
else
|
freev(r);
|
||||||
freev (r);
|
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
@ -13,12 +13,6 @@
|
|||||||
* Licensed under the GPL v2, see the file LICENSE in this tarball.
|
* 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"
|
#include "busybox.h"
|
||||||
|
|
||||||
/* 1 if any of the files read were the standard input */
|
/* 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. */
|
int checksum = 0; /* The checksum mod 2^16. */
|
||||||
uintmax_t total_bytes = 0; /* The number of bytes. */
|
uintmax_t total_bytes = 0; /* The number of bytes. */
|
||||||
int ch; /* Each character read. */
|
int ch; /* Each character read. */
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (IS_STDIN(file)) {
|
if (IS_STDIN(file)) {
|
||||||
fp = stdin;
|
fp = stdin;
|
||||||
have_read_stdin = 1;
|
have_read_stdin++;
|
||||||
} else {
|
} else {
|
||||||
fp = bb_wfopen(file, "r");
|
fp = bb_wfopen(file, "r");
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
return 0;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((ch = getc(fp)) != EOF) {
|
while ((ch = getc(fp)) != EOF) {
|
||||||
@ -58,21 +53,21 @@ static int bsd_sum_file(const char *file, int print_name)
|
|||||||
if (ferror(fp)) {
|
if (ferror(fp)) {
|
||||||
bb_perror_msg(file);
|
bb_perror_msg(file);
|
||||||
bb_fclose_nonstdin(fp);
|
bb_fclose_nonstdin(fp);
|
||||||
return 0;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bb_fclose_nonstdin(fp) == EOF) {
|
if (bb_fclose_nonstdin(fp) == EOF) {
|
||||||
bb_perror_msg(file);
|
bb_perror_msg(file);
|
||||||
return 0;
|
goto out;
|
||||||
}
|
}
|
||||||
|
ret++;
|
||||||
printf("%05d %5ju ", checksum, (total_bytes+1023)/1024);
|
printf("%05d %5ju ", checksum, (total_bytes+1023)/1024);
|
||||||
if (print_name > 1)
|
if (print_name > 1)
|
||||||
puts(file);
|
puts(file);
|
||||||
else
|
else
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
out:
|
||||||
return 1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate and print the checksum and the size in 512-byte blocks
|
/* 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 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)
|
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. */
|
/* 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();
|
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)
|
static ssize_t tail_read(int fd, char *buf, size_t count)
|
||||||
{
|
{
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
/* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */
|
/* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */
|
||||||
|
|
||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
int tee_main(int argc, char **argv)
|
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
|
/* gnu tee ignores SIGPIPE in case one of the output files is a pipe
|
||||||
* that doesn't consume all its input. Good idea... */
|
* 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. */
|
/* Allocate an array of FILE *'s, with one extra for a sentinal. */
|
||||||
p = files = (FILE **)xmalloc(sizeof(FILE *) * (argc - optind + 2));
|
p = files = (FILE **)xmalloc(sizeof(FILE *) * (argc - optind + 2));
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
* Mini watch implementation for busybox
|
* Mini watch implementation for busybox
|
||||||
*
|
*
|
||||||
* Copyright (C) 2001 by Michael Habermann <mhabermann@gmx.de>
|
* 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.
|
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
|
||||||
*/
|
*/
|
||||||
@ -10,14 +11,9 @@
|
|||||||
/* BB_AUDIT SUSv3 N/A */
|
/* BB_AUDIT SUSv3 N/A */
|
||||||
/* BB_AUDIT GNU defects -- only option -n is supported. */
|
/* 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"
|
#include "busybox.h"
|
||||||
|
|
||||||
|
|
||||||
int watch_main(int argc, char **argv)
|
int watch_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int width, len;
|
int width, len;
|
||||||
@ -26,19 +22,18 @@ int watch_main(int argc, char **argv)
|
|||||||
|
|
||||||
if (argc < 2) bb_show_usage();
|
if (argc < 2) bb_show_usage();
|
||||||
|
|
||||||
get_terminal_width_height(1, &width, 0);
|
get_terminal_width_height(STDOUT_FILENO, &width, 0);
|
||||||
header = xzalloc(width--);
|
header = xzalloc(width--);
|
||||||
|
|
||||||
/* don't use getopt, because it permutes the arguments */
|
/* don't use getopt, because it permutes the arguments */
|
||||||
++argv;
|
++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);
|
period = bb_xgetularg10_bnd(argv[1], 1, UINT_MAX);
|
||||||
argv += 2;
|
argv += 2;
|
||||||
}
|
}
|
||||||
watched_argv = argv;
|
watched_argv = argv;
|
||||||
|
|
||||||
/* create header */
|
/* create header */
|
||||||
|
|
||||||
len = snprintf(header, width, "Every %ds:", period);
|
len = snprintf(header, width, "Every %ds:", period);
|
||||||
while (*argv && len<width)
|
while (*argv && len<width)
|
||||||
snprintf(header+len, width-len, " %s", *(argv++));
|
snprintf(header+len, width-len, " %s", *(argv++));
|
||||||
@ -50,11 +45,13 @@ int watch_main(int argc, char **argv)
|
|||||||
time(&t);
|
time(&t);
|
||||||
thyme = ctime(&t);
|
thyme = ctime(&t);
|
||||||
len = strlen(thyme);
|
len = strlen(thyme);
|
||||||
if (len < width) header[width-len] = 0;
|
if (len < width)
|
||||||
|
header[width-len] = 0;
|
||||||
printf("\033[H\033[J%s %s\n", header, thyme);
|
bb_printf("\033[H\033[J%s %s\n", header, thyme);
|
||||||
|
|
||||||
waitpid(xspawn(watched_argv),0,0);
|
waitpid(xspawn(watched_argv),0,0);
|
||||||
sleep(period);
|
sleep(period);
|
||||||
}
|
}
|
||||||
|
if (ENABLE_FEATURE_CLEAN_UP)
|
||||||
|
free(header);
|
||||||
}
|
}
|
||||||
|
@ -60,10 +60,6 @@
|
|||||||
#define PATH_MAX 256
|
#define PATH_MAX 256
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DMALLOC
|
|
||||||
#include <dmalloc.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Some useful definitions */
|
/* Some useful definitions */
|
||||||
#undef FALSE
|
#undef FALSE
|
||||||
#define FALSE ((int) 0)
|
#define FALSE ((int) 0)
|
||||||
@ -211,7 +207,9 @@ extern int bb_fprintf(FILE * __restrict stream, const char * __restrict format,
|
|||||||
extern int bb_printf(const char * __restrict format, ...)
|
extern int bb_printf(const char * __restrict format, ...)
|
||||||
__attribute__ ((format (printf, 1, 2)));
|
__attribute__ ((format (printf, 1, 2)));
|
||||||
|
|
||||||
//#warning rename to xferror_filename?
|
#if ENABLE_NITPICK
|
||||||
|
#warning rename to xferror_filename?
|
||||||
|
#endif
|
||||||
extern void xferror(FILE *fp, const char *fn);
|
extern void xferror(FILE *fp, const char *fn);
|
||||||
extern void xferror_stdout(void);
|
extern void xferror_stdout(void);
|
||||||
extern void xfflush_stdout(void);
|
extern void xfflush_stdout(void);
|
||||||
@ -265,7 +263,9 @@ extern long bb_xgetlarg_bnd_sfx(const char *arg, int base,
|
|||||||
extern long bb_xgetlarg10_sfx(const char *arg, const struct suffix_mult *suffixes);
|
extern long bb_xgetlarg10_sfx(const char *arg, const struct suffix_mult *suffixes);
|
||||||
|
|
||||||
|
|
||||||
//#warning pitchable now?
|
#if ENABLE_NITPICK
|
||||||
|
#warning pitchable now?
|
||||||
|
#endif
|
||||||
extern unsigned long bb_xparse_number(const char *numstr,
|
extern unsigned long bb_xparse_number(const char *numstr,
|
||||||
const struct suffix_mult *suffixes);
|
const struct suffix_mult *suffixes);
|
||||||
|
|
||||||
@ -330,7 +330,9 @@ char *concat_path_file(const char *path, const char *filename);
|
|||||||
char *concat_subpath_file(const char *path, const char *filename);
|
char *concat_subpath_file(const char *path, const char *filename);
|
||||||
char *last_char_is(const char *s, int c);
|
char *last_char_is(const char *s, int c);
|
||||||
|
|
||||||
//#warning yuk!
|
#if ENABLE_NITPICK
|
||||||
|
#warning yuk!
|
||||||
|
#endif
|
||||||
char *fgets_str(FILE *file, const char *terminating_string);
|
char *fgets_str(FILE *file, const char *terminating_string);
|
||||||
|
|
||||||
extern int uncompress(int fd_in, int fd_out);
|
extern int uncompress(int fd_in, int fd_out);
|
||||||
@ -344,7 +346,9 @@ extern int xconnect(struct sockaddr_in *s_addr);
|
|||||||
extern unsigned short bb_lookup_port(const char *port, const char *protocol, unsigned short default_port);
|
extern unsigned short bb_lookup_port(const char *port, const char *protocol, unsigned short default_port);
|
||||||
extern void bb_lookup_host(struct sockaddr_in *s_in, const char *host);
|
extern void bb_lookup_host(struct sockaddr_in *s_in, const char *host);
|
||||||
|
|
||||||
//#warning wrap this?
|
#if ENABLE_NITPICK
|
||||||
|
#warning wrap this?
|
||||||
|
#endif
|
||||||
char *dirname (char *path);
|
char *dirname (char *path);
|
||||||
|
|
||||||
int bb_make_directory (char *path, long mode, int flags);
|
int bb_make_directory (char *path, long mode, int flags);
|
||||||
@ -456,8 +460,10 @@ extern int bb_default_error_retval;
|
|||||||
# define FB_0 "/dev/fb0"
|
# define FB_0 "/dev/fb0"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#warning put these in .o files
|
|
||||||
|
|
||||||
|
#if ENABLE_NITPICK
|
||||||
|
#warning put these in .o files
|
||||||
|
#endif
|
||||||
/* The following devices are the same on devfs and non-devfs systems. */
|
/* The following devices are the same on devfs and non-devfs systems. */
|
||||||
#define CURRENT_TTY "/dev/tty"
|
#define CURRENT_TTY "/dev/tty"
|
||||||
#define CONSOLE_DEV "/dev/console"
|
#define CONSOLE_DEV "/dev/console"
|
||||||
@ -581,4 +587,8 @@ extern const char BB_BANNER[];
|
|||||||
#undef isupper
|
#undef isupper
|
||||||
#undef isxdigit
|
#undef isxdigit
|
||||||
|
|
||||||
|
#ifdef DMALLOC
|
||||||
|
#include <dmalloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __LIBBUSYBOX_H__ */
|
#endif /* __LIBBUSYBOX_H__ */
|
||||||
|
@ -10,8 +10,6 @@
|
|||||||
#define ARCHIVE_NOPRESERVE_OWN 32
|
#define ARCHIVE_NOPRESERVE_OWN 32
|
||||||
#define ARCHIVE_NOPRESERVE_PERM 64
|
#define ARCHIVE_NOPRESERVE_PERM 64
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
|
|
||||||
typedef struct file_headers_s {
|
typedef struct file_headers_s {
|
||||||
|
@ -1426,12 +1426,12 @@ USE_FEATURE_DATE_ISOFMT( \
|
|||||||
#define ipcrm_trivial_usage \
|
#define ipcrm_trivial_usage \
|
||||||
"[-[MQS] key] [-[mqs] id]"
|
"[-[MQS] key] [-[mqs] id]"
|
||||||
#define ipcrm_full_usage \
|
#define ipcrm_full_usage \
|
||||||
"The upper-case options MQS are used to remove a shared memory\n" \
|
"The upper-case options MQS are used to remove a shared memory segment by a\n" \
|
||||||
"segment by an shmkey value. The lower-case options mqs are used\n" \
|
"segment by a shmkey value. The lower-case options mqs are used\n" \
|
||||||
"to remove a segment by shmid value.\n" \
|
"to remove a segment by shmid value.\n" \
|
||||||
"\t-m | -M\tRemove the memory segment after the last detach\n" \
|
"\t-[mM]\tRemove the memory segment after the last detach\n" \
|
||||||
"\t-q | -Q\tRemove the message queue\n" \
|
"\t-[qQ]\tRemove the message queue\n" \
|
||||||
"\t-s | -S\tRemove the semaphore"
|
"\t-[sS]\tRemove the semaphore"
|
||||||
|
|
||||||
#define ipcs_trivial_usage \
|
#define ipcs_trivial_usage \
|
||||||
"[[-smq] -i shmid] | [[-asmq] [-tclup]]"
|
"[[-smq] -i shmid] | [[-asmq] [-tclup]]"
|
||||||
|
133
libbb/xfuncs.c
133
libbb/xfuncs.c
@ -16,8 +16,12 @@
|
|||||||
* succeeded. */
|
* succeeded. */
|
||||||
|
|
||||||
#ifndef DMALLOC
|
#ifndef DMALLOC
|
||||||
|
/* dmalloc provides variants of these that do abort() on failure.
|
||||||
|
* Since dmalloc's prototypes overwrite the impls here as they are
|
||||||
|
* included after these prototypes in libbb.h, all is well.
|
||||||
|
*/
|
||||||
#ifdef L_xmalloc
|
#ifdef L_xmalloc
|
||||||
// Die if we can't allocate size bytes of memory.
|
/* Die if we can't allocate size bytes of memory. */
|
||||||
void *xmalloc(size_t size)
|
void *xmalloc(size_t size)
|
||||||
{
|
{
|
||||||
void *ptr = malloc(size);
|
void *ptr = malloc(size);
|
||||||
@ -28,9 +32,9 @@ void *xmalloc(size_t size)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xrealloc
|
#ifdef L_xrealloc
|
||||||
// Die if we can't resize previously allocated memory. (This returns a pointer
|
/* Die if we can't resize previously allocated memory. (This returns a pointer
|
||||||
// to the new memory, which may or may not be the same as the old memory.
|
* to the new memory, which may or may not be the same as the old memory.
|
||||||
// It'll copy the contents to a new chunk and free the old one if necessary.)
|
* It'll copy the contents to a new chunk and free the old one if necessary.) */
|
||||||
void *xrealloc(void *ptr, size_t size)
|
void *xrealloc(void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
ptr = realloc(ptr, size);
|
ptr = realloc(ptr, size);
|
||||||
@ -39,9 +43,11 @@ void *xrealloc(void *ptr, size_t size)
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* DMALLOC */
|
||||||
|
|
||||||
|
|
||||||
#ifdef L_xzalloc
|
#ifdef L_xzalloc
|
||||||
// Die if we can't allocate and zero size bytes of memory.
|
/* Die if we can't allocate and zero size bytes of memory. */
|
||||||
void *xzalloc(size_t size)
|
void *xzalloc(size_t size)
|
||||||
{
|
{
|
||||||
void *ptr = xmalloc(size);
|
void *ptr = xmalloc(size);
|
||||||
@ -50,10 +56,8 @@ void *xzalloc(size_t size)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* DMALLOC */
|
|
||||||
|
|
||||||
#ifdef L_xstrdup
|
#ifdef L_xstrdup
|
||||||
// Die if we can't copy a string to freshly allocated memory.
|
/* Die if we can't copy a string to freshly allocated memory. */
|
||||||
char * xstrdup(const char *s)
|
char * xstrdup(const char *s)
|
||||||
{
|
{
|
||||||
char *t;
|
char *t;
|
||||||
@ -71,8 +75,9 @@ char * xstrdup(const char *s)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xstrndup
|
#ifdef L_xstrndup
|
||||||
// Die if we can't allocate n+1 bytes (space for the null terminator) and copy
|
/* Die if we can't allocate n+1 bytes (space for the null terminator) and copy
|
||||||
// the (possibly truncated to length n) string into it.
|
* the (possibly truncated to length n) string into it.
|
||||||
|
*/
|
||||||
char * xstrndup(const char *s, int n)
|
char * xstrndup(const char *s, int n)
|
||||||
{
|
{
|
||||||
char *t;
|
char *t;
|
||||||
@ -87,8 +92,9 @@ char * xstrndup(const char *s, int n)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xfopen
|
#ifdef L_xfopen
|
||||||
// Die if we can't open a file and return a FILE * to it.
|
/* Die if we can't open a file and return a FILE * to it.
|
||||||
// Notice we haven't got xfread(), This is for use with fscanf() and friends.
|
* Notice we haven't got xfread(), This is for use with fscanf() and friends.
|
||||||
|
*/
|
||||||
FILE *xfopen(const char *path, const char *mode)
|
FILE *xfopen(const char *path, const char *mode)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
@ -99,7 +105,7 @@ FILE *xfopen(const char *path, const char *mode)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xopen
|
#ifdef L_xopen
|
||||||
// Die if we can't open an existing file and return an fd.
|
/* Die if we can't open an existing file and return an fd. */
|
||||||
int xopen(const char *pathname, int flags)
|
int xopen(const char *pathname, int flags)
|
||||||
{
|
{
|
||||||
if (ENABLE_DEBUG && (flags && O_CREAT))
|
if (ENABLE_DEBUG && (flags && O_CREAT))
|
||||||
@ -110,7 +116,7 @@ int xopen(const char *pathname, int flags)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xopen3
|
#ifdef L_xopen3
|
||||||
// Die if we can't open a new file and return an fd.
|
/* Die if we can't open a new file and return an fd. */
|
||||||
int xopen3(const char *pathname, int flags, int mode)
|
int xopen3(const char *pathname, int flags, int mode)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -124,7 +130,7 @@ int xopen3(const char *pathname, int flags, int mode)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xread
|
#ifdef L_xread
|
||||||
// Die with an error message if we can't read the entire buffer.
|
/* Die with an error message if we can't read the entire buffer. */
|
||||||
void xread(int fd, void *buf, size_t count)
|
void xread(int fd, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
while (count) {
|
while (count) {
|
||||||
@ -139,7 +145,7 @@ void xread(int fd, void *buf, size_t count)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xwrite
|
#ifdef L_xwrite
|
||||||
// Die with an error message if we can't write the entire buffer.
|
/* Die with an error message if we can't write the entire buffer. */
|
||||||
void xwrite(int fd, void *buf, size_t count)
|
void xwrite(int fd, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
while (count) {
|
while (count) {
|
||||||
@ -154,7 +160,7 @@ void xwrite(int fd, void *buf, size_t count)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xlseek
|
#ifdef L_xlseek
|
||||||
// Die with an error message if we can't lseek to the right spot.
|
/* Die with an error message if we can't lseek to the right spot. */
|
||||||
void xlseek(int fd, off_t offset, int whence)
|
void xlseek(int fd, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
if (offset != lseek(fd, offset, whence)) bb_error_msg_and_die("lseek");
|
if (offset != lseek(fd, offset, whence)) bb_error_msg_and_die("lseek");
|
||||||
@ -162,7 +168,7 @@ void xlseek(int fd, off_t offset, int whence)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xread_char
|
#ifdef L_xread_char
|
||||||
// Die with an error message if we can't read one character.
|
/* Die with an error message if we can't read one character. */
|
||||||
unsigned char xread_char(int fd)
|
unsigned char xread_char(int fd)
|
||||||
{
|
{
|
||||||
char tmp;
|
char tmp;
|
||||||
@ -174,7 +180,7 @@ unsigned char xread_char(int fd)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xferror
|
#ifdef L_xferror
|
||||||
// Die with supplied error message if this FILE * has ferror set.
|
/* Die with supplied error message if this FILE * has ferror set. */
|
||||||
void xferror(FILE *fp, const char *fn)
|
void xferror(FILE *fp, const char *fn)
|
||||||
{
|
{
|
||||||
if (ferror(fp)) {
|
if (ferror(fp)) {
|
||||||
@ -184,7 +190,7 @@ void xferror(FILE *fp, const char *fn)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xferror_stdout
|
#ifdef L_xferror_stdout
|
||||||
// Die with an error message if stdout has ferror set.
|
/* Die with an error message if stdout has ferror set. */
|
||||||
void xferror_stdout(void)
|
void xferror_stdout(void)
|
||||||
{
|
{
|
||||||
xferror(stdout, bb_msg_standard_output);
|
xferror(stdout, bb_msg_standard_output);
|
||||||
@ -192,7 +198,7 @@ void xferror_stdout(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xfflush_stdout
|
#ifdef L_xfflush_stdout
|
||||||
// Die with an error message if we have trouble flushing stdout.
|
/* Die with an error message if we have trouble flushing stdout. */
|
||||||
void xfflush_stdout(void)
|
void xfflush_stdout(void)
|
||||||
{
|
{
|
||||||
if (fflush(stdout)) {
|
if (fflush(stdout)) {
|
||||||
@ -202,24 +208,25 @@ void xfflush_stdout(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_spawn
|
#ifdef L_spawn
|
||||||
// This does a fork/exec in one call, using vfork(). Return PID of new child,
|
/* This does a fork/exec in one call, using vfork(). Return PID of new child,
|
||||||
// -1 for failure. Runs argv[0], searching path if that has no / in it.
|
* -1 for failure. Runs argv[0], searching path if that has no / in it.
|
||||||
|
*/
|
||||||
pid_t spawn(char **argv)
|
pid_t spawn(char **argv)
|
||||||
{
|
{
|
||||||
static int failed;
|
static int failed;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
void *app = ENABLE_FEATURE_SH_STANDALONE_SHELL ? find_applet_by_name(argv[0]) : 0;
|
void *app = ENABLE_FEATURE_SH_STANDALONE_SHELL ? find_applet_by_name(argv[0]) : 0;
|
||||||
|
|
||||||
// Be nice to nommu machines.
|
/* Be nice to nommu machines. */
|
||||||
failed = 0;
|
failed = 0;
|
||||||
pid = vfork();
|
pid = vfork();
|
||||||
if (pid < 0) return pid;
|
if (pid < 0) return pid;
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : *argv, argv);
|
execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : *argv, argv);
|
||||||
|
|
||||||
// We're sharing a stack with blocked parent, let parent know we failed
|
/* We're sharing a stack with blocked parent, let parent know we failed
|
||||||
// and then exit to unblock parent (but don't run atexit() stuff, which
|
* and then exit to unblock parent (but don't run atexit() stuff, which
|
||||||
// would screw up parent.)
|
would screw up parent.) */
|
||||||
|
|
||||||
failed = -1;
|
failed = -1;
|
||||||
_exit(0);
|
_exit(0);
|
||||||
@ -229,7 +236,7 @@ pid_t spawn(char **argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xspawn
|
#ifdef L_xspawn
|
||||||
// Die with an error message if we can't spawn a child process.
|
/* Die with an error message if we can't spawn a child process. */
|
||||||
pid_t xspawn(char **argv)
|
pid_t xspawn(char **argv)
|
||||||
{
|
{
|
||||||
pid_t pid = spawn(argv);
|
pid_t pid = spawn(argv);
|
||||||
@ -239,7 +246,7 @@ pid_t xspawn(char **argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_wait4
|
#ifdef L_wait4
|
||||||
// Wait for the specified child PID to exit, returning child's error return.
|
/* Wait for the specified child PID to exit, returning child's error return. */
|
||||||
int wait4pid(int pid)
|
int wait4pid(int pid)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
@ -252,9 +259,9 @@ int wait4pid(int pid)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_itoa
|
#ifdef L_itoa
|
||||||
// Convert unsigned integer to ascii, writing into supplied buffer. A
|
/* Convert unsigned integer to ascii, writing into supplied buffer. A
|
||||||
// truncated result is always null terminated (unless buflen is 0), and
|
* truncated result is always null terminated (unless buflen is 0), and
|
||||||
// contains the first few digits of the result ala strncpy.
|
* contains the first few digits of the result ala strncpy. */
|
||||||
void utoa_to_buf(unsigned n, char *buf, unsigned buflen)
|
void utoa_to_buf(unsigned n, char *buf, unsigned buflen)
|
||||||
{
|
{
|
||||||
int i, out = 0;
|
int i, out = 0;
|
||||||
@ -272,7 +279,7 @@ void utoa_to_buf(unsigned n, char *buf, unsigned buflen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert signed integer to ascii, like utoa_to_buf()
|
/* Convert signed integer to ascii, like utoa_to_buf() */
|
||||||
void itoa_to_buf(int n, char *buf, unsigned buflen)
|
void itoa_to_buf(int n, char *buf, unsigned buflen)
|
||||||
{
|
{
|
||||||
if (buflen && n<0) {
|
if (buflen && n<0) {
|
||||||
@ -283,16 +290,16 @@ void itoa_to_buf(int n, char *buf, unsigned buflen)
|
|||||||
utoa_to_buf((unsigned)n, buf, buflen);
|
utoa_to_buf((unsigned)n, buf, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following two functions use a static buffer, so calling either one a
|
/* The following two functions use a static buffer, so calling either one a
|
||||||
// second time will overwrite previous results.
|
* second time will overwrite previous results.
|
||||||
//
|
*
|
||||||
// The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes.
|
* The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes.
|
||||||
// Int should always be 32 bits on any remotely Unix-like system, see
|
* Int should always be 32 bits on any remotely Unix-like system, see
|
||||||
// http://www.unix.org/whitepapers/64bit.html for the reasons why.
|
* http://www.unix.org/whitepapers/64bit.html for the reasons why.
|
||||||
|
*/
|
||||||
static char local_buf[12];
|
static char local_buf[12];
|
||||||
|
|
||||||
// Convert unsigned integer to ascii using a static buffer (returned).
|
/* Convert unsigned integer to ascii using a static buffer (returned). */
|
||||||
char *utoa(unsigned n)
|
char *utoa(unsigned n)
|
||||||
{
|
{
|
||||||
utoa_to_buf(n, local_buf, sizeof(local_buf));
|
utoa_to_buf(n, local_buf, sizeof(local_buf));
|
||||||
@ -300,7 +307,7 @@ char *utoa(unsigned n)
|
|||||||
return local_buf;
|
return local_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert signed integer to ascii using a static buffer (returned).
|
/* Convert signed integer to ascii using a static buffer (returned). */
|
||||||
char *itoa(int n)
|
char *itoa(int n)
|
||||||
{
|
{
|
||||||
itoa_to_buf(n, local_buf, sizeof(local_buf));
|
itoa_to_buf(n, local_buf, sizeof(local_buf));
|
||||||
@ -310,15 +317,15 @@ char *itoa(int n)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_setuid
|
#ifdef L_setuid
|
||||||
// Die with an error message if we can't set gid. (Because resource limits may
|
/* Die with an error message if we can't set gid. (Because resource limits may
|
||||||
// limit this user to a given number of processes, and if that fills up the
|
* limit this user to a given number of processes, and if that fills up the
|
||||||
// setgid() will fail and we'll _still_be_root_, which is bad.)
|
* setgid() will fail and we'll _still_be_root_, which is bad.) */
|
||||||
void xsetgid(gid_t gid)
|
void xsetgid(gid_t gid)
|
||||||
{
|
{
|
||||||
if (setgid(gid)) bb_error_msg_and_die("setgid");
|
if (setgid(gid)) bb_error_msg_and_die("setgid");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Die with an error message if we cant' set uid. (See xsetgid() for why.)
|
/* Die with an error message if we cant' set uid. (See xsetgid() for why.) */
|
||||||
void xsetuid(uid_t uid)
|
void xsetuid(uid_t uid)
|
||||||
{
|
{
|
||||||
if (setuid(uid)) bb_error_msg_and_die("setuid");
|
if (setuid(uid)) bb_error_msg_and_die("setuid");
|
||||||
@ -326,31 +333,31 @@ void xsetuid(uid_t uid)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_fdlength
|
#ifdef L_fdlength
|
||||||
// Return how long the file at fd is, if there's any way to determine it.
|
/* Return how long the file at fd is, if there's any way to determine it. */
|
||||||
off_t fdlength(int fd)
|
off_t fdlength(int fd)
|
||||||
{
|
{
|
||||||
off_t bottom = 0, top = 0, pos;
|
off_t bottom = 0, top = 0, pos;
|
||||||
long size;
|
long size;
|
||||||
|
|
||||||
// If the ioctl works for this, return it.
|
/* If the ioctl works for this, return it. */
|
||||||
|
|
||||||
if (ioctl(fd, BLKGETSIZE, &size) >= 0) return size*512;
|
if (ioctl(fd, BLKGETSIZE, &size) >= 0) return size*512;
|
||||||
|
|
||||||
// If not, do a binary search for the last location we can read. (Some
|
/* If not, do a binary search for the last location we can read. (Some
|
||||||
// block devices don't do BLKGETSIZE right.)
|
* block devices don't do BLKGETSIZE right.) */
|
||||||
|
|
||||||
do {
|
do {
|
||||||
char temp;
|
char temp;
|
||||||
|
|
||||||
pos = bottom + (top - bottom) / 2;;
|
pos = bottom + (top - bottom) / 2;;
|
||||||
|
|
||||||
// If we can read from the current location, it's bigger.
|
/* If we can read from the current location, it's bigger. */
|
||||||
|
|
||||||
if (lseek(fd, pos, 0)>=0 && safe_read(fd, &temp, 1)==1) {
|
if (lseek(fd, pos, 0)>=0 && safe_read(fd, &temp, 1)==1) {
|
||||||
if (bottom == top) bottom = top = (top+1) * 2;
|
if (bottom == top) bottom = top = (top+1) * 2;
|
||||||
else bottom = pos;
|
else bottom = pos;
|
||||||
|
|
||||||
// If we can't, it's smaller.
|
/* If we can't, it's smaller. */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (bottom == top) {
|
if (bottom == top) {
|
||||||
@ -366,8 +373,8 @@ off_t fdlength(int fd)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xasprintf
|
#ifdef L_xasprintf
|
||||||
// Die with an error message if we can't malloc() enough space and do an
|
/* Die with an error message if we can't malloc() enough space and do an
|
||||||
// sprintf() into that space.
|
* sprintf() into that space. */
|
||||||
char *xasprintf(const char *format, ...)
|
char *xasprintf(const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list p;
|
va_list p;
|
||||||
@ -396,8 +403,8 @@ char *xasprintf(const char *format, ...)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xprint_and_close_file
|
#ifdef L_xprint_and_close_file
|
||||||
// Die with an error message if we can't copy an entire FILE * to stdout, then
|
/* Die with an error message if we can't copy an entire FILE * to stdout, then
|
||||||
// close that file.
|
* close that file. */
|
||||||
void xprint_and_close_file(FILE *file)
|
void xprint_and_close_file(FILE *file)
|
||||||
{
|
{
|
||||||
// copyfd outputs error messages for us.
|
// copyfd outputs error messages for us.
|
||||||
@ -408,7 +415,7 @@ void xprint_and_close_file(FILE *file)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xchdir
|
#ifdef L_xchdir
|
||||||
// Die if we can't chdir to a new path.
|
/* Die if we can't chdir to a new path. */
|
||||||
void xchdir(const char *path)
|
void xchdir(const char *path)
|
||||||
{
|
{
|
||||||
if (chdir(path))
|
if (chdir(path))
|
||||||
@ -417,7 +424,7 @@ void xchdir(const char *path)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_warn_opendir
|
#ifdef L_warn_opendir
|
||||||
// Print a warning message if opendir() fails, but don't die.
|
/* Print a warning message if opendir() fails, but don't die. */
|
||||||
DIR *warn_opendir(const char *path)
|
DIR *warn_opendir(const char *path)
|
||||||
{
|
{
|
||||||
DIR *dp;
|
DIR *dp;
|
||||||
@ -431,7 +438,7 @@ DIR *warn_opendir(const char *path)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xopendir
|
#ifdef L_xopendir
|
||||||
// Die with an error message if opendir() fails.
|
/* Die with an error message if opendir() fails. */
|
||||||
DIR *xopendir(const char *path)
|
DIR *xopendir(const char *path)
|
||||||
{
|
{
|
||||||
DIR *dp;
|
DIR *dp;
|
||||||
@ -444,7 +451,7 @@ DIR *xopendir(const char *path)
|
|||||||
|
|
||||||
#ifdef L_xdaemon
|
#ifdef L_xdaemon
|
||||||
#ifndef BB_NOMMU
|
#ifndef BB_NOMMU
|
||||||
// Die with an error message if we can't daemonize.
|
/* Die with an error message if we can't daemonize. */
|
||||||
void xdaemon(int nochdir, int noclose)
|
void xdaemon(int nochdir, int noclose)
|
||||||
{
|
{
|
||||||
if (daemon(nochdir, noclose)) bb_perror_msg_and_die("daemon");
|
if (daemon(nochdir, noclose)) bb_perror_msg_and_die("daemon");
|
||||||
@ -453,7 +460,7 @@ void xdaemon(int nochdir, int noclose)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xsocket
|
#ifdef L_xsocket
|
||||||
// Die with an error message if we can't open a new socket.
|
/* Die with an error message if we can't open a new socket. */
|
||||||
int xsocket(int domain, int type, int protocol)
|
int xsocket(int domain, int type, int protocol)
|
||||||
{
|
{
|
||||||
int r = socket(domain, type, protocol);
|
int r = socket(domain, type, protocol);
|
||||||
@ -465,7 +472,7 @@ int xsocket(int domain, int type, int protocol)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xbind
|
#ifdef L_xbind
|
||||||
// Die with an error message if we can't bind a socket to an address.
|
/* Die with an error message if we can't bind a socket to an address. */
|
||||||
void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
|
void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
|
||||||
{
|
{
|
||||||
if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind");
|
if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind");
|
||||||
@ -473,7 +480,7 @@ void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L_xlisten
|
#ifdef L_xlisten
|
||||||
// Die with an error message if we can't listen for connections on a socket.
|
/* Die with an error message if we can't listen for connections on a socket. */
|
||||||
void xlisten(int s, int backlog)
|
void xlisten(int s, int backlog)
|
||||||
{
|
{
|
||||||
if (listen(s, backlog)) bb_perror_msg_and_die("listen");
|
if (listen(s, backlog)) bb_perror_msg_and_die("listen");
|
||||||
|
@ -49,6 +49,7 @@ find $srcdir/../ \
|
|||||||
-e '\<algorithic\>' \
|
-e '\<algorithic\>' \
|
||||||
-e '\<deamon\>' \
|
-e '\<deamon\>' \
|
||||||
-e '\<derefernce\>' \
|
-e '\<derefernce\>' \
|
||||||
|
-e '\<acomadate\>' \
|
||||||
| sed -e "s:^$srcdir/\.\./::g" > src.typos
|
| sed -e "s:^$srcdir/\.\./::g" > src.typos
|
||||||
testing "Common typos" "cat src.typos" "" "" ""
|
testing "Common typos" "cat src.typos" "" "" ""
|
||||||
rm -f src.typos
|
rm -f src.typos
|
||||||
|
@ -1,56 +1,22 @@
|
|||||||
/* vi: set sw=4 ts=4: */
|
/* vi: set sw=4 ts=4: */
|
||||||
/*
|
/*
|
||||||
* ipcrm.c -- utility to allow removal of IPC objects and data structures.
|
* ipcrm.c - utility to allow removal of IPC objects and data structures.
|
||||||
*
|
*
|
||||||
* 01 Sept 2004 - Rodney Radford <rradford@mindspring.com>
|
* 01 Sept 2004 - Rodney Radford <rradford@mindspring.com>
|
||||||
* Adapted for busybox from util-linux-2.12a.
|
* Adapted for busybox from util-linux-2.12a.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
* --- Pre-busybox history from util-linux-2.12a ------------------------
|
|
||||||
*
|
|
||||||
* 1999-04-02 frank zago
|
|
||||||
* - can now remove several id's in the same call
|
|
||||||
*
|
|
||||||
* 1999-02-22 Arkadiusz Miÿkiewicz <misiek@pld.ORG.PL>
|
|
||||||
* - added Native Language Support
|
|
||||||
*
|
|
||||||
* Original author - krishna balasubramanian 1993
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "busybox.h"
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
/* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */
|
||||||
|
/* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */
|
||||||
#include <sys/ipc.h>
|
#include <sys/ipc.h>
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
#include <sys/msg.h>
|
#include <sys/msg.h>
|
||||||
#include <sys/sem.h>
|
#include <sys/sem.h>
|
||||||
|
|
||||||
/* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */
|
|
||||||
/* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */
|
|
||||||
/* for getopt */
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
/* for tolower and isupper */
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "busybox.h"
|
|
||||||
|
|
||||||
#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
|
#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
|
||||||
/* union semun is defined by including <sys/sem.h> */
|
/* union semun is defined by including <sys/sem.h> */
|
||||||
#else
|
#else
|
||||||
@ -63,164 +29,149 @@ union semun {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_IPCRM_DROP_LEGACY
|
||||||
|
|
||||||
typedef enum type_id {
|
typedef enum type_id {
|
||||||
SHM,
|
SHM,
|
||||||
SEM,
|
SEM,
|
||||||
MSG
|
MSG
|
||||||
} type_id;
|
} type_id;
|
||||||
|
|
||||||
static int
|
static int remove_ids(type_id type, int argc, char **argv)
|
||||||
remove_ids(type_id type, int argc, char **argv) {
|
{
|
||||||
int id;
|
int id;
|
||||||
int ret = 0; /* for gcc */
|
int ret = 0; /* silence gcc */
|
||||||
char *end;
|
char *end;
|
||||||
int nb_errors = 0;
|
int nb_errors = 0;
|
||||||
union semun arg;
|
union semun arg;
|
||||||
|
|
||||||
arg.val = 0;
|
arg.val = 0;
|
||||||
|
|
||||||
while(argc) {
|
while (argc) {
|
||||||
|
|
||||||
id = strtoul(argv[0], &end, 10);
|
id = strtoul(argv[0], &end, 10);
|
||||||
|
|
||||||
if (*end != 0) {
|
if (*end != 0) {
|
||||||
bb_printf ("invalid id: %s\n", argv[0]);
|
bb_error_msg("invalid id: %s", argv[0]);
|
||||||
nb_errors ++;
|
nb_errors++;
|
||||||
} else {
|
} else {
|
||||||
switch(type) {
|
if (type == SEM)
|
||||||
case SEM:
|
ret = semctl(id, 0, IPC_RMID, arg);
|
||||||
ret = semctl (id, 0, IPC_RMID, arg);
|
else if (type == MSG)
|
||||||
break;
|
ret = msgctl(id, IPC_RMID, NULL);
|
||||||
|
else if (type == SHM)
|
||||||
case MSG:
|
ret = shmctl(id, IPC_RMID, NULL);
|
||||||
ret = msgctl (id, IPC_RMID, NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SHM:
|
|
||||||
ret = shmctl (id, IPC_RMID, NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
bb_printf ("cannot remove id %s (%s)\n",
|
bb_perror_msg("cannot remove id %s", argv[0]);
|
||||||
argv[0], strerror(errno));
|
nb_errors++;
|
||||||
nb_errors ++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(nb_errors);
|
return (nb_errors);
|
||||||
}
|
|
||||||
|
|
||||||
static int deprecated_main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (argc < 3) {
|
|
||||||
bb_show_usage();
|
|
||||||
bb_fflush_stdout_and_exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(argv[1], "shm")) {
|
|
||||||
if (remove_ids(SHM, argc-2, &argv[2]))
|
|
||||||
bb_fflush_stdout_and_exit(1);
|
|
||||||
}
|
|
||||||
else if (!strcmp(argv[1], "msg")) {
|
|
||||||
if (remove_ids(MSG, argc-2, &argv[2]))
|
|
||||||
bb_fflush_stdout_and_exit(1);
|
|
||||||
}
|
|
||||||
else if (!strcmp(argv[1], "sem")) {
|
|
||||||
if (remove_ids(SEM, argc-2, &argv[2]))
|
|
||||||
bb_fflush_stdout_and_exit(1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bb_printf ("unknown resource type: %s\n", argv[1]);
|
|
||||||
bb_show_usage();
|
|
||||||
bb_fflush_stdout_and_exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bb_printf ("resource(s) deleted\n");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
#endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */
|
||||||
|
|
||||||
|
|
||||||
int ipcrm_main(int argc, char **argv)
|
int ipcrm_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
char *prog = argv[0];
|
|
||||||
|
|
||||||
/* if the command is executed without parameters, do nothing */
|
/* if the command is executed without parameters, do nothing */
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
#ifndef CONFIG_IPCRM_DROP_LEGACY
|
||||||
/* check to see if the command is being invoked in the old way if so
|
/* check to see if the command is being invoked in the old way if so
|
||||||
then run the old code */
|
then run the old code. Valid commands are msg, shm, sem. */
|
||||||
if (strcmp(argv[1], "shm") == 0 ||
|
{
|
||||||
strcmp(argv[1], "msg") == 0 ||
|
type_id what = 0; /* silence gcc */
|
||||||
strcmp(argv[1], "sem") == 0)
|
char w;
|
||||||
return deprecated_main(argc, argv);
|
|
||||||
|
if ((((w=argv[1][0]) == 'm' && argv[1][1] == 's' && argv[1][2] == 'g')
|
||||||
|
|| (argv[1][0] == 's'
|
||||||
|
&& ((w=argv[1][1]) == 'h' || w == 'e')
|
||||||
|
&& argv[1][2] == 'm'))
|
||||||
|
&& argv[1][3] == '\0') {
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
bb_show_usage();
|
||||||
|
|
||||||
|
if (w == 'h')
|
||||||
|
what = SHM;
|
||||||
|
else if (w == 'm')
|
||||||
|
what = MSG;
|
||||||
|
else if (w == 'e')
|
||||||
|
what = SEM;
|
||||||
|
|
||||||
|
if (remove_ids(what, argc-2, &argv[2]))
|
||||||
|
bb_fflush_stdout_and_exit(1);
|
||||||
|
bb_printf("resource(s) deleted\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */
|
||||||
|
|
||||||
/* process new syntax to conform with SYSV ipcrm */
|
/* process new syntax to conform with SYSV ipcrm */
|
||||||
while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) {
|
while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) {
|
||||||
int result;
|
int result;
|
||||||
int id = 0;
|
int id = 0;
|
||||||
int iskey = isupper(c);
|
int iskey = (isupper)(c);
|
||||||
|
|
||||||
/* needed to delete semaphores */
|
/* needed to delete semaphores */
|
||||||
union semun arg;
|
union semun arg;
|
||||||
|
|
||||||
arg.val = 0;
|
arg.val = 0;
|
||||||
|
|
||||||
if ((c == '?') || (c == 'h'))
|
if ((c == '?') || (c == 'h')) {
|
||||||
{
|
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we don't need case information any more */
|
/* we don't need case information any more */
|
||||||
c = tolower(c);
|
c = tolower(c);
|
||||||
|
|
||||||
/* make sure the option is in range */
|
/* make sure the option is in range: allowed are q, m, s */
|
||||||
if (c != 'q' && c != 'm' && c != 's') {
|
if (c != 'q' && c != 'm' && c != 's') {
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
error++;
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iskey) {
|
if (iskey) {
|
||||||
/* keys are in hex or decimal */
|
/* keys are in hex or decimal */
|
||||||
key_t key = strtoul(optarg, NULL, 0);
|
key_t key = strtoul(optarg, NULL, 0);
|
||||||
|
|
||||||
if (key == IPC_PRIVATE) {
|
if (key == IPC_PRIVATE) {
|
||||||
error++;
|
error++;
|
||||||
bb_fprintf(stderr, "%s: illegal key (%s)\n",
|
bb_error_msg("illegal key (%s)", optarg);
|
||||||
prog, optarg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert key to id */
|
/* convert key to id */
|
||||||
id = ((c == 'q') ? msgget(key, 0) :
|
id = ((c == 'q') ? msgget(key, 0) :
|
||||||
(c == 'm') ? shmget(key, 0, 0) :
|
(c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0));
|
||||||
semget(key, 0, 0));
|
|
||||||
|
|
||||||
if (id < 0) {
|
if (id < 0) {
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
|
const char * const what = "key";
|
||||||
|
|
||||||
error++;
|
error++;
|
||||||
switch(errno) {
|
switch (errno) {
|
||||||
case EACCES:
|
case EACCES:
|
||||||
errmsg = "permission denied for key";
|
errmsg = "permission denied for";
|
||||||
break;
|
break;
|
||||||
case EIDRM:
|
case EIDRM:
|
||||||
errmsg = "already removed key";
|
errmsg = "already removed";
|
||||||
break;
|
break;
|
||||||
case ENOENT:
|
case ENOENT:
|
||||||
errmsg = "invalid key";
|
errmsg = "invalid";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
errmsg = "unknown error in key";
|
errmsg = "unknown error in";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bb_fprintf(stderr, "%s: %s (%s)\n",
|
bb_error_msg("%s %s (%s)", errmsg, what, optarg);
|
||||||
prog, errmsg, optarg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -229,37 +180,30 @@ int ipcrm_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
|
result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
|
||||||
(c == 'm') ? shmctl(id, IPC_RMID, NULL) :
|
(c == 'm') ? shmctl(id, IPC_RMID, NULL) :
|
||||||
semctl(id, 0, IPC_RMID, arg));
|
semctl(id, 0, IPC_RMID, arg));
|
||||||
|
|
||||||
if (result < 0) {
|
if (result) {
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
|
const char * const what = iskey ? "key" : "id";
|
||||||
|
|
||||||
error++;
|
error++;
|
||||||
switch(errno) {
|
switch (errno) {
|
||||||
case EACCES:
|
case EACCES:
|
||||||
case EPERM:
|
case EPERM:
|
||||||
errmsg = iskey
|
errmsg = "permission denied for";
|
||||||
? "permission denied for key"
|
|
||||||
: "permission denied for id";
|
|
||||||
break;
|
break;
|
||||||
case EINVAL:
|
case EINVAL:
|
||||||
errmsg = iskey
|
errmsg = "invalid";
|
||||||
? "invalid key"
|
|
||||||
: "invalid id";
|
|
||||||
break;
|
break;
|
||||||
case EIDRM:
|
case EIDRM:
|
||||||
errmsg = iskey
|
errmsg = "already removed";
|
||||||
? "already removed key"
|
|
||||||
: "already removed id";
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
errmsg = iskey
|
errmsg = "unknown error in";
|
||||||
? "unknown error in key"
|
|
||||||
: "unknown error in id";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bb_fprintf(stderr, "%s: %s (%s)\n",
|
bb_error_msg("%s %s (%s)", errmsg, what, optarg);
|
||||||
prog, errmsg, optarg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,7 @@
|
|||||||
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
|
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "busybox.h"
|
||||||
#include <stdlib.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
@ -25,15 +23,15 @@
|
|||||||
#include <sys/msg.h>
|
#include <sys/msg.h>
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
|
|
||||||
#include "busybox.h"
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------*/
|
||||||
/* SHM_DEST and SHM_LOCKED are defined in kernel headers,
|
/* SHM_DEST and SHM_LOCKED are defined in kernel headers,
|
||||||
but inside #ifdef __KERNEL__ ... #endif */
|
but inside #ifdef __KERNEL__ ... #endif */
|
||||||
#ifndef SHM_DEST
|
#ifndef SHM_DEST
|
||||||
/* shm_mode upper byte flags */
|
/* shm_mode upper byte flags */
|
||||||
#define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
#define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
||||||
#define SHM_LOCKED 02000 /* segment will not be swapped */
|
#define SHM_LOCKED 02000 /* segment will not be swapped */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* For older kernels the same holds for the defines below */
|
/* For older kernels the same holds for the defines below */
|
||||||
@ -46,12 +44,12 @@
|
|||||||
#define SHM_STAT 13
|
#define SHM_STAT 13
|
||||||
#define SHM_INFO 14
|
#define SHM_INFO 14
|
||||||
struct shm_info {
|
struct shm_info {
|
||||||
int used_ids;
|
int used_ids;
|
||||||
ulong shm_tot; /* total allocated shm */
|
ulong shm_tot; /* total allocated shm */
|
||||||
ulong shm_rss; /* total resident shm */
|
ulong shm_rss; /* total resident shm */
|
||||||
ulong shm_swp; /* total swapped shm */
|
ulong shm_swp; /* total swapped shm */
|
||||||
ulong swap_attempts;
|
ulong swap_attempts;
|
||||||
ulong swap_successes;
|
ulong swap_successes;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -98,12 +96,14 @@ union semun {
|
|||||||
#define TIME 4
|
#define TIME 4
|
||||||
#define PID 5
|
#define PID 5
|
||||||
|
|
||||||
|
static char format;
|
||||||
|
|
||||||
static void print_perms (int id, struct ipc_perm *ipcp) {
|
static void print_perms(int id, struct ipc_perm *ipcp)
|
||||||
|
{
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
struct group *gr;
|
struct group *gr;
|
||||||
|
|
||||||
bb_printf ("%-10d %-10o", id, ipcp->mode & 0777);
|
bb_printf("%-10d %-10o", id, ipcp->mode & 0777);
|
||||||
|
|
||||||
if ((pw = getpwuid(ipcp->cuid)))
|
if ((pw = getpwuid(ipcp->cuid)))
|
||||||
bb_printf(" %-10s", pw->pw_name);
|
bb_printf(" %-10s", pw->pw_name);
|
||||||
@ -125,7 +125,7 @@ static void print_perms (int id, struct ipc_perm *ipcp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void do_shm (char format)
|
static void do_shm(void)
|
||||||
{
|
{
|
||||||
int maxid, shmid, id;
|
int maxid, shmid, id;
|
||||||
struct shmid_ds shmseg;
|
struct shmid_ds shmseg;
|
||||||
@ -134,127 +134,125 @@ static void do_shm (char format)
|
|||||||
struct ipc_perm *ipcp = &shmseg.shm_perm;
|
struct ipc_perm *ipcp = &shmseg.shm_perm;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
|
||||||
maxid = shmctl (0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info);
|
maxid = shmctl(0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info);
|
||||||
if (maxid < 0) {
|
if (maxid < 0) {
|
||||||
bb_printf ("kernel not configured for shared memory\n");
|
bb_printf("kernel not configured for shared memory\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case LIMITS:
|
case LIMITS:
|
||||||
bb_printf ("------ Shared Memory Limits --------\n");
|
bb_printf("------ Shared Memory Limits --------\n");
|
||||||
if ((shmctl (0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0 )
|
if ((shmctl(0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0)
|
||||||
return;
|
return;
|
||||||
/* glibc 2.1.3 and all earlier libc's have ints as fields
|
/* glibc 2.1.3 and all earlier libc's have ints as fields
|
||||||
of struct shminfo; glibc 2.1.91 has unsigned long; ach */
|
of struct shminfo; glibc 2.1.91 has unsigned long; ach */
|
||||||
bb_printf ("max number of segments = %lu\n"
|
bb_printf("max number of segments = %lu\n"
|
||||||
"max seg size (kbytes) = %lu\n"
|
"max seg size (kbytes) = %lu\n"
|
||||||
"max total shared memory (pages) = %lu\n"
|
"max total shared memory (pages) = %lu\n"
|
||||||
"min seg size (bytes) = %lu\n",
|
"min seg size (bytes) = %lu\n",
|
||||||
(unsigned long) shminfo.shmmni,
|
(unsigned long) shminfo.shmmni,
|
||||||
(unsigned long) (shminfo.shmmax >> 10),
|
(unsigned long) (shminfo.shmmax >> 10),
|
||||||
(unsigned long) shminfo.shmall,
|
(unsigned long) shminfo.shmall,
|
||||||
(unsigned long) shminfo.shmmin);
|
(unsigned long) shminfo.shmmin);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case STATUS:
|
case STATUS:
|
||||||
bb_printf ("------ Shared Memory Status --------\n"
|
bb_printf("------ Shared Memory Status --------\n"
|
||||||
"segments allocated %d\n"
|
"segments allocated %d\n"
|
||||||
"pages allocated %ld\n"
|
"pages allocated %ld\n"
|
||||||
"pages resident %ld\n"
|
"pages resident %ld\n"
|
||||||
"pages swapped %ld\n"
|
"pages swapped %ld\n"
|
||||||
"Swap performance: %ld attempts\t %ld successes\n",
|
"Swap performance: %ld attempts\t %ld successes\n",
|
||||||
shm_info.used_ids,
|
shm_info.used_ids,
|
||||||
shm_info.shm_tot,
|
shm_info.shm_tot,
|
||||||
shm_info.shm_rss,
|
shm_info.shm_rss,
|
||||||
shm_info.shm_swp,
|
shm_info.shm_swp,
|
||||||
shm_info.swap_attempts, shm_info.swap_successes);
|
shm_info.swap_attempts, shm_info.swap_successes);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CREATOR:
|
case CREATOR:
|
||||||
bb_printf ("------ Shared Memory Segment Creators/Owners --------\n"
|
bb_printf("------ Shared Memory Segment Creators/Owners --------\n"
|
||||||
"%-10s %-10s %-10s %-10s %-10s %-10s\n",
|
"%-10s %-10s %-10s %-10s %-10s %-10s\n",
|
||||||
"shmid","perms","cuid","cgid","uid","gid");
|
"shmid", "perms", "cuid", "cgid", "uid", "gid");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TIME:
|
case TIME:
|
||||||
bb_printf ("------ Shared Memory Attach/Detach/Change Times --------\n"
|
bb_printf("------ Shared Memory Attach/Detach/Change Times --------\n"
|
||||||
"%-10s %-10s %-20s %-20s %-20s\n",
|
"%-10s %-10s %-20s %-20s %-20s\n",
|
||||||
"shmid","owner","attached","detached","changed");
|
"shmid", "owner", "attached", "detached", "changed");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PID:
|
case PID:
|
||||||
bb_printf ("------ Shared Memory Creator/Last-op --------\n"
|
bb_printf("------ Shared Memory Creator/Last-op --------\n"
|
||||||
"%-10s %-10s %-10s %-10s\n",
|
"%-10s %-10s %-10s %-10s\n",
|
||||||
"shmid","owner","cpid","lpid");
|
"shmid", "owner", "cpid", "lpid");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
bb_printf ("------ Shared Memory Segments --------\n"
|
bb_printf("------ Shared Memory Segments --------\n"
|
||||||
"%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n",
|
"%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n",
|
||||||
"key","shmid","owner","perms","bytes","nattch","status");
|
"key", "shmid", "owner", "perms", "bytes", "nattch",
|
||||||
|
"status");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (id = 0; id <= maxid; id++) {
|
for (id = 0; id <= maxid; id++) {
|
||||||
shmid = shmctl (id, SHM_STAT, &shmseg);
|
shmid = shmctl(id, SHM_STAT, &shmseg);
|
||||||
if (shmid < 0)
|
if (shmid < 0)
|
||||||
continue;
|
continue;
|
||||||
if (format == CREATOR) {
|
if (format == CREATOR) {
|
||||||
print_perms (shmid, ipcp);
|
print_perms(shmid, ipcp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pw = getpwuid(ipcp->uid);
|
pw = getpwuid(ipcp->uid);
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case TIME:
|
case TIME:
|
||||||
if (pw)
|
if (pw)
|
||||||
bb_printf ("%-10d %-10.10s", shmid, pw->pw_name);
|
bb_printf("%-10d %-10.10s", shmid, pw->pw_name);
|
||||||
else
|
else
|
||||||
bb_printf ("%-10d %-10d", shmid, ipcp->uid);
|
bb_printf("%-10d %-10d", shmid, ipcp->uid);
|
||||||
/* ctime uses static buffer: use separate calls */
|
/* ctime uses static buffer: use separate calls */
|
||||||
bb_printf(" %-20.16s", shmseg.shm_atime
|
bb_printf(" %-20.16s", shmseg.shm_atime
|
||||||
? ctime(&shmseg.shm_atime) + 4 : "Not set");
|
? ctime(&shmseg.shm_atime) + 4 : "Not set");
|
||||||
bb_printf(" %-20.16s", shmseg.shm_dtime
|
bb_printf(" %-20.16s", shmseg.shm_dtime
|
||||||
? ctime(&shmseg.shm_dtime) + 4 : "Not set");
|
? ctime(&shmseg.shm_dtime) + 4 : "Not set");
|
||||||
bb_printf(" %-20.16s\n", shmseg.shm_ctime
|
bb_printf(" %-20.16s\n", shmseg.shm_ctime
|
||||||
? ctime(&shmseg.shm_ctime) + 4 : "Not set");
|
? ctime(&shmseg.shm_ctime) + 4 : "Not set");
|
||||||
break;
|
break;
|
||||||
case PID:
|
case PID:
|
||||||
if (pw)
|
if (pw)
|
||||||
bb_printf ("%-10d %-10.10s", shmid, pw->pw_name);
|
bb_printf("%-10d %-10.10s", shmid, pw->pw_name);
|
||||||
else
|
else
|
||||||
bb_printf ("%-10d %-10d", shmid, ipcp->uid);
|
bb_printf("%-10d %-10d", shmid, ipcp->uid);
|
||||||
bb_printf (" %-10d %-10d\n",
|
bb_printf(" %-10d %-10d\n", shmseg.shm_cpid, shmseg.shm_lpid);
|
||||||
shmseg.shm_cpid, shmseg.shm_lpid);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
bb_printf("0x%08x ",ipcp->KEY );
|
bb_printf("0x%08x ", ipcp->KEY);
|
||||||
if (pw)
|
if (pw)
|
||||||
bb_printf ("%-10d %-10.10s", shmid, pw->pw_name);
|
bb_printf("%-10d %-10.10s", shmid, pw->pw_name);
|
||||||
else
|
else
|
||||||
bb_printf ("%-10d %-10d", shmid, ipcp->uid);
|
bb_printf("%-10d %-10d", shmid, ipcp->uid);
|
||||||
bb_printf ("%-10o %-10lu %-10ld %-6s %-6s\n",
|
bb_printf("%-10o %-10lu %-10ld %-6s %-6s\n", ipcp->mode & 0777,
|
||||||
ipcp->mode & 0777,
|
/*
|
||||||
/*
|
* earlier: int, Austin has size_t
|
||||||
* earlier: int, Austin has size_t
|
*/
|
||||||
*/
|
(unsigned long) shmseg.shm_segsz,
|
||||||
(unsigned long) shmseg.shm_segsz,
|
/*
|
||||||
/*
|
* glibc-2.1.3 and earlier has unsigned short;
|
||||||
* glibc-2.1.3 and earlier has unsigned short;
|
* Austin has shmatt_t
|
||||||
* Austin has shmatt_t
|
*/
|
||||||
*/
|
(long) shmseg.shm_nattch,
|
||||||
(long) shmseg.shm_nattch,
|
ipcp->mode & SHM_DEST ? "dest" : " ",
|
||||||
ipcp->mode & SHM_DEST ? "dest" : " ",
|
ipcp->mode & SHM_LOCKED ? "locked" : " ");
|
||||||
ipcp->mode & SHM_LOCKED ? "locked" : " ");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void do_sem (char format)
|
static void do_sem(void)
|
||||||
{
|
{
|
||||||
int maxid, semid, id;
|
int maxid, semid, id;
|
||||||
struct semid_ds semary;
|
struct semid_ds semary;
|
||||||
@ -263,107 +261,104 @@ static void do_sem (char format)
|
|||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
union semun arg;
|
union semun arg;
|
||||||
|
|
||||||
arg.array = (ushort *) (void *) &seminfo;
|
arg.array = (ushort *) (void *) &seminfo;
|
||||||
maxid = semctl (0, 0, SEM_INFO, arg);
|
maxid = semctl(0, 0, SEM_INFO, arg);
|
||||||
if (maxid < 0) {
|
if (maxid < 0) {
|
||||||
bb_printf ("kernel not configured for semaphores\n");
|
bb_printf("kernel not configured for semaphores\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case LIMITS:
|
case LIMITS:
|
||||||
bb_printf ("------ Semaphore Limits --------\n");
|
bb_printf("------ Semaphore Limits --------\n");
|
||||||
arg.array = (ushort *) (void *) &seminfo; /* damn union */
|
arg.array = (ushort *) (void *) &seminfo; /* damn union */
|
||||||
if ((semctl (0, 0, IPC_INFO, arg)) < 0 )
|
if ((semctl(0, 0, IPC_INFO, arg)) < 0)
|
||||||
return;
|
return;
|
||||||
bb_printf ("max number of arrays = %d\n"
|
bb_printf("max number of arrays = %d\n"
|
||||||
"max semaphores per array = %d\n"
|
"max semaphores per array = %d\n"
|
||||||
"max semaphores system wide = %d\n"
|
"max semaphores system wide = %d\n"
|
||||||
"max ops per semop call = %d\n"
|
"max ops per semop call = %d\n"
|
||||||
"semaphore max value = %d\n",
|
"semaphore max value = %d\n",
|
||||||
seminfo.semmni,
|
seminfo.semmni,
|
||||||
seminfo.semmsl,
|
seminfo.semmsl,
|
||||||
seminfo.semmns,
|
seminfo.semmns, seminfo.semopm, seminfo.semvmx);
|
||||||
seminfo.semopm,
|
|
||||||
seminfo.semvmx);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case STATUS:
|
case STATUS:
|
||||||
bb_printf ("------ Semaphore Status --------\n"
|
bb_printf("------ Semaphore Status --------\n"
|
||||||
"used arrays = %d\n"
|
"used arrays = %d\n"
|
||||||
"allocated semaphores = %d\n",
|
"allocated semaphores = %d\n",
|
||||||
seminfo.semusz,
|
seminfo.semusz, seminfo.semaem);
|
||||||
seminfo.semaem);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CREATOR:
|
case CREATOR:
|
||||||
bb_printf ("------ Semaphore Arrays Creators/Owners --------\n"
|
bb_printf("------ Semaphore Arrays Creators/Owners --------\n"
|
||||||
"%-10s %-10s %-10s %-10s %-10s %-10s\n",
|
"%-10s %-10s %-10s %-10s %-10s %-10s\n",
|
||||||
"semid","perms","cuid","cgid","uid","gid");
|
"semid", "perms", "cuid", "cgid", "uid", "gid");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TIME:
|
case TIME:
|
||||||
bb_printf ("------ Shared Memory Operation/Change Times --------\n"
|
bb_printf("------ Shared Memory Operation/Change Times --------\n"
|
||||||
"%-8s %-10s %-26.24s %-26.24s\n",
|
"%-8s %-10s %-26.24s %-26.24s\n",
|
||||||
"shmid","owner","last-op","last-changed");
|
"shmid", "owner", "last-op", "last-changed");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PID:
|
case PID:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
bb_printf ("------ Semaphore Arrays --------\n"
|
bb_printf("------ Semaphore Arrays --------\n"
|
||||||
"%-10s %-10s %-10s %-10s %-10s\n",
|
"%-10s %-10s %-10s %-10s %-10s\n",
|
||||||
"key","semid","owner","perms","nsems");
|
"key", "semid", "owner", "perms", "nsems");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (id = 0; id <= maxid; id++) {
|
for (id = 0; id <= maxid; id++) {
|
||||||
arg.buf = (struct semid_ds *) &semary;
|
arg.buf = (struct semid_ds *) &semary;
|
||||||
semid = semctl (id, 0, SEM_STAT, arg);
|
semid = semctl(id, 0, SEM_STAT, arg);
|
||||||
if (semid < 0)
|
if (semid < 0)
|
||||||
continue;
|
continue;
|
||||||
if (format == CREATOR) {
|
if (format == CREATOR) {
|
||||||
print_perms (semid, ipcp);
|
print_perms(semid, ipcp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pw = getpwuid(ipcp->uid);
|
pw = getpwuid(ipcp->uid);
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case TIME:
|
case TIME:
|
||||||
if (pw)
|
if (pw)
|
||||||
bb_printf ("%-8d %-10.10s", semid, pw->pw_name);
|
bb_printf("%-8d %-10.10s", semid, pw->pw_name);
|
||||||
else
|
else
|
||||||
bb_printf ("%-8d %-10d", semid, ipcp->uid);
|
bb_printf("%-8d %-10d", semid, ipcp->uid);
|
||||||
bb_printf (" %-26.24s", semary.sem_otime
|
/* ctime uses static buffer: use separate calls */
|
||||||
? ctime(&semary.sem_otime) : "Not set");
|
bb_printf(" %-26.24s", semary.sem_otime
|
||||||
bb_printf (" %-26.24s\n", semary.sem_ctime
|
? ctime(&semary.sem_otime) : "Not set");
|
||||||
? ctime(&semary.sem_ctime) : "Not set");
|
bb_printf(" %-26.24s\n", semary.sem_ctime
|
||||||
|
? ctime(&semary.sem_ctime) : "Not set");
|
||||||
break;
|
break;
|
||||||
case PID:
|
case PID:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
bb_printf("0x%08x ", ipcp->KEY);
|
bb_printf("0x%08x ", ipcp->KEY);
|
||||||
if (pw)
|
if (pw)
|
||||||
bb_printf ("%-10d %-10.9s", semid, pw->pw_name);
|
bb_printf("%-10d %-10.9s", semid, pw->pw_name);
|
||||||
else
|
else
|
||||||
bb_printf ("%-10d %-9d", semid, ipcp->uid);
|
bb_printf("%-10d %-9d", semid, ipcp->uid);
|
||||||
bb_printf ("%-10o %-10ld\n",
|
bb_printf("%-10o %-10ld\n", ipcp->mode & 0777,
|
||||||
ipcp->mode & 0777,
|
/*
|
||||||
/*
|
* glibc-2.1.3 and earlier has unsigned short;
|
||||||
* glibc-2.1.3 and earlier has unsigned short;
|
* glibc-2.1.91 has variation between
|
||||||
* glibc-2.1.91 has variation between
|
* unsigned short and unsigned long
|
||||||
* unsigned short and unsigned long
|
* Austin prescribes unsigned short.
|
||||||
* Austin prescribes unsigned short.
|
*/
|
||||||
*/
|
(long) semary.sem_nsems);
|
||||||
(long) semary.sem_nsems);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void do_msg (char format)
|
static void do_msg(void)
|
||||||
{
|
{
|
||||||
int maxid, msqid, id;
|
int maxid, msqid, id;
|
||||||
struct msqid_ds msgque;
|
struct msqid_ds msgque;
|
||||||
@ -371,178 +366,165 @@ static void do_msg (char format)
|
|||||||
struct ipc_perm *ipcp = &msgque.msg_perm;
|
struct ipc_perm *ipcp = &msgque.msg_perm;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
|
||||||
maxid = msgctl (0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo);
|
maxid = msgctl(0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo);
|
||||||
if (maxid < 0) {
|
if (maxid < 0) {
|
||||||
bb_printf ("kernel not configured for message queues\n");
|
bb_printf("kernel not configured for message queues\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case LIMITS:
|
case LIMITS:
|
||||||
if ((msgctl (0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0 )
|
if ((msgctl(0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0)
|
||||||
return;
|
return;
|
||||||
bb_printf ("------ Messages: Limits --------\n"
|
bb_printf("------ Messages: Limits --------\n"
|
||||||
"max queues system wide = %d\n"
|
"max queues system wide = %d\n"
|
||||||
"max size of message (bytes) = %d\n"
|
"max size of message (bytes) = %d\n"
|
||||||
"default max size of queue (bytes) = %d\n",
|
"default max size of queue (bytes) = %d\n",
|
||||||
msginfo.msgmni,
|
msginfo.msgmni, msginfo.msgmax, msginfo.msgmnb);
|
||||||
msginfo.msgmax,
|
|
||||||
msginfo.msgmnb);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case STATUS:
|
case STATUS:
|
||||||
bb_printf ("------ Messages: Status --------\n"
|
bb_printf("------ Messages: Status --------\n"
|
||||||
"allocated queues = %d\n"
|
"allocated queues = %d\n"
|
||||||
"used headers = %d\n"
|
"used headers = %d\n"
|
||||||
"used space = %d bytes\n",
|
"used space = %d bytes\n",
|
||||||
msginfo.msgpool,
|
msginfo.msgpool, msginfo.msgmap, msginfo.msgtql);
|
||||||
msginfo.msgmap,
|
|
||||||
msginfo.msgtql);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CREATOR:
|
case CREATOR:
|
||||||
bb_printf ("------ Message Queues: Creators/Owners --------\n"
|
bb_printf("------ Message Queues: Creators/Owners --------\n"
|
||||||
"%-10s %-10s %-10s %-10s %-10s %-10s\n",
|
"%-10s %-10s %-10s %-10s %-10s %-10s\n",
|
||||||
"msqid","perms","cuid","cgid","uid","gid");
|
"msqid", "perms", "cuid", "cgid", "uid", "gid");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TIME:
|
case TIME:
|
||||||
bb_printf ("------ Message Queues Send/Recv/Change Times --------\n"
|
bb_printf("------ Message Queues Send/Recv/Change Times --------\n"
|
||||||
"%-8s %-10s %-20s %-20s %-20s\n",
|
"%-8s %-10s %-20s %-20s %-20s\n",
|
||||||
"msqid","owner","send","recv","change");
|
"msqid", "owner", "send", "recv", "change");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PID:
|
case PID:
|
||||||
bb_printf ("------ Message Queues PIDs --------\n"
|
bb_printf("------ Message Queues PIDs --------\n"
|
||||||
"%-10s %-10s %-10s %-10s\n",
|
"%-10s %-10s %-10s %-10s\n",
|
||||||
"msqid","owner","lspid","lrpid");
|
"msqid", "owner", "lspid", "lrpid");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
bb_printf ("------ Message Queues --------\n"
|
bb_printf("------ Message Queues --------\n"
|
||||||
"%-10s %-10s %-10s %-10s %-12s %-12s\n",
|
"%-10s %-10s %-10s %-10s %-12s %-12s\n",
|
||||||
"key","msqid","owner","perms","used-bytes","messages");
|
"key", "msqid", "owner", "perms", "used-bytes", "messages");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (id = 0; id <= maxid; id++) {
|
for (id = 0; id <= maxid; id++) {
|
||||||
msqid = msgctl (id, MSG_STAT, &msgque);
|
msqid = msgctl(id, MSG_STAT, &msgque);
|
||||||
if (msqid < 0)
|
if (msqid < 0)
|
||||||
continue;
|
continue;
|
||||||
if (format == CREATOR) {
|
if (format == CREATOR) {
|
||||||
print_perms (msqid, ipcp);
|
print_perms(msqid, ipcp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pw = getpwuid(ipcp->uid);
|
pw = getpwuid(ipcp->uid);
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case TIME:
|
case TIME:
|
||||||
if (pw)
|
if (pw)
|
||||||
bb_printf ("%-8d %-10.10s", msqid, pw->pw_name);
|
bb_printf("%-8d %-10.10s", msqid, pw->pw_name);
|
||||||
else
|
else
|
||||||
bb_printf ("%-8d %-10d", msqid, ipcp->uid);
|
bb_printf("%-8d %-10d", msqid, ipcp->uid);
|
||||||
bb_printf (" %-20.16s", msgque.msg_stime
|
bb_printf(" %-20.16s", msgque.msg_stime
|
||||||
? ctime(&msgque.msg_stime) + 4 : "Not set");
|
? ctime(&msgque.msg_stime) + 4 : "Not set");
|
||||||
bb_printf (" %-20.16s", msgque.msg_rtime
|
bb_printf(" %-20.16s", msgque.msg_rtime
|
||||||
? ctime(&msgque.msg_rtime) + 4 : "Not set");
|
? ctime(&msgque.msg_rtime) + 4 : "Not set");
|
||||||
bb_printf (" %-20.16s\n", msgque.msg_ctime
|
bb_printf(" %-20.16s\n", msgque.msg_ctime
|
||||||
? ctime(&msgque.msg_ctime) + 4 : "Not set");
|
? ctime(&msgque.msg_ctime) + 4 : "Not set");
|
||||||
break;
|
break;
|
||||||
case PID:
|
case PID:
|
||||||
if (pw)
|
if (pw)
|
||||||
bb_printf ("%-8d %-10.10s", msqid, pw->pw_name);
|
bb_printf("%-8d %-10.10s", msqid, pw->pw_name);
|
||||||
else
|
else
|
||||||
bb_printf ("%-8d %-10d", msqid, ipcp->uid);
|
bb_printf("%-8d %-10d", msqid, ipcp->uid);
|
||||||
bb_printf (" %5d %5d\n",
|
bb_printf(" %5d %5d\n", msgque.msg_lspid, msgque.msg_lrpid);
|
||||||
msgque.msg_lspid, msgque.msg_lrpid);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
bb_printf( "0x%08x ",ipcp->KEY );
|
bb_printf("0x%08x ", ipcp->KEY);
|
||||||
if (pw)
|
if (pw)
|
||||||
bb_printf ("%-10d %-10.10s", msqid, pw->pw_name);
|
bb_printf("%-10d %-10.10s", msqid, pw->pw_name);
|
||||||
else
|
else
|
||||||
bb_printf ("%-10d %-10d", msqid, ipcp->uid);
|
bb_printf("%-10d %-10d", msqid, ipcp->uid);
|
||||||
bb_printf (" %-10o %-12ld %-12ld\n",
|
bb_printf(" %-10o %-12ld %-12ld\n", ipcp->mode & 0777,
|
||||||
ipcp->mode & 0777,
|
/*
|
||||||
/*
|
* glibc-2.1.3 and earlier has unsigned short;
|
||||||
* glibc-2.1.3 and earlier has unsigned short;
|
* glibc-2.1.91 has variation between
|
||||||
* glibc-2.1.91 has variation between
|
* unsigned short, unsigned long
|
||||||
* unsigned short, unsigned long
|
* Austin has msgqnum_t
|
||||||
* Austin has msgqnum_t
|
*/
|
||||||
*/
|
(long) msgque.msg_cbytes, (long) msgque.msg_qnum);
|
||||||
(long) msgque.msg_cbytes,
|
|
||||||
(long) msgque.msg_qnum);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_shm (int shmid)
|
static void print_shm(int shmid)
|
||||||
{
|
{
|
||||||
struct shmid_ds shmds;
|
struct shmid_ds shmds;
|
||||||
struct ipc_perm *ipcp = &shmds.shm_perm;
|
struct ipc_perm *ipcp = &shmds.shm_perm;
|
||||||
|
|
||||||
if (shmctl (shmid, IPC_STAT, &shmds) == -1) {
|
if (shmctl(shmid, IPC_STAT, &shmds) == -1) {
|
||||||
perror ("shmctl ");
|
bb_perror_msg("shmctl");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb_printf ("\nShared memory Segment shmid=%d\n"
|
bb_printf("\nShared memory Segment shmid=%d\n"
|
||||||
"uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n"
|
"uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n"
|
||||||
"mode=%#o\taccess_perms=%#o\n"
|
"mode=%#o\taccess_perms=%#o\n"
|
||||||
"bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n"
|
"bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n",
|
||||||
"att_time=%-26.24s\n"
|
shmid,
|
||||||
"det_time=%-26.24s\n"
|
ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
|
||||||
"change_time=%-26.24s\n"
|
ipcp->mode, ipcp->mode & 0777,
|
||||||
"\n",
|
(long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid,
|
||||||
shmid,
|
(long) shmds.shm_nattch);
|
||||||
ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
|
bb_printf("att_time=%-26.24s\n",
|
||||||
ipcp->mode, ipcp->mode & 0777,
|
shmds.shm_atime ? ctime(&shmds.shm_atime) : "Not set");
|
||||||
(long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid,
|
bb_printf("det_time=%-26.24s\n",
|
||||||
(long) shmds.shm_nattch,
|
shmds.shm_dtime ? ctime(&shmds.shm_dtime) : "Not set");
|
||||||
shmds.shm_atime ? ctime (&shmds.shm_atime) : "Not set",
|
bb_printf("change_time=%-26.24s\n\n", ctime(&shmds.shm_ctime));
|
||||||
shmds.shm_dtime ? ctime (&shmds.shm_dtime) : "Not set",
|
|
||||||
ctime (&shmds.shm_ctime));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_msg (int msqid)
|
static void print_msg(int msqid)
|
||||||
{
|
{
|
||||||
struct msqid_ds buf;
|
struct msqid_ds buf;
|
||||||
struct ipc_perm *ipcp = &buf.msg_perm;
|
struct ipc_perm *ipcp = &buf.msg_perm;
|
||||||
|
|
||||||
if (msgctl (msqid, IPC_STAT, &buf) == -1) {
|
if (msgctl(msqid, IPC_STAT, &buf) == -1) {
|
||||||
perror ("msgctl ");
|
bb_perror_msg("msgctl");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb_printf ("\nMessage Queue msqid=%d\n"
|
bb_printf("\nMessage Queue msqid=%d\n"
|
||||||
"uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n"
|
"uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n"
|
||||||
"cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n"
|
"cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n",
|
||||||
"send_time=%-26.24s\n"
|
msqid, ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode,
|
||||||
"rcv_time=%-26.24s\n"
|
/*
|
||||||
"change_time=%-26.24s\n"
|
* glibc-2.1.3 and earlier has unsigned short;
|
||||||
"\n",
|
* glibc-2.1.91 has variation between
|
||||||
msqid,
|
* unsigned short, unsigned long
|
||||||
ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode,
|
* Austin has msgqnum_t (for msg_qbytes)
|
||||||
/*
|
*/
|
||||||
* glibc-2.1.3 and earlier has unsigned short;
|
(long) buf.msg_cbytes, (long) buf.msg_qbytes,
|
||||||
* glibc-2.1.91 has variation between
|
(long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid);
|
||||||
* unsigned short, unsigned long
|
|
||||||
* Austin has msgqnum_t (for msg_qbytes)
|
bb_printf("send_time=%-26.24s\n",
|
||||||
*/
|
buf.msg_stime ? ctime(&buf.msg_stime) : "Not set");
|
||||||
(long) buf.msg_cbytes, (long) buf.msg_qbytes,
|
bb_printf("rcv_time=%-26.24s\n",
|
||||||
(long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid,
|
buf.msg_rtime ? ctime(&buf.msg_rtime) : "Not set");
|
||||||
buf.msg_stime ? ctime (&buf.msg_stime) : "Not set",
|
bb_printf("change_time=%-26.24s\n\n",
|
||||||
buf.msg_rtime ? ctime (&buf.msg_rtime) : "Not set",
|
buf.msg_ctime ? ctime(&buf.msg_ctime) : "Not set");
|
||||||
buf.msg_ctime ? ctime (&buf.msg_ctime) : "Not set");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_sem (int semid)
|
static void print_sem(int semid)
|
||||||
{
|
{
|
||||||
struct semid_ds semds;
|
struct semid_ds semds;
|
||||||
struct ipc_perm *ipcp = &semds.sem_perm;
|
struct ipc_perm *ipcp = &semds.sem_perm;
|
||||||
@ -550,66 +532,69 @@ static void print_sem (int semid)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
arg.buf = &semds;
|
arg.buf = &semds;
|
||||||
if (semctl (semid, 0, IPC_STAT, arg) < 0) {
|
if (semctl(semid, 0, IPC_STAT, arg)) {
|
||||||
perror ("semctl ");
|
bb_perror_msg("semctl");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb_printf ("\nSemaphore Array semid=%d\n"
|
bb_printf("\nSemaphore Array semid=%d\n"
|
||||||
"uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n"
|
"uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n"
|
||||||
"mode=%#o, access_perms=%#o\n"
|
"mode=%#o, access_perms=%#o\n"
|
||||||
"nsems = %ld\n"
|
"nsems = %ld\n"
|
||||||
"otime = %-26.24s\n"
|
"otime = %-26.24s\n",
|
||||||
"ctime = %-26.24s\n"
|
semid,
|
||||||
"%-10s %-10s %-10s %-10s %-10s\n",
|
ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
|
||||||
semid,
|
ipcp->mode, ipcp->mode & 0777,
|
||||||
ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
|
(long) semds.sem_nsems,
|
||||||
ipcp->mode, ipcp->mode & 0777,
|
semds.sem_otime ? ctime(&semds.sem_otime) : "Not set");
|
||||||
(long) semds.sem_nsems,
|
bb_printf("ctime = %-26.24s\n"
|
||||||
semds.sem_otime ? ctime (&semds.sem_otime) : "Not set",
|
"%-10s %-10s %-10s %-10s %-10s\n",
|
||||||
ctime (&semds.sem_ctime),
|
ctime(&semds.sem_ctime),
|
||||||
"semnum","value","ncount","zcount","pid");
|
"semnum", "value", "ncount", "zcount", "pid");
|
||||||
|
|
||||||
arg.val = 0;
|
arg.val = 0;
|
||||||
for (i=0; i < semds.sem_nsems; i++) {
|
for (i = 0; i < semds.sem_nsems; i++) {
|
||||||
int val, ncnt, zcnt, pid;
|
int val, ncnt, zcnt, pid;
|
||||||
val = semctl (semid, i, GETVAL, arg);
|
|
||||||
ncnt = semctl (semid, i, GETNCNT, arg);
|
val = semctl(semid, i, GETVAL, arg);
|
||||||
zcnt = semctl (semid, i, GETZCNT, arg);
|
ncnt = semctl(semid, i, GETNCNT, arg);
|
||||||
pid = semctl (semid, i, GETPID, arg);
|
zcnt = semctl(semid, i, GETZCNT, arg);
|
||||||
|
pid = semctl(semid, i, GETPID, arg);
|
||||||
if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) {
|
if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) {
|
||||||
perror ("semctl ");
|
bb_perror_msg_and_die("semctl");
|
||||||
bb_fflush_stdout_and_exit (1);
|
|
||||||
}
|
}
|
||||||
bb_printf ("%-10d %-10d %-10d %-10d %-10d\n",
|
bb_printf("%-10d %-10d %-10d %-10d %-10d\n", i, val, ncnt, zcnt, pid);
|
||||||
i, val, ncnt, zcnt, pid);
|
|
||||||
}
|
}
|
||||||
bb_printf ("\n");
|
bb_printf("\n");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipcs_main (int argc, char **argv) {
|
int ipcs_main(int argc, char **argv)
|
||||||
int opt, msg = 0, sem = 0, shm = 0, id=0, print=0;
|
{
|
||||||
char format = 0;
|
int opt, id = 0;
|
||||||
char options[] = "atclupsmqi:ih?";
|
unsigned flags = 0;
|
||||||
|
#define flag_print (1<<0)
|
||||||
|
#define flag_msg (1<<1)
|
||||||
|
#define flag_sem (1<<2)
|
||||||
|
#define flag_shm (1<<3)
|
||||||
|
const char *const options = "atclupsmqi:ih?";
|
||||||
|
|
||||||
while ((opt = getopt (argc, argv, options)) != -1) {
|
while ((opt = getopt(argc, argv, options)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'i':
|
case 'i':
|
||||||
id = atoi (optarg);
|
id = atoi(optarg);
|
||||||
print = 1;
|
flags |= flag_print;
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
msg = shm = sem = 1;
|
flags |= flag_msg | flag_sem | flag_shm;
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
msg = 1;
|
flags |= flag_msg;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
sem = 1;
|
flags |= flag_sem;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
shm = 1;
|
flags |= flag_shm;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
format = TIME;
|
format = TIME;
|
||||||
@ -629,43 +614,40 @@ int ipcs_main (int argc, char **argv) {
|
|||||||
case 'h':
|
case 'h':
|
||||||
case '?':
|
case '?':
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
bb_fflush_stdout_and_exit (0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print) {
|
if (flags & flag_print) {
|
||||||
if (shm) {
|
if (flags & flag_shm) {
|
||||||
print_shm (id);
|
print_shm(id);
|
||||||
bb_fflush_stdout_and_exit (0);
|
bb_fflush_stdout_and_exit(0);
|
||||||
}
|
}
|
||||||
if (sem) {
|
if (flags & flag_sem) {
|
||||||
print_sem (id);
|
print_sem(id);
|
||||||
bb_fflush_stdout_and_exit (0);
|
bb_fflush_stdout_and_exit(0);
|
||||||
}
|
}
|
||||||
if (msg) {
|
if (flags & flag_msg) {
|
||||||
print_msg (id);
|
print_msg(id);
|
||||||
bb_fflush_stdout_and_exit (0);
|
bb_fflush_stdout_and_exit(0);
|
||||||
}
|
}
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
bb_fflush_stdout_and_exit (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !shm && !msg && !sem)
|
if (!(flags & (flag_shm | flag_msg | flag_sem)))
|
||||||
msg = sem = shm = 1;
|
flags |= flag_msg | flag_shm | flag_sem;
|
||||||
bb_printf ("\n");
|
bb_printf("\n");
|
||||||
|
|
||||||
if (shm) {
|
if (flags & flag_shm) {
|
||||||
do_shm (format);
|
do_shm();
|
||||||
bb_printf ("\n");
|
bb_printf("\n");
|
||||||
}
|
}
|
||||||
if (sem) {
|
if (flags & flag_sem) {
|
||||||
do_sem (format);
|
do_sem();
|
||||||
bb_printf ("\n");
|
bb_printf("\n");
|
||||||
}
|
}
|
||||||
if (msg) {
|
if (flags & flag_msg) {
|
||||||
do_msg (format);
|
do_msg();
|
||||||
bb_printf ("\n");
|
bb_printf("\n");
|
||||||
}
|
}
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user