2 * Test program for find files
5 Copyright (C) 2000-2006 Kern Sibbald
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 version 2 as amended with additional clauses defined in the
10 file LICENSE in the main source directory.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 the file LICENSE for additional details.
20 #include "findlib/find.h"
23 #if defined(HAVE_WIN32)
30 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
31 int generate_job_event(JCR *jcr, const char *event) { return 1; }
33 /* Global variables */
34 static int num_files = 0;
35 static int max_file_len = 0;
36 static int max_path_len = 0;
37 static int trunc_fname = 0;
38 static int trunc_path = 0;
43 static int print_file(FF_PKT *ff, void *pkt, bool);
44 static void count_files(FF_PKT *ff);
50 "Usage: testfind [-d debug_level] [-] [pattern1 ...]\n"
51 " -a print extended attributes (Win32 debug)\n"
52 " -dnn set debug level to nn\n"
53 " -e specify file of exclude patterns\n"
54 " -i specify file of include patterns\n"
55 " - read pattern(s) from stdin\n"
56 " -? print this message.\n"
58 "Patterns are used for file inclusion -- normally directories.\n"
59 "Debug level >= 1 prints each file found.\n"
60 "Debug level >= 10 prints path/file for catalog.\n"
61 "Errors are always printed.\n"
62 "Files/paths truncated is the number of files/paths with len > 255.\n"
63 "Truncation is only in the catalog.\n"
71 main (int argc, char *const *argv)
75 int i, ch, hard_links;
80 setlocale(LC_ALL, "");
81 bindtextdomain("bacula", LOCALEDIR);
84 while ((ch = getopt(argc, argv, "ad:e:i:?")) != -1) {
86 case 'a': /* print extended attributes *debug* */
90 case 'd': /* set debug level */
91 debug_level = atoi(optarg);
92 if (debug_level <= 0) {
97 case 'e': /* exclude patterns */
101 case 'i': /* include patterns */
114 jcr = new_jcr(sizeof(JCR), NULL);
116 ff = init_find_files();
117 if (argc == 0 && !inc) {
118 add_fname_to_include_list(ff, 0, "/"); /* default to / */
120 for (i=0; i < argc; i++) {
121 if (strcmp(argv[i], "-") == 0) {
122 while (fgets(name, sizeof(name)-1, stdin)) {
123 strip_trailing_junk(name);
124 add_fname_to_include_list(ff, 0, name);
128 add_fname_to_include_list(ff, 0, argv[i]);
132 fd = fopen(inc, "r");
134 printf(_("Could not open include file: %s\n"), inc);
137 while (fgets(name, sizeof(name)-1, fd)) {
138 strip_trailing_junk(name);
139 add_fname_to_include_list(ff, 0, name);
145 fd = fopen(exc, "r");
147 printf(_("Could not open exclude file: %s\n"), exc);
150 while (fgets(name, sizeof(name)-1, fd)) {
151 strip_trailing_junk(name);
152 add_fname_to_exclude_list(ff, name);
156 match_files(jcr, ff, print_file, NULL);
157 term_include_exclude_files(ff);
158 hard_links = term_find_files(ff);
162 "Max file length: %d\n"
163 "Max path length: %d\n"
164 "Files truncated: %d\n"
165 "Paths truncated: %d\n"
166 "Hard links : %d\n"),
167 num_files, max_file_len, max_path_len,
168 trunc_fname, trunc_path, hard_links);
176 static int print_file(FF_PKT *ff, void *pkt, bool top_level)
181 if (debug_level == 1) {
182 printf("%s\n", ff->fname);
183 } else if (debug_level > 1) {
184 printf("Lnka: %s -> %s\n", ff->fname, ff->link);
188 if (debug_level == 1) {
189 printf("%s\n", ff->fname);
190 } else if (debug_level > 1) {
191 printf("Empty: %s\n", ff->fname);
196 if (debug_level == 1) {
197 printf("%s\n", ff->fname);
198 } else if (debug_level > 1) {
199 printf(_("Reg: %s\n"), ff->fname);
204 if (debug_level == 1) {
205 printf("%s\n", ff->fname);
206 } else if (debug_level > 1) {
207 printf("Lnk: %s -> %s\n", ff->fname, ff->link);
218 char errmsg[100] = "";
219 if (ff->type == FT_NORECURSE) {
220 bstrncpy(errmsg, _("\t[will not descend: recursion turned off]"), sizeof(errmsg));
221 } else if (ff->type == FT_NOFSCHG) {
222 bstrncpy(errmsg, _("\t[will not descend: file system change not allowed]"), sizeof(errmsg));
223 } else if (ff->type == FT_INVALIDFS) {
224 bstrncpy(errmsg, _("\t[will not descend: disallowed file system]"), sizeof(errmsg));
226 printf("%s%s%s\n", (debug_level > 1 ? "Dir: " : ""), ff->fname, errmsg);
228 ff->type = FT_DIREND;
232 if (debug_level == 1) {
233 printf("%s\n", ff->fname);
234 } else if (debug_level > 1) {
235 printf("Spec: %s\n", ff->fname);
240 printf(_("Err: Could not access %s: %s\n"), ff->fname, strerror(errno));
243 printf(_("Err: Could not follow ff->link %s: %s\n"), ff->fname, strerror(errno));
246 printf(_("Err: Could not stat %s: %s\n"), ff->fname, strerror(errno));
249 printf(_("Skip: File not saved. No change. %s\n"), ff->fname);
252 printf(_("Err: Attempt to backup archive. Not saved. %s\n"), ff->fname);
255 printf(_("Err: Could not open directory %s: %s\n"), ff->fname, strerror(errno));
258 printf(_("Err: Unknown file ff->type %d: %s\n"), ff->type, ff->fname);
263 encode_attribsEx(NULL, attr, ff);
265 printf("AttrEx=%s\n", attr);
267 // set_attribsEx(NULL, ff->fname, NULL, NULL, ff->type, attr);
272 static void count_files(FF_PKT *ar)
276 char file[MAXSTRING];
277 char spath[MAXSTRING];
281 /* Find path without the filename.
282 * I.e. everything after the last / is a "filename".
283 * OK, maybe it is a directory name, but we treat it like
284 * a filename. If we don't find a / then the whole name
285 * must be a path name (e.g. c:).
287 for (p=l=ar->fname; *p; p++) {
289 l = p; /* set pos of last slash */
292 if (*l == '/') { /* did we find a slash? */
293 l++; /* yes, point to filename */
294 } else { /* no, whole thing must be path name */
298 /* If filename doesn't exist (i.e. root directory), we
299 * simply create a blank name consisting of a single
300 * space. This makes handling zero length filenames
304 if (fnl > max_file_len) {
308 printf(_("===== Filename truncated to 255 chars: %s\n"), l);
313 strncpy(file, l, fnl); /* copy filename */
316 file[0] = ' '; /* blank filename */
321 if (pnl > max_path_len) {
325 printf(_("========== Path name truncated to 255 chars: %s\n"), ar->fname);
329 strncpy(spath, ar->fname, pnl);
334 printf(_("========== Path length is zero. File=%s\n"), ar->fname);
336 if (debug_level >= 10) {
337 printf(_("Path: %s\n"), spath);
338 printf(_("File: %s\n"), file);
343 bool python_set_prog(JCR*, char const*) { return false; }