inetd: comment tweak. no code changes
[oweals/busybox.git] / findutils / find.c
index ea789a01c5f865987a262fdd19327772b83864af..5e8193ffa487030672c255f4495a65be788aaf52 100644 (file)
 /* 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;
@@ -73,27 +73,32 @@ typedef struct {
        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;
@@ -188,8 +193,9 @@ ACTF(name)
                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)
 {
@@ -277,7 +283,7 @@ ACTF(exec)
 
        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])
@@ -347,7 +353,7 @@ ACTF(delete)
                rc = unlink(fileName);
        }
        if (rc < 0)
-               bb_perror_msg("%s", fileName);
+               bb_simple_perror_msg(fileName);
        return TRUE;
 }
 #endif
@@ -371,21 +377,28 @@ ACTF(context)
 #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
        if (S_ISDIR(statbuf->st_mode) && xdev_count) {
                for (i = 0; i < xdev_count; i++) {
-                       if (xdev_dev[i] != statbuf->st_dev)
-                               return SKIP;
+                       if (xdev_dev[i] == statbuf->st_dev)
+                               break;
                }
+               if (i == xdev_count)
+                       return SKIP;
        }
 #endif
        i = exec_actions(actions, fileName, statbuf);
@@ -441,73 +454,78 @@ static action*** parse_params(char **argv)
        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"    )
+                                "-and\0"
+                                "-or\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")
+                                "-name\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;
@@ -515,8 +533,8 @@ static action*** parse_params(char **argv)
                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;
        }
 
@@ -554,10 +572,10 @@ static action*** parse_params(char **argv)
                 * 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));
@@ -566,7 +584,7 @@ static action*** parse_params(char **argv)
                        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;
                }
@@ -576,13 +594,13 @@ static action*** parse_params(char **argv)
                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
@@ -593,7 +611,7 @@ static action*** parse_params(char **argv)
 #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
@@ -609,7 +627,7 @@ static action*** parse_params(char **argv)
                        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;
@@ -652,10 +670,11 @@ static action*** parse_params(char **argv)
                        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) {
@@ -776,8 +795,9 @@ static action*** parse_params(char **argv)
                        action_context *ap;
                        ap = ALLOC_ACTION(context);
                        ap->context = NULL;
-                       if (selinux_raw_to_trans_context(arg1, &ap->context))
-                               bb_perror_msg("%s", arg1);
+                       /* SELinux headers erroneously declare non-const parameter */
+                       if (selinux_raw_to_trans_context((char*)arg1, &ap->context))
+                               bb_simple_perror_msg(arg1);
                }
 #endif
                else {
@@ -791,25 +811,27 @@ static action*** parse_params(char **argv)
 }
 
 
-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++) {
@@ -860,10 +882,10 @@ USE_FEATURE_FIND_MAXDEPTH(OPT_MAXDEPTH,)
                }
 #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++;
@@ -880,7 +902,7 @@ USE_FEATURE_FIND_MAXDEPTH(OPT_MAXDEPTH,)
                                fileAction,     /* file action */
                                fileAction,     /* dir action */
 #if ENABLE_FEATURE_FIND_MAXDEPTH
-                               (void*)maxdepth,/* user data */
+                               minmaxdepth,    /* user data */
 #else
                                NULL,           /* user data */
 #endif