~ubuntu-branches/ubuntu/natty/dump/natty

« back to all changes in this revision

Viewing changes to dump/itime.c

  • Committer: Bazaar Package Importer
  • Author(s): Bdale Garbee
  • Date: 2002-03-20 01:23:11 UTC
  • Revision ID: james.westby@ubuntu.com-20020320012311-94kbs6nojd19hmd6
Tags: upstream-0.4b27
Import upstream version 0.4b27

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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
 
7
 */
 
8
 
 
9
/*-
 
10
 * Copyright (c) 1980, 1993
 
11
 *      The Regents of the University of California.  All rights reserved.
 
12
 *
 
13
 * Redistribution and use in source and binary forms, with or without
 
14
 * modification, are permitted provided that the following conditions
 
15
 * are met:
 
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.
 
28
 *
 
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
 
39
 * SUCH DAMAGE.
 
40
 */
 
41
 
 
42
#ifndef lint
 
43
static const char rcsid[] =
 
44
        "$Id: itime.c,v 1.22 2002/01/25 15:08:59 stelian Exp $";
 
45
#endif /* not lint */
 
46
 
 
47
#include <config.h>
 
48
#include <errno.h>
 
49
#include <fcntl.h>
 
50
#include <stdio.h>
 
51
#ifdef __STDC__
 
52
#include <stdlib.h>
 
53
#include <string.h>
 
54
#endif
 
55
 
 
56
#include <sys/param.h>
 
57
#include <sys/time.h>
 
58
#include <time.h>
 
59
#ifdef  __linux__
 
60
#ifdef HAVE_EXT2FS_EXT2_FS_H
 
61
#include <ext2fs/ext2_fs.h>
 
62
#else
 
63
#include <linux/ext2_fs.h>
 
64
#endif
 
65
#include <ext2fs/ext2fs.h>
 
66
#include <bsdcompat.h>
 
67
#include <sys/file.h>
 
68
#include <unistd.h>
 
69
#elif defined sunos
 
70
#include <sys/vnode.h>
 
71
 
 
72
#include <ufs/fsdir.h>
 
73
#include <ufs/inode.h>
 
74
#include <ufs/fs.h>
 
75
#else
 
76
#include <ufs/ufs/dinode.h>
 
77
#endif
 
78
 
 
79
#include <protocols/dumprestore.h>
 
80
 
 
81
#include "dump.h"
 
82
 
 
83
struct  dumpdates **ddatev;
 
84
int     nddates;
 
85
int     ddates_in;
 
86
struct  dumptime *dthead;
 
87
 
 
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 *));
 
92
 
 
93
void
 
94
initdumptimes(int createdumpdates)
 
95
{
 
96
        FILE *df;
 
97
 
 
98
        if ((df = fopen(dumpdates, "r")) == NULL) {
 
99
                if (errno != ENOENT) {
 
100
                        quit("cannot read %s: %s\n", dumpdates,
 
101
                            strerror(errno));
 
102
                        /* NOTREACHED */
 
103
                }
 
104
                if (createdumpdates) {
 
105
                        /*
 
106
                         * Dumpdates does not exist, make an empty one.
 
107
                         */
 
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,
 
111
                                strerror(errno));
 
112
                                /* NOTREACHED */
 
113
                        }
 
114
                        (void) fclose(df);
 
115
                        if ((df = fopen(dumpdates, "r")) == NULL) {
 
116
                                quit("cannot read %s even after creating it: %s\n",
 
117
                                dumpdates, strerror(errno));
 
118
                                /* NOTREACHED */
 
119
                        }
 
120
                }
 
121
                else
 
122
                        msg("WARNING: no file `%s'\n", dumpdates);
 
123
        }
 
124
        if (df != NULL) {
 
125
                (void) flock(fileno(df), LOCK_SH);
 
126
                readdumptimes(df);
 
127
                (void) fclose(df);
 
128
        }
 
129
}
 
130
 
 
131
static void
 
132
readdumptimes(FILE *df)
 
133
{
 
134
        int i;
 
135
        struct  dumptime *dtwalk;
 
136
 
 
137
        for (;;) {
 
138
                dtwalk = (struct dumptime *)calloc(1, sizeof (struct dumptime));
 
139
                if (getrecord(df, &(dtwalk->dt_value)) < 0)
 
140
                        break;
 
141
                nddates++;
 
142
                dtwalk->dt_next = dthead;
 
143
                dthead = dtwalk;
 
144
        }
 
145
 
 
146
        ddates_in = 1;
 
147
        /*
 
148
         *      arrayify the list, leaving enough room for the additional
 
149
         *      record that we may have to add to the ddate structure
 
150
         */
 
151
        ddatev = (struct dumpdates **)
 
152
                calloc((unsigned) (nddates + 1), sizeof (struct dumpdates *));
 
153
        dtwalk = dthead;
 
154
        for (i = nddates - 1; i >= 0; i--, dtwalk = dtwalk->dt_next)
 
155
                ddatev[i] = &dtwalk->dt_value;
 
156
}
 
157
 
 
158
void
 
159
getdumptime(int createdumpdates)
 
160
{
 
161
        struct dumpdates *ddp;
 
162
        int i;
 
163
 
 
164
#ifdef FDEBUG
 
165
        msg("Looking for name %s in dumpdates = %s for level = %c\n",
 
166
                disk, dumpdates, level);
 
167
#endif
 
168
        spcl.c_ddate = 0;
 
169
        lastlevel = '0';
 
170
 
 
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)
 
176
                return;
 
