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