- Finish implementation of Verify=DiskToCatalog
 - Change console to bconsole.
 - Change smtp to bsmtp.
+- Possibly up network buffers to 65K.
 - Add device name to "Current Volume not acceptable because ..."
 - Make sure that Bacula rechecks the tape after the 20 min wait.
 - Set IO_NOWAIT on Bacula TCP/IP packets.
 - Document need to put LabelFormat in quotes.
 - Implement job in VerifyToCatalog
 - Eliminate ua_retention.c (retentioncmd) if possible.
-
 
 Release: 1
 Group: System Environment/Daemons
 Copyright: GPL v2
-Source: http://www.prdownloads.sourceforge.net/bacula/%{name}-%{version}.tar.gz
+Source0:http://www.prdownloads.sourceforge.net/bacula/%{name}-%{version}.tar.gz
+Source1:http://www.prdownloads.sourceforge.net/bacula/depkgs-24Jul03.tar.gz
 BuildRoot: %{_tmppath}/%{name}-root
 URL: http://www.bacula.org/
 Vendor: The Bacula Team
 
 %prep
 
-%setup
+%setup -b 1
 
 %build
 
 # patch the make_sqlite_tables script for installation bindir
 patch src/cats/make_sqlite_tables.in src/cats/make_sqlite_tables.in.patch
 
+# patch the make_catalog_backup script for installation bindir
+patch src/cats/make_catalog_backup.in src/cats/make_catalog_backup.in.patch
+
 %configure \
         --prefix=/usr \
         --sbindir=/usr/sbin \
 /sbin/chkconfig --del bacula-fd
 
 %changelog
+* Fri Oct 24 2003 D. Scott Barninger <barninger at fairfieldcomputers.com>
+- Added separate Source declaration for depkgs
+- added patch for make_catalog_backup script
 * Mon May 11 2003 D. Scott Barninger <barninger at fairfieldcomputers.com>
 - Misc changes to mysql/sqlite build and rh7/8 menu differences
 - Added rh_version to sub-package names
 
 #
 #  To read back a MySQL database use: 
 #     cd @working_dir@
-#     rm -f @SQL_BINDIR@/../var/bacula/*
 #     mysql <bacula.sql
 #
 #  To read back a SQLite database use:
 
--- /dev/null
+9c9
+<   echo ".dump" | @SQL_BINDIR@/sqlite bacula.db >bacula.sql
+---
+>   echo ".dump" | /usr/lib/sqlite/sqlite bacula.db >bacula.sql
+11c11
+<   @SQL_BINDIR@/mysqldump $* -f --opt bacula >bacula.sql
+---
+>   /usr/bin/mysqldump $* -f --opt bacula >bacula.sql
+16c16
+< #     rm -f @SQL_BINDIR@/../var/bacula/*
+---
+> #     rm -f /var/lib/mysql/bacula/*
+22c22
+< #     sqlite bacula.db <bacula.sql
+---
+> #     /usr/lib/sqlite/sqlite bacula.db <bacula.sql
 
    new_node->FileIndex = atoi(row[2]);
    new_node->JobId = atoi(row[3]);
    new_node->type = type;
-   new_node->extract = 1;            /* extract all by default */
+   new_node->extract = true;         /* extract all by default */
    tree->cnt++;
    return 0;
 }
  *  down the tree setting all children if the 
  *  node is a directory.
  */
