2
* Ported to Linux's Second Extended File System as part of the
3
* dump and restore backup suit
4
* Remy Card <card@Linux.EU.Org>, 1994-1997
5
* Stelian Pop <stelian@popies.net>, 1999-2000
6
* Stelian Pop <stelian@popies.net> - Alc�ve <www.alcove.com>, 2000-2002
10
* Copyright (c) 1980, 1993
11
* The Regents of the University of California. All rights reserved.
13
* Redistribution and use in source and binary forms, with or without
14
* modification, are permitted provided that the following conditions
16
* 1. Redistributions of source code must retain the above copyright
17
* notice, this list of conditions and the following disclaimer.
18
* 2. Redistributions in binary form must reproduce the above copyright
19
* notice, this list of conditions and the following disclaimer in the
20
* documentation and/or other materials provided with the distribution.
21
* 3. All advertising materials mentioning features or use of this software
22
* must display the following acknowledgement:
23
* This product includes software developed by the University of
24
* California, Berkeley and its contributors.
25
* 4. Neither the name of the University nor the names of its contributors
26
* may be used to endorse or promote products derived from this software
27
* without specific prior written permission.
29
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43
static const char rcsid[] =
44
"$Id: itime.c,v 1.22 2002/01/25 15:08:59 stelian Exp $";
56
#include <sys/param.h>
60
#ifdef HAVE_EXT2FS_EXT2_FS_H
61
#include <ext2fs/ext2_fs.h>
63
#include <linux/ext2_fs.h>
65
#include <ext2fs/ext2fs.h>
66
#include <bsdcompat.h>
70
#include <sys/vnode.h>
72
#include <ufs/fsdir.h>
73
#include <ufs/inode.h>
76
#include <ufs/ufs/dinode.h>
79
#include <protocols/dumprestore.h>
83
struct dumpdates **ddatev;
86
struct dumptime *dthead;
88
static void dumprecout __P((FILE *, struct dumpdates *));
89
static int getrecord __P((FILE *, struct dumpdates *));
90
static int makedumpdate __P((struct dumpdates *, char *));
91
static void readdumptimes __P((FILE *));
94
initdumptimes(int createdumpdates)
98
if ((df = fopen(dumpdates, "r")) == NULL) {
99
if (errno != ENOENT) {
100
quit("cannot read %s: %s\n", dumpdates,
104
if (createdumpdates) {
106
* Dumpdates does not exist, make an empty one.
108
msg("WARNING: no file `%s', making an empty one\n", dumpdates);
109
if ((df = fopen(dumpdates, "w")) == NULL) {
110
quit("cannot create %s: %s\n", dumpdates,
115
if ((df = fopen(dumpdates, "r")) == NULL) {
116
quit("cannot read %s even after creating it: %s\n",
117
dumpdates, strerror(errno));
122
msg("WARNING: no file `%s'\n", dumpdates);
125
(void) flock(fileno(df), LOCK_SH);
132
readdumptimes(FILE *df)
135
struct dumptime *dtwalk;
138
dtwalk = (struct dumptime *)calloc(1, sizeof (struct dumptime));
139
if (getrecord(df, &(dtwalk->dt_value)) < 0)
142
dtwalk->dt_next = dthead;
148
* arrayify the list, leaving enough room for the additional
149
* record that we may have to add to the ddate structure
151
ddatev = (struct dumpdates **)
152
calloc((unsigned) (nddates + 1), sizeof (struct dumpdates *));
154
for (i = nddates - 1; i >= 0; i--, dtwalk = dtwalk->dt_next)
155
ddatev[i] = &dtwalk->dt_value;
159
getdumptime(int createdumpdates)
161
struct dumpdates *ddp;
165
msg("Looking for name %s in dumpdates = %s for level = %c\n",
166
disk, dumpdates, level);
171
/* If this is a level 0 dump, and we're not updating
172
dumpdates, there's no point in trying to read
173
dumpdates. It may not exist yet, or may not be mounted. For
174
incrementals, we *must* read dumpdates (fail if it's not there!) */
175
if ( (level == lastlevel) && !createdumpdates)
177
initdumptimes(createdumpdates);
181
* Go find the entry with the same name for a lower increment
185
if (strncmp(disk, ddp->dd_name, sizeof (ddp->dd_name)) != 0)
187
if (ddp->dd_level >= level)
189
if (ddp->dd_ddate <= (time_t)spcl.c_ddate)
191
spcl.c_ddate = ddp->dd_ddate;
192
lastlevel = ddp->dd_level;
200
struct dumpdates *dtwalk;
206
if ((df = fopen(dumpdates, "r+")) == NULL)
207
quit("cannot rewrite %s: %s\n", dumpdates, strerror(errno));
209
(void) flock(fd, LOCK_EX);
210
free((char *)ddatev);
216
if (fseek(df, 0L, 0) < 0)
217
quit("fseek: %s\n", strerror(errno));
219
ITITERATE(i, dtwalk) {
220
if (strncmp(disk, dtwalk->dd_name,
221
sizeof (dtwalk->dd_name)) != 0)
223
if (dtwalk->dd_level != level)
228
* construct the new upper bound;
229
* Enough room has been allocated.
231
dtwalk = ddatev[nddates] =
232
(struct dumpdates *)calloc(1, sizeof (struct dumpdates));
235
(void) strncpy(dtwalk->dd_name, disk, sizeof (dtwalk->dd_name));
236
dtwalk->dd_level = level;
237
dtwalk->dd_ddate = spcl.c_date;
239
ITITERATE(i, dtwalk) {
240
dumprecout(df, dtwalk);
243
quit("%s: %s\n", dumpdates, strerror(errno));
244
if (ftruncate(fd, ftell(df)))
245
quit("ftruncate (%s): %s\n", dumpdates, strerror(errno));
250
dumprecout(FILE *file, struct dumpdates *what)
253
if (fprintf(file, "%s %c %s",
256
ctime(&what->dd_ddate)) < 0)
257
quit("%s: %s\n", dumpdates, strerror(errno));
263
getrecord(FILE *df, struct dumpdates *ddatep)
268
if (fgets(tbuf, sizeof (tbuf), df) == NULL)
271
if (makedumpdate(ddatep, tbuf) < 0)
272
msg("Unknown intermediate format in %s, line %d\n",
276
msg("getrecord: %s %c %s", ddatep->dd_name, ddatep->dd_level,
277
ddatep->dd_ddate == 0 ? "the epoch\n" : ctime(&ddatep->dd_ddate));
283
makedumpdate(struct dumpdates *ddp, char *tbuf)
288
if ( NULL == (tok = strsep( &tbuf, " ")) )
290
if ( strlen(tok) > MAXPATHLEN )
292
strcpy(ddp->dd_name, tok);
295
for( ; *tbuf == ' ' ; tbuf++);
298
ddp->dd_level = *tbuf;
302
for( ; *tbuf == ' ' ; tbuf++);
305
ddp->dd_ddate = unctime(tbuf);
306
if (ddp->dd_ddate < 0)
309
ddp->dd_fstab = fstabsearch(ddp->dd_name);