Imported Upstream version 3.1.0
[debian/amanda] / ndmp-src / ndml_fhdb.c
diff --git a/ndmp-src/ndml_fhdb.c b/ndmp-src/ndml_fhdb.c
new file mode 100644 (file)
index 0000000..974b5c9
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2001,2002
+ *     Traakan, Inc., Los Altos, CA
+ *     All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Project:  NDMJOB
+ * Ident:    $Id: $
+ *
+ * Description:
+ *
+ */
+
+
+#include "ndmlib.h"
+
+
+
+int
+ndmfhdb_add_file (struct ndmlog *ixlog, int tagc,
+  char *raw_name, ndmp9_file_stat *fstat)
+{
+       char            prefix[8];
+       char            statbuf[100];
+       char            namebuf[NDMOS_CONST_PATH_MAX];
+
+       strcpy (prefix, "DHf");
+       prefix[0] = tagc;
+
+       ndm_fstat_to_str (fstat, statbuf);
+
+       ndmcstr_from_str (raw_name, namebuf, sizeof namebuf);
+
+       ndmlogf (ixlog, prefix, 0, "%s UNIX %s", namebuf, statbuf);
+
+       return 0;
+}
+
+int
+ndmfhdb_add_dir (struct ndmlog *ixlog, int tagc,
+  char *raw_name, ndmp9_u_quad dir_node, ndmp9_u_quad node)
+{
+       char            prefix[8];
+       char            namebuf[NDMOS_CONST_PATH_MAX];
+
+       strcpy (prefix, "DHd");
+       prefix[0] = tagc;
+
+       ndmcstr_from_str (raw_name, namebuf, sizeof namebuf);
+
+       ndmlogf (ixlog, prefix, 0, "%llu %s UNIX %llu",
+               dir_node, namebuf, node);
+
+       return 0;
+}
+
+int
+ndmfhdb_add_node (struct ndmlog *ixlog, int tagc,
+  ndmp9_u_quad node, ndmp9_file_stat *fstat)
+{
+       char            prefix[8];
+       char            statbuf[100];
+
+       strcpy (prefix, "DHn");
+       prefix[0] = tagc;
+
+       ndm_fstat_to_str (fstat, statbuf);
+
+       ndmlogf (ixlog, prefix, 0, "%llu UNIX %s", node, statbuf);
+
+       return 0;
+}
+
+int
+ndmfhdb_add_dirnode_root (struct ndmlog *ixlog, int tagc,
+  ndmp9_u_quad root_node)
+{
+       char            prefix[8];
+
+       strcpy (prefix, "DHr");
+       prefix[0] = tagc;
+
+       ndmlogf (ixlog, prefix, 0, "%llu", root_node);
+
+       return 0;
+}
+
+
+int
+ndmfhdb_add_fh_info_to_nlist (FILE *fp, ndmp9_name *nlist, int n_nlist)
+{
+       struct ndmfhdb          _fhcb, *fhcb = &_fhcb;
+       int                     i, rc, n_found;
+       ndmp9_file_stat         fstat;
+
+       rc = ndmfhdb_open (fp, fhcb);
+       if (rc != 0) {
+               return -31;
+       }
+
+       n_found = 0;
+
+       for (i = 0; i < n_nlist; i++) {
+               char *          name = nlist[i].original_path;
+
+               rc = ndmfhdb_lookup (fhcb, name, &fstat);
+               if (rc > 0) {
+                       nlist[i].fh_info = fstat.fh_info;
+                       if (fstat.fh_info.valid) {
+                               n_found++;
+                       }
+               }
+       }
+
+       return n_found;
+}
+
+int
+ndmfhdb_open (FILE *fp, struct ndmfhdb *fhcb)
+{
+       int             rc;
+
+       NDMOS_MACRO_ZEROFILL (fhcb);
+
+       fhcb->fp = fp;
+
+       rc = ndmfhdb_dirnode_root (fhcb);
+       if (rc > 0) {
+               fhcb->use_dir_node = 1;
+               return 0;
+       }
+
+       rc = ndmfhdb_file_root (fhcb);
+       if (rc > 0) {
+               fhcb->use_dir_node = 0;
+               return 0;
+       }
+
+       return -1;
+}
+
+int
+ndmfhdb_lookup (struct ndmfhdb *fhcb, char *path, ndmp9_file_stat *fstat)
+{
+       if (fhcb->use_dir_node) {
+               return ndmfhdb_dirnode_lookup (fhcb, path, fstat);
+       } else {
+               return ndmfhdb_file_lookup (fhcb, path, fstat);
+       }
+}
+
+int
+ndmfhdb_dirnode_root (struct ndmfhdb *fhcb)
+{
+       int             rc, off;
+       char *          p;
+       char            key[256];
+       char            linebuf[2048];
+
+       sprintf (key, "DHr ");
+
+       p = NDMOS_API_STREND(key);
+       off = p - key;
+
+       rc = ndmbstf_first (fhcb->fp, key, linebuf, sizeof linebuf);
+
+       if (rc <= 0) {
+               return rc;      /* error or not found */
+       }
+
+       fhcb->root_node = NDMOS_API_STRTOLL (linebuf+off, &p, 0);
+
+       if (*p != 0) {
+               return -10;
+       }
+
+       return 1;
+}
+
+int
+ndmfhdb_dirnode_lookup (struct ndmfhdb *fhcb, char *path,
+  ndmp9_file_stat *fstat)
+{
+       int                     rc;
+       char *                  p;
+       char *                  q;
+       char                    component[256+128];
+       unsigned long long      dir_node;
+       unsigned long long      node;
+
+       /* classic path name reduction */
+       node = dir_node = fhcb->root_node;
+       p = path;
+       for (;;) {
+               if (*p == '/') {
+                       p++;
+                       continue;
+               }
+               if (*p == 0) {
+                       break;
+               }
+               q = component;
+               while (*p != 0 && *p != '/') {
+                       *q++ = *p++;
+               }
+               *q = 0;
+
+               dir_node = node;
+               rc = ndmfhdb_dir_lookup (fhcb, dir_node, component, &node);
+               if (rc <= 0)
+                       return rc;      /* error or not found */
+       }
+
+       rc = ndmfhdb_node_lookup (fhcb, node, fstat);
+
+       return rc;
+}
+
+int
+ndmfhdb_dir_lookup (struct ndmfhdb *fhcb, unsigned long long dir_node,
+  char *name, unsigned long long *node_p)
+{
+       int             rc, off;
+       char *          p;
+       char            key[256+128];
+       char            linebuf[2048];
+
+       sprintf (key, "DHd %llu ", dir_node);
+       p = NDMOS_API_STREND(key);
+
+       ndmcstr_from_str (name, p, sizeof key - (p-key) - 10);
+
+       strcat (p, " UNIX ");
+
+       p = NDMOS_API_STREND(key);
+       off = p - key;
+
+       rc = ndmbstf_first (fhcb->fp, key, linebuf, sizeof linebuf);
+
+       if (rc <= 0) {
+               return rc;      /* error or not found */
+       }
+
+       *node_p = NDMOS_API_STRTOLL (linebuf+off, &p, 0);
+
+       if (*p != 0) {
+               return -10;
+       }
+
+       return 1;
+}
+
+int
+ndmfhdb_node_lookup (struct ndmfhdb *fhcb, unsigned long long node,
+  ndmp9_file_stat *fstat)
+{
+       int             rc, off;
+       char *          p;
+       char            key[128];
+       char            linebuf[2048];
+
+       sprintf (key, "DHn %llu UNIX ", node);
+
+       p = NDMOS_API_STREND(key);
+       off = p - key;
+
+
+       rc = ndmbstf_first (fhcb->fp, key, linebuf, sizeof linebuf);
+
+       if (rc <= 0) {
+               return rc;      /* error or not found */
+       }
+
+
+       rc = ndm_fstat_from_str (fstat, linebuf + off);
+       if (rc < 0) {
+               return rc;
+       }
+
+       return 1;
+}
+
+int
+ndmfhdb_file_root (struct ndmfhdb *fhcb)
+{
+       int                     rc;
+       ndmp9_file_stat         fstat;
+
+       rc = ndmfhdb_file_lookup (fhcb, "/", &fstat);
+       if (rc > 0) {
+               if (fstat.node.valid)
+                       fhcb->root_node = fstat.node.value;
+       }
+
+       return rc;
+}
+
+int
+ndmfhdb_file_lookup (struct ndmfhdb *fhcb, char *path,
+  ndmp9_file_stat *fstat)
+{
+       int             rc, off;
+       char *          p;
+       char            key[2048];
+       char            linebuf[2048];
+
+       sprintf (key, "DHf ");
+       p = NDMOS_API_STREND(key);
+
+       ndmcstr_from_str (path, p, sizeof key - (p-key) - 10);
+
+       strcat (p, " UNIX ");
+
+       p = NDMOS_API_STREND(key);
+       off = p - key;
+
+       rc = ndmbstf_first (fhcb->fp, key, linebuf, sizeof linebuf);
+
+       if (rc <= 0) {
+               return rc;      /* error or not found */
+       }
+
+       rc = ndm_fstat_from_str (fstat, linebuf + off);
+       if (rc < 0) {
+               return rc;
+       }
+
+       return 1;
+}
+
+
+
+
+/*
+ * Same codes as wraplib.[ch] wrap_parse_fstat_subr()
+ * and wrap_send_fstat_subr().
+ */
+
+char *
+ndm_fstat_to_str (ndmp9_file_stat *fstat, char *buf)
+{
+       char *                  p = buf;
+
+       *p++ = 'f';
+       switch (fstat->ftype) {
+       case NDMP9_FILE_DIR:    *p++ = 'd';     break;
+       case NDMP9_FILE_FIFO:   *p++ = 'p';     break;
+       case NDMP9_FILE_CSPEC:  *p++ = 'c';     break;
+       case NDMP9_FILE_BSPEC:  *p++ = 'b';     break;
+       case NDMP9_FILE_REG:    *p++ = '-';     break;
+       case NDMP9_FILE_SLINK:  *p++ = 'l';     break;
+       case NDMP9_FILE_SOCK:   *p++ = 's';     break;
+       case NDMP9_FILE_REGISTRY: *p++ = 'R';   break;
+       case NDMP9_FILE_OTHER:  *p++ = 'o';     break;
+       default:                *p++ = '?';     break;
+       }
+
+       if (fstat->mode.valid) {
+               sprintf (p, " m%04lo", fstat->mode.value & 07777);
+       }
+       while (*p) p++;
+
+       if (fstat->uid.valid) {
+               sprintf (p, " u%ld", fstat->uid.value);
+       }
+       while (*p) p++;
+
+       if (fstat->gid.valid) {
+               sprintf (p, " g%ld", fstat->gid.value);
+       }
+       while (*p) p++;
+
+       if (fstat->ftype == NDMP9_FILE_REG
+        || fstat->ftype == NDMP9_FILE_SLINK) {
+               if (fstat->size.valid) {
+                       sprintf (p, " s%llu", fstat->size.value);
+               }
+       } else {
+               /* ignore size on other file types */
+       }
+       while (*p) p++;
+
+       /* tar -t can not recover atime/ctime */
+       /* they are also not particularly interesting in the index */
+
+       if (fstat->mtime.valid) {
+               sprintf (p, " tm%lu", fstat->mtime.value);
+       }
+       while (*p) p++;
+
+       if (fstat->fh_info.valid) {
+               sprintf (p, " @%lld", fstat->fh_info.value);
+       }
+       while (*p) p++;
+
+       return buf;
+}
+
+int
+ndm_fstat_from_str (ndmp9_file_stat *fstat, char *buf)
+{
+       char *                  scan = buf;
+       ndmp9_validity *        valid_p;
+
+       NDMOS_MACRO_ZEROFILL (fstat);
+
+       while (*scan) {
+               char *          p = scan + 1;
+
+               switch (*scan) {
+               case ' ':
+                       scan++;
+                       continue;
+
+               case '@':       /* fh_info */
+                       fstat->fh_info.value = NDMOS_API_STRTOLL (p, &scan, 0);
+                       valid_p = &fstat->fh_info.valid;
+                       break;
+
+               case 's':       /* size */
+                       fstat->size.value = NDMOS_API_STRTOLL (p, &scan, 0);
+                       valid_p = &fstat->size.valid;
+                       break;
+
+               case 'i':       /* fileno (inum) */
+                       fstat->node.value = NDMOS_API_STRTOLL (p, &scan, 0);
+                       valid_p = &fstat->node.valid;
+                       break;
+
+               case 'm':       /* mode low twelve bits */
+                       fstat->mode.value = strtol (p, &scan, 8);
+                       valid_p = &fstat->mode.valid;
+                       break;
+
+               case 'l':       /* link count */
+                       fstat->links.value = strtol (p, &scan, 0);
+                       valid_p = &fstat->links.valid;
+                       break;
+
+               case 'u':       /* uid */
+                       fstat->uid.value = strtol (p, &scan, 0);
+                       valid_p = &fstat->uid.valid;
+                       break;
+
+               case 'g':       /* gid */
+                       fstat->gid.value = strtol (p, &scan, 0);
+                       valid_p = &fstat->gid.valid;
+                       break;
+
+               case 't':               /* one of the times */
+                       p = scan+2;
+                       switch (scan[1]) {
+                       case 'm':       /* mtime */
+                               fstat->mtime.value = strtol (p, &scan, 0);
+                               valid_p = &fstat->mtime.valid;
+                               break;
+
+                       case 'a':       /* atime */
+                               fstat->atime.value = strtol (p, &scan, 0);
+                               valid_p = &fstat->atime.valid;
+                               break;
+
+                       case 'c':       /* ctime */
+                               fstat->ctime.value = strtol (p, &scan, 0);
+                               valid_p = &fstat->ctime.valid;
+                               break;
+
+                       default:
+                               return -13;
+                       }
+                       break;
+
+               case 'f':       /* ftype (file type) */
+                       switch (scan[1]) {
+                       case 'd': fstat->ftype = NDMP9_FILE_DIR; break;
+                       case 'p': fstat->ftype = NDMP9_FILE_FIFO; break;
+                       case 'c': fstat->ftype = NDMP9_FILE_CSPEC; break;
+                       case 'b': fstat->ftype = NDMP9_FILE_BSPEC; break;
+                       case '-': fstat->ftype = NDMP9_FILE_REG; break;
+                       case 'l': fstat->ftype = NDMP9_FILE_SLINK; break;
+                       case 's': fstat->ftype = NDMP9_FILE_SOCK; break;
+                       case 'R': fstat->ftype = NDMP9_FILE_REGISTRY; break;
+                       case 'o': fstat->ftype = NDMP9_FILE_OTHER; break;
+                       default:
+                               fstat->ftype = NDMP9_FILE_OTHER;
+                               return -15;
+                       }
+                       scan += 2;
+                       valid_p = 0;
+                       break;
+
+               default:
+                       return -13;
+               }
+
+               if (*scan != ' ' && *scan != 0)
+                       return -11;
+
+               if (valid_p)
+                       *valid_p = NDMP9_VALIDITY_VALID;
+       }
+
+       return 0;
+}