xref: /csrg-svn/sbin/dump/itime.c (revision 61484)
147082Smckusick /*-
2*61484Sbostic  * Copyright (c) 1980, 1993
3*61484Sbostic  *	The Regents of the University of California.  All rights reserved.
447082Smckusick  *
547082Smckusick  * %sccs.include.redist.c%
622036Sdist  */
712589Smckusick 
822036Sdist #ifndef lint
9*61484Sbostic static char sccsid[] = "@(#)itime.c	8.1 (Berkeley) 06/05/93";
1046590Storek #endif /* not lint */
1122036Sdist 
1257725Smckusick #include <sys/param.h>
1357725Smckusick #include <sys/time.h>
1450494Smckusick #ifdef sunos
1557725Smckusick #include <sys/vnode.h>
1657725Smckusick 
1757725Smckusick #include <ufs/fsdir.h>
1857725Smckusick #include <ufs/inode.h>
1950494Smckusick #include <ufs/fs.h>
2050494Smckusick #else
2157725Smckusick #include <ufs/ufs/dinode.h>
2254040Smckusick #endif
2357725Smckusick 
2446795Sbostic #include <protocols/dumprestore.h>
2557725Smckusick 
2646795Sbostic #include <errno.h>
2757725Smckusick #include <fcntl.h>
2846795Sbostic #include <stdio.h>
2946795Sbostic #ifdef __STDC__
3046795Sbostic #include <stdlib.h>
3146795Sbostic #include <string.h>
3257725Smckusick #include <unistd.h>
3346795Sbostic #endif
3457725Smckusick 
351422Sroot #include "dump.h"
361422Sroot 
3746791Smckusick struct	dumpdates **ddatev = 0;
3846791Smckusick int	nddates = 0;
3946791Smckusick int	ddates_in = 0;
4046791Smckusick struct	dumptime *dthead = 0;
411422Sroot 
4257725Smckusick static	void dumprecout __P((FILE *, struct dumpdates *));
4357725Smckusick static	int getrecord __P((FILE *, struct dumpdates *));
4457725Smckusick static	int makedumpdate __P((struct dumpdates *, char *));
4557725Smckusick static	void readdumptimes __P((FILE *));
4646590Storek 
4746590Storek void
initdumptimes()4846791Smckusick initdumptimes()
491422Sroot {
5028858Smckusick 	FILE *df;
511422Sroot 
5246791Smckusick 	if ((df = fopen(dumpdates, "r")) == NULL) {
5350493Smckusick 		if (errno != ENOENT) {
5450493Smckusick 			quit("cannot read %s: %s\n", dumpdates,
5550493Smckusick 			    strerror(errno));
5650493Smckusick 			/* NOTREACHED */
5746590Storek 		}
5850493Smckusick 		/*
5950493Smckusick 		 * Dumpdates does not exist, make an empty one.
6050493Smckusick 		 */
6150493Smckusick 		msg("WARNING: no file `%s', making an empty one\n", dumpdates);
6250493Smckusick 		if ((df = fopen(dumpdates, "w")) == NULL) {
6350493Smckusick 			quit("cannot create %s: %s\n", dumpdates,
6450493Smckusick 			    strerror(errno));
6550493Smckusick 			/* NOTREACHED */
6650493Smckusick 		}
6750493Smckusick 		(void) fclose(df);
6850493Smckusick 		if ((df = fopen(dumpdates, "r")) == NULL) {
6950493Smckusick 			quit("cannot read %s even after creating it: %s\n",
7050493Smckusick 			    dumpdates, strerror(errno));
7150493Smckusick 			/* NOTREACHED */
7250493Smckusick 		}
7312589Smckusick 	}
7428858Smckusick 	(void) flock(fileno(df), LOCK_SH);
7546791Smckusick 	readdumptimes(df);
7654040Smckusick 	(void) fclose(df);
7728858Smckusick }
7828858Smckusick 
7957725Smckusick static void
readdumptimes(df)8046791Smckusick readdumptimes(df)
8128858Smckusick 	FILE *df;
8228858Smckusick {
8346791Smckusick 	register int i;
8446791Smckusick 	register struct	dumptime *dtwalk;
8528858Smckusick 
8628858Smckusick 	for (;;) {
8746791Smckusick 		dtwalk = (struct dumptime *)calloc(1, sizeof (struct dumptime));
8846791Smckusick 		if (getrecord(df, &(dtwalk->dt_value)) < 0)
8928858Smckusick 			break;
9046791Smckusick 		nddates++;
9146791Smckusick 		dtwalk->dt_next = dthead;
9246791Smckusick 		dthead = dtwalk;
931422Sroot 	}
941422Sroot 
9546791Smckusick 	ddates_in = 1;
961422Sroot 	/*
971422Sroot 	 *	arrayify the list, leaving enough room for the additional
9846791Smckusick 	 *	record that we may have to add to the ddate structure
991422Sroot 	 */
10046791Smckusick 	ddatev = (struct dumpdates **)
10154040Smckusick 		calloc((unsigned) (nddates + 1), sizeof (struct dumpdates *));
10246791Smckusick 	dtwalk = dthead;
10346791Smckusick 	for (i = nddates - 1; i >= 0; i--, dtwalk = dtwalk->dt_next)
10446791Smckusick 		ddatev[i] = &dtwalk->dt_value;
1051422Sroot }
1061422Sroot 
10746590Storek void
getdumptime()10846791Smckusick getdumptime()
1091422Sroot {
11046791Smckusick 	register struct dumpdates *ddp;
11146791Smckusick 	register int i;
11246791Smckusick 	char *fname;
1131422Sroot 
1141422Sroot 	fname = disk;
1151422Sroot #ifdef FDEBUG
11646791Smckusick 	msg("Looking for name %s in dumpdates = %s for level = %c\n",
11746791Smckusick 		fname, dumpdates, level);
1181422Sroot #endif
1191422Sroot 	spcl.c_ddate = 0;
12046791Smckusick 	lastlevel = '0';
1211422Sroot 
12246791Smckusick 	initdumptimes();
1231422Sroot 	/*
1241422Sroot 	 *	Go find the entry with the same name for a lower increment
1251422Sroot 	 *	and older date
1261422Sroot 	 */
12746791Smckusick 	ITITERATE(i, ddp) {
12846791Smckusick 		if (strncmp(fname, ddp->dd_name, sizeof (ddp->dd_name)) != 0)
1291422Sroot 			continue;
13046791Smckusick 		if (ddp->dd_level >= level)
1311422Sroot 			continue;
13246791Smckusick 		if (ddp->dd_ddate <= spcl.c_ddate)
1331422Sroot 			continue;
13446791Smckusick 		spcl.c_ddate = ddp->dd_ddate;
13546791Smckusick 		lastlevel = ddp->dd_level;
13628858Smckusick 	}
1371422Sroot }
1381422Sroot 
13946590Storek void
putdumptime()14046791Smckusick putdumptime()
1411422Sroot {
14246791Smckusick 	FILE *df;
14346791Smckusick 	register struct dumpdates *dtwalk;
14446791Smckusick 	register int i;
14546791Smckusick 	int fd;
14646791Smckusick 	char *fname;
1471422Sroot 
1481422Sroot 	if(uflag == 0)
1491422Sroot 		return;
15046791Smckusick 	if ((df = fopen(dumpdates, "r+")) == NULL)
15146791Smckusick 		quit("cannot rewrite %s: %s\n", dumpdates, strerror(errno));
15228858Smckusick 	fd = fileno(df);
15313151Ssam 	(void) flock(fd, LOCK_EX);
1541422Sroot 	fname = disk;
15554040Smckusick 	free((char *)ddatev);
15646791Smckusick 	ddatev = 0;
15746791Smckusick 	nddates = 0;
15846791Smckusick 	dthead = 0;
15946791Smckusick 	ddates_in = 0;
16046791Smckusick 	readdumptimes(df);
16146590Storek 	if (fseek(df, 0L, 0) < 0)
16246590Storek 		quit("fseek: %s\n", strerror(errno));
1631422Sroot 	spcl.c_ddate = 0;
16446791Smckusick 	ITITERATE(i, dtwalk) {
16546791Smckusick 		if (strncmp(fname, dtwalk->dd_name,
16646791Smckusick 				sizeof (dtwalk->dd_name)) != 0)
1671422Sroot 			continue;
16846791Smckusick 		if (dtwalk->dd_level != level)
1691422Sroot 			continue;
1701422Sroot 		goto found;
1711422Sroot 	}
1721422Sroot 	/*
1731422Sroot 	 *	construct the new upper bound;
1741422Sroot 	 *	Enough room has been allocated.
1751422Sroot 	 */
17646791Smckusick 	dtwalk = ddatev[nddates] =
17752847Sleres 		(struct dumpdates *)calloc(1, sizeof (struct dumpdates));
17846791Smckusick 	nddates += 1;
1791422Sroot   found:
18046791Smckusick 	(void) strncpy(dtwalk->dd_name, fname, sizeof (dtwalk->dd_name));
18146791Smckusick 	dtwalk->dd_level = level;
18246791Smckusick 	dtwalk->dd_ddate = spcl.c_date;
1831422Sroot 
18446791Smckusick 	ITITERATE(i, dtwalk) {
18546791Smckusick 		dumprecout(df, dtwalk);
1861422Sroot 	}
18746590Storek 	if (fflush(df))
18846791Smckusick 		quit("%s: %s\n", dumpdates, strerror(errno));
18946590Storek 	if (ftruncate(fd, ftell(df)))
19046791Smckusick 		quit("ftruncate (%s): %s\n", dumpdates, strerror(errno));
19112589Smckusick 	(void) fclose(df);
19246791Smckusick 	msg("level %c dump on %s", level,
19346791Smckusick 		spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
1941422Sroot }
1951422Sroot 
19646590Storek static void
dumprecout(file,what)19746791Smckusick dumprecout(file, what)
19846791Smckusick 	FILE *file;
19946791Smckusick 	struct dumpdates *what;
2001422Sroot {
20146590Storek 
20246590Storek 	if (fprintf(file, DUMPOUTFMT,
20346791Smckusick 		    what->dd_name,
20446791Smckusick 		    what->dd_level,
20546791Smckusick 		    ctime(&what->dd_ddate)) < 0)
20646791Smckusick 		quit("%s: %s\n", dumpdates, strerror(errno));
2071422Sroot }
2081422Sroot 
2091422Sroot int	recno;
21057725Smckusick 
21157725Smckusick static int
getrecord(df,ddatep)21246791Smckusick getrecord(df, ddatep)
21346791Smckusick 	FILE *df;
21446791Smckusick 	struct dumpdates *ddatep;
2151422Sroot {
21652846Sleres 	char tbuf[BUFSIZ];
2171422Sroot 
2181422Sroot 	recno = 0;
21952847Sleres 	if ( (fgets(tbuf, sizeof (tbuf), df)) != tbuf)
2201422Sroot 		return(-1);
2211422Sroot 	recno++;
22252846Sleres 	if (makedumpdate(ddatep, tbuf) < 0)
2231422Sroot 		msg("Unknown intermediate format in %s, line %d\n",
22446791Smckusick 			dumpdates, recno);
2251422Sroot 
2261422Sroot #ifdef FDEBUG
22746791Smckusick 	msg("getrecord: %s %c %s", ddatep->dd_name, ddatep->dd_level,
22846791Smckusick 	    ddatep->dd_ddate == 0 ? "the epoch\n" : ctime(&ddatep->dd_ddate));
2291422Sroot #endif
2301422Sroot 	return(0);
2311422Sroot }
2321422Sroot 
23357725Smckusick static int
makedumpdate(ddp,tbuf)23452846Sleres makedumpdate(ddp, tbuf)
23546791Smckusick 	struct dumpdates *ddp;
23652846Sleres 	char *tbuf;
2371422Sroot {
23846791Smckusick 	char un_buf[128];
2391422Sroot 
24054040Smckusick 	(void) sscanf(tbuf, DUMPINFMT, ddp->dd_name, &ddp->dd_level, un_buf);
24146791Smckusick 	ddp->dd_ddate = unctime(un_buf);
24246791Smckusick 	if (ddp->dd_ddate < 0)
2431422Sroot 		return(-1);
2441422Sroot 	return(0);
2451422Sroot }
246