2 * Test program for find files
6 Copyright (C) 2000-2003 Kern Sibbald and John Walker
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of
11 the License, or (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public
19 License along with this program; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
26 #include "findlib/find.h"
29 #if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
36 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
37 int generate_job_event(JCR *jcr, const char *event) { return 1; }
39 /* Global variables */
40 static int num_files = 0;
41 static int max_file_len = 0;
42 static int max_path_len = 0;
43 static int trunc_fname = 0;
44 static int trunc_path = 0;
49 static int print_file(FF_PKT *ff, void *pkt, bool);
50 static void count_files(FF_PKT *ff);
56 "Usage: testfind [-d debug_level] [-] [pattern1 ...]\n"
57 " -a print extended attributes (Win32 debug)\n"
58 " -dnn set debug level to nn\n"
59 " -e specify file of exclude patterns\n"
60 " -i specify file of include patterns\n"
61 " - read pattern(s) from stdin\n"
62 " -? print this message.\n"
64 "Patterns are used for file inclusion -- normally directories.\n"
65 "Debug level >= 1 prints each file found.\n"
66 "Debug level >= 10 prints path/file for catalog.\n"
67 "Errors are always printed.\n"
68 "Files/paths truncated is the number of files/paths with len > 255.\n"
69 "Truncation is only in the catalog.\n"
77 main (int argc, char *const *argv)
81 int i, ch, hard_links;
86 while ((ch = getopt(argc, argv, "ad:e:i:?")) != -1) {
88 case 'a': /* print extended attributes *debug* */
92 case 'd': /* set debug level */
93 debug_level = atoi(optarg);
94 if (debug_level <= 0) {
99 case 'e': /* exclude patterns */
103 case 'i': /* include patterns */
116 jcr = new_jcr(sizeof(JCR), NULL);
118 ff = init_find_files();
119 if (argc == 0 && !inc) {
120 add_fname_to_include_list(ff, 0, "/"); /* default to / */
122 for (i=0; i < argc; i++) {
123 if (strcmp(argv[i], "-") == 0) {
124 while (fgets(name, sizeof(name)-1, stdin)) {
125 strip_trailing_junk(name);
126 add_fname_to_include_list(ff, 0, name);
130 add_fname_to_include_list(ff, 0, argv[i]);
134 fd = fopen(inc, "r");
136 printf("Could not open include file: %s\n", inc);
139 while (fgets(name, sizeof(name)-1, fd)) {
140 strip_trailing_junk(name);
141 add_fname_to_include_list(ff, 0, name);
147 fd = fopen(exc, "r");
149 printf("Could not open exclude file: %s\n", exc);
152 while (fgets(name, sizeof(name)-1, fd)) {
153 strip_trailing_junk(name);
154 add_fname_to_exclude_list(ff, name);
158 match_files(jcr, ff, print_file, NULL);
159 term_include_exclude_files(ff);
160 hard_links = term_find_files(ff);
164 "Max file length: %d\n"
165 "Max path length: %d\n"
166 "Files truncated: %d\n"
167 "Paths truncated: %d\n"
168 "Hard links : %d\n"),
169 num_files, max_file_len, max_path_len,
170 trunc_fname, trunc_path, hard_links);
178 static int print_file(FF_PKT *ff, void *pkt, bool top_level)
183 if (debug_level == 1) {
184 printf("%s\n", ff->fname);
185 } else if (debug_level > 1) {
186 printf("Lnka: %s -> %s\n", ff->fname, ff->link);
190 if (debug_level == 1) {
191 printf("%s\n", ff->fname);
192 } else if (debug_level > 1) {
193 printf("Empty: %s\n", ff->fname);
198 if (debug_level == 1) {
199 printf("%s\n", ff->fname);
200 } else if (debug_level > 1) {
201 printf("Reg: %s\n", ff->fname);
206 if (debug_level == 1) {
207 printf("%s\n", ff->fname);
208 } else if (debug_level > 1) {
209 printf("Lnk: %s -> %s\n", ff->fname, ff->link);
220 char errmsg[100] = "";
221 if (ff->type == FT_NORECURSE) {
222 bstrncpy(errmsg, "\t[will not descend: recursion turned off]", sizeof(errmsg));
223 } else if (ff->type == FT_NOFSCHG) {
224 bstrncpy(errmsg, "\t[will not descend: file system change not allowed]", sizeof(errmsg));
225 } else if (ff->type == FT_INVALIDFS) {
226 bstrncpy(errmsg, "\t[will not descend: disallowed file system]", sizeof(errmsg));
228 printf("%s%s%s\n", (debug_level > 1 ? "Dir: " : ""), ff->fname, errmsg);
230 ff->type = FT_DIREND;
234 if (debug_level == 1) {
235 printf("%s\n", ff->fname);
236 } else if (debug_level > 1) {
237 printf("Spec: %s\n", ff->fname);
242 printf(_("Err: Could not access %s: %s\n"), ff->fname, strerror(errno));
245 printf(_("Err: Could not follow ff->link %s: %s\n"), ff->fname, strerror(errno));
248 printf(_("Err: Could not stat %s: %s\n"), ff->fname, strerror(errno));
251 printf(_("Skip: File not saved. No change. %s\n"), ff->fname);
254 printf(_("Err: Attempt to backup archive. Not saved. %s\n"), ff->fname);
257 printf(_("Err: Could not open directory %s: %s\n"), ff->fname, strerror(errno));
260 printf(_("Err: Unknown file ff->type %d: %s\n"), ff->type, ff->fname);
265 encode_attribsEx(NULL, attr, ff);
267 printf("AttrEx=%s\n", attr);
269 // set_attribsEx(NULL, ff->fname, NULL, NULL, ff->type, attr);
274 static void count_files(FF_PKT *ar)
278 char file[MAXSTRING];
279 char spath[MAXSTRING];
283 /* Find path without the filename.
284 * I.e. everything after the last / is a "filename".
285 * OK, maybe it is a directory name, but we treat it like
286 * a filename. If we don't find a / then the whole name
287 * must be a path name (e.g. c:).
289 for (p=l=ar->fname; *p; p++) {
291 l = p; /* set pos of last slash */
294 if (*l == '/') { /* did we find a slash? */
295 l++; /* yes, point to filename */
296 } else { /* no, whole thing must be path name */
300 /* If filename doesn't exist (i.e. root directory), we
301 * simply create a blank name consisting of a single
302 * space. This makes handling zero length filenames
306 if (fnl > max_file_len) {
310 printf(_("===== Filename truncated to 255 chars: %s\n"), l);
315 strncpy(file, l, fnl); /* copy filename */
318 file[0] = ' '; /* blank filename */
323 if (pnl > max_path_len) {
327 printf(_("========== Path name truncated to 255 chars: %s\n"), ar->fname);
331 strncpy(spath, ar->fname, pnl);
336 printf(_("========== Path length is zero. File=%s\n"), ar->fname);
338 if (debug_level >= 10) {
339 printf("Path: %s\n", spath);
340 printf("File: %s\n", file);
345 bool python_set_prog(JCR*, char const*) { return false; }