]> git.wh0rd.org - dump.git/blobdiff - restore/symtab.c
Make the directory hashtable optional and controled via restore -H
[dump.git] / restore / symtab.c
index 8cd384c51dd36a7f2ba622f75f0214bdf93fd268..7e5605730db48ce73ca6472178b1bcd6f5b668cd 100644 (file)
@@ -37,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: symtab.c,v 1.23 2004/12/14 14:07:58 stelian Exp $";
+       "$Id: symtab.c,v 1.27 2005/07/07 09:16:08 stelian Exp $";
 #endif /* not lint */
 
 /*
@@ -50,6 +50,7 @@ static const char rcsid[] =
  */
 
 #include <config.h>
+#include <compatlfs.h>
 #include <sys/param.h>
 #include <sys/stat.h>
 
@@ -117,7 +118,7 @@ dir_hash(char *name)
                hash1 = hash0;
                hash0 = hash; 
        }       
-       return hash0 % DIRHASH_SIZE;
+       return hash0 % dirhash_size;
 }
 
 /*
@@ -189,9 +190,16 @@ lookupname(char *name)
        char *np, *cp;
        char buf[MAXPATHLEN];
 
+       ep = lookupino(ROOTINO);
+
        cp = name;
+       if (*cp == '.')
+               ++cp;
+       if (*cp == '/')
+               ++cp;
+       if (*cp == '\0')
+               return ep;
 
-       ep = lookupino(ROOTINO);
        while (ep != NULL) {
                for (np = buf; *cp != '/' && *cp != '\0' &&
                                np < &buf[sizeof(buf)]; )
@@ -202,8 +210,7 @@ lookupname(char *name)
 
                oldep = ep;
 
-               if (strcmp(ep->e_name, buf) != 0 &&
-                   ep->e_entries != NULL) {
+               if (ep->e_entries != NULL) {
 
                        ep = ep->e_entries[dir_hash(buf)];
                        for ( ; ep != NULL; ep = ep->e_sibling)
@@ -213,7 +220,7 @@ lookupname(char *name)
                        /* search all hash lists for renamed inodes */
                        if (ep == NULL) {
                                int j;
-                               for (j = 0; j < DIRHASH_SIZE; j++) {
+                               for (j = 0; j < dirhash_size; j++) {
                                        ep = oldep->e_entries[j];
                                        for ( ; ep != NULL; ep = ep->e_sibling)
                                                if (strcmp(ep->e_name, buf) == 0)
@@ -300,7 +307,7 @@ addentry(char *name, dump_ino_t inum, int type)
        }
        np->e_type = type & ~LINK;
        if (type & NODE) {
-               np->e_entries = calloc(1, DIRHASH_SIZE * sizeof(struct entry *));
+               np->e_entries = calloc(1, dirhash_size * sizeof(struct entry *));
                if (np->e_entries == NULL)
                        panic("unable to allocate directory entries\n");
        }
@@ -350,7 +357,7 @@ freeentry(struct entry *ep)
                        badentry(ep, "freeing referenced directory");
                if (ep->e_entries != NULL) {
                        int i;
-                       for (i = 0; i < DIRHASH_SIZE; i++) {
+                       for (i = 0; i < dirhash_size; i++) {
                                if (ep->e_entries[i] != NULL) 
                                        badentry(ep, "freeing non-empty directory");
                        }
@@ -432,7 +439,7 @@ removeentry(struct entry *ep)
 
                        /* search all hash lists for renamed inodes */
                        int j;
-                       for (j = 0; j < DIRHASH_SIZE; j++) {
+                       for (j = 0; j < dirhash_size; j++) {
                                np = ep->e_parent;
                                entry = np->e_entries[j];
                                if (entry == ep) {
@@ -543,12 +550,12 @@ dumpsymtable(char *filename, long checkpt)
        long mynum = 1, stroff = 0, hashoff = 0;
        FILE *fd;
        struct symtableheader hdr;
-       struct entry *temphash[DIRHASH_SIZE];
+       struct entry **temphash;
 
        Vprintf(stdout, "Check pointing the restore\n");
        if (Nflag)
                return;
-       if ((fd = fopen(filename, "w")) == NULL) {
+       if ((fd = FOPEN(filename, "w")) == NULL) {
                warn("fopen");
                panic("cannot create save file %s for symbol table\n",
                        filename);
@@ -568,19 +575,24 @@ dumpsymtable(char *filename, long checkpt)
        /*
         * Write out e_entries tables
         */
+       temphash = calloc(1, dirhash_size * sizeof(struct entry *));
+       if (temphash == NULL)
+               errx(1, "no memory for saving hashtable");
        for (i = WINO; i <= maxino; i++) {
                for (ep = lookupino(i); ep != NULL; ep = ep->e_links) {
                        if (ep->e_entries != NULL) {
                                int j;
-                               memcpy(temphash, ep->e_entries, DIRHASH_SIZE * sizeof(struct entry *));
-                               for (j = 0; j < DIRHASH_SIZE; j++) {
+                               memcpy(temphash, ep->e_entries, dirhash_size * sizeof(struct entry *));
+                               for (j = 0; j < dirhash_size; j++) {
                                        if (temphash[j])
                                                temphash[j] = (struct entry *)ep->e_entries[j]->e_index;
                                }
-                               fwrite(temphash, DIRHASH_SIZE, sizeof(struct entry *), fd);
+                               fwrite(temphash, dirhash_size, sizeof(struct entry *), fd);
                        }
                }
        }
+       free(temphash);
+
        /*
         * Convert pointers to indexes, and output
         */
@@ -601,7 +613,7 @@ dumpsymtable(char *filename, long checkpt)
                                        (struct entry *)ep->e_sibling->e_index;
                        if (ep->e_entries != NULL) {
                                tep->e_entries = (struct entry **)hashoff;
-                               hashoff += DIRHASH_SIZE * sizeof(struct entry *);
+                               hashoff += dirhash_size * sizeof(struct entry *);
                        }
                        if (ep->e_next != NULL)
                                tep->e_next =
@@ -648,7 +660,7 @@ initsymtable(char *filename)
        struct entry *ep;
        struct entry *baseep, *lep;
        struct symtableheader hdr;
-       struct stat stbuf;
+       struct STAT stbuf;
        long i;
        int fd;
 
@@ -663,11 +675,11 @@ initsymtable(char *filename)
                ep->e_flags |= NEW;
                return;
        }
-       if ((fd = open(filename, O_RDONLY, 0)) < 0) {
+       if ((fd = OPEN(filename, O_RDONLY, 0)) < 0) {
                warn("open");
                errx(1, "cannot open symbol table file %s", filename);
        }
-       if (fstat(fd, &stbuf) < 0) {
+       if (FSTAT(fd, &stbuf) < 0) {
                warn("stat");
                errx(1, "cannot stat symbol table file %s", filename);
        }
@@ -706,8 +718,10 @@ initsymtable(char *filename)
                panic("initsymtable called from command %c\n", command);
                break;
        }
-       resizemaps(maxino, hdr.maxino);
-       maxino = hdr.maxino;
+       if (hdr.maxino > maxino) {
+               resizemaps(maxino, hdr.maxino);
+               maxino = hdr.maxino;
+       }
        entrytblsize = hdr.entrytblsize;
        entry = (struct entry **)
                (base + tblsize - (entrytblsize * sizeof(struct entry *)));
@@ -728,7 +742,7 @@ initsymtable(char *filename)
                if (ep->e_type == NODE) {
                        int i;
                        ep->e_entries = (struct entry **)(base + hdr.stringsize + (long)ep->e_entries);
-                       for (i = 0; i < DIRHASH_SIZE; i++) {
+                       for (i = 0; i < dirhash_size; i++) {
                                if (ep->e_entries[i])
                                        ep->e_entries[i] = &baseep[(long)ep->e_entries[i]];
                        }