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