* 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@noos.fr>, 1999-2000
- * Stelian Pop <pop@noos.fr> - Alcôve <www.alcove.fr>, 2000
+ * 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
static const char rcsid[] =
- "$Id: itime.c,v 1.17 2001/03/20 09:14:58 stelian Exp $";
+ "$Id: itime.c,v 1.28 2004/06/17 09:01:15 stelian Exp $";
#endif /* not lint */
#include <config.h>
#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 <time.h>
#include <bsdcompat.h>
#include <sys/file.h>
#include <unistd.h>
initdumptimes(int createdumpdates)
{
FILE *df;
+ struct flock lock;
if ((df = fopen(dumpdates, "r")) == NULL) {
if (errno != ENOENT) {
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);
}
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));
void
getdumptime(int createdumpdates)
{
- register struct dumpdates *ddp;
- register int i;
+ struct dumpdates *ddp;
+ int i;
#ifdef FDEBUG
- msg("Looking for name %s in dumpdates = %s for level = %c\n",
+ 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 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 ( (level == lastlevel) && !createdumpdates)
+ if ( (!strcmp(level, lastlevel)) && !createdumpdates)
return;
initdumptimes(createdumpdates);
if (ddatev == NULL)
ITITERATE(i, ddp) {
if (strncmp(disk, ddp->dd_name, sizeof (ddp->dd_name)) != 0)
continue;
- if (ddp->dd_level >= level)
+ if (ddp->dd_level >= atoi(level))
continue;
if (ddp->dd_ddate <= (time_t)spcl.c_ddate)
continue;
spcl.c_ddate = ddp->dd_ddate;
- lastlevel = ddp->dd_level;
+ snprintf(lastlevel, NUM_STR_SIZE, "%d", ddp->dd_level);
}
}
putdumptime(void)
{
FILE *df;
- register struct dumpdates *dtwalk;
- register int i;
+ struct dumpdates *dtwalk;
+ int i;
int fd;
+ 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);
+ 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;
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;
}
nddates += 1;
found:
(void) strncpy(dtwalk->dd_name, disk, sizeof (dtwalk->dd_name));
- dtwalk->dd_level = level;
+ dtwalk->dd_level = atoi(level);
dtwalk->dd_ddate = spcl.c_date;
ITITERATE(i, dtwalk) {
if (ftruncate(fd, ftell(df)))
quit("ftruncate (%s): %s\n", dumpdates, strerror(errno));
(void) fclose(df);
- msg("level %c dump on %s", level,
- spcl.c_date == 0 ? "the epoch\n" : ctime4(&spcl.c_date));
}
static void
dumprecout(FILE *file, struct dumpdates *what)
{
+ char buf[26];
+ struct tm *tms;
- if (fprintf(file, "%s %c %s",
+ 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));
}
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);
makedumpdate(struct dumpdates *ddp, char *tbuf)
{
char *tok;
-
/* device name */
if ( NULL == (tok = strsep( &tbuf, " ")) )
return(-1);
- if ( strlen(tok) > MAXPATHLEN )
+ if ( !tbuf || strlen(tok) > MAXPATHLEN )
return(-1);
strcpy(ddp->dd_name, tok);
for( ; *tbuf == ' ' ; tbuf++);
/* dump level */
- ddp->dd_level = *tbuf;
- ++tbuf;
+ ddp->dd_level = atoi(tbuf);
+ /* eat the rest of the numbers*/
+ for( ; *tbuf >= '0' && *tbuf <= '9' ; tbuf++);
/* eat whitespace */
for( ; *tbuf == ' ' ; tbuf++);