]> git.sur5r.net Git - bacula/bacula/commitdiff
bacula script + stack overrun -- see kes30Oct02
authorKern Sibbald <kern@sibbald.com>
Fri, 1 Nov 2002 13:19:01 +0000 (13:19 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 1 Nov 2002 13:19:01 +0000 (13:19 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@181 91ce42f0-d328-0410-95d8-f526ca767f89

13 files changed:
bacula/kernstodo
bacula/src/baconfig.h
bacula/src/dird/dird_conf.c
bacula/src/dird/restore.c
bacula/src/dird/ua_run.c
bacula/src/filed/restore.c
bacula/src/findlib/create_file.c
bacula/src/findlib/find.h
bacula/src/findlib/protos.h
bacula/src/stored/bextract.c
bacula/src/stored/bscan.c
bacula/src/stored/label.c
bacula/src/version.h

index bd14c95fb6f93fcb568633225315b76a3acccaad..5713158b8330cfd64cc4ef341c23ac1b6481e5eb 100644 (file)
@@ -1,5 +1,5 @@
                  Kern's ToDo List
-                 30 October 2002
+                 1 November 2002
 
 To do:    
 - Document that two Verifys at same time on same client do not work.
@@ -9,6 +9,7 @@ To do:
 - Document buffer size considerations with Sparse files --
 - Document saving MySQL databases, where to find code for shutting 
   down and saving other databases.
+- Test restore options. Test bscan and MD5 in FileSet.
 
 For 1.27 release:
 - Continue improving the restore process (handling
@@ -16,10 +17,10 @@ For 1.27 release:
   position the tape, ...)
 - Work more on how to to a Bacula restore beginning with
   just a Bacula tape and a boot floppy (bare metal recovery).
+- Try bare metal Windows restore
 
-- Finish implementation of restore "replace" options, and document.
-- Write bcopy program.
-- Recovery of a bad tape (bcopy)
+- Write bcopy program -- recovery of bad tape.
+- Fix read_record to handle multiple sessions.
 
 - Program files (i.e. execute a program to read/write files).
   Pass read date of last backup, size of file last time.
@@ -34,11 +35,8 @@ For 1.27 release:
 - Add code to reject whole blocks if not wanted on restore.
 - Possibly add email to Watchdog if drive is unmounted too
   long and a job is waiting on the drive.
-- What to do with btime and JobTDate?
-- Add FileSet MD5 to bscan.
 - Strip trailing slashes from Include directory names in the FD.
 - Use read_record.c in SD code.
-- Try bare metal Windows restore
 - Add EOM records ???????
 - Why don't we get an error message from Win32 FD when bootstrap 
   file cannot be created for restore command?
@@ -555,4 +553,5 @@ Done: (see kernsdone for more)
   create_volume_list) -- also in restore command?
 - File system type from File daemon
 - Move block size code from block.c to init_dev().
-
+- Add FileSet MD5 to bscan.
+- Finish implementation of restore "replace" options, and document.
index 627dc0fdbbc2c3e324e9722adf7691ee4ed8e1c0..8a9f2f51f09ff05aa2024e2d66692d4986cae160 100644 (file)
@@ -348,5 +348,13 @@ extern int thr_setconcurrency(int);
 #define S_ISWIN32 020000
 #endif
 
+/* Replace codes needed in both file routines and non-file routines */
+/* Job replace codes -- in "replace" */
+#define REPLACE_ALWAYS   'a'
+#define REPLACE_IFNEWER  'w'
+#define REPLACE_NEVER    'n'
+#define REPLACE_IFOLDER  'o'
+
+
 
 #endif /* _BACONFIG_H */
index a5a4d12f1eec02905d5ce4e8ab046f05c1711beb..d7e873134b76162aff01c2ea23bd02ac69cdbdcc 100644 (file)
@@ -174,7 +174,7 @@ static struct res_items job_items[] = {
    {"client",   store_res,     ITEM(res_job.client),   R_CLIENT, 0, 0},
    {"fileset",  store_res,     ITEM(res_job.fileset),  R_FILESET, 0, 0},
    {"where",    store_dir,     ITEM(res_job.RestoreWhere), 0, 0, 0},
-   {"replace",  store_replace, ITEM(res_job.replace), 'a', ITEM_DEFAULT, 0},
+   {"replace",  store_replace, ITEM(res_job.replace), REPLACE_ALWAYS, ITEM_DEFAULT, 0},
    {"bootstrap",store_dir,     ITEM(res_job.RestoreBootstrap), 0, 0, 0},
    {"maxruntime", store_time,  ITEM(res_job.MaxRunTime), 0, 0, 0},
    {"maxstartdelay", store_time,ITEM(res_job.MaxStartDelay), 0, 0, 0},
@@ -333,9 +333,10 @@ static struct s_kw RestoreFields[] = {
 
 /* Options permitted in Restore replace= */
 struct s_kw ReplaceOptions[] = {
-   {"always",         'a'},           /* always */
-   {"ifnewer",        'w'},
-   {"never",          'n'},
+   {"always",         REPLACE_ALWAYS},
+   {"ifnewer",        REPLACE_IFNEWER},
+   {"ifolder",        REPLACE_IFOLDER},
+   {"never",          REPLACE_NEVER},
    {NULL,              0}
 };
 
@@ -1216,10 +1217,9 @@ static void store_restore(LEX *lc, struct res_items *item, int index, int pass)
  * Scan for Include options (keyword=option) is converted into one or
  *  two characters. Verifyopts=xxxx is Vxxxx:
  */
-static char *scan_include_options(LEX *lc, int keyword)
+static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen)
 {
    int token, i;
-   static char opts[100];
    char option[3];
 
    option[0] = 0;                    /* default option = none */
@@ -1228,12 +1228,13 @@ static char *scan_include_options(LEX *lc, int keyword)
       token = lex_get_token(lc, T_NAME);            /* expect at least one option */       
       if (keyword == INC_KW_VERIFY) { /* special case */
         /* ***FIXME**** ensure these are in permitted set */
-         strcpy(option, "V");         /* indicate Verify */
-        strcat(option, lc->str);
-         strcat(option, ":");         /* terminate it */
+         bstrncat(opts, "V", optlen);         /* indicate Verify */
+        bstrncat(opts, lc->str, optlen);
+         bstrncat(opts, ":", optlen);         /* terminate it */
       } else {
         for (i=0; FS_options[i].name; i++) {
            if (strcasecmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) {
+              /* NOTE! maximum 2 letters here or increase option[3] */
               option[0] = FS_options[i].option[0];
               option[1] = FS_options[i].option[1];
               i = 0;
@@ -1243,8 +1244,8 @@ static char *scan_include_options(LEX *lc, int keyword)
         if (i != 0) {
             scan_err1(lc, "Expected a FileSet option keyword, got: %s", lc->str);
         }
+        bstrncat(opts, option, optlen);
       }
-      strcat(opts, option);
 
       /* check if more options are specified */
       if (lc->ch != ',') {
@@ -1252,8 +1253,6 @@ static char *scan_include_options(LEX *lc, int keyword)
       }
       token = lex_get_token(lc, T_ALL);      /* yes, eat comma */
    }
-
-   return opts;
 }
 
 
@@ -1286,7 +1285,7 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass)
       if ((token=lex_get_token(lc, T_ALL)) != T_EQUALS) {
          scan_err1(lc, "expected an = following keyword, got: %s", lc->str);
       }
-      strcat(inc_opts, scan_include_options(lc, keyword));
+      scan_include_options(lc, keyword, inc_opts, sizeof(inc_opts));
       if (token == T_BOB) {
         break;
       }
index 9c686b7656671095c5579aeebaf9750416c51c1f..f702c620a6b0184117117f6b50671101b1289cae 100644 (file)
@@ -233,7 +233,7 @@ int do_restore(JCR *jcr)
    if (jcr->job->replace != 0) {
       replace = jcr->job->replace;
    } else {
-      replace = 'a';                  /* always replace */
+      replace = REPLACE_ALWAYS;       /* always replace */
    }
    if (jcr->RestoreWhere) {
       where = jcr->RestoreWhere;      /* override */
index be33e03479e5c028440d568b500c496f77583837..84e5b8c283134a04631ed0d2ba6d3f2285ec6e49 100644 (file)
@@ -281,7 +281,7 @@ int runcmd(UAContext *ua, char *cmd)
    } else if (job->replace) {
       jcr->replace = job->replace;
    } else {
-      jcr->replace = 'a';
+      jcr->replace = REPLACE_ALWAYS;
    }
    replace = ReplaceOptions[0].name;
    for (i=0; ReplaceOptions[i].name; i++) {
index 8953758e1b004ab7d31de1b63ac09cf195697950..322b24038eecd26eadfc88c9da5515b18ac21c65 100644 (file)
@@ -248,7 +248,7 @@ void do_restore(JCR *jcr)
         print_ls_output(jcr, ofile, lname, type, &statp);
 
         extract = create_file(jcr, fname, ofile, lname, type, 
-                              stream, &statp, attribsEx, &ofd);
+                              stream, &statp, attribsEx, &ofd, jcr->replace);
          Dmsg1(40, "Extract=%d\n", extract);
         if (extract) {
            jcr->JobFiles++;
index 12e8ede30905b881c9d0006091d2cd4174ad6d51..b1d83cc07eb843952b2def64e9879a4caf496689 100644 (file)
@@ -58,7 +58,7 @@
  */
 int create_file(void *jcr, char *fname, char *ofile, char *lname,
                int type, int stream, struct stat *statp, 
-               char *attribsEx, int *ofd)
+               char *attribsEx, int *ofd, int replace)
 {
    int new_mode, parent_mode, mode;
    uid_t uid;
@@ -68,9 +68,6 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname,
    char *f, *p, savechr;
 
    *ofd = -1;
-/*
- * new_mode = S_IRWXUGO & ~umask(0);
- */
    new_mode = statp->st_mode;
    Dmsg2(300, "newmode=%x file=%s\n", new_mode, ofile);
    parent_mode = S_IWUSR | S_IXUSR | new_mode;
@@ -81,12 +78,35 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname,
    case FT_LNKSAVED:                 /* Hard linked, file already saved */
       Dmsg2(130, "Hard link %s => %s\n", ofile, lname);
       if (link(lname, ofile) != 0) {
-         Jmsg3(jcr, M_ERROR, 0, "Could not hard link %s ==> %s: ERR=%s\n"
+         Jmsg3(jcr, M_ERROR, 0, _("Could not hard link %s ==> %s: ERR=%s\n")
               ofile, lname, strerror(errno));
       }
       break;
    case FT_REGE:                     /* empty file */
    case FT_REG:                      /* regular file */
+      /* If not always replacing, do a stat and decide */
+      if (replace != REPLACE_ALWAYS) {
+        struct stat mstatp;
+        if (lstat(ofile, &mstatp) == 0) {
+           switch (replace) {
+           case REPLACE_IFNEWER:
+              if (statp->st_mtime < mstatp.st_mtime) {
+                  Jmsg1(jcr, M_INFO, 0, _("File %s skipped. Not newer.\n"), ofile);
+                 return 0;
+              }
+              break;
+           case REPLACE_IFOLDER:
+              if (statp->st_mtime > mstatp.st_mtime) {
+                  Jmsg1(jcr, M_INFO, 0, _("File %s skipped. Not older.\n"), ofile);
+                 return 0;
+              }
+              break;
+           case REPLACE_NEVER:
+               Jmsg1(jcr, M_INFO, 0, _("File %s skipped. Already exists.\n"), ofile);
+              return 0;
+           }
+        }
+      }
       /* Separate pathname and filename */
       for (p=f=ofile; *p; p++) {
          if (*p == '/') {
@@ -99,13 +119,13 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname,
 
       fnl = p - f;
       if (fnl == 0) {
-         Jmsg1(jcr, M_ERROR, 0, "Zero length filename: %s\n", fname);
+         Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname);
         return 0;
       }
 
       pnl = f - ofile - 1;    
       if (pnl <= 0) {
-         Jmsg1(jcr, M_ERROR, 0, "Zero length path: %s\n", fname);
+         Jmsg1(jcr, M_ERROR, 0, _("Zero length path: %s\n"), fname);
         return 0;
       }
       savechr = ofile[pnl];
@@ -131,34 +151,34 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname,
       }
       Dmsg1(50, "Create file: %s\n", ofile);
       if ((*ofd = open(ofile, mode, S_IRUSR | S_IWUSR)) < 0) {
-         Jmsg2(jcr, M_ERROR, 0, "Could not create %s: ERR=%s\n", ofile, strerror(errno));
+         Jmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), ofile, strerror(errno));
         return 0;
       }
       return 1;
    case FT_LNK:
       Dmsg2(130, "FT_LNK should restore: %s -> %s\n", ofile, lname);
       if (symlink(lname, ofile) != 0 && errno != EEXIST) {
-         Jmsg3(jcr, M_ERROR, 0, "Could not symlink %s -> %s: ERR=%s\n"
+         Jmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n")
            ofile, lname, strerror(errno));
       }
       return 0;
    case FT_DIR:
       Dmsg2(300, "Make dir mode=%o dir=%s\n", new_mode, ofile);
       if (make_path(jcr, ofile, new_mode, parent_mode, uid, gid, 0, NULL) != 0) {
-         Jmsg1(jcr, M_ERROR, 0, "Could not make directory: %s\n", ofile);
+         Jmsg1(jcr, M_ERROR, 0, _("Could not make directory: %s\n"), ofile);
       }
       return 0;
    case FT_SPEC:
       if (S_ISFIFO(statp->st_mode)) {
          Dmsg1(0, "Restore fifo: %s\n", ofile);
         if (mkfifo(ofile, statp->st_mode) != 0) {
-            Jmsg2(jcr, M_ERROR, 0, "Cannot make fifo %s: ERR=%s\n", ofile, strerror(errno));
+            Jmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"), ofile, strerror(errno));
            return 0;
         }
       } else {         
          Dmsg1(0, "Restore node: %s\n", ofile);
         if (mknod(ofile, statp->st_mode, statp->st_rdev) != 0) {
-            Jmsg2(jcr, M_ERROR, 0, "Cannot make node %s: ERR=%s\n", ofile, strerror(errno));
+            Jmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"), ofile, strerror(errno));
            return 0;
         }
       }       
@@ -175,10 +195,10 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname,
    case FT_NORECURSE:
    case FT_NOFSCHG:
    case FT_NOOPEN:
-      Jmsg2(jcr, M_ERROR, 0, "Original file %s not saved. Stat=%d\n", fname, type);
+      Jmsg2(jcr, M_ERROR, 0, _("Original file %s not saved. Stat=%d\n"), fname, type);
       return 0;
    default:
-      Jmsg2(jcr, M_ERROR, 0, "Unknown file type %d; not restored: %s\n", type, fname);
+      Jmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), type, fname);
       return 0;
    }
 
