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