xref: /original-bsd/usr.bin/mt/mt.c (revision f0fd5f8a)
1 static	char *sccsid = "@(#)mt.c	4.4 (Berkeley) 82/12/19";
2 /*
3  * mt --
4  *   magnetic tape manipulation program
5  */
6 #include <stdio.h>
7 #include <ctype.h>
8 #include <sys/types.h>
9 #include <sys/mtio.h>
10 #include <sys/ioctl.h>
11 
12 #define	equal(s1,s2)	(strcmp(s1, s2) == 0)
13 #define	DEFTAPE		"/dev/rmt12"
14 
15 struct commands {
16 	char *c_name;
17 	int c_code;
18 	int c_ronly;
19 } com[] = {
20 	{ "weof",	MTWEOF,	0 },
21 	{ "eof",	MTWEOF,	0 },
22 	{ "fsf",	MTFSF,	1 },
23 	{ "bsf",	MTBSF,	1 },
24 	{ "fsr",	MTFSR,	1 },
25 	{ "bsr",	MTBSR,	1 },
26 	{ "rewind",	MTREW,	1 },
27 	{ "offline",	MTOFFL,	1 },
28 	{ "rewoffl",	MTOFFL,	1 },
29 	{ "status",	MTNOP,	1 },
30 	{ 0 }
31 };
32 
33 int mtfd;
34 struct mtop mt_com;
35 struct mtget mt_status;
36 char *tape;
37 
38 main(argc, argv)
39 	char **argv;
40 {
41 	char line[80], *getenv();
42 	register char *cp;
43 	register struct commands *comp;
44 
45 	if (argc < 2) {
46 		fprintf(stderr, "usage: mt [ -f device ] command [ count ]\n");
47 		exit(1);
48 	}
49 	if ((equal(argv[1], "-t") || equal(argv[1], "-f")) && argc > 2) {
50 		argc -= 2;
51 		tape = argv[2];
52 		argv += 2;
53 	} else
54 		if ((tape = getenv("TAPE")) == NULL)
55 			tape = DEFTAPE;
56 	cp = argv[1];
57 	for (comp = com; comp->c_name != NULL; comp++)
58 		if (strncmp(cp, comp->c_name, strlen(cp)) == 0)
59 			break;
60 	if (comp->c_name == NULL) {
61 		fprintf(stderr, "mt: don't grok \"%s\"\n", cp);
62 		exit(1);
63 	}
64 	if ((mtfd = open(tape, comp->c_ronly ? 0 : 2)) < 0) {
65 		perror(tape);
66 		exit(1);
67 	}
68 	if (comp->c_code != MTNOP) {
69 		mt_com.mt_op = comp->c_code;
70 		mt_com.mt_count = (argc > 2 ? atoi(argv[2]) : 1);
71 		if (mt_com.mt_count < 0) {
72 			fprintf(stderr, "mt: negative repeat count\n");
73 			exit(1);
74 		}
75 		if (ioctl(mtfd, MTIOCTOP, &mt_com) < 0) {
76 			fprintf(stderr, "%s %d ", comp->c_name,
77 				mt_com.mt_count);
78 			perror("failed");
79 			exit(2);
80 		}
81 	} else {
82 		if (ioctl(mtfd, MTIOCGET, (char *)&mt_status) < 0) {
83 			perror("mt");
84 			exit(2);
85 		}
86 		status(&mt_status);
87 	}
88 }
89 
90 #ifdef vax
91 #include <vaxmba/mtreg.h>
92 #include <vaxmba/htreg.h>
93 
94 #include <vaxuba/utreg.h>
95 #include <vaxuba/tmreg.h>
96 #undef b_repcnt		/* argh */
97 #include <vaxuba/tsreg.h>
98 #endif
99 
100 struct tape_desc {
101 	short	t_type;		/* type of magtape device */
102 	char	*t_name;	/* printing name */
103 	char	*t_dsbits;	/* "drive status" register */
104 	char	*t_erbits;	/* "error" register */
105 } tapes[] = {
106 #ifdef vax
107 	{ MT_ISTS,	"ts11",		0,		TSXS0_BITS },
108 	{ MT_ISHT,	"tm03",		HTDS_BITS,	HTER_BITS },
109 	{ MT_ISTM,	"tm11",		0,		TMER_BITS },
110 	{ MT_ISMT,	"tu78",		MTDS_BITS,	0 },
111 	{ MT_ISUT,	"tu45",		UTDS_BITS,	UTER_BITS },
112 #endif
113 	{ 0 }
114 };
115 
116 /*
117  * Interpret the status buffer returned
118  */
119 status(bp)
120 	register struct mtget *bp;
121 {
122 	register struct tape_desc *mt;
123 
124 	for (mt = tapes; mt->t_type; mt++)
125 		if (mt->t_type == bp->mt_type)
126 			break;
127 	if (mt->t_type == 0) {
128 		printf("unknown tape drive type (%d)\n", bp->mt_type);
129 		return;
130 	}
131 	printf("%s tape drive\n", mt->t_name);
132 	printreg("ds", bp->mt_dsreg, mt->t_dsbits);
133 	printreg(" er", bp->mt_erreg, mt->t_erbits);
134 	printf("\nresidual=%d\n", bp->mt_resid);
135 }
136 
137 /*
138  * Print a register a la the %b format of the kernel's printf
139  */
140 printreg(s, v, bits)
141 	char *s, *bits;
142 	unsigned short v;
143 {
144 	register int i, any = 0;
145 	register char c;
146 
147 	printf("%s=%o", s, v);
148 	if (v && bits) {
149 		putchar('<');
150 		while (i = *bits++) {
151 			if (v & (1 << (i-1))) {
152 				if (any)
153 					putchar(',');
154 				any = 1;
155 				for (; (c = *bits) > 32; bits++)
156 					putchar(c);
157 			} else
158 				for (; *bits > 32; bits++)
159 					;
160 		}
161 		if (any)
162 			putchar('>');
163 	}
164 }
165