xref: /original-bsd/usr.bin/mt/mt.c (revision 0b685140)
1 static	char *sccsid = "@(#)mt.c	4.3 (Berkeley) 81/11/12";
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 #include <sys/mtreg.h>
91 #include <sys/utreg.h>
92 #include <sys/htreg.h>
93 #include <sys/tmreg.h>
94 #undef b_repcnt		/* argh */
95 #include <sys/tsreg.h>
96 
97 struct tape_desc {
98 	short	t_type;		/* type of magtape device */
99 	char	*t_name;	/* printing name */
100 	char	*t_dsbits;	/* "drive status" register */
101 	char	*t_erbits;	/* "error" register */
102 } tapes[] = {
103 	{ MT_ISTS,	"ts11",		0,		TSXS0_BITS },
104 	{ MT_ISHT,	"tm03",		HTDS_BITS,	HTER_BITS },
105 	{ MT_ISTM,	"tm11",		0,		TMER_BITS },
106 	{ MT_ISMT,	"tu78",		MTDS_BITS,	0 },
107 	{ MT_ISUT,	"tu45",		UTDS_BITS,	UTER_BITS },
108 	{ 0 }
109 };
110 
111 /*
112  * Interpret the status buffer returned
113  */
114 status(bp)
115 	register struct mtget *bp;
116 {
117 	register struct tape_desc *mt;
118 
119 	for (mt = tapes; mt->t_type; mt++)
120 		if (mt->t_type == bp->mt_type)
121 			break;
122 	if (mt->t_type == 0) {
123 		printf("unknown tape drive type (%d)\n", bp->mt_type);
124 		return;
125 	}
126 	printf("%s tape drive\n", mt->t_name);
127 	printreg("ds", bp->mt_dsreg, mt->t_dsbits);
128 	printreg(" er", bp->mt_erreg, mt->t_erbits);
129 	printf("\nresidual=%d\n", bp->mt_resid);
130 }
131 
132 /*
133  * Print a register a la the %b format of the kernel's printf
134  */
135 printreg(s, v, bits)
136 	char *s, *bits;
137 	unsigned short v;
138 {
139 	register int i, any = 0;
140 	register char c;
141 
142 	printf("%s=%o", s, v);
143 	if (v && bits) {
144 		putchar('<');
145 		while (i = *bits++) {
146 			if (v & (1 << (i-1))) {
147 				if (any)
148 					putchar(',');
149 				any = 1;
150 				for (; (c = *bits) > 32; bits++)
151 					putchar(c);
152 			} else
153 				for (; *bits > 32; bits++)
154 					;
155 		}
156 		if (any)
157 			putchar('>');
158 	}
159 }
160