]> git.wh0rd.org - dump.git/blobdiff - dump/itime.c
Added EA/ACL support in dump and restore.
[dump.git] / dump / itime.c
index e29632cf75626cf721a38ab238d282f2bcbcd46c..f2cc76307eaf68d3e15b6569fc5760ba76598864 100644 (file)
@@ -2,8 +2,8 @@
  *     Ported to Linux's Second Extended File System as part of the
  *     dump and restore backup suit
  *     Remy Card <card@Linux.EU.Org>, 1994-1997
- *      Stelian Pop <pop@cybercable.fr>, 1999 
- *
+ *     Stelian Pop <stelian@popies.net>, 1999-2000
+ *     Stelian Pop <stelian@popies.net> - AlcĂ´ve <www.alcove.com>, 2000-2002
  */
 
 /*-
  * 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.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  */
 
 #ifndef lint
-#if 0
-static char sccsid[] = "@(#)itime.c    8.1 (Berkeley) 6/5/93";
-#endif
 static const char rcsid[] =
-       "$Id: itime.c,v 1.4 1999/10/11 13:08:07 stelian Exp $";
+       "$Id: itime.c,v 1.28 2004/06/17 09:01:15 stelian Exp $";
 #endif /* not lint */
 
+#include <config.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#include <string.h>
+#endif
+
 #include <sys/param.h>
 #include <sys/time.h>
+#include <time.h>
 #ifdef __linux__
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
 #include <linux/ext2_fs.h>
+#endif
+#include <ext2fs/ext2fs.h>
 #include <bsdcompat.h>
 #include <sys/file.h>
 #include <unistd.h>
-#else
-#ifdef sunos
+#elif defined sunos
 #include <sys/vnode.h>
 
 #include <ufs/fsdir.h>
@@ -64,28 +71,15 @@ static const char rcsid[] =
 #else
 #include <ufs/ufs/dinode.h>
 #endif
-#endif
 
 #include <protocols/dumprestore.h>
 
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#ifdef __STDC__
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#ifdef __linux__
-#include <ext2fs/ext2fs.h>
-#endif
-
 #include "dump.h"
 
-struct dumpdates **ddatev = 0;
-int    nddates = 0;
-int    ddates_in = 0;
-struct dumptime *dthead = 0;
+struct dumpdates **ddatev;
+int    nddates;
+int    ddates_in;
+struct dumptime *dthead;
 
 static void dumprecout __P((FILE *, struct dumpdates *));
 static int getrecord __P((FILE *, struct dumpdates *));
