xref: /csrg-svn/local/ukc/dump/dumplabel.c (revision 32045)
132027Spc #ifndef lint
2*32045Spc static char *sccsid = "@(#)dumplabel.c	1.3 (UKC) 08/11/87";
332027Spc #endif not lint
432027Spc /***
532027Spc 
632027Spc * program name:
732027Spc 	dumplabel.c
832027Spc * function:
932027Spc 	prints the label from a header
1032027Spc 	writes a dummy dump header at the start of a tape
1132027Spc 	Doesn't do any checksum
1232027Spc * switches:
1332027Spc 	-f <tapename>
1432027Spc 	-r	rewind/offline each tape
1532027Spc 	-l	label format
1632027Spc 	followed by list of tape labels in the same format at given to the
1732027Spc 		locally modified dump program
1832027Spc 	if no tape labels are given print the details on the start of a tape
1932027Spc * libraries used:
2032027Spc 	standard
2132027Spc * compile time parameters:
2232027Spc 	cc -o dumplabel dumplabel.c
2332027Spc * history:
2432027Spc 	Written August 1987 Peter Collinson UKC
2532027Spc 
2632027Spc ***/
2732027Spc #include "dump.h"
2832027Spc #include <sys/ioctl.h>
2932027Spc #include <sys/mtio.h>
3032027Spc 
3132027Spc #define	LABMAX	100		/* get space for 100 */
3232027Spc 
3332027Spc char	*labarg[LABMAX];	/* vector of map entries */
3432027Spc 
3532027Spc char	*labfmt;		/* format for tape label */
3632027Spc 
3732027Spc int	labct;			/* number of entries */
3832027Spc 				/* if zero then no labels used */
3932027Spc 
4032027Spc char *tape = "/dev/rmt8";
4132027Spc 
4232027Spc int	dorew;			/* set if rewind offline on exit */
4332027Spc int	tapecount;		/* number of tapes dealt with */
4432027Spc 
4532029Spc char	*index();
4632027Spc 
main(argc,argv)4732027Spc main(argc, argv)
4832027Spc char **argv;
4932027Spc {	register i;
5032027Spc 	register char *p;
5132027Spc 	while (--argc) {
5232027Spc 		argv++;
5332027Spc 		if (**argv == '-') {
5432027Spc 			for (p = *argv; *p; p++)
5532027Spc 				switch (*p) {
5632027Spc 
5732027Spc 				case 'f':
5832027Spc 					if (--argc > 0) {
5932027Spc 						argv++;
6032027Spc 						tape = *argv;
6132027Spc 					}
6232027Spc 					break;
6332027Spc 				case 'r':
6432027Spc 					dorew++;	/* no rewind/offline */
6532027Spc 					break;
6632027Spc 				case 'l':
6732027Spc 					if (--argc > 0) {
6832027Spc 						argv++;
6932027Spc 						labfmt = *argv;
7032027Spc 					}
7132027Spc 				}
7232027Spc 		} else {
7332029Spc 			storelabelmap(*argv);
7432029Spc 			if (labfmt && labct)
7532029Spc 				if (index(labfmt, '%') == NULL)
7632029Spc 					fprintf(stderr, "Warning - no format specifier (%%s) found in -l argument\n");
7732027Spc 			for (i = 1; i <= labct; i++)
7832027Spc 				dolabel(i);
7932027Spc 			labct = 0;
8032027Spc 		}
8132027Spc 	}
8232027Spc 	if (tapecount == 0) {
8332027Spc 		if (labfmt) {
8432027Spc 			labct = 0;
8532027Spc 			dolabel(1);	/* pretend a volume number of 1 */
8632027Spc 		} else
8732029Spc 			printlabel();
8832027Spc 	}
8932027Spc 	exit(0);
9032027Spc }
9132027Spc 
9232027Spc /*
9332027Spc  *	Store map list
9432027Spc  *	The map list
9532027Spc  *	allows a simple way to specify a range of tapes
9632027Spc  *	This generates a string which is inserted into the label format
9732027Spc  *	by use of an sprint operation
9832027Spc  *
9932027Spc  *	The basic form here is:
10032027Spc  *	<string>			a single string
10132027Spc  *	<string>,<string>,......	a list of strings
10232027Spc  *	<string>-<string>		a range of strings
10332027Spc  *					where the string is `incremented'
10432027Spc  *					to generate a list
10532027Spc  */
storelabelmap(arg)10632027Spc storelabelmap(arg)
10732027Spc 	char *arg;
10832027Spc {
10932027Spc 	register char *ss, *es;
11032027Spc 	register char *incbase, *incr;
11132027Spc 	register lastc;
11232027Spc 	char *labskip();
11332027Spc 	char *strstore();
11432027Spc 
11532027Spc 	/*
11632027Spc 	 *	Parse the argument looking for a single string
11732027Spc 	 */
11832029Spc 	for (ss = arg; *ss; ss = es) {
11932027Spc 		es = labskip(ss);
12032027Spc 		lastc = *es;	/* save last character */
12132027Spc 		*es++ = '\0';	/* make the first label into a string */
12232027Spc 		if (labct > LABMAX)
12332027Spc 			labfatal("Too many (> %d) tape labels specified\n", LABMAX);
12432029Spc 		if (*ss == '\0')
12532029Spc 			labfatal("Zero length label found\n");
12632027Spc 		labarg[labct++] = strstore(ss);
12732027Spc 
12832027Spc 		if (lastc == 0)
12932027Spc 			break;		/* end of list */
13032027Spc 
13132027Spc 		if (lastc == '-') {
13232027Spc 			/*
13332027Spc 			 * this gives a tape range
13432027Spc 			 * increment the source number until it equals the final
13532027Spc 			 * value
13632027Spc 			 */
13732027Spc 			incbase = ss;
13832027Spc 			ss = es;
13932027Spc 			es = labskip(ss);
14032027Spc 			if (*es == '-')
14132027Spc 				labfatal("Range has the format <string>-<string>\n");
14232027Spc 			lastc = *es;
14332029Spc 			if (lastc)
14432029Spc 				*es++ = '\0';
14532027Spc 			/*
14632027Spc 			 * basic test the source string length must be equal to the
14732027Spc 			 * end string length
14832027Spc 			 */
14932027Spc 			if (strlen(incbase) != strlen(ss))
15032027Spc 				labfatal("strlen(\"%s\") != strlen(\"%s\")\n", incbase, ss);
15132027Spc 			labelrange(incbase, ss);
15232027Spc 		}
15332027Spc 	}
15432027Spc }
15532027Spc 
15632027Spc /*
15732027Spc  *	Expand a label range
15832027Spc  */
15932027Spc /* static */
labelrange(startrange,endrange)16032027Spc labelrange(startrange, endrange)
16132027Spc 	char *startrange, *endrange;
16232027Spc {
16332027Spc 	register char *incr;
16432027Spc 	register int carry;
16532027Spc 
16632027Spc 
16732027Spc 	for (incr = startrange + strlen(startrange) - 1;
16832027Spc 			strcmp(startrange, endrange) != 0; ) {
16932027Spc 		/* start incrementing */
17032029Spc 		carry = 0;
17132029Spc 		do {
17232027Spc 			if (isdigit(*incr)) {
17332027Spc 				if (*incr == '9') {
17432027Spc 					*incr = '0';
17532027Spc 					carry = 1;
17632027Spc 				} else
17732029Spc 					(*incr)++;
17832027Spc 			} else
17932027Spc 			if (isupper(*incr)) {
18032027Spc 				if (*incr == 'Z') {
18132027Spc 					*incr = 'A';
18232027Spc 					carry = 1;
18332027Spc 				} else
18432029Spc 					(*incr)++;
18532027Spc 			} else
18632027Spc 			if (islower(*incr)) {
18732027Spc 				if (*incr == 'z') {
18832027Spc 					*incr = 'a';
18932027Spc 					carry = 1;
19032027Spc 				} else
19132029Spc 					(*incr)++;
19232027Spc 			} else
19332027Spc 				labfatal("Problem with label map range spec - can only increment alphanumeric values\n");
19432027Spc 			if (carry) {
19532027Spc 				incr--;
19632027Spc 				if (incr < startrange)
19732027Spc 					labfatal("Problem with label map range spec - end of range reached\n");
19832027Spc 			}
19932029Spc 		} while (carry);
20032029Spc 
20132027Spc 		if (labct > LABMAX)
20232027Spc 			labfatal("Too many (> %d) tape labels specified\n", LABMAX);
20332027Spc 		labarg[labct++] = strstore(startrange);
20432027Spc 
20532027Spc 	}
20632027Spc }
20732027Spc 
20832027Spc /*
20932027Spc  *	Store a string using malloc
21032027Spc  */
21132027Spc /* static */
21232027Spc char *
strstore(arg)21332027Spc strstore(arg)
21432027Spc 	char *arg;
21532027Spc {
21632027Spc 	register len = strlen(arg)+1;
21732027Spc 	register char *dest;
21832027Spc 	char *malloc();
21932027Spc 
22032027Spc 	dest = malloc(len);
22132027Spc 	if (dest == NULL)
22232027Spc 		labfatal("No memory for string storage\n");
22332027Spc 	bcopy(arg, dest, len);
22432027Spc 	return(dest);
22532027Spc }
22632027Spc 
22732027Spc /*
22832027Spc  *	Create a tape label from a volume number
22932027Spc  */
23032027Spc char *
createlabel(volno)23132027Spc createlabel(volno)
23232027Spc 	int volno;
23332027Spc {
23432027Spc 	static char buf[LBLSIZE+LBLSIZE];
23532027Spc 	char volbuf[8];
23632027Spc 	register char *arg;
23732027Spc 
23832027Spc 
23932027Spc 	if (labfmt == NULL)
24032027Spc 		labfmt = "%s";
24132027Spc 
24232027Spc 	if (labct == 0)
24332027Spc 	{	(void) sprintf(volbuf, "%d", volno);
24432027Spc 		arg = volbuf;
24532027Spc 	}
24632027Spc 	else
24732027Spc 		arg = labarg[volno-1];		/* volumes run 1-> */
24832027Spc 	(void) sprintf(buf, labfmt, arg);
24932027Spc 	buf[LBLSIZE-1] = '\0';			/* Truncate to correct size */
25032027Spc 	return(buf);
25132027Spc }
25232027Spc 
25332027Spc /*
25432027Spc  *	skip forward looking for valid end of label characters
25532027Spc  */
25632027Spc char *
labskip(str)25732027Spc labskip(str)
25832027Spc register char *str;
25932027Spc {	while (*str != ',' && *str != '-' && *str)
26032027Spc 		str++;
26132027Spc 	return (str);
26232027Spc }
26332027Spc 
26432027Spc /*
26532027Spc  *	do the actual labelling
26632027Spc  */
dolabel(index)26732027Spc dolabel(index)
26832027Spc {	register fd;
26932027Spc 
27032029Spc 	tapecount++;
27132029Spc 	askformount(index);
27232027Spc 
27332027Spc 	while ((fd = open(tape, 2)) < 0)
27432027Spc 	{	fprintf(stderr, "Tape open error\n");
27532027Spc 		askformount(index);
27632027Spc 	}
277*32045Spc 	if (spcl.c_host[0] == '\0')
278*32045Spc 	{	gethostname(spcl.c_host, NAMELEN);
279*32045Spc 		spcl.c_level = 0;
280*32045Spc 		strcpy(spcl.c_filesys, "Tape has only been labelled");
281*32045Spc 		strcpy(spcl.c_dev, "???????????");
282*32045Spc 	}
28332027Spc 	strcpy(spcl.c_label, createlabel(index));
28432027Spc 	if (write(fd, (char *)&u_spcl, sizeof (u_spcl)) != sizeof (u_spcl))
28532027Spc 	{	perror("Tape write error");
28632027Spc 		exit(1);
28732027Spc 	}
28832027Spc 	rewind(fd);
28932027Spc 	close(fd);
29032027Spc }
29132027Spc 
29232027Spc /*
29332027Spc  *	ask for a tape to be mounted
29432027Spc  */
askformount(index)29532027Spc askformount(index)
29632027Spc {
29732029Spc 	while (query("Mount tape `%s'\nReady to go? ", createlabel(index)) != 1);
29832027Spc }
29932027Spc 
30032027Spc /*
30132027Spc  *	ask yes/no question
30232027Spc  *	return	1 on yes
30332027Spc  *		0 on no
30432027Spc  */
query(question,arg)30532027Spc query(question, arg)
30632027Spc char	*question;
30732027Spc char *arg;
30832027Spc {
30932027Spc 	char	replybuffer[64];
31032027Spc 	int	back;
31132027Spc 
31232029Spc 	for(;;) {
31332027Spc 		fprintf(stdout, question, arg);
31432027Spc 		fflush(stdout);
31532029Spc 		if (fgets(replybuffer, 63, stdin) == NULL) {
31632029Spc 			if(ferror(stdin)) {
31732029Spc 				clearerr(stdin);
31832027Spc 				continue;
31932027Spc 			}
32032027Spc 		}
32132029Spc 		else {
32232029Spc 			qclean(replybuffer);
32332029Spc 			if (strcmp(replybuffer, "yes") == 0 ||
32432029Spc 			    strcmp(replybuffer, "y") == 0) {
32532029Spc 				back = 1;
32632029Spc 				goto done;
32732029Spc 			}
32832029Spc 			else
32932029Spc 			if (strcmp(replybuffer, "no") == 0 ||
33032029Spc 			    strcmp(replybuffer, "n") == 0) {
33132029Spc 				if (query("Abort? "))
33232029Spc 					labfatal("Aborting\n");
33332029Spc 				back = 0;
33432029Spc 				goto done;
33532029Spc 			}
33632029Spc 			else
33732029Spc 				fprintf(stderr, "\"yes\" or \"no\" ONLY!\n");
33832027Spc 		}
33932027Spc 	}
34032027Spc     done:
34132027Spc 	return(back);
34232027Spc }
34332027Spc 
qclean(ptr)34432029Spc qclean(ptr)
34532029Spc 	register char *ptr;
34632029Spc {
34732029Spc 	for (;*ptr; ptr++) {
34832029Spc 		if (isupper(*ptr))
34932029Spc 			*ptr = tolower(*ptr);
35032029Spc 		if (*ptr == '\n') {
35132029Spc 			*ptr = '\0';
35232029Spc 			break;
35332029Spc 		}
35432029Spc 	}
35532029Spc }
35632029Spc 
rewind(fd)35732027Spc rewind(fd)
35832027Spc {
35932027Spc 	struct mtop mtop;
36032029Spc 
36132029Spc 	if (dorew) {
36232029Spc 		mtop.mt_op = MTOFFL;
36332027Spc 		mtop.mt_count = 1;
36432027Spc 		ioctl(fd, MTIOCTOP, &mtop);
36532027Spc 	}
36632027Spc }
36732027Spc 
36832027Spc /*
36932027Spc  *	fatal error message routine
37032027Spc  */
labfatal(fmt,a1,a2,a3,a4,a5)37132027Spc labfatal(fmt, a1, a2, a3, a4, a5)
37232029Spc 	char	*fmt;
37332029Spc 	int	a1, a2, a3, a4, a5;
37432029Spc {
37532029Spc 	fprintf(stderr, fmt, a1, a2, a3, a4, a5);
37632027Spc 	exit(1);
37732027Spc }
37832027Spc 
37932027Spc /*
38032027Spc  *	print the label from a tape
38132027Spc  */
printlabel()38232027Spc printlabel()
38332027Spc {
38432027Spc 	register fd;
38532027Spc 
38632029Spc 	if ((fd = open(tape, 2)) < 0) {
38732029Spc 		perror("Tape open error");
38832027Spc 		exit(1);
38932027Spc 	}
39032029Spc 	if (read(fd, (char *)&u_spcl, sizeof u_spcl) < 0) {
39132029Spc 		perror("Tape read");
39232027Spc 		exit(1);
39332027Spc 	}
394*32045Spc 	printf("Dump   date: %s", ctime(&spcl.c_date));
395*32045Spc 	printf("Dumped from: %s", ctime(&spcl.c_ddate));
396*32045Spc 	if (spcl.c_host[0] == '\0')
397*32045Spc 		return;
398*32045Spc 	printf("Level %d dump of %s on %s:%s\n",
399*32045Spc 		spcl.c_level, spcl.c_filesys, spcl.c_host, spcl.c_dev);
400*32045Spc 	printf("Label: %s\n", spcl.c_label);
401*32045Spc 	printf("Volume %d of the dump, starting at inode %d\n",
402*32045Spc 			spcl.c_volume, spcl.c_inumber);
40332027Spc 	close(fd);
40432027Spc }
405