]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/job.c
Merge branch 'master' into basejobv3
[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             if (fo->ignoredir != NULL) {
346                free(fo->ignoredir);
347             }
348          }
349          incexe->opts_list.destroy();
350          incexe->name_list.destroy();
351          incexe->plugin_list.destroy();
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       }
375       fileset->exclude_list.destroy();
376       free(fileset);
377    }
378    ff->fileset = NULL;
379    Dmsg0(100, "Calling term_find_files\n");
380    term_find_files(jcr->ff);
381    jcr->ff = NULL;
382    Dmsg0(100, "Done with term_find_files\n");
383    free_jcr(jcr);                     /* destroy JCR record */
384    Dmsg0(100, "Done with free_jcr\n");
385    Dsm_check(1);
386    return NULL;
387 }
388
389 /*
390  * Hello from Director he must identify himself and provide his
391  *  password.
392  */
393 static int hello_cmd(JCR *jcr)
394 {
395    Dmsg0(120, "Calling Authenticate\n");
396    if (!authenticate_director(jcr)) {
397       return 0;
398    }
399    Dmsg0(120, "OK Authenticate\n");
400    jcr->authenticated = true;
401    return 1;
402 }
403
404 /*
405  * Cancel a Job
406  */
407 static int cancel_cmd(JCR *jcr)
408 {
409    BSOCK *dir = jcr->dir_bsock;
410    char Job[MAX_NAME_LENGTH];
411    JCR *cjcr;
412
413    if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) {
414       if (!(cjcr=get_jcr_by_full_name(Job))) {
415          dir->fsend(_("2901 Job %s not found.\n"), Job);
416       } else {
417          if (cjcr->store_bsock) {
418             cjcr->store_bsock->set_timed_out();
419             cjcr->store_bsock->set_terminated();
420             pthread_kill(cjcr->my_thread_id, TIMEOUT_SIGNAL);
421          }
422          generate_plugin_event(cjcr, bEventCancelCommand, NULL);
423          set_jcr_job_status(cjcr, JS_Canceled);
424          free_jcr(cjcr);
425          dir->fsend(_("2001 Job %s marked to be canceled.\n"), Job);
426       }
427    } else {
428       dir->fsend(_("2902 Error scanning cancel command.\n"));
429    }
430    dir->signal(BNET_EOD);
431    return 1;
432 }
433
434
435 /*
436  * Set debug level as requested by the Director
437  *
438  */
439 static int setdebug_cmd(JCR *jcr)
440 {
441    BSOCK *dir = jcr->dir_bsock;
442    int level, trace_flag;
443
444    Dmsg1(110, "setdebug_cmd: %s", dir->msg);
445    if (sscanf(dir->msg, "setdebug=%d trace=%d", &level, &trace_flag) != 2 || level < 0) {
446       pm_strcpy(jcr->errmsg, dir->msg);
447       dir->fsend(_("2991 Bad setdebug command: %s\n"), jcr->errmsg);
448       return 0;
449    }
450    debug_level = level;
451    set_trace(trace_flag);
452    return dir->fsend(OKsetdebug, level);
453 }
454
455
456 static int estimate_cmd(JCR *jcr)
457 {
458    BSOCK *dir = jcr->dir_bsock;
459    char ed1[50], ed2[50];
460
461    if (sscanf(dir->msg, estimatecmd, &jcr->listing) != 1) {
462       pm_strcpy(jcr->errmsg, dir->msg);
463       Jmsg(jcr, M_FATAL, 0, _("Bad estimate command: %s"), jcr->errmsg);
464       dir->fsend(_("2992 Bad estimate command.\n"));
465       return 0;
466    }
467    make_estimate(jcr);
468    dir->fsend(OKest, edit_uint64_with_commas(jcr->num_files_examined, ed1),
469       edit_uint64_with_commas(jcr->JobBytes, ed2));
470    dir->signal(BNET_EOD);
471    return 1;
472 }
473
474 /*
475  * Get JobId and Storage Daemon Authorization key from Director
476  */
477 static int job_cmd(JCR *jcr)
478 {
479    BSOCK *dir = jcr->dir_bsock;
480    POOL_MEM sd_auth_key(PM_MESSAGE);
481    sd_auth_key.check_size(dir->msglen);
482
483    if (sscanf(dir->msg, jobcmd,  &jcr->JobId, jcr->Job,
484               &jcr->VolSessionId, &jcr->VolSessionTime, 
485               sd_auth_key.c_str()) != 5) {
486       pm_strcpy(jcr->errmsg, dir->msg);
487       Jmsg(jcr, M_FATAL, 0, _("Bad Job Command: %s"), jcr->errmsg);
488       dir->fsend(BADjob);
489       return 0;
490    }
491    set_storage_auth_key(jcr, sd_auth_key.c_str());
492    Dmsg2(120, "JobId=%d Auth=%s\n", jcr->JobId, jcr->sd_auth_key);
493    Mmsg(jcr->errmsg, "JobId=%d Job=%s", jcr->JobId, jcr->Job);
494    new_plugins(jcr);                  /* instantiate plugins for this jcr */
495    generate_plugin_event(jcr, bEventJobStart, (void *)jcr->errmsg);
496    return dir->fsend(OKjob, VERSION, LSMDATE, HOST_OS, DISTNAME, DISTVER);
497 }
498
499 static int runbefore_cmd(JCR *jcr)
500 {
501    bool ok;
502    BSOCK *dir = jcr->dir_bsock;
503    POOLMEM *cmd = get_memory(dir->msglen+1);
504    RUNSCRIPT *script;
505
506    Dmsg1(100, "runbefore_cmd: %s", dir->msg);
507    if (sscanf(dir->msg, runbefore, cmd) != 1) {
508       pm_strcpy(jcr->errmsg, dir->msg);
509       Jmsg1(jcr, M_FATAL, 0, _("Bad RunBeforeJob command: %s\n"), jcr->errmsg);
510       dir->fsend(_("2905 Bad RunBeforeJob command.\n"));
511       free_memory(cmd);
512       return 0;
513    }
514    unbash_spaces(cmd);
515
516    /* Run the command now */
517    script = new_runscript();
518    script->set_command(cmd);
519    script->when = SCRIPT_Before;
520    ok = script->run(jcr, "ClientRunBeforeJob");
521    free_runscript(script);
522
523    free_memory(cmd);
524    if (ok) {
525       dir->fsend(OKRunBefore);
526       return 1;
527    } else {
528       dir->fsend(_("2905 Bad RunBeforeJob command.\n"));
529       return 0;
530    }
531 }
532
533 static int runbeforenow_cmd(JCR *jcr)
534 {
535    BSOCK *dir = jcr->dir_bsock;
536
537    run_scripts(jcr, jcr->RunScripts, "ClientBeforeJob");
538    if (job_canceled(jcr)) {
539       dir->fsend(_("2905 Bad RunBeforeNow command.\n"));
540       Dmsg0(100, "Back from run_scripts ClientBeforeJob now: FAILED\n");
541       return 0;
542    } else {
543       dir->fsend(OKRunBeforeNow);
544       Dmsg0(100, "Back from run_scripts ClientBeforeJob now: OK\n");
545       return 1;
546    }
547 }
548
549 static int runafter_cmd(JCR *jcr)
550 {
551    BSOCK *dir = jcr->dir_bsock;
552    POOLMEM *msg = get_memory(dir->msglen+1);
553    RUNSCRIPT *cmd;
554
555    Dmsg1(100, "runafter_cmd: %s", dir->msg);
556    if (sscanf(dir->msg, runafter, msg) != 1) {
557       pm_strcpy(jcr->errmsg, dir->msg);
558       Jmsg1(jcr, M_FATAL, 0, _("Bad RunAfter command: %s\n"), jcr->errmsg);
559       dir->fsend(_("2905 Bad RunAfterJob command.\n"));
560       free_memory(msg);
561       return 0;
562    }
563    unbash_spaces(msg);
564
565    cmd = new_runscript();
566    cmd->set_command(msg);
567    cmd->on_success = true;
568    cmd->on_failure = false;
569    cmd->when = SCRIPT_After;
570
571    jcr->RunScripts->append(cmd);
572
573    free_pool_memory(msg);
574    return dir->fsend(OKRunAfter);
575 }
576
577 static int runscript_cmd(JCR *jcr)
578 {
579    BSOCK *dir = jcr->dir_bsock;
580    POOLMEM *msg = get_memory(dir->msglen+1);
581    int on_success, on_failure, fail_on_error;
582
583    RUNSCRIPT *cmd = new_runscript() ;
584
585    Dmsg1(100, "runscript_cmd: '%s'\n", dir->msg);
586    /* Note, we cannot sscanf into bools */
587    if (sscanf(dir->msg, runscript, &on_success, 
588                                   &on_failure,
589                                   &fail_on_error,
590                                   &cmd->when,
591                                   msg) != 5) {
592       pm_strcpy(jcr->errmsg, dir->msg);
593       Jmsg1(jcr, M_FATAL, 0, _("Bad RunScript command: %s\n"), jcr->errmsg);
594       dir->fsend(_("2905 Bad RunScript command.\n"));
595       free_runscript(cmd);
596       free_memory(msg);
597       return 0;
598    }
599    cmd->on_success = on_success;
600    cmd->on_failure = on_failure;
601    cmd->fail_on_error = fail_on_error;
602    unbash_spaces(msg);
603
604    cmd->set_command(msg);
605    cmd->debug();
606    jcr->RunScripts->append(cmd);
607
608    free_pool_memory(msg);
609    return dir->fsend(OKRunScript);
610 }
611
612
613 static bool init_fileset(JCR *jcr)
614 {
615    FF_PKT *ff;
616    findFILESET *fileset;
617
618    if (!jcr->ff) {
619       return false;
620    }
621    ff = jcr->ff;
622    if (ff->fileset) {
623       return false;
624    }
625    fileset = (findFILESET *)malloc(sizeof(findFILESET));
626    memset(fileset, 0, sizeof(findFILESET));
627    ff->fileset = fileset;
628    fileset->state = state_none;
629    fileset->include_list.init(1, true);
630    fileset->exclude_list.init(1, true);
631    return true;
632 }
633
634 static findFOPTS *start_options(FF_PKT *ff)
635 {
636    int state = ff->fileset->state;
637    findINCEXE *incexe = ff->fileset->incexe;
638
639    if (state != state_options) {
640       ff->fileset->state = state_options;
641       findFOPTS *fo = (findFOPTS *)malloc(sizeof(findFOPTS));
642       memset(fo, 0, sizeof(findFOPTS));
643       fo->regex.init(1, true);
644       fo->regexdir.init(1, true);
645       fo->regexfile.init(1, true);
646       fo->wild.init(1, true);
647       fo->wilddir.init(1, true);
648       fo->wildfile.init(1, true);
649       fo->wildbase.init(1, true);
650       fo->base.init(1, true);
651       fo->fstype.init(1, true);
652       fo->drivetype.init(1, true);
653       incexe->current_opts = fo;
654       incexe->opts_list.append(fo);
655    }
656    return incexe->current_opts;
657
658 }
659
660 /*
661  * Add fname to include/exclude fileset list. First check for
662  * | and < and if necessary perform command.
663  */
664 static void add_file_to_fileset(JCR *jcr, const char *fname, findFILESET *fileset,
665                                 bool is_file)
666 {
667    char *p;
668    BPIPE *bpipe;
669    POOLMEM *fn;
670    FILE *ffd;
671    char buf[1000];
672    int ch;
673    int stat;
674
675    p = (char *)fname;
676    ch = (uint8_t)*p;
677    switch (ch) {
678    case '|':
679       p++;                            /* skip over | */
680       fn = get_pool_memory(PM_FNAME);
681       fn = edit_job_codes(jcr, fn, p, "");
682       bpipe = open_bpipe(fn, 0, "r");
683       if (!bpipe) {
684          berrno be;
685          Jmsg(jcr, M_FATAL, 0, _("Cannot run program: %s. ERR=%s\n"),
686             p, be.bstrerror());
687          free_pool_memory(fn);
688          return;
689       }
690       free_pool_memory(fn);
691       while (fgets(buf, sizeof(buf), bpipe->rfd)) {
692          strip_trailing_junk(buf);
693          if (is_file) {
694             fileset->incexe->name_list.append(new_dlistString(buf));
695          } else {
696             fileset->incexe->plugin_list.append(new_dlistString(buf));
697          }
698       }
699       if ((stat=close_bpipe(bpipe)) != 0) {
700          berrno be;
701          Jmsg(jcr, M_FATAL, 0, _("Error running program: %s. stat=%d: ERR=%s\n"),
702             p, be.code(stat), be.bstrerror(stat));
703          return;
704       }
705       break;
706    case '<':
707       Dmsg1(100, "Doing < of '%s' include on client.\n", p + 1);
708       p++;                      /* skip over < */
709       if ((ffd = fopen(p, "rb")) == NULL) {
710          berrno be;
711          Jmsg(jcr, M_FATAL, 0, _("Cannot open FileSet input file: %s. ERR=%s\n"),
712             p, be.bstrerror());
713          return;
714       }
715       while (fgets(buf, sizeof(buf), ffd)) {
716          strip_trailing_junk(buf);
717          Dmsg1(100, "%s\n", buf);
718          if (is_file) {
719             fileset->incexe->name_list.append(new_dlistString(buf));
720          } else {
721             fileset->incexe->plugin_list.append(new_dlistString(buf));
722          }
723       }
724       fclose(ffd);
725       break;
726    default:
727       if (is_file) {
728          fileset->incexe->name_list.append(new_dlistString(fname));
729       } else {
730          if (me->plugin_directory) {
731             fileset->incexe->plugin_list.append(new_dlistString(fname));
732          } else {
733             Jmsg(jcr, M_FATAL, 0, _("Plugin Directory not defined. Cannot use plugin: \"%\"\n"),
734                fname);
735          }
736       }
737       break;
738    }
739 }
740
741
742 static void add_fileset(JCR *jcr, const char *item)
743 {
744    FF_PKT *ff = jcr->ff;
745    findFILESET *fileset = ff->fileset;
746    int state = fileset->state;
747    findFOPTS *current_opts;
748
749    /* Get code, optional subcode, and position item past the dividing space */
750    Dmsg1(100, "%s\n", item);
751    int code = item[0];
752    if (code != '\0') {
753       ++item;
754    }
755    int subcode = ' ';               /* A space is always a valid subcode */
756    if (item[0] != '\0' && item[0] != ' ') {
757       subcode = item[0];
758       ++item;
759    }
760    if (*item == ' ') {
761       ++item;
762    }
763
764    /* Skip all lines we receive after an error */
765    if (state == state_error) {
766       Dmsg0(100, "State=error return\n");
767       return;
768    }
769
770    /*
771     * The switch tests the code for validity.
772     * The subcode is always good if it is a space, otherwise we must confirm.
773     * We set state to state_error first assuming the subcode is invalid,
774     * requiring state to be set in cases below that handle subcodes.
775     */
776    if (subcode != ' ') {
777       state = state_error;
778       Dmsg0(100, "Set state=error or double code.\n");
779    }
780    switch (code) {
781    case 'I':
782       /* New include */
783       fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE));
784       memset(fileset->incexe, 0, sizeof(findINCEXE));
785       fileset->incexe->opts_list.init(1, true);
786       fileset->incexe->name_list.init(); /* for dlist;  was 1,true for alist */
787       fileset->incexe->plugin_list.init();
788       fileset->include_list.append(fileset->incexe);
789       break;
790    case 'E':
791       /* New exclude */
792       fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE));
793       memset(fileset->incexe, 0, sizeof(findINCEXE));
794       fileset->incexe->opts_list.init(1, true);
795       fileset->incexe->name_list.init();
796       fileset->incexe->plugin_list.init();
797       fileset->exclude_list.append(fileset->incexe);
798       break;
799    case 'N':
800       state = state_none;
801       break;
802    case 'F':
803       /* File item to include or exclude list */
804       state = state_include;
805       add_file_to_fileset(jcr, item, fileset, true);
806       break;
807    case 'P':
808       /* Plugin item to include list */
809       state = state_include;
810       add_file_to_fileset(jcr, item, fileset, false);
811       break;
812    case 'R':
813       current_opts = start_options(ff);
814       regex_t *preg;
815       int rc;
816       char prbuf[500];
817       preg = (regex_t *)malloc(sizeof(regex_t));
818       if (current_opts->flags & FO_IGNORECASE) {
819          rc = regcomp(preg, item, REG_EXTENDED|REG_ICASE);
820       } else {
821          rc = regcomp(preg, item, REG_EXTENDED);
822       }
823       if (rc != 0) {
824          regerror(rc, preg, prbuf, sizeof(prbuf));
825          regfree(preg);
826          free(preg);
827          Jmsg(jcr, M_FATAL, 0, _("REGEX %s compile error. ERR=%s\n"), item, prbuf);
828          state = state_error;
829          break;
830       }
831       state = state_options;
832       if (subcode == ' ') {
833          current_opts->regex.append(preg);
834       } else if (subcode == 'D') {
835          current_opts->regexdir.append(preg);
836       } else if (subcode == 'F') {
837          current_opts->regexfile.append(preg);
838       } else {
839          state = state_error;
840       }
841       break;
842    case 'B':
843       current_opts = start_options(ff);
844       current_opts->base.append(bstrdup(item));
845       state = state_options;
846       break;
847    case 'X':
848       current_opts = start_options(ff);
849       state = state_options;
850       if (subcode == ' ') {
851          current_opts->fstype.append(bstrdup(item));
852       } else if (subcode == 'D') {
853          current_opts->drivetype.append(bstrdup(item));
854       } else {
855          state = state_error;
856       }
857       break;
858    case 'W':
859       current_opts = start_options(ff);
860       state = state_options;
861       if (subcode == ' ') {
862          current_opts->wild.append(bstrdup(item));
863       } else if (subcode == 'D') {
864          current_opts->wilddir.append(bstrdup(item));
865       } else if (subcode == 'F') {
866          current_opts->wildfile.append(bstrdup(item));
867       } else if (subcode == 'B') {
868          current_opts->wildbase.append(bstrdup(item));
869       } else {
870          state = state_error;
871       }
872       break;
873    case 'O':
874       current_opts = start_options(ff);
875       set_options(current_opts, item);
876       state = state_options;
877       break;
878    case 'Z':
879       current_opts = start_options(ff);
880       current_opts->ignoredir = bstrdup(item);
881       state = state_options;
882       break;
883    case 'D':
884       current_opts = start_options(ff);
885 //    current_opts->reader = bstrdup(item);
886       state = state_options;
887       break;
888    case 'T':
889       current_opts = start_options(ff);
890 //    current_opts->writer = bstrdup(item);
891       state = state_options;
892       break;
893    default:
894       Jmsg(jcr, M_FATAL, 0, _("Invalid FileSet command: %s\n"), item);
895       state = state_error;
896       break;
897    }
898    ff->fileset->state = state;
899 }
900
901 static bool term_fileset(JCR *jcr)
902 {
903    FF_PKT *ff = jcr->ff;
904
905 #ifdef xxx_DEBUG_CODE
906    findFILESET *fileset = ff->fileset;
907    int i, j, k;
908
909    for (i=0; i<fileset->include_list.size(); i++) {
910       findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i);
911       Dmsg0(400, "I\n");
912       for (j=0; j<incexe->opts_list.size(); j++) {
913          findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
914          for (k=0; k<fo->regex.size(); k++) {
915             Dmsg1(400, "R %s\n", (char *)fo->regex.get(k));
916          }
917          for (k=0; k<fo->regexdir.size(); k++) {
918             Dmsg1(400, "RD %s\n", (char *)fo->regexdir.get(k));
919          }
920          for (k=0; k<fo->regexfile.size(); k++) {
921             Dmsg1(400, "RF %s\n", (char *)fo->regexfile.get(k));
922          }
923          for (k=0; k<fo->wild.size(); k++) {
924             Dmsg1(400, "W %s\n", (char *)fo->wild.get(k));
925          }
926          for (k=0; k<fo->wilddir.size(); k++) {
927             Dmsg1(400, "WD %s\n", (char *)fo->wilddir.get(k));
928          }
929          for (k=0; k<fo->wildfile.size(); k++) {
930             Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k));
931          }
932          for (k=0; k<fo->wildbase.size(); k++) {
933             Dmsg1(400, "WB %s\n", (char *)fo->wildbase.get(k));
934          }
935          for (k=0; k<fo->base.size(); k++) {
936             Dmsg1(400, "B %s\n", (char *)fo->base.get(k));
937          }
938          for (k=0; k<fo->fstype.size(); k++) {
939             Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k));
940          }
941          for (k=0; k<fo->drivetype.size(); k++) {
942             Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k));
943          }
944          if (fo->ignoredir) {
945             Dmsg1(400, "Z %s\n", fo->ignoredir);
946          }
947       }
948       dlistString *node;
949       foreach_dlist(node, &incexe->name_list) {
950          Dmsg1(400, "F %s\n", node->c_str());
951       }
952       foreach_dlist(node, &incexe->plugin_list) {
953          Dmsg1(400, "P %s\n", node->c_str());
954       }
955    }
956    for (i=0; i<fileset->exclude_list.size(); i++) {
957       findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i);
958       Dmsg0(400, "E\n");
959       for (j=0; j<incexe->opts_list.size(); j++) {
960          findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
961          for (k=0; k<fo->regex.size(); k++) {
962             Dmsg1(400, "R %s\n", (char *)fo->regex.get(k));
963          }
964          for (k=0; k<fo->regexdir.size(); k++) {
965             Dmsg1(400, "RD %s\n", (char *)fo->regexdir.get(k));
966          }
967          for (k=0; k<fo->regexfile.size(); k++) {
968             Dmsg1(400, "RF %s\n", (char *)fo->regexfile.get(k));
969          }
970          for (k=0; k<fo->wild.size(); k++) {
971             Dmsg1(400, "W %s\n", (char *)fo->wild.get(k));
972          }
973          for (k=0; k<fo->wilddir.size(); k++) {
974             Dmsg1(400, "WD %s\n", (char *)fo->wilddir.get(k));
975          }
976          for (k=0; k<fo->wildfile.size(); k++) {
977             Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k));
978          }
979          for (k=0; k<fo->wildbase.size(); k++) {
980             Dmsg1(400, "WB %s\n", (char *)fo->wildbase.get(k));
981          }
982          for (k=0; k<fo->base.size(); k++) {
983             Dmsg1(400, "B %s\n", (char *)fo->base.get(k));
984          }
985          for (k=0; k<fo->fstype.size(); k++) {
986             Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k));
987          }
988          for (k=0; k<fo->drivetype.size(); k++) {
989             Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k));
990          }
991       }
992       dlistString *node;
993       foreach_dlist(node, incexe->name_list) {
994          Dmsg1(400, "F %s\n", node->c_str());
995       }
996       foreach_dlist(node, &incexe->plugin_list) {
997          Dmsg1(400, "P %s\n", node->c_str());
998       }
999    }
1000 #endif
1001    return ff->fileset->state != state_error;
1002 }
1003
1004
1005 /*
1006  * As an optimization, we should do this during
1007  *  "compile" time in filed/job.c, and keep only a bit mask
1008  *  and the Verify options.
1009  */
1010 static void set_options(findFOPTS *fo, const char *opts)
1011 {
1012    int j;
1013    const char *p;
1014    char strip[100];
1015
1016 // Commented out as it is not backward compatible - KES
1017 #ifdef HAVE_WIN32
1018 //   fo->flags |= FO_IGNORECASE; /* always ignorecase under windows */
1019 #endif
1020
1021    for (p=opts; *p; p++) {
1022       switch (*p) {
1023       case 'a':                 /* alway replace */
1024       case '0':                 /* no option */
1025          break;
1026       case 'e':
1027          fo->flags |= FO_EXCLUDE;
1028          break;
1029       case 'f':
1030          fo->flags |= FO_MULTIFS;
1031          break;
1032       case 'h':                 /* no recursion */
1033          fo->flags |= FO_NO_RECURSION;
1034          break;
1035       case 'H':                 /* no hard link handling */
1036          fo->flags |= FO_NO_HARDLINK;
1037          break;
1038       case 'i':
1039          fo->flags |= FO_IGNORECASE;
1040          break;
1041       case 'M':                 /* MD5 */
1042          fo->flags |= FO_MD5;
1043          break;
1044       case 'n':
1045          fo->flags |= FO_NOREPLACE;
1046          break;
1047       case 'p':                 /* use portable data format */
1048          fo->flags |= FO_PORTABLE;
1049          break;
1050       case 'R':                 /* Resource forks and Finder Info */
1051          fo->flags |= FO_HFSPLUS;
1052       case 'r':                 /* read fifo */
1053          fo->flags |= FO_READFIFO;
1054          break;
1055       case 'S':
1056          switch(*(p + 1)) {
1057          case '1':
1058             fo->flags |= FO_SHA1;
1059             p++;
1060             break;
1061 #ifdef HAVE_SHA2
1062          case '2':
1063             fo->flags |= FO_SHA256;
1064             p++;
1065             break;
1066          case '3':
1067             fo->flags |= FO_SHA512;
1068             p++;
1069             break;
1070 #endif
1071          default:
1072             /*
1073              * If 2 or 3 is seen here, SHA2 is not configured, so
1074              *  eat the option, and drop back to SHA-1.
1075              */
1076             if (p[1] == '2' || p[1] == '3') {
1077                p++;
1078             }
1079             fo->flags |= FO_SHA1;
1080             break;
1081          }
1082          break;
1083       case 's':
1084          fo->flags |= FO_SPARSE;
1085          break;
1086       case 'm':
1087          fo->flags |= FO_MTIMEONLY;
1088          break;
1089       case 'k':
1090          fo->flags |= FO_KEEPATIME;
1091          break;
1092       case 'A':
1093          fo->flags |= FO_ACL;
1094          break;
1095       case 'V':                  /* verify options */
1096          /* Copy Verify Options */
1097          for (j=0; *p && *p != ':'; p++) {
1098             fo->VerifyOpts[j] = *p;
1099             if (j < (int)sizeof(fo->VerifyOpts) - 1) {
1100                j++;
1101             }
1102          }
1103          fo->VerifyOpts[j] = 0;
1104          break;
1105       case 'C':                  /* accurate options */
1106          /* Copy Accurate Options */
1107          for (j=0; *p && *p != ':'; p++) {
1108             fo->AccurateOpts[j] = *p;
1109             if (j < (int)sizeof(fo->AccurateOpts) - 1) {
1110                j++;
1111             }
1112          }
1113          fo->AccurateOpts[j] = 0;
1114          break;
1115       case 'P':                  /* strip path */
1116          /* Get integer */
1117          p++;                    /* skip P */
1118          for (j=0; *p && *p != ':'; p++) {
1119             strip[j] = *p;
1120             if (j < (int)sizeof(strip) - 1) {
1121                j++;
1122             }
1123          }
1124          strip[j] = 0;
1125          fo->strip_path = atoi(strip);
1126          fo->flags |= FO_STRIPPATH;
1127          Dmsg2(100, "strip=%s strip_path=%d\n", strip, fo->strip_path);
1128          break;
1129       case 'w':
1130          fo->flags |= FO_IF_NEWER;
1131          break;
1132       case 'W':
1133          fo->flags |= FO_ENHANCEDWILD;
1134          break;
1135       case 'Z':                 /* gzip compression */
1136          fo->flags |= FO_GZIP;
1137          fo->GZIP_level = *++p - '0';
1138          break;
1139       case 'K':
1140          fo->flags |= FO_NOATIME;
1141          break;
1142       case 'c':
1143          fo->flags |= FO_CHKCHANGES;
1144          break;
1145       case 'N':
1146          fo->flags |= FO_HONOR_NODUMP;
1147          break;
1148       case 'X':
1149          fo->flags |= FO_XATTR;
1150          break;
1151       default:
1152          Emsg1(M_ERROR, 0, _("Unknown include/exclude option: %c\n"), *p);
1153          break;
1154       }
1155    }
1156 }
1157
1158
1159 /*
1160  * Director is passing his Fileset
1161  */
1162 static int fileset_cmd(JCR *jcr)
1163 {
1164    BSOCK *dir = jcr->dir_bsock;
1165
1166 #if defined(WIN32_VSS)
1167    int vss = 0;
1168
1169    sscanf(dir->msg, "fileset vss=%d", &vss);
1170    enable_vss = vss;
1171 #endif
1172
1173    if (!init_fileset(jcr)) {
1174       return 0;
1175    }
1176    while (dir->recv() >= 0) {
1177       strip_trailing_junk(dir->msg);
1178       Dmsg1(500, "Fileset: %s\n", dir->msg);
1179       add_fileset(jcr, dir->msg);
1180    }
1181    if (!term_fileset(jcr)) {
1182       return 0;
1183    }
1184    return dir->fsend(OKinc);
1185 }
1186
1187 static void free_bootstrap(JCR *jcr)
1188 {
1189    if (jcr->RestoreBootstrap) {
1190       unlink(jcr->RestoreBootstrap);
1191       free_pool_memory(jcr->RestoreBootstrap);
1192       jcr->RestoreBootstrap = NULL;
1193    }
1194 }
1195
1196
1197 static pthread_mutex_t bsr_mutex = PTHREAD_MUTEX_INITIALIZER;
1198 static uint32_t bsr_uniq = 0;
1199
1200 /* 
1201  * The Director sends us the bootstrap file, which
1202  *   we will in turn pass to the SD.
1203  */
1204 static int bootstrap_cmd(JCR *jcr)
1205 {
1206    BSOCK *dir = jcr->dir_bsock;
1207    POOLMEM *fname = get_pool_memory(PM_FNAME);
1208    FILE *bs;
1209
1210    free_bootstrap(jcr);
1211    P(bsr_mutex);
1212    bsr_uniq++;
1213    Mmsg(fname, "%s/%s.%s.%d.bootstrap", me->working_directory, me->hdr.name,
1214       jcr->Job, bsr_uniq);
1215    V(bsr_mutex);
1216    Dmsg1(400, "bootstrap=%s\n", fname);
1217    jcr->RestoreBootstrap = fname;
1218    bs = fopen(fname, "a+b");           /* create file */
1219    if (!bs) {
1220       berrno be;
1221       Jmsg(jcr, M_FATAL, 0, _("Could not create bootstrap file %s: ERR=%s\n"),
1222          jcr->RestoreBootstrap, be.bstrerror());
1223       /*
1224        * Suck up what he is sending to us so that he will then
1225        *   read our error message.
1226        */
1227       while (dir->recv() >= 0)
1228         {  }
1229       free_bootstrap(jcr);
1230       set_jcr_job_status(jcr, JS_ErrorTerminated);
1231       return 0;
1232    }
1233
1234    while (dir->recv() >= 0) {
1235        Dmsg1(200, "filed<dird: bootstrap: %s", dir->msg);
1236        fputs(dir->msg, bs);
1237    }
1238    fclose(bs);
1239    /*
1240     * Note, do not free the bootstrap yet -- it needs to be 
1241     *  sent to the SD 
1242     */
1243    return dir->fsend(OKbootstrap);
1244 }
1245
1246
1247 /*
1248  * Get backup level from Director
1249  *
1250  */
1251 static int level_cmd(JCR *jcr)
1252 {
1253    BSOCK *dir = jcr->dir_bsock;
1254    POOLMEM *level, *buf = NULL;
1255    int mtime_only;
1256
1257    level = get_memory(dir->msglen+1);
1258    Dmsg1(100, "level_cmd: %s", dir->msg);
1259
1260    /* keep compatibility with older directors */
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 }