]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/job.c
Allow restore from multiple storage
[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=%u 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 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, jcr->num_files_examined,
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    if (strstr(dir->msg, "accurate")) {
1260       jcr->accurate = true;
1261    }
1262    if (sscanf(dir->msg, "level = %s ", level) != 1) {
1263       goto bail_out;
1264    }
1265    /* Base backup requested? */
1266    if (strcmp(level, "base") == 0) {
1267       jcr->set_JobLevel(L_BASE);
1268    /* Full backup requested? */
1269    } else if (strcmp(level, "full") == 0) {
1270       jcr->set_JobLevel(L_FULL);
1271    } else if (strstr(level, "differential")) {
1272       jcr->set_JobLevel(L_DIFFERENTIAL);
1273       free_memory(level);
1274       return 1;
1275    } else if (strstr(level, "incremental")) {
1276       jcr->set_JobLevel(L_INCREMENTAL);
1277       free_memory(level);
1278       return 1;
1279    /*
1280     * We get his UTC since time, then sync the clocks and correct it
1281     *   to agree with our clock.
1282     */
1283    } else if (strcmp(level, "since_utime") == 0) {
1284       buf = get_memory(dir->msglen+1);
1285       utime_t since_time, adj;
1286       btime_t his_time, bt_start, rt=0, bt_adj=0;
1287       if (jcr->get_JobLevel() == L_NONE) {
1288          jcr->set_JobLevel(L_SINCE);     /* if no other job level set, do it now */
1289       }
1290       if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d",
1291                  buf, &mtime_only) != 2) {
1292          goto bail_out;
1293       }
1294       since_time = str_to_uint64(buf);  /* this is the since time */
1295       Dmsg1(100, "since_time=%lld\n", since_time);
1296       char ed1[50], ed2[50];
1297       /*
1298        * Sync clocks by polling him for the time. We take
1299        *   10 samples of his time throwing out the first two.
1300        */
1301       for (int i=0; i<10; i++) {
1302          bt_start = get_current_btime();
1303          dir->signal(BNET_BTIME);     /* poll for time */
1304          if (dir->recv() <= 0) {      /* get response */
1305             goto bail_out;
1306          }
1307          if (sscanf(dir->msg, "btime %s", buf) != 1) {
1308             goto bail_out;
1309          }
1310          if (i < 2) {                 /* toss first two results */
1311             continue;
1312          }
1313          his_time = str_to_uint64(buf);
1314          rt = get_current_btime() - bt_start; /* compute round trip time */
1315          Dmsg2(100, "Dirtime=%s FDtime=%s\n", edit_uint64(his_time, ed1),
1316                edit_uint64(bt_start, ed2));
1317          bt_adj +=  bt_start - his_time - rt/2;
1318          Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
1319       }
1320
1321       bt_adj = bt_adj / 8;            /* compute average time */
1322       Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
1323       adj = btime_to_utime(bt_adj);
1324       since_time += adj;              /* adjust for clock difference */
1325       /* Don't notify if time within 3 seconds */
1326       if (adj > 3 || adj < -3) {
1327          int type;
1328          if (adj > 600 || adj < -600) {
1329             type = M_WARNING;
1330          } else {
1331             type = M_INFO;
1332          }
1333          Jmsg(jcr, type, 0, _("DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n"), adj);
1334       }
1335       dir->signal(BNET_EOD);
1336
1337       Dmsg2(100, "adj=%lld since_time=%lld\n", adj, since_time);
1338       jcr->incremental = 1;           /* set incremental or decremental backup */
1339       jcr->mtime = since_time;        /* set since time */
1340       generate_plugin_event(jcr, bEventSince, (void *)(time_t)jcr->mtime);
1341    } else {
1342       Jmsg1(jcr, M_FATAL, 0, _("Unknown backup level: %s\n"), level);
1343       free_memory(level);
1344       return 0;
1345    }
1346    free_memory(level);
1347    if (buf) {
1348       free_memory(buf);
1349    }
1350    generate_plugin_event(jcr, bEventLevel, (void *)jcr->get_JobLevel());
1351    return dir->fsend(OKlevel);
1352
1353 bail_out:
1354    pm_strcpy(jcr->errmsg, dir->msg);
1355    Jmsg1(jcr, M_FATAL, 0, _("Bad level command: %s\n"), jcr->errmsg);
1356    free_memory(level);
1357    if (buf) {
1358       free_memory(buf);
1359    }
1360    return 0;
1361 }
1362
1363 /*
1364  * Get session parameters from Director -- this is for a Restore command
1365  */
1366 static int session_cmd(JCR *jcr)
1367 {
1368    BSOCK *dir = jcr->dir_bsock;
1369
1370    Dmsg1(100, "SessionCmd: %s", dir->msg);
1371    if (sscanf(dir->msg, sessioncmd, jcr->VolumeName,
1372               &jcr->VolSessionId, &jcr->VolSessionTime,
1373               &jcr->StartFile, &jcr->EndFile,
1374               &jcr->StartBlock, &jcr->EndBlock) != 7) {
1375       pm_strcpy(jcr->errmsg, dir->msg);
1376       Jmsg(jcr, M_FATAL, 0, _("Bad session command: %s"), jcr->errmsg);
1377       return 0;
1378    }
1379
1380    return dir->fsend(OKsession);
1381 }
1382
1383 static void set_storage_auth_key(JCR *jcr, char *key)
1384 {
1385    /* if no key don't update anything */
1386    if (!*key) {                
1387       return;
1388    }
1389
1390    /* We can be contacting multiple storage daemons.
1391     * So, make sure that any old jcr->store_bsock is cleaned up. 
1392     */
1393    if (jcr->store_bsock) {
1394       jcr->store_bsock->destroy();
1395       jcr->store_bsock = NULL;
1396    }
1397
1398    /* We can be contacting multiple storage daemons.
1399     *   So, make sure that any old jcr->sd_auth_key is cleaned up. 
1400     */
1401    if (jcr->sd_auth_key) {
1402       /* If we already have a Authorization key, director can do multi
1403        * storage restore
1404        */
1405       Dmsg0(5, "set multi_restore=true\n");
1406       jcr->multi_restore = true;
1407       bfree(jcr->sd_auth_key);
1408    }
1409
1410    jcr->sd_auth_key = bstrdup(key);
1411 }
1412
1413 /*
1414  * Get address of storage daemon from Director
1415  *
1416  */
1417 static int storage_cmd(JCR *jcr)
1418 {
1419    int stored_port;                /* storage daemon port */
1420    int enable_ssl;                 /* enable ssl to sd */
1421    POOL_MEM sd_auth_key(PM_MESSAGE);
1422    BSOCK *dir = jcr->dir_bsock;
1423    BSOCK *sd = new_bsock();        /* storage daemon bsock */
1424
1425
1426    Dmsg1(100, "StorageCmd: %s", dir->msg);
1427    sd_auth_key.check_size(dir->msglen);
1428    if (sscanf(dir->msg, storaddr, &jcr->stored_addr, &stored_port, 
1429               &enable_ssl, sd_auth_key.c_str()) != 4)
1430    {
1431       if (sscanf(dir->msg, storaddr_v1, &jcr->stored_addr,
1432                  &stored_port, &enable_ssl) != 3)
1433       {
1434          pm_strcpy(jcr->errmsg, dir->msg);
1435          Jmsg(jcr, M_FATAL, 0, _("Bad storage command: %s"), jcr->errmsg);
1436          goto bail_out;
1437       }
1438    }
1439
1440    set_storage_auth_key(jcr, sd_auth_key.c_str());
1441
1442    Dmsg3(110, "Open storage: %s:%d ssl=%d\n", jcr->stored_addr, stored_port, 
1443          enable_ssl);
1444    /* Open command communications with Storage daemon */
1445    /* Try to connect for 1 hour at 10 second intervals */
1446
1447    sd->set_source_address(me->FDsrc_addr);
1448    if (!sd->connect(jcr, 10, (int)me->SDConnectTimeout, me->heartbeat_interval,
1449                 _("Storage daemon"), jcr->stored_addr, NULL, stored_port, 1)) {
1450      sd->destroy();
1451      sd = NULL;
1452    }
1453
1454    if (sd == NULL) {
1455       Jmsg(jcr, M_FATAL, 0, _("Failed to connect to Storage daemon: %s:%d\n"),
1456           jcr->stored_addr, stored_port);
1457       Dmsg2(100, "Failed to connect to Storage daemon: %s:%d\n",
1458           jcr->stored_addr, stored_port);
1459       goto bail_out;
1460    }
1461    Dmsg0(110, "Connection OK to SD.\n");
1462
1463    jcr->store_bsock = sd;
1464
1465    sd->fsend("Hello Start Job %s\n", jcr->Job);
1466    if (!authenticate_storagedaemon(jcr)) {
1467       Jmsg(jcr, M_FATAL, 0, _("Failed to authenticate Storage daemon.\n"));
1468       goto bail_out;
1469    }
1470    Dmsg0(110, "Authenticated with SD.\n");
1471
1472    /* Send OK to Director */
1473    return dir->fsend(OKstore);
1474
1475 bail_out:
1476    dir->fsend(BADcmd, "storage");
1477    return 0;
1478
1479 }
1480
1481
1482 /*
1483  * Do a backup.
1484  */
1485 static int backup_cmd(JCR *jcr)
1486 {
1487    BSOCK *dir = jcr->dir_bsock;
1488    BSOCK *sd = jcr->store_bsock;
1489    int ok = 0;
1490    int SDJobStatus;
1491
1492 #if defined(WIN32_VSS)
1493    // capture state here, if client is backed up by multiple directors
1494    // and one enables vss and the other does not then enable_vss can change
1495    // between here and where its evaluated after the job completes.
1496    jcr->VSS = g_pVSSClient && enable_vss;
1497    if (jcr->VSS) {
1498       /* Run only one at a time */
1499       P(vss_mutex);
1500    }
1501 #endif
1502
1503    /*
1504     * Validate some options given to the backup make sense for the compiled in
1505     * options of this filed.
1506     */
1507    if (jcr->ff->flags & FO_ACL && !have_acl) {
1508       Jmsg(jcr, M_FATAL, 0, _("ACL support not configured for your machine.\n"));
1509       goto cleanup;
1510    }
1511    if (jcr->ff->flags & FO_XATTR && !have_xattr) {
1512       Jmsg(jcr, M_FATAL, 0, _("XATTR support not configured for your machine.\n"));
1513       goto cleanup;
1514    }
1515
1516    set_jcr_job_status(jcr, JS_Blocked);
1517    jcr->set_JobType(JT_BACKUP);
1518    Dmsg1(100, "begin backup ff=%p\n", jcr->ff);
1519
1520    if (sd == NULL) {
1521       Jmsg(jcr, M_FATAL, 0, _("Cannot contact Storage daemon\n"));
1522       dir->fsend(BADcmd, "backup");
1523       goto cleanup;
1524    }
1525
1526    dir->fsend(OKbackup);
1527    Dmsg1(110, "filed>dird: %s", dir->msg);
1528
1529    /*
1530     * Send Append Open Session to Storage daemon
1531     */
1532    sd->fsend(append_open);
1533    Dmsg1(110, ">stored: %s", sd->msg);
1534    /*
1535     * Expect to receive back the Ticket number
1536     */
1537    if (bget_msg(sd) >= 0) {
1538       Dmsg1(110, "<stored: %s", sd->msg);
1539       if (sscanf(sd->msg, OK_open, &jcr->Ticket) != 1) {
1540          Jmsg(jcr, M_FATAL, 0, _("Bad response to append open: %s\n"), sd->msg);
1541          goto cleanup;
1542       }
1543       Dmsg1(110, "Got Ticket=%d\n", jcr->Ticket);
1544    } else {
1545       Jmsg(jcr, M_FATAL, 0, _("Bad response from stored to open command\n"));
1546       goto cleanup;
1547    }
1548
1549    /*
1550     * Send Append data command to Storage daemon
1551     */
1552    sd->fsend(append_data, jcr->Ticket);
1553    Dmsg1(110, ">stored: %s", sd->msg);
1554
1555    /*
1556     * Expect to get OK data
1557     */
1558    Dmsg1(110, "<stored: %s", sd->msg);
1559    if (!response(jcr, sd, OK_data, "Append Data")) {
1560       goto cleanup;
1561    }
1562    
1563    generate_daemon_event(jcr, "JobStart");
1564    generate_plugin_event(jcr, bEventStartBackupJob);
1565
1566 #if defined(WIN32_VSS)
1567    /* START VSS ON WIN32 */
1568    if (jcr->VSS) {      
1569       if (g_pVSSClient->InitializeForBackup()) {   
1570         /* tell vss which drives to snapshot */   
1571         char szWinDriveLetters[27];   
1572         if (get_win32_driveletters(jcr->ff, szWinDriveLetters)) {
1573             Jmsg(jcr, M_INFO, 0, _("Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n"), g_pVSSClient->GetDriverName(), szWinDriveLetters);
1574             if (!g_pVSSClient->CreateSnapshots(szWinDriveLetters)) {               
1575                Jmsg(jcr, M_WARNING, 0, _("Generate VSS snapshots failed.\n"));
1576                jcr->JobErrors++;
1577             } else {
1578                /* tell user if snapshot creation of a specific drive failed */
1579                int i;
1580                for (i=0; i < (int)strlen(szWinDriveLetters); i++) {
1581                   if (islower(szWinDriveLetters[i])) {
1582                      Jmsg(jcr, M_WARNING, 0, _("Generate VSS snapshot of drive \"%c:\\\" failed. VSS support is disabled on this drive.\n"), szWinDriveLetters[i]);
1583                      jcr->JobErrors++;
1584                   }
1585                }
1586                /* inform user about writer states */
1587                for (i=0; i < (int)g_pVSSClient->GetWriterCount(); i++)                
1588                   if (g_pVSSClient->GetWriterState(i) < 1) {
1589                      Jmsg(jcr, M_WARNING, 0, _("VSS Writer (PrepareForBackup): %s\n"), g_pVSSClient->GetWriterInfo(i));                    
1590                      jcr->JobErrors++;
1591                   }                            
1592             }
1593         } else {
1594             Jmsg(jcr, M_INFO, 0, _("No drive letters found for generating VSS snapshots.\n"));
1595         }
1596       } else {
1597          berrno be;
1598          Jmsg(jcr, M_WARNING, 0, _("VSS was not initialized properly. VSS support is disabled. ERR=%s\n"), be.bstrerror());
1599       } 
1600       run_scripts(jcr, jcr->RunScripts, "ClientAfterVSS");
1601    }
1602 #endif
1603
1604    /*
1605     * Send Files to Storage daemon
1606     */
1607    Dmsg1(110, "begin blast ff=%p\n", (FF_PKT *)jcr->ff);
1608    if (!blast_data_to_storage_daemon(jcr, NULL)) {
1609       set_jcr_job_status(jcr, JS_ErrorTerminated);
1610       bnet_suppress_error_messages(sd, 1);
1611       bget_msg(sd);                   /* Read final response from append_data */
1612       Dmsg0(110, "Error in blast_data.\n");
1613    } else {
1614       set_jcr_job_status(jcr, JS_Terminated);
1615       /* Note, the above set status will not override an error */
1616       if (!(jcr->JobStatus == JS_Terminated || jcr->JobStatus == JS_Warnings)) {
1617          bnet_suppress_error_messages(sd, 1);
1618          goto cleanup;                /* bail out now */
1619       }
1620       /*
1621        * Expect to get response to append_data from Storage daemon
1622        */
1623       if (!response(jcr, sd, OK_append, "Append Data")) {
1624          set_jcr_job_status(jcr, JS_ErrorTerminated);
1625          goto cleanup;
1626       }
1627
1628       /*
1629        * Send Append End Data to Storage daemon
1630        */
1631       sd->fsend(append_end, jcr->Ticket);
1632       /* Get end OK */
1633       if (!response(jcr, sd, OK_end, "Append End")) {
1634          set_jcr_job_status(jcr, JS_ErrorTerminated);
1635          goto cleanup;
1636       }
1637
1638       /*
1639        * Send Append Close to Storage daemon
1640        */
1641       sd->fsend(append_close, jcr->Ticket);
1642       while (bget_msg(sd) >= 0) {    /* stop on signal or error */
1643          if (sscanf(sd->msg, OK_close, &SDJobStatus) == 1) {
1644             ok = 1;
1645             Dmsg2(200, "SDJobStatus = %d %c\n", SDJobStatus, (char)SDJobStatus);
1646          }
1647       }
1648       if (!ok) {
1649          Jmsg(jcr, M_FATAL, 0, _("Append Close with SD failed.\n"));
1650          goto cleanup;
1651       }
1652       if (!(SDJobStatus == JS_Terminated || SDJobStatus == JS_Warnings)) {
1653          Jmsg(jcr, M_FATAL, 0, _("Bad status %d returned from Storage Daemon.\n"),
1654             SDJobStatus);
1655       }
1656    }
1657
1658 cleanup:
1659 #if defined(WIN32_VSS)
1660    /* STOP VSS ON WIN32 */
1661    /* tell vss to close the backup session */
1662    if (jcr->VSS) {
1663       if (g_pVSSClient->CloseBackup()) {             
1664          /* inform user about writer states */
1665          for (int i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) {
1666             int msg_type = M_INFO;
1667             if (g_pVSSClient->GetWriterState(i) < 1) {
1668                msg_type = M_WARNING;
1669                jcr->JobErrors++;
1670             }
1671             Jmsg(jcr, msg_type, 0, _("VSS Writer (BackupComplete): %s\n"), g_pVSSClient->GetWriterInfo(i));
1672          }
1673       }
1674       Win32ConvCleanupCache();
1675       V(vss_mutex);
1676    }
1677 #endif
1678
1679    generate_plugin_event(jcr, bEventEndBackupJob);
1680    return 0;                          /* return and stop command loop */
1681 }
1682
1683 /*
1684  * Do a Verify for Director
1685  *
1686  */
1687 static int verify_cmd(JCR *jcr)
1688 {
1689    BSOCK *dir = jcr->dir_bsock;
1690    BSOCK *sd  = jcr->store_bsock;
1691    char level[100];
1692
1693    jcr->set_JobType(JT_VERIFY);
1694    if (sscanf(dir->msg, verifycmd, level) != 1) {
1695       dir->fsend(_("2994 Bad verify command: %s\n"), dir->msg);
1696       return 0;
1697    }
1698
1699    if (strcasecmp(level, "init") == 0) {
1700       jcr->set_JobLevel(L_VERIFY_INIT);
1701    } else if (strcasecmp(level, "catalog") == 0){
1702       jcr->set_JobLevel(L_VERIFY_CATALOG);
1703    } else if (strcasecmp(level, "volume") == 0){
1704       jcr->set_JobLevel(L_VERIFY_VOLUME_TO_CATALOG);
1705    } else if (strcasecmp(level, "data") == 0){
1706       jcr->set_JobLevel(L_VERIFY_DATA);
1707    } else if (strcasecmp(level, "disk_to_catalog") == 0) {
1708       jcr->set_JobLevel(L_VERIFY_DISK_TO_CATALOG);
1709    } else {
1710       dir->fsend(_("2994 Bad verify level: %s\n"), dir->msg);
1711       return 0;
1712    }
1713
1714    dir->fsend(OKverify);
1715
1716    generate_daemon_event(jcr, "JobStart");
1717    generate_plugin_event(jcr, bEventLevel, (void *)jcr->get_JobLevel());
1718    generate_plugin_event(jcr, bEventStartVerifyJob);
1719
1720    Dmsg1(110, "filed>dird: %s", dir->msg);
1721
1722    switch (jcr->get_JobLevel()) {
1723    case L_VERIFY_INIT:
1724    case L_VERIFY_CATALOG:
1725       do_verify(jcr);
1726       break;
1727    case L_VERIFY_VOLUME_TO_CATALOG:
1728       if (!open_sd_read_session(jcr)) {
1729          return 0;
1730       }
1731       start_dir_heartbeat(jcr);
1732       do_verify_volume(jcr);
1733       stop_dir_heartbeat(jcr);
1734       /*
1735        * Send Close session command to Storage daemon
1736        */
1737       sd->fsend(read_close, jcr->Ticket);
1738       Dmsg1(130, "filed>stored: %s", sd->msg);
1739
1740       /* ****FIXME**** check response */
1741       bget_msg(sd);                      /* get OK */
1742
1743       /* Inform Storage daemon that we are done */
1744       sd->signal(BNET_TERMINATE);
1745
1746       break;
1747    case L_VERIFY_DISK_TO_CATALOG:
1748       do_verify(jcr);
1749       break;
1750    default:
1751       dir->fsend(_("2994 Bad verify level: %s\n"), dir->msg);
1752       return 0;
1753    }
1754
1755    dir->signal(BNET_EOD);
1756    generate_plugin_event(jcr, bEventEndVerifyJob);
1757    return 0;                          /* return and terminate command loop */
1758 }
1759
1760 /*
1761  * Do a Restore for Director
1762  *
1763  */
1764 static int restore_cmd(JCR *jcr)
1765 {
1766    BSOCK *dir = jcr->dir_bsock;
1767    BSOCK *sd = jcr->store_bsock;
1768    POOLMEM *args;
1769    bool use_regexwhere=false;
1770    int prefix_links;
1771    char replace;
1772
1773    /*
1774     * Scan WHERE (base directory for restore) from command
1775     */
1776    Dmsg0(150, "restore command\n");
1777    /* Pickup where string */
1778    args = get_memory(dir->msglen+1);
1779    *args = 0;
1780
1781    if (sscanf(dir->msg, restorecmd, &replace, &prefix_links, args) != 3) {
1782       if (sscanf(dir->msg, restorecmdR, &replace, &prefix_links, args) != 3){
1783          if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
1784             pm_strcpy(jcr->errmsg, dir->msg);
1785             Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
1786             return 0;
1787          }
1788          *args = 0;
1789       }
1790       use_regexwhere = true;
1791    }
1792    /* Turn / into nothing */
1793    if (IsPathSeparator(args[0]) && args[1] == '\0') {
1794       args[0] = '\0';
1795    }
1796
1797    Dmsg2(150, "Got replace %c, where=%s\n", replace, args);
1798    unbash_spaces(args);
1799
1800    if (use_regexwhere) {
1801       jcr->where_bregexp = get_bregexps(args);
1802       if (!jcr->where_bregexp) {
1803          Jmsg(jcr, M_FATAL, 0, _("Bad where regexp. where=%s\n"), args);
1804          free_pool_memory(args);
1805          return 0;
1806       }
1807    } else {
1808       jcr->where = bstrdup(args);
1809    }
1810
1811    free_pool_memory(args);
1812    jcr->replace = replace;
1813    jcr->prefix_links = prefix_links;
1814
1815    dir->fsend(OKrestore);
1816    Dmsg1(110, "filed>dird: %s", dir->msg);
1817
1818    jcr->set_JobType(JT_RESTORE);
1819
1820    set_jcr_job_status(jcr, JS_Blocked);
1821
1822    if (!open_sd_read_session(jcr)) {
1823       set_jcr_job_status(jcr, JS_ErrorTerminated);
1824       goto bail_out;
1825    }
1826
1827    set_jcr_job_status(jcr, JS_Running);
1828
1829    /*
1830     * Do restore of files and data
1831     */
1832    start_dir_heartbeat(jcr);
1833    generate_daemon_event(jcr, "JobStart");
1834    generate_plugin_event(jcr, bEventStartRestoreJob);
1835    do_restore(jcr);
1836    stop_dir_heartbeat(jcr);
1837
1838    set_jcr_job_status(jcr, JS_Terminated);
1839    if (jcr->JobStatus != JS_Terminated) {
1840       bnet_suppress_error_messages(sd, 1);
1841    }
1842
1843    /*
1844     * Send Close session command to Storage daemon
1845     */
1846    sd->fsend(read_close, jcr->Ticket);
1847    Dmsg1(130, "filed>stored: %s", sd->msg);
1848
1849    bget_msg(sd);                      /* get OK */
1850
1851    /* Inform Storage daemon that we are done */
1852    sd->signal(BNET_TERMINATE);
1853
1854 bail_out:
1855    bfree_and_null(jcr->where);
1856
1857    if (jcr->JobErrors) {
1858       set_jcr_job_status(jcr, JS_ErrorTerminated);
1859    }
1860
1861    Dmsg0(130, "Done in job.c\n");
1862
1863    int ret;
1864    if (jcr->multi_restore) {
1865       dir->fsend(OKstoreend);
1866       ret = 1;     /* we continue the loop, waiting for next part */
1867    } else {
1868       end_restore_cmd(jcr);
1869       ret = 0;     /* we stop here */
1870    }
1871
1872    return ret;
1873 }
1874
1875 static int end_restore_cmd(JCR *jcr) 
1876 {
1877    Dmsg0(5, "end_restore_cmd\n");
1878    generate_plugin_event(jcr, bEventEndRestoreJob);
1879    return 0;                          /* return and terminate command loop */
1880 }
1881
1882 static int open_sd_read_session(JCR *jcr)
1883 {
1884    BSOCK *sd = jcr->store_bsock;
1885
1886    if (!sd) {
1887       Jmsg(jcr, M_FATAL, 0, _("Improper calling sequence.\n"));
1888       return 0;
1889    }
1890    Dmsg4(120, "VolSessId=%ld VolsessT=%ld SF=%ld EF=%ld\n",
1891       jcr->VolSessionId, jcr->VolSessionTime, jcr->StartFile, jcr->EndFile);
1892    Dmsg2(120, "JobId=%d vol=%s\n", jcr->JobId, "DummyVolume");
1893    /*
1894     * Open Read Session with Storage daemon
1895     */
1896    sd->fsend(read_open, "DummyVolume",
1897       jcr->VolSessionId, jcr->VolSessionTime, jcr->StartFile, jcr->EndFile,
1898       jcr->StartBlock, jcr->EndBlock);
1899    Dmsg1(110, ">stored: %s", sd->msg);
1900
1901    /*
1902     * Get ticket number
1903     */
1904    if (bget_msg(sd) >= 0) {
1905       Dmsg1(110, "filed<stored: %s", sd->msg);
1906       if (sscanf(sd->msg, OK_open, &jcr->Ticket) != 1) {
1907          Jmsg(jcr, M_FATAL, 0, _("Bad response to SD read open: %s\n"), sd->msg);
1908          return 0;
1909       }
1910       Dmsg1(110, "filed: got Ticket=%d\n", jcr->Ticket);
1911    } else {
1912       Jmsg(jcr, M_FATAL, 0, _("Bad response from stored to read open command\n"));
1913       return 0;
1914    }
1915
1916    if (!send_bootstrap_file(jcr)) {
1917       return 0;
1918    }
1919
1920    /*
1921     * Start read of data with Storage daemon
1922     */
1923    sd->fsend(read_data, jcr->Ticket);
1924    Dmsg1(110, ">stored: %s", sd->msg);
1925
1926    /*
1927     * Get OK data
1928     */
1929    if (!response(jcr, sd, OK_data, "Read Data")) {
1930       return 0;
1931    }
1932    return 1;
1933 }
1934
1935 /*
1936  * Destroy the Job Control Record and associated
1937  * resources (sockets).
1938  */
1939 static void filed_free_jcr(JCR *jcr)
1940 {
1941    if (jcr->store_bsock) {
1942       jcr->store_bsock->close();
1943    }
1944    free_bootstrap(jcr);
1945    if (jcr->last_fname) {
1946       free_pool_memory(jcr->last_fname);
1947    }
1948    free_runscripts(jcr->RunScripts);
1949    delete jcr->RunScripts;
1950
1951    if (jcr->JobId != 0)
1952       write_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
1953
1954    return;
1955 }
1956
1957 /*
1958  * Get response from Storage daemon to a command we
1959  * sent. Check that the response is OK.
1960  *
1961  *  Returns: 0 on failure
1962  *           1 on success
1963  */
1964 int response(JCR *jcr, BSOCK *sd, char *resp, const char *cmd)
1965 {
1966    if (sd->errors) {
1967       return 0;
1968    }
1969    if (bget_msg(sd) > 0) {
1970       Dmsg0(110, sd->msg);
1971       if (strcmp(sd->msg, resp) == 0) {
1972          return 1;
1973       }
1974    }
1975    if (job_canceled(jcr)) {
1976       return 0;                       /* if canceled avoid useless error messages */
1977    }
1978    if (is_bnet_error(sd)) {
1979       Jmsg2(jcr, M_FATAL, 0, _("Comm error with SD. bad response to %s. ERR=%s\n"),
1980          cmd, bnet_strerror(sd));
1981    } else {
1982       Jmsg3(jcr, M_FATAL, 0, _("Bad response to %s command. Wanted %s, got %s\n"),
1983          cmd, resp, sd->msg);
1984    }
1985    return 0;
1986 }
1987
1988 static int send_bootstrap_file(JCR *jcr)
1989 {
1990    FILE *bs;
1991    char buf[2000];
1992    BSOCK *sd = jcr->store_bsock;
1993    const char *bootstrap = "bootstrap\n";
1994    int stat = 0;
1995
1996    Dmsg1(400, "send_bootstrap_file: %s\n", jcr->RestoreBootstrap);
1997    if (!jcr->RestoreBootstrap) {
1998       return 1;
1999    }
2000    bs = fopen(jcr->RestoreBootstrap, "rb");
2001    if (!bs) {
2002       berrno be;
2003       Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"),
2004          jcr->RestoreBootstrap, be.bstrerror());
2005       set_jcr_job_status(jcr, JS_ErrorTerminated);
2006       goto bail_out;
2007    }
2008    sd->msglen = pm_strcpy(sd->msg, bootstrap);
2009    sd->send();
2010    while (fgets(buf, sizeof(buf), bs)) {
2011       sd->msglen = Mmsg(sd->msg, "%s", buf);
2012       sd->send();
2013    }
2014    sd->signal(BNET_EOD);
2015    fclose(bs);
2016    if (!response(jcr, sd, OKSDbootstrap, "Bootstrap")) {
2017       set_jcr_job_status(jcr, JS_ErrorTerminated);
2018       goto bail_out;
2019    }
2020    stat = 1;
2021
2022 bail_out:
2023    free_bootstrap(jcr);
2024    return stat;
2025 }