last_patch89 from vodz:
Manuel,
    I rewrite bb_getopt_ulflags() function for more universal usage.
    My version support now:
    - options with arguments (optional arg as GNU extension also)
    - complementaly and/or incomplementaly and/or incongruously and/or list
    options
    - long_opt (all applets may have long option, add supporting is trivial)
    This realisation full compatibile from your version.
    Code size grow 480 bytes, but only coreutils/* over compensate this size
    after using new function. Last patch reduced over 800 bytes and not full
    applied to all. "mkdir" and "mv" applets have long_opt now for demonstrate
    trivial addition support long_opt with usage new bb_getopt_ulflags().
    Complementaly and/or incomplementaly and/or incongruously and/or list options
    logic is not trivial, but new "cut" and "grep" applets using this logic
    for examples with full demostrating. New "grep" applet reduced over 300
    bytes.
    Mark,
    Also. I removed bug from "grep" applet.
    $ echo a b | busybox grep -e a b
    a b
    a b
    But right is printing one only.
    --w
    vodz
			
			
This commit is contained in:
		| @@ -22,20 +22,22 @@ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> /* getopt */ | ||||
| #include <getopt.h> | ||||
| #include <unistd.h> | ||||
| #include <string.h> | ||||
| #include <limits.h> | ||||
| #include "busybox.h" | ||||
|  | ||||
|  | ||||
| /* globals from other files */ | ||||
| extern int optind; | ||||
| extern char *optarg; | ||||
|  | ||||
|  | ||||
| /* option vars */ | ||||
| static char part = 0; /* (b)yte, (c)har, (f)ields */ | ||||
| static unsigned int supress_non_delimited_lines = 0; | ||||
| 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 */ | ||||
|  | ||||
| struct cut_list { | ||||
| @@ -270,11 +272,11 @@ static void cut_file(FILE *file) | ||||
| 	while ((line = bb_get_chomped_line_from_file(file)) != NULL) { | ||||
|  | ||||
| 		/* cut based on chars/bytes XXX: only works when sizeof(char) == byte */ | ||||
| 		if (part == 'c' || part == 'b') | ||||
| 		if ((part & (OPT_CHAR_FLGS | OPT_BYTE_FLGS))) | ||||
| 			cut_line_by_chars(line); | ||||
|  | ||||
| 		/* cut based on fields */ | ||||
| 		else if (part == 'f') { | ||||
| 		else { | ||||
| 			if (delim == '\n') | ||||
| 				cut_file_by_lines(line, linenum); | ||||
| 			else | ||||
| @@ -289,46 +291,32 @@ static void cut_file(FILE *file) | ||||
|  | ||||
| extern int cut_main(int argc, char **argv) | ||||
| { | ||||
| 	int opt; | ||||
| 	unsigned long opt; | ||||
| 	char *sopt, *sdopt; | ||||
|  | ||||
| 	while ((opt = getopt(argc, argv, "b:c:d:f:ns")) > 0) { | ||||
| 		switch (opt) { | ||||
| 			case 'b': | ||||
| 			case 'c': | ||||
| 			case 'f': | ||||
| 				/* make sure they didn't ask for two types of lists */ | ||||
| 				if (part != 0) { | ||||
| 	bb_opt_complementaly = "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 & 0x80000000UL) | ||||
| 					bb_error_msg_and_die("only one type of list may be specified"); | ||||
| 				} | ||||
| 				part = (char)opt; | ||||
| 				parse_lists(optarg); | ||||
| 				break; | ||||
| 			case 'd': | ||||
| 				if (strlen(optarg) > 1) { | ||||
| 	parse_lists(sopt); | ||||
| 	if((opt & (OPT_DELIM_FLGS))) { | ||||
| 		if (strlen(sdopt) > 1) { | ||||
| 					bb_error_msg_and_die("the delimiter must be a single character"); | ||||
| 				} | ||||
| 				delim = optarg[0]; | ||||
| 				break; | ||||
| 			case 'n': | ||||
| 				/* no-op */ | ||||
| 				break; | ||||
| 			case 's': | ||||
| 				supress_non_delimited_lines++; | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (part == 0) { | ||||
| 		bb_error_msg_and_die("you must specify a list of bytes, characters, or fields"); | ||||
| 		delim = sdopt[0]; | ||||
| 	} | ||||
| 	supress_non_delimited_lines = opt & OPT_SUPRESS_FLGS; | ||||
|  | ||||
| 	/*  non-field (char or byte) cutting has some special handling */ | ||||
| 	if (part != 'f') { | ||||
| 	if (part != OPT_FIELDS_FLGS) { | ||||
| 		if (supress_non_delimited_lines) { | ||||
| 			bb_error_msg_and_die("suppressing non-delimited lines makes sense" | ||||
| 					" only when operating on fields"); | ||||
| 		} | ||||
| 		if (delim != '\t' && part != 'f') { | ||||
| 		if (delim != '\t') { | ||||
| 			bb_error_msg_and_die("a delimiter may be specified only when operating on fields"); | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -120,74 +120,65 @@ int date_main(int argc, char **argv) | ||||
| 	char *date_str = NULL; | ||||
| 	char *date_fmt = NULL; | ||||
| 	char *t_buff; | ||||
| 	int c; | ||||
| 	int set_time = 0; | ||||
| 	int rfc822 = 0; | ||||
| 	int utc = 0; | ||||
| 	int set_time; | ||||
| 	int rfc822; | ||||
| 	int utc; | ||||
| 	int use_arg = 0; | ||||
| 	time_t tm; | ||||
| 	unsigned long opt; | ||||
| 	struct tm tm_time; | ||||
|  | ||||
| #ifdef CONFIG_FEATURE_DATE_ISOFMT | ||||
| 	int ifmt = 0; | ||||
| 	char *isofmt_arg; | ||||
|  | ||||
| # define GETOPT_ISOFMT  "I::" | ||||
| #else | ||||
| # define GETOPT_ISOFMT | ||||
| #endif | ||||
|  | ||||
| 	/* Interpret command line args */ | ||||
| 	while ((c = getopt(argc, argv, "Rs:ud:" GETOPT_ISOFMT)) != EOF) { | ||||
| 		switch (c) { | ||||
| 		case 'R': | ||||
| 			rfc822 = 1; | ||||
| 			break; | ||||
| 		case 's': | ||||
| 			set_time = 1; | ||||
| 			if ((date_str != NULL) || ((date_str = optarg) == NULL)) { | ||||
| 				bb_show_usage(); | ||||
| 			} | ||||
| 			break; | ||||
| 		case 'u': | ||||
| 			utc = 1; | ||||
| 	bb_opt_complementaly = "d~ds:s~ds"; | ||||
| 	opt = bb_getopt_ulflags(argc, argv, "Rs:ud:" GETOPT_ISOFMT, | ||||
| 					&date_str, &date_str | ||||
| #ifdef CONFIG_FEATURE_DATE_ISOFMT | ||||
| 					, &isofmt_arg | ||||
| #endif | ||||
| 					); | ||||
| 	rfc822 = opt & 1; | ||||
| 	set_time = opt & 2; | ||||
| 	utc = opt & 4; | ||||
| 	if(utc) { | ||||
| 			if (putenv("TZ=UTC0") != 0) | ||||
| 				bb_error_msg_and_die(bb_msg_memory_exhausted); | ||||
| 			break; | ||||
| 		case 'd': | ||||
| 			use_arg = 1; | ||||
| 			if ((date_str != NULL) || ((date_str = optarg) == NULL)) | ||||
| 	} | ||||
| 	use_arg = opt & 8; | ||||
| 	if(opt & 0x80000000UL) | ||||
| 				bb_show_usage(); | ||||
| 			break; | ||||
| #ifdef CONFIG_FEATURE_DATE_ISOFMT | ||||
| 		case 'I': | ||||
| 			if (!optarg) | ||||
| 	if(opt & 16) { | ||||
| 		if (!isofmt_arg) | ||||
| 				ifmt = 1; | ||||
| 			else { | ||||
| 				int ifmt_len = bb_strlen(optarg); | ||||
| 			int ifmt_len = bb_strlen(isofmt_arg); | ||||
|  | ||||
| 				if ((ifmt_len <= 4) | ||||
| 					&& (strncmp(optarg, "date", ifmt_len) == 0)) { | ||||
| 				&& (strncmp(isofmt_arg, "date", ifmt_len) == 0)) { | ||||
| 					ifmt = 1; | ||||
| 				} else if ((ifmt_len <= 5) | ||||
| 						   && (strncmp(optarg, "hours", ifmt_len) == 0)) { | ||||
| 					   && (strncmp(isofmt_arg, "hours", ifmt_len) == 0)) { | ||||
| 					ifmt = 2; | ||||
| 				} else if ((ifmt_len <= 7) | ||||
| 						   && (strncmp(optarg, "minutes", ifmt_len) == 0)) { | ||||
| 					   && (strncmp(isofmt_arg, "minutes", ifmt_len) == 0)) { | ||||
| 					ifmt = 3; | ||||
| 				} else if ((ifmt_len <= 7) | ||||
| 						   && (strncmp(optarg, "seconds", ifmt_len) == 0)) { | ||||
| 					   && (strncmp(isofmt_arg, "seconds", ifmt_len) == 0)) { | ||||
| 					ifmt = 4; | ||||
| 				} | ||||
| 			} | ||||
| 			if (ifmt) { | ||||
| 				break;	/* else bb_show_usage(); */ | ||||
| 			} | ||||
| #endif | ||||
| 		default: | ||||
| 		if (!ifmt) { | ||||
| 			bb_show_usage(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| #endif | ||||
|  | ||||
| 	if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) { | ||||
| 		date_fmt = &argv[optind][1];	/* Skip over the '+' */ | ||||
|   | ||||
| @@ -106,9 +106,7 @@ int dd_main(int argc, char **argv) | ||||
| 	buf = xmalloc(bs); | ||||
|  | ||||
| 	if (infile != NULL) { | ||||
| 		if ((ifd = open(infile, O_RDONLY)) < 0) { | ||||
| 			bb_perror_msg_and_die("%s", infile); | ||||
| 		} | ||||
| 		ifd = bb_xopen(infile, O_RDONLY); | ||||
| 	} else { | ||||
| 		ifd = STDIN_FILENO; | ||||
| 		infile = bb_msg_standard_input; | ||||
|   | ||||
| @@ -55,41 +55,27 @@ extern int df_main(int argc, char **argv) | ||||
| 	unsigned long df_disp_hr = KILOBYTE;  | ||||
| #endif | ||||
| 	int status = EXIT_SUCCESS; | ||||
| 	int opt; | ||||
| 	unsigned long opt; | ||||
| 	FILE *mount_table; | ||||
| 	struct mntent *mount_entry; | ||||
| 	struct statfs s; | ||||
| 	static const char hdr_1k[] = "1k-blocks"; /* default display is kilobytes */ | ||||
| 	const char *disp_units_hdr = hdr_1k; | ||||
|  | ||||
| 	while ((opt = getopt(argc, argv, "k" | ||||
| #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||||
| 	"hm" | ||||
| #endif | ||||
| )) > 0) | ||||
| 	{ | ||||
| 		switch (opt) { | ||||
| #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||||
| 			case 'h': | ||||
| 	bb_opt_complementaly = "h-km:k-hm:m-hk"; | ||||
| 	opt = bb_getopt_ulflags(argc, argv, "hmk"); | ||||
| 	if(opt & 1) { | ||||
| 				df_disp_hr = 0; | ||||
| 				disp_units_hdr = "     Size"; | ||||
| 				break; | ||||
| 			case 'm': | ||||
| 	} | ||||
| 	if(opt & 2) { | ||||
| 				df_disp_hr = MEGABYTE; | ||||
| 				disp_units_hdr = "1M-blocks"; | ||||
| 				break; | ||||
| #endif | ||||
| 			case 'k': | ||||
| 				/* default display is kilobytes */ | ||||
| #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||||
| 				df_disp_hr = KILOBYTE; | ||||
| 				disp_units_hdr =  hdr_1k; | ||||
| #endif | ||||
| 				break; | ||||
| 			default: | ||||
| 					  bb_show_usage(); | ||||
| 		} | ||||
| 	} | ||||
| #else | ||||
| 	opt = bb_getopt_ulflags(argc, argv, "k"); | ||||
| #endif | ||||
|  | ||||
| 	bb_printf("Filesystem%11s%-15sUsed Available Use%% Mounted on\n", | ||||
| 			  "", disp_units_hdr); | ||||
|   | ||||
							
								
								
									
										105
									
								
								coreutils/du.c
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								coreutils/du.c
									
									
									
									
									
								
							| @@ -166,8 +166,9 @@ int du_main(int argc, char **argv) | ||||
| { | ||||
| 	long total; | ||||
| 	int slink_depth_save; | ||||
| 	int print_final_total = 0; | ||||
| 	int c; | ||||
| 	int print_final_total; | ||||
| 	char *smax_print_depth; | ||||
| 	unsigned long opt; | ||||
|  | ||||
| #ifdef CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K | ||||
| 	if (getenv("POSIXLY_CORRECT")) {	/* TODO - a new libbb function? */ | ||||
| @@ -185,57 +186,57 @@ int du_main(int argc, char **argv) | ||||
| 	 * gnu du exits with an error code in this case.  We choose to simply | ||||
| 	 * ignore -a.  This is consistent with -s being equivalent to -d 0. | ||||
| 	 */ | ||||
|  | ||||
| 	while ((c = getopt(argc, argv, "aHkLsx" "d:" "lc" | ||||
| #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||||
| 					   "hm" | ||||
| #endif | ||||
| 					   )) > 0) { | ||||
| 		switch (c) { | ||||
| 		case 'a': | ||||
| 			print_files = INT_MAX; | ||||
| 			break; | ||||
| 		case 'H': | ||||
| 			slink_depth = 1; | ||||
| 			break; | ||||
| 		case 'k': | ||||
| #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||||
| 			disp_hr = KILOBYTE; | ||||
| #elif !defined CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K | ||||
| 			disp_k = 1; | ||||
| #endif | ||||
| 			break; | ||||
| 		case 'L': | ||||
| 			slink_depth = INT_MAX; | ||||
| 			break; | ||||
| 		case 's': | ||||
| 			max_print_depth = 0; | ||||
| 			break; | ||||
| 		case 'x': | ||||
| 			one_file_system = 1; | ||||
| 			break; | ||||
|  | ||||
| 		case 'd': | ||||
| 			max_print_depth = bb_xgetularg10_bnd(optarg, 0, INT_MAX); | ||||
| 			break; | ||||
| 		case 'l': | ||||
| 			count_hardlinks = 1; | ||||
| 			break; | ||||
| 		case 'c': | ||||
| 			print_final_total = 1; | ||||
| 			break; | ||||
| #ifdef CONFIG_FEATURE_HUMAN_READABLE | ||||
| 		case 'h': | ||||
| 			disp_hr = 0; | ||||
| 			break; | ||||
| 		case 'm': | ||||
| 			disp_hr = MEGABYTE; | ||||
| 			break; | ||||
| #endif | ||||
| 		default: | ||||
| 			bb_show_usage(); | ||||
| 		} | ||||
| 	bb_opt_complementaly = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s"; | ||||
| 	opt = bb_getopt_ulflags(argc, argv, "aHkLsx" "d:" "lc" "hm", &smax_print_depth); | ||||
| 	if((opt & (1 << 9))) { | ||||
| 		/* -h opt */ | ||||
| 		disp_hr = 0; | ||||
| 	} | ||||
| 	if((opt & (1 << 10))) { | ||||
| 		/* -m opt */ | ||||
| 		disp_hr = MEGABYTE; | ||||
| 	} | ||||
| 	if((opt & (1 << 2))) { | ||||
| 		/* -k opt */ | ||||
| 			disp_hr = KILOBYTE; | ||||
| 	} | ||||
| #else | ||||
| 	bb_opt_complementaly = "H-L:L-H:s-d:d-s"; | ||||
| 	opt = bb_getopt_ulflags(argc, argv, "aHkLsx" "d:" "lc", &smax_print_depth); | ||||
| #if !defined CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K | ||||
| 	if((opt & (1 << 2))) { | ||||
| 		/* -k opt */ | ||||
| 			disp_k = 1; | ||||
| 	} | ||||
| #endif | ||||
| #endif | ||||
| 	if((opt & (1 << 0))) { | ||||
| 		/* -a opt */ | ||||
| 		print_files = INT_MAX; | ||||
| 	} | ||||
| 	if((opt & (1 << 1))) { | ||||
| 		/* -H opt */ | ||||
| 		slink_depth = 1; | ||||
| 	} | ||||
| 	if((opt & (1 << 3))) { | ||||
| 		/* -L opt */ | ||||
| 			slink_depth = INT_MAX; | ||||
| 	} | ||||
| 	if((opt & (1 << 4))) { | ||||
| 		/* -s opt */ | ||||
| 			max_print_depth = 0; | ||||
| 		} | ||||
| 	one_file_system = opt & (1 << 5); /* -x opt */ | ||||
| 	if((opt & (1 << 6))) { | ||||
| 		/* -d opt */ | ||||
| 		max_print_depth = bb_xgetularg10_bnd(smax_print_depth, 0, INT_MAX); | ||||
| 	} | ||||
| 	if((opt & (1 << 7))) { | ||||
| 		/* -l opt */ | ||||
| 		count_hardlinks = 1; | ||||
| 	} | ||||
| 	print_final_total = opt & (1 << 8); /* -c opt */ | ||||
|  | ||||
| 	/* go through remaining args (if any) */ | ||||
| 	argv += optind; | ||||
| @@ -252,7 +253,9 @@ int du_main(int argc, char **argv) | ||||
| 		total += du(*argv); | ||||
| 		slink_depth = slink_depth_save; | ||||
| 	} while (*++argv); | ||||
| #ifdef CONFIG_FEATURE_CLEAN_UP | ||||
| 	reset_ino_dev_hashtable(); | ||||
| #endif | ||||
|  | ||||
| 	if (print_final_total) { | ||||
| 		print(total, "total"); | ||||
|   | ||||
| @@ -44,20 +44,13 @@ extern int env_main(int argc, char** argv) | ||||
| { | ||||
| 	char **ep, *p; | ||||
| 	char *cleanenv[1] = { NULL }; | ||||
| 	int ch; | ||||
| 	unsigned long opt; | ||||
|  | ||||
| 	while ((ch = getopt(argc, argv, "iu:")) > 0) { | ||||
| 		switch(ch) { | ||||
| 		case 'i': | ||||
| 	opt = bb_getopt_ulflags(argc, argv, "iu:", &p); | ||||
| 	if(opt & 1) | ||||
| 			environ = cleanenv; | ||||
| 			break; | ||||
| 		case 'u': | ||||
| 			unsetenv(optarg); | ||||
| 			break; | ||||
| 		default: | ||||
| 			bb_show_usage(); | ||||
| 		} | ||||
| 	} | ||||
| 	if(opt & 2) | ||||
| 		unsetenv(p); | ||||
|  | ||||
| 	argv += optind; | ||||
|  | ||||
|   | ||||
| @@ -31,27 +31,33 @@ | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <getopt.h> | ||||
| #include "busybox.h" | ||||
|  | ||||
| static const struct option mkdir_long_options[] = { | ||||
| 	{ "mode", 1, NULL, 'm' }, | ||||
| 	{ "parents", 0, NULL, 'p' }, | ||||
| 	{ 0, 0, 0, 0 } | ||||
| }; | ||||
|  | ||||
| extern int mkdir_main (int argc, char **argv) | ||||
| { | ||||
| 	mode_t mode = (mode_t)(-1); | ||||
| 	int status = EXIT_SUCCESS; | ||||
| 	int flags = 0; | ||||
| 	int opt; | ||||
| 	unsigned long opt; | ||||
| 	char *smode; | ||||
|  | ||||
| 	while ((opt = getopt (argc, argv, "m:p")) > 0) { | ||||
| 		if (opt == 'm') { | ||||
| 	bb_applet_long_options = mkdir_long_options; | ||||
| 	opt = bb_getopt_ulflags(argc, argv, "m:p", &smode); | ||||
| 	if(opt & 1) { | ||||
| 			mode = 0777; | ||||
| 			if (!bb_parse_mode (optarg, &mode)) { | ||||
| 				bb_error_msg_and_die ("invalid mode `%s'", optarg); | ||||
| 			} | ||||
| 		} else if (opt == 'p') { | ||||
| 			flags |= FILEUTILS_RECUR; | ||||
| 		} else { | ||||
| 			bb_show_usage(); | ||||
| 		if (!bb_parse_mode (smode, &mode)) { | ||||
| 			bb_error_msg_and_die ("invalid mode `%s'", smode); | ||||
| 		} | ||||
| 	} | ||||
| 	if(opt & 2) | ||||
| 		flags |= FILEUTILS_RECUR; | ||||
|  | ||||
| 	if (optind == argc) { | ||||
| 		bb_show_usage(); | ||||
|   | ||||
| @@ -31,10 +31,21 @@ | ||||
| #include <dirent.h> | ||||
| #include <errno.h> | ||||
| #include <stdlib.h> | ||||
| #include <getopt.h> | ||||
| #include "busybox.h" | ||||
| #include "libcoreutils/coreutils.h" | ||||
|  | ||||
| static const char *fmt = "cannot overwrite %sdirectory with %sdirectory"; | ||||
| static const struct option mv_long_options[] = { | ||||
| 	{ "interactive", 0, NULL, 'i' }, | ||||
| 	{ "force", 0, NULL, 'f' }, | ||||
| 	{ 0, 0, 0, 0 } | ||||
| }; | ||||
|  | ||||
| static const char mv_getopt_short_option[] = "fi"; | ||||
| #define OPT_FILEUTILS_FORCE       1 | ||||
| #define OPT_FILEUTILS_INTERACTIVE 2 | ||||
|  | ||||
| static const char fmt[] = "cannot overwrite %sdirectory with %sdirectory"; | ||||
|  | ||||
| extern int mv_main(int argc, char **argv) | ||||
| { | ||||
| @@ -44,20 +55,12 @@ extern int mv_main(int argc, char **argv) | ||||
| 	const char *dest; | ||||
| 	int dest_exists; | ||||
| 	int source_exists; | ||||
| 	int opt; | ||||
| 	int flags = 0; | ||||
| 	unsigned long flags; | ||||
| 	int status = 0; | ||||
|  | ||||
| 	while ((opt = getopt(argc, argv, "fi")) > 0) { | ||||
| 		flags &= ~(FILEUTILS_INTERACTIVE | FILEUTILS_FORCE); | ||||
| 		if (opt == 'i') { | ||||
| 			flags |= FILEUTILS_INTERACTIVE; | ||||
| 		} else if (opt == 'f') { | ||||
| 			flags |= FILEUTILS_FORCE; | ||||
| 		} else { | ||||
| 			bb_show_usage(); | ||||
| 		} | ||||
| 	} | ||||
| 	bb_applet_long_options = mv_long_options; | ||||
| 	bb_opt_complementaly = "f-i:i-f"; | ||||
| 	flags = bb_getopt_ulflags(argc, argv, mv_getopt_short_option); | ||||
|  | ||||
| 	if (optind + 2 > argc) | ||||
| 		bb_show_usage(); | ||||
| @@ -77,8 +80,7 @@ extern int mv_main(int argc, char **argv) | ||||
| 	} | ||||
| 	 | ||||
| 	do { | ||||
| 		dest = concat_path_file(last, | ||||
| 								bb_get_last_path_component(*argv)); | ||||
| 		dest = concat_path_file(last, bb_get_last_path_component(*argv)); | ||||
|  | ||||
| 		if ((dest_exists = cp_mv_stat(dest, &dest_stat)) < 0) { | ||||
| 			goto RET_1; | ||||
| @@ -86,9 +88,9 @@ extern int mv_main(int argc, char **argv) | ||||
|  | ||||
| 	DO_MOVE: | ||||
| 		 | ||||
| 		if (dest_exists && !(flags & FILEUTILS_FORCE) && | ||||
| 		if (dest_exists && !(flags & OPT_FILEUTILS_FORCE) && | ||||
| 			((access(dest, W_OK) < 0 && isatty(0)) || | ||||
| 			 (flags & FILEUTILS_INTERACTIVE))) { | ||||
| 			 (flags & OPT_FILEUTILS_INTERACTIVE))) { | ||||
| 				 if (fprintf(stderr, "mv: overwrite `%s'? ", dest) < 0) { | ||||
| 					 goto RET_1;	/* Ouch! fprintf failed! */ | ||||
| 				 } | ||||
|   | ||||
| @@ -36,22 +36,16 @@ extern int rm_main(int argc, char **argv) | ||||
| { | ||||
| 	int status = 0; | ||||
| 	int flags = 0; | ||||
| 	int opt; | ||||
| 	unsigned long opt; | ||||
|  | ||||
| 	while ((opt = getopt(argc, argv, "fiRr")) > 0) { | ||||
| 		if ((opt == 'r') || (opt == 'R')) { | ||||
| 			flags |= FILEUTILS_RECUR; | ||||
| 		} else { | ||||
| 			flags &= ~(FILEUTILS_INTERACTIVE | FILEUTILS_FORCE); | ||||
| 			if (opt == 'i') { | ||||
| 				flags |= FILEUTILS_INTERACTIVE; | ||||
| 			} else if (opt == 'f') { | ||||
| 	bb_opt_complementaly = "f-i:i-f"; | ||||
| 	opt = bb_getopt_ulflags(argc, argv, "fiRr"); | ||||
| 	if(opt & 1) | ||||
| 				flags |= FILEUTILS_FORCE; | ||||
| 			} else { | ||||
| 				bb_show_usage(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if(opt & 2) | ||||
| 		flags |= FILEUTILS_INTERACTIVE; | ||||
| 	if(opt & 12) | ||||
| 		flags |= FILEUTILS_RECUR; | ||||
|  | ||||
| 	if (*(argv += optind) != NULL) { | ||||
| 		do { | ||||
|   | ||||
| @@ -414,22 +414,25 @@ static int           set_mode(const struct mode_info *info, | ||||
| 					int reversed, struct termios *mode); | ||||
| static speed_t       string_to_baud(const char *arg); | ||||
| static tcflag_t*     mode_type_flag(enum mode_type type, struct termios *mode); | ||||
| static void          display_all(struct termios *mode, int fd, | ||||
| 								 const char *device_name); | ||||
| static void          display_changed(struct termios *mode, int fd, | ||||
| 									 const char *device_name); | ||||
| static void          display_recoverable(struct termios *mode, int fd, | ||||
| 										 const char *device_name); | ||||
| static void          display_all(struct termios *mode, int fd); | ||||
| static void          display_changed(struct termios *mode, int fd); | ||||
| static void          display_recoverable(struct termios *mode, int fd); | ||||
| static void          display_speed(struct termios *mode, int fancy); | ||||
| static void          display_window_size(int fancy, int fd, | ||||
| 					const char *device_name); | ||||
| static void          display_window_size(int fancy, int fd); | ||||
| static void          sane_mode(struct termios *mode); | ||||
| static void          set_control_char(const struct control_info *info, | ||||
| 					const char *arg, struct termios *mode); | ||||
| static void          set_speed(enum speed_setting type, | ||||
| 					const char *arg, struct termios *mode); | ||||
| static void          set_window_size(int rows, int cols, int fd, | ||||
| 					const char *device_name); | ||||
| static void          set_window_size(int rows, int cols, int fd); | ||||
|  | ||||
| static const char *device_name; | ||||
|  | ||||
| static __attribute__ ((noreturn)) void perror_on_device(const char *fmt) | ||||
| { | ||||
| 	bb_perror_msg_and_die(fmt, device_name); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* The width of the screen, for output wrapping. */ | ||||
| static int max_col; | ||||
| @@ -477,7 +480,7 @@ extern int main(int argc, char **argv) | ||||
| #endif | ||||
| { | ||||
| 	struct termios mode; | ||||
| 	void (*output_func)(struct termios *, int, const char *); | ||||
| 	void (*output_func)(struct termios *, int); | ||||
| 	int    optc; | ||||
| 	int    require_set_attr; | ||||
| 	int    speed_was_set; | ||||
| @@ -487,7 +490,7 @@ extern int main(int argc, char **argv) | ||||
| 	int    noargs = 1; | ||||
| 	char * file_name = NULL; | ||||
| 	int    fd; | ||||
| 	const char *device_name; | ||||
|  | ||||
|  | ||||
| 	output_func = display_changed; | ||||
| 	verbose_output = 0; | ||||
| @@ -543,13 +546,10 @@ extern int main(int argc, char **argv) | ||||
| 		int fdflags; | ||||
|  | ||||
| 		device_name = file_name; | ||||
| 		fd = open(device_name, O_RDONLY | O_NONBLOCK); | ||||
| 		if (fd < 0) | ||||
| 			bb_perror_msg_and_die("%s", device_name); | ||||
| 		fd = bb_xopen(device_name, O_RDONLY | O_NONBLOCK); | ||||
| 		if ((fdflags = fcntl(fd, F_GETFL)) == -1 | ||||
| 			|| fcntl(fd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) | ||||
| 			bb_perror_msg_and_die("%s: couldn't reset non-blocking mode", | ||||
| 							   device_name); | ||||
| 			perror_on_device("%s: couldn't reset non-blocking mode"); | ||||
| 	} else { | ||||
| 		fd = 0; | ||||
| 		device_name = bb_msg_standard_input; | ||||
| @@ -559,12 +559,12 @@ extern int main(int argc, char **argv) | ||||
| 	   spurious difference in an uninitialized portion of the structure.  */ | ||||
| 	memset(&mode, 0, sizeof(mode)); | ||||
| 	if (tcgetattr(fd, &mode)) | ||||
| 		bb_perror_msg_and_die("%s", device_name); | ||||
| 		perror_on_device("%s"); | ||||
|  | ||||
| 	if (verbose_output | recoverable_output | noargs) { | ||||
| 		max_col = screen_columns(); | ||||
| 		current_col = 0; | ||||
| 		output_func(&mode, fd, device_name); | ||||
| 		output_func(&mode, fd); | ||||
| 		return EXIT_SUCCESS; | ||||
| 	} | ||||
|  | ||||
| @@ -644,18 +644,18 @@ extern int main(int argc, char **argv) | ||||
| 				    bb_error_msg_and_die("missing argument to `%s'", argv[k]); | ||||
| 				++k; | ||||
| 				set_window_size((int) bb_xparse_number(argv[k], stty_suffixes), | ||||
| 								-1, fd, device_name); | ||||
| 								-1, fd); | ||||
| 			} else if (STREQ(argv[k], "cols") || STREQ(argv[k], "columns")) { | ||||
| 				if (k == argc - 1) | ||||
| 				    bb_error_msg_and_die("missing argument to `%s'", argv[k]); | ||||
| 				++k; | ||||
| 				set_window_size(-1, | ||||
| 						(int) bb_xparse_number(argv[k], stty_suffixes), | ||||
| 						fd, device_name); | ||||
| 						fd); | ||||
| 			} else if (STREQ(argv[k], "size")) { | ||||
| 				max_col = screen_columns(); | ||||
| 				current_col = 0; | ||||
| 				display_window_size(0, fd, device_name); | ||||
| 				display_window_size(0, fd); | ||||
| 			} | ||||
| #endif | ||||
| #ifdef HAVE_C_LINE | ||||
| @@ -685,7 +685,7 @@ extern int main(int argc, char **argv) | ||||
| 		struct termios new_mode; | ||||
|  | ||||
| 		if (tcsetattr(fd, TCSADRAIN, &mode)) | ||||
| 			bb_perror_msg_and_die("%s", device_name); | ||||
| 			perror_on_device("%s"); | ||||
|  | ||||
| 		/* POSIX (according to Zlotnick's book) tcsetattr returns zero if | ||||
| 		   it performs *any* of the requested operations.  This means it | ||||
| @@ -698,7 +698,7 @@ extern int main(int argc, char **argv) | ||||
| 		   spurious difference in an uninitialized portion of the structure.  */ | ||||
| 		memset(&new_mode, 0, sizeof(new_mode)); | ||||
| 		if (tcgetattr(fd, &new_mode)) | ||||
| 			bb_perror_msg_and_die("%s", device_name); | ||||
| 			perror_on_device("%s"); | ||||
|  | ||||
| 		/* Normally, one shouldn't use memcmp to compare structures that | ||||
| 		   may have `holes' containing uninitialized data, but we have been | ||||
| @@ -721,8 +721,7 @@ extern int main(int argc, char **argv) | ||||
| 			new_mode.c_cflag &= (~CIBAUD); | ||||
| 			if (speed_was_set || memcmp(&mode, &new_mode, sizeof(mode)) != 0) | ||||
| #endif | ||||
| 				bb_error_msg_and_die ("%s: unable to perform all requested operations", | ||||
| 					 device_name); | ||||
| 				perror_on_device ("%s: unable to perform all requested operations"); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -948,13 +947,13 @@ static int get_win_size(int fd, struct winsize *win) | ||||
| } | ||||
|  | ||||
| static void | ||||
| set_window_size(int rows, int cols, int fd, const char *device_name) | ||||
| set_window_size(int rows, int cols, int fd) | ||||
| { | ||||
| 	struct winsize win; | ||||
|  | ||||
| 	if (get_win_size(fd, &win)) { | ||||
| 		if (errno != EINVAL) | ||||
| 			bb_perror_msg_and_die("%s", device_name); | ||||
| 			perror_on_device("%s"); | ||||
| 		memset(&win, 0, sizeof(win)); | ||||
| 	} | ||||
|  | ||||
| @@ -980,23 +979,23 @@ set_window_size(int rows, int cols, int fd, const char *device_name) | ||||
|  | ||||
| 		if ((ioctl(fd, TIOCSWINSZ, (char *) &win) != 0) | ||||
| 			|| (ioctl(fd, TIOCSSIZE, (char *) &ttysz) != 0)) { | ||||
| 			bb_perror_msg_and_die("%s", device_name); | ||||
| 			perror_on_device("%s"); | ||||
| 		return; | ||||
| 	} | ||||
| # endif | ||||
|  | ||||
| 	if (ioctl(fd, TIOCSWINSZ, (char *) &win)) | ||||
| 		bb_perror_msg_and_die("%s", device_name); | ||||
| 		perror_on_device("%s"); | ||||
| } | ||||
|  | ||||
| static void display_window_size(int fancy, int fd, const char *device_name) | ||||
| static void display_window_size(int fancy, int fd) | ||||
| { | ||||
| 	const char *fmt_str = "%s" "\0" "%s: no size information for this device"; | ||||
| 	struct winsize win; | ||||
|  | ||||
| 	if (get_win_size(fd, &win)) { | ||||
| 		if ((errno != EINVAL) || ((fmt_str += 2), !fancy)) { | ||||
| 			bb_perror_msg_and_die(fmt_str, device_name); | ||||
| 			perror_on_device(fmt_str); | ||||
| 		} | ||||
| 	} else { | ||||
| 		wrapf(fancy ? "rows %d; columns %d;" : "%d %d\n", | ||||
| @@ -1047,7 +1046,7 @@ static tcflag_t *mode_type_flag(enum mode_type type, struct termios *mode) | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| static void display_changed(struct termios *mode, int fd, const char *device_name) | ||||
| static void display_changed(struct termios *mode, int fd) | ||||
| { | ||||
| 	int i; | ||||
| 	int empty_line; | ||||
| @@ -1122,7 +1121,7 @@ static void display_changed(struct termios *mode, int fd, const char *device_nam | ||||
| } | ||||
|  | ||||
| static void | ||||
| display_all(struct termios *mode, int fd, const char *device_name) | ||||
| display_all(struct termios *mode, int fd) | ||||
| { | ||||
| 	int i; | ||||
| 	tcflag_t *bitsp; | ||||
| @@ -1131,7 +1130,7 @@ display_all(struct termios *mode, int fd, const char *device_name) | ||||
|  | ||||
| 	display_speed(mode, 1); | ||||
| #ifdef TIOCGWINSZ | ||||
| 	display_window_size(1, fd, device_name); | ||||
| 	display_window_size(1, fd); | ||||
| #endif | ||||
| #ifdef HAVE_C_LINE | ||||
| 	wrapf("line = %d;", mode->c_line); | ||||
| @@ -1202,7 +1201,7 @@ static void display_speed(struct termios *mode, int fancy) | ||||
| 		current_col = 0; | ||||
| } | ||||
|  | ||||
| static void display_recoverable(struct termios *mode, int fd, const char *device_name) | ||||
| static void display_recoverable(struct termios *mode, int fd) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
|   | ||||
| @@ -452,10 +452,8 @@ static int getn(const char *s) | ||||
| 	if (errno != 0) | ||||
| 		bb_error_msg_and_die("%s: out of range", s); | ||||
|  | ||||
| 	while (isspace(*p)) | ||||
| 		p++; | ||||
|  | ||||
| 	if (*p) | ||||
| 	/*   p = bb_skip_whitespace(p); avoid const warning */ | ||||
| 	if (*(bb_skip_whitespace(p))) | ||||
| 		bb_error_msg_and_die("%s: bad number", s); | ||||
|  | ||||
| 	return (int) r; | ||||
|   | ||||
							
								
								
									
										365
									
								
								findutils/grep.c
									
									
									
									
									
								
							
							
						
						
									
										365
									
								
								findutils/grep.c
									
									
									
									
									
								
							| @@ -19,42 +19,71 @@ | ||||
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||
|  * | ||||
|  */ | ||||
| /* | ||||
|  * Jun 2003 by Vladimir Oleynik <dzo@simtreas.ru> - | ||||
|  * correction "-e pattern1 -e -e pattern2" logic and more optimizations. | ||||
| */ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <getopt.h> | ||||
| #include <regex.h> | ||||
| #include <string.h> /* for strerror() */ | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
| #include "busybox.h" | ||||
|  | ||||
|  | ||||
| extern int optind; /* in unistd.h */ | ||||
| extern void xregcomp(regex_t *preg, const char *regex, int cflags); /* in busybox.h */ | ||||
|  | ||||
| /* options */ | ||||
| static int reflags            = REG_NOSUB;  | ||||
| static int print_filename     = 0; | ||||
| static int print_line_num     = 0; | ||||
| static int print_match_counts = 0; | ||||
| static int be_quiet           = 0; | ||||
| static int invert_search      = 0; | ||||
| static int suppress_err_msgs  = 0; | ||||
| static int print_files_with_matches  = 0; | ||||
| static int fgrep_flag		 = 0; | ||||
| #define GREP_OPTS "lnqvscFiHhe:f:" | ||||
| #define GREP_OPT_l 1 | ||||
| static char print_files_with_matches; | ||||
| #define GREP_OPT_n 2 | ||||
| static char print_line_num; | ||||
| #define GREP_OPT_q 4 | ||||
| static char be_quiet; | ||||
| #define GREP_OPT_v 8 | ||||
| typedef char invert_search_t; | ||||
| static invert_search_t invert_search; | ||||
| #define GREP_OPT_s 16 | ||||
| static char suppress_err_msgs; | ||||
| #define GREP_OPT_c 32 | ||||
| static char print_match_counts; | ||||
| #define GREP_OPT_F 64 | ||||
| static char fgrep_flag; | ||||
| #define GREP_OPT_i 128 | ||||
| #define GREP_OPT_H 256 | ||||
| #define GREP_OPT_h 512 | ||||
| #define GREP_OPT_e 1024 | ||||
| #define GREP_OPT_f 2048 | ||||
| #ifdef CONFIG_FEATURE_GREP_CONTEXT | ||||
| #define GREP_OPT_CONTEXT "A:B:C" | ||||
| #define GREP_OPT_A 4096 | ||||
| #define GREP_OPT_B 8192 | ||||
| #define GREP_OPT_C 16384 | ||||
| #define GREP_OPT_E 32768U | ||||
| #else | ||||
| #define GREP_OPT_CONTEXT "" | ||||
| #define GREP_OPT_E 4096 | ||||
| #endif | ||||
| #ifdef CONFIG_FEATURE_GREP_EGREP_ALIAS | ||||
| # define OPT_EGREP "E" | ||||
| #else | ||||
| # define OPT_EGREP "" | ||||
| #endif | ||||
|  | ||||
| static int reflags; | ||||
| static int print_filename; | ||||
|  | ||||
| #ifdef CONFIG_FEATURE_GREP_CONTEXT | ||||
| extern char *optarg; /* in getopt.h */ | ||||
| static int lines_before      = 0; | ||||
| static int lines_after       = 0; | ||||
| static char **before_buf     = NULL; | ||||
| static int last_line_printed = 0; | ||||
| static int lines_before; | ||||
| static int lines_after; | ||||
| static char **before_buf; | ||||
| static int last_line_printed; | ||||
| #endif /* CONFIG_FEATURE_GREP_CONTEXT */ | ||||
|  | ||||
| /* globals used internally */ | ||||
| static llist_t *pattern_head = NULL; /* growable list of patterns to match */ | ||||
| static int matched; /* keeps track of whether we ever matched */ | ||||
| static char *cur_file = NULL; /* the current file we are reading */ | ||||
| static llist_t *pattern_head;   /* growable list of patterns to match */ | ||||
| static char *cur_file;          /* the current file we are reading */ | ||||
|  | ||||
|  | ||||
| static void print_line(const char *line, int linenum, char decoration) | ||||
| @@ -74,11 +103,13 @@ static void print_line(const char *line, int linenum, char decoration) | ||||
| 	puts(line); | ||||
| } | ||||
|  | ||||
| extern void xregcomp(regex_t *preg, const char *regex, int cflags); | ||||
|  | ||||
| static void grep_file(FILE *file) | ||||
|  | ||||
| static int grep_file(FILE *file) | ||||
| { | ||||
| 	char *line = NULL; | ||||
| 	int ret; | ||||
| 	char *line; | ||||
| 	invert_search_t ret; | ||||
| 	int linenum = 0; | ||||
| 	int nmatches = 0; | ||||
| #ifdef CONFIG_FEATURE_GREP_CONTEXT | ||||
| @@ -91,15 +122,10 @@ static void grep_file(FILE *file) | ||||
| 		llist_t *pattern_ptr = pattern_head; | ||||
|  | ||||
| 		linenum++; | ||||
|  | ||||
| 		ret = 0; | ||||
| 		while (pattern_ptr) { | ||||
| 			if (fgrep_flag) { | ||||
| 				if (strstr(line, pattern_ptr->data)) { | ||||
| 					/* Match found */ | ||||
| 					ret = 0; | ||||
| 				} else { | ||||
| 					ret = 1; | ||||
| 				} | ||||
| 				ret = strstr(line, pattern_ptr->data) != NULL; | ||||
| 			} else { | ||||
| 				/* | ||||
| 				 * test for a postitive-assertion match (regexec returns success (0) | ||||
| @@ -109,15 +135,22 @@ static void grep_file(FILE *file) | ||||
| 				 */ | ||||
| 				regex_t regex; | ||||
| 				xregcomp(®ex, pattern_ptr->data, reflags); | ||||
| 				ret = regexec(®ex, line, 0, NULL, 0); | ||||
| 				ret = regexec(®ex, line, 0, NULL, 0) == 0; | ||||
| 				regfree(®ex); | ||||
| 			} | ||||
| 			if ((ret == 0 && !invert_search) || (ret == REG_NOMATCH && invert_search)) { | ||||
| 			if (!ret) | ||||
| 				break; | ||||
| 			pattern_ptr = pattern_ptr->link; | ||||
| 		} /* while (pattern_ptr) */ | ||||
|  | ||||
| 				/* if we found a match but were told to be quiet, stop here and | ||||
| 				 * return success */ | ||||
| 		if ((ret ^ invert_search)) { | ||||
|  | ||||
| 			if (print_files_with_matches || be_quiet) | ||||
| 				free(line); | ||||
|  | ||||
| 			/* if we found a match but were told to be quiet, stop here */ | ||||
| 				if (be_quiet) | ||||
| 					exit(0); | ||||
| 				return -1; | ||||
|  | ||||
| 				/* keep track of matches */ | ||||
| 				nmatches++; | ||||
| @@ -177,8 +210,6 @@ static void grep_file(FILE *file) | ||||
| 				print_n_lines_after--; | ||||
| 			} | ||||
| #endif /* CONFIG_FEATURE_GREP_CONTEXT */  | ||||
| 			pattern_ptr = pattern_ptr->link; | ||||
| 		} /* for */ | ||||
| 		free(line); | ||||
| 	} | ||||
|  | ||||
| @@ -190,9 +221,6 @@ static void grep_file(FILE *file) | ||||
| 	if (print_match_counts) { | ||||
| 		if (print_filename) | ||||
| 			printf("%s:", cur_file); | ||||
| 		if (print_files_with_matches && nmatches > 0) | ||||
| 			printf("1\n"); | ||||
| 		else | ||||
| 		    printf("%d\n", nmatches); | ||||
| 	} | ||||
|  | ||||
| @@ -201,188 +229,163 @@ static void grep_file(FILE *file) | ||||
| 		puts(cur_file); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	/* remember if we matched */ | ||||
| 	if (nmatches != 0) | ||||
| 		matched = 1; | ||||
| 	return nmatches; | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| static void add_pattern(char *restr) | ||||
| { | ||||
| //	regexes = xrealloc(regexes, sizeof(regex_t) * (++nregexes)); | ||||
| //	xregcomp(®exes[nregexes-1], restr, reflags); | ||||
| 	pattern_head = llist_add_to(pattern_head, restr); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static void	load_regexes_from_file(const char *filename) | ||||
| static void load_regexes_from_file(llist_t *fopt) | ||||
| { | ||||
| 	char *line; | ||||
| 	FILE *f = bb_xfopen(filename, "r"); | ||||
| 	FILE *f; | ||||
|  | ||||
| 	while(fopt) { | ||||
| 		llist_t *cur = fopt; | ||||
| 		char *ffile = cur->data; | ||||
|  | ||||
| 		fopt = cur->link; | ||||
| 		free(cur); | ||||
| 		f = bb_xfopen(ffile, "r"); | ||||
| 	while ((line = bb_get_chomped_line_from_file(f)) != NULL) { | ||||
| 		pattern_head = llist_add_to(pattern_head, line); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifdef CONFIG_FEATURE_CLEAN_UP | ||||
| static void destroy_regexes(void) | ||||
| { | ||||
| 	llist_t *pattern_head_ptr; | ||||
|  | ||||
| 	if (pattern_head == NULL) | ||||
| 		return; | ||||
|  | ||||
| 	/* destroy all the elments in the pattern list */ | ||||
| 	while (pattern_head) { | ||||
| 		pattern_head_ptr = pattern_head; | ||||
| 		pattern_head = pattern_head->link; | ||||
| 		free(pattern_head_ptr->data); | ||||
| 		free(pattern_head_ptr);		 | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| extern int grep_main(int argc, char **argv) | ||||
| { | ||||
| 	int opt; | ||||
| #if defined (CONFIG_FEATURE_GREP_CONTEXT) | ||||
| 	char *junk; | ||||
| #endif | ||||
|  | ||||
| #ifdef CONFIG_FEATURE_CLEAN_UP | ||||
| 	/* destroy command strings on exit */ | ||||
| 	atexit(destroy_regexes); | ||||
| #endif | ||||
|  | ||||
| #ifdef CONFIG_FEATURE_GREP_EGREP_ALIAS | ||||
| 	if (strcmp(bb_get_last_path_component(argv[0]), "egrep") == 0) | ||||
| 		reflags |= REG_EXTENDED; | ||||
| #endif | ||||
| 	FILE *file; | ||||
| 	int matched; | ||||
| 	unsigned long opt; | ||||
| 	llist_t *fopt; | ||||
|  | ||||
| 	/* do normal option parsing */ | ||||
| 	while ((opt = getopt(argc, argv, "iHhlnqvsce:f:F" | ||||
| #ifdef CONFIG_FEATURE_GREP_CONTEXT | ||||
| "A:B:C:" | ||||
| #endif | ||||
| #ifdef CONFIG_FEATURE_GREP_EGREP_ALIAS | ||||
| "E" | ||||
| #endif | ||||
| )) > 0) { | ||||
| 		switch (opt) { | ||||
| 			case 'i': | ||||
| 				reflags |= REG_ICASE; | ||||
| 				break; | ||||
| 			case 'l': | ||||
| 				print_files_with_matches++; | ||||
| 				break; | ||||
| 			case 'H': | ||||
| 				print_filename++; | ||||
| 				break; | ||||
| 			case 'h': | ||||
| 				print_filename--; | ||||
| 				break; | ||||
| 			case 'n': | ||||
| 				print_line_num++; | ||||
| 				break; | ||||
| 			case 'q': | ||||
| 				be_quiet++; | ||||
| 				break; | ||||
| 			case 'v': | ||||
| 				invert_search++; | ||||
| 				break; | ||||
| 			case 's': | ||||
| 				suppress_err_msgs++; | ||||
| 				break; | ||||
| 			case 'c': | ||||
| 				print_match_counts++; | ||||
| 				break; | ||||
| 			case 'e': | ||||
| 				pattern_head = llist_add_to(pattern_head, strdup(optarg)); | ||||
| 				break; | ||||
| #ifdef CONFIG_FEATURE_GREP_EGREP_ALIAS | ||||
| 			case 'E': | ||||
| 				reflags |= REG_EXTENDED; | ||||
| 				break; | ||||
| #endif | ||||
| 			case 'F': | ||||
| 				fgrep_flag = 1; | ||||
| 				break; | ||||
| 			case 'f': | ||||
| 				load_regexes_from_file(optarg); | ||||
| 				break; | ||||
| #ifdef CONFIG_FEATURE_GREP_CONTEXT | ||||
| 			case 'A': | ||||
| 				lines_after = strtoul(optarg, &junk, 10); | ||||
| 				if(*junk != '\0') | ||||
| 					bb_error_msg_and_die("invalid context length argument"); | ||||
| 				break; | ||||
| 			case 'B': | ||||
| 				lines_before = strtoul(optarg, &junk, 10); | ||||
| 				if(*junk != '\0') | ||||
| 					bb_error_msg_and_die("invalid context length argument"); | ||||
| 				before_buf = (char **)xcalloc(lines_before, sizeof(char *)); | ||||
| 				break; | ||||
| 			case 'C': | ||||
| 				lines_after = lines_before = strtoul(optarg, &junk, 10); | ||||
| 				if(*junk != '\0') | ||||
| 					bb_error_msg_and_die("invalid context length argument"); | ||||
| 				before_buf = (char **)xcalloc(lines_before, sizeof(char *)); | ||||
| 				break; | ||||
| #endif /* CONFIG_FEATURE_GREP_CONTEXT */ | ||||
| 			default: | ||||
| 				bb_show_usage(); | ||||
| 		} | ||||
|   { | ||||
| 	char *junk; | ||||
| 	char *slines_after; | ||||
| 	char *slines_before; | ||||
| 	char *Copt; | ||||
|  | ||||
| 	bb_opt_complementaly = "H-h:e*:f*:C-AB"; | ||||
| 	opt = bb_getopt_ulflags(argc, argv, | ||||
| 		GREP_OPTS GREP_OPT_CONTEXT OPT_EGREP, | ||||
| 		&pattern_head, &fopt, | ||||
| 		&slines_after, &slines_before, &Copt); | ||||
|  | ||||
| 	if(opt & GREP_OPT_C) { | ||||
| 		/* C option unseted A and B options, but next -A or -B | ||||
| 		   may be ovewrite own option */ | ||||
| 		if(!(opt & GREP_OPT_A))         /* not overwtited */ | ||||
| 			slines_after = Copt; | ||||
| 		if(!(opt & GREP_OPT_B))         /* not overwtited */ | ||||
| 			slines_before = Copt; | ||||
| 		opt |= GREP_OPT_A|GREP_OPT_B;   /* set for parse now */ | ||||
| 	} | ||||
| 	if(opt & GREP_OPT_A) { | ||||
| 		lines_after = strtoul(slines_after, &junk, 10); | ||||
| 				if(*junk != '\0') | ||||
| 					bb_error_msg_and_die("invalid context length argument"); | ||||
| 	} | ||||
| 	if(opt & GREP_OPT_B) { | ||||
| 		lines_before = strtoul(slines_before, &junk, 10); | ||||
| 				if(*junk != '\0') | ||||
| 					bb_error_msg_and_die("invalid context length argument"); | ||||
| 		} | ||||
| 	/* sanity checks after parse may be invalid numbers ;-) */ | ||||
| 	if ((opt & (GREP_OPT_c|GREP_OPT_q|GREP_OPT_l))) { | ||||
| 		opt &= ~GREP_OPT_n; | ||||
| 		lines_before = 0; | ||||
| 		lines_after = 0; | ||||
| 	} else if(lines_before > 0) | ||||
| 		before_buf = (char **)xcalloc(lines_before, sizeof(char *)); | ||||
| 	} | ||||
| #else | ||||
| 	/* with auto sanity checks */ | ||||
| 	bb_opt_complementaly = "H-h:e*:f*:c-n:q-n:l-n"; | ||||
| 	opt = bb_getopt_ulflags(argc, argv, GREP_OPTS OPT_EGREP, | ||||
| 		&pattern_head, &fopt); | ||||
|  | ||||
| #endif | ||||
| 	print_files_with_matches = opt & GREP_OPT_l; | ||||
| 	print_line_num = opt & GREP_OPT_n; | ||||
| 	be_quiet = opt & GREP_OPT_q; | ||||
| 	invert_search = (opt & GREP_OPT_v) != 0;        /* 0 | 1 */ | ||||
| 	suppress_err_msgs = opt & GREP_OPT_s; | ||||
| 	print_match_counts = opt & GREP_OPT_c; | ||||
| 	fgrep_flag = opt & GREP_OPT_F; | ||||
| 	if(opt & GREP_OPT_H) | ||||
| 		print_filename++; | ||||
| 	if(opt & GREP_OPT_h) | ||||
| 		print_filename--; | ||||
| 	if(opt & GREP_OPT_f) | ||||
| 		load_regexes_from_file(fopt); | ||||
|  | ||||
| #ifdef CONFIG_FEATURE_GREP_EGREP_ALIAS | ||||
| 	if(bb_applet_name[0] == 'e' || (opt & GREP_OPT_E)) | ||||
| 		reflags = REG_EXTENDED | REG_NOSUB; | ||||
| 	else | ||||
| #endif | ||||
| 		reflags = REG_NOSUB; | ||||
|  | ||||
| 	if(opt & GREP_OPT_i) | ||||
| 		reflags |= REG_ICASE; | ||||
|  | ||||
| 	argv += optind; | ||||
| 	argc -= optind; | ||||
|  | ||||
| 	/* if we didn't get a pattern from a -e and no command file was specified, | ||||
| 	 * argv[optind] should be the pattern. no pattern, no worky */ | ||||
| 	if (pattern_head == NULL) { | ||||
| 		if (argv[optind] == NULL) | ||||
| 		if (*argv == NULL) | ||||
| 			bb_show_usage(); | ||||
| 		else { | ||||
| 			pattern_head = llist_add_to(pattern_head, strdup(argv[optind])); | ||||
| 			optind++; | ||||
| 			pattern_head = llist_add_to(pattern_head, *argv++); | ||||
| 			argc--; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* sanity checks */ | ||||
| 	if (print_match_counts || be_quiet || print_files_with_matches) { | ||||
| 		print_line_num = 0; | ||||
| #ifdef CONFIG_FEATURE_GREP_CONTEXT | ||||
| 		lines_before = 0; | ||||
| 		lines_after = 0; | ||||
| #endif | ||||
| 	} | ||||
|  | ||||
| 	/* argv[(optind)..(argc-1)] should be names of file to grep through. If | ||||
| 	 * there is more than one file to grep, we will print the filenames */ | ||||
| 	if ((argc-1) - (optind) > 0) | ||||
| 	if (argc > 1) { | ||||
| 		print_filename++; | ||||
|  | ||||
| 	/* If no files were specified, or '-' was specified, take input from | ||||
| 	 * stdin. Otherwise, we grep through all the files specified. */ | ||||
| 	if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) { | ||||
| 		grep_file(stdin); | ||||
| 	} else if (argc == 0) { | ||||
| 		argc++; | ||||
| 	} | ||||
| 	else { | ||||
| 		int i; | ||||
| 		FILE *file; | ||||
| 		for (i = optind; i < argc; i++) { | ||||
| 			cur_file = argv[i]; | ||||
| 	matched = 0; | ||||
| 	while (argc--) { | ||||
| 		cur_file = *argv++; | ||||
| 		if(!cur_file || (*cur_file == '-' && !cur_file[1])) { | ||||
| 			cur_file = "-"; | ||||
| 			file = stdin; | ||||
| 		} else { | ||||
| 			file = fopen(cur_file, "r"); | ||||
| 		} | ||||
| 			if (file == NULL) { | ||||
| 				if (!suppress_err_msgs) | ||||
| 					bb_perror_msg("%s", cur_file); | ||||
| 		} else { | ||||
| 			matched += grep_file(file); | ||||
| 			if(matched < 0) { | ||||
| 				/* we found a match but were told to be quiet, stop here and | ||||
| 				* return success */ | ||||
| 				break; | ||||
| 			} | ||||
| 			else { | ||||
| 				grep_file(file); | ||||
| 				fclose(file); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| #ifdef CONFIG_FEATURE_CLEAN_UP | ||||
| 	/* destroy all the elments in the pattern list */ | ||||
| 	while (pattern_head) { | ||||
| 		llist_t *pattern_head_ptr = pattern_head; | ||||
|  | ||||
| 		pattern_head = pattern_head->link; | ||||
| 		free(pattern_head_ptr); | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	return !matched; /* invert return value 0 = success, 1 = failed */ | ||||
| } | ||||
|   | ||||
| @@ -66,24 +66,13 @@ int xargs_main(int argc, char **argv) | ||||
| 	char *file_to_act_on; | ||||
| 	char **args; | ||||
| 	int  i, a; | ||||
| 	char flg_vi       = 0;    /* verbose |& interactive */ | ||||
| 	char flg_no_empty = 0; | ||||
| 	char flg_vi;            /* verbose |& interactive */ | ||||
| 	char flg_no_empty; | ||||
|  | ||||
| 	while ((a = getopt(argc, argv, "prt")) > 0) { | ||||
| 		switch(a) { | ||||
| 			case 'p': | ||||
| 				flg_vi |= 3; | ||||
| 				break; | ||||
| 			case 't': | ||||
| 				flg_vi |= 1; | ||||
| 				break; | ||||
| 			case 'r': | ||||
| 				flg_no_empty = 1; | ||||
| 				break; | ||||
| 			default: | ||||
| 				bb_show_usage(); | ||||
| 		} | ||||
| 	} | ||||
| 	bb_opt_complementaly = "pt"; | ||||
| 	a = bb_getopt_ulflags(argc, argv, "tpr"); | ||||
| 	flg_vi = a & 3; | ||||
| 	flg_no_empty = a & 4; | ||||
|  | ||||
| 	a = argc - optind; | ||||
| 	argv += optind; | ||||
| @@ -110,7 +99,7 @@ int xargs_main(int argc, char **argv) | ||||
| 						fputc(' ', stderr); | ||||
| 					fputs(args[i], stderr); | ||||
| 				} | ||||
| 				fprintf(stderr, "%s", ((flg_vi & 2) ? " ?..." : "\n")); | ||||
| 				fputs(((flg_vi & 2) ? " ?..." : "\n"), stderr); | ||||
| 			} | ||||
| 			if((flg_vi & 2) == 0 || bb_ask_confirmation() != 0 ) { | ||||
| 				xargs_exec(args); | ||||
|   | ||||
| @@ -158,6 +158,9 @@ extern FILE *bb_xfopen(const char *path, const char *mode); | ||||
| //#warning rename? | ||||
| extern int   bb_fclose_nonstdin(FILE *f); | ||||
| extern void  bb_fflush_stdout_and_exit(int retval) __attribute__ ((noreturn)); | ||||
|  | ||||
| extern const char *bb_opt_complementaly; | ||||
| extern const struct option *bb_applet_long_options; | ||||
| extern unsigned long bb_getopt_ulflags(int argc, char **argv, const char *applet_opts); | ||||
| //#warning rename? | ||||
| extern FILE *bb_wfopen_input(const char *filename); | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| /* vi: set sw=4 ts=4: */ | ||||
| /* | ||||
|  * getopt_ulflags implementation for busybox | ||||
|  * universal getopt_ulflags implementation for busybox | ||||
|  * | ||||
|  * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org> | ||||
|  * Copyright (C) 2003  Vladimir Oleynik  <dzo@simtreas.ru> | ||||
|  * | ||||
|  * 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 | ||||
| @@ -22,20 +22,149 @@ | ||||
|  | ||||
| #include <getopt.h> | ||||
| #include <string.h> | ||||
| #include <assert.h> | ||||
| #include <stdlib.h> | ||||
| #include "libbb.h" | ||||
|  | ||||
| unsigned long bb_getopt_ulflags(int argc, char **argv, const char *applet_opts) | ||||
| /* | ||||
| You can set bb_opt_complementaly as string with one or more | ||||
| complementaly or incongruously options. | ||||
| If sequential founded option haved from this string | ||||
| then your incongruously pairs unsets and complementaly make add sets. | ||||
| Format: | ||||
| one char - option for check, | ||||
| chars - complementaly option for add sets. | ||||
| - chars - option triggered for unsets. | ||||
| ~ chars - option incongruously. | ||||
| *       - option list, called add_to_list(*ptr_from_usaged, optarg) | ||||
| :       - separator. | ||||
| Example: du applet can have options "-s" and "-d size" | ||||
| If getopt found -s then -d option flag unset or if found -d then -s unset. | ||||
| For this result you must set bb_opt_complementaly = "s-d:d-s". | ||||
| Result have last option flag only from called arguments. | ||||
| Warning! You can check returned flag, pointer to "d:" argument seted | ||||
| to own optarg always. | ||||
| Example two: cut applet must only one type of list may be specified, | ||||
| and -b, -c and -f incongruously option, overwited option is error also. | ||||
| You must set bb_opt_complementaly = "b~bcf:c~bcf:f~bcf". | ||||
| If called have more one specified, return value have error flag - | ||||
| high bite set (0x80000000UL). | ||||
| Example three: grep applet can have one or more "-e pattern" arguments. | ||||
| You should use bb_getopt_ulflags() as | ||||
| llist_t *paterns; | ||||
| bb_opt_complementaly = "e*"; | ||||
| bb_getopt_ulflags (argc, argv, "e:", &paterns); | ||||
| */ | ||||
|  | ||||
| const char *bb_opt_complementaly; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
| 	char opt; | ||||
| 	char list_flg; | ||||
| 	unsigned long switch_on; | ||||
| 	unsigned long switch_off; | ||||
| 	unsigned long incongruously; | ||||
| 	void **optarg;              /* char **optarg or llist_t **optarg */ | ||||
| } t_complementaly; | ||||
|  | ||||
| /* You can set bb_applet_long_options for parse called long options */ | ||||
|  | ||||
| static const struct option bb_default_long_options[] = { | ||||
|      /*   { "help", 0, NULL, '?' }, */ | ||||
| 	{ 0, 0, 0, 0 } | ||||
| }; | ||||
|  | ||||
| const struct option *bb_applet_long_options = bb_default_long_options; | ||||
|  | ||||
|  | ||||
| unsigned long | ||||
| bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) | ||||
| { | ||||
| 	unsigned long flags = 0; | ||||
|   int c = 0; | ||||
| 	const char *s; | ||||
| 	int c; | ||||
|   t_complementaly *complementaly; | ||||
|   t_complementaly *on_off; | ||||
|   va_list p; | ||||
|  | ||||
| 	while ((c = getopt(argc, argv, applet_opts)) > 0) { | ||||
| 		if (!(s = strchr(applet_opts, c))) { | ||||
| 			bb_show_usage(); | ||||
| 		} | ||||
| 		flags |= (1 << (s-applet_opts)); | ||||
|   va_start (p, applet_opts); | ||||
|  | ||||
|   for (s = applet_opts; *s; s++) { | ||||
| 	c++; | ||||
| 	while (s[1] == ':') { | ||||
| 	    /* check GNU extension "o::" - optional arg */ | ||||
| 	    s++; | ||||
| 	} | ||||
|   } | ||||
|   complementaly = xcalloc (c + 1, sizeof (t_complementaly)); | ||||
|   c = 0; | ||||
|   for (s = applet_opts; *s; s++) { | ||||
| 	complementaly->opt = *s; | ||||
| 	complementaly->switch_on |= (1 << c); | ||||
| 	c++; | ||||
| 	if (s[1] == ':') { | ||||
| 	  complementaly->optarg = va_arg (p, void **); | ||||
| 	  do | ||||
| 		s++; | ||||
| 	  while (s[1] == ':'); | ||||
| 		} | ||||
| 	complementaly++; | ||||
| 	} | ||||
|   complementaly->opt = 0; | ||||
|   complementaly -= c; | ||||
|   c = 0; | ||||
|   for (s = bb_opt_complementaly; s && *s; s++) { | ||||
|     t_complementaly *pair; | ||||
|  | ||||
|     if (*s == ':') { | ||||
| 	  c = 0; | ||||
| 	  continue; | ||||
|     } | ||||
|     if (c) | ||||
| 	  continue; | ||||
|     for (on_off = complementaly; on_off->opt; on_off++) | ||||
| 	  if (on_off->opt == *s) | ||||
| 	    break; | ||||
|     pair = on_off; | ||||
|     for(s++; *s && *s != ':'; s++) { | ||||
|       if (*s == '-' || *s == '~') { | ||||
| 	  c = *s; | ||||
|       } else if(*s == '*') { | ||||
| 	pair->list_flg++; | ||||
|       } else { | ||||
| 	  unsigned long *pair_switch = &(pair->switch_on); | ||||
|  | ||||
| 	  if(c) | ||||
| 	    pair_switch = c == '-' ? &(pair->switch_off) : &(pair->incongruously); | ||||
| 	  for (on_off = complementaly; on_off->opt; on_off++) | ||||
| 	    if (on_off->opt == *s) { | ||||
| 		  *pair_switch |= on_off->switch_on; | ||||
| 		  break; | ||||
| 	    } | ||||
|       } | ||||
|     } | ||||
|     s--; | ||||
|   } | ||||
|  | ||||
|   while ((c = getopt_long (argc, argv, applet_opts, | ||||
| 			    bb_applet_long_options, NULL)) > 0) { | ||||
|  | ||||
| 	for (on_off = complementaly; on_off->opt != c; on_off++) { | ||||
| 	    if(!on_off->opt) | ||||
| 		bb_show_usage (); | ||||
| 	} | ||||
| 	if(flags & on_off->incongruously) | ||||
| 	    flags |= 0x80000000UL; | ||||
| 	flags &= ~on_off->switch_off; | ||||
| 	flags |= on_off->switch_on; | ||||
| 	if(on_off->list_flg) { | ||||
| 	   *(llist_t **)(on_off->optarg) = | ||||
| 		llist_add_to(*(llist_t **)(on_off->optarg), optarg); | ||||
| 	} else if (on_off->optarg) { | ||||
| 	    *(char **)(on_off->optarg) = optarg; | ||||
| 	} | ||||
|   } | ||||
|   free(complementaly); | ||||
| 	return flags; | ||||
| } | ||||
|   | ||||
| @@ -83,6 +83,7 @@ void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) | ||||
| 	ino_dev_hashtable[i] = bucket; | ||||
| } | ||||
|  | ||||
| #ifdef CONFIG_FEATURE_CLEAN_UP | ||||
| /* Clear statbuf hash table */ | ||||
| void reset_ino_dev_hashtable(void) | ||||
| { | ||||
| @@ -97,6 +98,7 @@ void reset_ino_dev_hashtable(void) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* END CODE */ | ||||
|   | ||||
| @@ -122,6 +122,17 @@ static int addgroup(const char *filename, char *group, gid_t gid, const char *us | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| #ifndef CONFIG_ADDUSER | ||||
| static inline void if_i_am_not_root(void) | ||||
| { | ||||
| 	if (geteuid()) { | ||||
| 		bb_error_msg_and_die( "Only root may add a user or group to the system."); | ||||
| 	} | ||||
| } | ||||
| #else | ||||
| extern void if_i_am_not_root(void); | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * addgroup will take a login_name as its first parameter. | ||||
|  * | ||||
| @@ -131,21 +142,13 @@ static int addgroup(const char *filename, char *group, gid_t gid, const char *us | ||||
|  * ________________________________________________________________________ */ | ||||
| int addgroup_main(int argc, char **argv) | ||||
| { | ||||
| 	int opt; | ||||
| 	char *group; | ||||
| 	char *user; | ||||
| 	gid_t gid = 0; | ||||
|  | ||||
| 	/* get remaining args */ | ||||
| 	while ((opt = getopt (argc, argv, "g:")) != -1) { | ||||
| 		switch (opt) { | ||||
| 			case 'g': | ||||
| 				gid = strtol(optarg, NULL, 10); | ||||
| 				break; | ||||
| 			default: | ||||
| 				bb_show_usage(); | ||||
| 				break; | ||||
| 		} | ||||
| 	if(bb_getopt_ulflags(argc, argv, "g:", &group)) { | ||||
| 		gid = strtol(group, NULL, 10); | ||||
| 	} | ||||
|  | ||||
| 	if (optind < argc) { | ||||
| @@ -161,14 +164,8 @@ int addgroup_main(int argc, char **argv) | ||||
| 	} else { | ||||
| 		user = ""; | ||||
| 	} | ||||
| 	 | ||||
| 	if (geteuid() != 0) { | ||||
| 		bb_error_msg_and_die | ||||
| 			("Only root may add a group to the system."); | ||||
| 	} | ||||
| 	if_i_am_not_root(); | ||||
|  | ||||
| 	/* werk */ | ||||
| 	return addgroup(bb_path_group_file, group, gid, user); | ||||
| } | ||||
|  | ||||
| /* $Id: addgroup.c,v 1.10 2003/03/19 09:12:20 mjn3 Exp $ */ | ||||
|   | ||||
| @@ -208,9 +208,15 @@ static int adduser(const char *filename, struct passwd *p) | ||||
|  | ||||
|  | ||||
| /* return current uid (root is always uid == 0, right?) */ | ||||
| static inline uid_t i_am_not_root(void) | ||||
| #ifndef CONFIG_ADDGROUP | ||||
| static inline void if_i_am_not_root(void) | ||||
| #else | ||||
| void if_i_am_not_root(void) | ||||
| #endif | ||||
| { | ||||
| 	return geteuid(); | ||||
| 	if (geteuid()) { | ||||
| 		bb_error_msg_and_die( "Only root may add a user or group to the system."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -224,11 +230,10 @@ static inline uid_t i_am_not_root(void) | ||||
|  * ________________________________________________________________________ */ | ||||
| int adduser_main(int argc, char **argv) | ||||
| { | ||||
| 	int opt; | ||||
| 	const char *login; | ||||
| 	const char *gecos; | ||||
| 	const char *gecos = default_gecos; | ||||
| 	const char *home = NULL; | ||||
| 	const char *shell; | ||||
| 	const char *shell = default_shell; | ||||
|  | ||||
| 	struct passwd pw; | ||||
|  | ||||
| @@ -236,30 +241,11 @@ int adduser_main(int argc, char **argv) | ||||
| 	if (argc < 2) { | ||||
| 		bb_show_usage(); | ||||
| 	} | ||||
| 	gecos = default_gecos; | ||||
| 	shell = default_shell; | ||||
|  | ||||
| 	/* get args */ | ||||
| 	while ((opt = getopt (argc, argv, "h:g:s:")) != -1) | ||||
| 		switch (opt) { | ||||
| 			case 'h': | ||||
| 				home = optarg; | ||||
| 				break; | ||||
| 			case 'g': | ||||
| 				gecos = optarg; | ||||
| 				break; | ||||
| 			case 's': | ||||
| 				shell = optarg; | ||||
| 				break; | ||||
| 			default: | ||||
| 				bb_show_usage(); | ||||
| 				break; | ||||
| 		} | ||||
| 	bb_getopt_ulflags(argc, argv, "h:g:s:", &home, &gecos, &shell); | ||||
|  | ||||
| 	/* got root? */ | ||||
| 	if (i_am_not_root()) { | ||||
| 		bb_error_msg_and_die( "Only root may add a user or group to the system."); | ||||
| 	} | ||||
| 	if_i_am_not_root(); | ||||
|  | ||||
| 	/* get login */ | ||||
| 	if (optind >= argc) { | ||||
| @@ -288,5 +274,3 @@ int adduser_main(int argc, char **argv) | ||||
| 	/* grand finale */ | ||||
| 	return adduser(bb_path_passwd_file, &pw); | ||||
| } | ||||
|  | ||||
| /* $Id: adduser.c,v 1.5 2003/03/19 09:12:20 mjn3 Exp $ */ | ||||
|   | ||||
| @@ -117,46 +117,40 @@ static CronFile *FileBase; | ||||
| int | ||||
| crond_main(int ac, char **av) | ||||
| { | ||||
|     int i; | ||||
|     unsigned long opt; | ||||
|     char *lopt, *Lopt, *copt; | ||||
| #ifdef FEATURE_DEBUG_OPT | ||||
|     char *dopt; | ||||
|     bb_opt_complementaly = "f-b:b-f:S-L:L-S:d-l"; | ||||
| #else | ||||
|     bb_opt_complementaly = "f-b:b-f:S-L:L-S"; | ||||
| #endif | ||||
|  | ||||
|     opterr = 0;         /* disable getopt 'errors' message.*/ | ||||
|  | ||||
|     while ((i = getopt(ac,av, | ||||
|     opt = bb_getopt_ulflags(ac, av, "l:L:fbSc:" | ||||
| #ifdef FEATURE_DEBUG_OPT | ||||
| 				"d:" | ||||
| #endif | ||||
| 					"l:L:fbSc:")) != EOF){ | ||||
|  | ||||
| 	switch (i){ | ||||
| 	    case 'l': | ||||
| 		LogLevel = atoi(optarg); | ||||
| 		break; | ||||
| 	    , &lopt, &Lopt, &copt | ||||
| #ifdef FEATURE_DEBUG_OPT | ||||
| 	    case 'd': | ||||
| 		DebugOpt = atoi(optarg); | ||||
| 		LogLevel = 0; | ||||
| 		break; | ||||
| 	    , &dopt | ||||
| #endif | ||||
| 	    case 'f': | ||||
| 		ForegroundOpt = 1; | ||||
| 		break; | ||||
| 	    case 'b': | ||||
| 		ForegroundOpt = 0; | ||||
| 		break; | ||||
| 	    case 'S':                   /* select logging to syslog */ | ||||
| 		LoggerOpt = 0; | ||||
| 		break; | ||||
| 	    case 'L':                   /* select internal file logger */ | ||||
| 		LoggerOpt = 1; | ||||
| 		if (*optarg != 0) LogFile = optarg; | ||||
| 		break; | ||||
| 	    case 'c': | ||||
| 		if (*optarg != 0) CDir = optarg; | ||||
| 		break; | ||||
| 	    default: /*  parse error */ | ||||
| 		bb_show_usage(); | ||||
| 	    ); | ||||
|     if(opt & 1) | ||||
| 	LogLevel = atoi(lopt); | ||||
|     LoggerOpt = opt & 2; | ||||
|     if(LoggerOpt) | ||||
| 	if (*Lopt != 0) LogFile = Lopt; | ||||
|     ForegroundOpt = opt & 4; | ||||
|     if(opt & 32) { | ||||
| 	if (*copt != 0) CDir = copt; | ||||
| 	} | ||||
| #ifdef FEATURE_DEBUG_OPT | ||||
|     if(opt & 64) { | ||||
| 	DebugOpt = atoi(dopt); | ||||
| 	LogLevel = 0; | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     /* | ||||
|      * change directory | ||||
| @@ -165,6 +159,9 @@ crond_main(int ac, char **av) | ||||
|     if (chdir(CDir) != 0) | ||||
| 	bb_perror_msg_and_die("chdir"); | ||||
|  | ||||
|     signal(SIGHUP,SIG_IGN);   /* hmm.. but, if kill -HUP original | ||||
| 				 * version - his died. ;( | ||||
| 				 */ | ||||
|     /* | ||||
|      * close stdin and stdout, stderr. | ||||
|      * close unused descriptors -  don't need. | ||||
| @@ -177,9 +174,6 @@ crond_main(int ac, char **av) | ||||
|     } | ||||
|  | ||||
|     (void)startlogger();                /* need if syslog mode selected */ | ||||
|     signal(SIGHUP,SIG_IGN);   /* hmm.. but, if kill -HUP original | ||||
| 				 * version - his died. ;( | ||||
| 				 */ | ||||
|  | ||||
|     /* | ||||
|      * main loop - synchronize to 1 second after the minute, minimum sleep | ||||
|   | ||||
		Reference in New Issue
	
	Block a user