have formatted logical read check for errors.
[unix-history] / usr / src / sbin / dump / itime.c
CommitLineData
e6acd2be 1static char *sccsid = "@(#)itime.c 1.13 (Berkeley) %G%";
51e45c89 2
31dd475e 3#include "dump.h"
51e45c89 4#include <sys/file.h>
31dd475e
BJ
5
6char *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
18struct idates **idatev = 0;
19int nidates = 0;
20int idates_in = 0;
21struct itime *ithead = 0;
22
23inititimes()
24{
25 FILE *df;
26 register int i;
27 register struct itime *itwalk;
51e45c89 28 int fd;
31dd475e
BJ
29
30 if (idates_in)
31 return;
7160eaec
SL
32 fd = open(increm, O_RDONLY);
33 if (fd < 0) {
51e45c89
KM
34 perror(increm);
35 return;
36 }
7160eaec 37 (void) flock(fd, LOCK_SH);
51e45c89 38 if ((df = fdopen(fd, "r")) == NULL) {
31dd475e
BJ
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
63getitime()
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;
dcd492fb 75 lastincno = '0';
31dd475e
BJ
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;
c02e5137 91 lastincno = ip->id_incno;
31dd475e
BJ
92 }
93}
94
95putitime()
96{
97 FILE *df;
98 register struct idates *itwalk;
99 register int i;
51e45c89 100 int fd;
31dd475e
BJ
101 char *fname;
102
103 if(uflag == 0)
104 return;
7160eaec
SL
105 fd = open(temp, O_RDWR|O_CREAT, 0600);
106 if (fd < 0) {
51e45c89
KM
107 perror(temp);
108 dumpabort();
109 }
7160eaec 110 (void) flock(fd, LOCK_EX);
51e45c89
KM
111 if ((df = fdopen(fd, "w")) == NULL) {
112 perror(temp);
113 dumpabort();
114 }
31dd475e 115 fname = disk;
9dcdb908
KM
116 free(idatev);
117 idatev = 0;
118 nidates = 0;
119 ithead = 0;
120 idates_in = 0;
121 inititimes();
31dd475e
BJ
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
31dd475e
BJ
144 ITITERATE(i, itwalk){
145 recout(df, itwalk);
146 }
51e45c89
KM
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);
31dd475e
BJ
154 msg("level %c dump on %s\n", incno, prdate(spcl.c_date));
155}
156
157recout(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
168int recno;
169int 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",
51e45c89 181 increm, recno);
31dd475e
BJ
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
31dd475e
BJ
190time_t unctime();
191
192int 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
003a2a9e 205/*
b6407c9d 206 * This is an estimation of the number of TP_BSIZE blocks in the file.
e6acd2be
KM
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.
003a2a9e 211 */
31dd475e
BJ
212est(ip)
213 struct dinode *ip;
214{
e6acd2be 215 long s, t;
31dd475e 216
e6acd2be
KM
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 */
31dd475e 230 esize++;
e6acd2be
KM
231 s = howmany(dbtob(ip->di_blocks), TP_BSIZE);
232 t = howmany(ip->di_size, TP_BSIZE);
233 if ( s > t )
234 s = t;
b6407c9d 235 if (ip->di_size > sblock->fs_bsize * NDADDR) {
e6acd2be
KM
236 /* calculate the number of indirect blocks on the dump tape */
237 s += howmany(t - NDADDR * sblock->fs_bsize / TP_BSIZE,
b6407c9d 238 TP_NINDIR);
31dd475e 239 }
b6407c9d 240 esize += s;
31dd475e
BJ
241}
242
243bmapest(map)
b6407c9d 244 char *map;
31dd475e
BJ
245{
246 register i, n;
247
248 n = -1;
b6407c9d 249 for (i = 0; i < msiz; i++)
31dd475e
BJ
250 if(map[i])
251 n = i;
252 if(n < 0)
253 return;
b6407c9d 254 n++;
31dd475e 255 esize++;
b6407c9d 256 esize += howmany(n * sizeof map[0], TP_BSIZE);
31dd475e 257}