index d8a0e26d8bbaff5714fd9270f6bd05679c29f735..ed362bbe05bb63ea45f5a5c88e78055921bb64f5 100755 (executable)
@@ -45,7 +45,6 @@
 
 #include "save-cwd.h"
 
-
 /* 
  *  NOTE!!! These go on the tape, so don't change them. If 
  *  need be, add to them.
index 69b5c2b6779edc30e36d7b685653720b5f34ed5a..5e2a61801ed1c86019c9a677a18250b0e5ade212 100644 (file)
@@ -34,7 +34,7 @@ int set_attributes(void *jcr, char *fname, char *ofile, char *lname,
 /* from create_file.c */
 int create_file(void *jcr, char *fname, char *ofile, char *lname,
                 int type, int stream, struct stat *statp, 
-                char *attribsEx, int *ofd);
+                char *attribsEx, int *ofd, int replace);
 
 /* From find.c */
 FF_PKT *init_find_files();
index c5a5554d7622626af6eb2599b1ff90fdda5670ad..4df73cd10214c25eca77b484f59ae5d260ee03ae 100644 (file)
@@ -362,7 +362,7 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
          /*          Pmsg1(000, "Restoring: %s\n", ofile); */
 
         extract = create_file(jcr, fname, ofile, lname, type, stream,
-                              &statp, attribsEx, &ofd);
+                              &statp, attribsEx, &ofd, REPLACE_ALWAYS);
         num_files++;
 
         if (extract) {
index 9ab112e5315598bbba1b274fbd875841fbc81e85..2034ca2fce044205c4f279f03a93a3e339260045 100644 (file)
@@ -398,6 +398,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
 
            /* Create FileSet record */
            strcpy(fsr.FileSet, label.FileSetName);
+           strcpy(fsr.MD5, label.FileSetMD5);
            create_fileset_record(db, &fsr);
            jr.FileSetId = fsr.FileSetId;
 
@@ -763,8 +764,10 @@ static int create_fileset_record(B_DB *db, FILESET_DBR *fsr)
       return 1;
    }
    fsr->FileSetId = 0;
