xref: /csrg-svn/sbin/dump/itime.c (revision 28858)
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*28858Smckusick static char sccsid[] = "@(#)itime.c	5.2 (Berkeley) 05/28/86";
922036Sdist #endif not lint
1022036Sdist 
111422Sroot #include "dump.h"
1212589Smckusick #include <sys/file.h>
131422Sroot 
141422Sroot char *prdate(d)
151422Sroot 	time_t d;
161422Sroot {
171422Sroot 	char *p;
181422Sroot 
191422Sroot 	if(d == 0)
201422Sroot 		return("the epoch");
211422Sroot 	p = ctime(&d);
221422Sroot 	p[24] = 0;
231422Sroot 	return(p);
241422Sroot }
251422Sroot 
261422Sroot struct	idates	**idatev = 0;
271422Sroot int	nidates = 0;
281422Sroot int	idates_in = 0;
291422Sroot struct	itime	*ithead = 0;
301422Sroot 
311422Sroot inititimes()
321422Sroot {
33*28858Smckusick 	FILE *df;
341422Sroot 
35*28858Smckusick 	if ((df = fopen(increm, "r")) == NULL) {
3612589Smckusick 		perror(increm);
3712589Smckusick 		return;
3812589Smckusick 	}
39*28858Smckusick 	(void) flock(fileno(df), LOCK_SH);
40*28858Smckusick 	readitimes(df);
41*28858Smckusick 	fclose(df);
42*28858Smckusick }
43*28858Smckusick 
44*28858Smckusick readitimes(df)
45*28858Smckusick 	FILE *df;
46*28858Smckusick {
47*28858Smckusick 	register	int	i;
48*28858Smckusick 	register	struct	itime	*itwalk;
49*28858Smckusick 
50*28858Smckusick 	for (;;) {
51*28858Smckusick 		itwalk = (struct itime *)calloc(1, sizeof (struct itime));
52*28858Smckusick 		if (getrecord(df, &(itwalk->it_value)) < 0)
53*28858Smckusick 			break;
54*28858Smckusick 		nidates++;
55*28858Smckusick 		itwalk->it_next = ithead;
56*28858Smckusick 		ithead = itwalk;
571422Sroot 	}
581422Sroot 
591422Sroot 	idates_in = 1;
601422Sroot 	/*
611422Sroot 	 *	arrayify the list, leaving enough room for the additional
621422Sroot 	 *	record that we may have to add to the idate structure
631422Sroot 	 */
641422Sroot 	idatev = (struct idates **)calloc(nidates + 1,sizeof (struct idates *));
65*28858Smckusick 	itwalk = ithead;
66*28858Smckusick 	for (i = nidates - 1; i >= 0; i--, itwalk = itwalk->it_next)
671422Sroot 		idatev[i] = &itwalk->it_value;
681422Sroot }
691422Sroot 
701422Sroot getitime()
711422Sroot {
721422Sroot 	register	struct	idates	*ip;
731422Sroot 	register	int	i;
741422Sroot 			char	*fname;
751422Sroot 
761422Sroot 	fname = disk;
771422Sroot #ifdef FDEBUG
781422Sroot 	msg("Looking for name %s in increm = %s for delta = %c\n",
791422Sroot 		fname, increm, incno);
801422Sroot #endif
811422Sroot 	spcl.c_ddate = 0;
8214964Smckusick 	lastincno = '0';
831422Sroot 
841422Sroot 	inititimes();
851422Sroot 	/*
861422Sroot 	 *	Go find the entry with the same name for a lower increment
871422Sroot 	 *	and older date
881422Sroot 	 */
89*28858Smckusick 	ITITERATE(i, ip) {
90*28858Smckusick 		if (strncmp(fname, ip->id_name, sizeof (ip->id_name)) != 0)
911422Sroot 			continue;
921422Sroot 		if (ip->id_incno >= incno)
931422Sroot 			continue;
941422Sroot 		if (ip->id_ddate <= spcl.c_ddate)
951422Sroot 			continue;
961422Sroot 		spcl.c_ddate = ip->id_ddate;
97*28858Smckusick 		lastincno = ip->id_incno;
98*28858Smckusick 	}
991422Sroot }
1001422Sroot 
1011422Sroot putitime()
1021422Sroot {
1031422Sroot 	FILE		*df;
1041422Sroot 	register	struct	idates	*itwalk;
1051422Sroot 	register	int	i;
10612589Smckusick 	int		fd;
1071422Sroot 	char		*fname;
1081422Sroot 
1091422Sroot 	if(uflag == 0)
1101422Sroot 		return;
111*28858Smckusick 	if ((df = fopen(increm, "r+")) == NULL) {
112*28858Smckusick 		perror(increm);
11312589Smckusick 		dumpabort();
11412589Smckusick 	}
115*28858Smckusick 	fd = fileno(df);
11613151Ssam 	(void) flock(fd, LOCK_EX);
1171422Sroot 	fname = disk;
11812584Smckusick 	free(idatev);
11912584Smckusick 	idatev = 0;
12012584Smckusick 	nidates = 0;
12112584Smckusick 	ithead = 0;
12212584Smckusick 	idates_in = 0;
123*28858Smckusick 	readitimes(df);
124*28858Smckusick 	if (fseek(df,0L,0) < 0) {   /* rewind() was redefined in dumptape.c */
125*28858Smckusick 		perror("fseek");
126*28858Smckusick 		dumpabort();
127*28858Smckusick 	}
1281422Sroot 	spcl.c_ddate = 0;
1291422Sroot 	ITITERATE(i, itwalk){
1301422Sroot 		if (strncmp(fname, itwalk->id_name,
1311422Sroot 				sizeof (itwalk->id_name)) != 0)
1321422Sroot 			continue;
1331422Sroot 		if (itwalk->id_incno != incno)
1341422Sroot 			continue;
1351422Sroot 		goto found;
1361422Sroot 	}
1371422Sroot 	/*
1381422Sroot 	 *	construct the new upper bound;
1391422Sroot 	 *	Enough room has been allocated.
1401422Sroot 	 */
1411422Sroot 	itwalk = idatev[nidates] =
1421422Sroot 		(struct idates *)calloc(1, sizeof(struct idates));
1431422Sroot 	nidates += 1;
1441422Sroot   found:
1451422Sroot 	strncpy(itwalk->id_name, fname, sizeof (itwalk->id_name));
1461422Sroot 	itwalk->id_incno = incno;
1471422Sroot 	itwalk->id_ddate = spcl.c_date;
1481422Sroot 
1491422Sroot 	ITITERATE(i, itwalk){
1501422Sroot 		recout(df, itwalk);
1511422Sroot 	}
152*28858Smckusick 	if (ftruncate(fd, ftell(df))) {
153*28858Smckusick 		perror("ftruncate");
15412589Smckusick 		dumpabort();
15512589Smckusick 	}
15612589Smckusick 	(void) fclose(df);
1571422Sroot 	msg("level %c dump on %s\n", incno, prdate(spcl.c_date));
1581422Sroot }
1591422Sroot 
1601422Sroot recout(file, what)
1611422Sroot 	FILE	*file;
1621422Sroot 	struct	idates	*what;
1631422Sroot {
1641422Sroot 	fprintf(file, DUMPOUTFMT,
1651422Sroot 		what->id_name,
1661422Sroot 		what->id_incno,
1671422Sroot 		ctime(&(what->id_ddate))
1681422Sroot 	);
1691422Sroot }
1701422Sroot 
1711422Sroot int	recno;
1721422Sroot int getrecord(df, idatep)
1731422Sroot 	FILE	*df;
1741422Sroot 	struct	idates	*idatep;
1751422Sroot {
1761422Sroot 	char		buf[BUFSIZ];
1771422Sroot 
1781422Sroot 	recno = 0;
1791422Sroot 	if ( (fgets(buf, BUFSIZ, df)) != buf)
1801422Sroot 		return(-1);
1811422Sroot 	recno++;
1821422Sroot 	if (makeidate(idatep, buf) < 0)
1831422Sroot 		msg("Unknown intermediate format in %s, line %d\n",
18412589Smckusick 			increm, recno);
1851422Sroot 
1861422Sroot #ifdef FDEBUG
1871422Sroot 	msg("getrecord: %s %c %s\n",
1881422Sroot 		idatep->id_name, idatep->id_incno, prdate(idatep->id_ddate));
1891422Sroot #endif
1901422Sroot 	return(0);
1911422Sroot }
1921422Sroot 
1931422Sroot time_t	unctime();
1941422Sroot 
1951422Sroot int makeidate(ip, buf)
1961422Sroot 	struct	idates	*ip;
1971422Sroot 	char	*buf;
1981422Sroot {
1991422Sroot 	char	un_buf[128];
2001422Sroot 
2011422Sroot 	sscanf(buf, DUMPINFMT, ip->id_name, &ip->id_incno, un_buf);
2021422Sroot 	ip->id_ddate = unctime(un_buf);
2031422Sroot 	if (ip->id_ddate < 0)
2041422Sroot 		return(-1);
2051422Sroot 	return(0);
2061422Sroot }
2071422Sroot 
2084701Smckusic /*
2095328Smckusic  * This is an estimation of the number of TP_BSIZE blocks in the file.
21016250Smckusick  * It estimates the number of blocks in files with holes by assuming
21116250Smckusick  * that all of the blocks accounted for by di_blocks are data blocks
21216250Smckusick  * (when some of the blocks are usually used for indirect pointers);
21316250Smckusick  * hence the estimate may be high.
2144701Smckusic  */
2151422Sroot est(ip)
2161422Sroot 	struct dinode *ip;
2171422Sroot {
21816250Smckusick 	long s, t;
2191422Sroot 
220*28858Smckusick 	/*
221*28858Smckusick 	 * ip->di_size is the size of the file in bytes.
222*28858Smckusick 	 * ip->di_blocks stores the number of sectors actually in the file.
223*28858Smckusick 	 * If there are more sectors than the size would indicate, this just
224*28858Smckusick 	 *	means that there are indirect blocks in the file or unused
225*28858Smckusick 	 *	sectors in the last file block; we can safely ignore these
22616250Smckusick 	 *	(s = t below).
227*28858Smckusick 	 * If the file is bigger than the number of sectors would indicate,
228*28858Smckusick 	 *	then the file has holes in it.	In this case we must use the
229*28858Smckusick 	 *	block count to estimate the number of data blocks used, but
230*28858Smckusick 	 *	we use the actual size for estimating the number of indirect
231*28858Smckusick 	 *	dump blocks (t vs. s in the indirect block calculation).
232*28858Smckusick 	 */
2331422Sroot 	esize++;
234*28858Smckusick 	s = howmany(dbtob(ip->di_blocks), TP_BSIZE);
235*28858Smckusick 	t = howmany(ip->di_size, TP_BSIZE);
236*28858Smckusick 	if ( s > t )
237*28858Smckusick 		s = t;
2385328Smckusic 	if (ip->di_size > sblock->fs_bsize * NDADDR) {
23916250Smckusick 		/* calculate the number of indirect blocks on the dump tape */
24016250Smckusick 		s += howmany(t - NDADDR * sblock->fs_bsize / TP_BSIZE,
2415328Smckusic 			TP_NINDIR);
2425328Smckusic 	}
2431422Sroot 	esize += s;
2441422Sroot }
2451422Sroot 
2461422Sroot bmapest(map)
2475328Smckusic 	char *map;
2481422Sroot {
2491422Sroot 	register i, n;
2501422Sroot 
2511422Sroot 	n = -1;
2525328Smckusic 	for (i = 0; i < msiz; i++)
2531422Sroot 		if(map[i])
2541422Sroot 			n = i;
2551422Sroot 	if(n < 0)
2561422Sroot 		return;
2575328Smckusic 	n++;
2581422Sroot 	esize++;
2595328Smckusic 	esize += howmany(n * sizeof map[0], TP_BSIZE);
2601422Sroot }
261