]> git.sur5r.net Git - bacula/bacula/commitdiff
kes15Jun02
authorKern Sibbald <kern@sibbald.com>
Sat, 15 Jun 2002 13:19:51 +0000 (13:19 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 15 Jun 2002 13:19:51 +0000 (13:19 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@42 91ce42f0-d328-0410-95d8-f526ca767f89

21 files changed:
bacula/src/cats/sql_create.c
bacula/src/dird/catreq.c
bacula/src/filed/restore.c
bacula/src/lib/lex.c
bacula/src/lib/message.c
bacula/src/lib/message.h
bacula/src/lib/parse_conf.c
bacula/src/lib/signal.c
bacula/src/stored/Makefile.in
bacula/src/stored/bextract.c
bacula/src/stored/block.c
bacula/src/stored/bls.c
bacula/src/stored/bsr.h [new file with mode: 0644]
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/device.c
bacula/src/stored/match_bsr.c [new file with mode: 0755]
bacula/src/stored/parse_bsr.c [new file with mode: 0755]
bacula/src/stored/protos.h
bacula/src/stored/stored.h
bacula/src/version.h

index 5d63af75772a2e3d367a7499953383b9cedee3a5..04768c323404d19538356a254df5058c4461bd34 100644 (file)
@@ -134,9 +134,11 @@ JobId=%d AND MediaId=%d", jm->JobId, jm->MediaId);
 
    /* Must create it */
    Mmsg(&mdb->cmd, 
-"INSERT INTO JobMedia (JobId, MediaId, FirstIndex, LastIndex) \
-VALUES (%d, %d, %u, %u)", 
-       jm->JobId, jm->MediaId, jm->FirstIndex, jm->LastIndex);
+"INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,\
+StartFile,EndFile,StartBlock,EndBlock) \
+VALUES (%u,%u,%u,%u,%u,%u,%u,%u)", 
+       jm->JobId, jm->MediaId, jm->FirstIndex, jm->LastIndex,
+       jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock);
 
    Dmsg0(30, mdb->cmd);
    if (!INSERT_DB(mdb, mdb->cmd)) {
index f8f9965f6562ca49057ae7c5a412bff32169e0e7..d8b8dc3b33962515dda5dabbc05bdac8d625790d 100644 (file)
@@ -180,8 +180,8 @@ MediaType=%s\n", mr.PoolId, jcr->PoolId, mr.VolStatus, mr.MediaType);
        * Otherwise, record the fact that this job used this Volume 
        */
       if (!relabel) {
-         Dmsg4(100, "create_jobmedia JobId=%d MediaId=%d FI=%d LI=%d\n",
-           jm.JobId, jm.MediaId, jm.FirstIndex, jm.LastIndex);
+         Dmsg6(100, "create_jobmedia JobId=%d MediaId=%d SF=%d EF=%d FI=%d LI=%d\n",
+           jm.JobId, jm.MediaId, jm.StartFile, jm.EndFile, jm.FirstIndex, jm.LastIndex);
         if(!db_create_jobmedia_record(jcr->db, &jm)) {
             Jmsg(jcr, M_ERROR, 0, _("Catalog error creating JobMedia record. %s"),
               db_strerror(jcr->db));
index 3c53741cf6ccd8d51e579e542e16695e10d56c4c..c892bff19a52f36700fe93d1c01e6aead219b362 100644 (file)
@@ -300,8 +300,8 @@ extern char *getgroup(gid_t gid);
  */
 static void print_ls_output(JCR *jcr, char *fname, char *lname, int type, struct stat *statp)
 {
-   /* ********FIXME******** make memory pool */
-   char buf[1000]; 
+   char buf[2000]; 
+   char ec1[30];
    char *p, *f;
    int n;
 
@@ -310,12 +310,12 @@ static void print_ls_output(JCR *jcr, char *fname, char *lname, int type, struct
    p += n;
    n = sprintf(p, "%-8.8s %-8.8s", getuser(statp->st_uid), getgroup(statp->st_gid));
    p += n;
-   n = sprintf(p, "%8" lld " ", (uint64_t)statp->st_size);
+   n = sprintf(p, "%8.8s ", edit_uint64(statp->st_size, ec1));
    p += n;
    p = encode_time(statp->st_ctime, p);
    *p++ = ' ';
    *p++ = ' ';
-   for (f=fname; *f; )
+   for (f=fname; *f && (p-buf) < (int)sizeof(buf); )
       *p++ = *f++;
    if (type == FT_LNK) {
       *p++ = ' ';
@@ -323,7 +323,7 @@ static void print_ls_output(JCR *jcr, char *fname, char *lname, int type, struct
       *p++ = '>';
       *p++ = ' ';
       /* Copy link name */
-      for (f=lname; *f; )
+      for (f=lname; *f && (p-buf) < (int)sizeof(buf); )
         *p++ = *f++;
    }
    *p++ = '\n';
index 9e07c6a5185b0888ca5621a2e05e80f0e807ff24..c25697fc3086caaf913314b5c099bcb6edd6aaf4 100644 (file)
 
 extern int debug_level;
 
+/*
+ * Scan to "logical" end of line. I.e. end of line,
+ * or semicolon.
+ */
+void scan_to_eol(LEX *lc)
+{
+   int token;
+   Dmsg0(150, "start scan to eof\n");
+   while ((token = lex_get_token(lc)) != T_EOL) {
+   }
+   Dmsg0(150, "done scan to eof\n");
+}
+
+   
+/*
+ * Format a scanner error message 
+ */
+void s_err(char *file, int line, LEX *lc, char *msg, ...)
+{
+   va_list arg_ptr;
+   char buf[MAXSTRING];
+
+   va_start(arg_ptr, msg);
+   bvsnprintf(buf, sizeof(buf), msg, arg_ptr);
+   va_end(arg_ptr);
+     
+   e_msg(file, line, M_ERROR_TERM, 0, "Config error: %s,\n\
+            : Line %d, col %d of file %s\n%s\n",
+      buf, lc->line_no, lc->col_no, lc->fname, lc->line);
+}
+
+
 /*
  * Free the current file, and retrieve the contents
  * of the previous packet if any.
index 42953586c7a50da07a8208104cefece9685c9603..83be2975e9a17f4985f69dd00e7645e03859e63b 100755 (executable)
@@ -196,7 +196,7 @@ void init_console_msg(char *wd)
    sprintf(con_fname, "%s/%s.conmsg", wd, my_name);
    fd = open(con_fname, O_CREAT|O_RDWR|O_BINARY, 0600);
    if (fd == -1) {
-       Emsg2(M_TERM, 0, "Could not open console message file %s: ERR=%s\n",
+       Emsg2(M_ERROR_TERM, 0, "Could not open console message file %s: ERR=%s\n",
          con_fname, strerror(errno));
    }
    if (lseek(fd, 0, SEEK_END) > 0) {
@@ -645,7 +645,7 @@ void dispatch_message(void *vjcr, int type, int level, char *msg)
 
     Dmsg2(200, "Enter dispatch_msg type=%d msg=%s\n", type, msg);
 
-    if (type == M_ABORT || type == M_TERM) {
+    if (type == M_ABORT || type == M_ERROR_TERM) {
        fprintf(stdout, msg);         /* print this here to INSURE that it is printed */
     }
 
@@ -755,7 +755,7 @@ void dispatch_message(void *vjcr, int type, int level, char *msg)
                break;
             case MD_STDOUT:
                 Dmsg1(200, "STDOUT for following err: %s\n", msg);
-               if (type != M_ABORT && type != M_TERM)  /* already printed */
+               if (type != M_ABORT && type != M_ERROR_TERM)  /* already printed */
                   fprintf(stdout, msg);
                break;
             case MD_STDERR:
@@ -829,9 +829,9 @@ e_msg(char *file, int line, int type, int level, char *fmt,...)
 
     /* 
      * Check if we have a message destination defined. 
-     * We always report M_ABORT and M_TERM 
+     * We always report M_ABORT and M_ERROR_TERM 
      */
-    if (!daemon_msgs || ((type != M_ABORT && type != M_TERM) && 
+    if (!daemon_msgs || ((type != M_ABORT && type != M_ERROR_TERM) && 
                         !bit_is_set(type, daemon_msgs->send_msg)))
        return;                       /* no destination */
     switch (type) {
@@ -839,8 +839,8 @@ e_msg(char *file, int line, int type, int level, char *fmt,...)
           sprintf(buf, "%s ABORTING due to ERROR in %s:%d\n", 
                  my_name, file, line);
          break;
-       case M_TERM:
-          sprintf(buf, "%s TERMINATING due to ERROR in %s:%d\n", 
+       case M_ERROR_TERM:
+          sprintf(buf, "%s ERROR TERMINATING at %s:%d\n", 
                  my_name, file, line);
          break;
        case M_FATAL:
@@ -874,7 +874,7 @@ e_msg(char *file, int line, int type, int level, char *fmt,...)
        char *p = 0;
        p[0] = 0;                     /* generate segmentation violation */
     }
-    if (type == M_TERM) {
+    if (type == M_ERROR_TERM) {
        _exit(1);
     }
 }
@@ -915,9 +915,9 @@ Jmsg(void *vjcr, int type, int level, char *fmt,...)
     buf = rbuf;                   /* we are the Director */
     /* 
      * Check if we have a message destination defined. 
-     * We always report M_ABORT and M_TERM 
+     * We always report M_ABORT and M_ERROR_TERM 
      */
-    if ((type != M_ABORT && type != M_TERM) && msgs && !bit_is_set(type, msgs->send_msg)) {
+    if ((type != M_ABORT && type != M_ERROR_TERM) && msgs && !bit_is_set(type, msgs->send_msg)) {
        Dmsg1(200, "No bit set for type %d\n", type);
        return;                       /* no destination */
     }
@@ -925,8 +925,8 @@ Jmsg(void *vjcr, int type, int level, char *fmt,...)
        case M_ABORT:
           sprintf(buf, "%s ABORTING due to ERROR\n", my_name);
          break;
-       case M_TERM:
-          sprintf(buf, "%s TERMINATING due to ERROR\n", my_name);
+       case M_ERROR_TERM:
+          sprintf(buf, "%s ERROR TERMINATING\n", my_name);
          break;
        case M_FATAL:
           sprintf(buf, "%s: Job %s Fatal error: ", my_name, job);
@@ -962,7 +962,7 @@ Jmsg(void *vjcr, int type, int level, char *fmt,...)
        char *p = 0;
        p[0] = 0;                     /* generate segmentation violation */
     }
-    if (type == M_TERM) {
+    if (type == M_ERROR_TERM) {
        _exit(1);
     }
 }
index 432c21b592602b065ec2994040cd2ade97465143..4f8200e0b34b0a2932341a13da6c4e0ddec078d8 100644 (file)
 
 #include "bits.h"
 
-#undef M_DEBUG
-#undef M_ABORT
-#undef M_FATAL
-#undef M_ERROR
-#undef M_WARNING
-#undef M_INFO
-#undef M_MOUNT
-#undef M_TERM
+#undef  M_DEBUG
+#undef  M_ABORT
+#undef  M_FATAL
+#undef  M_ERROR
+#undef  M_WARNING
+#undef  M_INFO
+#undef  M_MOUNT
+#undef  M_ERROR_TERM
+#undef  M_TERM
 
-#define M_DEBUG     1                /* debug message */
-#define M_ABORT     2                /* MUST abort immediately */
-#define M_FATAL     3                /* Fatal error, stopping job */
-#define M_ERROR     4                /* Error, but recoverable */
-#define M_WARNING   5                /* Warning message */
-#define M_INFO     6                 /* Informational message */
-#define M_SAVED     7                /* Info on saved file */
-#define M_NOTSAVED  8                /* Info on notsaved file */
-#define M_SKIPPED   9                /* File skipped by option setting */
-#define M_MOUNT    10                /* Mount requests */
-#define M_TERM    11                 /* Termination request */
+/*
+ * Most of these message levels are more or less obvious. 
+ * They have evolved somewhat during the development of Bacula,
+ * and here are some of the details of where I am trying to
+ * head (in the process of changing the code) as of 15 June 2002.
+ *
+ *  M_ABORT       Bacula immediately aborts and tries to produce a traceback
+ *                  This is for really serious errors like segmentation fault.
+ *  M_ERROR_TERM  Bacula immediately terminates but no dump. This is for
+ *                  "obvious" serious errors like daemon already running or
+ *                   cannot open critical file, ... where a dump is not wanted.
+ *  M_TERM        Bacula daemon shutting down because of request (SIGTERM).
+ *
+ * The remaining apply to Jobs rather than the daemon.
+ *
+ *  M_FATAL       Bacula detected a fatal Job error. The Job will be killed,
+ *                  but Bacula continues running.
+ *  M_ERROR       Bacula detected a Job error. The Job will continue running
+ *                  but the termination status will be error. 
+ *  M_WARNING     Job warning message.
+ *  M_INFO        Job information message.
+ *
+ */
+
+#define M_DEBUG       1               /* debug message */
+#define M_ABORT       2               /* MUST abort immediately */
+#define M_FATAL       3               /* Fatal error, stopping job */
+#define M_ERROR       4               /* Error, but recoverable */
+#define M_WARNING     5               /* Warning message */
+#define M_INFO        6               /* Informational message */
+#define M_SAVED       7               /* Info on saved file */
+#define M_NOTSAVED    8               /* Info on notsaved file */
+#define M_SKIPPED     9               /* File skipped by option setting */
+#define M_MOUNT      10               /* Mount requests */
+#define M_ERROR_TERM 11               /* Error termination request (no dump) */
+#define M_TERM       12               /* Terminating daemon */
 
-#define M_MAX     M_TERM             /* keep this updated ! */
+#define M_MAX      M_TERM             /* keep this updated ! */
 
 /* Define message destination structure */
 /* *** FIXME **** where should be extended to handle multiple values */
 typedef struct s_dest {
    struct s_dest *next;
-   int dest_code;                    /* destination (one of the MD_ codes) */
-   int max_len;                      /* max mail line length */
-   FILE *fd;                         /* file descriptor */
+   int dest_code;                     /* destination (one of the MD_ codes) */
+   int max_len;                       /* max mail line length */
+   FILE *fd;                          /* file descriptor */
    char msg_types[nbytes_for_bits(M_MAX+1)]; /* message type mask */
-   char *where;                      /* filename/program name */
-   char *mail_cmd;                   /* mail command */
-   POOLMEM *mail_filename;           /* unique mail filename */
+   char *where;                       /* filename/program name */
+   char *mail_cmd;                    /* mail command */
+   POOLMEM *mail_filename;            /* unique mail filename */
 } DEST;
 
 /* Message Destination values for dest field of DEST */
-#define MD_SYSLOG    1               /* send msg to syslog */
-#define MD_MAIL      2               /* email group of messages */
-#define MD_FILE      3               /* write messages to a file */
-#define MD_APPEND    4               /* append messages to a file */
-#define MD_STDOUT    5               /* print messages */
-#define MD_STDERR    6               /* print messages to stderr */
-#define MD_DIRECTOR  7               /* send message to the Director */
-#define MD_OPERATOR  8               /* email a single message to the operator */
-#define MD_CONSOLE   9               /* send msg to UserAgent or console */
-#define MD_MAIL_ON_ERROR 10          /* email messages if job errors */
+#define MD_SYSLOG    1                /* send msg to syslog */
+#define MD_MAIL      2                /* email group of messages */
+#define MD_FILE      3                /* write messages to a file */
+#define MD_APPEND    4                /* append messages to a file */
+#define MD_STDOUT    5                /* print messages */
+#define MD_STDERR    6                /* print messages to stderr */
+#define MD_DIRECTOR  7                /* send message to the Director */
+#define MD_OPERATOR  8                /* email a single message to the operator */
+#define MD_CONSOLE   9                /* send msg to UserAgent or console */
+#define MD_MAIL_ON_ERROR 10           /* email messages if job errors */
 
 
 void d_msg(char *file, int line, int level, char *fmt,...);
index 77590b139bbc329badb5e2b06c83b8357ca20e80..61f7d7eadca27802426ffd1fd52c978d18b7ca83 100755 (executable)
@@ -174,7 +174,7 @@ void init_resource(int type, struct res_items *items)
       }
       /* If this triggers, take a look at lib/parse_conf.h */
       if (i >= MAX_RES_ITEMS) {
-         Emsg1(M_ABORT, 0, _("Too many items in %s resource\n"), resources[rindex]);
+         Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), resources[rindex]);
       }
    }
 }
@@ -634,12 +634,11 @@ void store_yesno(LEX *lc, struct res_items *item, int index, int pass)
    int token;
 
    token = lex_get_token(lc);
-   lcase(lc->str);
    if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
       scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
-   } else if (strcmp(lc->str, "yes") == 0) {
+   } else if (strcasecmp(lc->str, "yes") == 0) {
       *(int *)(item->value) |= item->code;
-   } else if (strcmp(lc->str, "no") == 0) {
+   } else if (strcasecmp(lc->str, "no") == 0) {
       *(int *)(item->value) &= ~(item->code);
    } else {
       scan_err1(lc, "Expect a YES or NO, got: %s", lc->str);
@@ -649,36 +648,6 @@ void store_yesno(LEX *lc, struct res_items *item, int index, int pass)
 }
 
 
-/*
- * Scan to "logical" end of line. I.e. end of line,
- * or semicolon.
- */
-void scan_to_eol(LEX *lc)
-{
-   int token;
-   Dmsg0(150, "start scan to eof\n");
-   while ((token = lex_get_token(lc)) != T_EOL) {
-   }
-   Dmsg0(150, "done scan to eof\n");
-}
-
-   
-/*
- * Format a scanner error message 
- */
-void s_err(char *file, int line, LEX *lc, char *msg, ...)
-{
-   va_list arg_ptr;
-   char buf[MAXSTRING];
-
-   va_start(arg_ptr, msg);
-   bvsnprintf(buf, sizeof(buf), msg, arg_ptr);
-   va_end(arg_ptr);
-     
-   e_msg(file, line, M_ABORT, 0, "Config error: %s,\n\
-            : Line %d, col %d of file %s\n%s\n",
-      buf, lc->line_no, lc->col_no, lc->fname, lc->line);
-}
 
 void LockRes()
 {
@@ -775,9 +744,8 @@ parse_config(char *cf)
               if (token != T_IDENTIFIER) {
                   scan_err1(lc, "Expected a Resource name identifier, got: %s", lc->str);
               }
-              lcase(lc->str);
               for (i=0; resources[i].name; i++)
-                 if (strcmp(resources[i].name, lc->str) == 0) {
+                 if (strcasecmp(resources[i].name, lc->str) == 0) {
                     state = p_resource;
                     items = resources[i].items;
                     res_type = resources[i].rcode;
@@ -797,9 +765,8 @@ parse_config(char *cf)
                     if (level != 1) {
                         scan_err1(lc, "not in resource definition: %s", lc->str);
                     }
-                    lcase(lc->str);
                     for (i=0; items[i].name; i++) {
-                       if (strcmp(items[i].name, lc->str) == 0) {
+                       if (strcasecmp(items[i].name, lc->str) == 0) {
                           token = lex_get_token(lc);
                            Dmsg1 (150, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
                           if (token != T_EQUALS) {
index deefdb0401efdec4851016fd3e7eee074f313656..0b9fe5bc792cf2d232474782e611483619403c1a 100644 (file)
@@ -68,7 +68,7 @@ static void signal_handler(int sig)
    }
    already_dead = sig;
    if (sig == SIGTERM) {
-      Emsg1(M_INFO, -1, "Shutting down Bacula service: %s ...\n", my_name);
+      Emsg1(M_TERM, -1, "Shutting down Bacula service: %s ...\n", my_name);
    } else {
       Emsg2(M_FATAL, -1, "Interrupted by signal %d: %s\n", sig, sig_names[sig]);
    }
index 8e479dd01b44f64550bb32707d753fd137bf39f7..21dad53ec70bc35b8921c6ed2fe0623eb9357ca7 100644 (file)
@@ -20,10 +20,12 @@ dummy:
 #
 SVRSRCS = stored.c append.c askdir.c authenticate.c block.c dev.c \
          device.c dircmd.c fd_cmds.c fdmsg.c job.c \
-         label.c read.c record.c stored_conf.c 
+         label.c match_bsr.c parse_bsr.c \
+         read.c record.c stored_conf.c 
 SVROBJS = stored.o append.o askdir.o authenticate.o block.o dev.o \
          device.o dircmd.o fd_cmds.o fdmsg.o job.o \
-         label.o read.o record.o stored_conf.o 
+         label.o match_bsr.o parse_bsr.o \
+         read.o record.o stored_conf.o 
 
 # bpool is depricated
 #POOLSRCS = bpool.c block.c dev.c device.c askdir.c label.c \
@@ -39,7 +41,8 @@ TAPEOBJS = btape.o block.o dev.o device.o askdir.o label.o \
 
 BLSOBJS = bls.o block.o device.o dev.o askdir.o label.o record.o
 
-BEXTOBJS = bextract.o block.o device.o dev.o askdir.o label.o record.o
+BEXTOBJS = bextract.o block.o device.o dev.o askdir.o label.o record.o \
+          match_bsr.o parse_bsr.o
 
 SCNOBJS = bscan.o block.o device.o dev.o askdir.o label.o record.o
 
index 66834f6f12f5f76566452fe269cee233dc928870..d0e77f947ac51ed03bdf085aecd4190bcb1db4f4 100644 (file)
@@ -31,8 +31,9 @@
 #include "stored.h"
 #include "findlib/find.h"
 
+
 static void do_extract(char *fname, char *prefix);
-static void print_ls_output(char *fname, struct stat *statp);
+static void print_ls_output(char *fname, char *link, int type, struct stat *statp);
 
 
 static DEVICE *dev = NULL;
@@ -42,10 +43,14 @@ static JCR *jcr;
 static FF_PKT my_ff;
 static FF_PKT *ff = &my_ff;
 
+static BSR *bsr = NULL;
+static SESSION_LABEL sesrec;
+
 static void usage()
 {
    fprintf(stderr,
 "Usage: bextract [-d debug_level] <bacula-archive> <directory-to-store-files>\n"
+"       -b <file>       specify a bootstrap file\n"
 "       -dnn            set debug level to nn\n"
 "       -e <file>       exclude list\n"
 "       -i <file>       include list\n"
@@ -71,8 +76,13 @@ int main (int argc, char *argv[])
    memset(ff, 0, sizeof(FF_PKT));
    init_include_exclude_files(ff);
 
-   while ((ch = getopt(argc, argv, "d:e:i:?")) != -1) {
+   while ((ch = getopt(argc, argv, "b:d:e:i:?")) != -1) {
       switch (ch) {
+         case 'b':                    /* bootstrap file */
+           bsr = parse_bsr(optarg);
+           dump_bsr(bsr);
+           break;
+
          case 'd':                    /* debug level */
            debug_level = atoi(optarg);
            if (debug_level <= 0)
@@ -133,6 +143,9 @@ int main (int argc, char *argv[])
    do_extract(argv[0], argv[1]);
 
    free_jcr(jcr);
+   if (bsr) {
+      free_bsr(bsr);
+   }
    return 0;
 }
   
@@ -201,6 +214,7 @@ static void do_extract(char *devname, char *where)
    POOLMEM *compress_buf = get_memory(compress_buf_size);
 
    for ( ;; ) {
+      int ok;
 
       if (!read_record(dev, block, &rec)) {
         uint32_t status;
@@ -246,9 +260,11 @@ static void do_extract(char *devname, char *where)
               break;
            case VOL_LABEL:
                rtype = "Volume Label";
+              unser_volume_label(dev, &rec);
               break;
            case SOS_LABEL:
                rtype = "Begin Session";
+              unser_session_label(&sesrec, &rec);
               break;
            case EOS_LABEL:
                rtype = "End Session";
@@ -333,7 +349,13 @@ static void do_extract(char *devname, char *where)
         }
 
         /* Is this the file we want? */
-        if (file_is_included(ff, fname) && !file_is_excluded(ff, fname)) {
+        if (bsr) {
+           ok = match_bsr(bsr, &rec, &dev->VolHdr, &sesrec);
+        } else {
+           ok = TRUE;
+        }
+           
+        if (ok && file_is_included(ff, fname) && !file_is_excluded(ff, fname)) {
 
            decode_stat(ap, &statp);
            /*
@@ -361,7 +383,7 @@ static void do_extract(char *devname, char *where)
            extract = create_file(jcr, fname, ofile, lname, type, &statp, &ofd);
 
            if (extract) {
-               print_ls_output(ofile, &statp);   
+               print_ls_output(ofile, lname, type, &statp);   
            }
         }
 
@@ -437,9 +459,10 @@ static void do_extract(char *devname, char *where)
 extern char *getuser(uid_t uid);
 extern char *getgroup(gid_t gid);
 
-static void print_ls_output(char *fname, struct stat *statp)
+static void print_ls_output(char *fname, char *link, int type, struct stat *statp)
 {
    char buf[1000]; 
+   char ec1[30];
    char *p, *f;
    int n;
 
@@ -448,13 +471,23 @@ static void print_ls_output(char *fname, struct stat *statp)
    p += n;
    n = sprintf(p, "%-8.8s %-8.8s", getuser(statp->st_uid), getgroup(statp->st_gid));
    p += n;
-   n = sprintf(p, "%8lld  ", (uint64_t)statp->st_size);
+   n = sprintf(p, "%8.8s ", edit_uint64(statp->st_size, ec1));
    p += n;
    p = encode_time(statp->st_ctime, p);
    *p++ = ' ';
    *p++ = ' ';
-   for (f=fname; *f; )
+   /* Copy file name */
+   for (f=fname; *f && (p-buf) < (int)sizeof(buf); )
       *p++ = *f++;
+   if (type == FT_LNK) {
+      *p++ = ' ';
+      *p++ = '-';
+      *p++ = '>';
+      *p++ = ' ';
+      /* Copy link name */
+      for (f=link; *f && (p-buf) < (int)sizeof(buf); )
+        *p++ = *f++;
+   }
    *p++ = '\n';
    *p = 0;
    fputs(buf, stdout);
index c0a218a2442be3b9553a6d3e3a4d9d91d032811a..7615f392081eca84c8d1edb34b8a6613b4c86d1a 100644 (file)
@@ -299,7 +299,7 @@ int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block)
    block->BlockNumber = dev->block_num;
    ser_block_header(block);
 
-   /* dump_block(block, "after ser_hdr"); */
+   /* Limit maximum Volume size to value specified by user */
    if ((dev->max_volume_size > 0) &&
        ((int64_t) (dev->VolCatInfo.VolCatBytes + block->binbuf)) >= dev->max_volume_size) {
       dev->state |= ST_WEOT;
@@ -341,6 +341,14 @@ int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block)
    }
    dev->VolCatInfo.VolCatBytes += block->binbuf;
    dev->VolCatInfo.VolCatBlocks++;   
+   dev->file_bytes += block->binbuf;
+
+   /* Limit maximum File size on volume to user specified value */
+   if ((dev->max_file_size > 0) &&
+       dev->file_bytes >= dev->max_file_size) {
+      weof_dev, 1);                  /* write end of file */
+   }
+
    Dmsg2(190, "write_block: wrote block %d bytes=%d\n", dev->block_num,
       wlen);
    empty_block(block);
index 48ba9109341b9dcd0185a9fd1ecf2328dc290b2b..69aca0f40cc31f76c3c76a7e581e04456dc2b742 100644 (file)
@@ -496,6 +496,7 @@ extern char *getgroup(gid_t gid);
 static void print_ls_output(char *fname, char *link, int type, struct stat *statp)
 {
    char buf[1000]; 
+   char ec1[30];
    char *p, *f;
    int n;
 
@@ -507,24 +508,21 @@ static void print_ls_output(char *fname, char *link, int type, struct stat *stat
    p += n;
    n = sprintf(p, "%-8.8s %-8.8s", getuser(statp->st_uid), getgroup(statp->st_gid));
    p += n;
-   n = sprintf(p, "%8" lld " ", (uint64_t)statp->st_size);
+   n = sprintf(p, "%8.8s ", edit_uint64(statp->st_size, ec1));
    p += n;
    p = encode_time(statp->st_ctime, p);
    *p++ = ' ';
    *p++ = ' ';
    /* Copy file name */
-   for (f=fname; *f; )
+   for (f=fname; *f && (p-buf) < (int)sizeof(buf); )
       *p++ = *f++;
-   if (type == FT_DIR) {
-      *p++ = '/';
-   }
    if (type == FT_LNK) {
       *p++ = ' ';
       *p++ = '-';
       *p++ = '>';
       *p++ = ' ';
       /* Copy link name */
-      for (f=link; *f; )
+      for (f=link; *f && (p-buf) < (int)sizeof(buf); )
         *p++ = *f++;
    }
    *p++ = '\n';
diff --git a/bacula/src/stored/bsr.h b/bacula/src/stored/bsr.h
new file mode 100644 (file)
index 0000000..c6728e1
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * BootStrap record definition -- for restoring files.
+ *
+ *    Kern Sibbald, June 2002
+ *
+ *   Version $Id$
+ *
+ */
+/*
+   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+
+#ifndef __BSR_H
+#define __BSR_H 1
+
+#include "findlib/find.h"
+
+/*
+ * !!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * !!!                                               !!!
+ * !!!   All records must have a pointer to          !!!
+ * !!!   the next item as the first item defined.    !!!
+ * !!!                                               !!!
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+typedef struct s_bsr_client {
+   struct s_bsr_client *next;
+   char *ClientName;
+} BSR_CLIENT;
+
+typedef struct s_bsr_sessid {
+   struct s_bsr_sessid *next;
+   int type;
+   uint32_t sessid1;
+   uint32_t sessid2;
+   int found;
+} BSR_SESSID;
+
+typedef struct s_bsr_sesstime {
+   struct s_bsr_sesstime *next;
+   uint32_t sesstime;
+   int found;
+} BSR_SESSTIME;
+
+typedef struct s_bsr_findex {
+   struct s_bsr_findex *next;
+   int32_t FileIndex;
+   int found;
+} BSR_FINDEX;
+
+typedef struct s_bsr_jobid {
+   struct s_bsr_jobid *next;
+   uint32_t JobId;
+   int found;
+} BSR_JOBID;
+
+typedef struct s_bsr_jobtype {
+   struct s_bsr_jobtype *next;
+   uint32_t JobType;
+} BSR_JOBTYPE;
+
+typedef struct s_bsr_joblevel {
+   struct s_bsr_joblevel *next;
+   uint32_t JobLevel;
+} BSR_JOBLEVEL;
+
+typedef struct s_bsr_job {
+   struct s_bsr_job *next;
+   char *Job;
+   int found;
+} BSR_JOB;
+
+
+typedef struct s_bsr {
+   struct s_bsr *next;                /* pointer to next one */
+   int           done;                /* set when everything found */
+   char         *VolumeName;
+   BSR_CLIENT   *client;
+   BSR_JOB      *job;
+   BSR_SESSID   *sessid;
+   BSR_SESSTIME *sesstime;
+   BSR_FINDEX   *FileIndex;
+   BSR_JOBID    *JobId;
+   BSR_JOBTYPE  *JobType;
+   BSR_JOBLEVEL *JobLevel;
+   FF_PKT *ff;                        /* include/exclude */
+} BSR;
+
+
+#endif
index d4e4380ad7e9c81e0101b1d6f8615071c9906ec7..0d451a79620d003c6dd2fd0e72dcc913dc48c4b1 100644 (file)
@@ -269,6 +269,7 @@ int rewind_dev(DEVICE *dev)
    }
    dev->state &= ~(ST_APPEND|ST_READ|ST_EOT | ST_EOF | ST_WEOT);  /* remove EOF/EOT flags */
    dev->block_num = dev->file = 0;
+   dev->file_bytes = 0;
    if (dev->state & ST_TAPE) {
       mt_com.mt_op = MTREW;
       mt_com.mt_count = 1;
@@ -323,6 +324,7 @@ eod_dev(DEVICE *dev)
    }
    dev->state &= ~(ST_EOF);  /* remove EOF flags */
    dev->block_num = dev->file = 0;
+   dev->file_bytes = 0;
    if (!(dev->state & ST_TAPE)) {
       pos = lseek(dev->fd, 0, SEEK_END);
       if (pos > 0) {
@@ -395,6 +397,7 @@ int update_pos_dev(DEVICE *dev)
    /* Find out where we are */
    if (!(dev->state & ST_TAPE)) {
       dev->file = 0;
+      dev->file_bytes - 0;
       pos = lseek(dev->fd, 0, SEEK_CUR);
       if (pos < 0) {
          Dmsg1(200, "Seek error: ERR=%s\n", strerror(dev->dev_errno));
@@ -535,6 +538,7 @@ int load_dev(DEVICE *dev)
 #else
 
    dev->block_num = dev->file = 0;
+   dev->file_bytes = 0;
    mt_com.mt_op = MTLOAD;
    mt_com.mt_count = 1;
    if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
@@ -566,6 +570,7 @@ int offline_dev(DEVICE *dev)
    }
 
    dev->block_num = dev->file = 0;
+   dev->file_bytes = 0;
    mt_com.mt_op = MTOFFL;
    mt_com.mt_count = 1;
    if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
@@ -640,6 +645,7 @@ fsf_dev(DEVICE *dev, int num)
            } else {
               dev->state |= ST_EOF;
               dev->file++;
+              dev->file_bytes = 0;
               continue;
            }
         } else {                        /* Got data */
@@ -659,6 +665,7 @@ fsf_dev(DEVICE *dev, int num)
         } else {
            dev->state |= ST_EOF;     /* just read EOF */
            dev->file++;
+           dev->file_bytes = 0;
         }   
       }
    
@@ -710,6 +717,7 @@ bsf_dev(DEVICE *dev, int num)
    Dmsg0(29, "bsf_dev\n");
    dev->state &= ~(ST_EOT|ST_EOF);
    dev->file -= num;
+   dev->file_bytes = 0;
    mt_com.mt_op = MTBSF;
    mt_com.mt_count = num;
    stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
@@ -755,6 +763,7 @@ fsr_dev(DEVICE *dev, int num)
       } else {
         dev->state |= ST_EOF;           /* assume EOF */
         dev->file++;
+        dev->file_bytes = 0;
       }
       clrerror_dev(dev, MTFSR);
       Mmsg2(&dev->errmsg, _("ioctl MTFSR error on %s. ERR=%s.\n"),
@@ -827,6 +836,7 @@ weof_dev(DEVICE *dev, int num)
    stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
    if (stat == 0) {
       dev->file++;
+      dev->file_bytes = 0;
    } else {
       clrerror_dev(dev, MTWEOF);
       Mmsg2(&dev->errmsg, _("ioctl MTWEOF error on %s. ERR=%s.\n"),
@@ -934,6 +944,7 @@ static void do_close(DEVICE *dev)
    dev->state &= ~(ST_OPENED|ST_LABEL|ST_READ|ST_APPEND|ST_EOT|ST_WEOT|ST_EOF);
    dev->block_num = 0;
    dev->file = 0;
+   dev->file_bytes = 0;
    dev->LastBlockNumWritten = 0;
    memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo));
    memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
index cb9845b5fac12eb1788fcb6dd84b745aad66311a..f01b928f52fcedd341655e5a7b874df1505fab54 100644 (file)
 #define READ_ONLY  1
 
 /* Generic status bits returned from status_dev() */
-#define MT_TAPE      (1<<0)               /* is tape device */
-#define MT_EOF      (1<<1)                /* just read EOF */
-#define MT_BOT      (1<<2)                /* at beginning of tape */
-#define MT_EOT      (1<<3)                /* end of tape reached */
-#define MT_SM       (1<<4)                /* DDS setmark */
-#define MT_EOD      (1<<5)                /* DDS at end of data */
-#define MT_WR_PROT   (1<<6)               /* tape write protected */
-#define MT_ONLINE    (1<<7)               /* tape online */
-#define MT_DR_OPEN   (1<<8)               /* tape door open */
-#define MT_IM_REP_EN (1<<9)               /* immediate report enabled */
+#define MT_TAPE      (1<<0)                /* is tape device */
+#define MT_EOF       (1<<1)                /* just read EOF */
+#define MT_BOT       (1<<2)                /* at beginning of tape */
+#define MT_EOT       (1<<3)                /* end of tape reached */
+#define MT_SM        (1<<4)                /* DDS setmark */
+#define MT_EOD       (1<<5)                /* DDS at end of data */
+#define MT_WR_PROT   (1<<6)                /* tape write protected */
+#define MT_ONLINE    (1<<7)                /* tape online */
+#define MT_DR_OPEN   (1<<8)                /* tape door open */
+#define MT_IM_REP_EN (1<<9)                /* immediate report enabled */
 
 
 /* Bits for device capabilities */
-#define CAP_EOF        0x001         /* has MTWEOF */
-#define CAP_BSR        0x002         /* has MTBSR */
-#define CAP_BSF        0x004         /* has MTBSF */
-#define CAP_FSR        0x008         /* has MTFSR */
-#define CAP_FSF        0x010         /* has MTFSF */
-#define CAP_EOM        0x020         /* has MTEOM */
-#define CAP_REM        0x040         /* is removable media */
-#define CAP_RACCESS    0x080         /* is random access device */
-#define CAP_AUTOMOUNT  0x100         /* Read device at start to see what is there */
-#define CAP_LABEL      0x200         /* Label blank tapes */
-#define CAP_ANONVOLS   0x400         /* Mount without knowing volume name */
-#define CAP_ALWAYSOPEN 0x800         /* always keep device open */
+#define CAP_EOF        0x001          /* has MTWEOF */
+#define CAP_BSR        0x002          /* has MTBSR */
+#define CAP_BSF        0x004          /* has MTBSF */
+#define CAP_FSR        0x008          /* has MTFSR */
+#define CAP_FSF        0x010          /* has MTFSF */
+#define CAP_EOM        0x020          /* has MTEOM */
+#define CAP_REM        0x040          /* is removable media */
+#define CAP_RACCESS    0x080          /* is random access device */
+#define CAP_AUTOMOUNT  0x100          /* Read device at start to see what is there */
+#define CAP_LABEL      0x200          /* Label blank tapes */
+#define CAP_ANONVOLS   0x400          /* Mount without knowing volume name */
+#define CAP_ALWAYSOPEN 0x800          /* always keep device open */
 
 
 /* Tape state bits */
-#define ST_OPENED    0x001           /* set when device opened */
-#define ST_TAPE      0x002           /* is a tape device */  
-#define ST_LABEL     0x004           /* label found */
+#define ST_OPENED    0x001            /* set when device opened */
+#define ST_TAPE      0x002            /* is a tape device */  
+#define ST_LABEL     0x004            /* label found */
 #define ST_MALLOC    0x008            /* dev packet malloc'ed in init_dev() */
-#define ST_APPEND    0x010           /* ready for Bacula append */
-#define ST_READ      0x020           /* ready for Bacula read */
-#define ST_EOT      0x040            /* at end of tape */
-#define ST_WEOT      0x080           /* Got EOT on write */
-#define ST_EOF      0x100            /* Read EOF i.e. zero bytes */
-#define ST_NEXTVOL   0x200           /* Start writing on next volume */
-#define ST_SHORT     0x400           /* Short block read */
+#define ST_APPEND    0x010            /* ready for Bacula append */
+#define ST_READ      0x020            /* ready for Bacula read */
+#define ST_EOT       0x040            /* at end of tape */
+#define ST_WEOT      0x080            /* Got EOT on write */
+#define ST_EOF       0x100            /* Read EOF i.e. zero bytes */
+#define ST_NEXTVOL   0x200            /* Start writing on next volume */
+#define ST_SHORT     0x400            /* Short block read */
 
 /* dev_blocked states (mutually exclusive) */
 #define BST_NOT_BLOCKED       0       /* not blocked */
-#define BST_UNMOUNTED        1       /* User unmounted device */
+#define BST_UNMOUNTED         1       /* User unmounted device */
 #define BST_WAITING_FOR_SYSOP 2       /* Waiting for operator to mount tape */
 #define BST_DOING_ACQUIRE     3       /* Opening/validating/moving tape */
 #define BST_WRITING_LABEL     4       /* Labeling a tape */  
 /* Volume Catalog Information structure definition */
 typedef struct s_volume_catalog_info {
    /* Media info for the current Volume */
-   uint32_t VolCatJobs;              /* number of jobs on this Volume */
-   uint32_t VolCatFiles;             /* Number of files */
-   uint32_t VolCatBlocks;            /* Number of blocks */
-   uint64_t VolCatBytes;             /* Number of bytes written */
-   uint32_t VolCatMounts;            /* Number of mounts this volume */
-   uint32_t VolCatErrors;            /* Number of errors this volume */
-   uint32_t VolCatWrites;            /* Number of writes this volume */
-   uint32_t VolCatReads;             /* Number of reads this volume */
-   uint32_t VolCatRecycles;          /* Number of recycles this volume */
-   uint64_t VolCatMaxBytes;          /* max bytes to write */
+   uint32_t VolCatJobs;               /* number of jobs on this Volume */
+   uint32_t VolCatFiles;              /* Number of files */
+   uint32_t VolCatBlocks;             /* Number of blocks */
+   uint64_t VolCatBytes;              /* Number of bytes written */
+   uint32_t VolCatMounts;             /* Number of mounts this volume */
+   uint32_t VolCatErrors;             /* Number of errors this volume */
+   uint32_t VolCatWrites;             /* Number of writes this volume */
+   uint32_t VolCatReads;              /* Number of reads this volume */
+   uint32_t VolCatRecycles;           /* Number of recycles this volume */
+   uint64_t VolCatMaxBytes;           /* max bytes to write */
    uint64_t VolCatCapacityBytes;      /* capacity estimate */
-   char VolCatStatus[20];            /* Volume status */
+   char VolCatStatus[20];             /* Volume status */
    char VolCatName[MAX_NAME_LENGTH];  /* Desired volume to mount */
 } VOLUME_CAT_INFO;
 
 
 /* Device structure definition */
 typedef struct s_device {
-   struct s_device *next;            /* pointer to next open device */
-   pthread_mutex_t mutex;            /* access control */
-   pthread_cond_t wait;              /* thread wait variable */
+   struct s_device *next;             /* pointer to next open device */
+   pthread_mutex_t mutex;             /* access control */
+   pthread_cond_t wait;               /* thread wait variable */
    pthread_cond_t wait_next_vol;      /* wait for tape to be mounted */
-   pthread_t no_wait_id;             /* this thread must not wait */
-   int dev_blocked;                  /* set if we must wait (i.e. change tape) */
-   int num_waiting;                  /* number of threads waiting */
-   int num_writers;                  /* number of writing threads */
-   int use_count;                    /* usage count on this device */
-   int fd;                           /* file descriptor */
-   int capabilities;                 /* capabilities mask */
-   int state;                        /* state mask */
-   int dev_errno;                    /* Our own errno */
-   int mode;                         /* read/write modes */
-   char *dev_name;                   /* device name */
-   char *errmsg;                     /* nicely edited error message */
-   uint32_t block_num;               /* current block number base 0 */
-   uint32_t file;                    /* current file number base 0 */
+   pthread_t no_wait_id;              /* this thread must not wait */
+   int dev_blocked;                   /* set if we must wait (i.e. change tape) */
+   int num_waiting;                   /* number of threads waiting */
+   int num_writers;                   /* number of writing threads */
+   int use_count;                     /* usage count on this device */
+   int fd;                            /* file descriptor */
+   int capabilities;                  /* capabilities mask */
+   int state;                         /* state mask */
+   int dev_errno;                     /* Our own errno */
+   int mode;                          /* read/write modes */
+   char *dev_name;                    /* device name */
+   char *errmsg;                      /* nicely edited error message */
+   uint32_t block_num;                /* current block number base 0 */
+   uint32_t file;                     /* current file number base 0 */
+   uint32_t file_bytes;               /* bytes in this file */
    uint32_t LastBlockNumWritten;      /* last block written */
-   uint32_t min_block_size;          /* min block size */
-   uint32_t max_block_size;          /* max block size */
-   uint32_t max_volume_jobs;         /* max jobs to put on one volume */
-   int64_t max_volume_files;         /* max files to put on one volume */
-   int64_t max_volume_size;          /* max bytes to put on one volume */
-   int64_t max_file_size;            /* max file size in bytes */
-   int64_t volume_capacity;          /* advisory capacity */
-   uint32_t max_rewind_wait;         /* max secs to allow for rewind */
-   void *device;                     /* pointer to Device Resource */
-
-   VOLUME_CAT_INFO VolCatInfo;       /* Volume Catalog Information */
-   struct Volume_Label VolHdr;       /* Actual volume label */
+   uint32_t min_block_size;           /* min block size */
+   uint32_t max_block_size;           /* max block size */
+   uint32_t max_volume_jobs;          /* max jobs to put on one volume */
+   uint64_t max_volume_files;         /* max files to put on one volume */
+   uint64_t max_volume_size;          /* max bytes to put on one volume */
+   uint64_t max_file_size;            /* max file size to put in one file on volume */
+   uint64_t volume_capacity;          /* advisory capacity */
+   uint32_t max_rewind_wait;          /* max secs to allow for rewind */
+   void *device;                      /* pointer to Device Resource */
+
+   VOLUME_CAT_INFO VolCatInfo;        /* Volume Catalog Information */
+   VOLUME_LABEL VolHdr;               /* Actual volume label */
 
 } DEVICE;
 
@@ -172,7 +173,7 @@ typedef struct s_device {
  *  dependent. Arrgggg!
  */
 #ifndef MTEOM
-#ifdef MTSEOD
+#ifdef  MTSEOD
 #define MTEOM MTSEOD
 #endif
 #ifdef MTEOD
index 90f09795343f9cd20a840f94e5286452a5d71570..26038854efd6b4412b4af4783eba864a094f40e8 100644 (file)
@@ -562,6 +562,9 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
 
       strcpy(dev->VolCatInfo.VolCatStatus, "Full");
       Dmsg0(90, "Call update_vol_info\n");
+      /* Update position counters */
+      jcr->end_block = dev->block_num;
+      jcr->end_file = dev->file;
       if (!dir_update_volume_info(jcr, &dev->VolCatInfo, 0)) {   /* send Volume info to Director */
          Jmsg(jcr, M_ERROR, 0, _("Could not update Volume info Volume=%s Job=%s\n"),
            dev->VolCatInfo.VolCatName, jcr->Job);
@@ -624,6 +627,9 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
       jcr->NumVolumes++;
       Dmsg0(90, "Wake up any waiting threads.\n");
       free_block(label_blk);
+      /* Set new start/end positions */
+      jcr->start_block = dev->block_num;
+      jcr->start_file = dev->file;
       unblock_device(dev);
       jcr->run_time += time(NULL) - wait_time; /* correct run time */
       return 1;                               /* device locked */
diff --git a/bacula/src/stored/match_bsr.c b/bacula/src/stored/match_bsr.c
new file mode 100755 (executable)
index 0000000..2bdcbcb
--- /dev/null
@@ -0,0 +1,211 @@
+/*     
+ *   Match Bootstrap Records (used for restores) against
+ *     Volume Records
+ *  
+ *     Kern Sibbald, June MMII
+ *
+ *   Version $Id$
+ */
+
+/*
+   Copyright (C) 2002 Kern Sibbald and John Walker
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+
+#include "bacula.h"
+#include "stored.h"
+
+/* Forward references */
+static int match_sesstime(BSR_SESSTIME *sesstime, DEV_RECORD *rec);
+static int match_sessid(BSR_SESSID *sessid, DEV_RECORD *rec);
+static int match_client(BSR_CLIENT *client, SESSION_LABEL *sesrec);
+static int match_job(BSR_JOB *job, SESSION_LABEL *sesrec);
+static int match_job_type(BSR_JOBTYPE *job_type, SESSION_LABEL *sesrec);
+static int match_job_level(BSR_JOBLEVEL *job_level, SESSION_LABEL *sesrec);
+static int match_jobid(BSR_JOBID *jobid, SESSION_LABEL *sesrec);
+static int match_file_index(BSR_FINDEX *findex, DEV_RECORD *rec);
+static int match_one_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sesrec);
+
+/*********************************************************************
+ *
+ *     Match Bootstrap records
+ *
+ */
+int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sesrec)
+{
+   if (!bsr) {
+      return 0;
+   }
+   if (match_one_bsr(bsr, rec, volrec, sesrec)) {
+      return 1;
+   }
+   return match_bsr(bsr->next, rec, volrec, sesrec);
+}
+
+static int match_one_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sesrec)
+{
+   if (strcmp(bsr->VolumeName, volrec->VolName) != 0) {
+      return 0;
+   }
+   if (!match_client(bsr->client, sesrec)) {
+      return 0;
+   }
+   if (!match_sessid(bsr->sessid, rec)) {
+      return 0;
+   }
+   if (!match_sesstime(bsr->sesstime, rec)) {
+      return 0;
+   }
+   if (!match_job(bsr->job, sesrec)) {
+      return 0;
+   }
+   if (!match_file_index(bsr->FileIndex, rec)) {
+      return 0;
+   }
+   if (!match_job_type(bsr->JobType, sesrec)) {
+      return 0;
+   }
+   if (!match_job_level(bsr->JobLevel, sesrec)) {
+      return 0;
+   }
+   if (!match_jobid(bsr->JobId, sesrec)) {
+      return 0;
+   }
+   return 1;
+}
+
+static int match_client(BSR_CLIENT *client, SESSION_LABEL *sesrec)
+{
+   if (!client) {
+      return 1;                      /* no specification matches all */
+   }
+   if (strcmp(client->ClientName, sesrec->ClientName) == 0) {
+      return 1;
+   }
+   if (client->next) {
+      return match_client(client->next, sesrec);
+   }
+   return 0;
+}
+
+static int match_job(BSR_JOB *job, SESSION_LABEL *sesrec)
+{
+   if (!job) {
+      return 1;                      /* no specification matches all */
+   }
+   if (strcmp(job->Job, sesrec->Job) == 0) {
+      job->found++;
+      return 1;
+   }
+   if (job->next) {
+      return match_job(job->next, sesrec);
+   }
+   return 0;
+}
+
+
+static int match_job_type(BSR_JOBTYPE *job_type, SESSION_LABEL *sesrec)
+{
+   if (!job_type) {
+      return 1;                      /* no specification matches all */
+   }
+   if (job_type->JobType == sesrec->JobType) {
+      return 1;
+   }
+   if (job_type->next) {
+      return match_job_type(job_type->next, sesrec);
+   }
+   return 0;
+}
+
+static int match_job_level(BSR_JOBLEVEL *job_level, SESSION_LABEL *sesrec)
+{
+   if (!job_level) {
+      return 1;                      /* no specification matches all */
+   }
+   if (job_level->JobLevel == sesrec->JobLevel) {
+      return 1;
+   }
+   if (job_level->next) {
+      return match_job_level(job_level->next, sesrec);
+   }
+   return 0;
+}
+
+static int match_jobid(BSR_JOBID *jobid, SESSION_LABEL *sesrec)
+{
+   if (!jobid) {
+      return 1;                      /* no specification matches all */
+   }
+   if (jobid->JobId == sesrec->JobId) {
+      jobid->found++;
+      return 1;
+   }
+   if (jobid->next) {
+      return match_jobid(jobid->next, sesrec);
+   }
+   return 0;
+}
+
+
+static int match_file_index(BSR_FINDEX *findex, DEV_RECORD *rec)
+{
+   if (!findex) {
+      return 1;                      /* no specification matches all */
+   }
+   if (findex->FileIndex == rec->FileIndex) {
+      findex->found++;
+      return 1;
+   }
+   if (findex->next) {
+      return match_file_index(findex->next, rec);
+   }
+   return 0;
+}
+
+
+static int match_sessid(BSR_SESSID *sessid, DEV_RECORD *rec)
+{
+   if (!sessid) {
+      return 1;                      /* no specification matches all */
+   }
+   if (sessid->sessid1 == rec->VolSessionId) {
+      sessid->found++;
+      return 1;
+   }
+   if (sessid->next) {
+      return match_sessid(sessid->next, rec);
+   }
+   return 0;
+}
+
+static int match_sesstime(BSR_SESSTIME *sesstime, DEV_RECORD *rec)
+{
+   if (!sesstime) {
+      return 1;                      /* no specification matches all */
+   }
+   if (sesstime->sesstime == rec->VolSessionTime) {
+      sesstime->found++;
+      return 1;
+   }
+   if (sesstime->next) {
+      return match_sesstime(sesstime->next, rec);
+   }
+   return 0;
+}
diff --git a/bacula/src/stored/parse_bsr.c b/bacula/src/stored/parse_bsr.c
new file mode 100755 (executable)
index 0000000..e26ad8a
--- /dev/null
@@ -0,0 +1,430 @@
+/*     
+ *   Parse a Bootstrap Records (used for restores) 
+ *  
+ *     Kern Sibbald, June MMII
+ *
+ *   Version $Id$
+ */
+
+/*
+   Copyright (C) 2002 Kern Sibbald and John Walker
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+
+#include "bacula.h"
+#include "stored.h"
+
+typedef BSR * (ITEM_HANDLER)(LEX *lc, BSR *bsr);
+
+static BSR *store_vol(LEX *lc, BSR *bsr);
+static BSR *store_client(LEX *lc, BSR *bsr);
+static BSR *store_job(LEX *lc, BSR *bsr);
+static BSR *store_jobid(LEX *lc, BSR *bsr);
+static BSR *store_jobtype(LEX *lc, BSR *bsr);
+static BSR *store_joblevel(LEX *lc, BSR *bsr);
+static BSR *store_file_index(LEX *lc, BSR *bsr);
+static BSR *store_sessid(LEX *lc, BSR *bsr);
+static BSR *store_sesstime(LEX *lc, BSR *bsr);
+static BSR *store_include(LEX *lc, BSR *bsr);
+static BSR *store_exclude(LEX *lc, BSR *bsr);
+
+struct kw_items {
+   char *name;
+   ITEM_HANDLER *handler;
+};
+
+struct kw_items items[] = {
+   {"volume", store_vol},
+   {"client", store_client},
+   {"job", store_job},
+   {"jobid", store_jobid},
+   {"fileindex", store_file_index},
+   {"jobtype", store_jobtype},
+   {"joblevel", store_joblevel},
+   {"volsessionid", store_sessid},
+   {"volsessiontime", store_sesstime},
+   {"include", store_include},
+   {"exclude", store_exclude},
+   {NULL, NULL}
+
+};
+
+static BSR *new_bsr() 
+{
+   BSR *bsr = (BSR *)malloc(sizeof(BSR));
+   memset(bsr, 0, sizeof(BSR));
+   return bsr;
+}
+
+/*********************************************************************
+ *
+ *     Parse Bootstrap file
+ *
+ */
+BSR *parse_bsr(char *cf)
+{
+   LEX *lc = NULL;
+   int token, i;
+   BSR *root_bsr = new_bsr();
+   BSR *bsr = root_bsr;
+
+   Dmsg0(200, "Enter parse_bsf()\n");
+   lc = lex_open_file(lc, cf);
+   while ((token=lex_get_token(lc)) != T_EOF) {
+      Dmsg1(150, "parse got token=%s\n", lex_tok_to_str(token));
+      if (token == T_EOL) {
+        continue;
+      }
+      if (token != T_IDENTIFIER) {
+         scan_err1(lc, "Expected a keyword identifier, got: %s", lc->str);
+      }
+      for (i=0; items[i].name; i++) {
+        if (strcasecmp(items[i].name, lc->str) == 0) {
+           token = lex_get_token(lc);
+            Dmsg1 (150, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
+           if (token != T_EQUALS) {
+               scan_err1(lc, "expected an equals, got: %s", lc->str);
+           }
+            Dmsg1(150, "calling handler for %s\n", items[i].name);
+           /* Call item handler */
+           bsr = items[i].handler(lc, bsr);
+           i = -1;
+           break;
+        }
+      }
+      if (i >= 0) {
+         Dmsg1(150, "Keyword = %s\n", lc->str);
+         scan_err1(lc, "Keyword %s not found", lc->str);
+      }
+
+   }
+   lc = lex_close_file(lc);
+   Dmsg0(200, "Leave parse_bsf()\n");
+   return root_bsr;
+}
+
+static BSR *store_vol(LEX *lc, BSR *bsr)
+{
+   int token;
+    
+   token = lex_get_token(lc);
+   if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
+      scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
+   } else if (lc->str_len > MAX_RES_NAME_LENGTH) {
+      scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, 
+        lc->str_len, MAX_RES_NAME_LENGTH);
+   } else {
+      if (bsr->VolumeName) {
+        bsr->next = new_bsr();
+        bsr = bsr->next;
+      }
+      bsr->VolumeName = bstrdup(lc->str);
+   }
+   scan_to_eol(lc);
+   return bsr;
+}
+
+static BSR *store_client(LEX *lc, BSR *bsr)
+{
+   int token;
+   BSR_CLIENT *client;
+    
+   token = lex_get_token(lc);
+   if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
+      scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
+   } else if (lc->str_len > MAX_RES_NAME_LENGTH) {
+      scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, 
+        lc->str_len, MAX_RES_NAME_LENGTH);
+   } else {
+      client = (BSR_CLIENT *)malloc(sizeof(BSR_CLIENT));
+      memset(client, 0, sizeof(BSR_CLIENT));
+      client->ClientName = bstrdup(lc->str);
+      /* Add it to the end of the client chain */
+      if (!bsr->client) {
+        bsr->client = client;
+      } else {
+        BSR_CLIENT *bc = bsr->client;
+        for ( ;; ) {
+           if (bc->next) {
+              bc = bc->next;
+           } else {
+              bc->next = client;
+              break;
+           }
+        }
+      }
+   }
+   scan_to_eol(lc);
+   return bsr;
+}
+
+static BSR *store_job(LEX *lc, BSR *bsr)
+{
+   int token;
+   BSR_JOB *job;
+    
+   token = lex_get_token(lc);
+   if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
+      scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
+   } else if (lc->str_len > MAX_RES_NAME_LENGTH) {
+      scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, 
+        lc->str_len, MAX_RES_NAME_LENGTH);
+   } else {
+      job = (BSR_JOB *)malloc(sizeof(BSR_JOB));
+      memset(job, 0, sizeof(BSR_JOB));
+      job->Job = bstrdup(lc->str);
+      /* Add it to the end of the client chain */
+      if (!bsr->job) {
+        bsr->job = job;
+      } else {
+        /* Add to end of chain */
+        BSR_JOB *bc = bsr->job;
+        for ( ;bc->next; bc=bc->next)
+           { }
+        bc->next = job;
+      }
+   }
+   scan_to_eol(lc);
+   return bsr;
+}
+
+static BSR *store_file_index(LEX *lc, BSR *bsr)
+{
+   int token;
+   int32_t FileIndex;
+   BSR_FINDEX *findex;
+
+
+   token = lex_get_token(lc);
+   if (token != T_NUMBER || !is_a_number(lc->str)) {
+      scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
+   } else {
+      errno = 0;
+      FileIndex = strtoul(lc->str, NULL, 10);
+      if (errno != 0) {
+         scan_err1(lc, "expected a integer number, got: %s", lc->str);
+      }
+      findex = (BSR_FINDEX *)malloc(sizeof(BSR_FINDEX));
+      memset(findex, 0, sizeof(BSR_FINDEX));
+      findex->FileIndex = FileIndex;
+      /* Add it to the end of the chain */
+      if (!bsr->FileIndex) {
+        bsr->FileIndex = findex;
+      } else {
+        /* Add to end of chain */
+        BSR_FINDEX *bs = bsr->FileIndex;
+        for ( ;bs->next; bs=bs->next)
+          {  }
+        bs->next = findex;
+      }
+   }
+   scan_to_eol(lc);
+   return bsr;
+}
+
+
+static BSR *store_jobid(LEX *lc, BSR *bsr)
+{
+   int token;
+   uint32_t JobId;    
+   BSR_JOBID *jobid;
+
+
+   token = lex_get_token(lc);
+   if (token != T_NUMBER || !is_a_number(lc->str)) {
+      scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
+   } else {
+      errno = 0;
+      JobId = strtoul(lc->str, NULL, 10);
+      if (errno != 0) {
+         scan_err1(lc, "expected a integer number, got: %s", lc->str);
+      }
+      jobid = (BSR_JOBID *)malloc(sizeof(BSR_JOBID));
+      memset(jobid, 0, sizeof(BSR_JOBID));
+      jobid->JobId = JobId;
+      /* Add it to the end of the chain */
+      if (!bsr->JobId) {
+        bsr->JobId = jobid;
+      } else {
+        /* Add to end of chain */
+        BSR_JOBID *bs = bsr->JobId;
+        for ( ;bs->next; bs=bs->next)
+          {  }
+        bs->next = jobid;
+      }
+   }
+   scan_to_eol(lc);
+   return bsr;
+}
+
+static BSR *store_jobtype(LEX *lc, BSR *bsr)
+{
+   /* *****FIXME****** */
+   Dmsg0(-1, "JobType not yet implemented\n");
+   return bsr;
+}
+
+
+static BSR *store_joblevel(LEX *lc, BSR *bsr)
+{
+   /* *****FIXME****** */
+   Dmsg0(-1, "JobLevel not yet implemented\n");
+   return bsr;
+}
+
+
+
+static BSR *store_sessid(LEX *lc, BSR *bsr)
+{
+   int token;
+   uint32_t sessid1;
+   BSR_SESSID *sid;
+
+
+   token = lex_get_token(lc);
+   if (token != T_NUMBER || !is_a_number(lc->str)) {
+      scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
+   } else {
+      errno = 0;
+      sessid1 = strtoul(lc->str, NULL, 10);
+      if (errno != 0) {
+         scan_err1(lc, "expected a integer number, got: %s", lc->str);
+      }
+      sid = (BSR_SESSID *)malloc(sizeof(BSR_SESSID));
+      memset(sid, 0, sizeof(BSR_SESSID));
+      sid->sessid1 = sessid1;
+      /* Add it to the end of the chain */
+      if (!bsr->sessid) {
+        bsr->sessid = sid;
+      } else {
+        /* Add to end of chain */
+        BSR_SESSID *bs = bsr->sessid;
+        for ( ;bs->next; bs=bs->next)
+          {  }
+        bs->next = sid;
+      }
+   }
+   scan_to_eol(lc);
+   return bsr;
+}
+
+static BSR *store_sesstime(LEX *lc, BSR *bsr)
+{
+   int token;
+   uint32_t sesstime;
+   BSR_SESSTIME *stime;
+
+
+   token = lex_get_token(lc);
+   if (token != T_NUMBER || !is_a_number(lc->str)) {
+      scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
+   } else {
+      errno = 0;
+      sesstime = strtoul(lc->str, NULL, 10);
+      if (errno != 0) {
+         scan_err1(lc, "expected a integer number, got: %s", lc->str);
+      }
+      stime = (BSR_SESSTIME *)malloc(sizeof(BSR_SESSTIME));
+      memset(stime, 0, sizeof(BSR_SESSTIME));
+      stime->sesstime = sesstime;
+      /* Add it to the end of the chain */
+      if (!bsr->sesstime) {
+        bsr->sesstime = stime;
+      } else {
+        /* Add to end of chain */
+        BSR_SESSTIME *bs = bsr->sesstime;
+        for ( ;bs->next; bs=bs->next)
+           { }
+        bs->next = stime;
+      }
+   }
+   scan_to_eol(lc);
+   return bsr;
+}
+
+static BSR *store_include(LEX *lc, BSR *bsr)
+{
+   scan_to_eol(lc);
+   return bsr;
+}
+
+static BSR *store_exclude(LEX *lc, BSR *bsr)
+{
+   scan_to_eol(lc);
+   return bsr;
+}
+
+void dump_bsr(BSR *bsr)
+{
+   if (!bsr) {
+      Dmsg0(-1, "BSR is NULL\n");
+      return;
+   }
+   Dmsg8(-1,   
+"Next        : 0x%x\n"
+"VolumeName  : %s\n"
+"Client      : %s\n"
+"Job         : %s\n"
+"JobId       : %u\n"
+"SessId      : %u\n"
+"SessTime    : %u\n"
+"FileIndex   : %d\n",
+                bsr->next,
+                 bsr->VolumeName ? bsr->VolumeName : "*None*",
+                 bsr->client ? bsr->client->ClientName : "*None*",
+                 bsr->job ? bsr->job->Job : "*None*",
+                bsr->JobId ? bsr->JobId->JobId : 0,
+                bsr->sessid ? bsr->sessid->sessid1 : 0,
+                bsr->sesstime ? bsr->sesstime->sesstime : 0,
+                bsr->FileIndex ? bsr->FileIndex->FileIndex : 0);
+   if (bsr->next) {
+      Dmsg0(-1, "\n");
+      dump_bsr(bsr->next);
+   }
+}
+
+
+/*********************************************************************
+ *
+ *     Free bsr resources
+ */
+
+static void free_bsr_item(BSR *bsr)
+{
+   if (!bsr) {
+      return;
+   }
+   free_bsr_item(bsr->next);
+   free(bsr);
+}
+
+void free_bsr(BSR *bsr)
+{
+   if (!bsr) {
+      return;
+   }
+   free_bsr_item((BSR *)bsr->client);
+   free_bsr_item((BSR *)bsr->sessid);
+   free_bsr_item((BSR *)bsr->sesstime);
+   if (bsr->VolumeName) {
+      free(bsr->VolumeName);
+   }
+   free_bsr(bsr->next);
+   free(bsr);
+}
index 7fffbc952c989f9aa320015521b76f65b15e2a2a..38ac7c081801bfee0e6738912efed8d8da71f030 100644 (file)
 uint32_t new_VolSessionId();
 
 /* From askdir.c */
-int    dir_get_volume_info(JCR *jcr);
-int    dir_find_next_appendable_volume(JCR *jcr);
-int    dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel);
-int    dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev);
-int    dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev);
-int    dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec);
-int    dir_send_job_status(JCR *jcr);
+int     dir_get_volume_info(JCR *jcr);
+int     dir_find_next_appendable_volume(JCR *jcr);
+int     dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel);
+int     dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev);
+int     dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev);
+int     dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec);
+int     dir_send_job_status(JCR *jcr);
 
 /* authenticate.c */