-   fsr->MD5[0] = ' ';                 /* ***FIXME*** */
-   fsr->MD5[1] = 0;
+   if (fsr->MD5[0] == 0) {
+      fsr->MD5[0] = ' ';              /* Equivalent to nothing */
+      fsr->MD5[1] = 0;
+   }
    if (db_get_fileset_record(db, fsr)) {
       if (verbose) {
          Pmsg1(000, _("Fileset \"%s\" already exists.\n"), fsr->FileSet);
index 137ea73e24b4b7e68fa36570adb5c0e464c3efad..82432efd37b045d8851cafa7c38897d627521646 100644 (file)
@@ -662,6 +662,8 @@ int unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec)
    }
    if (label->VerNum >= 11) {
       unser_string(label->FileSetMD5);
+   } else {
+      label->FileSetMD5[0] = 0;
    }
    if (rec->FileIndex == EOS_LABEL) {
       unser_uint32(label->JobFiles);
index b02e1cd68b1acb23f5ab50927db55b29d51db6eb..a4070d4e598f7aa198feb51f6af98046779048a9 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #define VERSION "1.27"
 #define VSTRING "1"
-#define DATE    "30 October 2002"
-#define LSMDATE "30Oct02"
+#define DATE    "01 November 2002"
+#define LSMDATE "01Nov02"
 
 /* Debug flags */
 #define DEBUG 1