- check if CC supports -funsigned-char
[oweals/busybox.git] / findutils / find.c
index b0f4bca6b7510b3b1372d97550e6f121fd84153b..75ed4e208106e7257ff8db35e5888b02b0740d0f 100644 (file)
@@ -2,8 +2,7 @@
 /*
  * Mini find implementation for busybox
  *
- * Copyright (C) 1999,2000 by Lineo, inc. and Erik Andersen
- * Copyright (C) 1999,2000,2001 by Erik Andersen <andersee@debian.org>
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
  *
  * Reworked by David Douthitt <n9ubh@callsign.net> and
  *  Matt Kraai <kraai@alumni.carnegiemellon.edu>.
@@ -34,6 +33,9 @@
 #include <ctype.h>
 #include "busybox.h"
 
+//XXX just found out about libbb/messages.c . maybe move stuff there ? - ghoz
+static const char msg_req_arg[] = "option `%s' requires an argument";
+static const char msg_invalid_arg[] = "invalid argument `%s' to `%s'";
 
 static char *pattern;
 
@@ -56,6 +58,19 @@ static dev_t *xdev_dev;
 static int xdev_count = 0;
 #endif
 
+#ifdef CONFIG_FEATURE_FIND_NEWER
+static time_t newer_mtime;
+#endif
+
+#ifdef CONFIG_FEATURE_FIND_INUM
+static ino_t inode_num;
+#endif
+
+#ifdef CONFIG_FEATURE_FIND_EXEC
+static char **exec_str;
+static int num_matches;
+static int exec_opt;
+#endif
 
 static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
 {
@@ -89,7 +104,7 @@ static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
                time_t mtime_secs = mtime_days * 24 * 60 * 60;
                if (!((isdigit(mtime_char) && file_age >= mtime_secs &&
                                                file_age < mtime_secs + 24 * 60 * 60) ||
-                               (mtime_char == '+' && file_age >= mtime_secs + 24 * 60 * 60) || 
+                               (mtime_char == '+' && file_age >= mtime_secs + 24 * 60 * 60) ||
                                (mtime_char == '-' && file_age < mtime_secs)))
                        goto no_match;
        }
@@ -109,7 +124,31 @@ static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
                }
        }
 #endif
-
+#ifdef CONFIG_FEATURE_FIND_NEWER
+       if (newer_mtime != 0) {
+               time_t file_age = newer_mtime - statbuf->st_mtime;
+               if (file_age >= 0)
+                       goto no_match;
+       }
+#endif
+#ifdef CONFIG_FEATURE_FIND_INUM
+       if (inode_num != 0) {
+               if (!(statbuf->st_ino == inode_num))
+                       goto no_match;
+       }
+#endif
+#ifdef CONFIG_FEATURE_FIND_EXEC
+       if (exec_opt) {
+               int i;
+               char *cmd_string = "";
+               for (i = 0; i < num_matches; i++)
+                       cmd_string = bb_xasprintf("%s%s%s", cmd_string, exec_str[i], fileName);
+               cmd_string = bb_xasprintf("%s%s", cmd_string, exec_str[num_matches]);
+               system(cmd_string);
+               goto no_match;
+       }
+#endif
+       
        puts(fileName);
 no_match:
        return (TRUE);
@@ -145,7 +184,7 @@ static int find_type(char *type)
        }
 
        if (mask == 0 || type[1] != '\0')
-               error_msg_and_die("invalid argument `%s' to `-type'", type);
+               bb_error_msg_and_die(msg_invalid_arg, type, "-type");
 
        return mask;
 }
@@ -170,24 +209,22 @@ int find_main(int argc, char **argv)
                        }
                else if (strcmp(argv[i], "-name") == 0) {
                        if (++i == argc)
-                               error_msg_and_die("option `-name' requires an argument");
+                               bb_error_msg_and_die(msg_req_arg, "-name");
                        pattern = argv[i];
 #ifdef CONFIG_FEATURE_FIND_TYPE
                } else if (strcmp(argv[i], "-type") == 0) {
                        if (++i == argc)
-                               error_msg_and_die("option `-type' requires an argument");
+                               bb_error_msg_and_die(msg_req_arg, "-type");
                        type_mask = find_type(argv[i]);
 #endif
 #ifdef CONFIG_FEATURE_FIND_PERM
                } else if (strcmp(argv[i], "-perm") == 0) {
                        char *end;
                        if (++i == argc)
-                               error_msg_and_die("option `-perm' requires an argument");
+                               bb_error_msg_and_die(msg_req_arg, "-perm");
                        perm_mask = strtol(argv[i], &end, 8);
-                       if (end[0] != '\0')
-                               error_msg_and_die("invalid argument `%s' to `-perm'", argv[i]);
-                       if (perm_mask > 07777)
-                               error_msg_and_die("invalid argument `%s' to `-perm'", argv[i]);
+                       if ((end[0] != '\0') || (perm_mask > 07777))
+                               bb_error_msg_and_die(msg_invalid_arg, argv[i], "-perm");
                        if ((perm_char = argv[i][0]) == '-')
                                perm_mask = -perm_mask;
 #endif
@@ -195,10 +232,10 @@ int find_main(int argc, char **argv)
                } else if (strcmp(argv[i], "-mtime") == 0) {
                        char *end;
                        if (++i == argc)
-                               error_msg_and_die("option `-mtime' requires an argument");
+                               bb_error_msg_and_die(msg_req_arg, "-mtime");
                        mtime_days = strtol(argv[i], &end, 10);
                        if (end[0] != '\0')
-                               error_msg_and_die("invalid argument `%s' to `-mtime'", argv[i]);
+                               bb_error_msg_and_die(msg_invalid_arg, argv[i], "-mtime");
                        if ((mtime_char = argv[i][0]) == '-')
                                mtime_days = -mtime_days;
 #endif
@@ -211,20 +248,65 @@ int find_main(int argc, char **argv)
 
                        if ( firstopt == 1 ) {
                                if ( stat ( ".", &stbuf ) < 0 )
-                                       error_msg_and_die("could not stat '.'" );
+                                       bb_error_msg_and_die("could not stat '.'" );
                                xdev_dev [0] = stbuf. st_dev;
                        }
                        else {
-                       
+
                                for (i = 1; i < firstopt; i++) {
                                        if ( stat ( argv [i], &stbuf ) < 0 )
-                                               error_msg_and_die("could not stat '%s'", argv [i] );
+                                               bb_error_msg_and_die("could not stat '%s'", argv [i] );
                                        xdev_dev [i-1] = stbuf. st_dev;
                                }
-                       }                                               
+                       }
+#endif
+#ifdef CONFIG_FEATURE_FIND_NEWER
+               } else if (strcmp(argv[i], "-newer") == 0) {
+                       struct stat stat_newer;
+                       if (++i == argc)
+                               bb_error_msg_and_die(msg_req_arg, "-newer");
+                   if (stat (argv[i], &stat_newer) != 0)
+                               bb_error_msg_and_die("file %s not found", argv[i]);
+                       newer_mtime = stat_newer.st_mtime;
+#endif
+#ifdef CONFIG_FEATURE_FIND_INUM
+               } else if (strcmp(argv[i], "-inum") == 0) {
+                       char *end;
+                       if (++i == argc)
+                               bb_error_msg_and_die(msg_req_arg, "-inum");
+                       inode_num = strtol(argv[i], &end, 10);
+                       if (end[0] != '\0')
+                               bb_error_msg_and_die(msg_invalid_arg, argv[i], "-inum");
+#endif
+#ifdef CONFIG_FEATURE_FIND_EXEC
+               } else if (strcmp(argv[i], "-exec") == 0) {
+                       int b_pos;
+                       char *cmd_string = "";
+
+                       while (i++) {
+                               if (i == argc)
+                                       bb_error_msg_and_die(msg_req_arg, "-exec");
+                               if (*argv[i] == ';')
+                                       break;
+                               cmd_string = bb_xasprintf("%s %s", cmd_string, argv[i]);
+                       }
+                       
+                       if (*cmd_string == 0)
+                               bb_error_msg_and_die(msg_req_arg, "-exec");
+                       cmd_string++;
+                       exec_str = xmalloc(sizeof(char *));
+
+                       while ((b_pos = strstr(cmd_string, "{}") - cmd_string), (b_pos >= 0)) {
+                               num_matches++;
+                               exec_str = xrealloc(exec_str, (num_matches + 1) * sizeof(char *));
+                               exec_str[num_matches - 1] = bb_xstrndup(cmd_string, b_pos);
+                               cmd_string += b_pos + 2;
+                       }
+                       exec_str[num_matches] = bb_xstrdup(cmd_string);
+                       exec_opt = 1;
 #endif
                } else
-                       show_usage();
+                       bb_show_usage();
        }
 
        if (firstopt == 1) {