xref: /csrg-svn/sbin/dump/itime.c (revision 57725)
147082Smckusick /*-
247082Smckusick  * Copyright (c) 1980 The Regents of the University of California.
347082Smckusick  * All rights reserved.
447082Smckusick  *
547082Smckusick  * %sccs.include.redist.c%
622036Sdist  */
712589Smckusick 
822036Sdist #ifndef lint
9*57725Smckusick static char sccsid[] = "@(#)itime.c	5.16 (Berkeley) 01/25/93";
1046590Storek #endif /* not lint */
1122036Sdist 
12*57725Smckusick #include <sys/param.h>
13*57725Smckusick #include <sys/time.h>
1450494Smckusick #ifdef sunos
15*57725Smckusick #include <sys/vnode.h>
16*57725Smckusick 
17*57725Smckusick #include <ufs/fsdir.h>
18*57725Smckusick #include <ufs/inode.h>
1950494Smckusick #include <ufs/fs.h>
2050494Smckusick #else
21*57725Smckusick #include <ufs/ufs/dinode.h>
2254040Smckusick #endif
23*57725Smckusick 
2446795Sbostic #include <protocols/dumprestore.h>
25*57725Smckusick 
2646795Sbostic #include <errno.h>
27*57725Smckusick #include <fcntl.h>
2846795Sbostic #include <stdio.h>
2946795Sbostic #ifdef __STDC__
3046795Sbostic #include <stdlib.h>
3146795Sbostic #include <string.h>
32*57725Smckusick #include <unistd.h>
3346795Sbostic #endif
34*57725Smckusick 
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 
42*57725Smckusick static	void dumprecout __P((FILE *, struct dumpdates *));
43*57725Smckusick static	int getrecord __P((FILE *, struct dumpdates *));
44*57725Smckusick static	int makedumpdate __P((struct dumpdates *, char *));
45*57725Smckusick static	void readdumptimes __P((FILE *));
4646590Storek 
47*57725Smckusick #ifdef COMPAT
48*57725Smckusick extern	char *calloc();
49*57725Smckusick #endif
5046590Storek 
5146590Storek void
5246791Smckusick initdumptimes()
531422Sroot {
5428858Smckusick 	FILE *df;
551422Sroot 
5646791Smckusick 	if ((df = fopen(dumpdates, "r")) == NULL) {
5750493Smckusick 		if (errno != ENOENT) {
5850493Smckusick 			quit("cannot read %s: %s\n", dumpdates,
5950493Smckusick 			    strerror(errno));
6050493Smckusick 			/* NOTREACHED */
6146590Storek 		}
6250493Smckusick 		/*
6350493Smckusick 		 * Dumpdates does not exist, make an empty one.
6450493Smckusick 		 */
6550493Smckusick 		msg("WARNING: no file `%s', making an empty one\n", dumpdates);
6650493Smckusick 		if ((df = fopen(dumpdates, "w")) == NULL) {
6750493Smckusick 			quit("cannot create %s: %s\n", dumpdates,
6850493Smckusick 			    strerror(errno));
6950493Smckusick 			/* NOTREACHED */
7050493Smckusick 		}
7150493Smckusick 		(void) fclose(df);
7250493Smckusick 		if ((df = fopen(dumpdates, "r")) == NULL) {
7350493Smckusick 			quit("cannot read %s even after creating it: %s\n",
7450493Smckusick 			    dumpdates, strerror(errno));
7550493Smckusick 			/* NOTREACHED */
7650493Smckusick 		}
7712589Smckusick 	}
7828858Smckusick 	(void) flock(fileno(df), LOCK_SH);
7946791Smckusick 	readdumptimes(df);
8054040Smckusick 	(void) fclose(df);
8128858Smckusick }
8228858Smckusick 
83*57725Smckusick static void
8446791Smckusick readdumptimes(df)
8528858Smckusick 	FILE *df;
8628858Smckusick {
8746791Smckusick 	register int i;
8846791Smckusick 	register struct	dumptime *dtwalk;
8928858Smckusick 
9028858Smckusick 	for (;;) {
9146791Smckusick 		dtwalk = (struct dumptime *)calloc(1, sizeof (struct dumptime));
9246791Smckusick 		if (getrecord(df, &(dtwalk->dt_value)) < 0)
9328858Smckusick 			break;
9446791Smckusick 		nddates++;
9546791Smckusick 		dtwalk->dt_next = dthead;
9646791Smckusick 		dthead = dtwalk;
971422Sroot 	}
981422Sroot 
9946791Smckusick 	ddates_in = 1;
1001422Sroot 	/*
1011422Sroot 	 *	arrayify the list, leaving enough room for the additional
10246791Smckusick 	 *	record that we may have to add to the ddate structure
1031422Sroot 	 */
10446791Smckusick 	ddatev = (struct dumpdates **)
10554040Smckusick 		calloc((unsigned) (nddates + 1), sizeof (struct dumpdates *));
10646791Smckusick 	dtwalk = dthead;
10746791Smckusick 	for (i = nddates - 1; i >= 0; i--, dtwalk = dtwalk->dt_next)
10846791Smckusick 		ddatev[i] = &dtwalk->dt_value;
1091422Sroot }
1101422Sroot 
11146590Storek void
11246791Smckusick getdumptime()
1131422Sroot {
11446791Smckusick 	register struct dumpdates *ddp;
11546791Smckusick 	register int i;
11646791Smckusick 	char *fname;
1171422Sroot 
1181422Sroot 	fname = disk;
1191422Sroot #ifdef FDEBUG
12046791Smckusick 	msg("Looking for name %s in dumpdates = %s for level = %c\n",
12146791Smckusick 		fname, dumpdates, level);
1221422Sroot #endif
1231422Sroot 	spcl.c_ddate = 0;
12446791Smckusick 	lastlevel = '0';
1251422Sroot 
12646791Smckusick 	initdumptimes();
1271422Sroot 	/*
1281422Sroot 	 *	Go find the entry with the same name for a lower increment
1291422Sroot 	 *	and older date
1301422Sroot 	 */
13146791Smckusick 	ITITERATE(i, ddp) {
13246791Smckusick 		if (strncmp(fname, ddp->dd_name, sizeof (ddp->dd_name)) != 0)
1331422Sroot 			continue;
13446791Smckusick 		if (ddp->dd_level >= level)
1351422Sroot 			continue;
13646791Smckusick 		if (ddp->dd_ddate <= spcl.c_ddate)
1371422Sroot 			continue;
13846791Smckusick 		spcl.c_ddate = ddp->dd_ddate;
13946791Smckusick 		lastlevel = ddp->dd_level;
14028858Smckusick 	}
1411422Sroot }
1421422Sroot 
14346590Storek void
14446791Smckusick putdumptime()
1451422Sroot {
14646791Smckusick 	FILE *df;
14746791Smckusick 	register struct dumpdates *dtwalk;
14846791Smckusick 	register int i;
14946791Smckusick 	int fd;
15046791Smckusick 	char *fname;
1511422Sroot 
1521422Sroot 	if(uflag == 0)
1531422Sroot 		return;
15446791Smckusick 	if ((df = fopen(dumpdates, "r+")) == NULL)
15546791Smckusick 		quit("cannot rewrite %s: %s\n", dumpdates, strerror(errno));
15628858Smckusick 	fd = fileno(df);
15713151Ssam 	(void) flock(fd, LOCK_EX);
1581422Sroot 	fname = disk;
15954040Smckusick 	free((char *)ddatev);
16046791Smckusick 	ddatev = 0;
16146791Smckusick 	nddates = 0;
16246791Smckusick 	dthead = 0;
16346791Smckusick 	ddates_in = 0;
16446791Smckusick 	readdumptimes(df);
16546590Storek 	if (fseek(df, 0L, 0) < 0)
16646590Storek 		quit("fseek: %s\n", strerror(errno));
1671422Sroot 	spcl.c_ddate = 0;
16846791Smckusick 	ITITERATE(i, dtwalk) {
16946791Smckusick 		if (strncmp(fname, dtwalk->dd_name,
17046791Smckusick 				sizeof (dtwalk->dd_name)) != 0)
1711422Sroot 			continue;
17246791Smckusick 		if (dtwalk->dd_level != level)
1731422Sroot 			continue;
1741422Sroot 		goto found;
1751422Sroot 	}
1761422Sroot 	/*
1771422Sroot 	 *	construct the new upper bound;
1781422Sroot 	 *	Enough room has been allocated.
1791422Sroot 	 */
18046791Smckusick 	dtwalk = ddatev[nddates] =
18152847Sleres 		(struct dumpdates *)calloc(1, sizeof (struct dumpdates));
18246791Smckusick 	nddates += 1;
1831422Sroot   found:
18446791Smckusick 	(void) strncpy(dtwalk->dd_name, fname, sizeof (dtwalk->dd_name));
18546791Smckusick 	dtwalk->dd_level = level;
18646791Smckusick 	dtwalk->dd_ddate = spcl.c_date;
1871422Sroot 
18846791Smckusick 	ITITERATE(i, dtwalk) {
18946791Smckusick 		dumprecout(df, dtwalk);
1901422Sroot 	}
19146590Storek 	if (fflush(df))
19246791Smckusick 		quit("%s: %s\n", dumpdates, strerror(errno));
19346590Storek 	if (ftruncate(fd, ftell(df)))
19446791Smckusick 		quit("ftruncate (%s): %s\n", dumpdates, strerror(errno));
19512589Smckusick 	(void) fclose(df);
19646791Smckusick 	msg("level %c dump on %s", level,
19746791Smckusick 		spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
1981422Sroot }
1991422Sroot 
20046590Storek static void
20146791Smckusick dumprecout(file, what)
20246791Smckusick 	FILE *file;
20346791Smckusick 	struct dumpdates *what;
2041422Sroot {
20546590Storek 
20646590Storek 	if (fprintf(file, DUMPOUTFMT,
20746791Smckusick 		    what->dd_name,
20846791Smckusick 		    what->dd_level,
20946791Smckusick 		    ctime(&what->dd_ddate)) < 0)
21046791Smckusick 		quit("%s: %s\n", dumpdates, strerror(errno));
2111422Sroot }
2121422Sroot 
2131422Sroot int	recno;
214*57725Smckusick 
215*57725Smckusick static int
21646791Smckusick getrecord(df, ddatep)
21746791Smckusick 	FILE *df;
21846791Smckusick 	struct dumpdates *ddatep;
2191422Sroot {
22052846Sleres 	char tbuf[BUFSIZ];
2211422Sroot 
2221422Sroot 	recno = 0;
22352847Sleres 	if ( (fgets(tbuf, sizeof (tbuf), df)) != tbuf)
2241422Sroot 		return(-1);
2251422Sroot 	recno++;
22652846Sleres 	if (makedumpdate(ddatep, tbuf) < 0)
2271422Sroot 		msg("Unknown intermediate format in %s, line %d\n",
22846791Smckusick 			dumpdates, recno);
2291422Sroot 
2301422Sroot #ifdef FDEBUG
23146791Smckusick 	msg("getrecord: %s %c %s", ddatep->dd_name, ddatep->dd_level,
23246791Smckusick 	    ddatep->dd_ddate == 0 ? "the epoch\n" : ctime(&ddatep->dd_ddate));
2331422Sroot #endif
2341422Sroot 	return(0);
2351422Sroot }
2361422Sroot 
237*57725Smckusick static int
23852846Sleres makedumpdate(ddp, tbuf)
23946791Smckusick 	struct dumpdates *ddp;
24052846Sleres 	char *tbuf;
2411422Sroot {
24246791Smckusick 	char un_buf[128];
2431422Sroot 
24454040Smckusick 	(void) sscanf(tbuf, DUMPINFMT, ddp->dd_name, &ddp->dd_level, un_buf);
24546791Smckusick 	ddp->dd_ddate = unctime(un_buf);
24646791Smckusick 	if (ddp->dd_ddate < 0)
2471422Sroot 		return(-1);
2481422Sroot 	return(0);
2491422Sroot }
250