@@ -96,6 +90,7 @@ void
 initdumptimes(int createdumpdates)
 {
        FILE *df;
+       struct flock lock;
 
        if ((df = fopen(dumpdates, "r")) == NULL) {
                if (errno != ENOENT) {
@@ -124,7 +119,11 @@ initdumptimes(int createdumpdates)
                        msg("WARNING: no file `%s'\n", dumpdates);
        }
        if (df != NULL) {
-               (void) flock(fileno(df), LOCK_SH);
+               memset(&lock, 0, sizeof(lock));
+               lock.l_type = F_RDLCK;
+               if (fcntl(fileno(df), F_SETLKW, &lock) < 0)
+                       quit("cannot set read lock on %s: %s\n",
+                               dumpdates, strerror(errno));
                readdumptimes(df);
                (void) fclose(df);
        }
@@ -133,8 +132,8 @@ initdumptimes(int createdumpdates)
 static void
 readdumptimes(FILE *df)
 {
-       register int i;
-       register struct dumptime *dtwalk;
+       int i;
+       struct  dumptime *dtwalk;
 
        for (;;) {
                dtwalk = (struct dumptime *)calloc(1, sizeof (struct dumptime));
@@ -160,22 +159,21 @@ readdumptimes(FILE *df)
 void
 getdumptime(int createdumpdates)
 {
-       register struct dumpdates *ddp;
-       register int i;
-       char *fname;
+       struct dumpdates *ddp;
+       int i;
 
-       fname = disk;
 #ifdef FDEBUG
-       msg("Looking for name %s in dumpdates = %s for level = %c\n",
-               fname, dumpdates, level);
+       msg("Looking for name %s in dumpdates = %s for level = %s\n",
+               disk, dumpdates, level);
 #endif
        spcl.c_ddate = 0;
-       lastlevel = '0';
+       memset(&lastlevel, 0, NUM_STR_SIZE);
 
-       /* if we're not going to update dumpdates, there's no point in reading
-          it, particularly since /var might not be mounted... wait until here
-          to benefit from the initialization of variables needed by parent */
-       if (!uflag && level == lastlevel)
+       /* If this is a level 0 dump, and we're not updating 
+          dumpdates, there's no point in trying to read
+          dumpdates.  It may not exist yet, or may not be mounted.  For
+          incrementals, we *must* read dumpdates (fail if it's not there!) */
+       if ( (!strcmp(level, lastlevel)) && !createdumpdates)
                return;
        initdumptimes(createdumpdates);
        if (ddatev == NULL)
@@ -185,18 +183,14 @@ getdumptime(int createdumpdates)
         *      and older date
         */
        ITITERATE(i, ddp) {
-               if (strncmp(fname, ddp->dd_name, sizeof (ddp->dd_name)) != 0)
+               if (strncmp(disk, ddp->dd_name, sizeof (ddp->dd_name)) != 0)
                        continue;
-               if (ddp->dd_level >= level)
+               if (ddp->dd_level >= atoi(level))
                        continue;
-#ifdef __linux__
                if (ddp->dd_ddate <= (time_t)spcl.c_ddate)
-#else
-               if (ddp->dd_ddate <= spcl.c_ddate)
-#endif
                        continue;
                spcl.c_ddate = ddp->dd_ddate;
-               lastlevel = ddp->dd_level;
+               snprintf(lastlevel, NUM_STR_SIZE, "%d", ddp->dd_level);
        }
 }
 
@@ -204,18 +198,20 @@ void
 putdumptime(void)
 {
        FILE *df;
-       register struct dumpdates *dtwalk;
-       register int i;
+       struct dumpdates *dtwalk;
+       int i;
        int fd;
-       char *fname;
+       struct flock lock;
 
        if(uflag == 0)
                return;
        if ((df = fopen(dumpdates, "r+")) == NULL)
                quit("cannot rewrite %s: %s\n", dumpdates, strerror(errno));
        fd = fileno(df);
-       (void) flock(fd, LOCK_EX);
-       fname = disk;
+       memset(&lock, 0, sizeof(lock));
+       lock.l_type = F_WRLCK;
+       if (fcntl(fd, F_SETLKW, &lock) < 0)
+               quit("cannot set write lock on %s: %s\n", dumpdates, strerror(errno));
        free((char *)ddatev);
        ddatev = 0;
        nddates = 0;
@@ -226,10 +222,10 @@ putdumptime(void)
                quit("fseek: %s\n", strerror(errno));
        spcl.c_ddate = 0;
        ITITERATE(i, dtwalk) {
-               if (strncmp(fname, dtwalk->dd_name,
+               if (strncmp(disk, dtwalk->dd_name,
                                sizeof (dtwalk->dd_name)) != 0)
                        continue;
-               if (dtwalk->dd_level != level)
+               if (dtwalk->dd_level != atoi(level))
                        continue;
                goto found;
        }
@@ -241,8 +237,8 @@ putdumptime(void)
                (struct dumpdates *)calloc(1, sizeof (struct dumpdates));
        nddates += 1;
   found:
-       (void) strncpy(dtwalk->dd_name, fname, sizeof (dtwalk->dd_name));
-       dtwalk->dd_level = level;
+       (void) strncpy(dtwalk->dd_name, disk, sizeof (dtwalk->dd_name));
+       dtwalk->dd_level = atoi(level);
        dtwalk->dd_ddate = spcl.c_date;
 
        ITITERATE(i, dtwalk) {
@@ -253,22 +249,26 @@ putdumptime(void)
        if (ftruncate(fd, ftell(df)))
                quit("ftruncate (%s): %s\n", dumpdates, strerror(errno));
        (void) fclose(df);
-       msg("level %c dump on %s", level,
-#ifdef __linux__
-               spcl.c_date == 0 ? "the epoch\n" : ctime4(&spcl.c_date));
-#else
-               spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
-#endif
 }
 
 static void
 dumprecout(FILE *file, struct dumpdates *what)
 {
+       char buf[26];
+       struct tm *tms;
 
-       if (fprintf(file, DUMPOUTFMT,
+       tms = localtime(&what->dd_ddate);
+       strncpy(buf, asctime(tms), sizeof(buf));
+       if (buf[24] != '\n' || buf[25] != '\0')
+               quit("asctime returned an unexpected string\n");
+       buf[24] = 0;
+       if (fprintf(file, "%s %d %s %c%2.2d%2.2d\n",
                    what->dd_name,
                    what->dd_level,
-                   ctime(&what->dd_ddate)) < 0)
+                   buf,
+                   (tms->tm_gmtoff < 0 ? '-' : '+'),
+                   abs(tms->tm_gmtoff) / 3600,
+                   abs(tms->tm_gmtoff) % 3600 / 60) < 0)
                quit("%s: %s\n", dumpdates, strerror(errno));
 }
 
@@ -283,12 +283,14 @@ getrecord(FILE *df, struct dumpdates *ddatep)
        if (fgets(tbuf, sizeof (tbuf), df) == NULL)
                return(-1);
        recno++;
-       if (makedumpdate(ddatep, tbuf) < 0)
-               msg("Unknown intermediate format in %s, line %d\n",
+       if (makedumpdate(ddatep, tbuf) < 0) {
+               msg("Unknown format in %s, line %d\n",
                        dumpdates, recno);
+               return(-1);
+       }
 
 #ifdef FDEBUG
-       msg("getrecord: %s %c %s", ddatep->dd_name, ddatep->dd_level,
+       msg("getrecord: %s %d %s", ddatep->dd_name, ddatep->dd_level,
            ddatep->dd_ddate == 0 ? "the epoch\n" : ctime(&ddatep->dd_ddate));
 #endif
        return(0);
@@ -297,11 +299,30 @@ getrecord(FILE *df, struct dumpdates *ddatep)
 static int
 makedumpdate(struct dumpdates *ddp, char *tbuf)
 {
-       char un_buf[BUFSIZ];
+       char *tok;
+       /* device name */
+       if ( NULL == (tok = strsep( &tbuf, " ")) )
+               return(-1);
+       if ( !tbuf || strlen(tok) >  MAXPATHLEN )
+               return(-1);
+       strcpy(ddp->dd_name, tok);
+
+       /* eat whitespace */
+       for( ; *tbuf == ' ' ; tbuf++);
+
+       /* dump level */
+       ddp->dd_level = atoi(tbuf);
+       /* eat the rest of the numbers*/
+       for( ; *tbuf >= '0' && *tbuf <= '9' ; tbuf++);
+
+       /* eat whitespace */
+       for( ; *tbuf == ' ' ; tbuf++);
 
-       (void) sscanf(tbuf, DUMPINFMT, ddp->dd_name, &ddp->dd_level, un_buf);
-       ddp->dd_ddate = unctime(un_buf);
+       /* dump date */
+       ddp->dd_ddate = unctime(tbuf);
        if (ddp->dd_ddate < 0)
                return(-1);
+       /* fstab entry */
+       ddp->dd_fstab = fstabsearch(ddp->dd_name);
        return(0);
 }