c154cf4e784a6923552838e9ba12a313bf94efb1
[oweals/busybox.git] / findutils / find.c
1 /*
2  * Mini find implementation for busybox
3  *
4  *
5  * Copyright (C) 1999 by Lineo, inc.
6  * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  *
22  */
23
24 #include "internal.h"
25 #include "regexp.h"
26 #include <stdio.h>
27 #include <unistd.h>
28 #include <dirent.h>
29
30
31 static char* pattern=NULL;
32 static char* directory=".";
33 static int dereferenceFlag=FALSE;
34
35 static const char find_usage[] = "find [path...] [expression]\n"
36 "default path is the current directory; default expression is -print\n"
37 "expression may consist of:\n";
38
39
40
41 static int fileAction(const char *fileName, struct stat* statbuf)
42 {
43     if (pattern==NULL)
44         fprintf(stdout, "%s\n", fileName);
45     else if (find_match(fileName, pattern, TRUE) == TRUE)
46         fprintf(stdout, "%s\n", fileName);
47     return( TRUE);
48 }
49
50 static int dirAction(const char *fileName, struct stat* statbuf)
51 {
52     DIR *dir;
53     struct dirent *entry;
54     
55     if (pattern==NULL)
56         fprintf(stdout, "%s\n", fileName);
57     else if (find_match(fileName, pattern, TRUE) == TRUE)
58         fprintf(stdout, "%s\n", fileName);
59
60     dir = opendir( fileName);
61     if (!dir) {
62         perror("Can't open directory");
63         exit(FALSE);
64     }
65     while ((entry = readdir(dir)) != NULL) {
66         char dirName[NAME_MAX];
67         sprintf(dirName, "%s/%s", fileName, entry->d_name);
68         recursiveAction( dirName, TRUE, dereferenceFlag, FALSE, fileAction, dirAction);
69     }
70     return( TRUE);
71 }
72
73 int find_main(int argc, char **argv)
74 {
75     /* peel off the "find" */
76     argc--;
77     argv++;
78
79     if ( argc > 0 && **argv != '-') {
80         directory=*argv;
81         argc--;
82         argv++;
83     }
84
85     /* Parse any options */
86     while (argc > 0 && **argv == '-') {
87         int stopit=FALSE;
88         while (*++(*argv) && stopit==FALSE) switch (**argv) {
89             case 'f':
90                 if (strcmp(*argv, "follow")==0) {
91                     argc--;
92                     argv++;
93                     dereferenceFlag=TRUE;
94                 }
95                 break;
96             case 'n':
97                 if (strcmp(*argv, "name")==0) {
98                     if (argc-- > 1) {
99                         pattern=*(++argv);
100                         stopit=-TRUE;
101                     } else {
102                         usage (find_usage);
103                     }
104                 }
105                 break;
106             case '-':
107                 /* Ignore all long options */
108                 break;
109             default:
110                 usage (find_usage);
111         }
112         if (argc-- > 1)
113             argv++;
114             if (**argv != '-')
115                 break;
116         else
117             break;
118     }
119
120     if (recursiveAction(directory, TRUE, FALSE, FALSE,
121                            fileAction, fileAction) == FALSE) {
122         exit( FALSE);
123     }
124
125     exit(TRUE);
126 }