-int    authenticate_director(JCR *jcr);
-int    authenticate_filed(JCR *jcr);
+int     authenticate_director(JCR *jcr);
+int     authenticate_filed(JCR *jcr);
 
 /* From block.c */
-void   dump_block(DEV_BLOCK *b, char *msg);
+void    dump_block(DEV_BLOCK *b, char *msg);
 DEV_BLOCK *new_block(DEVICE *dev);
-void   init_block_write(DEV_BLOCK *block);
-void   empty_block(DEV_BLOCK *block);
-void   free_block(DEV_BLOCK *block);
-int    write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int    write_block_to_dev(DEVICE *dev, DEV_BLOCK *block);
-int    read_block_from_device(DEVICE *dev, DEV_BLOCK *block);
-int    read_block_from_dev(DEVICE *dev, DEV_BLOCK *block);
+void    init_block_write(DEV_BLOCK *block);
+void    empty_block(DEV_BLOCK *block);
+void    free_block(DEV_BLOCK *block);
+int     write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int     write_block_to_dev(DEVICE *dev, DEV_BLOCK *block);
+int     read_block_from_device(DEVICE *dev, DEV_BLOCK *block);
+int     read_block_from_dev(DEVICE *dev, DEV_BLOCK *block);
 
 
 /* From dev.c */