177
        initdumptimes(createdumpdates);
 
178
        if (ddatev == NULL)
 
179
                return;
 
180
        /*
 
181
         *      Go find the entry with the same name for a lower increment
 
182
         *      and older date
 
183
         */
 
184
        ITITERATE(i, ddp) {
 
185
                if (strncmp(disk, ddp->dd_name, sizeof (ddp->dd_name)) != 0)
 
186
                        continue;
 
187
                if (ddp->dd_level >= level)
 
188
                        continue;
 
189
                if (ddp->dd_ddate <= (time_t)spcl.c_ddate)
 
190
                        continue;
 
191
                spcl.c_ddate = ddp->dd_ddate;
 
192
                lastlevel = ddp->dd_level;
 
193
        }
 
194
}
 
195
 
 
196
void
 
197
putdumptime(void)
 
198
{
 
199
        FILE *df;
 
200
        struct dumpdates *dtwalk;
 
201
        int i;
 
202
        int fd;
 
203
 
 
204
        if(uflag == 0)
 
205
                return;
 
206
        if ((df = fopen(dumpdates, "r+")) == NULL)
 
207
                quit("cannot rewrite %s: %s\n", dumpdates, strerror(errno));
 
208
        fd = fileno(df);
 
209
        (void) flock(fd, LOCK_EX);
 
210
        free((char *)ddatev);
 
211
        ddatev = 0;
 
212
        nddates = 0;
 
213
        dthead = 0;
 
214
        ddates_in = 0;
 
215
        readdumptimes(df);
 
216
        if (fseek(df, 0L, 0) < 0)
 
217
                quit("fseek: %s\n", strerror(errno));
 
218
        spcl.c_ddate = 0;
 
219
        ITITERATE(i, dtwalk) {
 
220
                if (strncmp(disk, dtwalk->dd_name,
 
221
                                sizeof (dtwalk->dd_name)) != 0)
 
222
                        continue;
 
223
                if (dtwalk->dd_level != level)
 
224
                        continue;
 
225
                goto found;
 
226
        }
 
227
        /*
 
228
         *      construct the new upper bound;
 
229
         *      Enough room has been allocated.
 
230
         */
 
231
        dtwalk = ddatev[nddates] =
 
232
                (struct dumpdates *)calloc(1, sizeof (struct dumpdates));
 
233
        nddates += 1;
 
234
  found:
 
235
        (void) strncpy(dtwalk->dd_name, disk, sizeof (dtwalk->dd_name));
 
236
        dtwalk->dd_level = level;
 
237
        dtwalk->dd_ddate = spcl.c_date;
 
238
 
 
239
        ITITERATE(i, dtwalk) {
 
240
                dumprecout(df, dtwalk);
 
241
        }
 
242
        if (fflush(df))
 
243
                quit("%s: %s\n", dumpdates, strerror(errno));
 
244
        if (ftruncate(fd, ftell(df)))
 
245
                quit("ftruncate (%s): %s\n", dumpdates, strerror(errno));
 
246
        (void) fclose(df);
 
247
}
 
248
 
 
249
static void
 
250
dumprecout(FILE *file, struct dumpdates *what)
 
251
{
 
252
 
 
253
        if (fprintf(file, "%s %c %s",
 
254
                    what->dd_name,
 
255
                    what->dd_level,
 
256
                    ctime(&what->dd_ddate)) < 0)
 
257
                quit("%s: %s\n", dumpdates, strerror(errno));
 
258
}
 
259
 
 
260
int     recno;
 
261
 
 
262
static int
 
263
getrecord(FILE *df, struct dumpdates *ddatep)
 
264
{
 
265
        char tbuf[BUFSIZ];
 
266
 
 
267
        recno = 0;
 
268
        if (fgets(tbuf, sizeof (tbuf), df) == NULL)
 
269
                return(-1);
 
270
        recno++;
 
271
        if (makedumpdate(ddatep, tbuf) < 0)
 
272
                msg("Unknown intermediate format in %s, line %d\n",
 
273
                        dumpdates, recno);
 
274
 
 
275
#ifdef FDEBUG
 
276
        msg("getrecord: %s %c %s", ddatep->dd_name, ddatep->dd_level,
 
277
            ddatep->dd_ddate == 0 ? "the epoch\n" : ctime(&ddatep->dd_ddate));
 
278
#endif
 
279
        return(0);
 
280
}
 
281
 
 
282
static int
 
283
makedumpdate(struct dumpdates *ddp, char *tbuf)
 
284
{
 
285
        char *tok;
 
286
        
 
287
        /* device name */
 
288
        if ( NULL == (tok = strsep( &tbuf, " ")) )
 
289
                return(-1);
 
290
        if ( strlen(tok) >  MAXPATHLEN )
 
291
                return(-1);
 
292
        strcpy(ddp->dd_name, tok);
 
293
 
 
294
        /* eat whitespace */
 
295
        for( ; *tbuf == ' ' ; tbuf++);
 
296
 
 
297
        /* dump level */
 
298
        ddp->dd_level = *tbuf;
 
299
        ++tbuf;
 
300
 
 
301
        /* eat whitespace */
 
302
        for( ; *tbuf == ' ' ; tbuf++);
 
303
 
 
304
        /* dump date */
 
305
        ddp->dd_ddate = unctime(tbuf);
 
306
        if (ddp->dd_ddate < 0)
 
307
                return(-1);
 
308
        /* fstab entry */
 
309
        ddp->dd_fstab = fstabsearch(ddp->dd_name);
 
310
        return(0);
 
311
}