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