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