xref: /original-bsd/usr.bin/mt/mt.c (revision 2301fdfb)
1 /*
2  * Copyright (c) 1980 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)mt.c	5.3 (Berkeley) 08/31/88";
26 #endif /* not lint */
27 
28 /*
29  * mt --
30  *   magnetic tape manipulation program
31  */
32 #include <stdio.h>
33 #include <ctype.h>
34 #include <sys/types.h>
35 #include <sys/mtio.h>
36 #include <sys/ioctl.h>
37 
38 #define	equal(s1,s2)	(strcmp(s1, s2) == 0)
39 
40 struct commands {
41 	char *c_name;
42 	int c_code;
43 	int c_ronly;
44 } com[] = {
45 	{ "weof",	MTWEOF,	0 },
46 	{ "eof",	MTWEOF,	0 },
47 	{ "fsf",	MTFSF,	1 },
48 	{ "bsf",	MTBSF,	1 },
49 	{ "fsr",	MTFSR,	1 },
50 	{ "bsr",	MTBSR,	1 },
51 	{ "rewind",	MTREW,	1 },
52 	{ "offline",	MTOFFL,	1 },
53 	{ "rewoffl",	MTOFFL,	1 },
54 	{ "status",	MTNOP,	1 },
55 	{ 0 }
56 };
57 
58 int mtfd;
59 struct mtop mt_com;
60 struct mtget mt_status;
61 char *tape;
62 
63 main(argc, argv)
64 	char **argv;
65 {
66 	char line[80], *getenv();
67 	register char *cp;
68 	register struct commands *comp;
69 
70 	if (argc > 2 && (equal(argv[1], "-t") || equal(argv[1], "-f"))) {
71 		argc -= 2;
72 		tape = argv[2];
73 		argv += 2;
74 	} else
75 		if ((tape = getenv("TAPE")) == NULL)
76 			tape = DEFTAPE;
77 	if (argc < 2) {
78 		fprintf(stderr, "usage: mt [ -f device ] command [ count ]\n");
79 		exit(1);
80 	}
81 	cp = argv[1];
82 	for (comp = com; comp->c_name != NULL; comp++)
83 		if (strncmp(cp, comp->c_name, strlen(cp)) == 0)
84 			break;
85 	if (comp->c_name == NULL) {
86 		fprintf(stderr, "mt: don't grok \"%s\"\n", cp);
87 		exit(1);
88 	}
89 	if ((mtfd = open(tape, comp->c_ronly ? 0 : 2)) < 0) {
90 		perror(tape);
91 		exit(1);
92 	}
93 	if (comp->c_code != MTNOP) {
94 		mt_com.mt_op = comp->c_code;
95 		mt_com.mt_count = (argc > 2 ? atoi(argv[2]) : 1);
96 		if (mt_com.mt_count < 0) {
97 			fprintf(stderr, "mt: negative repeat count\n");
98 			exit(1);
99 		}
100 		if (ioctl(mtfd, MTIOCTOP, &mt_com) < 0) {
101 			fprintf(stderr, "%s %s %d ", tape, comp->c_name,
102 				mt_com.mt_count);
103 			perror("failed");
104 			exit(2);
105 		}
106 	} else {
107 		if (ioctl(mtfd, MTIOCGET, (char *)&mt_status) < 0) {
108 			perror("mt");
109 			exit(2);
110 		}
111 		status(&mt_status);
112 	}
113 }
114 
115 #ifdef vax
116 #include <vaxmba/mtreg.h>
117 #include <vaxmba/htreg.h>
118 
119 #include <vaxuba/utreg.h>
120 #include <vaxuba/tmreg.h>
121 #undef b_repcnt		/* argh */
122 #include <vaxuba/tsreg.h>
123 #endif
124 
125 #ifdef sun
126 #include <sundev/tmreg.h>
127 #include <sundev/arreg.h>
128 #endif
129 
130 #ifdef tahoe
131 #include <tahoevba/cyreg.h>
132 #endif
133 
134 struct tape_desc {
135 	short	t_type;		/* type of magtape device */
136 	char	*t_name;	/* printing name */
137 	char	*t_dsbits;	/* "drive status" register */
138 	char	*t_erbits;	/* "error" register */
139 } tapes[] = {
140 #ifdef vax
141 	{ MT_ISTS,	"ts11",		0,		TSXS0_BITS },
142 	{ MT_ISHT,	"tm03",		HTDS_BITS,	HTER_BITS },
143 	{ MT_ISTM,	"tm11",		0,		TMER_BITS },
144 	{ MT_ISMT,	"tu78",		MTDS_BITS,	0 },
145 	{ MT_ISUT,	"tu45",		UTDS_BITS,	UTER_BITS },
146 #endif
147 #ifdef sun
148 	{ MT_ISCPC,	"TapeMaster",	TMS_BITS,	0 },
149 	{ MT_ISAR,	"Archive",	ARCH_CTRL_BITS,	ARCH_BITS },
150 #endif
151 #ifdef tahoe
152 	{ MT_ISCY,	"cipher",	CYS_BITS,	CYCW_BITS },
153 #endif
154 	{ 0 }
155 };
156 
157 /*
158  * Interpret the status buffer returned
159  */
160 status(bp)
161 	register struct mtget *bp;
162 {
163 	register struct tape_desc *mt;
164 
165 	for (mt = tapes; mt->t_type; mt++)
166 		if (mt->t_type == bp->mt_type)
167 			break;
168 	if (mt->t_type == 0) {
169 		printf("unknown tape drive type (%d)\n", bp->mt_type);
170 		return;
171 	}
172 	printf("%s tape drive, residual=%d\n", mt->t_name, bp->mt_resid);
173 	printreg("ds", bp->mt_dsreg, mt->t_dsbits);
174 	printreg("\ner", bp->mt_erreg, mt->t_erbits);
175 	putchar('\n');
176 }
177 
178 /*
179  * Print a register a la the %b format of the kernel's printf
180  */
181 printreg(s, v, bits)
182 	char *s;
183 	register char *bits;
184 	register unsigned short v;
185 {
186 	register int i, any = 0;
187 	register char c;
188 
189 	if (bits && *bits == 8)
190 		printf("%s=%o", s, v);
191 	else
192 		printf("%s=%x", s, v);
193 	bits++;
194 	if (v && bits) {
195 		putchar('<');
196 		while (i = *bits++) {
197 			if (v & (1 << (i-1))) {
198 				if (any)
199 					putchar(',');
200 				any = 1;
201 				for (; (c = *bits) > 32; bits++)
202 					putchar(c);
203 			} else
204 				for (; *bits > 32; bits++)
205 					;
206 		}
207 		putchar('>');
208 	}
209 }
210