* 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
[] = "@(#)main.c 5.11 (Berkeley) %G%";
int notify
= 0; /* notify operator flag */
int blockswritten
= 0; /* number of blocks written on current tape */
int tapeno
= 0; /* current tape number */
int density
= 0; /* density in bytes/0.1" */
int ntrec
= NTREC
; /* # tape blocks in each tape record */
int cartridge
= 0; /* Assume non-cartridge tape */
long dev_bsize
= 1; /* recalculated below */
long blocksperfile
; /* output blocks per file */
int anydskipped
; /* set true in mark() if any directories are skipped */
/* this lets us avoid map pass 2 in some cases */
register struct fstab
*dt
;
tsize
= 0; /* Default later, based on 'c' option for cart tapes */
increm
= _PATH_DUMPDATES
;
if (TP_BSIZE
/ DEV_BSIZE
== 0 || TP_BSIZE
% DEV_BSIZE
!= 0)
quit("TP_BSIZE must be a multiple of DEV_BSIZE\n");
lastdump('w'); /* tell us only what has to be done */
case 'W': /* what to do */
lastdump('W'); /* tell us the current state of what has been done */
exit(0); /* do nothing else */
case 'f': /* output file */
case 'd': /* density, in bits per inch */
density
= atoi(*argv
) / 10;
if (density
>= 625 && !bflag
)
case 's': /* tape size, feet */
case 'b': /* blocks per tape write */
"bad number of blocks per write \"%s\"\n",
case 'B': /* blocks per output file */
blocksperfile
= atol(*argv
);
case 'c': /* Tape is cart. not 9-track */
case '0': /* dump level */
case 'u': /* update /etc/dumpdates */
case 'n': /* notify operators */
fprintf(stderr
, "bad key '%c'\n", arg
[-1]);
if (strcmp(tape
, "-") == 0) {
tape
= "standard output";
blocksperfile
= blocksperfile
/ ntrec
* ntrec
; /* round down */
* Determine how to default tape size and density
* 9-track 1600 bpi (160 bytes/.1") 2300 ft.
* 9-track 6250 bpi (625 bytes/.1") 2300 ft.
* cartridge 8000 bpi (100 bytes/.1") 1700 ft.
density
= cartridge
? 100 : 160;
tsize
= cartridge
? 1700L*120L : 2300L*120L;
msg("need keyletter ``f'' and device ``host:tape''\n");
setuid(getuid()); /* rmthost() is the only reason to be setuid */
if (signal(SIGHUP
, SIG_IGN
) != SIG_IGN
)
if (signal(SIGTRAP
, SIG_IGN
) != SIG_IGN
)
signal(SIGTRAP
, sigtrap
);
if (signal(SIGFPE
, SIG_IGN
) != SIG_IGN
)
if (signal(SIGBUS
, SIG_IGN
) != SIG_IGN
)
if (signal(SIGSEGV
, SIG_IGN
) != SIG_IGN
)
signal(SIGSEGV
, sigsegv
);
if (signal(SIGTERM
, SIG_IGN
) != SIG_IGN
)
signal(SIGTERM
, sigterm
);
if (signal(SIGINT
, interrupt
) == SIG_IGN
)
set_operators(); /* /etc/group snarfed */
getfstab(); /* /etc/fstab snarfed */
* disk can be either the full special file name,
* the suffix of the special file name,
* the special name missing the leading '/',
* the file system name with or without the leading '/'.
disk
= rawname(dt
->fs_spec
);
strncpy(spcl
.c_dev
, dt
->fs_spec
, NAMELEN
);
strncpy(spcl
.c_filesys
, dt
->fs_file
, NAMELEN
);
strncpy(spcl
.c_dev
, disk
, NAMELEN
);
strncpy(spcl
.c_filesys
, "an unlisted file system", NAMELEN
);
strcpy(spcl
.c_label
, "none");
gethostname(spcl
.c_host
, NAMELEN
);
spcl
.c_level
= incno
- '0';
getitime(); /* /etc/dumpdates snarfed */
msg("Date of this level %c dump: %s\n", incno
, prdate(spcl
.c_date
));
msg("Date of last level %c dump: %s\n",
lastincno
, prdate(spcl
.c_ddate
));
msg("Dumping %s ", disk
);
msgtail("(%s) ", dt
->fs_file
);
msgtail("to %s on host %s\n", tape
, host
);
msgtail("to %s\n", tape
);
msg("Cannot open %s\n", disk
);
sblock
= (struct fs
*)buf
;
bread(SBOFF
, sblock
, SBSIZE
);
if (sblock
->fs_magic
!= FS_MAGIC
)
quit("bad sblock magic number\n");
dev_bsize
= sblock
->fs_fsize
/ fsbtodb(sblock
, 1);
dev_bshift
= ffs(dev_bsize
) - 1;
if (dev_bsize
!= (1 << dev_bshift
))
quit("dev_bsize (%d) is not a power of 2", dev_bsize
);
tp_bshift
= ffs(TP_BSIZE
) - 1;
if (TP_BSIZE
!= (1 << tp_bshift
))
quit("TP_BSIZE (%d) is not a power of 2", TP_BSIZE
);
msiz
= roundup(howmany(sblock
->fs_ipg
* sblock
->fs_ncg
, NBBY
),
clrmap
= (char *)calloc(msiz
, sizeof(char));
dirmap
= (char *)calloc(msiz
, sizeof(char));
nodmap
= (char *)calloc(msiz
, sizeof(char));
msg("mapping (Pass I) [regular files]\n");
pass(mark
, (char *)NULL
); /* mark updates esize */
msg("mapping (Pass II) [directories]\n");
} else /* keep the operators happy */
msg("mapping (Pass II) [directories]\n");
esize
+= 10; /* 10 trailer blocks */
fetapes
= esize
/ blocksperfile
;
/* Estimate number of tapes, assuming streaming stops at
the end of each block written, and not in mid-block.
Assume no erroneous blocks; this can be compensated
for with an artificially low tape size. */
* TP_BSIZE
/* bytes/block */
* (1.0/density
) /* 0.1" / byte */
* (1.0/ntrec
) /* streaming-stops per block */
* 15.48 /* 0.1" / streaming-stop */
) * (1.0 / tsize
); /* tape / 0.1" */
/* Estimate number of tapes, for old fashioned 9-track
int tenthsperirg
= (density
== 625) ? 3 : 7;
* TP_BSIZE
/* bytes / block */
* (1.0/density
) /* 0.1" / byte */
* (1.0/ntrec
) /* IRG's / block */
* tenthsperirg
/* 0.1" / IRG */
) * (1.0 / tsize
); /* tape / 0.1" */
etapes
= fetapes
; /* truncating assignment */
/* count the nodemap on each additional tape */
for (i
= 1; i
< etapes
; i
++)
esize
+= i
+ 10; /* headers + 10 trailer blocks */
msg("estimated %ld tape blocks.\n", esize
);
msg("estimated %ld tape blocks on %3.2f tape(s).\n",
alloctape(); /* Allocate tape buffer */
otape(); /* bitmap is the first to tape write */
msg("dumping (Pass III) [directories]\n");
msg("dumping (Pass IV) [regular files]\n");
msg("DUMP: %ld tape blocks\n",spcl
.c_tapea
);
msg("DUMP: %ld tape blocks on %d volumes(s)\n",
spcl
.c_tapea
, spcl
.c_volume
);
broadcast("DUMP IS DONE!\7\7\n");
quit("Unknown signal, cannot recover\n");
msg("Rewriting attempted as response to unknown signal.\n");
void sighup(){ msg("SIGHUP() try rewriting\n"); sigAbort();}
void sigtrap(){ msg("SIGTRAP() try rewriting\n"); sigAbort();}
void sigfpe(){ msg("SIGFPE() try rewriting\n"); sigAbort();}
void sigbus(){ msg("SIGBUS() try rewriting\n"); sigAbort();}
void sigsegv(){ msg("SIGSEGV() ABORTING!\n"); abort();}
void sigalrm(){ msg("SIGALRM() try rewriting\n"); sigAbort();}
void sigterm(){ msg("SIGTERM() try rewriting\n"); sigAbort();}
char *dp
= rindex(cp
, '/');