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