-static void set_extract(UAContext *ua, TREE_NODE *node, TREE_CTX *tree, int value)
+static void set_extract(UAContext *ua, TREE_NODE *node, TREE_CTX *tree, bool extract)
 {
    TREE_NODE *n;
    FILE_DBR fdbr;
    struct stat statp;
 
-   node->extract = value;
+   node->extract = extract;
    /* For a non-file (i.e. directory), we see all the children */
    if (node->type != TN_FILE) {
       for (n=node->child; n; n=n->sibling) {
-        set_extract(ua, n, tree, value);
+        set_extract(ua, n, tree, extract);
       }
-   } else if (value) {
+   } else if (extract) {
       char cwd[2000];
       /* Ordinary file, we get the full path, look up the
        * attributes, decode them, and if we are hard linked to
         if (LinkFI) {
            for (n=first_tree_node(tree->root); n; n=next_tree_node(n)) {
               if (n->FileIndex == LinkFI && n->JobId == node->JobId) {
-                 n->extract = 1;
+                 n->extract = true;
                  break;
               }
            }
    }
    for (node = tree->node->child; node; node=node->sibling) {
       if (fnmatch(ua->argk[1], node->fname, 0) == 0) {
-        set_extract(ua, node, tree, 1);
+        set_extract(ua, node, tree, true);
       }
    }
    return 1;
 
 static int countcmd(UAContext *ua, TREE_CTX *tree)
 {
-   int total, extract;
+   int total, num_extract;
 
-   total = extract = 0;
+   total = num_extract = 0;
    for (TREE_NODE *node=first_tree_node(tree->root); node; node=next_tree_node(node)) {
       if (node->type != TN_NEWDIR) {
         total++;
         if (node->extract) {
-           extract++;
+           num_extract++;
         }
       }
    }
-   bsendmsg(ua, "%d total files. %d marked for restoration.\n", total, extract);
+   bsendmsg(ua, "%d total files. %d marked for restoration.\n", total, num_extract);
    return 1;
 }
 
 /*
  * This is actually the long form used for "dir"
  */
-static void ls_output(char *buf, char *fname, int extract, struct stat *statp)
+static void ls_output(char *buf, char *fname, bool extract, struct stat *statp)
 {
    char *p, *f;
    char ec1[30];
    }
    for (node = tree->node->child; node; node=node->sibling) {
       if (fnmatch(ua->argk[1], node->fname, 0) == 0) {
-        set_extract(ua, node, tree, 0);
+        set_extract(ua, node, tree, false);
       }
    }
    return 1;
 
 
 clean:
        @$(RMF) gnome-console core core.* a.out *.o *.bak *~ *.intpro *.extpro 1 2 3
-       @$(RMF) static-gnome-console
+       @$(RMF) static-gnome-console gmon.out
 
 realclean: clean
        @$(RMF) tags
 
 #define MAXPATHLEN 1000
 #endif
 
+#undef Dmsg0
+#undef Dmsg1
+#undef Dmsg2
+#undef Dmsg3
+#define Dmsg0(n,f)
+#define Dmsg1(n,f,a1)
+#define Dmsg2(n,f,a1,a2)
+#define Dmsg3(n,f,a1,a2,a3)
+
 /*
  * This subroutine gets a big buffer.
  */
    struct s_mem *mem;
 
    mem = (struct s_mem *)malloc(size);
+   root->total_size += size;
+   root->blocks++;
    mem->next = root->mem;
    root->mem = mem;
    mem->mem = mem->first;
    mem->rem = (char *)mem + size - mem->mem;
-   Dmsg2(400, "malloc buf size=%d rem=%d\n", size, mem->rem);
+   Dmsg2(200, "malloc buf size=%d rem=%d\n", size, mem->rem);
 }
 
 
    root = (TREE_ROOT *)malloc(sizeof(TREE_ROOT));
    memset(root, 0, sizeof(TREE_ROOT));
    root->type = TN_ROOT;
-   /* Assume filename = 20 characters average length */
-   size = count * (BALIGN(sizeof(TREE_NODE)) + 20);
-   if (size > 10000000) {
+   /* Assume filename + node  = 40 characters average length */
+   size = count * (BALIGN(sizeof(TREE_NODE)) + 40);
+   if (count > 1000000 || size > 10000000) {
       size = 10000000;
    }
    Dmsg2(400, "count=%d size=%d\n", count, size);
 TREE_NODE *new_tree_node(TREE_ROOT *root, int type)
 {
    TREE_NODE *node;
-   int size = BALIGN(sizeof(TREE_NODE));
+   int asize = BALIGN(sizeof(TREE_NODE));
 
-   if (root->mem->rem < size) {
-      malloc_buf(root, 20000);
+   if (root->mem->rem < asize) {
+      uint32_t mb_size;
+      if (root->total_size >= 1000000) {
+        mb_size = 1000000;
+      } else {
+        mb_size = 100000;
+      }
+      malloc_buf(root, mb_size);
    }
-
-   root->mem->rem -= size;
+   root->mem->rem -= asize;
    node = (TREE_NODE *)root->mem->mem;
-   root->mem->mem += size;
+   root->mem->mem += asize;
    memset(node, 0, sizeof(TREE_NODE));
    node->type = type;
    return node;
    int asize = BALIGN(size);
 
    if (root->mem->rem < asize) {
-      malloc_buf(root, 20000+asize);
+      uint32_t mb_size;
+      if (root->total_size >= 1000000) {
+        mb_size = 1000000;
+      } else {
+        mb_size = 100000;
+      }
+      malloc_buf(root, mb_size);
    }
    root->mem->rem -= asize;
    buf = root->mem->mem;
    if (root->cached_path) {
       free_pool_memory(root->cached_path);
    }
+   Dmsg2(400, "Total size=%u blocks=%d\n", root->total_size, root->blocks);
    free(root);
    return;
 }
 
 
 /* 
- * Insert a node in the tree
+ * Insert a node in the tree. This is the main subroutine
+ *   called when building a tree.
  *
  */
 TREE_NODE *insert_tree_node(char *path, TREE_NODE *node, 
 {
    TREE_NODE *sibling;
    char *p, *q, *fname;
-   int len = strlen(path);
+   int path_len = strlen(path);
 
    Dmsg1(100, "insert_tree_node: %s\n", path);
    /*
     * If trailing slash, strip it
     */
-   if (len > 0) {
-      q = path + len - 1;
+   if (path_len > 0) {
+      q = path + path_len - 1;
       if (*q == '/') {
         *q = 0;                      /* strip trailing slash */
       } else {
       if (!parent) {                 /* if no parent, we need to make one */
         *p = 0;                      /* terminate path */
          Dmsg1(100, "make_tree_path for %s\n", path);
-        if ((int)strlen(path) == root->cached_path_len &&
+        path_len = strlen(path);     /* get new length */
+        if (path_len == root->cached_path_len &&
             strcmp(path, root->cached_path) == 0) {
            parent = root->cached_parent;
         } else {
-           root->cached_path_len = strlen(path);
+           root->cached_path_len = path_len;
            pm_strcpy(&root->cached_path, path);
            parent = make_tree_path(path, root);
            root->cached_parent = parent; 
       Dmsg1(100, "No / found: %s\n", path);
    }
 
+   uint16_t fname_len = strlen(fname);
    for (sibling=parent->child; sibling; sibling=sibling->sibling) {
       Dmsg2(100, "sibling->fname=%s fname=%s\n", sibling->fname, fname);
-      if (strcmp(sibling->fname, fname) == 0) {
+      if (sibling->fname_len == fname_len &&
+         strcmp(sibling->fname, fname) == 0) {
          Dmsg1(100, "make_tree_path: found parent=%s\n", parent->fname);
         if (q) {                     /* if trailing slash on entry */
             *q = '/';                 /*  restore it */
       type = TN_DIR_NLS;
    }
    /* Is it already a sibling? */
+   uint16_t fname_len = strlen(fname);
    for (sibling=parent->child; sibling; sibling=sibling->sibling) {
       Dmsg2(100, "sibling->fname=%s fname=%s\n", sibling->fname, fname);
-      if (strcmp(sibling->fname, fname) == 0) {
+      if (sibling->fname_len == fname_len &&
+         strcmp(sibling->fname, fname) == 0) {
          Dmsg1(100, "make_tree_path: found parent=%s\n", parent->fname);
         return sibling;
       }
    TREE_NODE *child;
 
    Dmsg1(100, "append_tree_node: %s\n", fname);
-   node->fname = tree_alloc(root, strlen(fname) + 1);
+   node->fname_len = strlen(fname);
+   node->fname = tree_alloc(root, node->fname_len + 1);
    strcpy(node->fname, fname);
    node->parent = parent;
    if (!parent->child) {
     root = new_tree();
     root->fname = tree_alloc(root, 1);
     *root->fname = 0;
+    root->fname_len = 0;
 
     FillDirectoryTree("/home/kern/bacula/k", root, NULL);
 
 
    char first[1];                     /* first byte */
 };
 
+/*
+ * Keep this node as small as possible because
+ *   there is one for each file.
+ */
 struct s_tree_node {
    char *fname;                       /* file name */
    int32_t FileIndex;                 /* file index */
    uint32_t JobId;                    /* JobId */
-   short type;                        /* node type */
-   short extract;                     /* set if extracting */
+   uint16_t fname_len;                /* length of string */
+   uint8_t type;                      /* node type */
+   bool extract;                      /* set if extracting */
    struct s_tree_node *parent;
    struct s_tree_node *sibling;
    struct s_tree_node *child;
    char *fname;                       /* file name */
    int32_t FileIndex;                 /* file index */
    uint32_t JobId;                    /* JobId */
-   short type;                        /* node type */
-   short extract;                     /* set if extracting */
+   uint16_t fname_len;                /* length of string */
+   uint8_t type;                      /* node type */
+   bool extract;                      /* set if extracting */
    struct s_tree_node *parent;
    struct s_tree_node *sibling;
    struct s_tree_node *child;
    struct s_tree_node *first;         /* first entry in the tree */
    struct s_tree_node *last;          /* last entry in tree */
    struct s_mem *mem;                 /* tree memory */
+   uint32_t total_size;               /* total bytes allocated */
+   uint32_t blocks;                   /* total mallocs */
    int cached_path_len;               /* length of cached path */
    char *cached_path;                 /* cached current path */
    TREE_NODE *cached_parent;          /* cached parent for above path */