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