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