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