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