static char *sccsid
= "@(#)dumplab.c 1.3 (UKC) %G%";
* This file included by Peter Collinson
* to handle tape labelling
* There are two dump parameters which are used to specify labels
* -l Give the basic label format string - this may contain
* a single %s to insert the volume number string
* -m Map string - used to map volume numbers into a string
* storelabel(arg) - called from main() to store a label format
* storelabelmap(arg) - called from main() to process a map argument
* string-string expanded by incrementing
* string,string,..list of the above
* createlabel(volno) - returns a label appropriate for the volume
* initialtape() - called to print an operator message asking for
* labelest(etapes) - checks if there are enough tape labels
* - specified for a given dump
* labelcheck() - reads one record from tape
* - checks that the labels match
* - backspace one record back
* - so that multi-volume dumps work
* log_volume() - write a logfile entry for the volume
#define LABMAX 100 /* get space for 100 */
char *labfmt
; /* Basic tape format */
char *labarg
[LABMAX
]; /* Pointer to argument list */
int labct
; /* number of entries */
/* if zero then no labels used */
int userlabel
; /* set if user has given a label */
int labchk
; /* check labels - set by t(est) flag */
* The file /etc/dumpvolumes is used to maintain a log of
* tapes which are/have been used for tape dumping
* label: date dev=<devname> level=<dump level> reel=<volume number> inode=<start inode>
char dumpvolumes
[] = "/etc/dumpvolumes";
* Called from argument decoding to store the
* This is the parameter to the -l parameter
* allows a simple way to specify a range of tapes
* This generates a string which is inserted into the label format
* by use of an sprint operation
* The basic form here is:
* <string> a single string
* <string>,<string>,...... a list of strings
* <string>-<string> a range of strings
* where the string is `incremented'
register char *incbase
, *incr
;
* Parse the argument looking for a single string
for (ss
= arg
; *ss
; ss
= es
) {
lastc
= *es
; /* save last character */
*es
++ = '\0'; /* make the first label into a string */
labfatal("Too many (> %d) tape labels specified\n", LABMAX
);
labfatal("Zero length tape label found\n");
labarg
[labct
++] = strstore(ss
);
* this gives a tape range
* increment the source number until it equals the final
labfatal("Range has the format <string>-<string>\n");
* basic test the source string length must be equal to the
if (strlen(incbase
) != strlen(ss
))
labfatal("strlen(\"%s\") != strlen(\"%s\")\n", incbase
, ss
);
labelrange(startrange
, endrange
)
char *startrange
, *endrange
;
for (incr
= startrange
+ strlen(startrange
) - 1;
strcmp(startrange
, endrange
) != 0; ) {
labfatal("Problem with label map range spec - can only increment alphanumeric values\n");
labfatal("Problem with label map range spec - end of range reached\n");
labfatal("Too many (> %d) tape labels specified\n", LABMAX
);
labarg
[labct
++] = strstore(startrange
);
* Store a string using malloc
register len
= strlen(arg
)+1;
labfatal("No memory for string storage\n");
* Create a tape label from a volume number
static char buf
[LBLSIZE
+LBLSIZE
];
return ("none"); /* previous behaviour */
if (volno
== lastvol
) /* cache */
{ (void) sprintf(volbuf
, "%d", volno
);
arg
= labarg
[volno
-1]; /* volumes run 1-> */
(void) sprintf(buf
, labfmt
, arg
);
buf
[LBLSIZE
-1] = '\0'; /* Truncate to correct size */
msg("Mount tape %s for reel 1 of the dump\n", createlabel(1));
* given an estimated number of tapes, check that
* there are enough tapes on the label list
labfatal("Only %d labe%s given, estimated need %d\n",
labct
, labct
== 1 ? "l" : "ls", et
);
* read a dump header and check that the tape header contains
* close the tape after use
register char *ontape
= uin
.s_spcl
.c_label
;
if (labchk
== 0 || pipeout
)
label
= createlabel(tno
);
/* doing it this way to make it easier to read */
while (rmtopen(tape
, 0) < 0)
if (!query("Cannot open tape. Do you want to retry the open?"))
if (rmtread((char *)&uin
, sizeof uin
) != sizeof uin
) {
msg("Tape does not start with the correctly sized record\n");
strcmp(ontape
, "none") == 0 ||
strcmp(ontape
, label
) == 0) {
msg("Tape labels do not match should be `%s' is `%s'\n", label
, ontape
);
while ((fd
= open(tape
, 0)) < 0)
if (!query("Cannot open tape. Do you want to retry the open?"))
if (read(fd
, (char *)&uin
, sizeof uin
) != sizeof uin
) {
msg("Tape does not start with the correctly sized record\n");
strcmp(ontape
, "none") == 0 ||
strcmp(ontape
, label
) == 0) {
msg("Tape labels do not match should be `%s' is `%s'\n", label
, ontape
);
* write a log entry for the volume into the log file
if (uflag
== 0 || labchk
== 0)
if ((logfd
= fopen(dumpvolumes
, "a")) == NULL
)
fprintf(logfd
, "%s: date=%20.20s dev=%s level=%c reel=%d ino=%d\n",
tlabel
, ctime(&spcl
.c_date
)+4, disk
, incno
, tapeno
,
tapeno
== 1 ? ROOTINO
: ino
);
* skip forward looking for valid end of label characters
while (*str
!= ',' && *str
!= '-' && *str
)
* generate a fatal error message
labfatal(fmt
, a1
, a2
, a3
, a4
, a5
)
msg(fmt
, a1
, a2
, a3
, a4
, a5
);