X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/c02e51374f557723a0ee751108f93177760d40c1..ad7871609881e73855d0b04da49b486cd93efca7:/usr/src/sbin/dump/itime.c diff --git a/usr/src/sbin/dump/itime.c b/usr/src/sbin/dump/itime.c index 80136c059b..94656ac649 100644 --- a/usr/src/sbin/dump/itime.c +++ b/usr/src/sbin/dump/itime.c @@ -1,126 +1,197 @@ -static char *sccsid = "@(#)itime.c 1.10 (Berkeley) %G%"; +/*- + * Copyright (c) 1980, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)itime.c 8.1 (Berkeley) 6/5/93"; +#endif /* not lint */ + +#include +#include +#ifdef sunos +#include + +#include +#include +#include +#else +#include +#endif + +#include + +#include +#include +#include +#ifdef __STDC__ +#include +#include +#include +#endif #include "dump.h" -#include -char *prdate(d) - time_t d; +struct dumpdates **ddatev = 0; +int nddates = 0; +int ddates_in = 0; +struct dumptime *dthead = 0; + +static void dumprecout __P((FILE *, struct dumpdates *)); +static int getrecord __P((FILE *, struct dumpdates *)); +static int makedumpdate __P((struct dumpdates *, char *)); +static void readdumptimes __P((FILE *)); + +void +initdumptimes() { - char *p; + FILE *df; - if(d == 0) - return("the epoch"); - p = ctime(&d); - p[24] = 0; - return(p); + if ((df = fopen(dumpdates, "r")) == NULL) { + if (errno != ENOENT) { + quit("cannot read %s: %s\n", dumpdates, + strerror(errno)); + /* NOTREACHED */ + } + /* + * Dumpdates does not exist, make an empty one. + */ + msg("WARNING: no file `%s', making an empty one\n", dumpdates); + if ((df = fopen(dumpdates, "w")) == NULL) { + quit("cannot create %s: %s\n", dumpdates, + strerror(errno)); + /* NOTREACHED */ + } + (void) fclose(df); + if ((df = fopen(dumpdates, "r")) == NULL) { + quit("cannot read %s even after creating it: %s\n", + dumpdates, strerror(errno)); + /* NOTREACHED */ + } + } + (void) flock(fileno(df), LOCK_SH); + readdumptimes(df); + (void) fclose(df); } -struct idates **idatev = 0; -int nidates = 0; -int idates_in = 0; -struct itime *ithead = 0; - -inititimes() +static void +readdumptimes(df) + FILE *df; { - FILE *df; - register int i; - register struct itime *itwalk; - int fd; + register int i; + register struct dumptime *dtwalk; - if (idates_in) - return; - if ((fd = open(increm, FSHLOCK|FRDONLY, 0600)) < 0) { - perror(increm); - return; - } - if ((df = fdopen(fd, "r")) == NULL) { - nidates = 0; - ithead = 0; - } else { - do{ - itwalk=(struct itime *)calloc(1,sizeof (struct itime)); - if (getrecord(df, &(itwalk->it_value)) < 0) - break; - nidates++; - itwalk->it_next = ithead; - ithead = itwalk; - } while (1); - fclose(df); + for (;;) { + dtwalk = (struct dumptime *)calloc(1, sizeof (struct dumptime)); + if (getrecord(df, &(dtwalk->dt_value)) < 0) + break; + nddates++; + dtwalk->dt_next = dthead; + dthead = dtwalk; } - idates_in = 1; + ddates_in = 1; /* * arrayify the list, leaving enough room for the additional - * record that we may have to add to the idate structure + * record that we may have to add to the ddate structure */ - idatev = (struct idates **)calloc(nidates + 1,sizeof (struct idates *)); - for (i = nidates-1, itwalk = ithead; i >= 0; i--, itwalk = itwalk->it_next) - idatev[i] = &itwalk->it_value; + ddatev = (struct dumpdates **) + calloc((unsigned) (nddates + 1), sizeof (struct dumpdates *)); + dtwalk = dthead; + for (i = nddates - 1; i >= 0; i--, dtwalk = dtwalk->dt_next) + ddatev[i] = &dtwalk->dt_value; } -getitime() +void +getdumptime() { - register struct idates *ip; - register int i; - char *fname; + register struct dumpdates *ddp; + register int i; + char *fname; fname = disk; #ifdef FDEBUG - msg("Looking for name %s in increm = %s for delta = %c\n", - fname, increm, incno); + msg("Looking for name %s in dumpdates = %s for level = %c\n", + fname, dumpdates, level); #endif spcl.c_ddate = 0; + lastlevel = '0'; - inititimes(); + initdumptimes(); /* * Go find the entry with the same name for a lower increment * and older date */ - ITITERATE(i, ip){ - if(strncmp(fname, ip->id_name, - sizeof (ip->id_name)) != 0) + ITITERATE(i, ddp) { + if (strncmp(fname, ddp->dd_name, sizeof (ddp->dd_name)) != 0) continue; - if (ip->id_incno >= incno) + if (ddp->dd_level >= level) continue; - if (ip->id_ddate <= spcl.c_ddate) + if (ddp->dd_ddate <= spcl.c_ddate) continue; - spcl.c_ddate = ip->id_ddate; - lastincno = ip->id_incno; - } + spcl.c_ddate = ddp->dd_ddate; + lastlevel = ddp->dd_level; + } } -putitime() +void +putdumptime() { - FILE *df; - register struct idates *itwalk; - register int i; - int fd; - char *fname; + FILE *df; + register struct dumpdates *dtwalk; + register int i; + int fd; + char *fname; if(uflag == 0) return; - if ((fd = open(temp, FCREATE|FEXLOCK|FRDWR, 0600)) < 0) { - perror(temp); - dumpabort(); - } - if ((df = fdopen(fd, "w")) == NULL) { - perror(temp); - dumpabort(); - } + if ((df = fopen(dumpdates, "r+")) == NULL) + quit("cannot rewrite %s: %s\n", dumpdates, strerror(errno)); + fd = fileno(df); + (void) flock(fd, LOCK_EX); fname = disk; - free(idatev); - idatev = 0; - nidates = 0; - ithead = 0; - idates_in = 0; - inititimes(); - + free((char *)ddatev); + ddatev = 0; + nddates = 0; + dthead = 0; + ddates_in = 0; + readdumptimes(df); + if (fseek(df, 0L, 0) < 0) + quit("fseek: %s\n", strerror(errno)); spcl.c_ddate = 0; - ITITERATE(i, itwalk){ - if (strncmp(fname, itwalk->id_name, - sizeof (itwalk->id_name)) != 0) + ITITERATE(i, dtwalk) { + if (strncmp(fname, dtwalk->dd_name, + sizeof (dtwalk->dd_name)) != 0) continue; - if (itwalk->id_incno != incno) + if (dtwalk->dd_level != level) continue; goto found; } @@ -128,108 +199,73 @@ putitime() * construct the new upper bound; * Enough room has been allocated. */ - itwalk = idatev[nidates] = - (struct idates *)calloc(1, sizeof(struct idates)); - nidates += 1; + dtwalk = ddatev[nddates] = + (struct dumpdates *)calloc(1, sizeof (struct dumpdates)); + nddates += 1; found: - strncpy(itwalk->id_name, fname, sizeof (itwalk->id_name)); - itwalk->id_incno = incno; - itwalk->id_ddate = spcl.c_date; + (void) strncpy(dtwalk->dd_name, fname, sizeof (dtwalk->dd_name)); + dtwalk->dd_level = level; + dtwalk->dd_ddate = spcl.c_date; - ITITERATE(i, itwalk){ - recout(df, itwalk); + ITITERATE(i, dtwalk) { + dumprecout(df, dtwalk); } - if (rename(temp, increm) < 0) { - perror("rename"); - (void) unlink(temp); - dumpabort(); - } - (void) chmod(increm, 0644); + if (fflush(df)) + quit("%s: %s\n", dumpdates, strerror(errno)); + if (ftruncate(fd, ftell(df))) + quit("ftruncate (%s): %s\n", dumpdates, strerror(errno)); (void) fclose(df); - msg("level %c dump on %s\n", incno, prdate(spcl.c_date)); + msg("level %c dump on %s", level, + spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date)); } -recout(file, what) - FILE *file; - struct idates *what; +static void +dumprecout(file, what) + FILE *file; + struct dumpdates *what; { - fprintf(file, DUMPOUTFMT, - what->id_name, - what->id_incno, - ctime(&(what->id_ddate)) - ); + + if (fprintf(file, DUMPOUTFMT, + what->dd_name, + what->dd_level, + ctime(&what->dd_ddate)) < 0) + quit("%s: %s\n", dumpdates, strerror(errno)); } int recno; -int getrecord(df, idatep) - FILE *df; - struct idates *idatep; + +static int +getrecord(df, ddatep) + FILE *df; + struct dumpdates *ddatep; { - char buf[BUFSIZ]; + char tbuf[BUFSIZ]; recno = 0; - if ( (fgets(buf, BUFSIZ, df)) != buf) + if ( (fgets(tbuf, sizeof (tbuf), df)) != tbuf) return(-1); recno++; - if (makeidate(idatep, buf) < 0) + if (makedumpdate(ddatep, tbuf) < 0) msg("Unknown intermediate format in %s, line %d\n", - increm, recno); + dumpdates, recno); #ifdef FDEBUG - msg("getrecord: %s %c %s\n", - idatep->id_name, idatep->id_incno, prdate(idatep->id_ddate)); + msg("getrecord: %s %c %s", ddatep->dd_name, ddatep->dd_level, + ddatep->dd_ddate == 0 ? "the epoch\n" : ctime(&ddatep->dd_ddate)); #endif return(0); } -time_t unctime(); - -int makeidate(ip, buf) - struct idates *ip; - char *buf; +static int +makedumpdate(ddp, tbuf) + struct dumpdates *ddp; + char *tbuf; { - char un_buf[128]; + char un_buf[128]; - sscanf(buf, DUMPINFMT, ip->id_name, &ip->id_incno, un_buf); - ip->id_ddate = unctime(un_buf); - if (ip->id_ddate < 0) + (void) sscanf(tbuf, DUMPINFMT, ddp->dd_name, &ddp->dd_level, un_buf); + ddp->dd_ddate = unctime(un_buf); + if (ddp->dd_ddate < 0) return(-1); return(0); } - -/* - * This is an estimation of the number of TP_BSIZE blocks in the file. - * It assumes that there are no unallocated blocks; hence - * the estimate may be high - */ -est(ip) - struct dinode *ip; -{ - long s; - - esize++; - /* calc number of TP_BSIZE blocks */ - s = howmany(ip->di_size, TP_BSIZE); - if (ip->di_size > sblock->fs_bsize * NDADDR) { - /* calc number of indirect blocks on the dump tape */ - s += howmany(s - NDADDR * sblock->fs_bsize / TP_BSIZE, - TP_NINDIR); - } - esize += s; -} - -bmapest(map) - char *map; -{ - register i, n; - - n = -1; - for (i = 0; i < msiz; i++) - if(map[i]) - n = i; - if(n < 0) - return; - n++; - esize++; - esize += howmany(n * sizeof map[0], TP_BSIZE); -}