1*13151Ssam static char *sccsid = "@(#)itime.c 1.11 (Berkeley) 06/15/83"; 212589Smckusick 31422Sroot #include "dump.h" 412589Smckusick #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; 2812589Smckusick int fd; 291422Sroot 301422Sroot if (idates_in) 311422Sroot return; 32*13151Ssam fd = open(increm, O_RDONLY); 33*13151Ssam if (fd < 0) { 3412589Smckusick perror(increm); 3512589Smckusick return; 3612589Smckusick } 37*13151Ssam (void) flock(fd, LOCK_SH); 3812589Smckusick if ((df = fdopen(fd, "r")) == NULL) { 391422Sroot nidates = 0; 401422Sroot ithead = 0; 411422Sroot } else { 421422Sroot do{ 431422Sroot itwalk=(struct itime *)calloc(1,sizeof (struct itime)); 441422Sroot if (getrecord(df, &(itwalk->it_value)) < 0) 451422Sroot break; 461422Sroot nidates++; 471422Sroot itwalk->it_next = ithead; 481422Sroot ithead = itwalk; 491422Sroot } while (1); 501422Sroot fclose(df); 511422Sroot } 521422Sroot 531422Sroot idates_in = 1; 541422Sroot /* 551422Sroot * arrayify the list, leaving enough room for the additional 561422Sroot * record that we may have to add to the idate structure 571422Sroot */ 581422Sroot idatev = (struct idates **)calloc(nidates + 1,sizeof (struct idates *)); 591422Sroot for (i = nidates-1, itwalk = ithead; i >= 0; i--, itwalk = itwalk->it_next) 601422Sroot idatev[i] = &itwalk->it_value; 611422Sroot } 621422Sroot 631422Sroot getitime() 641422Sroot { 651422Sroot register struct idates *ip; 661422Sroot register int i; 671422Sroot char *fname; 681422Sroot 691422Sroot fname = disk; 701422Sroot #ifdef FDEBUG 711422Sroot msg("Looking for name %s in increm = %s for delta = %c\n", 721422Sroot fname, increm, incno); 731422Sroot #endif 741422Sroot spcl.c_ddate = 0; 751422Sroot 761422Sroot inititimes(); 771422Sroot /* 781422Sroot * Go find the entry with the same name for a lower increment 791422Sroot * and older date 801422Sroot */ 811422Sroot ITITERATE(i, ip){ 821422Sroot if(strncmp(fname, ip->id_name, 831422Sroot sizeof (ip->id_name)) != 0) 841422Sroot continue; 851422Sroot if (ip->id_incno >= incno) 861422Sroot continue; 871422Sroot if (ip->id_ddate <= spcl.c_ddate) 881422Sroot continue; 891422Sroot spcl.c_ddate = ip->id_ddate; 9012947Smckusick lastincno = ip->id_incno; 911422Sroot } 921422Sroot } 931422Sroot 941422Sroot putitime() 951422Sroot { 961422Sroot FILE *df; 971422Sroot register struct idates *itwalk; 981422Sroot register int i; 9912589Smckusick int fd; 1001422Sroot char *fname; 1011422Sroot 1021422Sroot if(uflag == 0) 1031422Sroot return; 104*13151Ssam fd = open(temp, O_RDWR|O_CREAT, 0600); 105*13151Ssam if (fd < 0) { 10612589Smckusick perror(temp); 10712589Smckusick dumpabort(); 10812589Smckusick } 109*13151Ssam (void) flock(fd, LOCK_EX); 11012589Smckusick if ((df = fdopen(fd, "w")) == NULL) { 11112589Smckusick perror(temp); 11212589Smckusick dumpabort(); 11312589Smckusick } 1141422Sroot fname = disk; 11512584Smckusick free(idatev); 11612584Smckusick idatev = 0; 11712584Smckusick nidates = 0; 11812584Smckusick ithead = 0; 11912584Smckusick idates_in = 0; 12012584Smckusick inititimes(); 1211422Sroot 1221422Sroot spcl.c_ddate = 0; 1231422Sroot ITITERATE(i, itwalk){ 1241422Sroot if (strncmp(fname, itwalk->id_name, 1251422Sroot sizeof (itwalk->id_name)) != 0) 1261422Sroot continue; 1271422Sroot if (itwalk->id_incno != incno) 1281422Sroot continue; 1291422Sroot goto found; 1301422Sroot } 1311422Sroot /* 1321422Sroot * construct the new upper bound; 1331422Sroot * Enough room has been allocated. 1341422Sroot */ 1351422Sroot itwalk = idatev[nidates] = 1361422Sroot (struct idates *)calloc(1, sizeof(struct idates)); 1371422Sroot nidates += 1; 1381422Sroot found: 1391422Sroot strncpy(itwalk->id_name, fname, sizeof (itwalk->id_name)); 1401422Sroot itwalk->id_incno = incno; 1411422Sroot itwalk->id_ddate = spcl.c_date; 1421422Sroot 1431422Sroot ITITERATE(i, itwalk){ 1441422Sroot recout(df, itwalk); 1451422Sroot } 14612589Smckusick if (rename(temp, increm) < 0) { 14712589Smckusick perror("rename"); 14812589Smckusick (void) unlink(temp); 14912589Smckusick dumpabort(); 15012589Smckusick } 15112589Smckusick (void) chmod(increm, 0644); 15212589Smckusick (void) fclose(df); 1531422Sroot msg("level %c dump on %s\n", incno, prdate(spcl.c_date)); 1541422Sroot } 1551422Sroot 1561422Sroot recout(file, what) 1571422Sroot FILE *file; 1581422Sroot struct idates *what; 1591422Sroot { 1601422Sroot fprintf(file, DUMPOUTFMT, 1611422Sroot what->id_name, 1621422Sroot what->id_incno, 1631422Sroot ctime(&(what->id_ddate)) 1641422Sroot ); 1651422Sroot } 1661422Sroot 1671422Sroot int recno; 1681422Sroot int getrecord(df, idatep) 1691422Sroot FILE *df; 1701422Sroot struct idates *idatep; 1711422Sroot { 1721422Sroot char buf[BUFSIZ]; 1731422Sroot 1741422Sroot recno = 0; 1751422Sroot if ( (fgets(buf, BUFSIZ, df)) != buf) 1761422Sroot return(-1); 1771422Sroot recno++; 1781422Sroot if (makeidate(idatep, buf) < 0) 1791422Sroot msg("Unknown intermediate format in %s, line %d\n", 18012589Smckusick increm, recno); 1811422Sroot 1821422Sroot #ifdef FDEBUG 1831422Sroot msg("getrecord: %s %c %s\n", 1841422Sroot idatep->id_name, idatep->id_incno, prdate(idatep->id_ddate)); 1851422Sroot #endif 1861422Sroot return(0); 1871422Sroot } 1881422Sroot 1891422Sroot time_t unctime(); 1901422Sroot 1911422Sroot int makeidate(ip, buf) 1921422Sroot struct idates *ip; 1931422Sroot char *buf; 1941422Sroot { 1951422Sroot char un_buf[128]; 1961422Sroot 1971422Sroot sscanf(buf, DUMPINFMT, ip->id_name, &ip->id_incno, un_buf); 1981422Sroot ip->id_ddate = unctime(un_buf); 1991422Sroot if (ip->id_ddate < 0) 2001422Sroot return(-1); 2011422Sroot return(0); 2021422Sroot } 2031422Sroot 2044701Smckusic /* 2055328Smckusic * This is an estimation of the number of TP_BSIZE blocks in the file. 2064701Smckusic * It assumes that there are no unallocated blocks; hence 2074701Smckusic * the estimate may be high 2084701Smckusic */ 2091422Sroot est(ip) 2101422Sroot struct dinode *ip; 2111422Sroot { 2121422Sroot long s; 2131422Sroot 2141422Sroot esize++; 2155328Smckusic /* calc number of TP_BSIZE blocks */ 2169403Smckusick s = howmany(ip->di_size, TP_BSIZE); 2175328Smckusic if (ip->di_size > sblock->fs_bsize * NDADDR) { 2185328Smckusic /* calc number of indirect blocks on the dump tape */ 2198536Smckusick s += howmany(s - NDADDR * sblock->fs_bsize / TP_BSIZE, 2205328Smckusic TP_NINDIR); 2215328Smckusic } 2221422Sroot esize += s; 2231422Sroot } 2241422Sroot 2251422Sroot bmapest(map) 2265328Smckusic char *map; 2271422Sroot { 2281422Sroot register i, n; 2291422Sroot 2301422Sroot n = -1; 2315328Smckusic for (i = 0; i < msiz; i++) 2321422Sroot if(map[i]) 2331422Sroot n = i; 2341422Sroot if(n < 0) 2351422Sroot return; 2365328Smckusic n++; 2371422Sroot esize++; 2385328Smckusic esize += howmany(n * sizeof map[0], TP_BSIZE); 2391422Sroot } 240