fixed setjmp/longjmp to save/restore the floating point masks (control word)
[unix-history] / sbin / dump / dumpitime.c
CommitLineData
15637ed4
RG
1/*-
2 * Copyright (c) 1980 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)dumpitime.c 5.7 (Berkeley) 3/7/91";
b16a1b0e 36static char rcsid[] = "$Header: /b/source/CVS/src/sbin/dump/dumpitime.c,v 1.3 1993/03/23 00:27:05 cgd Exp $";
15637ed4
RG
37#endif /* not lint */
38
39#include <sys/param.h>
40#include <ufs/dir.h>
41#include <ufs/dinode.h>
42#include <fcntl.h>
43#include <protocols/dumprestore.h>
44#include <errno.h>
45#include <stdio.h>
46#ifdef __STDC__
47#include <time.h>
48#include <unistd.h>
49#include <stdlib.h>
50#include <string.h>
51#endif
52#include "dump.h"
53
54struct dumpdates **ddatev = 0;
55int nddates = 0;
56int ddates_in = 0;
57struct dumptime *dthead = 0;
58
59void readdumptimes();
60int getrecord();
61int makedumpdate();
62
63static void dumprecout();
64
65void
66initdumptimes()
67{
68 FILE *df;
69
70 if ((df = fopen(dumpdates, "r")) == NULL) {
71 if (errno == ENOENT) {
72 msg("WARNING: no file `%s'\n", dumpdates);
73 return;
74 }
75 quit("cannot read %s: %s\n", dumpdates, strerror(errno));
76 /* NOTREACHED */
77 }
78 (void) flock(fileno(df), LOCK_SH);
79 readdumptimes(df);
80 fclose(df);
81}
82
83void
84readdumptimes(df)
85 FILE *df;
86{
87 register int i;
88 register struct dumptime *dtwalk;
89
90 for (;;) {
91 dtwalk = (struct dumptime *)calloc(1, sizeof (struct dumptime));
92 if (getrecord(df, &(dtwalk->dt_value)) < 0)
93 break;
94 nddates++;
95 dtwalk->dt_next = dthead;
96 dthead = dtwalk;
97 }
98
99 ddates_in = 1;
100 /*
101 * arrayify the list, leaving enough room for the additional
102 * record that we may have to add to the ddate structure
103 */
104 ddatev = (struct dumpdates **)
105 calloc(nddates + 1, sizeof (struct dumpdates *));
106 dtwalk = dthead;
107 for (i = nddates - 1; i >= 0; i--, dtwalk = dtwalk->dt_next)
108 ddatev[i] = &dtwalk->dt_value;
109}
110
111void
112getdumptime()
113{
114 register struct dumpdates *ddp;
115 register int i;
116 char *fname;
117
118 fname = disk;
119#ifdef FDEBUG
120 msg("Looking for name %s in dumpdates = %s for level = %c\n",
121 fname, dumpdates, level);
122#endif
123 spcl.c_ddate = 0;
124 lastlevel = '0';
125
126 initdumptimes();
127 /*
128 * Go find the entry with the same name for a lower increment
129 * and older date
130 */
131 ITITERATE(i, ddp) {
132 if (strncmp(fname, ddp->dd_name, sizeof (ddp->dd_name)) != 0)
133 continue;
134 if (ddp->dd_level >= level)
135 continue;
136 if (ddp->dd_ddate <= spcl.c_ddate)
137 continue;
138 spcl.c_ddate = ddp->dd_ddate;
139 lastlevel = ddp->dd_level;
140 }
141}
142
143void
144putdumptime()
145{
146 FILE *df;
147 register struct dumpdates *dtwalk;
148 register int i;
149 int fd;
150 char *fname;
151
152 if(uflag == 0)
153 return;
154 if ((df = fopen(dumpdates, "r+")) == NULL)
155 quit("cannot rewrite %s: %s\n", dumpdates, strerror(errno));
156 fd = fileno(df);
157 (void) flock(fd, LOCK_EX);
158 fname = disk;
159 free(ddatev);
160 ddatev = 0;
161 nddates = 0;
162 dthead = 0;
163 ddates_in = 0;
164 readdumptimes(df);
165 if (fseek(df, 0L, 0) < 0)
166 quit("fseek: %s\n", strerror(errno));
167 spcl.c_ddate = 0;
168 ITITERATE(i, dtwalk) {
169 if (strncmp(fname, dtwalk->dd_name,
170 sizeof (dtwalk->dd_name)) != 0)
171 continue;
172 if (dtwalk->dd_level != level)
173 continue;
174 goto found;
175 }
176 /*
177 * construct the new upper bound;
178 * Enough room has been allocated.
179 */
180 dtwalk = ddatev[nddates] =
181 (struct dumpdates *)calloc(1, sizeof(struct dumpdates));
182 nddates += 1;
183 found:
184 (void) strncpy(dtwalk->dd_name, fname, sizeof (dtwalk->dd_name));
185 dtwalk->dd_level = level;
186 dtwalk->dd_ddate = spcl.c_date;
187
188 ITITERATE(i, dtwalk) {
189 dumprecout(df, dtwalk);
190 }
191 if (fflush(df))
192 quit("%s: %s\n", dumpdates, strerror(errno));
193 if (ftruncate(fd, ftell(df)))
194 quit("ftruncate (%s): %s\n", dumpdates, strerror(errno));
195 (void) fclose(df);
196 msg("level %c dump on %s", level,
197 spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
198}
199
200static void
201dumprecout(file, what)
202 FILE *file;
203 struct dumpdates *what;
204{
205
206 if (fprintf(file, DUMPOUTFMT,
207 what->dd_name,
208 what->dd_level,
209 ctime(&what->dd_ddate)) < 0)
210 quit("%s: %s\n", dumpdates, strerror(errno));
211}
212
213int recno;
214int
215getrecord(df, ddatep)
216 FILE *df;
217 struct dumpdates *ddatep;
218{
219 char buf[BUFSIZ];
220
221 recno = 0;
222 if ( (fgets(buf, BUFSIZ, df)) != buf)
223 return(-1);
224 recno++;
225 if (makedumpdate(ddatep, buf) < 0)
226 msg("Unknown intermediate format in %s, line %d\n",
227 dumpdates, recno);
228
229#ifdef FDEBUG
230 msg("getrecord: %s %c %s", ddatep->dd_name, ddatep->dd_level,
231 ddatep->dd_ddate == 0 ? "the epoch\n" : ctime(&ddatep->dd_ddate));
232#endif
233 return(0);
234}
235
236time_t unctime();
237
238int
239makedumpdate(ddp, buf)
240 struct dumpdates *ddp;
241 char *buf;
242{
243 char un_buf[128];
244
245 sscanf(buf, DUMPINFMT, ddp->dd_name, &ddp->dd_level, un_buf);
246 ddp->dd_ddate = unctime(un_buf);
247 if (ddp->dd_ddate < 0)
248 return(-1);
249 return(0);
250}