* Copyright (c) 1980, 1991 The Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
"@(#) Copyright (c) 1980, 1991 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)dumpmain.c 5.16 (Berkeley) 4/24/91";
static char rcsid
[] = "$Header: /a/cvs/386BSD/src/sbin/dump/dumpmain.c,v 1.2 1993/07/22 16:49:16 jkh Exp $";
#include <protocols/dumprestore.h>
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 */
register struct dinode
*dp
;
register struct fstab
*dt
;
int i
, anydirskipped
, bflag
= 0;
tsize
= 0; /* Default later, based on 'c' option for cart tapes */
dumpdates
= _PATH_DUMPDATES
;
if (TP_BSIZE
/ DEV_BSIZE
== 0 || TP_BSIZE
% DEV_BSIZE
!= 0)
quit("TP_BSIZE must be a multiple of DEV_BSIZE\n");
for (cp
= *argv
++; cp
&& *cp
; cp
++) {
lastdump('w'); /* tell us only what has to be done */
case 'W': /* what to do */
lastdump('W'); /* tell us state of what is done */
exit(0); /* do nothing else */
case 'f': /* output file */
case 'd': /* density, in bits per inch */
density
= atoi(*argv
) / 10;
fprintf(stderr
, "bad density \"%s\"\n", *argv
);
if (density
>= 625 && !bflag
)
case 's': /* tape size, feet */
fprintf(stderr
, "bad size \"%s\"\n", *argv
);
case 'b': /* blocks per tape write */
fprintf(stderr
, "%s \"%s\"\n",
"bad number of blocks per write ", *argv
);
case 'B': /* blocks per output file */
blocksperfile
= atol(*argv
);
fprintf(stderr
, "%s \"%s\"\n",
"bad number of blocks per file ", *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", *cp
);
fprintf(stderr
, "missing argument to '%c'\n", *cp
);
fprintf(stderr
, "Must specify disk or filesystem\n");
fprintf(stderr
, "Unknown arguments to dump:");
fprintf(stderr
, " %s", *argv
++);
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");
if (rmthost(host
,user
) == 0)
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
= level
- '0';
getdumptime(); /* /etc/dumpdates snarfed */
msg("Date of this level %c dump: %s", level
,
spcl
.c_date
== 0 ? "the epoch\n" : ctime(&spcl
.c_date
));
msg("Date of last level %c dump: %s", lastlevel
,
spcl
.c_ddate
== 0 ? "the epoch\n" : ctime(&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
);
if ((diskfd
= open(disk
, O_RDONLY
)) < 0) {
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
);
maxino
= sblock
->fs_ipg
* sblock
->fs_ncg
- 1;
mapsize
= roundup(howmany(sblock
->fs_ipg
* sblock
->fs_ncg
, NBBY
),
usedinomap
= (char *)calloc(mapsize
, sizeof(char));
dumpdirmap
= (char *)calloc(mapsize
, sizeof(char));
dumpinomap
= (char *)calloc(mapsize
, sizeof(char));
tapesize
= 3 * (howmany(mapsize
* sizeof(char), TP_BSIZE
) + 1);
msg("mapping (Pass I) [regular files]\n");
anydirskipped
= mapfiles(maxino
, &tapesize
);
msg("mapping (Pass II) [directories]\n");
anydirskipped
= mapdirs(maxino
, &tapesize
);
tapesize
+= 10; /* 10 trailer blocks */
fetapes
= (float) tapesize
/ 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 dumped inodes map on each additional tape */
tapesize
+= (etapes
- 1) *
(howmany(mapsize
* sizeof(char), TP_BSIZE
) + 1);
tapesize
+= etapes
+ 10; /* headers + 10 trailer blks */
msg("estimated %ld tape blocks.\n", tapesize
);
msg("estimated %ld tape blocks on %3.2f tape(s).\n",
alloctape(); /* Allocate tape buffer */
dumpmap(usedinomap
, TS_CLRI
, maxino
);
msg("dumping (Pass III) [directories]\n");
for (map
= dumpdirmap
, ino
= 0; ino
< maxino
; ) {
* Skip directory inodes deleted and maybe reallocated
if ((dp
->di_mode
& IFMT
) != IFDIR
)
msg("dumping (Pass IV) [regular files]\n");
for (map
= dumpinomap
, ino
= 0; ino
< maxino
; ) {
* Skip inodes deleted and reallocated as directories.
if ((dp
->di_mode
& IFMT
) == IFDIR
)
for (i
= 0; i
< ntrec
; i
++)
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
);
for (i
= 0; i
< ntrec
; i
++)
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
, '/');