-DEVICE *init_dev(DEVICE *dev, char *device);
-int     open_dev(DEVICE *dev, char *VolName, int mode);
-void    close_dev(DEVICE *dev);
-void    force_close_dev(DEVICE *dev);
-int     truncate_dev(DEVICE *dev);
-void    term_dev(DEVICE *dev);
-char *  strerror_dev(DEVICE *dev);
-void    clrerror_dev(DEVICE *dev, int func);
-int     update_pos_dev(DEVICE *dev);
-int     rewind_dev(DEVICE *dev);
-int     load_dev(DEVICE *dev);
-int     offline_dev(DEVICE *dev);
-int     flush_dev(DEVICE *dev);
-int     weof_dev(DEVICE *dev, int num);
-int     write_block(DEVICE *dev);
-int     write_dev(DEVICE *dev, char *buf, size_t len);
-int     read_dev(DEVICE *dev, char *buf, size_t len);
-int     status_dev(DEVICE *dev, uint32_t *status);
-int     eod_dev(DEVICE *dev);
-int     fsf_dev(DEVICE *dev, int num);
-int     fsr_dev(DEVICE *dev, int num);
-int     bsf_dev(DEVICE *dev, int num);
-int     bsr_dev(DEVICE *dev, int num);
+DEVICE  *init_dev(DEVICE *dev, char *device);
+int      open_dev(DEVICE *dev, char *VolName, int mode);
+void     close_dev(DEVICE *dev);
+void     force_close_dev(DEVICE *dev);
+int      truncate_dev(DEVICE *dev);
+void     term_dev(DEVICE *dev);
+char *   strerror_dev(DEVICE *dev);
+void     clrerror_dev(DEVICE *dev, int func);
+int      update_pos_dev(DEVICE *dev);
+int      rewind_dev(DEVICE *dev);
+int      load_dev(DEVICE *dev);
+int      offline_dev(DEVICE *dev);
+int      flush_dev(DEVICE *dev);
+int      weof_dev(DEVICE *dev, int num);
+int      write_block(DEVICE *dev);
+int      write_dev(DEVICE *dev, char *buf, size_t len);
+int      read_dev(DEVICE *dev, char *buf, size_t len);
+int      status_dev(DEVICE *dev, uint32_t *status);
+int      eod_dev(DEVICE *dev);
+int      fsf_dev(DEVICE *dev, int num);
+int      fsr_dev(DEVICE *dev, int num);
+int      bsf_dev(DEVICE *dev, int num);
+int      bsr_dev(DEVICE *dev, int num);
 
 /* Get info about device */
