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