]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/tools/testfind.c
- Change cats/sql.c to elimate %-*s format, which I think is turned
[bacula/bacula] / bacula / src / tools / testfind.c
1 /*
2  * Test program for find files
3  */
4 /*
5    Copyright (C) 2000-2006 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_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    setlocale(LC_ALL, "");
81    bindtextdomain("bacula", LOCALEDIR);
82    textdomain("bacula");
83
84    while ((ch = getopt(argc, argv, "ad:e:i:?")) != -1) {
85       switch (ch) {
86          case 'a':                    /* print extended attributes *debug* */
87             attrs = 1;
88             break;
89
90          case 'd':                    /* set debug level */
91             debug_level = atoi(optarg);
92             if (debug_level <= 0) {
93                debug_level = 1;
94             }
95             break;
96
97          case 'e':                    /* exclude patterns */
98             exc = optarg;
99             break;
100
101          case 'i':                    /* include patterns */
102             inc = optarg;
103             break;
104
105          case '?':
106          default:
107             usage();
108
109       }
110    }
111    argc -= optind;
112    argv += optind;
113
114    jcr = new_jcr(sizeof(JCR), NULL);
115
116    ff = init_find_files();
117    if (argc == 0 && !inc) {
118       add_fname_to_include_list(ff, 0, "/"); /* default to / */
119    } else {
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);
125               }
126               continue;
127          }
128          add_fname_to_include_list(ff, 0, argv[i]);
129       }
130    }
131    if (inc) {
132       fd = fopen(inc, "r");
133       if (!fd) {
134          printf(_("Could not open include file: %s\n"), inc);
135          exit(1);
136       }
137       while (fgets(name, sizeof(name)-1, fd)) {
138          strip_trailing_junk(name);
139          add_fname_to_include_list(ff, 0, name);
140       }
141       fclose(fd);
142    }
143
144    if (exc) {
145       fd = fopen(exc, "r");
146       if (!fd) {
147          printf(_("Could not open exclude file: %s\n"), exc);
148          exit(1);
149       }
150       while (fgets(name, sizeof(name)-1, fd)) {
151          strip_trailing_junk(name);
152          add_fname_to_exclude_list(ff, name);
153       }
154       fclose(fd);
155    }
156    match_files(jcr, ff, print_file, NULL);
157    term_include_exclude_files(ff);
158    hard_links = term_find_files(ff);
159
160    printf(_(""
161 "Total files    : %d\n"
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);
169
170   free_jcr(jcr);
171   close_memory_pool();
172   sm_dump(false);
173   exit(0);
174 }
175
176 static int print_file(FF_PKT *ff, void *pkt, bool top_level) 
177 {
178
179    switch (ff->type) {
180    case FT_LNKSAVED:
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);
185       }
186       break;
187    case FT_REGE:
188       if (debug_level == 1) {
189          printf("%s\n", ff->fname);
190       } else if (debug_level > 1) {
191          printf("Empty: %s\n", ff->fname);
192       }
193       count_files(ff);
194       break;
195    case FT_REG:
196       if (debug_level == 1) {
197          printf("%s\n", ff->fname);
198       } else if (debug_level > 1) {
199          printf(_("Reg: %s\n"), ff->fname);
200       }
201       count_files(ff);
202       break;
203    case FT_LNK:
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);
208       }
209       count_files(ff);
210       break;
211    case FT_DIRBEGIN:
212       return 1;
213    case FT_NORECURSE:
214    case FT_NOFSCHG:
215    case FT_INVALIDFS:
216    case FT_DIREND:
217       if (debug_level) {
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));
225          }
226          printf("%s%s%s\n", (debug_level > 1 ? "Dir: " : ""), ff->fname, errmsg);
227       }
228       ff->type = FT_DIREND;
229       count_files(ff);
230       break;
231    case FT_SPEC:
232       if (debug_level == 1) {
233          printf("%s\n", ff->fname);
234       } else if (debug_level > 1) {
235          printf("Spec: %s\n", ff->fname);
236       }
237       count_files(ff);
238       break;
239    case FT_NOACCESS:
240       printf(_("Err: Could not access %s: %s\n"), ff->fname, strerror(errno));
241       break;
242    case FT_NOFOLLOW:
243       printf(_("Err: Could not follow ff->link %s: %s\n"), ff->fname, strerror(errno));
244       break;
245    case FT_NOSTAT:
246       printf(_("Err: Could not stat %s: %s\n"), ff->fname, strerror(errno));
247       break;
248    case FT_NOCHG:
249       printf(_("Skip: File not saved. No change. %s\n"), ff->fname);
250       break;
251    case FT_ISARCH:
252       printf(_("Err: Attempt to backup archive. Not saved. %s\n"), ff->fname);
253       break;
254    case FT_NOOPEN:
255       printf(_("Err: Could not open directory %s: %s\n"), ff->fname, strerror(errno));
256       break;
257    default:
258       printf(_("Err: Unknown file ff->type %d: %s\n"), ff->type, ff->fname);
259       break;
260    }
261    if (attrs) {
262       char attr[200];
263       encode_attribsEx(NULL, attr, ff);
264       if (*attr != 0) {
265          printf("AttrEx=%s\n", attr);
266       }
267 //    set_attribsEx(NULL, ff->fname, NULL, NULL, ff->type, attr);
268    }
269    return 1;
270 }
271
272 static void count_files(FF_PKT *ar)
273 {
274    int fnl, pnl;
275    char *l, *p;
276    char file[MAXSTRING];
277    char spath[MAXSTRING];
278
279    num_files++;
280
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:).
286     */
287    for (p=l=ar->fname; *p; p++) {
288       if (*p == '/') {
289          l = p;                       /* set pos of last slash */
290       }
291    }
292    if (*l == '/') {                   /* did we find a slash? */
293       l++;                            /* yes, point to filename */
294    } else {                           /* no, whole thing must be path name */
295       l = p;
296    }
297
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
301     * easier.
302     */
303    fnl = p - l;
304    if (fnl > max_file_len) {
305       max_file_len = fnl;
306    }
307    if (fnl > 255) {
308       printf(_("===== Filename truncated to 255 chars: %s\n"), l);
309       fnl = 255;
310       trunc_fname++;
311    }
312    if (fnl > 0) {
313       strncpy(file, l, fnl);          /* copy filename */
314       file[fnl] = 0;
315    } else {
316       file[0] = ' ';                  /* blank filename */
317       file[1] = 0;
318    }
319
320    pnl = l - ar->fname;
321    if (pnl > max_path_len) {
322       max_path_len = pnl;
323    }
324    if (pnl > 255) {
325       printf(_("========== Path name truncated to 255 chars: %s\n"), ar->fname);
326       pnl = 255;
327       trunc_path++;
328    }
329    strncpy(spath, ar->fname, pnl);
330    spath[pnl] = 0;
331    if (pnl == 0) {
332       spath[0] = ' ';
333       spath[1] = 0;
334       printf(_("========== Path length is zero. File=%s\n"), ar->fname);
335    }
336    if (debug_level >= 10) {
337       printf(_("Path: %s\n"), spath);
338       printf(_("File: %s\n"), file);
339    }
340
341 }
342
343 bool python_set_prog(JCR*, char const*) { return false; }