/* This is a NOEXEC applet. Be very careful! */
-USE_FEATURE_FIND_XDEV(static dev_t *xdev_dev;)
-USE_FEATURE_FIND_XDEV(static int xdev_count;)
+IF_FEATURE_FIND_XDEV(static dev_t *xdev_dev;)
+IF_FEATURE_FIND_XDEV(static int xdev_count;)
-typedef int (*action_fp)(const char *fileName, struct stat *statbuf, void *);
+typedef int (*action_fp)(const char *fileName, struct stat *statbuf, void *) FAST_FUNC;
typedef struct {
action_fp f;
bool invert;
#endif
} action;
+
#define ACTS(name, arg...) typedef struct { action a; arg; } action_##name;
-#define ACTF(name) static int func_##name(const char *fileName, struct stat *statbuf, action_##name* ap)
- ACTS(print)
- ACTS(name, const char *pattern;)
-USE_FEATURE_FIND_PATH( ACTS(path, const char *pattern;))
-USE_FEATURE_FIND_REGEX( ACTS(regex, regex_t compiled_pattern;))
-USE_FEATURE_FIND_PRINT0( ACTS(print0))
-USE_FEATURE_FIND_TYPE( ACTS(type, int type_mask;))
-USE_FEATURE_FIND_PERM( ACTS(perm, char perm_char; mode_t perm_mask;))
-USE_FEATURE_FIND_MTIME( ACTS(mtime, char mtime_char; unsigned mtime_days;))
-USE_FEATURE_FIND_MMIN( ACTS(mmin, char mmin_char; unsigned mmin_mins;))
-USE_FEATURE_FIND_NEWER( ACTS(newer, time_t newer_mtime;))
-USE_FEATURE_FIND_INUM( ACTS(inum, ino_t inode_num;))
-USE_FEATURE_FIND_USER( ACTS(user, uid_t uid;))
-USE_FEATURE_FIND_SIZE( ACTS(size, char size_char; off_t size;))
-USE_FEATURE_FIND_CONTEXT(ACTS(context, security_context_t context;))
-USE_FEATURE_FIND_PAREN( ACTS(paren, action ***subexpr;))
-USE_FEATURE_FIND_PRUNE( ACTS(prune))
-USE_FEATURE_FIND_DELETE( ACTS(delete))
-USE_FEATURE_FIND_EXEC( ACTS(exec, char **exec_argv; unsigned *subst_count; int exec_argc;))
-USE_FEATURE_FIND_GROUP( ACTS(group, gid_t gid;))
+#define ACTF(name) \
+ static int FAST_FUNC func_##name(const char *fileName UNUSED_PARAM, \
+ struct stat *statbuf UNUSED_PARAM, \
+ action_##name* ap UNUSED_PARAM)
+
+ ACTS(print)
+ ACTS(name, const char *pattern; bool iname;)
+IF_FEATURE_FIND_PATH( ACTS(path, const char *pattern;))
+IF_FEATURE_FIND_REGEX( ACTS(regex, regex_t compiled_pattern;))
+IF_FEATURE_FIND_PRINT0( ACTS(print0))
+IF_FEATURE_FIND_TYPE( ACTS(type, int type_mask;))
+IF_FEATURE_FIND_PERM( ACTS(perm, char perm_char; mode_t perm_mask;))
+IF_FEATURE_FIND_MTIME( ACTS(mtime, char mtime_char; unsigned mtime_days;))
+IF_FEATURE_FIND_MMIN( ACTS(mmin, char mmin_char; unsigned mmin_mins;))
+IF_FEATURE_FIND_NEWER( ACTS(newer, time_t newer_mtime;))
+IF_FEATURE_FIND_INUM( ACTS(inum, ino_t inode_num;))
+IF_FEATURE_FIND_USER( ACTS(user, uid_t uid;))
+IF_FEATURE_FIND_SIZE( ACTS(size, char size_char; off_t size;))
+IF_FEATURE_FIND_CONTEXT(ACTS(context, security_context_t context;))
+IF_FEATURE_FIND_PAREN( ACTS(paren, action ***subexpr;))
+IF_FEATURE_FIND_PRUNE( ACTS(prune))
+IF_FEATURE_FIND_DELETE( ACTS(delete))
+IF_FEATURE_FIND_EXEC( ACTS(exec, char **exec_argv; unsigned *subst_count; int exec_argc;))
+IF_FEATURE_FIND_GROUP( ACTS(group, gid_t gid;))
static action ***actions;
static bool need_print = 1;
if (*tmp == '/')
tmp++;
}
- return fnmatch(ap->pattern, tmp, FNM_PERIOD) == 0;
+ return fnmatch(ap->pattern, tmp, FNM_PERIOD | (ap->iname ? FNM_CASEFOLD : 0)) == 0;
}
+
#if ENABLE_FEATURE_FIND_PATH
ACTF(path)
{
rc = spawn_and_wait(argv);
if (rc < 0)
- bb_perror_msg("%s", argv[0]);
+ bb_simple_perror_msg(argv[0]);
i = 0;
while (argv[i])
rc = unlink(fileName);
}
if (rc < 0)
- bb_perror_msg("%s", fileName);
+ bb_simple_perror_msg(fileName);
return TRUE;
}
#endif
#endif
-static int fileAction(const char *fileName, struct stat *statbuf, void *userData, int depth)
+static int FAST_FUNC fileAction(const char *fileName,
+ struct stat *statbuf,
+ void *userData IF_NOT_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM),
+ int depth IF_NOT_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM))
{
int i;
#if ENABLE_FEATURE_FIND_MAXDEPTH
- int maxdepth = (int)(ptrdiff_t)userData;
+#define minmaxdepth ((int*)userData)
- if (depth > maxdepth) return SKIP;
+ if (depth < minmaxdepth[0]) return TRUE;
+ if (depth > minmaxdepth[1]) return SKIP;
+#undef minmaxdepth
#endif
#if ENABLE_FEATURE_FIND_XDEV
enum {
PARM_a ,
PARM_o ,
- USE_FEATURE_FIND_NOT( PARM_char_not ,)
+ IF_FEATURE_FIND_NOT( PARM_char_not ,)
#if ENABLE_DESKTOP
PARM_and ,
PARM_or ,
- USE_FEATURE_FIND_NOT( PARM_not ,)
+ IF_FEATURE_FIND_NOT( PARM_not ,)
#endif
PARM_print ,
- USE_FEATURE_FIND_PRINT0( PARM_print0 ,)
- USE_FEATURE_FIND_DEPTH( PARM_depth ,)
- USE_FEATURE_FIND_PRUNE( PARM_prune ,)
- USE_FEATURE_FIND_DELETE( PARM_delete ,)
- USE_FEATURE_FIND_EXEC( PARM_exec ,)
- USE_FEATURE_FIND_PAREN( PARM_char_brace,)
+ IF_FEATURE_FIND_PRINT0( PARM_print0 ,)
+ IF_FEATURE_FIND_DEPTH( PARM_depth ,)
+ IF_FEATURE_FIND_PRUNE( PARM_prune ,)
+ IF_FEATURE_FIND_DELETE( PARM_delete ,)
+ IF_FEATURE_FIND_EXEC( PARM_exec ,)
+ IF_FEATURE_FIND_PAREN( PARM_char_brace,)
/* All options starting from here require argument */
PARM_name ,
- USE_FEATURE_FIND_PATH( PARM_path ,)
- USE_FEATURE_FIND_REGEX( PARM_regex ,)
- USE_FEATURE_FIND_TYPE( PARM_type ,)
- USE_FEATURE_FIND_PERM( PARM_perm ,)
- USE_FEATURE_FIND_MTIME( PARM_mtime ,)
- USE_FEATURE_FIND_MMIN( PARM_mmin ,)
- USE_FEATURE_FIND_NEWER( PARM_newer ,)
- USE_FEATURE_FIND_INUM( PARM_inum ,)
- USE_FEATURE_FIND_USER( PARM_user ,)
- USE_FEATURE_FIND_GROUP( PARM_group ,)
- USE_FEATURE_FIND_SIZE( PARM_size ,)
- USE_FEATURE_FIND_CONTEXT(PARM_context ,)
+ PARM_iname ,
+ IF_FEATURE_FIND_PATH( PARM_path ,)
+ IF_FEATURE_FIND_REGEX( PARM_regex ,)
+ IF_FEATURE_FIND_TYPE( PARM_type ,)
+ IF_FEATURE_FIND_PERM( PARM_perm ,)
+ IF_FEATURE_FIND_MTIME( PARM_mtime ,)
+ IF_FEATURE_FIND_MMIN( PARM_mmin ,)
+ IF_FEATURE_FIND_NEWER( PARM_newer ,)
+ IF_FEATURE_FIND_INUM( PARM_inum ,)
+ IF_FEATURE_FIND_USER( PARM_user ,)
+ IF_FEATURE_FIND_GROUP( PARM_group ,)
+ IF_FEATURE_FIND_SIZE( PARM_size ,)
+ IF_FEATURE_FIND_CONTEXT(PARM_context ,)
};
static const char params[] ALIGN1 =
"-a\0"
"-o\0"
- USE_FEATURE_FIND_NOT( "!\0" )
+ IF_FEATURE_FIND_NOT( "!\0" )
#if ENABLE_DESKTOP
"-and\0"
"-or\0"
- USE_FEATURE_FIND_NOT( "-not\0" )
+ IF_FEATURE_FIND_NOT( "-not\0" )
#endif
"-print\0"
- USE_FEATURE_FIND_PRINT0( "-print0\0" )
- USE_FEATURE_FIND_DEPTH( "-depth\0" )
- USE_FEATURE_FIND_PRUNE( "-prune\0" )
- USE_FEATURE_FIND_DELETE( "-delete\0" )
- USE_FEATURE_FIND_EXEC( "-exec\0" )
- USE_FEATURE_FIND_PAREN( "(\0" )
+ IF_FEATURE_FIND_PRINT0( "-print0\0" )
+ IF_FEATURE_FIND_DEPTH( "-depth\0" )
+ IF_FEATURE_FIND_PRUNE( "-prune\0" )
+ IF_FEATURE_FIND_DELETE( "-delete\0" )
+ IF_FEATURE_FIND_EXEC( "-exec\0" )
+ IF_FEATURE_FIND_PAREN( "(\0" )
/* All options starting from here require argument */
"-name\0"
- USE_FEATURE_FIND_PATH( "-path\0" )
- USE_FEATURE_FIND_REGEX( "-regex\0" )
- USE_FEATURE_FIND_TYPE( "-type\0" )
- USE_FEATURE_FIND_PERM( "-perm\0" )
- USE_FEATURE_FIND_MTIME( "-mtime\0" )
- USE_FEATURE_FIND_MMIN( "-mmin\0" )
- USE_FEATURE_FIND_NEWER( "-newer\0" )
- USE_FEATURE_FIND_INUM( "-inum\0" )
- USE_FEATURE_FIND_USER( "-user\0" )
- USE_FEATURE_FIND_GROUP( "-group\0" )
- USE_FEATURE_FIND_SIZE( "-size\0" )
- USE_FEATURE_FIND_CONTEXT("-context\0")
+ "-iname\0"
+ IF_FEATURE_FIND_PATH( "-path\0" )
+ IF_FEATURE_FIND_REGEX( "-regex\0" )
+ IF_FEATURE_FIND_TYPE( "-type\0" )
+ IF_FEATURE_FIND_PERM( "-perm\0" )
+ IF_FEATURE_FIND_MTIME( "-mtime\0" )
+ IF_FEATURE_FIND_MMIN( "-mmin\0" )
+ IF_FEATURE_FIND_NEWER( "-newer\0" )
+ IF_FEATURE_FIND_INUM( "-inum\0" )
+ IF_FEATURE_FIND_USER( "-user\0" )
+ IF_FEATURE_FIND_GROUP( "-group\0" )
+ IF_FEATURE_FIND_SIZE( "-size\0" )
+ IF_FEATURE_FIND_CONTEXT("-context\0")
;
action*** appp;
unsigned cur_group = 0;
unsigned cur_action = 0;
- USE_FEATURE_FIND_NOT( bool invert_flag = 0; )
+ IF_FEATURE_FIND_NOT( bool invert_flag = 0; )
- /* 'static' doesn't work here! (gcc 4.1.2) */
+ /* This is the only place in busybox where we use nested function.
+ * So far more standard alternatives were bigger. */
+ /* Suppress a warning "func without a prototype" */
+ auto action* alloc_action(int sizeof_struct, action_fp f);
action* alloc_action(int sizeof_struct, action_fp f)
{
action *ap;
appp[cur_group][cur_action++] = ap = xmalloc(sizeof_struct);
appp[cur_group][cur_action] = NULL;
ap->f = f;
- USE_FEATURE_FIND_NOT( ap->invert = invert_flag; )
- USE_FEATURE_FIND_NOT( invert_flag = 0; )
+ IF_FEATURE_FIND_NOT( ap->invert = invert_flag; )
+ IF_FEATURE_FIND_NOT( invert_flag = 0; )
return ap;
}
* it doesn't give smaller code. Other arches? */
/* --- Operators --- */
- if (parm == PARM_a USE_DESKTOP(|| parm == PARM_and)) {
+ if (parm == PARM_a IF_DESKTOP(|| parm == PARM_and)) {
/* no further special handling required */
}
- else if (parm == PARM_o USE_DESKTOP(|| parm == PARM_or)) {
+ else if (parm == PARM_o IF_DESKTOP(|| parm == PARM_or)) {
/* start new OR group */
cur_group++;
appp = xrealloc(appp, (cur_group+2) * sizeof(*appp));
cur_action = 0;
}
#if ENABLE_FEATURE_FIND_NOT
- else if (parm == PARM_char_not USE_DESKTOP(|| parm == PARM_not)) {
+ else if (parm == PARM_char_not IF_DESKTOP(|| parm == PARM_not)) {
/* also handles "find ! ! -name 'foo*'" */
invert_flag ^= 1;
}
else if (parm == PARM_print) {
need_print = 0;
/* GNU find ignores '!' here: "find ! -print" */
- USE_FEATURE_FIND_NOT( invert_flag = 0; )
+ IF_FEATURE_FIND_NOT( invert_flag = 0; )
(void) ALLOC_ACTION(print);
}
#if ENABLE_FEATURE_FIND_PRINT0
else if (parm == PARM_print0) {
need_print = 0;
- USE_FEATURE_FIND_NOT( invert_flag = 0; )
+ IF_FEATURE_FIND_NOT( invert_flag = 0; )
(void) ALLOC_ACTION(print0);
}
#endif
#endif
#if ENABLE_FEATURE_FIND_PRUNE
else if (parm == PARM_prune) {
- USE_FEATURE_FIND_NOT( invert_flag = 0; )
+ IF_FEATURE_FIND_NOT( invert_flag = 0; )
(void) ALLOC_ACTION(prune);
}
#endif
int i;
action_exec *ap;
need_print = 0;
- USE_FEATURE_FIND_NOT( invert_flag = 0; )
+ IF_FEATURE_FIND_NOT( invert_flag = 0; )
ap = ALLOC_ACTION(exec);
ap->exec_argv = ++argv; /* first arg after -exec */
ap->exec_argc = 0;
argv = endarg;
}
#endif
- else if (parm == PARM_name) {
+ else if (parm == PARM_name || parm == PARM_iname) {
action_name *ap;
ap = ALLOC_ACTION(name);
ap->pattern = arg1;
+ ap->iname = (parm == PARM_iname);
}
#if ENABLE_FEATURE_FIND_PATH
else if (parm == PARM_path) {
ap->context = NULL;
/* SELinux headers erroneously declare non-const parameter */
if (selinux_raw_to_trans_context((char*)arg1, &ap->context))
- bb_perror_msg("%s", arg1);
+ bb_simple_perror_msg(arg1);
}
#endif
else {
}
-int find_main(int argc, char **argv);
+int find_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int find_main(int argc, char **argv)
{
static const char options[] ALIGN1 =
"-follow\0"
-USE_FEATURE_FIND_XDEV( "-xdev\0" )
-USE_FEATURE_FIND_MAXDEPTH("-maxdepth\0")
+IF_FEATURE_FIND_XDEV( "-xdev\0" )
+IF_FEATURE_FIND_MAXDEPTH("-mindepth\0""-maxdepth\0")
;
enum {
OPT_FOLLOW,
-USE_FEATURE_FIND_XDEV( OPT_XDEV ,)
-USE_FEATURE_FIND_MAXDEPTH(OPT_MAXDEPTH,)
+IF_FEATURE_FIND_XDEV( OPT_XDEV ,)
+IF_FEATURE_FIND_MAXDEPTH(OPT_MINDEPTH,)
};
char *arg;
char **argp;
int i, firstopt, status = EXIT_SUCCESS;
#if ENABLE_FEATURE_FIND_MAXDEPTH
- int maxdepth = INT_MAX;
+ int minmaxdepth[2] = { 0, INT_MAX };
+#else
+#define minmaxdepth NULL
#endif
for (firstopt = 1; firstopt < argc; firstopt++) {
}
#endif
#if ENABLE_FEATURE_FIND_MAXDEPTH
- if (opt == OPT_MAXDEPTH) {
+ if (opt == OPT_MINDEPTH || opt == OPT_MINDEPTH + 1) {
if (!argp[1])
bb_show_usage();
- maxdepth = xatoi_u(argp[1]);
+ minmaxdepth[opt - OPT_MINDEPTH] = xatoi_u(argp[1]);
argp[0] = (char*)"-a";
argp[1] = (char*)"-a";
argp++;
fileAction, /* file action */
fileAction, /* dir action */
#if ENABLE_FEATURE_FIND_MAXDEPTH
- /* double cast suppresses
- * "cast to ptr from int of different size" */
- (void*)(ptrdiff_t)maxdepth,/* user data */
+ minmaxdepth, /* user data */
#else
NULL, /* user data */
#endif