xref: /original-bsd/sbin/dump/itime.c (revision 3708840b)
1 static	char *sccsid = "@(#)itime.c	1.9 (Berkeley) 05/19/83";
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 	if ((fd = open(increm, FSHLOCK|FRDONLY, 0600)) < 0) {
33 		perror(increm);
34 		return;
35 	}
36 	if ((df = fdopen(fd, "r")) == NULL) {
37 		nidates = 0;
38 		ithead = 0;
39 	} else {
40 		do{
41 			itwalk=(struct itime *)calloc(1,sizeof (struct itime));
42 			if (getrecord(df, &(itwalk->it_value)) < 0)
43 				break;
44 			nidates++;
45 			itwalk->it_next = ithead;
46 			ithead = itwalk;
47 		} while (1);
48 		fclose(df);
49 	}
50 
51 	idates_in = 1;
52 	/*
53 	 *	arrayify the list, leaving enough room for the additional
54 	 *	record that we may have to add to the idate structure
55 	 */
56 	idatev = (struct idates **)calloc(nidates + 1,sizeof (struct idates *));
57 	for (i = nidates-1, itwalk = ithead; i >= 0; i--, itwalk = itwalk->it_next)
58 		idatev[i] = &itwalk->it_value;
59 }
60 
61 getitime()
62 {
63 	register	struct	idates	*ip;
64 	register	int	i;
65 			char	*fname;
66 
67 	fname = disk;
68 #ifdef FDEBUG
69 	msg("Looking for name %s in increm = %s for delta = %c\n",
70 		fname, increm, incno);
71 #endif
72 	spcl.c_ddate = 0;
73 
74 	inititimes();
75 	/*
76 	 *	Go find the entry with the same name for a lower increment
77 	 *	and older date
78 	 */
79 	ITITERATE(i, ip){
80 		if(strncmp(fname, ip->id_name,
81 				sizeof (ip->id_name)) != 0)
82 			continue;
83 		if (ip->id_incno >= incno)
84 			continue;
85 		if (ip->id_ddate <= spcl.c_ddate)
86 			continue;
87 		spcl.c_ddate = ip->id_ddate;
88 	}
89 }
90 
91 putitime()
92 {
93 	FILE		*df;
94 	register	struct	idates	*itwalk;
95 	register	int	i;
96 	int		fd;
97 	char		*fname;
98 
99 	if(uflag == 0)
100 		return;
101 	if ((fd = open(temp, FCREATE|FEXLOCK|FRDWR, 0600)) < 0) {
102 		perror(temp);
103 		dumpabort();
104 	}
105 	if ((df = fdopen(fd, "w")) == NULL) {
106 		perror(temp);
107 		dumpabort();
108 	}
109 	fname = disk;
110 	free(idatev);
111 	idatev = 0;
112 	nidates = 0;
113 	ithead = 0;
114 	idates_in = 0;
115 	inititimes();
116 
117 	spcl.c_ddate = 0;
118 	ITITERATE(i, itwalk){
119 		if (strncmp(fname, itwalk->id_name,
120 				sizeof (itwalk->id_name)) != 0)
121 			continue;
122 		if (itwalk->id_incno != incno)
123 			continue;
124 		goto found;
125 	}
126 	/*
127 	 *	construct the new upper bound;
128 	 *	Enough room has been allocated.
129 	 */
130 	itwalk = idatev[nidates] =
131 		(struct idates *)calloc(1, sizeof(struct idates));
132 	nidates += 1;
133   found:
134 	strncpy(itwalk->id_name, fname, sizeof (itwalk->id_name));
135 	itwalk->id_incno = incno;
136 	itwalk->id_ddate = spcl.c_date;
137 
138 	ITITERATE(i, itwalk){
139 		recout(df, itwalk);
140 	}
141 	if (rename(temp, increm) < 0) {
142 		perror("rename");
143 		(void) unlink(temp);
144 		dumpabort();
145 	}
146 	(void) chmod(increm, 0644);
147 	(void) fclose(df);
148 	msg("level %c dump on %s\n", incno, prdate(spcl.c_date));
149 }
150 
151 recout(file, what)
152 	FILE	*file;
153 	struct	idates	*what;
154 {
155 	fprintf(file, DUMPOUTFMT,
156 		what->id_name,
157 		what->id_incno,
158 		ctime(&(what->id_ddate))
159 	);
160 }
161 
162 int	recno;
163 int getrecord(df, idatep)
164 	FILE	*df;
165 	struct	idates	*idatep;
166 {
167 	char		buf[BUFSIZ];
168 
169 	recno = 0;
170 	if ( (fgets(buf, BUFSIZ, df)) != buf)
171 		return(-1);
172 	recno++;
173 	if (makeidate(idatep, buf) < 0)
174 		msg("Unknown intermediate format in %s, line %d\n",
175 			increm, recno);
176 
177 #ifdef FDEBUG
178 	msg("getrecord: %s %c %s\n",
179 		idatep->id_name, idatep->id_incno, prdate(idatep->id_ddate));
180 #endif
181 	return(0);
182 }
183 
184 time_t	unctime();
185 
186 int makeidate(ip, buf)
187 	struct	idates	*ip;
188 	char	*buf;
189 {
190 	char	un_buf[128];
191 
192 	sscanf(buf, DUMPINFMT, ip->id_name, &ip->id_incno, un_buf);
193 	ip->id_ddate = unctime(un_buf);
194 	if (ip->id_ddate < 0)
195 		return(-1);
196 	return(0);
197 }
198 
199 /*
200  * This is an estimation of the number of TP_BSIZE blocks in the file.
201  * It assumes that there are no unallocated blocks; hence
202  * the estimate may be high
203  */
204 est(ip)
205 	struct dinode *ip;
206 {
207 	long s;
208 
209 	esize++;
210 	/* calc number of TP_BSIZE blocks */
211 	s = howmany(ip->di_size, TP_BSIZE);
212 	if (ip->di_size > sblock->fs_bsize * NDADDR) {
213 		/* calc number of indirect blocks on the dump tape */
214 		s += howmany(s - NDADDR * sblock->fs_bsize / TP_BSIZE,
215 			TP_NINDIR);
216 	}
217 	esize += s;
218 }
219 
220 bmapest(map)
221 	char *map;
222 {
223 	register i, n;
224 
225 	n = -1;
226 	for (i = 0; i < msiz; i++)
227 		if(map[i])
228 			n = i;
229 	if(n < 0)
230 		return;
231 	n++;
232 	esize++;
233 	esize += howmany(n * sizeof map[0], TP_BSIZE);
234 }
235