]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/tools/testfind.c
- Move Python variables from Job to Bacula. They are
[bacula/bacula] / bacula / src / tools / testfind.c
1 /*
2  * Test program for find files
3  */
4 /*
5    Copyright (C) 2000-2005 Kern Sibbald
6
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.
11
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.
16
17  */
18
19 #include "bacula.h"
20 #include "findlib/find.h"
21
22
23 #if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
24 int win32_client = 1;
25 #else
26 int win32_client = 0;
27 #endif
28
29 /* Dummy functions */
30 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
31 int generate_job_event(JCR *jcr, const char *event) { return 1; }
32
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;
39 static int attrs = 0;
40
41 static JCR *jcr;
42
43 static int print_file(FF_PKT *ff, void *pkt, bool);
44 static void count_files(FF_PKT *ff);
45
46 static void usage()
47 {
48    fprintf(stderr, _(
49 "\n"
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"
57 "\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"
64 "\n"));
65
66    exit(1);
67 }
68
69
70 int
71 main (int argc, char *const *argv)
72 {
73    FF_PKT *ff;
74    char name[1000];
75    int i, ch, hard_links;
76    char *inc = NULL;
77    char *exc = NULL;
78    FILE *fd;
79
80    while ((ch = getopt(argc, argv, "ad:e:i:?")) != -1) {
81       switch (ch) {
82          case 'a':                    /* print extended attributes *debug* */
83             attrs = 1;
84             break;
85
86          case 'd':                    /* set debug level */
87             debug_level = atoi(optarg);
88             if (debug_level <= 0) {
89                debug_level = 1;
90             }
91             break;
92
93          case 'e':                    /* exclude patterns */
94             exc = optarg;
95             break;
96
97          case 'i':                    /* include patterns */
98             inc = optarg;
99             break;
100
101          case '?':
102          default:
103             usage();
104
105       }
106    }
107    argc -= optind;
108    argv += optind;
109
110    jcr = new_jcr(sizeof(JCR), NULL);
111
112    ff = init_find_files();
113    if (argc == 0 && !inc) {
114       add_fname_to_include_list(ff, 0, "/"); /* default to / */
115    } else {
116       for (i=0; i < argc; i++) {
117          if (strcmp(argv[i], "-") == 0) {
118              while (fgets(name, sizeof(name)-1, stdin)) {
119                 strip_trailing_junk(name);
120                 add_fname_to_include_list(ff, 0, name);
121               }
122               continue;
123          }
124          add_fname_to_include_list(ff, 0, argv[i]);
125       }
126    }
127    if (inc) {
128       fd = fopen(inc, "r");
129       if (!fd) {
130          printf("Could not open include file: %s\n", inc);
131          exit(1);
132       }
133       while (fgets(name, sizeof(name)-1, fd)) {
134          strip_trailing_junk(name);
135          add_fname_to_include_list(ff, 0, name);
136       }
137       fclose(fd);
138    }
139
140    if (exc) {
141       fd = fopen(exc, "r");
142       if (!fd) {
143          printf("Could not open exclude file: %s\n", exc);
144          exit(1);
145       }
146       while (fgets(name, sizeof(name)-1, fd)) {
147          strip_trailing_junk(name);
148          add_fname_to_exclude_list(ff, name);
149       }
150       fclose(fd);
151    }
152    match_files(jcr, ff, print_file, NULL);
153    term_include_exclude_files(ff);
154    hard_links = term_find_files(ff);
155
156    printf(_(""
157 "Total files    : %d\n"
158 "Max file length: %d\n"
159 "Max path length: %d\n"
160 "Files truncated: %d\n"
161 "Paths truncated: %d\n"
162 "Hard links     : %d\n"),
163      num_files, max_file_len, max_path_len,
164      trunc_fname, trunc_path, hard_links);
165
166   free_jcr(jcr);
167   close_memory_pool();
168   sm_dump(false);
169   exit(0);
170 }
171
172 static int print_file(FF_PKT *ff, void *pkt, bool top_level) 
173 {
174
175    switch (ff->type) {
176    case FT_LNKSAVED:
177       if (debug_level == 1) {
178          printf("%s\n", ff->fname);
179       } else if (debug_level > 1) {
180          printf("Lnka: %s -> %s\n", ff->fname, ff->link);
181       }
182       break;
183    case FT_REGE:
184       if (debug_level == 1) {
185          printf("%s\n", ff->fname);
186       } else if (debug_level > 1) {
187          printf("Empty: %s\n", ff->fname);
188       }
189       count_files(ff);
190       break;
191    case FT_REG:
192       if (debug_level == 1) {
193          printf("%s\n", ff->fname);
194       } else if (debug_level > 1) {
195          printf("Reg: %s\n", ff->fname);
196       }
197       count_files(ff);
198       break;
199    case FT_LNK:
200       if (debug_level == 1) {
201          printf("%s\n", ff->fname);
202       } else if (debug_level > 1) {
203          printf("Lnk: %s -> %s\n", ff->fname, ff->link);
204       }
205       count_files(ff);
206       break;
207    case FT_DIRBEGIN:
208       return 1;
209    case FT_NORECURSE:
210    case FT_NOFSCHG:
211    case FT_INVALIDFS:
212    case FT_DIREND:
213       if (debug_level) {
214          char errmsg[100] = "";
215          if (ff->type == FT_NORECURSE) {
216             bstrncpy(errmsg, "\t[will not descend: recursion turned off]", sizeof(errmsg));
217          } else if (ff->type == FT_NOFSCHG) {
218             bstrncpy(errmsg, "\t[will not descend: file system change not allowed]", sizeof(errmsg));
219          } else if (ff->type == FT_INVALIDFS) {
220             bstrncpy(errmsg, "\t[will not descend: disallowed file system]", sizeof(errmsg));
221          }
222          printf("%s%s%s\n", (debug_level > 1 ? "Dir: " : ""), ff->fname, errmsg);
223       }
224       ff->type = FT_DIREND;
225       count_files(ff);
226       break;
227    case FT_SPEC:
228       if (debug_level == 1) {
229          printf("%s\n", ff->fname);
230       } else if (debug_level > 1) {
231          printf("Spec: %s\n", ff->fname);
232       }
233       count_files(ff);
234       break;
235    case FT_NOACCESS:
236       printf(_("Err: Could not access %s: %s\n"), ff->fname, strerror(errno));
237       break;
238    case FT_NOFOLLOW:
239       printf(_("Err: Could not follow ff->link %s: %s\n"), ff->fname, strerror(errno));
240       break;
241    case FT_NOSTAT:
242       printf(_("Err: Could not stat %s: %s\n"), ff->fname, strerror(errno));
243       break;
244    case FT_NOCHG:
245       printf(_("Skip: File not saved. No change. %s\n"), ff->fname);
246       break;
247    case FT_ISARCH:
248       printf(_("Err: Attempt to backup archive. Not saved. %s\n"), ff->fname);
249       break;
250    case FT_NOOPEN:
251       printf(_("Err: Could not open directory %s: %s\n"), ff->fname, strerror(errno));
252       break;
253    default:
254       printf(_("Err: Unknown file ff->type %d: %s\n"), ff->type, ff->fname);
255       break;
256    }
257    if (attrs) {
258       char attr[200];
259       encode_attribsEx(NULL, attr, ff);
260       if (*attr != 0) {
261          printf("AttrEx=%s\n", attr);
262       }
263 //    set_attribsEx(NULL, ff->fname, NULL, NULL, ff->type, attr);
264    }
265    return 1;
266 }
267
268 static void count_files(FF_PKT *ar)
269 {
270    int fnl, pnl;
271    char *l, *p;
272    char file[MAXSTRING];
273    char spath[MAXSTRING];
274
275    num_files++;
276
277    /* Find path without the filename.
278     * I.e. everything after the last / is a "filename".
279     * OK, maybe it is a directory name, but we treat it like
280     * a filename. If we don't find a / then the whole name
281     * must be a path name (e.g. c:).
282     */
283    for (p=l=ar->fname; *p; p++) {
284       if (*p == '/') {
285          l = p;                       /* set pos of last slash */
286       }
287    }
288    if (*l == '/') {                   /* did we find a slash? */
289       l++;                            /* yes, point to filename */
290    } else {                           /* no, whole thing must be path name */
291       l = p;
292    }
293
294    /* If filename doesn't exist (i.e. root directory), we
295     * simply create a blank name consisting of a single
296     * space. This makes handling zero length filenames
297     * easier.
298     */
299    fnl = p - l;
300    if (fnl > max_file_len) {
301       max_file_len = fnl;
302    }
303    if (fnl > 255) {
304       printf(_("===== Filename truncated to 255 chars: %s\n"), l);
305       fnl = 255;
306       trunc_fname++;
307    }
308    if (fnl > 0) {
309       strncpy(file, l, fnl);          /* copy filename */
310       file[fnl] = 0;
311    } else {
312       file[0] = ' ';                  /* blank filename */
313       file[1] = 0;
314    }
315
316    pnl = l - ar->fname;
317    if (pnl > max_path_len) {
318       max_path_len = pnl;
319    }
320    if (pnl > 255) {
321       printf(_("========== Path name truncated to 255 chars: %s\n"), ar->fname);
322       pnl = 255;
323       trunc_path++;
324    }
325    strncpy(spath, ar->fname, pnl);
326    spath[pnl] = 0;
327    if (pnl == 0) {
328       spath[0] = ' ';
329       spath[1] = 0;
330       printf(_("========== Path length is zero. File=%s\n"), ar->fname);
331    }
332    if (debug_level >= 10) {
333       printf("Path: %s\n", spath);
334       printf("File: %s\n", file);
335    }
336
337 }
338
339 bool python_set_prog(JCR*, char const*) { return false; }