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