Release 6
[unix-history] / usr / src / usr.bin / mt / mt.c
CommitLineData
bcf1365c 1/*
ab567d4c
KB
2 * Copyright (c) 1980 The Regents of the University of California.
3 * All rights reserved.
4 *
f15db449 5 * %sccs.include.redist.c%
bcf1365c
DF
6 */
7
8#ifndef lint
9char copyright[] =
ab567d4c 10"@(#) Copyright (c) 1980 The Regents of the University of California.\n\
bcf1365c 11 All rights reserved.\n";
ab567d4c 12#endif /* not lint */
bcf1365c
DF
13
14#ifndef lint
b96a22bd 15static char sccsid[] = "@(#)mt.c 5.8 (Berkeley) %G%";
ab567d4c 16#endif /* not lint */
bcf1365c 17
d8c0aff8 18/*
209f2457
SL
19 * mt --
20 * magnetic tape manipulation program
d8c0aff8 21 */
d8c0aff8 22#include <sys/types.h>
d8c0aff8 23#include <sys/ioctl.h>
e667f2c6 24#include <sys/mtio.h>
83f4702a 25#include <fcntl.h>
b96a22bd
KB
26#include <errno.h>
27#include <stdlib.h>
e667f2c6
KB
28#include <stdio.h>
29#include <ctype.h>
b96a22bd 30#include <string.h>
209f2457 31
d8c0aff8
BJ
32struct commands {
33 char *c_name;
34 int c_code;
fdb20def 35 int c_ronly;
d8c0aff8 36} com[] = {
b96a22bd
KB
37 { "bsf", MTBSF, 1 },
38 { "bsr", MTBSR, 1 },
209f2457
SL
39 { "eof", MTWEOF, 0 },
40 { "fsf", MTFSF, 1 },
209f2457 41 { "fsr", MTFSR, 1 },
209f2457 42 { "offline", MTOFFL, 1 },
b96a22bd 43 { "rewind", MTREW, 1 },
209f2457
SL
44 { "rewoffl", MTOFFL, 1 },
45 { "status", MTNOP, 1 },
b96a22bd
KB
46 { "weof", MTWEOF, 0 },
47 { NULL }
d8c0aff8
BJ
48};
49
b96a22bd
KB
50void err __P((const char *, ...));
51void printreg __P((char *, u_int, char *));
52void status __P((struct mtget *));
53void usage __P((void));
d8c0aff8 54
b96a22bd 55int
d8c0aff8 56main(argc, argv)
b96a22bd
KB
57 int argc;
58 char *argv[];
d8c0aff8 59{
d8c0aff8 60 register struct commands *comp;
b96a22bd
KB
61 struct mtget mt_status;
62 struct mtop mt_com;
63 int ch, len, mtfd;
64 char *p, *tape;
65
66 if ((tape = getenv("TAPE")) == NULL)
67 tape = DEFTAPE;
68
69 while ((ch = getopt(argc, argv, "f:t:")) != EOF)
70 switch(ch) {
71 case 'f':
72 case 't':
73 tape = optarg;
74 break;
75 case '?':
76 default:
77 usage();
78 }
79 argc -= optind;
80 argv += optind;
d8c0aff8 81
b96a22bd
KB
82 if (argc < 1 || argc > 2)
83 usage();
84
85 len = strlen(p = *argv++);
86 for (comp = com;; comp++) {
87 if (comp->c_name == NULL)
88 err("%s: unknown command", p);
89 if (strncmp(p, comp->c_name, len) == 0)
d8c0aff8 90 break;
fdb20def 91 }
b96a22bd
KB
92 if ((mtfd = open(tape, comp->c_ronly ? O_RDONLY : O_RDWR)) < 0)
93 err("%s: %s", tape, strerror(errno));
209f2457
SL
94 if (comp->c_code != MTNOP) {
95 mt_com.mt_op = comp->c_code;
b96a22bd
KB
96 if (*argv) {
97 mt_com.mt_count = strtol(*argv, &p, 10);
98 if (mt_com.mt_count <= 0 || *p)
99 err("%s: illegal count", *argv);
209f2457 100 }
b96a22bd
KB
101 else
102 mt_com.mt_count = 1;
103 if (ioctl(mtfd, MTIOCTOP, &mt_com) < 0)
104 err("%s: %s: %s", tape, comp->c_name, strerror(errno));
209f2457 105 } else {
b96a22bd
KB
106 if (ioctl(mtfd, MTIOCGET, &mt_status) < 0)
107 err("%s", strerror(errno));
209f2457
SL
108 status(&mt_status);
109 }
b96a22bd
KB
110 exit (0);
111 /* NOTREACHED */
209f2457
SL
112}
113
09868be4 114#ifdef vax
5e19bd2f
KB
115#include <vax/mba/mtreg.h>
116#include <vax/mba/htreg.h>
09868be4 117
5e19bd2f
KB
118#include <vax/uba/utreg.h>
119#include <vax/uba/tmreg.h>
209f2457 120#undef b_repcnt /* argh */
5e19bd2f 121#include <vax/uba/tsreg.h>
09868be4 122#endif
209f2457 123
61fc63ff 124#ifdef sun
fba0261b
SL
125#include <sundev/tmreg.h>
126#include <sundev/arreg.h>
61fc63ff
SL
127#endif
128
24ecf073 129#ifdef tahoe
e667f2c6 130#include <tahoe/vba/cyreg.h>
24ecf073
SL
131#endif
132
209f2457
SL
133struct tape_desc {
134 short t_type; /* type of magtape device */
135 char *t_name; /* printing name */
136 char *t_dsbits; /* "drive status" register */
137 char *t_erbits; /* "error" register */
138} tapes[] = {
09868be4 139#ifdef vax
209f2457
SL
140 { MT_ISTS, "ts11", 0, TSXS0_BITS },
141 { MT_ISHT, "tm03", HTDS_BITS, HTER_BITS },
142 { MT_ISTM, "tm11", 0, TMER_BITS },
143 { MT_ISMT, "tu78", MTDS_BITS, 0 },
144 { MT_ISUT, "tu45", UTDS_BITS, UTER_BITS },
61fc63ff
SL
145#endif
146#ifdef sun
147 { MT_ISCPC, "TapeMaster", TMS_BITS, 0 },
fba0261b 148 { MT_ISAR, "Archive", ARCH_CTRL_BITS, ARCH_BITS },
24ecf073
SL
149#endif
150#ifdef tahoe
151 { MT_ISCY, "cipher", CYS_BITS, CYCW_BITS },
09868be4 152#endif
209f2457
SL
153 { 0 }
154};
155
156/*
157 * Interpret the status buffer returned
158 */
b96a22bd 159void
209f2457
SL
160status(bp)
161 register struct mtget *bp;
162{
163 register struct tape_desc *mt;
164
b96a22bd
KB
165 for (mt = tapes;; mt++) {
166 if (mt->t_type == 0) {
167 (void)printf("%d: unknown tape drive type\n",
168 bp->mt_type);
169 return;
170 }
209f2457
SL
171 if (mt->t_type == bp->mt_type)
172 break;
209f2457 173 }
b96a22bd 174 (void)printf("%s tape drive, residual=%d\n", mt->t_name, bp->mt_resid);
209f2457 175 printreg("ds", bp->mt_dsreg, mt->t_dsbits);
61fc63ff 176 printreg("\ner", bp->mt_erreg, mt->t_erbits);
b96a22bd 177 (void)putchar('\n');
209f2457
SL
178}
179
180/*
b96a22bd 181 * Print a register a la the %b format of the kernel's printf.
209f2457 182 */
b96a22bd 183void
209f2457 184printreg(s, v, bits)
61fc63ff 185 char *s;
b96a22bd 186 register u_int v;
61fc63ff 187 register char *bits;
209f2457
SL
188{
189 register int i, any = 0;
190 register char c;
191
61fc63ff
SL
192 if (bits && *bits == 8)
193 printf("%s=%o", s, v);
194 else
195 printf("%s=%x", s, v);
196 bits++;
209f2457
SL
197 if (v && bits) {
198 putchar('<');
199 while (i = *bits++) {
200 if (v & (1 << (i-1))) {
201 if (any)
202 putchar(',');
203 any = 1;
204 for (; (c = *bits) > 32; bits++)
205 putchar(c);
206 } else
207 for (; *bits > 32; bits++)
208 ;
209 }
61fc63ff 210 putchar('>');
d8c0aff8
BJ
211 }
212}
b96a22bd
KB
213
214void
215usage()
216{
217 (void)fprintf(stderr, "usage: mt [-f device] command [ count ]\n");
218 exit(1);
219}
220
221#if __STDC__
222#include <stdarg.h>
223#else
224#include <varargs.h>
225#endif
226
227void
228#if __STDC__
229err(const char *fmt, ...)
230#else
231err(fmt, va_alist)
232 char *fmt;
233 va_dcl
234#endif
235{
236 va_list ap;
237#if __STDC__
238 va_start(ap, fmt);
239#else
240 va_start(ap);
241#endif
242 (void)fprintf(stderr, "mt: ");
243 (void)vfprintf(stderr, fmt, ap);
244 va_end(ap);
245 (void)fprintf(stderr, "\n");
246 exit(1);
247 /* NOTREACHED */
248}