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