]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/job.c
Implement level=Data to the Verify job
[bacula/bacula] / bacula / src / filed / job.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  *  Bacula File Daemon Job processing
22  *
23  *    Written by Kern Sibbald, October MM
24  *
25  */
26
27 #include "bacula.h"
28 #include "filed.h"
29 #include "ch.h"
30
31 /* Globals */
32 bool win32decomp = false;
33 bool no_win32_write_errors = false;
34
35 /* Static variables */
36 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
37
38
39 const bool have_win32 = false;
40
41 #ifdef HAVE_ACL
42 const bool have_acl = true; 
43 #else 
44 const bool have_acl = false; 
45 #endif 
46
47 #if HAVE_XATTR
48 const bool have_xattr = true; 
49 #else 
50 const bool have_xattr = false; 
51 #endif 
52  
53 extern CLIENT *me;                    /* our client resource */
54
55 /* Imported functions */
56 extern int status_cmd(JCR *jcr);
57 extern int qstatus_cmd(JCR *jcr);
58 extern int accurate_cmd(JCR *jcr);
59
60 /* Forward referenced functions */
61 static int backup_cmd(JCR *jcr);
62 static int component_cmd(JCR *jcr);
63 static int cancel_cmd(JCR *jcr);
64 static int setdebug_cmd(JCR *jcr);
65 static int setbandwidth_cmd(JCR *jcr);
66 static int estimate_cmd(JCR *jcr);
67 static int hello_cmd(JCR *jcr);
68 static int job_cmd(JCR *jcr);
69 static int fileset_cmd(JCR *jcr);
70 static int level_cmd(JCR *jcr);
71 static int verify_cmd(JCR *jcr);
72 static int restore_cmd(JCR *jcr);
73 static int end_restore_cmd(JCR *jcr);
74 static int storage_cmd(JCR *jcr);
75 static int session_cmd(JCR *jcr);
76 static int response(JCR *jcr, BSOCK *sd, char *resp, const char *cmd);
77 static void filed_free_jcr(JCR *jcr);
78 static int open_sd_read_session(JCR *jcr);
79 static int runscript_cmd(JCR *jcr);
80 static int runbefore_cmd(JCR *jcr);
81 static int runafter_cmd(JCR *jcr);
82 static int runbeforenow_cmd(JCR *jcr);
83 static int restore_object_cmd(JCR *jcr);
84 static int set_options(findFOPTS *fo, const char *opts);
85 static void set_storage_auth_key(JCR *jcr, char *key);
86 static int sm_dump_cmd(JCR *jcr);
87 #ifdef DEVELOPER
88 static int exit_cmd(JCR *jcr);
89 #endif
90
91 /* Exported functions */
92
93
94 /*
95  * The following are the recognized commands from the Director.
96  */
97 struct s_cmds cmds[] = {
98    {"backup",       backup_cmd,    0},
99    {"cancel",       cancel_cmd,    0},
100    {"setdebug=",    setdebug_cmd,  0},
101    {"setbandwidth=",setbandwidth_cmd, 0},
102    {"snapshot",     snapshot_cmd,  0},
103    {"estimate",     estimate_cmd,  0},
104    {"Hello",        hello_cmd,     1},
105    {"fileset",      fileset_cmd,   0},
106    {"JobId=",       job_cmd,       0},
107    {"level = ",     level_cmd,     0},
108    {"restore ",     restore_cmd,   0},
109    {"endrestore",   end_restore_cmd, 0},
110    {"session",      session_cmd,   0},
111    {"status",       status_cmd,    1},
112    {".status",      qstatus_cmd,   1},
113    {"storage ",     storage_cmd,   0},
114    {"verify",       verify_cmd,    0},
115    {"component",    component_cmd, 0},
116    {"RunBeforeNow", runbeforenow_cmd, 0},
117    {"RunBeforeJob", runbefore_cmd, 0},
118    {"RunAfterJob",  runafter_cmd,  0},
119    {"Run",          runscript_cmd, 0},
120    {"accurate",     accurate_cmd,  0},
121    {"restoreobject", restore_object_cmd, 0},
122    {"sm_dump",      sm_dump_cmd, 0},
123    {"stop",         cancel_cmd,    0},
124 #ifdef DEVELOPER
125    {"exit",         exit_cmd, 0},
126 #endif
127    {NULL,       NULL}                  /* list terminator */
128 };
129
130 /* Commands received from director that need scanning */
131 static char jobcmd[]      = "JobId=%d Job=%127s SDid=%d SDtime=%d Authorization=%100s";
132 static char storaddr[]    = "storage address=%s port=%d ssl=%d Authorization=%100s";
133 static char storaddr_v1[] = "storage address=%s port=%d ssl=%d";
134 static char sessioncmd[]  = "session %127s %ld %ld %ld %ld %ld %ld\n";
135
136 static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n";
137 static char restorefcmd1[] = "restore files=%d replace=%c prelinks=%d where=\n";
138
139 /* The following restore commands may have a big where=/regexwhere= parameter
140  * the bsscanf is limiting the default %s to 1000c. To allow more than 1000 bytes,
141  * we can specify %xxxxs where xxxx is the size expected in bytes.
142  *
143  * So, the code will add %s\n to the end of the following restore commands
144  */
145 static char restorecmd[]  = "restore replace=%c prelinks=%d where=";
146 static char restorecmdR[] = "restore replace=%c prelinks=%d regexwhere=";
147 static char restorefcmd[]  = "restore files=%d replace=%c prelinks=%d where=";
148 static char restorefcmdR[] = "restore files=%d replace=%c prelinks=%d regexwhere=";
149
150 static char restoreobjcmd[]  = "restoreobject JobId=%u %d,%d,%d,%d,%d,%d,%s";
151 static char restoreobjcmd1[] = "restoreobject JobId=%u %d,%d,%d,%d,%d,%d\n";
152 static char endrestoreobjectcmd[] = "restoreobject end\n";
153 static char verifycmd[]   = "verify level=%30s";
154 static char estimatecmd[] = "estimate listing=%d";
155 static char runbefore[]   = "RunBeforeJob %s";
156 static char runafter[]    = "RunAfterJob %s";
157 static char runscript[]   = "Run OnSuccess=%d OnFailure=%d AbortOnError=%d When=%d Command=%s";
158 static char setbandwidth[]= "setbandwidth=%lld Job=%127s";
159
160 /* Responses sent to Director */
161 static char errmsg[]      = "2999 Invalid command\n";
162 static char no_auth[]     = "2998 No Authorization\n";
163 static char invalid_cmd[] = "2997 Invalid command for a Director with Monitor directive enabled.\n";
164 static char OKBandwidth[] = "2000 OK Bandwidth\n";
165 static char OKinc[]       = "2000 OK include\n";
166 static char OKest[]       = "2000 OK estimate files=%s bytes=%s\n";
167 static char OKlevel[]     = "2000 OK level\n";
168 static char OKbackup[]    = "2000 OK backup\n";
169 static char OKverify[]    = "2000 OK verify\n";
170 static char OKrestore[]   = "2000 OK restore\n";
171 static char OKsession[]   = "2000 OK session\n";
172 static char OKstore[]     = "2000 OK storage\n";
173 static char OKstoreend[]  = "2000 OK storage end\n";
174 static char OKjob[]       = "2000 OK Job %s (%s) %s,%s,%s";
175 static char OKsetdebug[]  = "2000 OK setdebug=%ld trace=%ld hangup=%ld"
176                             " blowup=%ld options=%s tags=%s\n";
177 static char BADjob[]      = "2901 Bad Job\n";
178 static char EndJob[]      = "2800 End Job TermCode=%d JobFiles=%d ReadBytes=%lld"
179                             " JobBytes=%lld Errors=%d VSS=%d Encrypt=%d"
180                             " CommBytes=0 CompressCommBytes=0\n";
181 static char OKRunBefore[] = "2000 OK RunBefore\n";
182 static char OKRunBeforeNow[] = "2000 OK RunBeforeNow\n";
183 static char OKRunAfter[]  = "2000 OK RunAfter\n";
184 static char OKRunScript[] = "2000 OK RunScript\n";
185 static char BADcmd[]      = "2902 Bad %s\n";
186 static char OKRestoreObject[] = "2000 OK ObjectRestored\n";
187 static char OKComponentInfo[] = "2000 OK ComponentInfo\n";
188
189
190 /* Responses received from Storage Daemon */
191 static char OK_end[]       = "3000 OK end\n";
192 static char OK_close[]     = "3000 OK close Status = %d\n";
193 static char OK_open[]      = "3000 OK open ticket = %d\n";
194 static char OK_data[]      = "3000 OK data\n";
195 static char OK_append[]    = "3000 OK append data\n";
196
197
198 /* Commands sent to Storage Daemon */
199 static char append_open[]  = "append open session\n";
200 static char append_data[]  = "append data %d\n";
201 static char append_end[]   = "append end session %d\n";
202 static char append_close[] = "append close session %d\n";
203 static char read_open[]    = "read open session = %s %ld %ld %ld %ld %ld %ld\n";
204 static char read_data[]    = "read data %d\n";
205 static char read_close[]   = "read close session %d\n";
206 static char read_ctrl[]    = "read control %d\n";
207
208 /*
209  * Accept requests from a Director
210  *
211  * NOTE! We are running as a separate thread
212  *
213  * Send output one line
214  * at a time followed by a zero length transmission.
215  *
216  * Return when the connection is terminated or there
217  * is an error.
218  *
219  * Basic task here is:
220  *   Authenticate Director (during Hello command).
221  *   Accept commands one at a time from the Director
222  *     and execute them.
223  *
224  * Concerning ClientRunBefore/After, the sequence of events
225  * is rather critical. If they are not done in the right
226  * order one can easily get FD->SD timeouts if the script
227  * runs a long time.
228  *
229  * The current sequence of events is:
230  *  1. Dir starts job with FD
231  *  2. Dir connects to SD
232  *  3. Dir connects to FD
233  *  4. FD connects to SD
234  *  5. FD gets/runs ClientRunBeforeJob and sends ClientRunAfterJob
235  *  6. Dir sends include/exclude
236  *  7. FD sends the file data to SD
237  *  8. SD/FD disconnects while the SD despools data and attributes (optional)
238  *  9. FD runs ClientRunAfterJob
239  */
240
241 static void *handle_director_request(BSOCK *dir)
242 {
243    int i;
244    bool found, quit;
245    bool first = true;
246    JCR *jcr;
247    const char jobname[12] = "*Director*";
248
249    prevent_os_suspensions();   /* do not suspend during backup/restore */
250    jcr = new_jcr(sizeof(JCR), filed_free_jcr); /* create JCR */
251    jcr->sd_calls_client_bsock = NULL;
252    jcr->sd_calls_client = false;
253    jcr->dir_bsock = dir;
254    jcr->ff = init_find_files();
255    jcr->start_time = time(NULL);
256    jcr->RunScripts = New(alist(10, not_owned_by_alist));
257    jcr->last_fname = get_pool_memory(PM_FNAME);
258    jcr->last_fname[0] = 0;
259    jcr->client_name = get_memory(strlen(my_name) + 1);
260    pm_strcpy(jcr->client_name, my_name);
261    bstrncpy(jcr->Job, jobname, sizeof(jobname));  /* dummy */
262    jcr->crypto.pki_sign = me->pki_sign;
263    jcr->crypto.pki_encrypt = me->pki_encrypt;
264    jcr->crypto.pki_keypair = me->pki_keypair;
265    jcr->crypto.pki_signers = me->pki_signers;
266    jcr->crypto.pki_recipients = me->pki_recipients;
267
268    dir->set_jcr(jcr);
269    /* Initialize SD start condition variable */
270    int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
271    if (errstat != 0) {
272       berrno be;
273       Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat));
274       goto bail_out;
275    }
276    enable_backup_privileges(NULL, 1 /* ignore_errors */);
277
278    for (quit=false; !quit;) {
279       if (!first) {      /* first call the read is done */
280          /* Read command */
281          if (dir->recv() < 0) {
282             break;               /* connection terminated */
283          }
284       }
285       if (dir->msglen == 0) {    /* Bad connection */
286          break;
287       }
288       first = false;
289       dir->msg[dir->msglen] = 0;
290       Dmsg1(100, "<dird: %s", dir->msg);
291       found = false;
292       for (i=0; cmds[i].cmd; i++) {
293          if (strncmp(cmds[i].cmd, dir->msg, strlen(cmds[i].cmd)) == 0) {
294             found = true;         /* indicate command found */
295             if (!jcr->authenticated && cmds[i].func != hello_cmd) {
296                dir->fsend(no_auth);
297                dir->signal(BNET_EOD);
298                break;
299             }
300             if ((jcr->authenticated) && (!cmds[i].monitoraccess) && (jcr->director->monitor)) {
301                Dmsg1(100, "Command \"%s\" is invalid.\n", cmds[i].cmd);
302                dir->fsend(invalid_cmd);
303                dir->signal(BNET_EOD);
304                break;
305             }
306             if ((me->disabled_cmds_array && me->disabled_cmds_array[i]) ||
307                 (jcr->director && jcr->director->disabled_cmds_array &&
308                  jcr->director->disabled_cmds_array[i])) {
309                 Jmsg(jcr, M_FATAL, 0, _("Command: \"%s\" is disabled.\n"), cmds[i].cmd);
310                 quit = true;
311                 break;
312             }
313             Dmsg1(100, "Executing Dir %s command.\n", dir->msg);
314             if (!cmds[i].func(jcr)) {         /* do command */
315                quit = true;         /* error or fully terminated, get out */
316                Dmsg1(100, "Quit command loop. Canceled=%d\n", job_canceled(jcr));
317             }
318             break;
319          }
320       }
321       if (!found) {              /* command not found */
322          dir->fsend(errmsg);
323          quit = true;
324          break;
325       }
326    }
327
328    /* Inform Storage daemon that we are done */
329    if (jcr->store_bsock) {
330       jcr->store_bsock->signal(BNET_TERMINATE);
331    }
332
333    /* Run the after job */
334    run_scripts(jcr, jcr->RunScripts, "ClientAfterJob");
335
336    if (jcr->JobId) {            /* send EndJob if running a job */
337       uint32_t vss, encrypt;
338       /* Send termination status back to Dir */
339       encrypt = jcr->crypto.pki_encrypt;
340       vss = jcr->Snapshot;
341       dir->fsend(EndJob, jcr->JobStatus, jcr->JobFiles,
342               jcr->ReadBytes, jcr->JobBytes, jcr->JobErrors, vss,
343               encrypt, 0, 0);
344    }
345
346    generate_daemon_event(jcr, "JobEnd");
347    generate_plugin_event(jcr, bEventJobEnd);
348
349 bail_out:
350    dequeue_messages(jcr);             /* send any queued messages */
351
352    /* Inform Director that we are done */
353    dir->signal(BNET_TERMINATE);
354
355    free_and_null_pool_memory(jcr->job_metadata);
356
357    /* Clean up fileset */
358    FF_PKT *ff = jcr->ff;
359    findFILESET *fileset = ff->fileset;
360    if (fileset) {
361       int i, j, k;
362       /* Delete FileSet Include lists */
363       for (i=0; i<fileset->include_list.size(); i++) {
364          findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i);
365          for (j=0; j<incexe->opts_list.size(); j++) {
366             findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
367             if (fo->plugin) {
368                free(fo->plugin);
369             }
370             for (k=0; k<fo->regex.size(); k++) {
371                regfree((regex_t *)fo->regex.get(k));
372             }
373             for (k=0; k<fo->regexdir.size(); k++) {
374                regfree((regex_t *)fo->regexdir.get(k));
375             }
376             for (k=0; k<fo->regexfile.size(); k++) {
377                regfree((regex_t *)fo->regexfile.get(k));
378             }
379             fo->regex.destroy();
380             fo->regexdir.destroy();
381             fo->regexfile.destroy();
382             fo->wild.destroy();
383             fo->wilddir.destroy();
384             fo->wildfile.destroy();
385             fo->wildbase.destroy();
386             fo->base.destroy();
387             fo->fstype.destroy();
388             fo->drivetype.destroy();
389          }
390          incexe->opts_list.destroy();
391          incexe->name_list.destroy();
392          incexe->plugin_list.destroy();
393          if (incexe->ignoredir) {
394             free(incexe->ignoredir);
395          }
396       }
397       fileset->include_list.destroy();
398
399       /* Delete FileSet Exclude lists */
400       for (i=0; i<fileset->exclude_list.size(); i++) {
401          findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i);
402          for (j=0; j<incexe->opts_list.size(); j++) {
403             findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
404             fo->regex.destroy();
405             fo->regexdir.destroy();
406             fo->regexfile.destroy();
407             fo->wild.destroy();
408             fo->wilddir.destroy();
409             fo->wildfile.destroy();
410             fo->wildbase.destroy();
411             fo->base.destroy();
412             fo->fstype.destroy();
413             fo->drivetype.destroy();
414          }
415          incexe->opts_list.destroy();
416          incexe->name_list.destroy();
417          incexe->plugin_list.destroy();
418          if (incexe->ignoredir) {
419             free(incexe->ignoredir);
420          }
421       }
422       fileset->exclude_list.destroy();
423       free(fileset);
424    }
425    ff->fileset = NULL;
426    ff->mount_points.destroy();
427    Dmsg0(100, "Calling term_find_files\n");
428    term_find_files(jcr->ff);
429    jcr->ff = NULL;
430    Dmsg0(100, "Done with term_find_files\n");
431    pthread_cond_destroy(&jcr->job_start_wait);
432    free_jcr(jcr);                     /* destroy JCR record */
433    Dmsg0(100, "Done with free_jcr\n");
434    allow_os_suspensions();            /* FD can now be suspended */
435    Dsm_check(100);
436    garbage_collect_memory_pool();
437    return NULL;
438 }
439
440
441 /*
442  * Accept requests from a Director or a Storage daemon
443  */
444 void *handle_connection_request(void *caller)
445 {
446    BSOCK *bs = (BSOCK *)caller;
447
448    if (bs->recv() > 0) {
449       if (strncmp(bs->msg, "Ping", 4) == 0) {
450          bs->fsend("2000 Ping OK\n");
451          bs->destroy();
452          return NULL;
453       }
454       if (bs->msglen < 25 || bs->msglen > 500) {
455          goto bail_out;
456       }
457       Dmsg1(100, "Got: %s", bs->msg);
458       if (strncmp(bs->msg, "Hello Director", 14) == 0) {
459          return handle_director_request(bs);
460       }
461       if (strncmp(bs->msg, "Hello FD: Bacula Storage", 20) ==0) {
462          return handle_storage_connection(bs);
463       }
464    }
465 bail_out:
466    Dmsg2(100, "Bad command from %s. Len=%d.\n", bs->who(), bs->msglen);
467    char addr[64];
468    char *who = bs->get_peer(addr, sizeof(addr)) ? bs->who() : addr;
469    Jmsg2(NULL, M_FATAL, 0, _("Bad command from %s. Len=%d.\n"), who, bs->msglen);
470    bs->destroy();
471    return NULL;
472 }
473
474 static int sm_dump_cmd(JCR *jcr)
475 {
476    close_memory_pool();
477    sm_dump(false, true);
478    jcr->dir_bsock->fsend("2000 sm_dump OK\n");
479    return 1;
480 }
481
482 #ifdef DEVELOPER
483 static int exit_cmd(JCR *jcr)
484 {
485    jcr->dir_bsock->fsend("2000 exit OK\n");
486    terminate_filed(0);
487    return 0;
488 }
489 #endif
490
491
492 /**
493  * Hello from Director he must identify himself and provide his
494  *  password.
495  */
496 static int hello_cmd(JCR *jcr)
497 {
498    Dmsg0(120, "Calling Authenticate\n");
499    if (!validate_dir_hello(jcr)) {
500       return 0;
501    }
502    if (!authenticate_director(jcr)) {
503       return 0;
504    }
505    Dmsg0(120, "OK Authenticate\n");
506    jcr->authenticated = true;
507
508    return 1;
509 }
510
511 /**
512  * Cancel a Job
513  */
514 static int cancel_cmd(JCR *jcr)
515 {
516    BSOCK *dir = jcr->dir_bsock;
517    char Job[MAX_NAME_LENGTH];
518    JCR *cjcr;
519    int status;
520    const char *reason;
521
522    if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) {
523       status = JS_Canceled;
524       reason = "canceled";
525    } else if (sscanf(dir->msg, "stop Job=%127s", Job) == 1) {
526       status = JS_Incomplete;
527       reason = "stopped";
528    } else {
529       dir->fsend(_("2902 Error scanning cancel command.\n"));
530       goto bail_out;
531    }
532    if (!(cjcr=get_jcr_by_full_name(Job))) {
533       dir->fsend(_("2901 Job %s not found.\n"), Job);
534    } else {
535       generate_plugin_event(cjcr, bEventCancelCommand, NULL);
536       cjcr->setJobStatus(status);
537       if (cjcr->store_bsock) {
538          cjcr->store_bsock->set_timed_out();
539          cjcr->store_bsock->set_terminated();
540       }
541       cjcr->my_thread_send_signal(TIMEOUT_SIGNAL);
542       free_jcr(cjcr);
543       dir->fsend(_("2001 Job \"%s\" marked to be %s.\n"),
544          Job, reason);
545    }
546
547 bail_out:
548    dir->signal(BNET_EOD);
549    return 1;
550 }
551
552 /**
553  * Set bandwidth limit as requested by the Director
554  *
555  */
556 static int setbandwidth_cmd(JCR *jcr)
557 {
558    BSOCK *dir = jcr->dir_bsock;
559    int64_t bw=0;
560    JCR *cjcr;
561    char Job[MAX_NAME_LENGTH];
562    *Job=0;
563
564    if (sscanf(dir->msg, setbandwidth, &bw, Job) != 2 || bw < 0) {
565       pm_strcpy(jcr->errmsg, dir->msg);
566       dir->fsend(_("2991 Bad setbandwidth command: %s\n"), jcr->errmsg);
567       return 0;
568    }
569
570    if (*Job) {
571       if(!(cjcr=get_jcr_by_full_name(Job))) {
572          dir->fsend(_("2901 Job %s not found.\n"), Job);
573       } else {
574          cjcr->max_bandwidth = bw;
575          if (cjcr->store_bsock) {
576             cjcr->store_bsock->set_bwlimit(bw);
577          }
578          free_jcr(cjcr);
579       }
580
581    } else {                           /* No job requested, apply globally */
582       me->max_bandwidth_per_job = bw; /* Overwrite directive */
583       foreach_jcr(cjcr) {
584          cjcr->max_bandwidth = bw;
585          if (cjcr->store_bsock) {
586             cjcr->store_bsock->set_bwlimit(bw);
587          }
588       }
589       endeach_jcr(cjcr);
590    }
591
592    return dir->fsend(OKBandwidth);
593 }
594
595 /**
596  * Set debug level as requested by the Director
597  *
598  */
599 static int setdebug_cmd(JCR *jcr)
600 {
601    BSOCK *dir = jcr->dir_bsock;
602    int32_t trace, lvl;
603    int32_t hangup = -1;
604    int32_t blowup = -1;
605    int64_t level, level_tags = 0;
606    int scan;
607    char options[60];
608    char tags[512];
609
610    Dmsg1(50, "setdebug_cmd: %s", dir->msg);
611    tags[0] = options[0] = 0;
612    scan = sscanf(dir->msg, "setdebug=%ld trace=%ld hangup=%ld blowup=%ld"
613              " options=%55s tags=%511s",
614                  &lvl, &trace, &hangup, &blowup, options, tags);
615    if (scan != 6) {
616       scan = sscanf(dir->msg, "setdebug=%ld trace=%ld hangup=%ld",
617                     &lvl, &trace, &hangup);
618       if (scan != 3) {
619          Dmsg2(20, "sscanf failed: msg=%s scan=%d\n", dir->msg, scan);
620          if (sscanf(dir->msg, "setdebug=%ld trace=%ld", &lvl, &trace) != 2) {
621             pm_strcpy(jcr->errmsg, dir->msg);
622             dir->fsend(_("2991 Bad setdebug command: %s\n"), jcr->errmsg);
623             return 0;
624          } else {
625             hangup = -1;
626          }
627       }
628    }
629    level = lvl;
630    set_trace(trace);
631    set_hangup(hangup);
632    set_blowup(blowup);
633    if (!debug_parse_tags(tags, &level_tags)) {
634       *tags = 0;
635    }
636    if (level >= 0) {
637       debug_level = level;
638    }
639    debug_level_tags = level_tags;
640
641    /* handle other options */
642    set_debug_flags(options);
643
644    Dmsg6(150, "level=%ld trace=%ld hangup=%ld blowup=%d options=%s tags=%s\n",
645          lvl, get_trace(), get_hangup(), get_blowup(), options, tags);
646    return dir->fsend(OKsetdebug, lvl, get_trace(), get_hangup(),
647              get_blowup(), options, tags);
648 }
649
650
651 static int estimate_cmd(JCR *jcr)
652 {
653    BSOCK *dir = jcr->dir_bsock;
654    char ed1[50], ed2[50];
655
656    if (sscanf(dir->msg, estimatecmd, &jcr->listing) != 1) {
657       pm_strcpy(jcr->errmsg, dir->msg);
658       Jmsg(jcr, M_FATAL, 0, _("Bad estimate command: %s"), jcr->errmsg);
659       dir->fsend(_("2992 Bad estimate command.\n"));
660       return 0;
661    }
662    make_estimate(jcr);
663    dir->fsend(OKest, edit_uint64_with_commas(jcr->num_files_examined, ed1),
664       edit_uint64_with_commas(jcr->JobBytes, ed2));
665    dir->signal(BNET_EOD);
666    return 1;
667 }
668
669 /**
670  * Get JobId and Storage Daemon Authorization key from Director
671  */
672 static int job_cmd(JCR *jcr)
673 {
674    BSOCK *dir = jcr->dir_bsock;
675    POOL_MEM sd_auth_key(PM_MESSAGE);
676    sd_auth_key.check_size(dir->msglen);
677
678    if (sscanf(dir->msg, jobcmd,  &jcr->JobId, jcr->Job,
679               &jcr->VolSessionId, &jcr->VolSessionTime,
680               sd_auth_key.c_str()) != 5) {
681       pm_strcpy(jcr->errmsg, dir->msg);
682       Jmsg(jcr, M_FATAL, 0, _("Bad Job Command: %s"), jcr->errmsg);
683       dir->fsend(BADjob);
684       return 0;
685    }
686    set_jcr_in_tsd(jcr);
687    set_storage_auth_key(jcr, sd_auth_key.c_str());
688    Dmsg2(120, "JobId=%d Auth=%s\n", jcr->JobId, jcr->sd_auth_key);
689    Mmsg(jcr->errmsg, "JobId=%d Job=%s", jcr->JobId, jcr->Job);
690    new_plugins(jcr);                  /* instantiate plugins for this jcr */
691    generate_plugin_event(jcr, bEventJobStart, (void *)jcr->errmsg);
692    return dir->fsend(OKjob, VERSION, LSMDATE, HOST_OS, DISTNAME, DISTVER);
693 }
694
695 extern "C" char *job_code_callback_filed(JCR *jcr, const char* param)
696 {
697    switch (param[0]) {
698       case 'D':
699          if (jcr->director) {
700             return jcr->director->hdr.name;
701          }
702          break;
703    }
704    return NULL;
705
706 }
707
708 static int runbefore_cmd(JCR *jcr)
709 {
710    bool ok;
711    BSOCK *dir = jcr->dir_bsock;
712    POOLMEM *cmd = get_memory(dir->msglen+1);
713    RUNSCRIPT *script;
714
715    Dmsg1(100, "runbefore_cmd: %s", dir->msg);
716    if (sscanf(dir->msg, runbefore, cmd) != 1) {
717       pm_strcpy(jcr->errmsg, dir->msg);
718       Jmsg1(jcr, M_FATAL, 0, _("Bad RunBeforeJob command: %s\n"), jcr->errmsg);
719       dir->fsend(_("2905 Bad RunBeforeJob command.\n"));
720       free_memory(cmd);
721       return 0;
722    }
723    unbash_spaces(cmd);
724
725    /* Run the command now */
726    script = new_runscript();
727    script->set_job_code_callback(job_code_callback_filed);
728    script->set_command(cmd);
729    script->when = SCRIPT_Before;
730    ok = script->run(jcr, "ClientRunBeforeJob");
731    free_runscript(script);
732
733    free_memory(cmd);
734    if (ok) {
735       dir->fsend(OKRunBefore);
736       return 1;
737    } else {
738       dir->fsend(_("2905 Bad RunBeforeJob command.\n"));
739       return 0;
740    }
741 }
742
743 static int runbeforenow_cmd(JCR *jcr)
744 {
745    BSOCK *dir = jcr->dir_bsock;
746
747    run_scripts(jcr, jcr->RunScripts, "ClientBeforeJob");
748    if (job_canceled(jcr)) {
749       dir->fsend(_("2905 Bad RunBeforeNow command.\n"));
750       Dmsg0(100, "Back from run_scripts ClientBeforeJob now: FAILED\n");
751       return 0;
752    } else {
753       dir->fsend(OKRunBeforeNow);
754       Dmsg0(100, "Back from run_scripts ClientBeforeJob now: OK\n");
755       return 1;
756    }
757 }
758
759 static int runafter_cmd(JCR *jcr)
760 {
761    BSOCK *dir = jcr->dir_bsock;
762    POOLMEM *msg = get_memory(dir->msglen+1);
763    RUNSCRIPT *cmd;
764
765    Dmsg1(100, "runafter_cmd: %s", dir->msg);
766    if (sscanf(dir->msg, runafter, msg) != 1) {
767       pm_strcpy(jcr->errmsg, dir->msg);
768       Jmsg1(jcr, M_FATAL, 0, _("Bad RunAfter command: %s\n"), jcr->errmsg);
769       dir->fsend(_("2905 Bad RunAfterJob command.\n"));
770       free_memory(msg);
771       return 0;
772    }
773    unbash_spaces(msg);
774
775    cmd = new_runscript();
776    cmd->set_job_code_callback(job_code_callback_filed);
777    cmd->set_command(msg);
778    cmd->on_success = true;
779    cmd->on_failure = false;
780    cmd->when = SCRIPT_After;
781
782    jcr->RunScripts->append(cmd);
783
784    free_pool_memory(msg);
785    return dir->fsend(OKRunAfter);
786 }
787
788 static int runscript_cmd(JCR *jcr)
789 {
790    BSOCK *dir = jcr->dir_bsock;
791    POOLMEM *msg = get_memory(dir->msglen+1);
792    int on_success, on_failure, fail_on_error;
793
794    RUNSCRIPT *cmd = new_runscript() ;
795    cmd->set_job_code_callback(job_code_callback_filed);
796
797    Dmsg1(100, "runscript_cmd: '%s'\n", dir->msg);
798    /* Note, we cannot sscanf into bools */
799    if (sscanf(dir->msg, runscript, &on_success,
800                                   &on_failure,
801                                   &fail_on_error,
802                                   &cmd->when,
803                                   msg) != 5) {
804       pm_strcpy(jcr->errmsg, dir->msg);
805       Jmsg1(jcr, M_FATAL, 0, _("Bad RunScript command: %s\n"), jcr->errmsg);
806       dir->fsend(_("2905 Bad RunScript command.\n"));
807       free_runscript(cmd);
808       free_memory(msg);
809       return 0;
810    }
811    cmd->on_success = on_success;
812    cmd->on_failure = on_failure;
813    cmd->fail_on_error = fail_on_error;
814    unbash_spaces(msg);
815
816    cmd->set_command(msg);
817    cmd->debug();
818    jcr->RunScripts->append(cmd);
819
820    free_pool_memory(msg);
821    return dir->fsend(OKRunScript);
822 }
823
824 /*
825  * This reads data sent from the Director from the
826  *   RestoreObject table that allows us to get objects
827  *   that were backed up (VSS .xml data) and are needed
828  *   before starting the restore.
829  */
830 static int restore_object_cmd(JCR *jcr)
831 {
832    BSOCK *dir = jcr->dir_bsock;
833    int32_t FileIndex;
834    restore_object_pkt rop;
835
836    memset(&rop, 0, sizeof(rop));
837    rop.pkt_size = sizeof(rop);
838    rop.pkt_end = sizeof(rop);
839
840    Dmsg1(100, "Enter restoreobject_cmd: %s", dir->msg);
841    if (strcmp(dir->msg, endrestoreobjectcmd) == 0) {
842       Dmsg0(20, "Got endrestoreobject\n");
843       generate_plugin_event(jcr, bEventRestoreObject, NULL);
844       return dir->fsend(OKRestoreObject);
845    }
846
847    rop.plugin_name = (char *)malloc(dir->msglen);
848    *rop.plugin_name = 0;
849
850    if (sscanf(dir->msg, restoreobjcmd, &rop.JobId, &rop.object_len,
851               &rop.object_full_len, &rop.object_index,
852               &rop.object_type, &rop.object_compression, &FileIndex,
853               rop.plugin_name) != 8) {
854
855       /* Old version, no plugin_name */
856       if (sscanf(dir->msg, restoreobjcmd1, &rop.JobId, &rop.object_len,
857                  &rop.object_full_len, &rop.object_index,
858                  &rop.object_type, &rop.object_compression, &FileIndex) != 7) {
859          Dmsg0(5, "Bad restore object command\n");
860          pm_strcpy(jcr->errmsg, dir->msg);
861          Jmsg1(jcr, M_FATAL, 0, _("Bad RestoreObject command: %s\n"), jcr->errmsg);
862          goto bail_out;
863       }
864    }
865
866    unbash_spaces(rop.plugin_name);
867
868    Dmsg7(100, "Recv object: JobId=%u objlen=%d full_len=%d objinx=%d objtype=%d "
869          "FI=%d plugin_name=%s\n",
870          rop.JobId, rop.object_len, rop.object_full_len,
871          rop.object_index, rop.object_type, FileIndex, rop.plugin_name);
872    /* Read Object name */
873    if (dir->recv() < 0) {
874       goto bail_out;
875    }
876    Dmsg2(100, "Recv Oname object: len=%d Oname=%s\n", dir->msglen, dir->msg);
877    rop.object_name = bstrdup(dir->msg);
878
879    /* Read Object */
880    if (dir->recv() < 0) {
881       goto bail_out;
882    }
883    /* Transfer object from message buffer, and get new message buffer */
884    rop.object = dir->msg;
885    dir->msg = get_pool_memory(PM_MESSAGE);
886
887    /* If object is compressed, uncompress it */
888    if (rop.object_compression == 1) {   /* zlib level 9 */
889       int stat;
890       int out_len = rop.object_full_len + 100;
891       POOLMEM *obj = get_memory(out_len);
892       Dmsg2(100, "Inflating from %d to %d\n", rop.object_len, rop.object_full_len);
893       stat = Zinflate(rop.object, rop.object_len, obj, out_len);
894       Dmsg1(100, "Zinflate stat=%d\n", stat);
895       if (out_len != rop.object_full_len) {
896          Jmsg3(jcr, M_ERROR, 0, ("Decompression failed. Len wanted=%d got=%d. Object=%s\n"),
897             rop.object_full_len, out_len, rop.object_name);
898       }
899       free_pool_memory(rop.object);   /* release compressed object */
900       rop.object = obj;               /* new uncompressed object */
901       rop.object_len = out_len;
902    }
903    Dmsg2(100, "Recv Object: len=%d Object=%s\n", rop.object_len, rop.object);
904    /* we still need to do this to detect a vss restore */
905    if (strcmp(rop.object_name, "job_metadata.xml") == 0) {
906       Dmsg0(100, "got job metadata\n");
907       jcr->got_metadata = true;
908    }
909
910    generate_plugin_event(jcr, bEventRestoreObject, (void *)&rop);
911
912    if (rop.object_name) {
913       free(rop.object_name);
914    }
915    if (rop.object) {
916       free_pool_memory(rop.object);
917    }
918    if (rop.plugin_name) {
919       free(rop.plugin_name);
920    }
921
922    Dmsg1(100, "Send: %s", OKRestoreObject);
923    return 1;
924
925 bail_out:
926    dir->fsend(_("2909 Bad RestoreObject command.\n"));
927    return 0;
928
929 }
930
931
932 static bool init_fileset(JCR *jcr)
933 {
934    FF_PKT *ff;
935    findFILESET *fileset;
936
937    if (!jcr->ff) {
938       return false;
939    }
940    ff = jcr->ff;
941    if (ff->fileset) {
942       return false;
943    }
944    fileset = (findFILESET *)malloc(sizeof(findFILESET));
945    memset(fileset, 0, sizeof(findFILESET));
946    ff->fileset = fileset;
947    fileset->state = state_none;
948    fileset->include_list.init(1, true);
949    fileset->exclude_list.init(1, true);
950    return true;
951 }
952
953
954 static void append_file(JCR *jcr, findINCEXE *incexe,
955                         const char *buf, bool is_file)
956 {
957    if (is_file) {
958       incexe->name_list.append(new_dlistString(buf));
959
960    } else if (me->plugin_directory) {
961       generate_plugin_event(jcr, bEventPluginCommand, (void *)buf);
962       incexe->plugin_list.append(new_dlistString(buf));
963
964    } else {
965       Jmsg(jcr, M_FATAL, 0,
966            _("Plugin Directory not defined. Cannot use plugin: \"%s\"\n"),
967            buf);
968    }
969 }
970
971 /**
972  * Add fname to include/exclude fileset list. First check for
973  * | and < and if necessary perform command.
974  */
975 void add_file_to_fileset(JCR *jcr, const char *fname, bool is_file)
976 {
977    findFILESET *fileset = jcr->ff->fileset;
978    char *p;
979    BPIPE *bpipe;
980    POOLMEM *fn;
981    FILE *ffd;
982    char buf[1000];
983    int ch;
984    int stat;
985
986    p = (char *)fname;
987    ch = (uint8_t)*p;
988    switch (ch) {
989    case '|':
990       p++;                            /* skip over | */
991       fn = get_pool_memory(PM_FNAME);
992       fn = edit_job_codes(jcr, fn, p, "", job_code_callback_filed);
993       bpipe = open_bpipe(fn, 0, "r");
994       if (!bpipe) {
995          berrno be;
996          Jmsg(jcr, M_FATAL, 0, _("Cannot run program: %s. ERR=%s\n"),
997             p, be.bstrerror());
998          free_pool_memory(fn);
999          return;
1000       }
1001       free_pool_memory(fn);
1002       while (fgets(buf, sizeof(buf), bpipe->rfd)) {
1003          strip_trailing_junk(buf);
1004          append_file(jcr, fileset->incexe, buf, is_file);
1005       }
1006       if ((stat=close_bpipe(bpipe)) != 0) {
1007          berrno be;
1008          Jmsg(jcr, M_FATAL, 0, _("Error running program: %s. stat=%d: ERR=%s\n"),
1009             p, be.code(stat), be.bstrerror(stat));
1010          return;
1011       }
1012       break;
1013    case '<':
1014       Dmsg1(100, "Doing < of '%s' include on client.\n", p + 1);
1015       p++;                      /* skip over < */
1016       if ((ffd = fopen(p, "rb")) == NULL) {
1017          berrno be;
1018          Jmsg(jcr, M_FATAL, 0,
1019               _("Cannot open FileSet input file: %s. ERR=%s\n"),
1020             p, be.bstrerror());
1021          return;
1022       }
1023       while (fgets(buf, sizeof(buf), ffd)) {
1024          strip_trailing_junk(buf);
1025          append_file(jcr, fileset->incexe, buf, is_file);
1026       }
1027       fclose(ffd);
1028       break;
1029    default:
1030       append_file(jcr, fileset->incexe, fname, is_file);
1031       break;
1032    }
1033 }
1034
1035 findINCEXE *get_incexe(JCR *jcr)
1036 {
1037    if (jcr->ff && jcr->ff->fileset) {
1038       return jcr->ff->fileset->incexe;
1039    }
1040    return NULL;
1041 }
1042
1043 void set_incexe(JCR *jcr, findINCEXE *incexe)
1044 {
1045    findFILESET *fileset = jcr->ff->fileset;
1046    fileset->incexe = incexe;
1047 }
1048
1049
1050 /**
1051  * Define a new Exclude block in the FileSet
1052  */
1053 findINCEXE *new_exclude(JCR *jcr)
1054 {
1055    findFILESET *fileset = jcr->ff->fileset;
1056
1057    /* New exclude */
1058    fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE));
1059    memset(fileset->incexe, 0, sizeof(findINCEXE));
1060    fileset->incexe->opts_list.init(1, true);
1061    fileset->incexe->name_list.init();
1062    fileset->incexe->plugin_list.init();
1063    fileset->exclude_list.append(fileset->incexe);
1064    return fileset->incexe;
1065 }
1066
1067 /**
1068  * Define a new Include block in the FileSet
1069  */
1070 findINCEXE *new_include(JCR *jcr)
1071 {
1072    findFILESET *fileset = jcr->ff->fileset;
1073
1074    /* New include */
1075    fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE));
1076    memset(fileset->incexe, 0, sizeof(findINCEXE));
1077    fileset->incexe->opts_list.init(1, true);
1078    fileset->incexe->name_list.init(); /* for dlist;  was 1,true for alist */
1079    fileset->incexe->plugin_list.init();
1080    fileset->include_list.append(fileset->incexe);
1081    return fileset->incexe;
1082 }
1083
1084 /**
1085  * Define a new preInclude block in the FileSet
1086  *   That is the include is prepended to the other
1087  *   Includes.  This is used for plugin exclusions.
1088  */
1089 findINCEXE *new_preinclude(JCR *jcr)
1090 {
1091    findFILESET *fileset = jcr->ff->fileset;
1092
1093    /* New pre-include */
1094    fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE));
1095    memset(fileset->incexe, 0, sizeof(findINCEXE));
1096    fileset->incexe->opts_list.init(1, true);
1097    fileset->incexe->name_list.init(); /* for dlist;  was 1,true for alist */
1098    fileset->incexe->plugin_list.init();
1099    fileset->include_list.prepend(fileset->incexe);
1100    return fileset->incexe;
1101 }
1102
1103 static findFOPTS *start_options(FF_PKT *ff)
1104 {
1105    int state = ff->fileset->state;
1106    findINCEXE *incexe = ff->fileset->incexe;
1107
1108    if (state != state_options) {
1109       ff->fileset->state = state_options;
1110       findFOPTS *fo = (findFOPTS *)malloc(sizeof(findFOPTS));
1111       memset(fo, 0, sizeof(findFOPTS));
1112       fo->regex.init(1, true);
1113       fo->regexdir.init(1, true);
1114       fo->regexfile.init(1, true);
1115       fo->wild.init(1, true);
1116       fo->wilddir.init(1, true);
1117       fo->wildfile.init(1, true);
1118       fo->wildbase.init(1, true);
1119       fo->base.init(1, true);
1120       fo->fstype.init(1, true);
1121       fo->drivetype.init(1, true);
1122       incexe->current_opts = fo;
1123       incexe->opts_list.append(fo);
1124    }
1125    return incexe->current_opts;
1126 }
1127
1128 /*
1129  * Used by plugins to define a new options block
1130  */
1131 void new_options(JCR *jcr, findINCEXE *incexe)
1132 {
1133    if (!incexe) {
1134       incexe = jcr->ff->fileset->incexe;
1135    }
1136    findFOPTS *fo = (findFOPTS *)malloc(sizeof(findFOPTS));
1137    memset(fo, 0, sizeof(findFOPTS));
1138    fo->regex.init(1, true);
1139    fo->regexdir.init(1, true);
1140    fo->regexfile.init(1, true);
1141    fo->wild.init(1, true);
1142    fo->wilddir.init(1, true);
1143    fo->wildfile.init(1, true);
1144    fo->wildbase.init(1, true);
1145    fo->base.init(1, true);
1146    fo->fstype.init(1, true);
1147    fo->drivetype.init(1, true);
1148    incexe->current_opts = fo;
1149    incexe->opts_list.prepend(fo);
1150    jcr->ff->fileset->state = state_options;
1151 }
1152
1153 /**
1154  * Add a regex to the current fileset
1155  */
1156 int add_regex_to_fileset(JCR *jcr, const char *item, int type)
1157 {
1158    findFOPTS *current_opts = start_options(jcr->ff);
1159    regex_t *preg;
1160    int rc;
1161    char prbuf[500];
1162
1163    preg = (regex_t *)malloc(sizeof(regex_t));
1164    if (current_opts->flags & FO_IGNORECASE) {
1165       rc = regcomp(preg, item, REG_EXTENDED|REG_ICASE);
1166    } else {
1167       rc = regcomp(preg, item, REG_EXTENDED);
1168    }
1169    if (rc != 0) {
1170       regerror(rc, preg, prbuf, sizeof(prbuf));
1171       regfree(preg);
1172       free(preg);
1173       Jmsg(jcr, M_FATAL, 0, _("REGEX %s compile error. ERR=%s\n"), item, prbuf);
1174       return state_error;
1175    }
1176    if (type == ' ') {
1177       current_opts->regex.append(preg);
1178    } else if (type == 'D') {
1179       current_opts->regexdir.append(preg);
1180    } else if (type == 'F') {
1181       current_opts->regexfile.append(preg);
1182    } else {
1183       return state_error;
1184    }
1185    return state_options;
1186 }
1187
1188 /**
1189  * Add a wild card to the current fileset
1190  */
1191 int add_wild_to_fileset(JCR *jcr, const char *item, int type)
1192 {
1193    findFOPTS *current_opts = start_options(jcr->ff);
1194
1195    if (type == ' ') {
1196       current_opts->wild.append(bstrdup(item));
1197    } else if (type == 'D') {
1198       current_opts->wilddir.append(bstrdup(item));
1199    } else if (type == 'F') {
1200       current_opts->wildfile.append(bstrdup(item));
1201    } else if (type == 'B') {
1202       current_opts->wildbase.append(bstrdup(item));
1203    } else {
1204       return state_error;
1205    }
1206    return state_options;
1207 }
1208
1209
1210 /**
1211  * Add options to the current fileset
1212  */
1213 int add_options_to_fileset(JCR *jcr, const char *item)
1214 {
1215    findFOPTS *current_opts = start_options(jcr->ff);
1216
1217    set_options(current_opts, item);
1218    return state_options;
1219 }
1220
1221 static void add_fileset(JCR *jcr, const char *item)
1222 {
1223    FF_PKT *ff = jcr->ff;
1224    findFILESET *fileset = ff->fileset;
1225    int state = fileset->state;
1226    findFOPTS *current_opts;
1227
1228    /* Get code, optional subcode, and position item past the dividing space */
1229    Dmsg1(100, "%s\n", item);
1230    int code = item[0];
1231    if (code != '\0') {
1232       ++item;
1233    }
1234    int subcode = ' ';               /* A space is always a valid subcode */
1235    if (item[0] != '\0' && item[0] != ' ') {
1236       subcode = item[0];
1237       ++item;
1238    }
1239    if (*item == ' ') {
1240       ++item;
1241    }
1242
1243    /* Skip all lines we receive after an error */
1244    if (state == state_error) {
1245       Dmsg0(100, "State=error return\n");
1246       return;
1247    }
1248
1249    /**
1250     * The switch tests the code for validity.
1251     * The subcode is always good if it is a space, otherwise we must confirm.
1252     * We set state to state_error first assuming the subcode is invalid,
1253     * requiring state to be set in cases below that handle subcodes.
1254     */
1255    if (subcode != ' ') {
1256       state = state_error;
1257       Dmsg0(100, "Set state=error or double code.\n");
1258    }
1259    switch (code) {
1260    case 'I':
1261       (void)new_include(jcr);
1262       break;
1263    case 'E':
1264       (void)new_exclude(jcr);
1265       break;
1266    case 'N':                             /* null */
1267       state = state_none;
1268       break;
1269    case 'F':                             /* file = */
1270       /* File item to include or exclude list */
1271       state = state_include;
1272       add_file_to_fileset(jcr, item, true);
1273       break;
1274    case 'P':                              /* plugin */
1275       /* Plugin item to include list */
1276       state = state_include;
1277       add_file_to_fileset(jcr, item, false);
1278       break;
1279    case 'R':                              /* regex */
1280       state = add_regex_to_fileset(jcr, item, subcode);
1281       break;
1282    case 'B':
1283       current_opts = start_options(ff);
1284       current_opts->base.append(bstrdup(item));
1285       state = state_options;
1286       break;
1287    case 'X':                             /* Filetype or Drive type */
1288       current_opts = start_options(ff);
1289       state = state_options;
1290       if (subcode == ' ') {
1291          current_opts->fstype.append(bstrdup(item));
1292       } else if (subcode == 'D') {
1293          current_opts->drivetype.append(bstrdup(item));
1294       } else {
1295          state = state_error;
1296       }
1297       break;
1298    case 'W':                               /* wild cards */
1299       state = add_wild_to_fileset(jcr, item, subcode);
1300       break;
1301    case 'O':                                /* Options */
1302       state = add_options_to_fileset(jcr, item);
1303       break;
1304    case 'Z':                                /* ignore dir */
1305       state = state_include;
1306       fileset->incexe->ignoredir = bstrdup(item);
1307       break;
1308    case 'D':
1309       current_opts = start_options(ff);
1310 //    current_opts->reader = bstrdup(item); /* deprecated */
1311       state = state_options;
1312       break;
1313    case 'T':
1314       current_opts = start_options(ff);
1315 //    current_opts->writer = bstrdup(item); /* deprecated */
1316       state = state_options;
1317       break;
1318    case 'G':                    /* Plugin command for this Option block */
1319       current_opts = start_options(ff);
1320       current_opts->plugin = bstrdup(item);
1321       state = state_options;
1322       break;
1323    default:
1324       Jmsg(jcr, M_FATAL, 0, _("Invalid FileSet command: %s\n"), item);
1325       state = state_error;
1326       break;
1327    }
1328    ff->fileset->state = state;
1329 }
1330
1331 static bool term_fileset(JCR *jcr)
1332 {
1333    FF_PKT *ff = jcr->ff;
1334
1335 #ifdef xxx_DEBUG_CODE
1336    findFILESET *fileset = ff->fileset;
1337    int i, j, k;
1338
1339    for (i=0; i<fileset->include_list.size(); i++) {
1340       findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i);
1341       Dmsg0(400, "I\n");
1342       for (j=0; j<incexe->opts_list.size(); j++) {
1343          findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
1344          for (k=0; k<fo->regex.size(); k++) {
1345             Dmsg1(400, "R %s\n", (char *)fo->regex.get(k));
1346          }
1347          for (k=0; k<fo->regexdir.size(); k++) {
1348             Dmsg1(400, "RD %s\n", (char *)fo->regexdir.get(k));
1349          }
1350          for (k=0; k<fo->regexfile.size(); k++) {
1351             Dmsg1(400, "RF %s\n", (char *)fo->regexfile.get(k));
1352          }
1353          for (k=0; k<fo->wild.size(); k++) {
1354             Dmsg1(400, "W %s\n", (char *)fo->wild.get(k));
1355          }
1356          for (k=0; k<fo->wilddir.size(); k++) {
1357             Dmsg1(400, "WD %s\n", (char *)fo->wilddir.get(k));
1358          }
1359          for (k=0; k<fo->wildfile.size(); k++) {
1360             Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k));
1361          }
1362          for (k=0; k<fo->wildbase.size(); k++) {
1363             Dmsg1(400, "WB %s\n", (char *)fo->wildbase.get(k));
1364          }
1365          for (k=0; k<fo->base.size(); k++) {
1366             Dmsg1(400, "B %s\n", (char *)fo->base.get(k));
1367          }
1368          for (k=0; k<fo->fstype.size(); k++) {
1369             Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k));
1370          }
1371          for (k=0; k<fo->drivetype.size(); k++) {
1372             Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k));
1373          }
1374       }
1375       if (incexe->ignoredir) {
1376          Dmsg1(400, "Z %s\n", incexe->ignoredir);
1377       }
1378       dlistString *node;
1379       foreach_dlist(node, &incexe->name_list) {
1380          Dmsg1(400, "F %s\n", node->c_str());
1381       }
1382       foreach_dlist(node, &incexe->plugin_list) {
1383          Dmsg1(400, "P %s\n", node->c_str());
1384       }
1385    }
1386    for (i=0; i<fileset->exclude_list.size(); i++) {
1387       findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i);
1388       Dmsg0(400, "E\n");
1389       for (j=0; j<incexe->opts_list.size(); j++) {
1390          findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
1391          for (k=0; k<fo->regex.size(); k++) {
1392             Dmsg1(400, "R %s\n", (char *)fo->regex.get(k));
1393          }
1394          for (k=0; k<fo->regexdir.size(); k++) {
1395             Dmsg1(400, "RD %s\n", (char *)fo->regexdir.get(k));
1396          }
1397          for (k=0; k<fo->regexfile.size(); k++) {
1398             Dmsg1(400, "RF %s\n", (char *)fo->regexfile.get(k));
1399          }
1400          for (k=0; k<fo->wild.size(); k++) {
1401             Dmsg1(400, "W %s\n", (char *)fo->wild.get(k));
1402          }
1403          for (k=0; k<fo->wilddir.size(); k++) {
1404             Dmsg1(400, "WD %s\n", (char *)fo->wilddir.get(k));
1405          }
1406          for (k=0; k<fo->wildfile.size(); k++) {
1407             Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k));
1408          }
1409          for (k=0; k<fo->wildbase.size(); k++) {
1410             Dmsg1(400, "WB %s\n", (char *)fo->wildbase.get(k));
1411          }
1412          for (k=0; k<fo->base.size(); k++) {
1413             Dmsg1(400, "B %s\n", (char *)fo->base.get(k));
1414          }
1415          for (k=0; k<fo->fstype.size(); k++) {
1416             Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k));
1417          }
1418          for (k=0; k<fo->drivetype.size(); k++) {
1419             Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k));
1420          }
1421       }
1422       dlistString *node;
1423       foreach_dlist(node, &incexe->name_list) {
1424          Dmsg1(400, "F %s\n", node->c_str());
1425       }
1426       foreach_dlist(node, &incexe->plugin_list) {
1427          Dmsg1(400, "P %s\n", node->c_str());
1428       }
1429    }
1430 #endif
1431    return ff->fileset->state != state_error;
1432 }
1433
1434
1435 /**
1436  * As an optimization, we should do this during
1437  *  "compile" time in filed/job.c, and keep only a bit mask
1438  *  and the Verify options.
1439  */
1440 static int set_options(findFOPTS *fo, const char *opts)
1441 {
1442    int j;
1443    const char *p;
1444    char strip[100];
1445
1446 // Commented out as it is not backward compatible - KES
1447
1448    for (p=opts; *p; p++) {
1449       switch (*p) {
1450       case 'a':                 /* alway replace */
1451       case '0':                 /* no option */
1452          break;
1453       case 'e':
1454          fo->flags |= FO_EXCLUDE;
1455          break;
1456       case 'f':
1457          fo->flags |= FO_MULTIFS;
1458          break;
1459       case 'h':                 /* no recursion */
1460          fo->flags |= FO_NO_RECURSION;
1461          break;
1462       case 'H':                 /* no hard link handling */
1463          fo->flags |= FO_NO_HARDLINK;
1464          break;
1465       case 'i':
1466          fo->flags |= FO_IGNORECASE;
1467          break;
1468       case 'M':                 /* MD5 */
1469          fo->flags |= FO_MD5;
1470          break;
1471       case 'n':
1472          fo->flags |= FO_NOREPLACE;
1473          break;
1474       case 'p':                 /* use portable data format */
1475          fo->flags |= FO_PORTABLE;
1476          break;
1477       case 'R':                 /* Resource forks and Finder Info */
1478          fo->flags |= FO_HFSPLUS;
1479          break;
1480       case 'r':                 /* read fifo */
1481          fo->flags |= FO_READFIFO;
1482          break;
1483       case 'S':
1484          switch(*(p + 1)) {
1485          case '1':
1486             fo->flags |= FO_SHA1;
1487             p++;
1488             break;
1489 #ifdef HAVE_SHA2
1490          case '2':
1491             fo->flags |= FO_SHA256;
1492             p++;
1493             break;
1494          case '3':
1495             fo->flags |= FO_SHA512;
1496             p++;
1497             break;
1498 #endif
1499          default:
1500             /*
1501              * If 2 or 3 is seen here, SHA2 is not configured, so
1502              *  eat the option, and drop back to SHA-1.
1503              */
1504             if (p[1] == '2' || p[1] == '3') {
1505                p++;
1506             }
1507             fo->flags |= FO_SHA1;
1508             break;
1509          }
1510          break;
1511       case 's':
1512          fo->flags |= FO_SPARSE;
1513          break;
1514       case 'm':
1515          fo->flags |= FO_MTIMEONLY;
1516          break;
1517       case 'k':
1518          fo->flags |= FO_KEEPATIME;
1519          break;
1520       case 'A':
1521          fo->flags |= FO_ACL;
1522          break;
1523       case 'V':                  /* verify options */
1524          /* Copy Verify Options */
1525          for (j=0; *p && *p != ':'; p++) {
1526             fo->VerifyOpts[j] = *p;
1527             if (j < (int)sizeof(fo->VerifyOpts) - 1) {
1528                j++;
1529             }
1530          }
1531          fo->VerifyOpts[j] = 0;
1532          break;
1533       case 'C':                  /* accurate options */
1534          /* Copy Accurate Options */
1535          for (j=0; *p && *p != ':'; p++) {
1536             fo->AccurateOpts[j] = *p;
1537             if (j < (int)sizeof(fo->AccurateOpts) - 1) {
1538                j++;
1539             }
1540          }
1541          fo->AccurateOpts[j] = 0;
1542          break;
1543       case 'J':                  /* Basejob options */
1544          /* Copy BaseJob Options */
1545          for (j=0; *p && *p != ':'; p++) {
1546             fo->BaseJobOpts[j] = *p;
1547             if (j < (int)sizeof(fo->BaseJobOpts) - 1) {
1548                j++;
1549             }
1550          }
1551          fo->BaseJobOpts[j] = 0;
1552          break;
1553       case 'P':                  /* strip path */
1554          /* Get integer */
1555          p++;                    /* skip P */
1556          for (j=0; *p && *p != ':'; p++) {
1557             strip[j] = *p;
1558             if (j < (int)sizeof(strip) - 1) {
1559                j++;
1560             }
1561          }
1562          strip[j] = 0;
1563          fo->strip_path = atoi(strip);
1564          fo->flags |= FO_STRIPPATH;
1565          Dmsg2(100, "strip=%s strip_path=%d\n", strip, fo->strip_path);
1566          break;
1567       case 'w':
1568          fo->flags |= FO_IF_NEWER;
1569          break;
1570       case 'W':
1571          fo->flags |= FO_ENHANCEDWILD;
1572          break;
1573       case 'Z':                 /* compression */
1574          p++;                   /* skip Z */
1575          if (*p >= '0' && *p <= '9') {
1576             fo->flags |= FO_COMPRESS;
1577             fo->Compress_algo = COMPRESS_GZIP;
1578             fo->Compress_level = *p - '0';
1579          }
1580          else if (*p == 'o') {
1581             fo->flags |= FO_COMPRESS;
1582             fo->Compress_algo = COMPRESS_LZO1X;
1583             fo->Compress_level = 1; /* not used with LZO */
1584          }
1585          break;
1586       case 'K':
1587          fo->flags |= FO_NOATIME;
1588          break;
1589       case 'c':
1590          fo->flags |= FO_CHKCHANGES;
1591          break;
1592       case 'N':
1593          fo->flags |= FO_HONOR_NODUMP;
1594          break;
1595       case 'X':
1596          fo->flags |= FO_XATTR;
1597          break;
1598       default:
1599          Jmsg1(NULL, M_ERROR, 0, _("Unknown include/exclude option: %c\n"), *p);
1600          break;
1601       }
1602    }
1603    return state_options;
1604 }
1605
1606
1607 /**
1608  * Director is passing his Fileset
1609  */
1610 static int fileset_cmd(JCR *jcr)
1611 {
1612    POOL_MEM buf(PM_MESSAGE);
1613    BSOCK *dir = jcr->dir_bsock;
1614    int rtnstat;
1615
1616    jcr->Snapshot = (strstr(dir->msg, "snap=1") != NULL);
1617    if (!init_fileset(jcr)) {
1618       return 0;
1619    }
1620    while (dir->recv() >= 0) {
1621       strip_trailing_junk(dir->msg);
1622       Dmsg1(500, "Fileset: %s\n", dir->msg);
1623       pm_strcpy(buf, dir->msg);
1624       add_fileset(jcr, buf.c_str());
1625    }
1626    if (!term_fileset(jcr)) {
1627       return 0;
1628    }
1629    rtnstat = dir->fsend(OKinc);
1630    generate_plugin_event(jcr, bEventEndFileSet);
1631    return rtnstat;
1632 }
1633
1634
1635 /*
1636  * The Director sends us the component info file, which
1637  *   we will in turn pass to the VSS plugin.
1638  */
1639 static int component_cmd(JCR *jcr)
1640 {
1641    BSOCK *dir = jcr->dir_bsock;
1642
1643    while (dir->recv() >= 0) {
1644        Dmsg1(200, "filed<dird: component: %s", dir->msg);
1645        generate_plugin_event(jcr, bEventComponentInfo, (void *)dir->msg);
1646    }
1647    return dir->fsend(OKComponentInfo);
1648 }
1649
1650
1651 /**
1652  * Get backup level from Director
1653  *
1654  * Note: there are odd things such as accurate_differential,
1655  *  and accurate_incremental that are passed in level, thus
1656  *  the calls to strstr() below.
1657  *
1658  */
1659 static int level_cmd(JCR *jcr)
1660 {
1661    BSOCK *dir = jcr->dir_bsock;
1662    POOLMEM *level, *buf = NULL;
1663    int mtime_only;
1664
1665    level = get_memory(dir->msglen+1);
1666    Dmsg1(10, "level_cmd: %s", dir->msg);
1667
1668    /* keep compatibility with older directors */
1669    if (strstr(dir->msg, "accurate")) {
1670       jcr->accurate = true;
1671    }
1672    if (strstr(dir->msg, "rerunning")) {
1673       jcr->rerunning = true;
1674    }
1675    if (sscanf(dir->msg, "level = %s ", level) != 1) {
1676       goto bail_out;
1677    }
1678    /* Base backup requested? */
1679    if (strcasecmp(level, "base") == 0) {
1680       jcr->setJobLevel(L_BASE);
1681    /* Full backup requested? */
1682    } else if (strcasecmp(level, "full") == 0) {
1683       jcr->setJobLevel(L_FULL);
1684    } else if (strstr(level, "differential")) {
1685       jcr->setJobLevel(L_DIFFERENTIAL);
1686       free_memory(level);
1687       return 1;
1688    } else if (strstr(level, "incremental")) {
1689       jcr->setJobLevel(L_INCREMENTAL);
1690       free_memory(level);
1691       return 1;
1692    /*
1693     * We get his UTC since time, then sync the clocks and correct it
1694     *   to agree with our clock.
1695     */
1696    } else if (strcasecmp(level, "since_utime") == 0) {
1697       buf = get_memory(dir->msglen+1);
1698       utime_t since_time, adj;
1699       btime_t his_time, bt_start, rt=0, bt_adj=0, his_time_prev=0, n=0;
1700       if (jcr->getJobLevel() == L_NONE) {
1701          jcr->setJobLevel(L_SINCE);     /* if no other job level set, do it now */
1702       }
1703       if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d prev_job=%127s",
1704                  buf, &mtime_only, jcr->PrevJob) != 3) {
1705          if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d",
1706                     buf, &mtime_only) != 2) {
1707             goto bail_out;
1708          }
1709       }
1710       since_time = str_to_uint64(buf);  /* this is the since time */
1711       Dmsg2(100, "since_time=%lld prev_job=%s\n", since_time, jcr->PrevJob);
1712       char ed1[50], ed2[50];
1713       /*
1714        * Sync clocks by polling him for the time. We take
1715        *   10 samples of his time throwing out the first two.
1716        */
1717       for (int i=0; i<10; i++) {
1718          bt_start = get_current_btime();
1719          dir->signal(BNET_BTIME);     /* poll for time */
1720          if (dir->recv() <= 0) {      /* get response */
1721             goto bail_out;
1722          }
1723          if (sscanf(dir->msg, "btime %s", buf) != 1) {
1724             goto bail_out;
1725          }
1726          his_time = str_to_uint64(buf);
1727          rt = get_current_btime() - bt_start; /* compute round trip time */
1728          /* skip first two results and check for leap second */
1729          /* if any of the FD or DIR went back in time, skip this iteration */
1730          if (i < 2 || (his_time_prev > 0 && his_time < his_time_prev) || rt<0) {
1731             his_time_prev = his_time;
1732             continue;
1733          }
1734          his_time_prev = his_time;
1735          n++;
1736          Dmsg2(100, "Dirtime=%s FDtime=%s\n", edit_uint64(his_time, ed1),
1737                edit_uint64(bt_start, ed2));
1738          bt_adj +=  bt_start - his_time - rt/2;
1739          Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
1740       }
1741       adj = 0;
1742       if (n > 0) { /* Should be 1 in the worst case */
1743          bt_adj = bt_adj / n;            /* compute average time */
1744          Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
1745          adj = btime_to_utime(bt_adj);
1746          since_time += adj;              /* adjust for clock difference */
1747       }
1748       /* Don't notify if time within 3 seconds */
1749       if (adj > 3 || adj < -3) {
1750          int type;
1751          if (adj > 600 || adj < -600) {
1752             type = M_WARNING;
1753          } else {
1754             type = M_INFO;
1755          }
1756          Jmsg(jcr, type, 0, _("DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n"), adj);
1757       }
1758       dir->signal(BNET_EOD);
1759
1760       Dmsg2(100, "adj=%lld since_time=%lld\n", adj, since_time);
1761       jcr->incremental = 1;           /* set incremental or decremental backup */
1762       jcr->mtime = since_time;        /* set since time */
1763       generate_plugin_event(jcr, bEventSince, (void *)(time_t)jcr->mtime);
1764    } else {
1765       Jmsg1(jcr, M_FATAL, 0, _("Unknown backup level: %s\n"), level);
1766       free_memory(level);
1767       return 0;
1768    }
1769    free_memory(level);
1770    if (buf) {
1771       free_memory(buf);
1772    }
1773    generate_plugin_event(jcr, bEventLevel, (void*)(intptr_t)jcr->getJobLevel());
1774    return dir->fsend(OKlevel);
1775
1776 bail_out:
1777    pm_strcpy(jcr->errmsg, dir->msg);
1778    Jmsg1(jcr, M_FATAL, 0, _("Bad level command: %s\n"), jcr->errmsg);
1779    free_memory(level);
1780    if (buf) {
1781       free_memory(buf);
1782    }
1783    return 0;
1784 }
1785
1786 /**
1787  * Get session parameters from Director -- this is for a Restore command
1788  *   This is deprecated. It is now passed via the bsr.
1789  */
1790 static int session_cmd(JCR *jcr)
1791 {
1792    BSOCK *dir = jcr->dir_bsock;
1793
1794    Dmsg1(100, "SessionCmd: %s", dir->msg);
1795    if (sscanf(dir->msg, sessioncmd, jcr->VolumeName,
1796               &jcr->VolSessionId, &jcr->VolSessionTime,
1797               &jcr->StartFile, &jcr->EndFile,
1798               &jcr->StartBlock, &jcr->EndBlock) != 7) {
1799       pm_strcpy(jcr->errmsg, dir->msg);
1800       Jmsg(jcr, M_FATAL, 0, _("Bad session command: %s"), jcr->errmsg);
1801       return 0;
1802    }
1803
1804    return dir->fsend(OKsession);
1805 }
1806
1807 static void set_storage_auth_key(JCR *jcr, char *key)
1808 {
1809    /* if no key don't update anything */
1810    if (!*key) {
1811       return;
1812    }
1813
1814    /**
1815     * We can be contacting multiple storage daemons.
1816     * So, make sure that any old jcr->store_bsock is cleaned up.
1817     */
1818    free_bsock(jcr->store_bsock);
1819
1820    /**
1821     * We can be contacting multiple storage daemons.
1822     *   So, make sure that any old jcr->sd_auth_key is cleaned up.
1823     */
1824    if (jcr->sd_auth_key) {
1825       /*
1826        * If we already have a Authorization key, director can do multi
1827        * storage restore
1828        */
1829       Dmsg0(5, "set multi_restore=true\n");
1830       jcr->multi_restore = true;
1831       bfree(jcr->sd_auth_key);
1832    }
1833
1834    jcr->sd_auth_key = bstrdup(key);
1835    Dmsg1(5, "set sd auth key %s\n", jcr->sd_auth_key);
1836 }
1837
1838 /**
1839  * Get address of storage daemon from Director
1840  *
1841  */
1842 static int storage_cmd(JCR *jcr)
1843 {
1844    int stored_port = 0;            /* storage daemon port */
1845    int enable_ssl;                 /* enable ssl to sd */
1846    POOL_MEM sd_auth_key(PM_MESSAGE);
1847    BSOCK *dir = jcr->dir_bsock;
1848    BSOCK *sd;
1849
1850    Dmsg1(100, "StorageCmd: %s", dir->msg);
1851    sd_auth_key.check_size(dir->msglen);
1852    if (sscanf(dir->msg, storaddr, &jcr->stored_addr, &stored_port,
1853               &enable_ssl, sd_auth_key.c_str()) == 4) {
1854       Dmsg1(100, "Set auth key %s\n", sd_auth_key.c_str());
1855       set_storage_auth_key(jcr, sd_auth_key.c_str());
1856   } else if (sscanf(dir->msg, storaddr_v1, &jcr->stored_addr,
1857                  &stored_port, &enable_ssl) != 3) {
1858       pm_strcpy(jcr->errmsg, dir->msg);
1859       Jmsg(jcr, M_FATAL, 0, _("Bad storage command: %s"), jcr->errmsg);
1860       Pmsg1(010, "Bad storage command: %s", jcr->errmsg);
1861       goto bail_out;
1862    }
1863
1864
1865    /* TODO: see if we put limit on restore and backup... */
1866    if (!jcr->max_bandwidth) {
1867       if (jcr->director->max_bandwidth_per_job) {
1868          jcr->max_bandwidth = jcr->director->max_bandwidth_per_job;
1869
1870       } else if (me->max_bandwidth_per_job) {
1871          jcr->max_bandwidth = me->max_bandwidth_per_job;
1872       }
1873    }
1874
1875    if (stored_port != 0) { /* We are doing the connecting */
1876       Dmsg3(110, "Connect to storage: %s:%d ssl=%d\n", jcr->stored_addr, stored_port,
1877             enable_ssl);
1878       jcr->sd_calls_client = false;
1879       sd = new_bsock();
1880       /* Open command communications with Storage daemon */
1881       /* Try to connect for 1 hour at 10 second intervals */
1882       sd->set_source_address(me->FDsrc_addr);
1883       if (!sd->connect(jcr, 10, (int)me->SDConnectTimeout, me->heartbeat_interval,
1884                 _("Storage daemon"), jcr->stored_addr, NULL, stored_port, 1)) {
1885          /* destroy() OK because sd is local */
1886          sd->destroy();
1887          Jmsg2(jcr, M_FATAL, 0, _("Failed to connect to Storage daemon: %s:%d\n"),
1888              jcr->stored_addr, stored_port);
1889          Dmsg2(100, "Failed to connect to Storage daemon: %s:%d\n",
1890              jcr->stored_addr, stored_port);
1891          goto bail_out;
1892       }
1893
1894       Dmsg0(110, "Connection OK to SD.\n");
1895       jcr->store_bsock = sd;
1896    } else {                      /* The storage daemon called us */
1897       struct timeval tv;
1898       struct timezone tz;
1899       struct timespec timeout;
1900       int errstat;
1901
1902       free_bsock(jcr->store_bsock);
1903       jcr->sd_calls_client = true;
1904
1905       /*
1906        * Wait for the Storage daemon to contact us to start the Job,
1907        *  when he does, we will be released, unless the 30 minutes
1908        *  expires.
1909        */
1910       gettimeofday(&tv, &tz);
1911       timeout.tv_nsec = tv.tv_usec * 1000;
1912       timeout.tv_sec = tv.tv_sec + 30 * 60;  /* wait 30 minutes */
1913       P(mutex);
1914       while (jcr->sd_calls_client_bsock == NULL && !jcr->is_job_canceled()) {
1915          errstat = pthread_cond_timedwait(&jcr->job_start_wait, &mutex, &timeout);
1916          if (errstat == ETIMEDOUT || errstat == EINVAL || errstat == EPERM) {
1917             break;
1918          }
1919          Dmsg1(800, "=== Auth cond errstat=%d\n", errstat);
1920       }
1921       V(mutex);
1922       Dmsg2(800, "Auth fail or cancel for jid=%d %p\n", jcr->JobId, jcr);
1923
1924       /* We should already have a storage connection! */
1925       if (jcr->sd_calls_client_bsock == NULL) {
1926          Pmsg0(000, "Failed connect from Storage daemon. SD bsock=NULL.\n");
1927          Pmsg1(000, "Storagecmd: %s", dir->msg);
1928          Jmsg0(jcr, M_FATAL, 0, _("Failed connect from Storage daemon. SD bsock=NULL.\n"));
1929          goto bail_out;
1930       }
1931       if (jcr->is_job_canceled()) {
1932          goto bail_out;
1933       }
1934       /* Assign the new socket to the main one */
1935       jcr->lock_auth();
1936       jcr->store_bsock = jcr->sd_calls_client_bsock;
1937       jcr->sd_calls_client_bsock = NULL;
1938       jcr->unlock_auth();
1939    }
1940    jcr->store_bsock->set_bwlimit(jcr->max_bandwidth);
1941
1942    if (!send_hello_sd(jcr, jcr->Job)) {
1943       goto bail_out;
1944    }
1945
1946    if (!authenticate_storagedaemon(jcr)) {
1947       goto bail_out;
1948    }
1949    memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
1950    Dmsg0(110, "Authenticated with SD.\n");
1951
1952    /* Send OK to Director */
1953    return dir->fsend(OKstore);
1954
1955 bail_out:
1956    dir->fsend(BADcmd, "storage");
1957    return 0;
1958 }
1959
1960
1961 /**
1962  * Do a backup.
1963  */
1964 static int backup_cmd(JCR *jcr)
1965 {
1966    BSOCK *dir = jcr->dir_bsock;
1967    BSOCK *sd = jcr->store_bsock;
1968    int ok = 0;
1969    int SDJobStatus;
1970    int32_t FileIndex;
1971
1972    if (sscanf(dir->msg, "backup FileIndex=%ld\n", &FileIndex) == 1) {
1973       jcr->JobFiles = FileIndex;
1974       Dmsg1(100, "JobFiles=%ld\n", jcr->JobFiles);
1975    }
1976
1977    /*
1978     * If explicitly requesting FO_ACL or FO_XATTR, fail job if it
1979     *  is not available on Client machine
1980     */ 
1981    if (jcr->ff->flags & FO_ACL && !(have_acl||have_win32)) {
1982       Jmsg(jcr, M_FATAL, 0, _("ACL support not configured for Client.\n"));
1983       goto cleanup; 
1984    } 
1985    if (jcr->ff->flags & FO_XATTR && !have_xattr) { 
1986       Jmsg(jcr, M_FATAL, 0, _("XATTR support not configured for Client.\n"));
1987       goto cleanup; 
1988    } 
1989    jcr->setJobStatus(JS_Blocked);
1990    jcr->setJobType(JT_BACKUP);
1991    Dmsg1(100, "begin backup ff=%p\n", jcr->ff);
1992    if (sd == NULL) {
1993       Jmsg(jcr, M_FATAL, 0, _("Cannot contact Storage daemon\n"));
1994       dir->fsend(BADcmd, "backup");
1995       goto cleanup;
1996    }
1997
1998    dir->fsend(OKbackup);
1999    Dmsg1(110, "filed>dird: %s", dir->msg);
2000
2001    /**
2002     * Send Append Open Session to Storage daemon
2003     */
2004    sd->fsend(append_open);
2005    Dmsg1(110, ">stored: %s", sd->msg);
2006    /**
2007     * Expect to receive back the Ticket number
2008     */
2009    if (bget_msg(sd) >= 0) {
2010       Dmsg1(110, "<stored: %s", sd->msg);
2011       if (sscanf(sd->msg, OK_open, &jcr->Ticket) != 1) {
2012          Jmsg(jcr, M_FATAL, 0, _("Bad response to append open: %s\n"), sd->msg);
2013          goto cleanup;
2014       }
2015       Dmsg1(110, "Got Ticket=%d\n", jcr->Ticket);
2016    } else {
2017       Jmsg(jcr, M_FATAL, 0, _("Bad response from stored to open command\n"));
2018       goto cleanup;
2019    }
2020
2021    /**
2022     * Send Append data command to Storage daemon
2023     */
2024    sd->fsend(append_data, jcr->Ticket);
2025    Dmsg1(110, ">stored: %s", sd->msg);
2026
2027    /**
2028     * Expect to get OK data
2029     */
2030    Dmsg1(110, "<stored: %s", sd->msg);
2031    if (!response(jcr, sd, OK_data, "Append Data")) {
2032       goto cleanup;
2033    }
2034
2035    generate_daemon_event(jcr, "JobStart");
2036    generate_plugin_event(jcr, bEventStartBackupJob);
2037
2038    if (jcr->Snapshot) {
2039       Dmsg0(10, "Open a snapshot session\n");
2040       /* TODO: See if we abort the job */
2041       jcr->Snapshot = open_snapshot_backup_session(jcr);
2042    }
2043    /* Call RunScript just after the Snapshot creation, usually, we restart services */
2044    run_scripts(jcr, jcr->RunScripts, "ClientAfterVSS");
2045
2046
2047    /**
2048     * Send Files to Storage daemon
2049     */
2050    Dmsg1(110, "begin blast ff=%p\n", (FF_PKT *)jcr->ff);
2051    if (!blast_data_to_storage_daemon(jcr, NULL)) {
2052       jcr->setJobStatus(JS_ErrorTerminated);
2053       sd->suppress_error_messages(true);
2054       Dmsg0(110, "Error in blast_data.\n");
2055    } else {
2056       jcr->setJobStatus(JS_Terminated);
2057       /* Note, the above set status will not override an error */
2058       if (!(jcr->JobStatus == JS_Terminated || jcr->JobStatus == JS_Warnings)) {
2059          sd->suppress_error_messages(true);
2060          goto cleanup;                /* bail out now */
2061       }
2062       /**
2063        * Expect to get response to append_data from Storage daemon
2064        */
2065       if (!response(jcr, sd, OK_append, "Append Data")) {
2066          jcr->setJobStatus(JS_ErrorTerminated);
2067          goto cleanup;
2068       }
2069
2070       /**
2071        * Send Append End Data to Storage daemon
2072        */
2073       sd->fsend(append_end, jcr->Ticket);
2074       /* Get end OK */
2075       if (!response(jcr, sd, OK_end, "Append End")) {
2076          jcr->setJobStatus(JS_ErrorTerminated);
2077          goto cleanup;
2078       }
2079
2080       /**
2081        * Send Append Close to Storage daemon
2082        */
2083       sd->fsend(append_close, jcr->Ticket);
2084       sd->msg[0] = 0;
2085       while (bget_msg(sd) >= 0) {    /* stop on signal or error */
2086          if (sscanf(sd->msg, OK_close, &SDJobStatus) == 1) {
2087             ok = 1;
2088             Dmsg2(200, "SDJobStatus = %d %c\n", SDJobStatus, (char)SDJobStatus);
2089          } else {
2090             Dmsg1(100, "append_close: scan fail from %s\n", sd->msg);
2091          }
2092       }
2093       if (!ok) {
2094          Jmsg(jcr, M_FATAL, 0, _("Append Close with SD failed.\n"));
2095          Dmsg1(100, "append_close: scan fail from %s\n", sd->msg);
2096          goto cleanup;
2097       }
2098       if (!(SDJobStatus == JS_Terminated || SDJobStatus == JS_Warnings ||
2099             SDJobStatus == JS_Incomplete)) {
2100          Jmsg(jcr, M_FATAL, 0, _("Bad status %d %c returned from Storage Daemon.\n"),
2101             SDJobStatus, (char)SDJobStatus);
2102       }
2103    }
2104
2105 cleanup:
2106
2107    generate_plugin_event(jcr, bEventEndBackupJob);
2108    return 0;                          /* return and stop command loop */
2109 }
2110
2111 /**
2112  * Do a Verify for Director
2113  *
2114  */
2115 static int verify_cmd(JCR *jcr)
2116 {
2117    BSOCK *dir = jcr->dir_bsock;
2118    BSOCK *sd  = jcr->store_bsock;
2119    char level[100];
2120
2121    jcr->setJobType(JT_VERIFY);
2122    if (sscanf(dir->msg, verifycmd, level) != 1) {
2123       dir->fsend(_("2994 Bad verify command: %s\n"), dir->msg);
2124       return 0;
2125    }
2126
2127    if (strcasecmp(level, "init") == 0) {
2128       jcr->setJobLevel(L_VERIFY_INIT);
2129    } else if (strcasecmp(level, "catalog") == 0){
2130       jcr->setJobLevel(L_VERIFY_CATALOG);
2131    } else if (strcasecmp(level, "volume") == 0){
2132       jcr->setJobLevel(L_VERIFY_VOLUME_TO_CATALOG);
2133    } else if (strcasecmp(level, "data") == 0){
2134       jcr->setJobLevel(L_VERIFY_DATA);
2135    } else if (strcasecmp(level, "disk_to_catalog") == 0) {
2136       jcr->setJobLevel(L_VERIFY_DISK_TO_CATALOG);
2137    } else {
2138       dir->fsend(_("2994 Bad verify level: %s\n"), dir->msg);
2139       return 0;
2140    }
2141
2142    dir->fsend(OKverify);
2143
2144    generate_daemon_event(jcr, "JobStart");
2145    generate_plugin_event(jcr, bEventLevel,(void *)(intptr_t)jcr->getJobLevel());
2146    generate_plugin_event(jcr, bEventStartVerifyJob);
2147
2148    Dmsg1(110, "filed>dird: %s", dir->msg);
2149
2150    switch (jcr->getJobLevel()) {
2151    case L_VERIFY_INIT:
2152    case L_VERIFY_CATALOG:
2153       do_verify(jcr);
2154       break;
2155    case L_VERIFY_DATA:
2156    case L_VERIFY_VOLUME_TO_CATALOG:
2157       if (!open_sd_read_session(jcr)) {
2158          return 0;
2159       }
2160       start_dir_heartbeat(jcr);
2161       do_verify_volume(jcr);
2162       stop_dir_heartbeat(jcr);
2163       /*
2164        * Send Close session command to Storage daemon
2165        */
2166       sd->fsend(read_close, jcr->Ticket);
2167       Dmsg1(130, "filed>stored: %s", sd->msg);
2168
2169       /* ****FIXME**** check response */
2170       bget_msg(sd);                      /* get OK */
2171
2172       /* Inform Storage daemon that we are done */
2173       sd->signal(BNET_TERMINATE);
2174
2175       break;
2176    case L_VERIFY_DISK_TO_CATALOG:
2177       do_verify(jcr);
2178       break;
2179    default:
2180       dir->fsend(_("2994 Bad verify level: %s\n"), dir->msg);
2181       return 0;
2182    }
2183
2184    dir->signal(BNET_EOD);
2185    generate_plugin_event(jcr, bEventEndVerifyJob);
2186    return 0;                          /* return and terminate command loop */
2187 }
2188
2189 /*
2190  * Do a Restore for Director
2191  *
2192  */
2193 static int restore_cmd(JCR *jcr)
2194 {
2195    BSOCK *dir = jcr->dir_bsock;
2196    BSOCK *sd = jcr->store_bsock;
2197    POOLMEM *args=NULL, *restore_where=NULL, *restore_rwhere=NULL;
2198    bool use_regexwhere=false;
2199    int prefix_links;
2200    char replace;
2201    bool scan_ok = true;
2202    int files;
2203    int ret = 0;
2204
2205    /**
2206     * Scan WHERE (base directory for restore) from command
2207     */
2208    Dmsg0(100, "restore command\n");
2209
2210    /* Pickup where string */
2211    args = get_memory(dir->msglen+1);
2212    *args = 0;
2213
2214    restore_where = get_pool_memory(PM_FNAME);
2215    restore_rwhere = get_pool_memory(PM_FNAME);
2216
2217    /* We don't know the size of where/rwhere in advance,
2218     * where= -> where=%202s\n
2219     */
2220    Mmsg(restore_where, "%s%%%ds\n", restorefcmd, dir->msglen);
2221    Mmsg(restore_rwhere, "%s%%%ds\n", restorefcmdR, dir->msglen);
2222
2223    Dmsg2(200, "where=%srwhere=%s", restore_where, restore_rwhere);
2224
2225    /* Scan for new form with number of files to restore */
2226    if (sscanf(dir->msg, restore_where, &files, &replace, &prefix_links, args) != 4) {
2227       if (sscanf(dir->msg, restore_rwhere, &files, &replace, &prefix_links, args) != 4) {
2228          if (sscanf(dir->msg, restorefcmd1, &files, &replace, &prefix_links) != 3) {
2229             scan_ok = false;
2230          }
2231          *args = 0;             /* No where argument */
2232       } else {
2233          use_regexwhere = true;
2234       }
2235    }
2236
2237    if (scan_ok) {
2238       jcr->ExpectedFiles = files;
2239    } else {
2240       /* Scan for old form without number of files */
2241       jcr->ExpectedFiles = 0;
2242
2243       /* where= -> where=%202s\n */
2244       Mmsg(restore_where, "%s%%%ds\n", restorecmd, dir->msglen);
2245       Mmsg(restore_rwhere, "%s%%%ds\n", restorecmdR, dir->msglen);
2246
2247       if (sscanf(dir->msg, restore_where, &replace, &prefix_links, args) != 3) {
2248          if (sscanf(dir->msg, restore_rwhere, &replace, &prefix_links, args) != 3){
2249             if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
2250                pm_strcpy(jcr->errmsg, dir->msg);
2251                Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
2252                goto free_mempool;
2253             }
2254             *args = 0;          /* No where argument */
2255          } else {
2256             use_regexwhere = true;
2257          }
2258       }
2259    }
2260
2261    /* Turn / into nothing */
2262    if (IsPathSeparator(args[0]) && args[1] == '\0') {
2263       args[0] = '\0';
2264    }
2265
2266    Dmsg2(150, "Got replace %c, where=%s\n", replace, args);
2267    unbash_spaces(args);
2268
2269    /* Keep track of newly created directories to apply them correct attributes */
2270    if (replace == REPLACE_NEVER || replace == REPLACE_IFNEWER) {
2271       jcr->keep_path_list = true;
2272    }
2273
2274    if (use_regexwhere) {
2275       jcr->where_bregexp = get_bregexps(args);
2276       if (!jcr->where_bregexp) {
2277          Jmsg(jcr, M_FATAL, 0, _("Bad where regexp. where=%s\n"), args);
2278          goto free_mempool;
2279       }
2280    } else {
2281       jcr->where = bstrdup(args);
2282    }
2283
2284    jcr->replace = replace;
2285    jcr->prefix_links = prefix_links;
2286
2287    dir->fsend(OKrestore);
2288    Dmsg1(110, "filed>dird: %s", dir->msg);
2289
2290    jcr->setJobType(JT_RESTORE);
2291
2292    jcr->setJobStatus(JS_Blocked);
2293
2294    if (!open_sd_read_session(jcr)) {
2295       jcr->setJobStatus(JS_ErrorTerminated);
2296       goto bail_out;
2297    }
2298
2299    jcr->setJobStatus(JS_Running);
2300
2301    /**
2302     * Do restore of files and data
2303     */
2304    start_dir_heartbeat(jcr);
2305    generate_daemon_event(jcr, "JobStart");
2306    generate_plugin_event(jcr, bEventStartRestoreJob);
2307
2308    do_restore(jcr);
2309    stop_dir_heartbeat(jcr);
2310
2311    jcr->setJobStatus(JS_Terminated);
2312    if (jcr->JobStatus != JS_Terminated) {
2313       sd->suppress_error_messages(true);
2314    }
2315
2316    /**
2317     * Send Close session command to Storage daemon
2318     */
2319    sd->fsend(read_close, jcr->Ticket);
2320    Dmsg1(100, "filed>stored: %s", sd->msg);
2321
2322    bget_msg(sd);                      /* get OK */
2323
2324    /* Inform Storage daemon that we are done */
2325    sd->signal(BNET_TERMINATE);
2326
2327 bail_out:
2328    bfree_and_null(jcr->where);
2329
2330    if (jcr->JobErrors) {
2331       jcr->setJobStatus(JS_ErrorTerminated);
2332    }
2333
2334    Dmsg0(100, "Done in job.c\n");
2335
2336    if (jcr->multi_restore) {
2337       Dmsg0(100, OKstoreend);
2338       dir->fsend(OKstoreend);
2339       ret = 1;     /* we continue the loop, waiting for next part */
2340    } else {
2341       ret = 0;     /* we stop here */
2342    }
2343
2344    if (job_canceled(jcr)) {
2345       ret = 0;     /* we stop here */
2346    }
2347
2348    if (ret == 0) {
2349       end_restore_cmd(jcr);  /* stopping so send bEventEndRestoreJob */
2350    }
2351
2352 free_mempool:
2353    free_and_null_pool_memory(args);
2354    free_and_null_pool_memory(restore_where);
2355    free_and_null_pool_memory(restore_rwhere);
2356
2357    return ret;
2358 }
2359
2360 static int end_restore_cmd(JCR *jcr)
2361 {
2362    Dmsg0(5, "end_restore_cmd\n");
2363    generate_plugin_event(jcr, bEventEndRestoreJob);
2364    return 0;                          /* return and terminate command loop */
2365 }
2366
2367 static int open_sd_read_session(JCR *jcr)
2368 {
2369    BSOCK *sd = jcr->store_bsock;
2370
2371    if (!sd) {
2372       Jmsg(jcr, M_FATAL, 0, _("Improper calling sequence.\n"));
2373       return 0;
2374    }
2375    Dmsg4(120, "VolSessId=%ld VolsessT=%ld SF=%ld EF=%ld\n",
2376       jcr->VolSessionId, jcr->VolSessionTime, jcr->StartFile, jcr->EndFile);
2377    Dmsg2(120, "JobId=%d vol=%s\n", jcr->JobId, "DummyVolume");
2378    /*
2379     * Open Read Session with Storage daemon
2380     */
2381    sd->fsend(read_open, "DummyVolume",
2382       jcr->VolSessionId, jcr->VolSessionTime, jcr->StartFile, jcr->EndFile,
2383       jcr->StartBlock, jcr->EndBlock);
2384    Dmsg1(110, ">stored: %s", sd->msg);
2385
2386    /*
2387     * Get ticket number
2388     */
2389    if (bget_msg(sd) >= 0) {
2390       Dmsg1(110, "filed<stored: %s", sd->msg);
2391       if (sscanf(sd->msg, OK_open, &jcr->Ticket) != 1) {
2392          Jmsg(jcr, M_FATAL, 0, _("Bad response to SD read open: %s\n"), sd->msg);
2393          return 0;
2394       }
2395       Dmsg1(110, "filed: got Ticket=%d\n", jcr->Ticket);
2396    } else {
2397       Jmsg(jcr, M_FATAL, 0, _("Bad response from stored to read open command\n"));
2398       return 0;
2399    }
2400
2401    /*
2402     * Use interactive session for the current restore
2403     */
2404    if (jcr->interactive_session) {
2405       sd->fsend(read_ctrl, jcr->Ticket);
2406       Dmsg1(110, ">stored: %s", sd->msg);
2407    }
2408
2409    /*
2410     * Start read of data with Storage daemon
2411     */
2412    sd->fsend(read_data, jcr->Ticket);
2413    Dmsg1(110, ">stored: %s", sd->msg);
2414
2415    /*
2416     * Get OK data
2417     */
2418    if (!response(jcr, sd, OK_data, "Read Data")) {
2419       return 0;
2420    }
2421    return 1;
2422 }
2423
2424 /**
2425  * Destroy the Job Control Record and associated
2426  * resources (sockets).
2427  */
2428 static void filed_free_jcr(JCR *jcr)
2429 {
2430    if (jcr->dir_bsock) {
2431       free_bsock(jcr->dir_bsock);
2432       jcr->dir_bsock = NULL;
2433    }
2434    if (jcr->sd_calls_client_bsock) {
2435       free_bsock(jcr->sd_calls_client_bsock);
2436       jcr->sd_calls_client_bsock = NULL;
2437    }
2438    if (jcr->store_bsock) {
2439       free_bsock(jcr->store_bsock);
2440       jcr->store_bsock = NULL;
2441    }
2442    if (jcr->last_fname) {
2443       free_pool_memory(jcr->last_fname);
2444    }
2445    free_plugins(jcr);                 /* release instantiated plugins */
2446    free_runscripts(jcr->RunScripts);
2447    delete jcr->RunScripts;
2448    free_path_list(jcr);
2449
2450    if (jcr->JobId != 0)
2451       write_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
2452
2453    return;
2454 }
2455
2456 /**
2457  * Get response from Storage daemon to a command we
2458  * sent. Check that the response is OK.
2459  *
2460  *  Returns: 0 on failure
2461  *           1 on success
2462  */
2463 int response(JCR *jcr, BSOCK *sd, char *resp, const char *cmd)
2464 {
2465    int ret;
2466
2467    if (sd->errors) {
2468       return 0;
2469    }
2470    if ((ret = bget_msg(sd)) > 0) {
2471       Dmsg0(110, sd->msg);
2472       if (strcmp(sd->msg, resp) == 0) {
2473          return 1;
2474       }
2475    }
2476    if (job_canceled(jcr)) {
2477       return 0;                       /* if canceled avoid useless error messages */
2478    }
2479    if (sd->is_error()) {
2480       Jmsg2(jcr, M_FATAL, 0, _("Comm error with SD. bad response to %s. ERR=%s\n"),
2481          cmd, sd->bstrerror());
2482    } else {
2483       char buf[256];
2484       if (ret > 0) {
2485          Jmsg4(jcr, M_FATAL, 0, _("Bad response from SD to %s command. Wanted %s, got len=%ld msg=\"%s\"\n"),
2486             cmd, resp, sd->msglen, smartdump(sd->msg, sd->msglen, buf, sizeof(buf)));
2487       } else {
2488          Jmsg3(jcr, M_FATAL, 0, _("Bad response from SD to %s command. Wanted %s, got SIGNAL %s\n"),
2489             cmd, resp, bnet_sig_to_ascii(ret));
2490       }
2491    }
2492    return 0;
2493 }