xref: /original-bsd/sbin/dump/itime.c (revision 39c8fdd5)
1 static	char *sccsid = "@(#)itime.c	1.13 (Berkeley) 03/28/84";
2 
3 #include "dump.h"
4 #include <sys/file.h>
5 
6 char *prdate(d)
7 	time_t d;
8 {
9 	char *p;
10 
11 	if(d == 0)
12 		return("the epoch");
13 	p = ctime(&d);
14 	p[24] = 0;
15 	return(p);
16 }
17 
18 struct	idates	**idatev = 0;
19 int	nidates = 0;
20 int	idates_in = 0;
21 struct	itime	*ithead = 0;
22 
23 inititimes()
24 {
25 			FILE	*df;
26 	register	int	i;
27 	register	struct	itime	*itwalk;
28 			int fd;
29 
30 	if (idates_in)
31 		return;
32 	fd = open(increm, O_RDONLY);
33 	if (fd < 0) {
34 		perror(increm);
35 		return;
36 	}
37 	(void) flock(fd, LOCK_SH);
38 	if ((df = fdopen(fd, "r")) == NULL) {
39 		nidates = 0;
40 		ithead = 0;
41 	} else {
42 		do{
43 			itwalk=(struct itime *)calloc(1,sizeof (struct itime));
44 			if (getrecord(df, &(itwalk->it_value)) < 0)
45 				break;
46 			nidates++;
47 			itwalk->it_next = ithead;
48 			ithead = itwalk;
49 		} while (1);
50 		fclose(df);
51 	}
52 
53 	idates_in = 1;
54 	/*
55 	 *	arrayify the list, leaving enough room for the additional
56 	 *	record that we may have to add to the idate structure
57 	 */
58 	idatev = (struct idates **)calloc(nidates + 1,sizeof (struct idates *));
59 	for (i = nidates-1, itwalk = ithead; i >= 0; i--, itwalk = itwalk->it_next)
60 		idatev[i] = &itwalk->it_value;
61 }
62 
63 getitime()
64 {
65 	register	struct	idates	*ip;
66 	register	int	i;
67 			char	*fname;
68 
69 	fname = disk;
70 #ifdef FDEBUG
71 	msg("Looking for name %s in increm = %s for delta = %c\n",
72 		fname, increm, incno);
73 #endif
74 	spcl.c_ddate = 0;
75 	lastincno = '0';
76 
77 	inititimes();
78 	/*
79 	 *	Go find the entry with the same name for a lower increment
80 	 *	and older date
81 	 */
82 	ITITERATE(i, ip){
83 		if(strncmp(fname, ip->id_name,
84 				sizeof (ip->id_name)) != 0)
85 			continue;
86 		if (ip->id_incno >= incno)
87 			continue;
88 		if (ip->id_ddate <= spcl.c_ddate)
89 			continue;
90 		spcl.c_ddate = ip->id_ddate;
91  		lastincno = ip->id_incno;
92 	}
93 }
94 
95 putitime()
96 {
97 	FILE		*df;
98 	register	struct	idates	*itwalk;
99 	register	int	i;
100 	int		fd;
101 	char		*fname;
102 
103 	if(uflag == 0)
104 		return;
105 	fd = open(temp, O_RDWR|O_CREAT, 0600);
106 	if (fd < 0) {
107 		perror(temp);
108 		dumpabort();
109 	}
110 	(void) flock(fd, LOCK_EX);
111 	if ((df = fdopen(fd, "w")) == NULL) {
112 		perror(temp);
113 		dumpabort();
114 	}
115 	fname = disk;
116 	free(idatev);
117 	idatev = 0;
118 	nidates = 0;
119 	ithead = 0;
120 	idates_in = 0;
121 	inititimes();
122 
123 	spcl.c_ddate = 0;
124 	ITITERATE(i, itwalk){
125 		if (strncmp(fname, itwalk->id_name,
126 				sizeof (itwalk->id_name)) != 0)
127 			continue;
128 		if (itwalk->id_incno != incno)
129 			continue;
130 		goto found;
131 	}
132 	/*
133 	 *	construct the new upper bound;
134 	 *	Enough room has been allocated.
135 	 */
136 	itwalk = idatev[nidates] =
137 		(struct idates *)calloc(1, sizeof(struct idates));
138 	nidates += 1;
139   found:
140 	strncpy(itwalk->id_name, fname, sizeof (itwalk->id_name));
141 	itwalk->id_incno = incno;
142 	itwalk->id_ddate = spcl.c_date;
143 
144 	ITITERATE(i, itwalk){
145 		recout(df, itwalk);
146 	}
147 	if (rename(temp, increm) < 0) {
148 		perror("rename");
149 		(void) unlink(temp);
150 		dumpabort();
151 	}
152 	(void) chmod(increm, 0644);
153 	(void) fclose(df);
154 	msg("level %c dump on %s\n", incno, prdate(spcl.c_date));
155 }
156 
157 recout(file, what)
158 	FILE	*file;
159 	struct	idates	*what;
160 {
161 	fprintf(file, DUMPOUTFMT,
162 		what->id_name,
163 		what->id_incno,
164 		ctime(&(what->id_ddate))
165 	);
166 }
167 
168 int	recno;
169 int getrecord(df, idatep)
170 	FILE	*df;
171 	struct	idates	*idatep;
172 {
173 	char		buf[BUFSIZ];
174 
175 	recno = 0;
176 	if ( (fgets(buf, BUFSIZ, df)) != buf)
177 		return(-1);
178 	recno++;
179 	if (makeidate(idatep, buf) < 0)
180 		msg("Unknown intermediate format in %s, line %d\n",
181 			increm, recno);
182 
183 #ifdef FDEBUG
184 	msg("getrecord: %s %c %s\n",
185 		idatep->id_name, idatep->id_incno, prdate(idatep->id_ddate));
186 #endif
187 	return(0);
188 }
189 
190 time_t	unctime();
191 
192 int makeidate(ip, buf)
193 	struct	idates	*ip;
194 	char	*buf;
195 {
196 	char	un_buf[128];
197 
198 	sscanf(buf, DUMPINFMT, ip->id_name, &ip->id_incno, un_buf);
199 	ip->id_ddate = unctime(un_buf);
200 	if (ip->id_ddate < 0)
201 		return(-1);
202 	return(0);
203 }
204 
205 /*
206  * This is an estimation of the number of TP_BSIZE blocks in the file.
207  * It estimates the number of blocks in files with holes by assuming
208  * that all of the blocks accounted for by di_blocks are data blocks
209  * (when some of the blocks are usually used for indirect pointers);
210  * hence the estimate may be high.
211  */
212 est(ip)
213 	struct dinode *ip;
214 {
215 	long s, t;
216 
217  	/*
218  	 * ip->di_size is the size of the file in bytes.
219  	 * ip->di_blocks stores the number of sectors actually in the file.
220  	 * If there are more sectors than the size would indicate, this just
221  	 *	means that there are indirect blocks in the file or unused
222 	 *	sectors in the last file block;	we can safely ignore these
223 	 *	(s = t below).
224  	 * If the file is bigger than the number of sectors would indicate,
225  	 *	then the file has holes in it.  In this case we must use the
226  	 *	block count to estimate the number of data blocks used, but
227  	 *	we use the actual size for estimating the number of indirect
228  	 *	dump blocks (t vs. s in the indirect block calculation).
229  	 */
230 	esize++;
231  	s = howmany(dbtob(ip->di_blocks), TP_BSIZE);
232  	t = howmany(ip->di_size, TP_BSIZE);
233  	if ( s > t )
234  		s = t;
235 	if (ip->di_size > sblock->fs_bsize * NDADDR) {
236 		/* calculate the number of indirect blocks on the dump tape */
237 		s += howmany(t - NDADDR * sblock->fs_bsize / TP_BSIZE,
238 			TP_NINDIR);
239 	}
240 	esize += s;
241 }
242 
243 bmapest(map)
244 	char *map;
245 {
246 	register i, n;
247 
248 	n = -1;
249 	for (i = 0; i < msiz; i++)
250 		if(map[i])
251 			n = i;
252 	if(n < 0)
253 		return;
254 	n++;
255 	esize++;
256 	esize += howmany(n * sizeof map[0], TP_BSIZE);
257 }
258