]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/tools/testls.c
Backport from Bacula Enterprise
[bacula/bacula] / bacula / src / tools / testls.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2015 Kern Sibbald
5    Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
6
7    The original author of Bacula is Kern Sibbald, with contributions
8    from many others, a complete list can be found in the file AUTHORS.
9
10    You may use this file and others of this release according to the
11    license defined in the LICENSE file, which includes the Affero General
12    Public License, v3.0 ("AGPLv3") and some additional permissions and
13    terms pursuant to its AGPLv3 Section 7.
14
15    This notice must be preserved when any source code is 
16    conveyed and/or propagated.
17
18    Bacula(R) is a registered trademark of Kern Sibbald.
19 */
20 /*
21  * Test program for listing files during regression testing
22  *   Links have their permissions and time bashed since they cannot
23  *   be set by Bacula.
24  *
25  *  Kern Sibbald, MM
26  *
27  */
28
29 #include "bacula.h"
30 #include "findlib/find.h"
31
32 /* Dummy functions */
33 int generate_job_event(JCR *jcr, const char *event) { return 1; }
34 void generate_plugin_event(JCR *jcr, bEventType eventType, void *value) { }
35
36
37 /* Global variables */
38 int attrs = 0;
39
40 static JCR *jcr;
41 static int num_files = 0;
42
43 static int print_file(JCR *jcr, FF_PKT *ff, bool);
44 static void print_ls_output(char *fname, char *link, int type, struct stat *statp);
45 static int count_files(JCR *jcr, FF_PKT *ff, bool top_level);
46
47 static void usage()
48 {
49    fprintf(stderr, _(
50 "\n"
51 "Usage: testls [-d debug_level] [-] [pattern1 ...]\n"
52 "       -a          print extended attributes (Win32 debug)\n"
53 "       -d <nn>     set debug level to <nn>\n"
54 "       -dt         print timestamp in debug output\n"
55 "       -e          specify file of exclude patterns\n"
56 "       -i          specify file of include patterns\n"
57 "       -q          quiet, don't print filenames (debug)\n"
58 "       -           read pattern(s) from stdin\n"
59 "       -?          print this message.\n"
60 "\n"
61 "Patterns are file inclusion -- normally directories.\n"
62 "Debug level >= 1 prints each file found.\n"
63 "Debug level >= 10 prints path/file for catalog.\n"
64 "Errors always printed.\n"
65 "Files/paths truncated is number with len > 255.\n"
66 "Truncation is only in catalog.\n"
67 "\n"));
68
69    exit(1);
70 }
71
72
73 int main(int argc, char *const *argv)
74 {
75    FF_PKT *ff;
76    char name[1000];
77    bool quiet = false;
78    int i, ch;
79    char *inc = NULL;
80    char *exc = NULL;
81    FILE *fd;
82
83    setlocale(LC_ALL, "");
84    bindtextdomain("bacula", LOCALEDIR);
85    textdomain("bacula");
86    lmgr_init_thread();
87
88    while ((ch = getopt(argc, argv, "ad:e:i:q?")) != -1) {
89       switch (ch) {
90       case 'a':                       /* print extended attributes *debug* */
91          attrs = 1;
92          break;
93
94       case 'd':                       /* set debug level */
95          if (*optarg == 't') {
96             dbg_timestamp = true;
97          } else {
98             debug_level = atoi(optarg);
99             if (debug_level <= 0) {
100                debug_level = 1;
101             }
102          }
103          break;
104
105       case 'e':                       /* exclude patterns */
106          exc = optarg;
107          break;
108
109       case 'i':                       /* include patterns */
110          inc = optarg;
111          break;
112
113       case 'q':
114          quiet = true;
115          break;
116
117       case '?':
118       default:
119          usage();
120
121       }
122    }
123    argc -= optind;
124    argv += optind;
125
126    jcr = new_jcr(sizeof(JCR), NULL);
127
128    ff = init_find_files();
129    if (argc == 0 && !inc) {
130       add_fname_to_include_list(ff, 0, "/"); /* default to / */
131    } else {
132       for (i=0; i < argc; i++) {
133          if (strcmp(argv[i], "-") == 0) {
134              while (fgets(name, sizeof(name)-1, stdin)) {
135                 strip_trailing_junk(name);
136                 add_fname_to_include_list(ff, 0, name);
137               }
138               continue;
139          }
140          add_fname_to_include_list(ff, 0, argv[i]);
141       }
142    }
143    if (inc) {
144       fd = fopen(inc, "rb");
145       if (!fd) {
146          printf(_("Could not open include file: %s\n"), inc);
147          exit(1);
148       }
149       while (fgets(name, sizeof(name)-1, fd)) {
150          strip_trailing_junk(name);
151          add_fname_to_include_list(ff, 0, name);
152       }
153       fclose(fd);
154    }
155
156    if (exc) {
157       fd = fopen(exc, "rb");
158       if (!fd) {
159          printf(_("Could not open exclude file: %s\n"), exc);
160          exit(1);
161       }
162       while (fgets(name, sizeof(name)-1, fd)) {
163          strip_trailing_junk(name);
164          add_fname_to_exclude_list(ff, name);
165       }
166       fclose(fd);
167    }
168    if (quiet) {
169       match_files(jcr, ff, count_files);
170    } else {
171       match_files(jcr, ff, print_file);
172    }
173    printf(_("Files seen = %d\n"), num_files);
174    term_include_exclude_files(ff);
175    term_find_files(ff);
176
177    free_jcr(jcr);
178    term_last_jobs_list();             /* free jcr chain */
179    close_memory_pool();
180    lmgr_cleanup_main();
181    sm_dump(false);
182    exit(0);
183 }
184
185 static int count_files(JCR *jcr, FF_PKT *ff, bool top_level)
186 {
187    num_files++;
188    return 1;
189 }
190
191 static int print_file(JCR *jcr, FF_PKT *ff, bool top_level) 
192 {
193
194    switch (ff->type) {
195    case FT_LNKSAVED:
196    case FT_REGE:
197    case FT_REG:
198    case FT_LNK:
199    case FT_DIREND:
200    case FT_SPEC:
201       print_ls_output(ff->fname, ff->link, ff->type, &ff->statp);
202       break;
203    case FT_DIRBEGIN:
204       break;
205    case FT_NOACCESS:
206       printf(_("Err: Could not access %s: %s\n"), ff->fname, strerror(errno));
207       break;
208    case FT_NOFOLLOW:
209       printf(_("Err: Could not follow ff->link %s: %s\n"), ff->fname, strerror(errno));
210       break;
211    case FT_NOSTAT:
212       printf(_("Err: Could not stat %s: %s\n"), ff->fname, strerror(errno));
213       break;
214    case FT_NOCHG:
215       printf(_("Skip: File not saved. No change. %s\n"), ff->fname);
216       break;
217    case FT_ISARCH:
218       printf(_("Err: Attempt to backup archive. Not saved. %s\n"), ff->fname);
219       break;
220    case FT_NORECURSE:
221       printf(_("Recursion turned off. Directory not entered. %s\n"), ff->fname);
222       break;
223    case FT_NOFSCHG:
224       printf(_("Skip: File system change prohibited. Directory not entered. %s\n"), ff->fname);
225       break;
226    case FT_NOOPEN:
227       printf(_("Err: Could not open directory %s: %s\n"), ff->fname, strerror(errno));
228       break;
229    default:
230       printf(_("Err: Unknown file ff->type %d: %s\n"), ff->type, ff->fname);
231       break;
232    }
233    num_files++;
234    return 1;
235 }
236
237 static void print_ls_output(char *fname, char *link, int type, struct stat *statp)
238 {
239    char buf[2000];
240    char ec1[30];
241    char *p, *f;
242    int n;
243
244    if (type == FT_LNK) {
245       statp->st_mtime = 0;
246       statp->st_mode |= 0777;
247    }
248    p = encode_mode(statp->st_mode, buf);
249    n = sprintf(p, " %2d ", (uint32_t)statp->st_nlink);
250    p += n;
251    n = sprintf(p, "%-4d %-4d", (int)statp->st_uid, (int)statp->st_gid);
252    p += n;
253    n = sprintf(p, "%10.10s ", edit_uint64(statp->st_size, ec1));
254    p += n;
255    if (S_ISCHR(statp->st_mode) || S_ISBLK(statp->st_mode)) {
256       n = sprintf(p, "%4x ", (int)statp->st_rdev);
257    } else {
258       n = sprintf(p, "     ");
259    }
260    p += n;
261    p = encode_time(statp->st_mtime, p);
262    *p++ = ' ';
263    /* Copy file name */
264    for (f=fname; *f && (p-buf) < (int)sizeof(buf); )
265       *p++ = *f++;
266    if (type == FT_LNK) {
267       *p++ = '-';
268       *p++ = '>';
269       *p++ = ' ';
270       /* Copy link name */
271       for (f=link; *f && (p-buf) < (int)sizeof(buf); )
272          *p++ = *f++;
273    }
274    *p++ = '\n';
275    *p = 0;
276    fputs(buf, stdout);
277 }
278
279 bool python_set_prog(JCR*, char const*) { return false; }