xref: /csrg-svn/sbin/dump/itime.c (revision 13151)
1*13151Ssam static	char *sccsid = "@(#)itime.c	1.11 (Berkeley) 06/15/83";
212589Smckusick 
31422Sroot #include "dump.h"
412589Smckusick #include <sys/file.h>
51422Sroot 
61422Sroot char *prdate(d)
71422Sroot 	time_t d;
81422Sroot {
91422Sroot 	char *p;
101422Sroot 
111422Sroot 	if(d == 0)
121422Sroot 		return("the epoch");
131422Sroot 	p = ctime(&d);
141422Sroot 	p[24] = 0;
151422Sroot 	return(p);
161422Sroot }
171422Sroot 
181422Sroot struct	idates	**idatev = 0;
191422Sroot int	nidates = 0;
201422Sroot int	idates_in = 0;
211422Sroot struct	itime	*ithead = 0;
221422Sroot 
231422Sroot inititimes()
241422Sroot {
251422Sroot 			FILE	*df;
261422Sroot 	register	int	i;
271422Sroot 	register	struct	itime	*itwalk;
2812589Smckusick 			int fd;
291422Sroot 
301422Sroot 	if (idates_in)
311422Sroot 		return;
32*13151Ssam 	fd = open(increm, O_RDONLY);
33*13151Ssam 	if (fd < 0) {
3412589Smckusick 		perror(increm);
3512589Smckusick 		return;
3612589Smckusick 	}
37*13151Ssam 	(void) flock(fd, LOCK_SH);
3812589Smckusick 	if ((df = fdopen(fd, "r")) == NULL) {
391422Sroot 		nidates = 0;
401422Sroot 		ithead = 0;
411422Sroot 	} else {
421422Sroot 		do{
431422Sroot 			itwalk=(struct itime *)calloc(1,sizeof (struct itime));
441422Sroot 			if (getrecord(df, &(itwalk->it_value)) < 0)
451422Sroot 				break;
461422Sroot 			nidates++;
471422Sroot 			itwalk->it_next = ithead;
481422Sroot 			ithead = itwalk;
491422Sroot 		} while (1);
501422Sroot 		fclose(df);
511422Sroot 	}
521422Sroot 
531422Sroot 	idates_in = 1;
541422Sroot 	/*
551422Sroot 	 *	arrayify the list, leaving enough room for the additional
561422Sroot 	 *	record that we may have to add to the idate structure
571422Sroot 	 */
581422Sroot 	idatev = (struct idates **)calloc(nidates + 1,sizeof (struct idates *));
591422Sroot 	for (i = nidates-1, itwalk = ithead; i >= 0; i--, itwalk = itwalk->it_next)
601422Sroot 		idatev[i] = &itwalk->it_value;
611422Sroot }
621422Sroot 
631422Sroot getitime()
641422Sroot {
651422Sroot 	register	struct	idates	*ip;
661422Sroot 	register	int	i;
671422Sroot 			char	*fname;
681422Sroot 
691422Sroot 	fname = disk;
701422Sroot #ifdef FDEBUG
711422Sroot 	msg("Looking for name %s in increm = %s for delta = %c\n",
721422Sroot 		fname, increm, incno);
731422Sroot #endif
741422Sroot 	spcl.c_ddate = 0;
751422Sroot 
761422Sroot 	inititimes();
771422Sroot 	/*
781422Sroot 	 *	Go find the entry with the same name for a lower increment
791422Sroot 	 *	and older date
801422Sroot 	 */
811422Sroot 	ITITERATE(i, ip){
821422Sroot 		if(strncmp(fname, ip->id_name,
831422Sroot 				sizeof (ip->id_name)) != 0)
841422Sroot 			continue;
851422Sroot 		if (ip->id_incno >= incno)
861422Sroot 			continue;
871422Sroot 		if (ip->id_ddate <= spcl.c_ddate)
881422Sroot 			continue;
891422Sroot 		spcl.c_ddate = ip->id_ddate;
9012947Smckusick  		lastincno = ip->id_incno;
911422Sroot 	}
921422Sroot }
931422Sroot 
941422Sroot putitime()
951422Sroot {
961422Sroot 	FILE		*df;
971422Sroot 	register	struct	idates	*itwalk;
981422Sroot 	register	int	i;
9912589Smckusick 	int		fd;
1001422Sroot 	char		*fname;
1011422Sroot 
1021422Sroot 	if(uflag == 0)
1031422Sroot 		return;
104*13151Ssam 	fd = open(temp, O_RDWR|O_CREAT, 0600);
105*13151Ssam 	if (fd < 0) {
10612589Smckusick 		perror(temp);
10712589Smckusick 		dumpabort();
10812589Smckusick 	}
109*13151Ssam 	(void) flock(fd, LOCK_EX);
11012589Smckusick 	if ((df = fdopen(fd, "w")) == NULL) {
11112589Smckusick 		perror(temp);
11212589Smckusick 		dumpabort();
11312589Smckusick 	}
1141422Sroot 	fname = disk;
11512584Smckusick 	free(idatev);
11612584Smckusick 	idatev = 0;
11712584Smckusick 	nidates = 0;
11812584Smckusick 	ithead = 0;
11912584Smckusick 	idates_in = 0;
12012584Smckusick 	inititimes();
1211422Sroot 
1221422Sroot 	spcl.c_ddate = 0;
1231422Sroot 	ITITERATE(i, itwalk){
1241422Sroot 		if (strncmp(fname, itwalk->id_name,
1251422Sroot 				sizeof (itwalk->id_name)) != 0)
1261422Sroot 			continue;
1271422Sroot 		if (itwalk->id_incno != incno)
1281422Sroot 			continue;
1291422Sroot 		goto found;
1301422Sroot 	}
1311422Sroot 	/*
1321422Sroot 	 *	construct the new upper bound;
1331422Sroot 	 *	Enough room has been allocated.
1341422Sroot 	 */
1351422Sroot 	itwalk = idatev[nidates] =
1361422Sroot 		(struct idates *)calloc(1, sizeof(struct idates));
1371422Sroot 	nidates += 1;
1381422Sroot   found:
1391422Sroot 	strncpy(itwalk->id_name, fname, sizeof (itwalk->id_name));
1401422Sroot 	itwalk->id_incno = incno;
1411422Sroot 	itwalk->id_ddate = spcl.c_date;
1421422Sroot 
1431422Sroot 	ITITERATE(i, itwalk){
1441422Sroot 		recout(df, itwalk);
1451422Sroot 	}
14612589Smckusick 	if (rename(temp, increm) < 0) {
14712589Smckusick 		perror("rename");
14812589Smckusick 		(void) unlink(temp);
14912589Smckusick 		dumpabort();
15012589Smckusick 	}
15112589Smckusick 	(void) chmod(increm, 0644);
15212589Smckusick 	(void) fclose(df);
1531422Sroot 	msg("level %c dump on %s\n", incno, prdate(spcl.c_date));
1541422Sroot }
1551422Sroot 
1561422Sroot recout(file, what)
1571422Sroot 	FILE	*file;
1581422Sroot 	struct	idates	*what;
1591422Sroot {
1601422Sroot 	fprintf(file, DUMPOUTFMT,
1611422Sroot 		what->id_name,
1621422Sroot 		what->id_incno,
1631422Sroot 		ctime(&(what->id_ddate))
1641422Sroot 	);
1651422Sroot }
1661422Sroot 
1671422Sroot int	recno;
1681422Sroot int getrecord(df, idatep)
1691422Sroot 	FILE	*df;
1701422Sroot 	struct	idates	*idatep;
1711422Sroot {
1721422Sroot 	char		buf[BUFSIZ];
1731422Sroot 
1741422Sroot 	recno = 0;
1751422Sroot 	if ( (fgets(buf, BUFSIZ, df)) != buf)
1761422Sroot 		return(-1);
1771422Sroot 	recno++;
1781422Sroot 	if (makeidate(idatep, buf) < 0)
1791422Sroot 		msg("Unknown intermediate format in %s, line %d\n",
18012589Smckusick 			increm, recno);
1811422Sroot 
1821422Sroot #ifdef FDEBUG
1831422Sroot 	msg("getrecord: %s %c %s\n",
1841422Sroot 		idatep->id_name, idatep->id_incno, prdate(idatep->id_ddate));
1851422Sroot #endif
1861422Sroot 	return(0);
1871422Sroot }
1881422Sroot 
1891422Sroot time_t	unctime();
1901422Sroot 
1911422Sroot int makeidate(ip, buf)
1921422Sroot 	struct	idates	*ip;
1931422Sroot 	char	*buf;
1941422Sroot {
1951422Sroot 	char	un_buf[128];
1961422Sroot 
1971422Sroot 	sscanf(buf, DUMPINFMT, ip->id_name, &ip->id_incno, un_buf);
1981422Sroot 	ip->id_ddate = unctime(un_buf);
1991422Sroot 	if (ip->id_ddate < 0)
2001422Sroot 		return(-1);
2011422Sroot 	return(0);
2021422Sroot }
2031422Sroot 
2044701Smckusic /*
2055328Smckusic  * This is an estimation of the number of TP_BSIZE blocks in the file.
2064701Smckusic  * It assumes that there are no unallocated blocks; hence
2074701Smckusic  * the estimate may be high
2084701Smckusic  */
2091422Sroot est(ip)
2101422Sroot 	struct dinode *ip;
2111422Sroot {
2121422Sroot 	long s;
2131422Sroot 
2141422Sroot 	esize++;
2155328Smckusic 	/* calc number of TP_BSIZE blocks */
2169403Smckusick 	s = howmany(ip->di_size, TP_BSIZE);
2175328Smckusic 	if (ip->di_size > sblock->fs_bsize * NDADDR) {
2185328Smckusic 		/* calc number of indirect blocks on the dump tape */
2198536Smckusick 		s += howmany(s - NDADDR * sblock->fs_bsize / TP_BSIZE,
2205328Smckusic 			TP_NINDIR);
2215328Smckusic 	}
2221422Sroot 	esize += s;
2231422Sroot }
2241422Sroot 
2251422Sroot bmapest(map)
2265328Smckusic 	char *map;
2271422Sroot {
2281422Sroot 	register i, n;
2291422Sroot 
2301422Sroot 	n = -1;
2315328Smckusic 	for (i = 0; i < msiz; i++)
2321422Sroot 		if(map[i])
2331422Sroot 			n = i;
2341422Sroot 	if(n < 0)
2351422Sroot 		return;
2365328Smckusic 	n++;
2371422Sroot 	esize++;
2385328Smckusic 	esize += howmany(n * sizeof map[0], TP_BSIZE);
2391422Sroot }
240