1
0
Files
irix-657m-src/eoe/cmd/bsd/dump/dumpitime.c
2022-09-29 17:59:04 +03:00

272 lines
5.6 KiB
C

#ident "$Revision: 1.6 $"
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* static char sccsid[] = "@(#)dumpitime.c 5.2 (Berkeley) 5/28/86";
*/
#include "dump.h"
static struct itime *ithead; /* head of the list version */
static int getrecord(FILE *, struct idates *);
static int makeidate(struct idates *, char *);
static void readitimes(FILE *);
static void recout(FILE *, struct idates *);
char *
prdate(time_t d)
{
char *p;
if (d == 0)
return("the epoch");
p = ctime(&d);
p[24] = 0;
return(p);
}
void
inititimes(void)
{
FILE *df;
if ((df = fopen(increm, "r")) == NULL) {
if (errno != ENOENT) /* don't panic the operator */
perror(increm);
return;
}
(void) flock(fileno(df), LOCK_SH);
readitimes(df);
fclose(df);
}
static void
readitimes(FILE *df)
{
int i;
struct itime *itwalk;
for (;;) {
itwalk = (struct itime *)calloc(1, sizeof (struct itime));
if (getrecord(df, &(itwalk->it_value)) < 0)
break;
nidates++;
itwalk->it_next = ithead;
ithead = itwalk;
}
/*
* arrayify the list, leaving enough room for the additional
* record that we may have to add to the idate structure
*/
idatev = (struct idates **)calloc(nidates + 1,sizeof (struct idates *));
itwalk = ithead;
for (i = nidates - 1; i >= 0; i--, itwalk = itwalk->it_next)
idatev[i] = &itwalk->it_value;
}
void
getitime(void)
{
struct idates *ip;
int i;
char *fname;
fname = disk;
#ifdef FDEBUG
msg("Looking for name %s in increm = %s for delta = %c\n",
fname, increm, incno);
#endif
spcl.c_ddate = 0;
lastincno = '0';
inititimes();
if (idatev == 0)
return;
/*
* 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)
continue;
if (ip->id_incno >= incno)
continue;
if (ip->id_ddate <= spcl.c_ddate)
continue;
spcl.c_ddate = ip->id_ddate;
lastincno = ip->id_incno;
}
}
void
putitime(void)
{
FILE *df;
struct idates *itwalk;
int i;
int fd;
char *fname;
mode_t omask;
if(uflag == 0)
return;
if ((df = fopen(increm, "r+")) == NULL) {
if (errno == ENOENT) {
fprintf(stderr, " DUMP: creating file %s\n", increm);
omask = umask((mode_t)0022);
if ((df = fopen(increm, "w")) == NULL) {
perror(increm);
fprintf(stderr, "Couldn't update %s\n", increm);
return;
}
(void) umask(omask);
} else {
perror(increm);
fprintf(stderr, "Couldn't update %s\n", increm);
return;
}
}
fd = fileno(df);
(void) flock(fd, LOCK_EX);
fname = disk;
if (idatev)
free(idatev);
idatev = 0;
nidates = 0;
ithead = 0;
readitimes(df);
if (fseek(df,0L,0) < 0) { /* rewind() was redefined in dumptape.c */
perror("fseek");
dumpabort();
}
spcl.c_ddate = 0;
ITITERATE(i, itwalk){
if (strncmp(fname, itwalk->id_name,
sizeof (itwalk->id_name)) != 0)
continue;
if (itwalk->id_incno != incno)
continue;
goto found;
}
/*
* construct the new upper bound;
* Enough room has been allocated.
*/
itwalk = idatev[nidates] =
(struct idates *)calloc(1, sizeof(struct idates));
nidates += 1;
found:
strncpy(itwalk->id_name, fname, sizeof (itwalk->id_name));
itwalk->id_incno = incno;
itwalk->id_ddate = spcl.c_date;
ITITERATE(i, itwalk){
recout(df, itwalk);
}
if (ftruncate(fd, ftell(df))) {
perror("ftruncate");
dumpabort();
}
(void) fclose(df);
msg("level %c dump on %s\n", incno, prdate(spcl.c_date));
}
static void
recout(FILE *file, struct idates *what)
{
fprintf(file, DUMPOUTFMT,
what->id_name,
what->id_incno,
ctime(&(what->id_ddate))
);
}
int recno;
static int
getrecord(FILE *df, struct idates* idatep)
{
char buf[BUFSIZ];
recno = 0;
if ( (fgets(buf, BUFSIZ, df)) != buf)
return(-1);
recno++;
if (makeidate(idatep, buf) < 0)
msg("Unknown intermediate format in %s, line %d\n",
increm, recno);
#ifdef FDEBUG
msg("getrecord: %s %c %s\n",
idatep->id_name, idatep->id_incno, prdate(idatep->id_ddate));
#endif
return(0);
}
static int
makeidate(struct idates *ip, char *buf)
{
char un_buf[128];
if (sscanf(buf, DUMPINFMT, ip->id_name, &ip->id_incno, un_buf) != 3)
return(-1);
ip->id_ddate = unctime(un_buf);
if (ip->id_ddate < 0)
return(-1);
return(0);
}
/*
* This is an estimation of the number of TP_BSIZE blocks in the file.
* It estimates the number of blocks in files with holes by assuming
* that all of the blocks accounted for by di_blocks are data blocks
* (when some of the blocks are usually used for indirect pointers);
* hence the estimate may be high.
*/
void
est(struct efs_dinode *ip)
{
unsigned long s;
/*
* ip->di_size is the size of the file in bytes.
* ip->di_blocks stores the number of sectors actually in the file.
* If there are more sectors than the size would indicate, this just
* means that there are indirect blocks in the file or unused
* sectors in the last file block; we can safely ignore these
* (s = t below).
* If the file is bigger than the number of sectors would indicate,
* then the file has holes in it. In this case we must use the
* block count to estimate the number of data blocks used, but
* we use the actual size for estimating the number of indirect
* dump blocks (t vs. s in the indirect block calculation).
*/
esize++;
/*
* No holes in EFS.
*/
s = howmany(ip->di_size, TP_BSIZE);
esize += s;
}
void
bmapest(char *map)
{
int 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);
}