]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/tools/testfind.c
Get FD Python running -- design Python backup interface.
[bacula/bacula] / bacula / src / tools / testfind.c
1 /*
2  * Test program for find files
3  */
4
5 /*
6    Copyright (C) 2000-2003 Kern Sibbald and John Walker
7
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.
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
19    License along with this program; if not, write to the Free
20    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21    MA 02111-1307, USA.
22
23  */
24
25 #include "bacula.h"
26 #include "findlib/find.h"
27
28
29 #if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
30 int win32_client = 1;
31 #else
32 int win32_client = 0;
33 #endif
34
35 /* Dummy functions */
36 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
37 int generate_job_event(JCR *jcr, const char *event) { return 1; }
38
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;
45 static int attrs = 0;
46
47 static JCR *jcr;
48
49 static int print_file(FF_PKT *ff, void *pkt, bool);
50 static void count_files(FF_PKT *ff);
51
52 static void usage()
53 {
54    fprintf(stderr, _(
55 "\n"
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"
63 "\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"
70 "\n"));
71
72    exit(1);
73 }
74
75
76 int
77 main (int argc, char *const *argv)
78 {
79    FF_PKT *ff;
80    char name[1000];
81    int i, ch, hard_links;
82    char *inc = NULL;
83    char *exc = NULL;
84    FILE *fd;
85
86    while ((ch = getopt(argc, argv, "ad:e:i:?")) != -1) {
87       switch (ch) {
88          case 'a':                    /* print extended attributes *debug* */
89             attrs = 1;
90             break;
91
92          case 'd':                    /* set debug level */
93             debug_level = atoi(optarg);
94             if (debug_level <= 0) {
95                debug_level = 1;
96             }
97             break;
98
99          case 'e':                    /* exclude patterns */
100             exc = optarg;
101             break;
102
103          case 'i':                    /* include patterns */
104             inc = optarg;
105             break;
106
107          case '?':
108          default:
109             usage();
110
111       }
112    }
113    argc -= optind;
114    argv += optind;
115
116    jcr = new_jcr(sizeof(JCR), NULL);
117
118    ff = init_find_files();
119    if (argc == 0 && !inc) {
120       add_fname_to_include_list(ff, 0, "/"); /* default to / */
121    } else {
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);
127               }
128               continue;
129          }
130          add_fname_to_include_list(ff, 0, argv[i]);
131       }
132    }
133    if (inc) {
134       fd = fopen(inc, "r");
135       if (!fd) {
136          printf("Could not open include file: %s\n", inc);
137          exit(1);
138       }
139       while (fgets(name, sizeof(name)-1, fd)) {
140          strip_trailing_junk(name);
141          add_fname_to_include_list(ff, 0, name);
142       }
143       fclose(fd);
144    }
145
146    if (exc) {
147       fd = fopen(exc, "r");
148       if (!fd) {
149          printf("Could not open exclude file: %s\n", exc);
150          exit(1);
151       }
152       while (fgets(name, sizeof(name)-1, fd)) {
153          strip_trailing_junk(name);
154          add_fname_to_exclude_list(ff, name);
155       }
156       fclose(fd);
157    }
158    match_files(jcr, ff, print_file, NULL);
159    term_include_exclude_files(ff);
160    hard_links = term_find_files(ff);
161
162    printf(_(""
163 "Total files    : %d\n"
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);
171
172   free_jcr(jcr);
173   close_memory_pool();
174   sm_dump(false);
175   exit(0);
176 }
177
178 static int print_file(FF_PKT *ff, void *pkt, bool top_level) 
179 {
180
181    switch (ff->type) {
182    case FT_LNKSAVED:
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);
187       }
188       break;
189    case FT_REGE:
190       if (debug_level == 1) {
191          printf("%s\n", ff->fname);
192       } else if (debug_level > 1) {
193          printf("Empty: %s\n", ff->fname);
194       }
195       count_files(ff);
196       break;
197    case FT_REG:
198       if (debug_level == 1) {
199          printf("%s\n", ff->fname);
200       } else if (debug_level > 1) {
201          printf("Reg: %s\n", ff->fname);
202       }
203       count_files(ff);
204       break;
205    case FT_LNK:
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);
210       }
211       count_files(ff);
212       break;
213    case FT_DIRBEGIN:
214       return 1;
215    case FT_NORECURSE:
216    case FT_NOFSCHG:
217    case FT_INVALIDFS:
218    case FT_DIREND:
219       if (debug_level) {
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));
227          }
228          printf("%s%s%s\n", (debug_level > 1 ? "Dir: " : ""), ff->fname, errmsg);
229       }
230       ff->type = FT_DIREND;
231       count_files(ff);
232       break;
233    case FT_SPEC:
234       if (debug_level == 1) {
235          printf("%s\n", ff->fname);
236       } else if (debug_level > 1) {
237          printf("Spec: %s\n", ff->fname);
238       }
239       count_files(ff);
240       break;
241    case FT_NOACCESS:
242       printf(_("Err: Could not access %s: %s\n"), ff->fname, strerror(errno));
243       break;
244    case FT_NOFOLLOW:
245       printf(_("Err: Could not follow ff->link %s: %s\n"), ff->fname, strerror(errno));
246       break;
247    case FT_NOSTAT:
248       printf(_("Err: Could not stat %s: %s\n"), ff->fname, strerror(errno));
249       break;
250    case FT_NOCHG:
251       printf(_("Skip: File not saved. No change. %s\n"), ff->fname);
252       break;
253    case FT_ISARCH:
254       printf(_("Err: Attempt to backup archive. Not saved. %s\n"), ff->fname);
255       break;
256    case FT_NOOPEN:
257       printf(_("Err: Could not open directory %s: %s\n"), ff->fname, strerror(errno));
258       break;
259    default:
260       printf(_("Err: Unknown file ff->type %d: %s\n"), ff->type, ff->fname);
261       break;
262    }
263    if (attrs) {
264       char attr[200];
265       encode_attribsEx(NULL, attr, ff);
266       if (*attr != 0) {
267          printf("AttrEx=%s\n", attr);
268       }
269 //    set_attribsEx(NULL, ff->fname, NULL, NULL, ff->type, attr);
270    }
271    return 1;
272 }
273
274 static void count_files(FF_PKT *ar)
275 {
276    int fnl, pnl;
277    char *l, *p;
278    char file[MAXSTRING];
279    char spath[MAXSTRING];
280
281    num_files++;
282
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:).
288     */
289    for (p=l=ar->fname; *p; p++) {
290       if (*p == '/') {
291          l = p;                       /* set pos of last slash */
292       }
293    }
294    if (*l == '/') {                   /* did we find a slash? */
295       l++;                            /* yes, point to filename */
296    } else {                           /* no, whole thing must be path name */
297       l = p;
298    }
299
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
303     * easier.
304     */
305    fnl = p - l;
306    if (fnl > max_file_len) {
307       max_file_len = fnl;
308    }
309    if (fnl > 255) {
310       printf(_("===== Filename truncated to 255 chars: %s\n"), l);
311       fnl = 255;
312       trunc_fname++;
313    }
314    if (fnl > 0) {
315       strncpy(file, l, fnl);          /* copy filename */
316       file[fnl] = 0;
317    } else {
318       file[0] = ' ';                  /* blank filename */
319       file[1] = 0;
320    }
321
322    pnl = l - ar->fname;
323    if (pnl > max_path_len) {
324       max_path_len = pnl;
325    }
326    if (pnl > 255) {
327       printf(_("========== Path name truncated to 255 chars: %s\n"), ar->fname);
328       pnl = 255;
329       trunc_path++;
330    }
331    strncpy(spath, ar->fname, pnl);
332    spath[pnl] = 0;
333    if (pnl == 0) {
334       spath[0] = ' ';
335       spath[1] = 0;
336       printf(_("========== Path length is zero. File=%s\n"), ar->fname);
337    }
338    if (debug_level >= 10) {
339       printf("Path: %s\n", spath);
340       printf("File: %s\n", file);
341    }
342
343 }
344
345 bool python_set_prog(JCR*, char const*) { return false; }