find: implement ( )
This commit is contained in:
		
							
								
								
									
										265
									
								
								findutils/find.c
									
									
									
									
									
								
							
							
						
						
									
										265
									
								
								findutils/find.c
									
									
									
									
									
								
							| @@ -60,8 +60,15 @@ USE_FEATURE_FIND_MMIN(  SACT(mmin,  char mmin_char; int mmin_mins;)) | |||||||
| USE_FEATURE_FIND_NEWER( SACT(newer, time_t newer_mtime;)) | USE_FEATURE_FIND_NEWER( SACT(newer, time_t newer_mtime;)) | ||||||
| USE_FEATURE_FIND_INUM(  SACT(inum,  ino_t inode_num;)) | USE_FEATURE_FIND_INUM(  SACT(inum,  ino_t inode_num;)) | ||||||
| USE_FEATURE_FIND_EXEC(  SACT(exec,  char **exec_argv; int *subst_count; int exec_argc;)) | USE_FEATURE_FIND_EXEC(  SACT(exec,  char **exec_argv; int *subst_count; int exec_argc;)) | ||||||
|  | USE_DESKTOP(            SACT(paren, action ***subexpr;)) | ||||||
|  |  | ||||||
| static action ***actions; | static action ***actions; | ||||||
|  | static int need_print = 1; | ||||||
|  |  | ||||||
|  | static inline int one_char(const char* str, char c) | ||||||
|  | { | ||||||
|  | 	return (str[0] == c && str[1] == '\0'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| static int count_subst(const char *str) | static int count_subst(const char *str) | ||||||
| @@ -93,6 +100,28 @@ static char* subst(const char *src, int count, const char* filename) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static int exec_actions(action ***appp, const char *fileName, struct stat *statbuf) | ||||||
|  | { | ||||||
|  | 	int cur_group; | ||||||
|  | 	int cur_action; | ||||||
|  | 	int rc = TRUE; | ||||||
|  | 	action **app, *ap; | ||||||
|  |  | ||||||
|  | 	cur_group = -1; | ||||||
|  | 	while ((app = appp[++cur_group])) { | ||||||
|  | 		cur_action = -1; | ||||||
|  | 		do { | ||||||
|  | 			ap = app[++cur_action]; | ||||||
|  | 		} while (ap && (rc = ap->f(fileName, statbuf, ap))); | ||||||
|  | 		if (!ap) { | ||||||
|  | 			/* all actions in group were successful */ | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return rc; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| SFUNC(name) | SFUNC(name) | ||||||
| { | { | ||||||
| 	const char *tmp = strrchr(fileName, '/'); | 	const char *tmp = strrchr(fileName, '/'); | ||||||
| @@ -164,6 +193,7 @@ SFUNC(exec) | |||||||
| 		bb_perror_msg("%s", argv[0]); | 		bb_perror_msg("%s", argv[0]); | ||||||
| 	for (i = 0; i < ap->exec_argc; i++) | 	for (i = 0; i < ap->exec_argc; i++) | ||||||
| 		free(argv[i]); | 		free(argv[i]); | ||||||
|  | 	need_print = 0; | ||||||
| 	return rc == 0; /* return 1 if success */ | 	return rc == 0; /* return 1 if success */ | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| @@ -172,33 +202,40 @@ SFUNC(exec) | |||||||
| SFUNC(print0) | SFUNC(print0) | ||||||
| { | { | ||||||
| 	printf("%s%c", fileName, '\0'); | 	printf("%s%c", fileName, '\0'); | ||||||
|  | 	need_print = 0; | ||||||
| 	return TRUE; | 	return TRUE; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| SFUNC(print) | SFUNC(print) | ||||||
| { | { | ||||||
| 	puts(fileName); | 	puts(fileName); | ||||||
|  | 	need_print = 0; | ||||||
| 	return TRUE; | 	return TRUE; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #if ENABLE_DESKTOP | ||||||
|  | SFUNC(paren) | ||||||
|  | { | ||||||
|  | 	return exec_actions(ap->subexpr, fileName, statbuf); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| static int fileAction(const char *fileName, struct stat *statbuf, void* junk, int depth) | static int fileAction(const char *fileName, struct stat *statbuf, void* junk, int depth) | ||||||
| { | { | ||||||
| 	int cur_group; | #ifdef CONFIG_FEATURE_FIND_XDEV | ||||||
| 	int cur_action; | 	if (S_ISDIR(statbuf->st_mode) && xdev_count) { | ||||||
| 	action **app, *ap; | 		int i; | ||||||
|  | 		for (i = 0; i < xdev_count; i++) { | ||||||
| 	cur_group = -1; | 			if (xdev_dev[i] != statbuf->st_dev) | ||||||
| 	while ((app = actions[++cur_group])) { | 				return SKIP; | ||||||
| 		cur_action = -1; |  | ||||||
| 		do { |  | ||||||
| 			ap = app[++cur_action]; |  | ||||||
| 		} while (ap && ap->f(fileName, statbuf, ap)); |  | ||||||
| 		if (!ap) { |  | ||||||
| 			/* all actions in group were successful */ |  | ||||||
| 			break; |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | #endif | ||||||
|  | 	/* had no explicit -print[0] or -exec? then print */ | ||||||
|  | 	if (exec_actions(actions, fileName, statbuf) && need_print) | ||||||
|  | 		puts(fileName); | ||||||
| 	return TRUE; | 	return TRUE; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -239,41 +276,24 @@ static int find_type(char *type) | |||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | action*** parse_params(char **argv) | ||||||
| int find_main(int argc, char **argv) |  | ||||||
| { | { | ||||||
| 	int dereference = FALSE; | 	action*** appp; | ||||||
| 	int i, j, firstopt, status = EXIT_SUCCESS; | 	int cur_group = 0; | ||||||
| 	int cur_group; | 	int cur_action = 0; | ||||||
| 	int cur_action; |  | ||||||
| 	int need_default = 1; |  | ||||||
|  |  | ||||||
| 	action* alloc_action(int sizeof_struct, action_fp f) | 	action* alloc_action(int sizeof_struct, action_fp f) | ||||||
| 	{ | 	{ | ||||||
| 		action *ap; | 		action *ap; | ||||||
| 		actions[cur_group] = xrealloc(actions[cur_group], (cur_action+2) * sizeof(*actions)); | 		appp[cur_group] = xrealloc(appp[cur_group], (cur_action+2) * sizeof(*appp)); | ||||||
| 		actions[cur_group][cur_action++] = ap = xmalloc(sizeof_struct); | 		appp[cur_group][cur_action++] = ap = xmalloc(sizeof_struct); | ||||||
| 		actions[cur_group][cur_action] = NULL; | 		appp[cur_group][cur_action] = NULL; | ||||||
| 		ap->f = f; | 		ap->f = f; | ||||||
| 		return ap; | 		return ap; | ||||||
| 	} | 	} | ||||||
| #define ALLOC_ACTION(name) (action_##name*)alloc_action(sizeof(action_##name), (action_fp) func_##name) | #define ALLOC_ACTION(name) (action_##name*)alloc_action(sizeof(action_##name), (action_fp) func_##name) | ||||||
|  |  | ||||||
| 	for (firstopt = 1; firstopt < argc; firstopt++) { | 	appp = xzalloc(2 * sizeof(*appp)); /* appp[0],[1] == NULL */ | ||||||
| 		if (argv[firstopt][0] == '-') |  | ||||||
| 			break; |  | ||||||
| 	} |  | ||||||
| 	if (firstopt == 1) { |  | ||||||
| 		argv[0] = "."; |  | ||||||
| 		argv--; |  | ||||||
| 		argc++; |  | ||||||
| 		firstopt++; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| // All options always return true. They always take effect, |  | ||||||
| // rather than being processed only when their place in the |  | ||||||
| // expression is reached |  | ||||||
| // We implement: -follow, -xdev |  | ||||||
|  |  | ||||||
| // Actions have side effects and return a true or false value | // Actions have side effects and return a true or false value | ||||||
| // We implement: -print, -print0, -exec | // We implement: -print, -print0, -exec | ||||||
| @@ -287,67 +307,40 @@ int find_main(int argc, char **argv) | |||||||
| // expr1 [-a[nd]] expr2  And; expr2 is not evaluated if expr1 is false | // expr1 [-a[nd]] expr2  And; expr2 is not evaluated if expr1 is false | ||||||
| // expr1 -o[r] expr2     Or; expr2 is not evaluated if expr1 is true | // expr1 -o[r] expr2     Or; expr2 is not evaluated if expr1 is true | ||||||
| // expr1 , expr2         List; both expr1 and expr2 are always evaluated | // expr1 , expr2         List; both expr1 and expr2 are always evaluated | ||||||
| // We implement: -a, -o | // We implement: (), -a, -o | ||||||
|  |  | ||||||
| 	cur_group = 0; |  | ||||||
| 	cur_action = 0; |  | ||||||
| 	actions = xzalloc(sizeof(*actions)); /* actions[0] == NULL */ |  | ||||||
|  |  | ||||||
| 	/* Parse any options */ |  | ||||||
| 	for (i = firstopt; i < argc; i++) { |  | ||||||
| 		char *arg = argv[i]; |  | ||||||
| 		char *arg1 = argv[i+1]; |  | ||||||
|  |  | ||||||
|  | 	while (*argv) { | ||||||
|  | 		char *arg = argv[0]; | ||||||
|  | 		char *arg1 = argv[1]; | ||||||
| 	/* --- Operators --- */ | 	/* --- Operators --- */ | ||||||
| 		if (ENABLE_DESKTOP | 		if (strcmp(arg, "-a") == 0 | ||||||
| 		 && (strcmp(arg, "-a") == 0 || strcmp(arg, "-and") == 0) | 		    USE_DESKTOP(|| strcmp(arg, "-and") == 0) | ||||||
| 		) { | 		) { | ||||||
| 			/* no special handling required */ | 			/* no special handling required */ | ||||||
| 		} | 		} | ||||||
| 		else if (strcmp(arg, "-o") == 0 | 		else if (strcmp(arg, "-o") == 0 | ||||||
| 			USE_DESKTOP(|| strcmp(arg, "-or") == 0) | 		         USE_DESKTOP(|| strcmp(arg, "-or") == 0) | ||||||
| 		) { | 		) { | ||||||
| 			if (need_default) | 			/* start new OR group */ | ||||||
| 				(void) ALLOC_ACTION(print); |  | ||||||
| 			cur_group++; | 			cur_group++; | ||||||
| 			actions = xrealloc(actions, (cur_group+1) * sizeof(*actions)); | 			appp = xrealloc(appp, (cur_group+2) * sizeof(*appp)); | ||||||
| 			actions[cur_group] = NULL; | 			appp[cur_group] = NULL; | ||||||
| 			actions[cur_group+1] = NULL; | 			appp[cur_group+1] = NULL; | ||||||
| 			cur_action = 0; | 			cur_action = 0; | ||||||
| 			need_default = 1; |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	/* --- Options --- */ |  | ||||||
| 		else if (strcmp(arg, "-follow") == 0) |  | ||||||
| 			dereference = TRUE; |  | ||||||
| #if ENABLE_FEATURE_FIND_XDEV |  | ||||||
| 		else if (strcmp(arg, "-xdev") == 0) { |  | ||||||
| 			struct stat stbuf; |  | ||||||
|  |  | ||||||
| 			xdev_count = firstopt - 1; |  | ||||||
| 			xdev_dev = xmalloc(xdev_count * sizeof(dev_t)); |  | ||||||
| 			for (j = 1; j < firstopt; i++) { |  | ||||||
| 				/* not xstat(): shouldn't bomd out on |  | ||||||
| 				 * "find not_exist exist -xdev" */ |  | ||||||
| 				if (stat(argv[j], &stbuf)) stbuf.st_dev = -1L; |  | ||||||
| 				xdev_dev[j-1] = stbuf.st_dev; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| #endif |  | ||||||
| 	/* --- Tests and actions --- */ | 	/* --- Tests and actions --- */ | ||||||
| 		else if (strcmp(arg, "-print") == 0) { | 		else if (strcmp(arg, "-print") == 0) { | ||||||
| 			need_default = 0; |  | ||||||
| 			(void) ALLOC_ACTION(print); | 			(void) ALLOC_ACTION(print); | ||||||
| 		} | 		} | ||||||
| #if ENABLE_FEATURE_FIND_PRINT0 | #if ENABLE_FEATURE_FIND_PRINT0 | ||||||
| 		else if (strcmp(arg, "-print0") == 0) { | 		else if (strcmp(arg, "-print0") == 0) { | ||||||
| 			need_default = 0; |  | ||||||
| 			(void) ALLOC_ACTION(print0); | 			(void) ALLOC_ACTION(print0); | ||||||
| 		} | 		} | ||||||
| #endif | #endif | ||||||
| 		else if (strcmp(arg, "-name") == 0) { | 		else if (strcmp(arg, "-name") == 0) { | ||||||
| 			action_name *ap; | 			action_name *ap; | ||||||
| 			if (++i == argc) | 			if (!*++argv) | ||||||
| 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||||||
| 			ap = ALLOC_ACTION(name); | 			ap = ALLOC_ACTION(name); | ||||||
| 			ap->pattern = arg1; | 			ap->pattern = arg1; | ||||||
| @@ -355,7 +348,7 @@ int find_main(int argc, char **argv) | |||||||
| #if ENABLE_FEATURE_FIND_TYPE | #if ENABLE_FEATURE_FIND_TYPE | ||||||
| 		else if (strcmp(arg, "-type") == 0) { | 		else if (strcmp(arg, "-type") == 0) { | ||||||
| 			action_type *ap; | 			action_type *ap; | ||||||
| 			if (++i == argc) | 			if (!*++argv) | ||||||
| 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||||||
| 			ap = ALLOC_ACTION(type); | 			ap = ALLOC_ACTION(type); | ||||||
| 			ap->type_mask = find_type(arg1); | 			ap->type_mask = find_type(arg1); | ||||||
| @@ -370,7 +363,7 @@ int find_main(int argc, char **argv) | |||||||
|  */ |  */ | ||||||
| 		else if (strcmp(arg, "-perm") == 0) { | 		else if (strcmp(arg, "-perm") == 0) { | ||||||
| 			action_perm *ap; | 			action_perm *ap; | ||||||
| 			if (++i == argc) | 			if (!*++argv) | ||||||
| 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||||||
| 			ap = ALLOC_ACTION(perm); | 			ap = ALLOC_ACTION(perm); | ||||||
| 			ap->perm_mask = xstrtol_range(arg1, 8, 0, 07777); | 			ap->perm_mask = xstrtol_range(arg1, 8, 0, 07777); | ||||||
| @@ -382,7 +375,7 @@ int find_main(int argc, char **argv) | |||||||
| #if ENABLE_FEATURE_FIND_MTIME | #if ENABLE_FEATURE_FIND_MTIME | ||||||
| 		else if (strcmp(arg, "-mtime") == 0) { | 		else if (strcmp(arg, "-mtime") == 0) { | ||||||
| 			action_mtime *ap; | 			action_mtime *ap; | ||||||
| 			if (++i == argc) | 			if (!*++argv) | ||||||
| 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||||||
| 			ap = ALLOC_ACTION(mtime); | 			ap = ALLOC_ACTION(mtime); | ||||||
| 			ap->mtime_days = xatol(arg1); | 			ap->mtime_days = xatol(arg1); | ||||||
| @@ -394,7 +387,7 @@ int find_main(int argc, char **argv) | |||||||
| #if ENABLE_FEATURE_FIND_MMIN | #if ENABLE_FEATURE_FIND_MMIN | ||||||
| 		else if (strcmp(arg, "-mmin") == 0) { | 		else if (strcmp(arg, "-mmin") == 0) { | ||||||
| 			action_mmin *ap; | 			action_mmin *ap; | ||||||
| 			if (++i == argc) | 			if (!*++argv) | ||||||
| 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||||||
| 			ap = ALLOC_ACTION(mmin); | 			ap = ALLOC_ACTION(mmin); | ||||||
| 			ap->mmin_mins = xatol(arg1); | 			ap->mmin_mins = xatol(arg1); | ||||||
| @@ -407,7 +400,7 @@ int find_main(int argc, char **argv) | |||||||
| 		else if (strcmp(arg, "-newer") == 0) { | 		else if (strcmp(arg, "-newer") == 0) { | ||||||
| 			action_newer *ap; | 			action_newer *ap; | ||||||
| 			struct stat stat_newer; | 			struct stat stat_newer; | ||||||
| 			if (++i == argc) | 			if (!*++argv) | ||||||
| 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||||||
| 			xstat(arg1, &stat_newer); | 			xstat(arg1, &stat_newer); | ||||||
| 			ap = ALLOC_ACTION(newer); | 			ap = ALLOC_ACTION(newer); | ||||||
| @@ -417,7 +410,7 @@ int find_main(int argc, char **argv) | |||||||
| #if ENABLE_FEATURE_FIND_INUM | #if ENABLE_FEATURE_FIND_INUM | ||||||
| 		else if (strcmp(arg, "-inum") == 0) { | 		else if (strcmp(arg, "-inum") == 0) { | ||||||
| 			action_inum *ap; | 			action_inum *ap; | ||||||
| 			if (++i == argc) | 			if (!*++argv) | ||||||
| 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||||||
| 			ap = ALLOC_ACTION(inum); | 			ap = ALLOC_ACTION(inum); | ||||||
| 			ap->inode_num = xatoul(arg1); | 			ap->inode_num = xatoul(arg1); | ||||||
| @@ -425,34 +418,114 @@ int find_main(int argc, char **argv) | |||||||
| #endif | #endif | ||||||
| #if ENABLE_FEATURE_FIND_EXEC | #if ENABLE_FEATURE_FIND_EXEC | ||||||
| 		else if (strcmp(arg, "-exec") == 0) { | 		else if (strcmp(arg, "-exec") == 0) { | ||||||
|  | 			int i; | ||||||
| 			action_exec *ap; | 			action_exec *ap; | ||||||
| 			need_default = 0; |  | ||||||
| 			ap = ALLOC_ACTION(exec); | 			ap = ALLOC_ACTION(exec); | ||||||
| 			i++; /* now: argv[i] is the first arg after -exec */ | 			ap->exec_argv = ++argv; /* first arg after -exec */ | ||||||
| 			ap->exec_argv = &argv[i]; | 			ap->exec_argc = 0; | ||||||
| 			ap->exec_argc = i; |  | ||||||
| 			while (1) { | 			while (1) { | ||||||
| 				if (i == argc) /* did not see ';' till end */ | 				if (!*argv) /* did not see ';' till end */ | ||||||
| 					bb_error_msg_and_die(bb_msg_requires_arg, arg); | 					bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||||||
| 				if (argv[i][0] == ';' && argv[i][1] == '\0') | 				if (one_char(argv[0], ';')) | ||||||
| 					break; | 					break; | ||||||
| 				i++; | 				argv++; | ||||||
|  | 				ap->exec_argc++; | ||||||
| 			} | 			} | ||||||
| 			ap->exec_argc = i - ap->exec_argc; /* number of --exec arguments */ |  | ||||||
| 			if (ap->exec_argc == 0) | 			if (ap->exec_argc == 0) | ||||||
| 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | 				bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||||||
| 			ap->subst_count = xmalloc(ap->exec_argc * sizeof(int)); | 			ap->subst_count = xmalloc(ap->exec_argc * sizeof(int)); | ||||||
| 			j = ap->exec_argc; | 			i = ap->exec_argc; | ||||||
| 			while (j--) | 			while (i--) | ||||||
| 				ap->subst_count[j] = count_subst(ap->exec_argv[j]); | 				ap->subst_count[i] = count_subst(ap->exec_argv[i]); | ||||||
|  | 		} | ||||||
|  | #endif | ||||||
|  | #if ENABLE_DESKTOP | ||||||
|  | 		else if (one_char(arg, '(')) { | ||||||
|  | 			action_paren *ap; | ||||||
|  | 			char **endarg; | ||||||
|  | 			int nested = 1; | ||||||
|  |  | ||||||
|  | 			endarg = argv; | ||||||
|  | 			while (1) { | ||||||
|  | 				if (!*++endarg) | ||||||
|  | 					bb_error_msg_and_die("unpaired '('"); | ||||||
|  | 				if (one_char(*endarg, '(')) | ||||||
|  | 					nested++; | ||||||
|  | 				else if (one_char(*endarg, ')') && !--nested) { | ||||||
|  | 					*endarg = NULL; | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			ap = ALLOC_ACTION(paren); | ||||||
|  | 			ap->subexpr = parse_params(argv + 1); | ||||||
|  | 			*endarg = ")"; /* restore NULLed parameter */ | ||||||
|  | 			argv = endarg; | ||||||
| 		} | 		} | ||||||
| #endif | #endif | ||||||
| 		else | 		else | ||||||
| 			bb_show_usage(); | 			bb_show_usage(); | ||||||
|  | 		argv++; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (need_default) | 	return appp; | ||||||
| 		(void) ALLOC_ACTION(print); | #undef ALLOC_ACTION | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int find_main(int argc, char **argv) | ||||||
|  | { | ||||||
|  | 	int dereference = FALSE; | ||||||
|  | 	char **argp; | ||||||
|  | 	int i, firstopt, status = EXIT_SUCCESS; | ||||||
|  |  | ||||||
|  | 	for (firstopt = 1; firstopt < argc; firstopt++) { | ||||||
|  | 		if (argv[firstopt][0] == '-') | ||||||
|  | 			break; | ||||||
|  | #if ENABLE_DESKTOP | ||||||
|  | 		if (one_char(argv[firstopt], '(')) | ||||||
|  | 			break; | ||||||
|  | #endif | ||||||
|  | 	} | ||||||
|  | 	if (firstopt == 1) { | ||||||
|  | 		argv[0] = "."; | ||||||
|  | 		argv--; | ||||||
|  | 		firstopt++; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | // All options always return true. They always take effect, | ||||||
|  | // rather than being processed only when their place in the | ||||||
|  | // expression is reached | ||||||
|  | // We implement: -follow, -xdev | ||||||
|  |  | ||||||
|  | 	/* Process options, and replace then with -a */ | ||||||
|  | 	/* (that will be ignored by recursive parser later) */ | ||||||
|  | 	argp = &argv[firstopt]; | ||||||
|  | 	while (*argp) { | ||||||
|  | 		char *arg = argp[0]; | ||||||
|  | 		if (strcmp(arg, "-follow") == 0) { | ||||||
|  | 			dereference = TRUE; | ||||||
|  | 			argp[0] = "-a"; | ||||||
|  | 		} | ||||||
|  | #if ENABLE_FEATURE_FIND_XDEV | ||||||
|  | 		else if (strcmp(arg, "-xdev") == 0) { | ||||||
|  | 			struct stat stbuf; | ||||||
|  | 			if (!xdev_count) { | ||||||
|  | 				xdev_count = firstopt - 1; | ||||||
|  | 				xdev_dev = xmalloc(xdev_count * sizeof(dev_t)); | ||||||
|  | 				for (i = 1; i < firstopt; i++) { | ||||||
|  | 					/* not xstat(): shouldn't bomb out on | ||||||
|  | 					 * "find not_exist exist -xdev" */ | ||||||
|  | 					if (stat(argv[i], &stbuf)) stbuf.st_dev = -1L; | ||||||
|  | 					xdev_dev[i-1] = stbuf.st_dev; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			argp[0] = "-a"; | ||||||
|  | 		} | ||||||
|  | 		argp++; | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 	actions = parse_params(&argv[firstopt]); | ||||||
|  |  | ||||||
| 	for (i = 1; i < firstopt; i++) { | 	for (i = 1; i < firstopt; i++) { | ||||||
| 		if (!recursive_action(argv[i], | 		if (!recursive_action(argv[i], | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user