-char *  dev_name(DEVICE *dev);
-char *  dev_vol_name(DEVICE *dev);
+char *   dev_name(DEVICE *dev);
+char *   dev_vol_name(DEVICE *dev);
 uint32_t dev_block(DEVICE *dev);
 uint32_t dev_file(DEVICE *dev);
-int     dev_is_tape(DEVICE *dev);
+int      dev_is_tape(DEVICE *dev);
 
 /* From device.c */
-int     open_device(DEVICE *dev);
-int     acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int     acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int     ready_dev_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int     release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-void    block_device(DEVICE *dev, int state);
-void    unblock_device(DEVICE *dev);
-void    lock_device(DEVICE *dev);
-void    unlock_device(DEVICE *dev);
-int     fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int      open_device(DEVICE *dev);
+int      acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int      acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int      ready_dev_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int      release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+void     block_device(DEVICE *dev, int state);
+void     unblock_device(DEVICE *dev);
+void     lock_device(DEVICE *dev);
+void     unlock_device(DEVICE *dev);
+int      fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
 
 /* From dircmd.c */
-void    connection_request(void *arg); 
+void     connection_request(void *arg); 
 
 
 /* From fd_cmds.c */
-void    run_job(JCR *jcr);
+void     run_job(JCR *jcr);
 
 /* From fdmsg.c */
