xref: /csrg-svn/sbin/dump/itime.c (revision 46590)
122036Sdist /*
222036Sdist  * Copyright (c) 1980 Regents of the University of California.
322036Sdist  * All rights reserved.  The Berkeley software License Agreement
422036Sdist  * specifies the terms and conditions for redistribution.
522036Sdist  */
612589Smckusick 
722036Sdist #ifndef lint
8*46590Storek static char sccsid[] = "@(#)itime.c	5.4 (Berkeley) 02/23/91";
9*46590Storek #endif /* not lint */
1022036Sdist 
111422Sroot #include "dump.h"
1212589Smckusick #include <sys/file.h>
13*46590Storek #include <errno.h>
141422Sroot 
15*46590Storek char *
16*46590Storek prdate(d)
171422Sroot 	time_t d;
181422Sroot {
191422Sroot 	char *p;
201422Sroot 
211422Sroot 	if(d == 0)
221422Sroot 		return("the epoch");
231422Sroot 	p = ctime(&d);
241422Sroot 	p[24] = 0;
251422Sroot 	return(p);
261422Sroot }
271422Sroot 
281422Sroot struct	idates	**idatev = 0;
291422Sroot int	nidates = 0;
301422Sroot int	idates_in = 0;
311422Sroot struct	itime	*ithead = 0;
321422Sroot 
33*46590Storek void	readitimes();
34*46590Storek int	getrecord();
35*46590Storek int	makeidate();
36*46590Storek 
37*46590Storek static void recout();
38*46590Storek 
39*46590Storek void
401422Sroot inititimes()
411422Sroot {
4228858Smckusick 	FILE *df;
431422Sroot 
4428858Smckusick 	if ((df = fopen(increm, "r")) == NULL) {
45*46590Storek 		if (errno == ENOENT) {
46*46590Storek 			msg("WARNING: no file `%s'\n", increm);
47*46590Storek 			return;
48*46590Storek 		}
49*46590Storek 		quit("cannot read %s: %s\n", increm, strerror(errno));
50*46590Storek 		/* NOTREACHED */
5112589Smckusick 	}
5228858Smckusick 	(void) flock(fileno(df), LOCK_SH);
5328858Smckusick 	readitimes(df);
5428858Smckusick 	fclose(df);
5528858Smckusick }
5628858Smckusick 
57*46590Storek void
5828858Smckusick readitimes(df)
5928858Smckusick 	FILE *df;
6028858Smckusick {
6128858Smckusick 	register	int	i;
6228858Smckusick 	register	struct	itime	*itwalk;
6328858Smckusick 
6428858Smckusick 	for (;;) {
6528858Smckusick 		itwalk = (struct itime *)calloc(1, sizeof (struct itime));
6628858Smckusick 		if (getrecord(df, &(itwalk->it_value)) < 0)
6728858Smckusick 			break;
6828858Smckusick 		nidates++;
6928858Smckusick 		itwalk->it_next = ithead;
7028858Smckusick 		ithead = itwalk;
711422Sroot 	}
721422Sroot 
731422Sroot 	idates_in = 1;
741422Sroot 	/*
751422Sroot 	 *	arrayify the list, leaving enough room for the additional
761422Sroot 	 *	record that we may have to add to the idate structure
771422Sroot 	 */
781422Sroot 	idatev = (struct idates **)calloc(nidates + 1,sizeof (struct idates *));
7928858Smckusick 	itwalk = ithead;
8028858Smckusick 	for (i = nidates - 1; i >= 0; i--, itwalk = itwalk->it_next)
811422Sroot 		idatev[i] = &itwalk->it_value;
821422Sroot }
831422Sroot 
84*46590Storek void
851422Sroot getitime()
861422Sroot {
871422Sroot 	register	struct	idates	*ip;
881422Sroot 	register	int	i;
891422Sroot 			char	*fname;
901422Sroot 
911422Sroot 	fname = disk;
921422Sroot #ifdef FDEBUG
931422Sroot 	msg("Looking for name %s in increm = %s for delta = %c\n",
941422Sroot 		fname, increm, incno);
951422Sroot #endif
961422Sroot 	spcl.c_ddate = 0;
9714964Smckusick 	lastincno = '0';
981422Sroot 
991422Sroot 	inititimes();
1001422Sroot 	/*
1011422Sroot 	 *	Go find the entry with the same name for a lower increment
1021422Sroot 	 *	and older date
1031422Sroot 	 */
10428858Smckusick 	ITITERATE(i, ip) {
10528858Smckusick 		if (strncmp(fname, ip->id_name, sizeof (ip->id_name)) != 0)
1061422Sroot 			continue;
1071422Sroot 		if (ip->id_incno >= incno)
1081422Sroot 			continue;
1091422Sroot 		if (ip->id_ddate <= spcl.c_ddate)
1101422Sroot 			continue;
1111422Sroot 		spcl.c_ddate = ip->id_ddate;
11228858Smckusick 		lastincno = ip->id_incno;
11328858Smckusick 	}
1141422Sroot }
1151422Sroot 
116*46590Storek void
1171422Sroot putitime()
1181422Sroot {
1191422Sroot 	FILE		*df;
1201422Sroot 	register	struct	idates	*itwalk;
1211422Sroot 	register	int	i;
12212589Smckusick 	int		fd;
1231422Sroot 	char		*fname;
1241422Sroot 
1251422Sroot 	if(uflag == 0)
1261422Sroot 		return;
127*46590Storek 	if ((df = fopen(increm, "r+")) == NULL)
128*46590Storek 		quit("cannot rewrite %s: %s\n", increm, strerror(errno));
12928858Smckusick 	fd = fileno(df);
13013151Ssam 	(void) flock(fd, LOCK_EX);
1311422Sroot 	fname = disk;
13212584Smckusick 	free(idatev);
13312584Smckusick 	idatev = 0;
13412584Smckusick 	nidates = 0;
13512584Smckusick 	ithead = 0;
13612584Smckusick 	idates_in = 0;
13728858Smckusick 	readitimes(df);
138*46590Storek 	if (fseek(df, 0L, 0) < 0)
139*46590Storek 		quit("fseek: %s\n", strerror(errno));
1401422Sroot 	spcl.c_ddate = 0;
141*46590Storek 	ITITERATE(i, itwalk) {
1421422Sroot 		if (strncmp(fname, itwalk->id_name,
1431422Sroot 				sizeof (itwalk->id_name)) != 0)
1441422Sroot 			continue;
1451422Sroot 		if (itwalk->id_incno != incno)
1461422Sroot 			continue;
1471422Sroot 		goto found;
1481422Sroot 	}
1491422Sroot 	/*
1501422Sroot 	 *	construct the new upper bound;
1511422Sroot 	 *	Enough room has been allocated.
1521422Sroot 	 */
1531422Sroot 	itwalk = idatev[nidates] =
1541422Sroot 		(struct idates *)calloc(1, sizeof(struct idates));
1551422Sroot 	nidates += 1;
1561422Sroot   found:
157*46590Storek 	(void) strncpy(itwalk->id_name, fname, sizeof (itwalk->id_name));
1581422Sroot 	itwalk->id_incno = incno;
1591422Sroot 	itwalk->id_ddate = spcl.c_date;
1601422Sroot 
161*46590Storek 	ITITERATE(i, itwalk) {
1621422Sroot 		recout(df, itwalk);
1631422Sroot 	}
164*46590Storek 	if (fflush(df))
165*46590Storek 		quit("%s: %s\n", increm, strerror(errno));
166*46590Storek 	if (ftruncate(fd, ftell(df)))
167*46590Storek 		quit("ftruncate (%s): %s\n", increm, strerror(errno));
16812589Smckusick 	(void) fclose(df);
1691422Sroot 	msg("level %c dump on %s\n", incno, prdate(spcl.c_date));
1701422Sroot }
1711422Sroot 
172*46590Storek static void
1731422Sroot recout(file, what)
1741422Sroot 	FILE	*file;
1751422Sroot 	struct	idates	*what;
1761422Sroot {
177*46590Storek 
178*46590Storek 	if (fprintf(file, DUMPOUTFMT,
179*46590Storek 		    what->id_name,
180*46590Storek 		    what->id_incno,
181*46590Storek 		    ctime(&what->id_ddate)) < 0)
182*46590Storek 		quit("%s: %s\n", increm, strerror(errno));
1831422Sroot }
1841422Sroot 
1851422Sroot int	recno;
186*46590Storek int
187*46590Storek getrecord(df, idatep)
1881422Sroot 	FILE	*df;
1891422Sroot 	struct	idates	*idatep;
1901422Sroot {
1911422Sroot 	char		buf[BUFSIZ];
1921422Sroot 
1931422Sroot 	recno = 0;
1941422Sroot 	if ( (fgets(buf, BUFSIZ, df)) != buf)
1951422Sroot 		return(-1);
1961422Sroot 	recno++;
1971422Sroot 	if (makeidate(idatep, buf) < 0)
1981422Sroot 		msg("Unknown intermediate format in %s, line %d\n",
19912589Smckusick 			increm, recno);
2001422Sroot 
2011422Sroot #ifdef FDEBUG
2021422Sroot 	msg("getrecord: %s %c %s\n",
2031422Sroot 		idatep->id_name, idatep->id_incno, prdate(idatep->id_ddate));
2041422Sroot #endif
2051422Sroot 	return(0);
2061422Sroot }
2071422Sroot 
2081422Sroot time_t	unctime();
2091422Sroot 
210*46590Storek int
211*46590Storek makeidate(ip, buf)
2121422Sroot 	struct	idates	*ip;
2131422Sroot 	char	*buf;
2141422Sroot {
2151422Sroot 	char	un_buf[128];
2161422Sroot 
2171422Sroot 	sscanf(buf, DUMPINFMT, ip->id_name, &ip->id_incno, un_buf);
2181422Sroot 	ip->id_ddate = unctime(un_buf);
2191422Sroot 	if (ip->id_ddate < 0)
2201422Sroot 		return(-1);
2211422Sroot 	return(0);
2221422Sroot }
223