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