-int     bget_msg(BSOCK *sock);
+int      bget_msg(BSOCK *sock);
 
 /* From job.c */
-void    stored_free_jcr(JCR *jcr);
-void    connection_from_filed(void *arg);     
-void    handle_filed_connection(BSOCK *fd, char *job_name);
+void     stored_free_jcr(JCR *jcr);
+void     connection_from_filed(void *arg);     
+void     handle_filed_connection(BSOCK *fd, char *job_name);
 
 /* From label.c */
-int     read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-void    create_session_label(JCR *jcr, DEV_RECORD *rec, int label);
-int     write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName);
-int     write_session_label(JCR *jcr, DEV_BLOCK *block, int label);
-int     write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-void    dump_volume_label(DEVICE *dev);
-void    dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
-int     unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
-int     unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
+int      read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+void     create_session_label(JCR *jcr, DEV_RECORD *rec, int label);
+int      write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName);
+int      write_session_label(JCR *jcr, DEV_BLOCK *block, int label);
+int      write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+void     dump_volume_label(DEVICE *dev);
+void     dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
+int      unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
+int      unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
+
+/* From match_bsr.c */
+int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, 
+              SESSION_LABEL *sesrec);
+
+/* From parse_bsr.c */
+extern BSR *parse_bsr(char *lf);
+extern void dump_bsr(BSR *bsr);
+extern void free_bsr(BSR *bsr);
 
 /* From record.c */
 char   *FI_to_ascii(int fi);
 char   *stream_to_ascii(int stream);
