122036Sdist /* 222036Sdist * Copyright (c) 1980 Regents of the University of California. 322036Sdist * All rights reserved. The Berkeley software License Agreement 422036Sdist * specifies the terms and conditions for redistribution. 522036Sdist */ 612589Smckusick 722036Sdist #ifndef lint 8*46590Storek static char sccsid[] = "@(#)itime.c 5.4 (Berkeley) 02/23/91"; 9*46590Storek #endif /* not lint */ 1022036Sdist 111422Sroot #include "dump.h" 1212589Smckusick #include <sys/file.h> 13*46590Storek #include <errno.h> 141422Sroot 15*46590Storek char * 16*46590Storek prdate(d) 171422Sroot time_t d; 181422Sroot { 191422Sroot char *p; 201422Sroot 211422Sroot if(d == 0) 221422Sroot return("the epoch"); 231422Sroot p = ctime(&d); 241422Sroot p[24] = 0; 251422Sroot return(p); 261422Sroot } 271422Sroot 281422Sroot struct idates **idatev = 0; 291422Sroot int nidates = 0; 301422Sroot int idates_in = 0; 311422Sroot struct itime *ithead = 0; 321422Sroot 33*46590Storek void readitimes(); 34*46590Storek int getrecord(); 35*46590Storek int makeidate(); 36*46590Storek 37*46590Storek static void recout(); 38*46590Storek 39*46590Storek void 401422Sroot inititimes() 411422Sroot { 4228858Smckusick FILE *df; 431422Sroot 4428858Smckusick if ((df = fopen(increm, "r")) == NULL) { 45*46590Storek if (errno == ENOENT) { 46*46590Storek msg("WARNING: no file `%s'\n", increm); 47*46590Storek return; 48*46590Storek } 49*46590Storek quit("cannot read %s: %s\n", increm, strerror(errno)); 50*46590Storek /* NOTREACHED */ 5112589Smckusick } 5228858Smckusick (void) flock(fileno(df), LOCK_SH); 5328858Smckusick readitimes(df); 5428858Smckusick fclose(df); 5528858Smckusick } 5628858Smckusick 57*46590Storek void 5828858Smckusick readitimes(df) 5928858Smckusick FILE *df; 6028858Smckusick { 6128858Smckusick register int i; 6228858Smckusick register struct itime *itwalk; 6328858Smckusick 6428858Smckusick for (;;) { 6528858Smckusick itwalk = (struct itime *)calloc(1, sizeof (struct itime)); 6628858Smckusick if (getrecord(df, &(itwalk->it_value)) < 0) 6728858Smckusick break; 6828858Smckusick nidates++; 6928858Smckusick itwalk->it_next = ithead; 7028858Smckusick ithead = itwalk; 711422Sroot } 721422Sroot 731422Sroot idates_in = 1; 741422Sroot /* 751422Sroot * arrayify the list, leaving enough room for the additional 761422Sroot * record that we may have to add to the idate structure 771422Sroot */ 781422Sroot idatev = (struct idates **)calloc(nidates + 1,sizeof (struct idates *)); 7928858Smckusick itwalk = ithead; 8028858Smckusick for (i = nidates - 1; i >= 0; i--, itwalk = itwalk->it_next) 811422Sroot idatev[i] = &itwalk->it_value; 821422Sroot } 831422Sroot 84*46590Storek void 851422Sroot getitime() 861422Sroot { 871422Sroot register struct idates *ip; 881422Sroot register int i; 891422Sroot char *fname; 901422Sroot 911422Sroot fname = disk; 921422Sroot #ifdef FDEBUG 931422Sroot msg("Looking for name %s in increm = %s for delta = %c\n", 941422Sroot fname, increm, incno); 951422Sroot #endif 961422Sroot spcl.c_ddate = 0; 9714964Smckusick lastincno = '0'; 981422Sroot 991422Sroot inititimes(); 1001422Sroot /* 1011422Sroot * Go find the entry with the same name for a lower increment 1021422Sroot * and older date 1031422Sroot */ 10428858Smckusick ITITERATE(i, ip) { 10528858Smckusick if (strncmp(fname, ip->id_name, sizeof (ip->id_name)) != 0) 1061422Sroot continue; 1071422Sroot if (ip->id_incno >= incno) 1081422Sroot continue; 1091422Sroot if (ip->id_ddate <= spcl.c_ddate) 1101422Sroot continue; 1111422Sroot spcl.c_ddate = ip->id_ddate; 11228858Smckusick lastincno = ip->id_incno; 11328858Smckusick } 1141422Sroot } 1151422Sroot 116*46590Storek void 1171422Sroot putitime() 1181422Sroot { 1191422Sroot FILE *df; 1201422Sroot register struct idates *itwalk; 1211422Sroot register int i; 12212589Smckusick int fd; 1231422Sroot char *fname; 1241422Sroot 1251422Sroot if(uflag == 0) 1261422Sroot return; 127*46590Storek if ((df = fopen(increm, "r+")) == NULL) 128*46590Storek quit("cannot rewrite %s: %s\n", increm, strerror(errno)); 12928858Smckusick fd = fileno(df); 13013151Ssam (void) flock(fd, LOCK_EX); 1311422Sroot fname = disk; 13212584Smckusick free(idatev); 13312584Smckusick idatev = 0; 13412584Smckusick nidates = 0; 13512584Smckusick ithead = 0; 13612584Smckusick idates_in = 0; 13728858Smckusick readitimes(df); 138*46590Storek if (fseek(df, 0L, 0) < 0) 139*46590Storek quit("fseek: %s\n", strerror(errno)); 1401422Sroot spcl.c_ddate = 0; 141*46590Storek ITITERATE(i, itwalk) { 1421422Sroot if (strncmp(fname, itwalk->id_name, 1431422Sroot sizeof (itwalk->id_name)) != 0) 1441422Sroot continue; 1451422Sroot if (itwalk->id_incno != incno) 1461422Sroot continue; 1471422Sroot goto found; 1481422Sroot } 1491422Sroot /* 1501422Sroot * construct the new upper bound; 1511422Sroot * Enough room has been allocated. 1521422Sroot */ 1531422Sroot itwalk = idatev[nidates] = 1541422Sroot (struct idates *)calloc(1, sizeof(struct idates)); 1551422Sroot nidates += 1; 1561422Sroot found: 157*46590Storek (void) strncpy(itwalk->id_name, fname, sizeof (itwalk->id_name)); 1581422Sroot itwalk->id_incno = incno; 1591422Sroot itwalk->id_ddate = spcl.c_date; 1601422Sroot 161*46590Storek ITITERATE(i, itwalk) { 1621422Sroot recout(df, itwalk); 1631422Sroot } 164*46590Storek if (fflush(df)) 165*46590Storek quit("%s: %s\n", increm, strerror(errno)); 166*46590Storek if (ftruncate(fd, ftell(df))) 167*46590Storek quit("ftruncate (%s): %s\n", increm, strerror(errno)); 16812589Smckusick (void) fclose(df); 1691422Sroot msg("level %c dump on %s\n", incno, prdate(spcl.c_date)); 1701422Sroot } 1711422Sroot 172*46590Storek static void 1731422Sroot recout(file, what) 1741422Sroot FILE *file; 1751422Sroot struct idates *what; 1761422Sroot { 177*46590Storek 178*46590Storek if (fprintf(file, DUMPOUTFMT, 179*46590Storek what->id_name, 180*46590Storek what->id_incno, 181*46590Storek ctime(&what->id_ddate)) < 0) 182*46590Storek quit("%s: %s\n", increm, strerror(errno)); 1831422Sroot } 1841422Sroot 1851422Sroot int recno; 186*46590Storek int 187*46590Storek getrecord(df, idatep) 1881422Sroot FILE *df; 1891422Sroot struct idates *idatep; 1901422Sroot { 1911422Sroot char buf[BUFSIZ]; 1921422Sroot 1931422Sroot recno = 0; 1941422Sroot if ( (fgets(buf, BUFSIZ, df)) != buf) 1951422Sroot return(-1); 1961422Sroot recno++; 1971422Sroot if (makeidate(idatep, buf) < 0) 1981422Sroot msg("Unknown intermediate format in %s, line %d\n", 19912589Smckusick increm, recno); 2001422Sroot 2011422Sroot #ifdef FDEBUG 2021422Sroot msg("getrecord: %s %c %s\n", 2031422Sroot idatep->id_name, idatep->id_incno, prdate(idatep->id_ddate)); 2041422Sroot #endif 2051422Sroot return(0); 2061422Sroot } 2071422Sroot 2081422Sroot time_t unctime(); 2091422Sroot 210*46590Storek int 211*46590Storek makeidate(ip, buf) 2121422Sroot struct idates *ip; 2131422Sroot char *buf; 2141422Sroot { 2151422Sroot char un_buf[128]; 2161422Sroot 2171422Sroot sscanf(buf, DUMPINFMT, ip->id_name, &ip->id_incno, un_buf); 2181422Sroot ip->id_ddate = unctime(un_buf); 2191422Sroot if (ip->id_ddate < 0) 2201422Sroot return(-1); 2211422Sroot return(0); 2221422Sroot } 223