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