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