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