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