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