]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/job.c
Fix #1370 about the implementation of the "Exclude Dir Containing" option on FD.
[bacula/bacula] / bacula / src / filed / job.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *  Bacula File Daemon Job processing
30  *
31  *    Kern Sibbald, October MM
32  *
33  *   Version $Id$
34  *
35  */
36
37 #include "bacula.h"
38 #include "filed.h"
39
40 #if defined(WIN32_VSS)
41 #include "vss.h"
42
43 static pthread_mutex_t vss_mutex = PTHREAD_MUTEX_INITIALIZER;
44 static int enable_vss = 0;
45 #endif
46
47 /*
48  * As Windows saves ACLs as part of the standard backup stream
49  * we just pretend here that is has implicit acl support.
50  */
51 #if defined(HAVE_ACL) || defined(HAVE_WIN32)
52 const bool have_acl = true;
53 #else
54 const bool have_acl = false;
55 #endif
56
57 #if defined(HAVE_XATTR)
58 const bool have_xattr = true;
59 #else
60 const bool have_xattr = false;
61 #endif
62
63 extern CLIENT *me;                    /* our client resource */
64
65 /* Imported functions */
66 extern int status_cmd(JCR *jcr);
67 extern int qstatus_cmd(JCR *jcr);
68 extern int accurate_cmd(JCR *jcr);
69
70 /* Forward referenced functions */
71 static int backup_cmd(JCR *jcr);
72 static int bootstrap_cmd(JCR *jcr);
73 static int cancel_cmd(JCR *jcr);
74 static int setdebug_cmd(JCR *jcr);
75 static int estimate_cmd(JCR *jcr);
76 static int hello_cmd(JCR *jcr);
77 static int job_cmd(JCR *jcr);
78 static int fileset_cmd(JCR *jcr);
79 static int level_cmd(JCR *jcr);
80 static int verify_cmd(JCR *jcr);
81 static int restore_cmd(JCR *jcr);
82 static int end_restore_cmd(JCR *jcr);
83 static int storage_cmd(JCR *jcr);
84 static int session_cmd(JCR *jcr);
85 static int response(JCR *jcr, BSOCK *sd, char *resp, const char *cmd);
86 static void filed_free_jcr(JCR *jcr);
87 static int open_sd_read_session(JCR *jcr);
88 static int send_bootstrap_file(JCR *jcr);
89 static int runscript_cmd(JCR *jcr);
90 static int runbefore_cmd(JCR *jcr);
91 static int runafter_cmd(JCR *jcr);
92 static int runbeforenow_cmd(JCR *jcr);
93 static void set_options(findFOPTS *fo, const char *opts);
94 static void set_storage_auth_key(JCR *jcr, char *key);
95
96 /* Exported functions */
97
98 struct s_cmds {
99    const char *cmd;
100    int (*func)(JCR *);
101    int monitoraccess; /* specify if monitors have access to this function */
102 };
103
104 /*
105  * The following are the recognized commands from the Director.
106  */
107 static struct s_cmds cmds[] = {
108    {"backup",       backup_cmd,    0},
109    {"cancel",       cancel_cmd,    0},
110    {"setdebug=",    setdebug_cmd,  0},
111    {"estimate",     estimate_cmd,  0},
112    {"Hello",        hello_cmd,     1},
113    {"fileset",      fileset_cmd,   0},
114    {"JobId=",       job_cmd,       0},
115    {"level = ",     level_cmd,     0},
116    {"restore",      restore_cmd,   0},
117    {"endrestore",   end_restore_cmd, 0},
118    {"session",      session_cmd,   0},
119    {"status",       status_cmd,    1},
120    {".status",      qstatus_cmd,   1},
121    {"storage ",     storage_cmd,   0},
122    {"verify",       verify_cmd,    0},
123    {"bootstrap",    bootstrap_cmd, 0},
124    {"RunBeforeNow", runbeforenow_cmd, 0},
125    {"RunBeforeJob", runbefore_cmd, 0},
126    {"RunAfterJob",  runafter_cmd,  0},
127    {"Run",          runscript_cmd, 0},
128    {"accurate",     accurate_cmd,  0},
129    {NULL,       NULL}                  /* list terminator */
130 };
131
132 /* Commands received from director that need scanning */
133 static char jobcmd[]      = "JobId=%d Job=%127s SDid=%d SDtime=%d Authorization=%100s";
134 static char storaddr[]    = "storage address=%s port=%d ssl=%d Authorization=%100s";
135 static char storaddr_v1[] = "storage address=%s port=%d ssl=%d";
136 static char sessioncmd[]  = "session %127s %ld %ld %ld %ld %ld %ld\n";
137 static char restorecmd[]  = "restore replace=%c prelinks=%d where=%s\n";
138 static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n";
139 static char restorecmdR[] = "restore replace=%c prelinks=%d regexwhere=%s\n";
140 static char verifycmd[]   = "verify level=%30s";
141 static char estimatecmd[] = "estimate listing=%d";
142 static char runbefore[]   = "RunBeforeJob %s";
143 static char runafter[]    = "RunAfterJob %s";
144 static char runscript[]   = "Run OnSuccess=%d OnFailure=%d AbortOnError=%d When=%d Command=%s";
145
146 /* Responses sent to Director */
147 static char errmsg[]      = "2999 Invalid command\n";
148 static char no_auth[]     = "2998 No Authorization\n";
149 static char invalid_cmd[] = "2997 Invalid command for a Director with Monitor directive enabled.\n";
150 static char OKinc[]       = "2000 OK include\n";
151 static char OKest[]       = "2000 OK estimate files=%s bytes=%s\n";
152 static char OKlevel[]     = "2000 OK level\n";
153 static char OKbackup[]    = "2000 OK backup\n";
154 static char OKbootstrap[] = "2000 OK bootstrap\n";
155 static char OKverify[]    = "2000 OK verify\n";
156 static char OKrestore[]   = "2000 OK restore\n";
157 static char OKsession[]   = "2000 OK session\n";
158 static char OKstore[]     = "2000 OK storage\n";
159 static char OKstoreend[]  = "2000 OK storage end\n";
160 static char OKjob[]       = "2000 OK Job %s (%s) %s,%s,%s";
161 static char OKsetdebug[]  = "2000 OK setdebug=%d\n";
162 static char BADjob[]      = "2901 Bad Job\n";
163 static char EndJob[]      = "2800 End Job TermCode=%d JobFiles=%u ReadBytes=%s"
164                             " JobBytes=%s Errors=%u VSS=%d Encrypt=%d\n";
165 static char OKRunBefore[] = "2000 OK RunBefore\n";
166 static char OKRunBeforeNow[] = "2000 OK RunBeforeNow\n";
167 static char OKRunAfter[]  = "2000 OK RunAfter\n";
168 static char OKRunScript[] = "2000 OK RunScript\n";
169 static char BADcmd[]      = "2902 Bad %s\n";
170
171
172 /* Responses received from Storage Daemon */
173 static char OK_end[]       = "3000 OK end\n";
174 static char OK_close[]     = "3000 OK close Status = %d\n";
175 static char OK_open[]      = "3000 OK open ticket = %d\n";
176 static char OK_data[]      = "3000 OK data\n";
177 static char OK_append[]    = "3000 OK append data\n";
178 static char OKSDbootstrap[]= "3000 OK bootstrap\n";
179
180
181 /* Commands sent to Storage Daemon */
182 static char append_open[]  = "append open session\n";
183 static char append_data[]  = "append data %d\n";
184 static char append_end[]   = "append end session %d\n";
185 static char append_close[] = "append close session %d\n";
186 static char read_open[]    = "read open session = %s %ld %ld %ld %ld %ld %ld\n";
187 static char read_data[]    = "read data %d\n";
188 static char read_close[]   = "read close session %d\n";
189
190 /*
191  * Accept requests from a Director
192  *
193  * NOTE! We are running as a separate thread
194  *
195  * Send output one line
196  * at a time followed by a zero length transmission.
197  *
198  * Return when the connection is terminated or there
199  * is an error.
200  *
201  * Basic task here is:
202  *   Authenticate Director (during Hello command).
203  *   Accept commands one at a time from the Director
204  *     and execute them.
205  *
206  * Concerning ClientRunBefore/After, the sequence of events
207  * is rather critical. If they are not done in the right
208  * order one can easily get FD->SD timeouts if the script
209  * runs a long time.
210  *
211  * The current sequence of events is:
212  *  1. Dir starts job with FD
213  *  2. Dir connects to SD
214  *  3. Dir connects to FD
215  *  4. FD connects to SD
216  *  5. FD gets/runs ClientRunBeforeJob and sends ClientRunAfterJob
217  *  6. Dir sends include/exclude
218  *  7. FD sends data to SD
219  *  8. SD/FD disconnects while SD despools data and attributes (optional)
220  *  9. FD runs ClientRunAfterJob
221  */
222
223 void *handle_client_request(void *dirp)
224 {
225    int i;
226    bool found, quit;
227    JCR *jcr;
228    BSOCK *dir = (BSOCK *)dirp;
229    const char jobname[12] = "*Director*";
230
231    jcr = new_jcr(sizeof(JCR), filed_free_jcr); /* create JCR */
232    jcr->dir_bsock = dir;
233    jcr->ff = init_find_files();
234    jcr->start_time = time(NULL);
235    jcr->RunScripts = New(alist(10, not_owned_by_alist));
236    jcr->last_fname = get_pool_memory(PM_FNAME);
237    jcr->last_fname[0] = 0;
238    jcr->client_name = get_memory(strlen(my_name) + 1);
239    pm_strcpy(jcr->client_name, my_name);
240    bstrncpy(jcr->Job, jobname, sizeof(jobname));  /* dummy */
241    jcr->crypto.pki_sign = me->pki_sign;
242    jcr->crypto.pki_encrypt = me->pki_encrypt;
243    jcr->crypto.pki_keypair = me->pki_keypair;
244    jcr->crypto.pki_signers = me->pki_signers;
245    jcr->crypto.pki_recipients = me->pki_recipients;
246    dir->set_jcr(jcr);
247    enable_backup_privileges(NULL, 1 /* ignore_errors */);
248
249    /**********FIXME******* add command handler error code */
250
251    for (quit=false; !quit;) {
252       /* Read command */
253       if (dir->recv() < 0) {
254          break;               /* connection terminated */
255       }
256       dir->msg[dir->msglen] = 0;
257       Dmsg1(100, "<dird: %s", dir->msg);
258       found = false;
259       for (i=0; cmds[i].cmd; i++) {
260          if (strncmp(cmds[i].cmd, dir->msg, strlen(cmds[i].cmd)) == 0) {
261             found = true;         /* indicate command found */
262             if (!jcr->authenticated && cmds[i].func != hello_cmd) {
263                dir->fsend(no_auth);
264                dir->signal(BNET_EOD);
265                break;
266             }
267             if ((jcr->authenticated) && (!cmds[i].monitoraccess) && (jcr->director->monitor)) {
268                Dmsg1(100, "Command \"%s\" is invalid.\n", cmds[i].cmd);
269                dir->fsend(invalid_cmd);
270                dir->signal(BNET_EOD);
271                break;
272             }
273             Dmsg1(100, "Executing %s command.\n", cmds[i].cmd);
274             if (!cmds[i].func(jcr)) {         /* do command */
275                quit = true;         /* error or fully terminated, get out */
276                Dmsg1(100, "Quit command loop. Canceled=%d\n", job_canceled(jcr));
277             }
278             break;
279          }
280       }
281       if (!found) {              /* command not found */
282          dir->fsend(errmsg);
283          quit = true;
284          break;
285       }
286    }
287
288    /* Inform Storage daemon that we are done */
289    if (jcr->store_bsock) {
290       jcr->store_bsock->signal(BNET_TERMINATE);
291    }
292
293    /* Run the after job */
294    run_scripts(jcr, jcr->RunScripts, "ClientAfterJob");
295
296    if (jcr->JobId) {            /* send EndJob if running a job */
297       char ed1[50], ed2[50];
298       /* Send termination status back to Dir */
299       dir->fsend(EndJob, jcr->JobStatus, jcr->JobFiles,
300                  edit_uint64(jcr->ReadBytes, ed1),
301                  edit_uint64(jcr->JobBytes, ed2), jcr->JobErrors, jcr->VSS,
302                  jcr->crypto.pki_encrypt);
303       Dmsg1(110, "End FD msg: %s\n", dir->msg);
304    }
305
306    generate_daemon_event(jcr, "JobEnd");
307    generate_plugin_event(jcr, bEventJobEnd);
308
309    dequeue_messages(jcr);             /* send any queued messages */
310
311    /* Inform Director that we are done */
312    dir->signal(BNET_TERMINATE);
313
314    free_plugins(jcr);                 /* release instantiated plugins */
315
316    /* Clean up fileset */
317    FF_PKT *ff = jcr->ff;
318    findFILESET *fileset = ff->fileset;
319    if (fileset) {
320       int i, j, k;
321       /* Delete FileSet Include lists */
322       for (i=0; i<fileset->include_list.size(); i++) {
323          findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i);
324          for (j=0; j<incexe->opts_list.size(); j++) {
325             findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
326             for (k=0; k<fo->regex.size(); k++) {
327                regfree((regex_t *)fo->regex.get(k));
328             }
329             for (k=0; k<fo->regexdir.size(); k++) {
330                regfree((regex_t *)fo->regexdir.get(k));
331             }
332             for (k=0; k<fo->regexfile.size(); k++) {
333                regfree((regex_t *)fo->regexfile.get(k));
334             }
335             fo->regex.destroy();
336             fo->regexdir.destroy();
337             fo->regexfile.destroy();
338             fo->wild.destroy();
339             fo->wilddir.destroy();
340             fo->wildfile.destroy();
341             fo->wildbase.destroy();
342             fo->base.destroy();
343             fo->fstype.destroy();
344             fo->drivetype.destroy();
345          }
346          incexe->opts_list.destroy();
347          incexe->name_list.destroy();
348          incexe->plugin_list.destroy();
349          if (incexe->ignoredir) {
350             free(incexe->ignoredir);
351          }
352       }
353       fileset->include_list.destroy();
354
355       /* Delete FileSet Exclude lists */
356       for (i=0; i<fileset->exclude_list.size(); i++) {
357          findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i);
358          for (j=0; j<incexe->opts_list.size(); j++) {
359             findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
360             fo->regex.destroy();
361             fo->regexdir.destroy();
362             fo->regexfile.destroy();
363             fo->wild.destroy();
364             fo->wilddir.destroy();
365             fo->wildfile.destroy();
366             fo->wildbase.destroy();
367             fo->base.destroy();
368             fo->fstype.destroy();
369             fo->drivetype.destroy();
370          }
371          incexe->opts_list.destroy();
372          incexe->name_list.destroy();
373          incexe->plugin_list.destroy();
374          if (incexe->ignoredir) {
375             free(incexe->ignoredir);
376          }
377       }
378       fileset->exclude_list.destroy();
379       free(fileset);
380    }
381    ff->fileset = NULL;
382    Dmsg0(100, "Calling term_find_files\n");
383    term_find_files(jcr->ff);
384    jcr->ff = NULL;
385    Dmsg0(100, "Done with term_find_files\n");
386    free_jcr(jcr);                     /* destroy JCR record */
387    Dmsg0(100, "Done with free_jcr\n");
388    Dsm_check(1);
389    return NULL;
390 }
391
392 /*
393  * Hello from Director he must identify himself and provide his
394  *  password.
395  */
396 static int hello_cmd(JCR *jcr)
397 {
398    Dmsg0(120, "Calling Authenticate\n");
399    if (!authenticate_director(jcr)) {
400       return 0;
401    }
402    Dmsg0(120, "OK Authenticate\n");
403    jcr->authenticated = true;
404    return 1;
405 }
406
407 /*
408  * Cancel a Job
409  */
410 static int cancel_cmd(JCR *jcr)
411 {
412    BSOCK *dir = jcr->dir_bsock;
413    char Job[MAX_NAME_LENGTH];
414    JCR *cjcr;
415
416    if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) {
417       if (!(cjcr=get_jcr_by_full_name(Job))) {
418          dir->fsend(_("2901 Job %s not found.\n"), Job);
419       } else {
420          if (cjcr->store_bsock) {
421             cjcr->store_bsock->set_timed_out();
422             cjcr->store_bsock->set_terminated();
423             pthread_kill(cjcr->my_thread_id, TIMEOUT_SIGNAL);
424          }
425          generate_plugin_event(cjcr, bEventCancelCommand, NULL);
426          set_jcr_job_status(cjcr, JS_Canceled);
427          free_jcr(cjcr);
428          dir->fsend(_("2001 Job %s marked to be canceled.\n"), Job);
429       }
430    } else {
431       dir->fsend(_("2902 Error scanning cancel command.\n"));
432    }
433    dir->signal(BNET_EOD);
434    return 1;
435 }
436
437
438 /*
439  * Set debug level as requested by the Director
440  *
441  */
442 static int setdebug_cmd(JCR *jcr)
443 {
444    BSOCK *dir = jcr->dir_bsock;
445    int level, trace_flag;
446
447    Dmsg1(110, "setdebug_cmd: %s", dir->msg);
448    if (sscanf(dir->msg, "setdebug=%d trace=%d", &level, &trace_flag) != 2 || level < 0) {
449       pm_strcpy(jcr->errmsg, dir->msg);
450       dir->fsend(_("2991 Bad setdebug command: %s\n"), jcr->errmsg);
451       return 0;
452    }
453    debug_level = level;
454    set_trace(trace_flag);
455    return dir->fsend(OKsetdebug, level);
456 }
457
458
459 static int estimate_cmd(JCR *jcr)
460 {
461    BSOCK *dir = jcr->dir_bsock;
462    char ed1[50], ed2[50];
463
464    if (sscanf(dir->msg, estimatecmd, &jcr->listing) != 1) {
465       pm_strcpy(jcr->errmsg, dir->msg);
466       Jmsg(jcr, M_FATAL, 0, _("Bad estimate command: %s"), jcr->errmsg);
467       dir->fsend(_("2992 Bad estimate command.\n"));
468       return 0;
469    }
470    make_estimate(jcr);
471    dir->fsend(OKest, edit_uint64_with_commas(jcr->num_files_examined, ed1),
472       edit_uint64_with_commas(jcr->JobBytes, ed2));
473    dir->signal(BNET_EOD);
474    return 1;
475 }
476
477 /*
478  * Get JobId and Storage Daemon Authorization key from Director
479  */
480 static int job_cmd(JCR *jcr)
481 {
482    BSOCK *dir = jcr->dir_bsock;
483    POOL_MEM sd_auth_key(PM_MESSAGE);
484    sd_auth_key.check_size(dir->msglen);
485
486    if (sscanf(dir->msg, jobcmd,  &jcr->JobId, jcr->Job,
487               &jcr->VolSessionId, &jcr->VolSessionTime, 
488               sd_auth_key.c_str()) != 5) {
489       pm_strcpy(jcr->errmsg, dir->msg);
490       Jmsg(jcr, M_FATAL, 0, _("Bad Job Command: %s"), jcr->errmsg);
491       dir->fsend(BADjob);
492       return 0;
493    }
494    set_storage_auth_key(jcr, sd_auth_key.c_str());
495    Dmsg2(120, "JobId=%d Auth=%s\n", jcr->JobId, jcr->sd_auth_key);
496    Mmsg(jcr->errmsg, "JobId=%d Job=%s", jcr->JobId, jcr->Job);
497    new_plugins(jcr);                  /* instantiate plugins for this jcr */
498    generate_plugin_event(jcr, bEventJobStart, (void *)jcr->errmsg);
499    return dir->fsend(OKjob, VERSION, LSMDATE, HOST_OS, DISTNAME, DISTVER);
500 }
501
502 static int runbefore_cmd(JCR *jcr)
503 {
504    bool ok;
505    BSOCK *dir = jcr->dir_bsock;
506    POOLMEM *cmd = get_memory(dir->msglen+1);
507    RUNSCRIPT *script;
508
509    Dmsg1(100, "runbefore_cmd: %s", dir->msg);
510    if (sscanf(dir->msg, runbefore, cmd) != 1) {
511       pm_strcpy(jcr->errmsg, dir->msg);
512       Jmsg1(jcr, M_FATAL, 0, _("Bad RunBeforeJob command: %s\n"), jcr->errmsg);
513       dir->fsend(_("2905 Bad RunBeforeJob command.\n"));
514       free_memory(cmd);
515       return 0;
516    }
517    unbash_spaces(cmd);
518
519    /* Run the command now */
520    script = new_runscript();
521    script->set_command(cmd);
522    script->when = SCRIPT_Before;
523    ok = script->run(jcr, "ClientRunBeforeJob");
524    free_runscript(script);
525
526    free_memory(cmd);
527    if (ok) {
528       dir->fsend(OKRunBefore);
529       return 1;
530    } else {
531       dir->fsend(_("2905 Bad RunBeforeJob command.\n"));
532       return 0;
533    }
534 }
535
536 static int runbeforenow_cmd(JCR *jcr)
537 {
538    BSOCK *dir = jcr->dir_bsock;
539
540    run_scripts(jcr, jcr->RunScripts, "ClientBeforeJob");
541    if (job_canceled(jcr)) {
542       dir->fsend(_("2905 Bad RunBeforeNow command.\n"));
543       Dmsg0(100, "Back from run_scripts ClientBeforeJob now: FAILED\n");
544       return 0;
545    } else {
546       dir->fsend(OKRunBeforeNow);
547       Dmsg0(100, "Back from run_scripts ClientBeforeJob now: OK\n");
548       return 1;
549    }
550 }
551
552 static int runafter_cmd(JCR *jcr)
553 {
554    BSOCK *dir = jcr->dir_bsock;
555    POOLMEM *msg = get_memory(dir->msglen+1);
556    RUNSCRIPT *cmd;
557
558    Dmsg1(100, "runafter_cmd: %s", dir->msg);
559    if (sscanf(dir->msg, runafter, msg) != 1) {
560       pm_strcpy(jcr->errmsg, dir->msg);
561       Jmsg1(jcr, M_FATAL, 0, _("Bad RunAfter command: %s\n"), jcr->errmsg);
562       dir->fsend(_("2905 Bad RunAfterJob command.\n"));
563       free_memory(msg);
564       return 0;
565    }
566    unbash_spaces(msg);
567
568    cmd = new_runscript();
569    cmd->set_command(msg);
570    cmd->on_success = true;
571    cmd->on_failure = false;
572    cmd->when = SCRIPT_After;
573
574    jcr->RunScripts->append(cmd);
575
576    free_pool_memory(msg);
577    return dir->fsend(OKRunAfter);
578 }
579
580 static int runscript_cmd(JCR *jcr)
581 {
582    BSOCK *dir = jcr->dir_bsock;
583    POOLMEM *msg = get_memory(dir->msglen+1);
584    int on_success, on_failure, fail_on_error;
585
586    RUNSCRIPT *cmd = new_runscript() ;
587
588    Dmsg1(100, "runscript_cmd: '%s'\n", dir->msg);
589    /* Note, we cannot sscanf into bools */
590    if (sscanf(dir->msg, runscript, &on_success, 
591                                   &on_failure,
592                                   &fail_on_error,
593                                   &cmd->when,
594                                   msg) != 5) {
595       pm_strcpy(jcr->errmsg, dir->msg);
596       Jmsg1(jcr, M_FATAL, 0, _("Bad RunScript command: %s\n"), jcr->errmsg);
597       dir->fsend(_("2905 Bad RunScript command.\n"));
598       free_runscript(cmd);
599       free_memory(msg);
600       return 0;
601    }
602    cmd->on_success = on_success;
603    cmd->on_failure = on_failure;
604    cmd->fail_on_error = fail_on_error;
605    unbash_spaces(msg);
606
607    cmd->set_command(msg);
608    cmd->debug();
609    jcr->RunScripts->append(cmd);
610
611    free_pool_memory(msg);
612    return dir->fsend(OKRunScript);
613 }
614
615
616 static bool init_fileset(JCR *jcr)
617 {
618    FF_PKT *ff;
619    findFILESET *fileset;
620
621    if (!jcr->ff) {
622       return false;
623    }
624    ff = jcr->ff;
625    if (ff->fileset) {
626       return false;
627    }
628    fileset = (findFILESET *)malloc(sizeof(findFILESET));
629    memset(fileset, 0, sizeof(findFILESET));
630    ff->fileset = fileset;
631    fileset->state = state_none;
632    fileset->include_list.init(1, true);
633    fileset->exclude_list.init(1, true);
634    return true;
635 }
636
637 static findFOPTS *start_options(FF_PKT *ff)
638 {
639    int state = ff->fileset->state;
640    findINCEXE *incexe = ff->fileset->incexe;
641
642    if (state != state_options) {
643       ff->fileset->state = state_options;
644       findFOPTS *fo = (findFOPTS *)malloc(sizeof(findFOPTS));
645       memset(fo, 0, sizeof(findFOPTS));
646       fo->regex.init(1, true);
647       fo->regexdir.init(1, true);
648       fo->regexfile.init(1, true);
649       fo->wild.init(1, true);
650       fo->wilddir.init(1, true);
651       fo->wildfile.init(1, true);
652       fo->wildbase.init(1, true);
653       fo->base.init(1, true);
654       fo->fstype.init(1, true);
655       fo->drivetype.init(1, true);
656       incexe->current_opts = fo;
657       incexe->opts_list.append(fo);
658    }
659    return incexe->current_opts;
660
661 }
662
663 /*
664  * Add fname to include/exclude fileset list. First check for
665  * | and < and if necessary perform command.
666  */
667 static void add_file_to_fileset(JCR *jcr, const char *fname, findFILESET *fileset,
668                                 bool is_file)
669 {
670    char *p;
671    BPIPE *bpipe;
672    POOLMEM *fn;
673    FILE *ffd;
674    char buf[1000];
675    int ch;
676    int stat;
677
678    p = (char *)fname;
679    ch = (uint8_t)*p;
680    switch (ch) {
681    case '|':
682       p++;                            /* skip over | */
683       fn = get_pool_memory(PM_FNAME);
684       fn = edit_job_codes(jcr, fn, p, "");
685       bpipe = open_bpipe(fn, 0, "r");
686       if (!bpipe) {
687          berrno be;
688          Jmsg(jcr, M_FATAL, 0, _("Cannot run program: %s. ERR=%s\n"),
689             p, be.bstrerror());
690          free_pool_memory(fn);
691          return;
692       }
693       free_pool_memory(fn);
694       while (fgets(buf, sizeof(buf), bpipe->rfd)) {
695          strip_trailing_junk(buf);
696          if (is_file) {
697             fileset->incexe->name_list.append(new_dlistString(buf));
698          } else {
699             fileset->incexe->plugin_list.append(new_dlistString(buf));
700          }
701       }
702       if ((stat=close_bpipe(bpipe)) != 0) {
703          berrno be;
704          Jmsg(jcr, M_FATAL, 0, _("Error running program: %s. stat=%d: ERR=%s\n"),
705             p, be.code(stat), be.bstrerror(stat));
706          return;
707       }
708       break;
709    case '<':
710       Dmsg1(100, "Doing < of '%s' include on client.\n", p + 1);
711       p++;                      /* skip over < */
712       if ((ffd = fopen(p, "rb")) == NULL) {
713          berrno be;
714          Jmsg(jcr, M_FATAL, 0, _("Cannot open FileSet input file: %s. ERR=%s\n"),
715             p, be.bstrerror());
716          return;
717       }
718       while (fgets(buf, sizeof(buf), ffd)) {
719          strip_trailing_junk(buf);
720          Dmsg1(100, "%s\n", buf);
721          if (is_file) {
722             fileset->incexe->name_list.append(new_dlistString(buf));
723          } else {
724             fileset->incexe->plugin_list.append(new_dlistString(buf));
725          }
726       }
727       fclose(ffd);
728       break;
729    default:
730       if (is_file) {
731          fileset->incexe->name_list.append(new_dlistString(fname));
732       } else {
733          if (me->plugin_directory) {
734             fileset->incexe->plugin_list.append(new_dlistString(fname));
735          } else {
736             Jmsg(jcr, M_FATAL, 0, _("Plugin Directory not defined. Cannot use plugin: \"%\"\n"),
737                fname);
738          }
739       }
740       break;
741    }
742 }
743
744
745 static void add_fileset(JCR *jcr, const char *item)
746 {
747    FF_PKT *ff = jcr->ff;
748    findFILESET *fileset = ff->fileset;
749    int state = fileset->state;
750    findFOPTS *current_opts;
751
752    /* Get code, optional subcode, and position item past the dividing space */
753    Dmsg1(100, "%s\n", item);
754    int code = item[0];
755    if (code != '\0') {
756       ++item;
757    }
758    int subcode = ' ';               /* A space is always a valid subcode */
759    if (item[0] != '\0' && item[0] != ' ') {
760       subcode = item[0];
761       ++item;
762    }
763    if (*item == ' ') {
764       ++item;
765    }
766
767    /* Skip all lines we receive after an error */
768    if (state == state_error) {
769       Dmsg0(100, "State=error return\n");
770       return;
771    }
772
773    /*
774     * The switch tests the code for validity.
775     * The subcode is always good if it is a space, otherwise we must confirm.
776     * We set state to state_error first assuming the subcode is invalid,
777     * requiring state to be set in cases below that handle subcodes.
778     */
779    if (subcode != ' ') {
780       state = state_error;
781       Dmsg0(100, "Set state=error or double code.\n");
782    }
783    switch (code) {
784    case 'I':
785       /* New include */
786       fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE));
787       memset(fileset->incexe, 0, sizeof(findINCEXE));
788       fileset->incexe->opts_list.init(1, true);
789       fileset->incexe->name_list.init(); /* for dlist;  was 1,true for alist */
790       fileset->incexe->plugin_list.init();
791       fileset->include_list.append(fileset->incexe);
792       break;
793    case 'E':
794       /* New exclude */
795       fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE));
796       memset(fileset->incexe, 0, sizeof(findINCEXE));
797       fileset->incexe->opts_list.init(1, true);
798       fileset->incexe->name_list.init();
799       fileset->incexe->plugin_list.init();
800       fileset->exclude_list.append(fileset->incexe);
801       break;
802    case 'N':
803       state = state_none;
804       break;
805    case 'F':
806       /* File item to include or exclude list */
807       state = state_include;
808       add_file_to_fileset(jcr, item, fileset, true);
809       break;
810    case 'P':
811       /* Plugin item to include list */
812       state = state_include;
813       add_file_to_fileset(jcr, item, fileset, false);
814       break;
815    case 'R':
816       current_opts = start_options(ff);
817       regex_t *preg;
818       int rc;
819       char prbuf[500];
820       preg = (regex_t *)malloc(sizeof(regex_t));
821       if (current_opts->flags & FO_IGNORECASE) {
822          rc = regcomp(preg, item, REG_EXTENDED|REG_ICASE);
823       } else {
824          rc = regcomp(preg, item, REG_EXTENDED);
825       }
826       if (rc != 0) {
827          regerror(rc, preg, prbuf, sizeof(prbuf));
828          regfree(preg);
829          free(preg);
830          Jmsg(jcr, M_FATAL, 0, _("REGEX %s compile error. ERR=%s\n"), item, prbuf);
831          state = state_error;
832          break;
833       }
834       state = state_options;
835       if (subcode == ' ') {
836          current_opts->regex.append(preg);
837       } else if (subcode == 'D') {
838          current_opts->regexdir.append(preg);
839       } else if (subcode == 'F') {
840          current_opts->regexfile.append(preg);
841       } else {
842          state = state_error;
843       }
844       break;
845    case 'B':
846       current_opts = start_options(ff);
847       current_opts->base.append(bstrdup(item));
848       state = state_options;
849       break;
850    case 'X':
851       current_opts = start_options(ff);
852       state = state_options;
853       if (subcode == ' ') {
854          current_opts->fstype.append(bstrdup(item));
855       } else if (subcode == 'D') {
856          current_opts->drivetype.append(bstrdup(item));
857       } else {
858          state = state_error;
859       }
860       break;
861    case 'W':
862       current_opts = start_options(ff);
863       state = state_options;
864       if (subcode == ' ') {
865          current_opts->wild.append(bstrdup(item));
866       } else if (subcode == 'D') {
867          current_opts->wilddir.append(bstrdup(item));
868       } else if (subcode == 'F') {
869          current_opts->wildfile.append(bstrdup(item));
870       } else if (subcode == 'B') {
871          current_opts->wildbase.append(bstrdup(item));
872       } else {
873          state = state_error;
874       }
875       break;
876    case 'O':
877       current_opts = start_options(ff);
878       set_options(current_opts, item);
879       state = state_options;
880       break;
881    case 'Z':
882       state = state_include;
883       fileset->incexe->ignoredir = bstrdup(item);
884       break;
885    case 'D':
886       current_opts = start_options(ff);
887 //    current_opts->reader = bstrdup(item);
888       state = state_options;
889       break;
890    case 'T':
891       current_opts = start_options(ff);
892 //    current_opts->writer = bstrdup(item);
893       state = state_options;
894       break;
895    default:
896       Jmsg(jcr, M_FATAL, 0, _("Invalid FileSet command: %s\n"), item);
897       state = state_error;
898       break;
899    }
900    ff->fileset->state = state;
901 }
902
903 static bool term_fileset(JCR *jcr)
904 {
905    FF_PKT *ff = jcr->ff;
906
907 #ifdef xxx_DEBUG_CODE
908    findFILESET *fileset = ff->fileset;
909    int i, j, k;
910
911    for (i=0; i<fileset->include_list.size(); i++) {
912       findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i);
913       Dmsg0(400, "I\n");
914       for (j=0; j<incexe->opts_list.size(); j++) {
915          findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
916          for (k=0; k<fo->regex.size(); k++) {
917             Dmsg1(400, "R %s\n", (char *)fo->regex.get(k));
918          }
919          for (k=0; k<fo->regexdir.size(); k++) {
920             Dmsg1(400, "RD %s\n", (char *)fo->regexdir.get(k));
921          }
922          for (k=0; k<fo->regexfile.size(); k++) {
923             Dmsg1(400, "RF %s\n", (char *)fo->regexfile.get(k));
924          }
925          for (k=0; k<fo->wild.size(); k++) {
926             Dmsg1(400, "W %s\n", (char *)fo->wild.get(k));
927          }
928          for (k=0; k<fo->wilddir.size(); k++) {
929             Dmsg1(400, "WD %s\n", (char *)fo->wilddir.get(k));
930          }
931          for (k=0; k<fo->wildfile.size(); k++) {
932             Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k));
933          }
934          for (k=0; k<fo->wildbase.size(); k++) {
935             Dmsg1(400, "WB %s\n", (char *)fo->wildbase.get(k));
936          }
937          for (k=0; k<fo->base.size(); k++) {
938             Dmsg1(400, "B %s\n", (char *)fo->base.get(k));
939          }
940          for (k=0; k<fo->fstype.size(); k++) {
941             Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k));
942          }
943          for (k=0; k<fo->drivetype.size(); k++) {
944             Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k));
945          }
946       }
947       if (incexe->ignoredir) {
948          Dmsg1(400, "Z %s\n", incexe->ignoredir);
949       }
950       dlistString *node;
951       foreach_dlist(node, &incexe->name_list) {
952          Dmsg1(400, "F %s\n", node->c_str());
953       }
954       foreach_dlist(node, &incexe->plugin_list) {
955          Dmsg1(400, "P %s\n", node->c_str());
956       }
957    }
958    for (i=0; i<fileset->exclude_list.size(); i++) {
959       findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i);
960       Dmsg0(400, "E\n");
961       for (j=0; j<incexe->opts_list.size(); j++) {
962          findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
963          for (k=0; k<fo->regex.size(); k++) {
964             Dmsg1(400, "R %s\n", (char *)fo->regex.get(k));
965          }
966          for (k=0; k<fo->regexdir.size(); k++) {
967             Dmsg1(400, "RD %s\n", (char *)fo->regexdir.get(k));
968          }
969          for (k=0; k<fo->regexfile.size(); k++) {
970             Dmsg1(400, "RF %s\n", (char *)fo->regexfile.get(k));
971          }
972          for (k=0; k<fo->wild.size(); k++) {
973             Dmsg1(400, "W %s\n", (char *)fo->wild.get(k));
974          }
975          for (k=0; k<fo->wilddir.size(); k++) {
976             Dmsg1(400, "WD %s\n", (char *)fo->wilddir.get(k));
977          }
978          for (k=0; k<fo->wildfile.size(); k++) {
979             Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k));
980          }
981          for (k=0; k<fo->wildbase.size(); k++) {
982             Dmsg1(400, "WB %s\n", (char *)fo->wildbase.get(k));
983          }
984          for (k=0; k<fo->base.size(); k++) {
985             Dmsg1(400, "B %s\n", (char *)fo->base.get(k));
986          }
987          for (k=0; k<fo->fstype.size(); k++) {
988             Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k));
989          }
990          for (k=0; k<fo->drivetype.size(); k++) {
991             Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k));
992          }
993       }
994       dlistString *node;
995       foreach_dlist(node, incexe->name_list) {
996          Dmsg1(400, "F %s\n", node->c_str());
997       }
998       foreach_dlist(node, &incexe->plugin_list) {
999          Dmsg1(400, "P %s\n", node->c_str());
1000       }
1001    }
1002 #endif
1003    return ff->fileset->state != state_error;
1004 }
1005
1006
1007 /*
1008  * As an optimization, we should do this during
1009  *  "compile" time in filed/job.c, and keep only a bit mask
1010  *  and the Verify options.
1011  */
1012 static void set_options(findFOPTS *fo, const char *opts)
1013 {
1014    int j;
1015    const char *p;
1016    char strip[100];
1017
1018 // Commented out as it is not backward compatible - KES
1019 #ifdef HAVE_WIN32
1020 //   fo->flags |= FO_IGNORECASE; /* always ignorecase under windows */
1021 #endif
1022
1023    for (p=opts; *p; p++) {
1024       switch (*p) {
1025       case 'a':                 /* alway replace */
1026       case '0':                 /* no option */
1027          break;
1028       case 'e':
1029          fo->flags |= FO_EXCLUDE;
1030          break;
1031       case 'f':
1032          fo->flags |= FO_MULTIFS;
1033          break;
1034       case 'h':                 /* no recursion */
1035          fo->flags |= FO_NO_RECURSION;
1036          break;
1037       case 'H':                 /* no hard link handling */
1038          fo->flags |= FO_NO_HARDLINK;
1039          break;
1040       case 'i':
1041          fo->flags |= FO_IGNORECASE;
1042          break;
1043       case 'M':                 /* MD5 */
1044          fo->flags |= FO_MD5;
1045          break;
1046       case 'n':
1047          fo->flags |= FO_NOREPLACE;
1048          break;
1049       case 'p':                 /* use portable data format */
1050          fo->flags |= FO_PORTABLE;
1051          break;
1052       case 'R':                 /* Resource forks and Finder Info */
1053          fo->flags |= FO_HFSPLUS;
1054       case 'r':                 /* read fifo */
1055          fo->flags |= FO_READFIFO;
1056          break;
1057       case 'S':
1058          switch(*(p + 1)) {
1059          case '1':
1060             fo->flags |= FO_SHA1;
1061             p++;
1062             break;
1063 #ifdef HAVE_SHA2
1064          case '2':
1065             fo->flags |= FO_SHA256;
1066             p++;
1067             break;
1068          case '3':
1069             fo->flags |= FO_SHA512;
1070             p++;
1071             break;
1072 #endif
1073          default:
1074             /*
1075              * If 2 or 3 is seen here, SHA2 is not configured, so
1076              *  eat the option, and drop back to SHA-1.
1077              */
1078             if (p[1] == '2' || p[1] == '3') {
1079                p++;
1080             }
1081             fo->flags |= FO_SHA1;
1082             break;
1083          }
1084          break;
1085       case 's':
1086          fo->flags |= FO_SPARSE;
1087          break;
1088       case 'm':
1089          fo->flags |= FO_MTIMEONLY;
1090          break;
1091       case 'k':
1092          fo->flags |= FO_KEEPATIME;
1093          break;
1094       case 'A':
1095          fo->flags |= FO_ACL;
1096          break;
1097       case 'V':                  /* verify options */
1098          /* Copy Verify Options */
1099          for (j=0; *p && *p != ':'; p++) {
1100             fo->VerifyOpts[j] = *p;
1101             if (j < (int)sizeof(fo->VerifyOpts) - 1) {
1102                j++;
1103             }
1104          }
1105          fo->VerifyOpts[j] = 0;
1106          break;
1107       case 'C':                  /* accurate options */
1108          /* Copy Accurate Options */
1109          for (j=0; *p && *p != ':'; p++) {
1110             fo->AccurateOpts[j] = *p;
1111             if (j < (int)sizeof(fo->AccurateOpts) - 1) {
1112                j++;
1113             }
1114          }
1115          fo->AccurateOpts[j] = 0;
1116          break;
1117       case 'P':                  /* strip path */
1118          /* Get integer */
1119          p++;                    /* skip P */
1120          for (j=0; *p && *p != ':'; p++) {
1121             strip[j] = *p;
1122             if (j < (int)sizeof(strip) - 1) {
1123                j++;
1124             }
1125          }
1126          strip[j] = 0;
1127          fo->strip_path = atoi(strip);
1128          fo->flags |= FO_STRIPPATH;
1129          Dmsg2(100, "strip=%s strip_path=%d\n", strip, fo->strip_path);
1130          break;
1131       case 'w':
1132          fo->flags |= FO_IF_NEWER;
1133          break;
1134       case 'W':
1135          fo->flags |= FO_ENHANCEDWILD;
1136          break;
1137       case 'Z':                 /* gzip compression */
1138          fo->flags |= FO_GZIP;
1139          fo->GZIP_level = *++p - '0';
1140          break;
1141       case 'K':
1142          fo->flags |= FO_NOATIME;
1143          break;
1144       case 'c':
1145          fo->flags |= FO_CHKCHANGES;
1146          break;
1147       case 'N':
1148          fo->flags |= FO_HONOR_NODUMP;
1149          break;
1150       case 'X':
1151          fo->flags |= FO_XATTR;
1152          break;
1153       default:
1154          Emsg1(M_ERROR, 0, _("Unknown include/exclude option: %c\n"), *p);
1155          break;
1156       }
1157    }
1158 }
1159
1160
1161 /*
1162  * Director is passing his Fileset
1163  */
1164 static int fileset_cmd(JCR *jcr)
1165 {
1166    BSOCK *dir = jcr->dir_bsock;
1167
1168 #if defined(WIN32_VSS)
1169    int vss = 0;
1170
1171    sscanf(dir->msg, "fileset vss=%d", &vss);
1172    enable_vss = vss;
1173 #endif
1174
1175    if (!init_fileset(jcr)) {
1176       return 0;
1177    }
1178    while (dir->recv() >= 0) {
1179       strip_trailing_junk(dir->msg);
1180       Dmsg1(500, "Fileset: %s\n", dir->msg);
1181       add_fileset(jcr, dir->msg);
1182    }
1183    if (!term_fileset(jcr)) {
1184       return 0;
1185    }
1186    return dir->fsend(OKinc);
1187 }
1188
1189 static void free_bootstrap(JCR *jcr)
1190 {
1191    if (jcr->RestoreBootstrap) {
1192       unlink(jcr->RestoreBootstrap);
1193       free_pool_memory(jcr->RestoreBootstrap);
1194       jcr->RestoreBootstrap = NULL;
1195    }
1196 }
1197
1198
1199 static pthread_mutex_t bsr_mutex = PTHREAD_MUTEX_INITIALIZER;
1200 static uint32_t bsr_uniq = 0;
1201
1202 /* 
1203  * The Director sends us the bootstrap file, which
1204  *   we will in turn pass to the SD.
1205  */
1206 static int bootstrap_cmd(JCR *jcr)
1207 {
1208    BSOCK *dir = jcr->dir_bsock;
1209    POOLMEM *fname = get_pool_memory(PM_FNAME);
1210    FILE *bs;
1211
1212    free_bootstrap(jcr);
1213    P(bsr_mutex);
1214    bsr_uniq++;
1215    Mmsg(fname, "%s/%s.%s.%d.bootstrap", me->working_directory, me->hdr.name,
1216       jcr->Job, bsr_uniq);
1217    V(bsr_mutex);
1218    Dmsg1(400, "bootstrap=%s\n", fname);
1219    jcr->RestoreBootstrap = fname;
1220    bs = fopen(fname, "a+b");           /* create file */
1221    if (!bs) {
1222       berrno be;
1223       Jmsg(jcr, M_FATAL, 0, _("Could not create bootstrap file %s: ERR=%s\n"),
1224          jcr->RestoreBootstrap, be.bstrerror());
1225       /*
1226        * Suck up what he is sending to us so that he will then
1227        *   read our error message.
1228        */
1229       while (dir->recv() >= 0)
1230         {  }
1231       free_bootstrap(jcr);
1232       set_jcr_job_status(jcr, JS_ErrorTerminated);
1233       return 0;
1234    }
1235
1236    while (dir->recv() >= 0) {
1237        Dmsg1(200, "filed<dird: bootstrap: %s", dir->msg);
1238        fputs(dir->msg, bs);
1239    }
1240    fclose(bs);
1241    /*
1242     * Note, do not free the bootstrap yet -- it needs to be 
1243     *  sent to the SD 
1244     */
1245    return dir->fsend(OKbootstrap);
1246 }
1247
1248
1249 /*
1250  * Get backup level from Director
1251  *
1252  */
1253 static int level_cmd(JCR *jcr)
1254 {
1255    BSOCK *dir = jcr->dir_bsock;
1256    POOLMEM *level, *buf = NULL;
1257    int mtime_only;
1258
1259    level = get_memory(dir->msglen+1);
1260    Dmsg1(100, "level_cmd: %s", dir->msg);
1261    if (strstr(dir->msg, "accurate")) {
1262       jcr->accurate = true;
1263    }
1264    if (sscanf(dir->msg, "level = %s ", level) != 1) {
1265       goto bail_out;
1266    }
1267    /* Base backup requested? */
1268    if (strcmp(level, "base") == 0) {
1269       jcr->set_JobLevel(L_BASE);
1270    /* Full backup requested? */
1271    } else if (strcmp(level, "full") == 0) {
1272       jcr->set_JobLevel(L_FULL);
1273    } else if (strstr(level, "differential")) {
1274       jcr->set_JobLevel(L_DIFFERENTIAL);
1275       free_memory(level);
1276       return 1;
1277    } else if (strstr(level, "incremental")) {
1278       jcr->set_JobLevel(L_INCREMENTAL);
1279       free_memory(level);
1280       return 1;
1281    /*
1282     * We get his UTC since time, then sync the clocks and correct it
1283     *   to agree with our clock.
1284     */
1285    } else if (strcmp(level, "since_utime") == 0) {
1286       buf = get_memory(dir->msglen+1);
1287       utime_t since_time, adj;
1288       btime_t his_time, bt_start, rt=0, bt_adj=0;
1289       if (jcr->get_JobLevel() == L_NONE) {
1290          jcr->set_JobLevel(L_SINCE);     /* if no other job level set, do it now */
1291       }
1292       if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d",
1293                  buf, &mtime_only) != 2) {
1294          goto bail_out;
1295       }
1296       since_time = str_to_uint64(buf);  /* this is the since time */
1297       Dmsg1(100, "since_time=%lld\n", since_time);
1298       char ed1[50], ed2[50];
1299       /*
1300        * Sync clocks by polling him for the time. We take
1301        *   10 samples of his time throwing out the first two.
1302        */
1303       for (int i=0; i<10; i++) {
1304          bt_start = get_current_btime();
1305          dir->signal(BNET_BTIME);     /* poll for time */
1306          if (dir->recv() <= 0) {      /* get response */
1307             goto bail_out;
1308          }
1309          if (sscanf(dir->msg, "btime %s", buf) != 1) {
1310             goto bail_out;
1311          }
1312          if (i < 2) {                 /* toss first two results */
1313             continue;
1314          }
1315          his_time = str_to_uint64(buf);
1316          rt = get_current_btime() - bt_start; /* compute round trip time */
1317          Dmsg2(100, "Dirtime=%s FDtime=%s\n", edit_uint64(his_time, ed1),
1318                edit_uint64(bt_start, ed2));
1319          bt_adj +=  bt_start - his_time - rt/2;
1320          Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
1321       }
1322
1323       bt_adj = bt_adj / 8;            /* compute average time */
1324       Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
1325       adj = btime_to_utime(bt_adj);
1326       since_time += adj;              /* adjust for clock difference */
1327       /* Don't notify if time within 3 seconds */
1328       if (adj > 3 || adj < -3) {
1329          int type;
1330          if (adj > 600 || adj < -600) {
1331             type = M_WARNING;
1332          } else {
1333             type = M_INFO;
1334          }
1335          Jmsg(jcr, type, 0, _("DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n"), adj);
1336       }
1337       dir->signal(BNET_EOD);
1338
1339       Dmsg2(100, "adj=%lld since_time=%lld\n", adj, since_time);
1340       jcr->incremental = 1;           /* set incremental or decremental backup */
1341       jcr->mtime = since_time;        /* set since time */
1342       generate_plugin_event(jcr, bEventSince, (void *)(time_t)jcr->mtime);
1343    } else {
1344       Jmsg1(jcr, M_FATAL, 0, _("Unknown backup level: %s\n"), level);
1345       free_memory(level);
1346       return 0;
1347    }
1348    free_memory(level);
1349    if (buf) {
1350       free_memory(buf);
1351    }
1352    generate_plugin_event(jcr, bEventLevel, (void *)jcr->get_JobLevel());
1353    return dir->fsend(OKlevel);
1354
1355 bail_out:
1356    pm_strcpy(jcr->errmsg, dir->msg);
1357    Jmsg1(jcr, M_FATAL, 0, _("Bad level command: %s\n"), jcr->errmsg);
1358    free_memory(level);
1359    if (buf) {
1360       free_memory(buf);
1361    }
1362    return 0;
1363 }
1364
1365 /*
1366  * Get session parameters from Director -- this is for a Restore command
1367  */
1368 static int session_cmd(JCR *jcr)
1369 {
1370    BSOCK *dir = jcr->dir_bsock;
1371
1372    Dmsg1(100, "SessionCmd: %s", dir->msg);
1373    if (sscanf(dir->msg, sessioncmd, jcr->VolumeName,
1374               &jcr->VolSessionId, &jcr->VolSessionTime,
1375               &jcr->StartFile, &jcr->EndFile,
1376               &jcr->StartBlock, &jcr->EndBlock) != 7) {
1377       pm_strcpy(jcr->errmsg, dir->msg);
1378       Jmsg(jcr, M_FATAL, 0, _("Bad session command: %s"), jcr->errmsg);
1379       return 0;
1380    }
1381
1382    return dir->fsend(OKsession);
1383 }
1384
1385 static void set_storage_auth_key(JCR *jcr, char *key)
1386 {
1387    /* if no key don't update anything */
1388    if (!*key) {                
1389       return;
1390    }
1391
1392    /* We can be contacting multiple storage daemons.
1393     * So, make sure that any old jcr->store_bsock is cleaned up. 
1394     */
1395    if (jcr->store_bsock) {
1396       jcr->store_bsock->destroy();
1397       jcr->store_bsock = NULL;
1398    }
1399
1400    /* We can be contacting multiple storage daemons.
1401     *   So, make sure that any old jcr->sd_auth_key is cleaned up. 
1402     */
1403    if (jcr->sd_auth_key) {
1404       /* If we already have a Authorization key, director can do multi
1405        * storage restore
1406        */
1407       Dmsg0(5, "set multi_restore=true\n");
1408       jcr->multi_restore = true;
1409       bfree(jcr->sd_auth_key);
1410    }
1411
1412    jcr->sd_auth_key = bstrdup(key);
1413 }
1414
1415 /*
1416  * Get address of storage daemon from Director
1417  *
1418  */
1419 static int storage_cmd(JCR *jcr)
1420 {
1421    int stored_port;                /* storage daemon port */
1422    int enable_ssl;                 /* enable ssl to sd */
1423    POOL_MEM sd_auth_key(PM_MESSAGE);
1424    BSOCK *dir = jcr->dir_bsock;
1425    BSOCK *sd = new_bsock();        /* storage daemon bsock */
1426
1427
1428    Dmsg1(100, "StorageCmd: %s", dir->msg);
1429    sd_auth_key.check_size(dir->msglen);
1430    if (sscanf(dir->msg, storaddr, &jcr->stored_addr, &stored_port, 
1431               &enable_ssl, sd_auth_key.c_str()) != 4)
1432    {
1433       if (sscanf(dir->msg, storaddr_v1, &jcr->stored_addr,
1434                  &stored_port, &enable_ssl) != 3)
1435       {
1436          pm_strcpy(jcr->errmsg, dir->msg);
1437          Jmsg(jcr, M_FATAL, 0, _("Bad storage command: %s"), jcr->errmsg);
1438          goto bail_out;
1439       }
1440    }
1441
1442    set_storage_auth_key(jcr, sd_auth_key.c_str());
1443
1444    Dmsg3(110, "Open storage: %s:%d ssl=%d\n", jcr->stored_addr, stored_port, 
1445          enable_ssl);
1446    /* Open command communications with Storage daemon */
1447    /* Try to connect for 1 hour at 10 second intervals */
1448
1449    sd->set_source_address(me->FDsrc_addr);
1450    if (!sd->connect(jcr, 10, (int)me->SDConnectTimeout, me->heartbeat_interval,
1451                 _("Storage daemon"), jcr->stored_addr, NULL, stored_port, 1)) {
1452      sd->destroy();
1453      sd = NULL;
1454    }
1455
1456    if (sd == NULL) {
1457       Jmsg(jcr, M_FATAL, 0, _("Failed to connect to Storage daemon: %s:%d\n"),
1458           jcr->stored_addr, stored_port);
1459       Dmsg2(100, "Failed to connect to Storage daemon: %s:%d\n",
1460           jcr->stored_addr, stored_port);
1461       goto bail_out;
1462    }
1463    Dmsg0(110, "Connection OK to SD.\n");
1464
1465    jcr->store_bsock = sd;
1466
1467    sd->fsend("Hello Start Job %s\n", jcr->Job);
1468    if (!authenticate_storagedaemon(jcr)) {
1469       Jmsg(jcr, M_FATAL, 0, _("Failed to authenticate Storage daemon.\n"));
1470       goto bail_out;
1471    }
1472    Dmsg0(110, "Authenticated with SD.\n");
1473
1474    /* Send OK to Director */
1475    return dir->fsend(OKstore);
1476
1477 bail_out:
1478    dir->fsend(BADcmd, "storage");
1479    return 0;
1480
1481 }
1482
1483
1484 /*
1485  * Do a backup.
1486  */
1487 static int backup_cmd(JCR *jcr)
1488 {
1489    BSOCK *dir = jcr->dir_bsock;
1490    BSOCK *sd = jcr->store_bsock;
1491    int ok = 0;
1492    int SDJobStatus;
1493
1494 #if defined(WIN32_VSS)
1495    // capture state here, if client is backed up by multiple directors
1496    // and one enables vss and the other does not then enable_vss can change
1497    // between here and where its evaluated after the job completes.
1498    jcr->VSS = g_pVSSClient && enable_vss;
1499    if (jcr->VSS) {
1500       /* Run only one at a time */
1501       P(vss_mutex);
1502    }
1503 #endif
1504
1505    /*
1506     * Validate some options given to the backup make sense for the compiled in
1507     * options of this filed.
1508     */
1509    if (jcr->ff->flags & FO_ACL && !have_acl) {
1510       Jmsg(jcr, M_FATAL, 0, _("ACL support not configured for your machine.\n"));
1511       goto cleanup;
1512    }
1513    if (jcr->ff->flags & FO_XATTR && !have_xattr) {
1514       Jmsg(jcr, M_FATAL, 0, _("XATTR support not configured for your machine.\n"));
1515       goto cleanup;
1516    }
1517
1518    set_jcr_job_status(jcr, JS_Blocked);
1519    jcr->set_JobType(JT_BACKUP);
1520    Dmsg1(100, "begin backup ff=%p\n", jcr->ff);
1521
1522    if (sd == NULL) {
1523       Jmsg(jcr, M_FATAL, 0, _("Cannot contact Storage daemon\n"));
1524       dir->fsend(BADcmd, "backup");
1525       goto cleanup;
1526    }
1527
1528    dir->fsend(OKbackup);
1529    Dmsg1(110, "filed>dird: %s", dir->msg);
1530
1531    /*
1532     * Send Append Open Session to Storage daemon
1533     */
1534    sd->fsend(append_open);
1535    Dmsg1(110, ">stored: %s", sd->msg);
1536    /*
1537     * Expect to receive back the Ticket number
1538     */
1539    if (bget_msg(sd) >= 0) {
1540       Dmsg1(110, "<stored: %s", sd->msg);
1541       if (sscanf(sd->msg, OK_open, &jcr->Ticket) != 1) {
1542          Jmsg(jcr, M_FATAL, 0, _("Bad response to append open: %s\n"), sd->msg);
1543          goto cleanup;
1544       }
1545       Dmsg1(110, "Got Ticket=%d\n", jcr->Ticket);
1546    } else {
1547       Jmsg(jcr, M_FATAL, 0, _("Bad response from stored to open command\n"));
1548       goto cleanup;
1549    }
1550
1551    /*
1552     * Send Append data command to Storage daemon
1553     */
1554    sd->fsend(append_data, jcr->Ticket);
1555    Dmsg1(110, ">stored: %s", sd->msg);
1556
1557    /*
1558     * Expect to get OK data
1559     */
1560    Dmsg1(110, "<stored: %s", sd->msg);
1561    if (!response(jcr, sd, OK_data, "Append Data")) {
1562       goto cleanup;
1563    }
1564    
1565    generate_daemon_event(jcr, "JobStart");
1566    generate_plugin_event(jcr, bEventStartBackupJob);
1567
1568 #if defined(WIN32_VSS)
1569    /* START VSS ON WIN32 */
1570    if (jcr->VSS) {      
1571       if (g_pVSSClient->InitializeForBackup()) {   
1572         /* tell vss which drives to snapshot */   
1573         char szWinDriveLetters[27];   
1574         if (get_win32_driveletters(jcr->ff, szWinDriveLetters)) {
1575             Jmsg(jcr, M_INFO, 0, _("Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n"), g_pVSSClient->GetDriverName(), szWinDriveLetters);
1576             if (!g_pVSSClient->CreateSnapshots(szWinDriveLetters)) {               
1577                Jmsg(jcr, M_WARNING, 0, _("Generate VSS snapshots failed.\n"));
1578                jcr->JobErrors++;
1579             } else {
1580                /* tell user if snapshot creation of a specific drive failed */
1581                int i;
1582                for (i=0; i < (int)strlen(szWinDriveLetters); i++) {
1583                   if (islower(szWinDriveLetters[i])) {
1584                      Jmsg(jcr, M_WARNING, 0, _("Generate VSS snapshot of drive \"%c:\\\" failed. VSS support is disabled on this drive.\n"), szWinDriveLetters[i]);
1585                      jcr->JobErrors++;
1586                   }
1587                }
1588                /* inform user about writer states */
1589                for (i=0; i < (int)g_pVSSClient->GetWriterCount(); i++)                
1590                   if (g_pVSSClient->GetWriterState(i) < 1) {
1591                      Jmsg(jcr, M_WARNING, 0, _("VSS Writer (PrepareForBackup): %s\n"), g_pVSSClient->GetWriterInfo(i));                    
1592                      jcr->JobErrors++;
1593                   }                            
1594             }
1595         } else {
1596             Jmsg(jcr, M_INFO, 0, _("No drive letters found for generating VSS snapshots.\n"));
1597         }
1598       } else {
1599          berrno be;
1600          Jmsg(jcr, M_WARNING, 0, _("VSS was not initialized properly. VSS support is disabled. ERR=%s\n"), be.bstrerror());
1601       } 
1602       run_scripts(jcr, jcr->RunScripts, "ClientAfterVSS");
1603    }
1604 #endif
1605
1606    /*
1607     * Send Files to Storage daemon
1608     */
1609    Dmsg1(110, "begin blast ff=%p\n", (FF_PKT *)jcr->ff);
1610    if (!blast_data_to_storage_daemon(jcr, NULL)) {
1611       set_jcr_job_status(jcr, JS_ErrorTerminated);
1612       bnet_suppress_error_messages(sd, 1);
1613       bget_msg(sd);                   /* Read final response from append_data */
1614       Dmsg0(110, "Error in blast_data.\n");
1615    } else {
1616       set_jcr_job_status(jcr, JS_Terminated);
1617       /* Note, the above set status will not override an error */
1618       if (!(jcr->JobStatus == JS_Terminated || jcr->JobStatus == JS_Warnings)) {
1619          bnet_suppress_error_messages(sd, 1);
1620          goto cleanup;                /* bail out now */
1621       }
1622       /*
1623        * Expect to get response to append_data from Storage daemon
1624        */
1625       if (!response(jcr, sd, OK_append, "Append Data")) {
1626          set_jcr_job_status(jcr, JS_ErrorTerminated);
1627          goto cleanup;
1628       }
1629
1630       /*
1631        * Send Append End Data to Storage daemon
1632        */
1633       sd->fsend(append_end, jcr->Ticket);
1634       /* Get end OK */
1635       if (!response(jcr, sd, OK_end, "Append End")) {
1636          set_jcr_job_status(jcr, JS_ErrorTerminated);
1637          goto cleanup;
1638       }
1639
1640       /*
1641        * Send Append Close to Storage daemon
1642        */
1643       sd->fsend(append_close, jcr->Ticket);
1644       while (bget_msg(sd) >= 0) {    /* stop on signal or error */
1645          if (sscanf(sd->msg, OK_close, &SDJobStatus) == 1) {
1646             ok = 1;
1647             Dmsg2(200, "SDJobStatus = %d %c\n", SDJobStatus, (char)SDJobStatus);
1648          }
1649       }
1650       if (!ok) {
1651          Jmsg(jcr, M_FATAL, 0, _("Append Close with SD failed.\n"));
1652          goto cleanup;
1653       }
1654       if (!(SDJobStatus == JS_Terminated || SDJobStatus == JS_Warnings)) {
1655          Jmsg(jcr, M_FATAL, 0, _("Bad status %d returned from Storage Daemon.\n"),
1656             SDJobStatus);
1657       }
1658    }
1659
1660 cleanup:
1661 #if defined(WIN32_VSS)
1662    /* STOP VSS ON WIN32 */
1663    /* tell vss to close the backup session */
1664    if (jcr->VSS) {
1665       if (g_pVSSClient->CloseBackup()) {             
1666          /* inform user about writer states */
1667          for (int i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) {
1668             int msg_type = M_INFO;
1669             if (g_pVSSClient->GetWriterState(i) < 1) {
1670                msg_type = M_WARNING;
1671                jcr->JobErrors++;
1672             }
1673             Jmsg(jcr, msg_type, 0, _("VSS Writer (BackupComplete): %s\n"), g_pVSSClient->GetWriterInfo(i));
1674          }
1675       }
1676       Win32ConvCleanupCache();
1677       V(vss_mutex);
1678    }
1679 #endif
1680
1681    generate_plugin_event(jcr, bEventEndBackupJob);
1682    return 0;                          /* return and stop command loop */
1683 }
1684
1685 /*
1686  * Do a Verify for Director
1687  *
1688  */
1689 static int verify_cmd(JCR *jcr)
1690 {
1691    BSOCK *dir = jcr->dir_bsock;
1692    BSOCK *sd  = jcr->store_bsock;
1693    char level[100];
1694
1695    jcr->set_JobType(JT_VERIFY);
1696    if (sscanf(dir->msg, verifycmd, level) != 1) {
1697       dir->fsend(_("2994 Bad verify command: %s\n"), dir->msg);
1698       return 0;
1699    }
1700
1701    if (strcasecmp(level, "init") == 0) {
1702       jcr->set_JobLevel(L_VERIFY_INIT);
1703    } else if (strcasecmp(level, "catalog") == 0){
1704       jcr->set_JobLevel(L_VERIFY_CATALOG);
1705    } else if (strcasecmp(level, "volume") == 0){
1706       jcr->set_JobLevel(L_VERIFY_VOLUME_TO_CATALOG);
1707    } else if (strcasecmp(level, "data") == 0){
1708       jcr->set_JobLevel(L_VERIFY_DATA);
1709    } else if (strcasecmp(level, "disk_to_catalog") == 0) {
1710       jcr->set_JobLevel(L_VERIFY_DISK_TO_CATALOG);
1711    } else {
1712       dir->fsend(_("2994 Bad verify level: %s\n"), dir->msg);
1713       return 0;
1714    }
1715
1716    dir->fsend(OKverify);
1717
1718    generate_daemon_event(jcr, "JobStart");
1719    generate_plugin_event(jcr, bEventLevel, (void *)jcr->get_JobLevel());
1720    generate_plugin_event(jcr, bEventStartVerifyJob);
1721
1722    Dmsg1(110, "filed>dird: %s", dir->msg);
1723
1724    switch (jcr->get_JobLevel()) {
1725    case L_VERIFY_INIT:
1726    case L_VERIFY_CATALOG:
1727       do_verify(jcr);
1728       break;
1729    case L_VERIFY_VOLUME_TO_CATALOG:
1730       if (!open_sd_read_session(jcr)) {
1731          return 0;
1732       }
1733       start_dir_heartbeat(jcr);
1734       do_verify_volume(jcr);
1735       stop_dir_heartbeat(jcr);
1736       /*
1737        * Send Close session command to Storage daemon
1738        */
1739       sd->fsend(read_close, jcr->Ticket);
1740       Dmsg1(130, "filed>stored: %s", sd->msg);
1741
1742       /* ****FIXME**** check response */
1743       bget_msg(sd);                      /* get OK */
1744
1745       /* Inform Storage daemon that we are done */
1746       sd->signal(BNET_TERMINATE);
1747
1748       break;
1749    case L_VERIFY_DISK_TO_CATALOG:
1750       do_verify(jcr);
1751       break;
1752    default:
1753       dir->fsend(_("2994 Bad verify level: %s\n"), dir->msg);
1754       return 0;
1755    }
1756
1757    dir->signal(BNET_EOD);
1758    generate_plugin_event(jcr, bEventEndVerifyJob);
1759    return 0;                          /* return and terminate command loop */
1760 }
1761
1762 /*
1763  * Do a Restore for Director
1764  *
1765  */
1766 static int restore_cmd(JCR *jcr)
1767 {
1768    BSOCK *dir = jcr->dir_bsock;
1769    BSOCK *sd = jcr->store_bsock;
1770    POOLMEM *args;
1771    bool use_regexwhere=false;
1772    int prefix_links;
1773    char replace;
1774
1775    /*
1776     * Scan WHERE (base directory for restore) from command
1777     */
1778    Dmsg0(150, "restore command\n");
1779    /* Pickup where string */
1780    args = get_memory(dir->msglen+1);
1781    *args = 0;
1782
1783    if (sscanf(dir->msg, restorecmd, &replace, &prefix_links, args) != 3) {
1784       if (sscanf(dir->msg, restorecmdR, &replace, &prefix_links, args) != 3){
1785          if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
1786             pm_strcpy(jcr->errmsg, dir->msg);
1787             Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
1788             return 0;
1789          }
1790          *args = 0;
1791       }
1792       use_regexwhere = true;
1793    }
1794    /* Turn / into nothing */
1795    if (IsPathSeparator(args[0]) && args[1] == '\0') {
1796       args[0] = '\0';
1797    }
1798
1799    Dmsg2(150, "Got replace %c, where=%s\n", replace, args);
1800    unbash_spaces(args);
1801
1802    if (use_regexwhere) {
1803       jcr->where_bregexp = get_bregexps(args);
1804       if (!jcr->where_bregexp) {
1805          Jmsg(jcr, M_FATAL, 0, _("Bad where regexp. where=%s\n"), args);
1806          free_pool_memory(args);
1807          return 0;
1808       }
1809    } else {
1810       jcr->where = bstrdup(args);
1811    }
1812
1813    free_pool_memory(args);
1814    jcr->replace = replace;
1815    jcr->prefix_links = prefix_links;
1816
1817    dir->fsend(OKrestore);
1818    Dmsg1(110, "filed>dird: %s", dir->msg);
1819
1820    jcr->set_JobType(JT_RESTORE);
1821
1822    set_jcr_job_status(jcr, JS_Blocked);
1823
1824    if (!open_sd_read_session(jcr)) {
1825       set_jcr_job_status(jcr, JS_ErrorTerminated);
1826       goto bail_out;
1827    }
1828
1829    set_jcr_job_status(jcr, JS_Running);
1830
1831    /*
1832     * Do restore of files and data
1833     */
1834    start_dir_heartbeat(jcr);
1835    generate_daemon_event(jcr, "JobStart");
1836    generate_plugin_event(jcr, bEventStartRestoreJob);
1837    do_restore(jcr);
1838    stop_dir_heartbeat(jcr);
1839
1840    set_jcr_job_status(jcr, JS_Terminated);
1841    if (jcr->JobStatus != JS_Terminated) {
1842       bnet_suppress_error_messages(sd, 1);
1843    }
1844
1845    /*
1846     * Send Close session command to Storage daemon
1847     */
1848    sd->fsend(read_close, jcr->Ticket);
1849    Dmsg1(130, "filed>stored: %s", sd->msg);
1850
1851    bget_msg(sd);                      /* get OK */
1852
1853    /* Inform Storage daemon that we are done */
1854    sd->signal(BNET_TERMINATE);
1855
1856 bail_out:
1857    bfree_and_null(jcr->where);
1858
1859    if (jcr->JobErrors) {
1860       set_jcr_job_status(jcr, JS_ErrorTerminated);
1861    }
1862
1863    Dmsg0(130, "Done in job.c\n");
1864
1865    int ret;
1866    if (jcr->multi_restore) {
1867       dir->fsend(OKstoreend);
1868       ret = 1;     /* we continue the loop, waiting for next part */
1869    } else {
1870       end_restore_cmd(jcr);
1871       ret = 0;     /* we stop here */
1872    }
1873
1874    return ret;
1875 }
1876
1877 static int end_restore_cmd(JCR *jcr) 
1878 {
1879    Dmsg0(5, "end_restore_cmd\n");
1880    generate_plugin_event(jcr, bEventEndRestoreJob);
1881    return 0;                          /* return and terminate command loop */
1882 }
1883
1884 static int open_sd_read_session(JCR *jcr)
1885 {
1886    BSOCK *sd = jcr->store_bsock;
1887
1888    if (!sd) {
1889       Jmsg(jcr, M_FATAL, 0, _("Improper calling sequence.\n"));
1890       return 0;
1891    }
1892    Dmsg4(120, "VolSessId=%ld VolsessT=%ld SF=%ld EF=%ld\n",
1893       jcr->VolSessionId, jcr->VolSessionTime, jcr->StartFile, jcr->EndFile);
1894    Dmsg2(120, "JobId=%d vol=%s\n", jcr->JobId, "DummyVolume");
1895    /*
1896     * Open Read Session with Storage daemon
1897     */
1898    sd->fsend(read_open, "DummyVolume",
1899       jcr->VolSessionId, jcr->VolSessionTime, jcr->StartFile, jcr->EndFile,
1900       jcr->StartBlock, jcr->EndBlock);
1901    Dmsg1(110, ">stored: %s", sd->msg);
1902
1903    /*
1904     * Get ticket number
1905     */
1906    if (bget_msg(sd) >= 0) {
1907       Dmsg1(110, "filed<stored: %s", sd->msg);
1908       if (sscanf(sd->msg, OK_open, &jcr->Ticket) != 1) {
1909          Jmsg(jcr, M_FATAL, 0, _("Bad response to SD read open: %s\n"), sd->msg);
1910          return 0;
1911       }
1912       Dmsg1(110, "filed: got Ticket=%d\n", jcr->Ticket);
1913    } else {
1914       Jmsg(jcr, M_FATAL, 0, _("Bad response from stored to read open command\n"));
1915       return 0;
1916    }
1917
1918    if (!send_bootstrap_file(jcr)) {
1919       return 0;
1920    }
1921
1922    /*
1923     * Start read of data with Storage daemon
1924     */
1925    sd->fsend(read_data, jcr->Ticket);
1926    Dmsg1(110, ">stored: %s", sd->msg);
1927
1928    /*
1929     * Get OK data
1930     */
1931    if (!response(jcr, sd, OK_data, "Read Data")) {
1932       return 0;
1933    }
1934    return 1;
1935 }
1936
1937 /*
1938  * Destroy the Job Control Record and associated
1939  * resources (sockets).
1940  */
1941 static void filed_free_jcr(JCR *jcr)
1942 {
1943    if (jcr->store_bsock) {
1944       jcr->store_bsock->close();
1945    }
1946    free_bootstrap(jcr);
1947    if (jcr->last_fname) {
1948       free_pool_memory(jcr->last_fname);
1949    }
1950    free_runscripts(jcr->RunScripts);
1951    delete jcr->RunScripts;
1952
1953    if (jcr->JobId != 0)
1954       write_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
1955
1956    return;
1957 }
1958
1959 /*
1960  * Get response from Storage daemon to a command we
1961  * sent. Check that the response is OK.
1962  *
1963  *  Returns: 0 on failure
1964  *           1 on success
1965  */
1966 int response(JCR *jcr, BSOCK *sd, char *resp, const char *cmd)
1967 {
1968    if (sd->errors) {
1969       return 0;
1970    }
1971    if (bget_msg(sd) > 0) {
1972       Dmsg0(110, sd->msg);
1973       if (strcmp(sd->msg, resp) == 0) {
1974          return 1;
1975       }
1976    }
1977    if (job_canceled(jcr)) {
1978       return 0;                       /* if canceled avoid useless error messages */
1979    }
1980    if (is_bnet_error(sd)) {
1981       Jmsg2(jcr, M_FATAL, 0, _("Comm error with SD. bad response to %s. ERR=%s\n"),
1982          cmd, bnet_strerror(sd));
1983    } else {
1984       Jmsg3(jcr, M_FATAL, 0, _("Bad response to %s command. Wanted %s, got %s\n"),
1985          cmd, resp, sd->msg);
1986    }
1987    return 0;
1988 }
1989
1990 static int send_bootstrap_file(JCR *jcr)
1991 {
1992    FILE *bs;
1993    char buf[2000];
1994    BSOCK *sd = jcr->store_bsock;
1995    const char *bootstrap = "bootstrap\n";
1996    int stat = 0;
1997
1998    Dmsg1(400, "send_bootstrap_file: %s\n", jcr->RestoreBootstrap);
1999    if (!jcr->RestoreBootstrap) {
2000       return 1;
2001    }
2002    bs = fopen(jcr->RestoreBootstrap, "rb");
2003    if (!bs) {
2004       berrno be;
2005       Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"),
2006          jcr->RestoreBootstrap, be.bstrerror());
2007       set_jcr_job_status(jcr, JS_ErrorTerminated);
2008       goto bail_out;
2009    }
2010    sd->msglen = pm_strcpy(sd->msg, bootstrap);
2011    sd->send();
2012    while (fgets(buf, sizeof(buf), bs)) {
2013       sd->msglen = Mmsg(sd->msg, "%s", buf);
2014       sd->send();
2015    }
2016    sd->signal(BNET_EOD);
2017    fclose(bs);
2018    if (!response(jcr, sd, OKSDbootstrap, "Bootstrap")) {
2019       set_jcr_job_status(jcr, JS_ErrorTerminated);
2020       goto bail_out;
2021    }
2022    stat = 1;
2023
2024 bail_out:
2025    free_bootstrap(jcr);
2026    return stat;
2027 }