-int    write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-int    read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec); 
+int     write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+int     read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec); 
 DEV_RECORD *new_record();
-void   free_record(DEV_RECORD *rec);
-int    read_record(DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *record);
-int    write_record_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *record);
+void    free_record(DEV_RECORD *rec);
+int     read_record(DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *record);
+int     write_record_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *record);
index 285aa5b5ced66ff89462e4d2563ed86f7f0168ea..91d274510dffb1ee5ceea30408011f3507eb3e52 100644 (file)
@@ -32,6 +32,7 @@
 #include "dev.h"
 #include "stored_conf.h"
 #include "jcr.h"
+#include "bsr.h"
 #include "protos.h"
 #ifdef HAVE_LIBZ
 #include <zlib.h>                     /* compression headers */
index e1b57fda6f81ecc576f154cbf52f652766422ee0..9125719d82c8af86dabc0328c7d24b0e78bb39fd 100644 (file)
@@ -1,8 +1,8 @@
 /* */
-#define VERSION "1.21"
+#define VERSION "1.22"
 #define VSTRING "1"
-#define DATE    "12 June 2002"
-#define LSMDATE "12Jun02"
+#define DATE    "15 June 2002"
+#define LSMDATE "15Jun02"
 
 /* Debug flags */
 #define DEBUG 1