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