1*12589Smckusick static char *sccsid = "@(#)itime.c 1.9 (Berkeley) 05/19/83"; 2*12589Smckusick 31422Sroot #include "dump.h" 4*12589Smckusick #include <sys/file.h> 51422Sroot 61422Sroot char *prdate(d) 71422Sroot time_t d; 81422Sroot { 91422Sroot char *p; 101422Sroot 111422Sroot if(d == 0) 121422Sroot return("the epoch"); 131422Sroot p = ctime(&d); 141422Sroot p[24] = 0; 151422Sroot return(p); 161422Sroot } 171422Sroot 181422Sroot struct idates **idatev = 0; 191422Sroot int nidates = 0; 201422Sroot int idates_in = 0; 211422Sroot struct itime *ithead = 0; 221422Sroot 231422Sroot inititimes() 241422Sroot { 251422Sroot FILE *df; 261422Sroot register int i; 271422Sroot register struct itime *itwalk; 28*12589Smckusick int fd; 291422Sroot 301422Sroot if (idates_in) 311422Sroot return; 32*12589Smckusick if ((fd = open(increm, FSHLOCK|FRDONLY, 0600)) < 0) { 33*12589Smckusick perror(increm); 34*12589Smckusick return; 35*12589Smckusick } 36*12589Smckusick if ((df = fdopen(fd, "r")) == NULL) { 371422Sroot nidates = 0; 381422Sroot ithead = 0; 391422Sroot } else { 401422Sroot do{ 411422Sroot itwalk=(struct itime *)calloc(1,sizeof (struct itime)); 421422Sroot if (getrecord(df, &(itwalk->it_value)) < 0) 431422Sroot break; 441422Sroot nidates++; 451422Sroot itwalk->it_next = ithead; 461422Sroot ithead = itwalk; 471422Sroot } while (1); 481422Sroot fclose(df); 491422Sroot } 501422Sroot 511422Sroot idates_in = 1; 521422Sroot /* 531422Sroot * arrayify the list, leaving enough room for the additional 541422Sroot * record that we may have to add to the idate structure 551422Sroot */ 561422Sroot idatev = (struct idates **)calloc(nidates + 1,sizeof (struct idates *)); 571422Sroot for (i = nidates-1, itwalk = ithead; i >= 0; i--, itwalk = itwalk->it_next) 581422Sroot idatev[i] = &itwalk->it_value; 591422Sroot } 601422Sroot 611422Sroot getitime() 621422Sroot { 631422Sroot register struct idates *ip; 641422Sroot register int i; 651422Sroot char *fname; 661422Sroot 671422Sroot fname = disk; 681422Sroot #ifdef FDEBUG 691422Sroot msg("Looking for name %s in increm = %s for delta = %c\n", 701422Sroot fname, increm, incno); 711422Sroot #endif 721422Sroot spcl.c_ddate = 0; 731422Sroot 741422Sroot inititimes(); 751422Sroot /* 761422Sroot * Go find the entry with the same name for a lower increment 771422Sroot * and older date 781422Sroot */ 791422Sroot ITITERATE(i, ip){ 801422Sroot if(strncmp(fname, ip->id_name, 811422Sroot sizeof (ip->id_name)) != 0) 821422Sroot continue; 831422Sroot if (ip->id_incno >= incno) 841422Sroot continue; 851422Sroot if (ip->id_ddate <= spcl.c_ddate) 861422Sroot continue; 871422Sroot spcl.c_ddate = ip->id_ddate; 881422Sroot } 891422Sroot } 901422Sroot 911422Sroot putitime() 921422Sroot { 931422Sroot FILE *df; 941422Sroot register struct idates *itwalk; 951422Sroot register int i; 96*12589Smckusick int fd; 971422Sroot char *fname; 981422Sroot 991422Sroot if(uflag == 0) 1001422Sroot return; 101*12589Smckusick if ((fd = open(temp, FCREATE|FEXLOCK|FRDWR, 0600)) < 0) { 102*12589Smckusick perror(temp); 103*12589Smckusick dumpabort(); 104*12589Smckusick } 105*12589Smckusick if ((df = fdopen(fd, "w")) == NULL) { 106*12589Smckusick perror(temp); 107*12589Smckusick dumpabort(); 108*12589Smckusick } 1091422Sroot fname = disk; 11012584Smckusick free(idatev); 11112584Smckusick idatev = 0; 11212584Smckusick nidates = 0; 11312584Smckusick ithead = 0; 11412584Smckusick idates_in = 0; 11512584Smckusick inititimes(); 1161422Sroot 1171422Sroot spcl.c_ddate = 0; 1181422Sroot ITITERATE(i, itwalk){ 1191422Sroot if (strncmp(fname, itwalk->id_name, 1201422Sroot sizeof (itwalk->id_name)) != 0) 1211422Sroot continue; 1221422Sroot if (itwalk->id_incno != incno) 1231422Sroot continue; 1241422Sroot goto found; 1251422Sroot } 1261422Sroot /* 1271422Sroot * construct the new upper bound; 1281422Sroot * Enough room has been allocated. 1291422Sroot */ 1301422Sroot itwalk = idatev[nidates] = 1311422Sroot (struct idates *)calloc(1, sizeof(struct idates)); 1321422Sroot nidates += 1; 1331422Sroot found: 1341422Sroot strncpy(itwalk->id_name, fname, sizeof (itwalk->id_name)); 1351422Sroot itwalk->id_incno = incno; 1361422Sroot itwalk->id_ddate = spcl.c_date; 1371422Sroot 1381422Sroot ITITERATE(i, itwalk){ 1391422Sroot recout(df, itwalk); 1401422Sroot } 141*12589Smckusick if (rename(temp, increm) < 0) { 142*12589Smckusick perror("rename"); 143*12589Smckusick (void) unlink(temp); 144*12589Smckusick dumpabort(); 145*12589Smckusick } 146*12589Smckusick (void) chmod(increm, 0644); 147*12589Smckusick (void) fclose(df); 1481422Sroot msg("level %c dump on %s\n", incno, prdate(spcl.c_date)); 1491422Sroot } 1501422Sroot 1511422Sroot recout(file, what) 1521422Sroot FILE *file; 1531422Sroot struct idates *what; 1541422Sroot { 1551422Sroot fprintf(file, DUMPOUTFMT, 1561422Sroot what->id_name, 1571422Sroot what->id_incno, 1581422Sroot ctime(&(what->id_ddate)) 1591422Sroot ); 1601422Sroot } 1611422Sroot 1621422Sroot int recno; 1631422Sroot int getrecord(df, idatep) 1641422Sroot FILE *df; 1651422Sroot struct idates *idatep; 1661422Sroot { 1671422Sroot char buf[BUFSIZ]; 1681422Sroot 1691422Sroot recno = 0; 1701422Sroot if ( (fgets(buf, BUFSIZ, df)) != buf) 1711422Sroot return(-1); 1721422Sroot recno++; 1731422Sroot if (makeidate(idatep, buf) < 0) 1741422Sroot msg("Unknown intermediate format in %s, line %d\n", 175*12589Smckusick increm, recno); 1761422Sroot 1771422Sroot #ifdef FDEBUG 1781422Sroot msg("getrecord: %s %c %s\n", 1791422Sroot idatep->id_name, idatep->id_incno, prdate(idatep->id_ddate)); 1801422Sroot #endif 1811422Sroot return(0); 1821422Sroot } 1831422Sroot 1841422Sroot time_t unctime(); 1851422Sroot 1861422Sroot int makeidate(ip, buf) 1871422Sroot struct idates *ip; 1881422Sroot char *buf; 1891422Sroot { 1901422Sroot char un_buf[128]; 1911422Sroot 1921422Sroot sscanf(buf, DUMPINFMT, ip->id_name, &ip->id_incno, un_buf); 1931422Sroot ip->id_ddate = unctime(un_buf); 1941422Sroot if (ip->id_ddate < 0) 1951422Sroot return(-1); 1961422Sroot return(0); 1971422Sroot } 1981422Sroot 1994701Smckusic /* 2005328Smckusic * This is an estimation of the number of TP_BSIZE blocks in the file. 2014701Smckusic * It assumes that there are no unallocated blocks; hence 2024701Smckusic * the estimate may be high 2034701Smckusic */ 2041422Sroot est(ip) 2051422Sroot struct dinode *ip; 2061422Sroot { 2071422Sroot long s; 2081422Sroot 2091422Sroot esize++; 2105328Smckusic /* calc number of TP_BSIZE blocks */ 2119403Smckusick s = howmany(ip->di_size, TP_BSIZE); 2125328Smckusic if (ip->di_size > sblock->fs_bsize * NDADDR) { 2135328Smckusic /* calc number of indirect blocks on the dump tape */ 2148536Smckusick s += howmany(s - NDADDR * sblock->fs_bsize / TP_BSIZE, 2155328Smckusic TP_NINDIR); 2165328Smckusic } 2171422Sroot esize += s; 2181422Sroot } 2191422Sroot 2201422Sroot bmapest(map) 2215328Smckusic char *map; 2221422Sroot { 2231422Sroot register i, n; 2241422Sroot 2251422Sroot n = -1; 2265328Smckusic for (i = 0; i < msiz; i++) 2271422Sroot if(map[i]) 2281422Sroot n = i; 2291422Sroot if(n < 0) 2301422Sroot return; 2315328Smckusic n++; 2321422Sroot esize++; 2335328Smckusic esize += howmany(n * sizeof map[0], TP_BSIZE); 2341422Sroot } 235