mt.c revision 1591
138032Speter/*
2132943Sgshapiro * Copyright (c) 1980, 1993
364562Sgshapiro *	The Regents of the University of California.  All rights reserved.
438032Speter *
538032Speter * Redistribution and use in source and binary forms, with or without
638032Speter * modification, are permitted provided that the following conditions
738032Speter * are met:
838032Speter * 1. Redistributions of source code must retain the above copyright
938032Speter *    notice, this list of conditions and the following disclaimer.
1038032Speter * 2. Redistributions in binary form must reproduce the above copyright
1138032Speter *    notice, this list of conditions and the following disclaimer in the
1238032Speter *    documentation and/or other materials provided with the distribution.
1338032Speter * 3. All advertising materials mentioning features or use of this software
1464562Sgshapiro *    must display the following acknowledgement:
1564562Sgshapiro *	This product includes software developed by the University of
16132943Sgshapiro *	California, Berkeley and its contributors.
1738032Speter * 4. Neither the name of the University nor the names of its contributors
1890792Sgshapiro *    may be used to endorse or promote products derived from this software
1938032Speter *    without specific prior written permission.
2090792Sgshapiro *
2190792Sgshapiro * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2290792Sgshapiro * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23120256Sgshapiro * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2490792Sgshapiro * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25125820Sgshapiro * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26125820Sgshapiro * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27125820Sgshapiro * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28125820Sgshapiro * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29125820Sgshapiro * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30125820Sgshapiro * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31120256Sgshapiro * SUCH DAMAGE.
32125820Sgshapiro */
33125820Sgshapiro
34125820Sgshapiro#ifndef lint
35125820Sgshapirostatic char copyright[] =
3690792Sgshapiro"@(#) Copyright (c) 1980, 1993\n\
3790792Sgshapiro	The Regents of the University of California.  All rights reserved.\n";
38120256Sgshapiro#endif /* not lint */
39120256Sgshapiro
40132943Sgshapiro#ifndef lint
41132943Sgshapirostatic char sccsid[] = "@(#)mt.c	8.1 (Berkeley) 6/6/93";
42132943Sgshapiro#endif /* not lint */
4390792Sgshapiro
4490792Sgshapiro/*
45132943Sgshapiro * mt --
46132943Sgshapiro *   magnetic tape manipulation program
4790792Sgshapiro */
4890792Sgshapiro#include <sys/types.h>
4964562Sgshapiro#include <sys/ioctl.h>
5090792Sgshapiro#include <sys/mtio.h>
5190792Sgshapiro#include <fcntl.h>
5238032Speter#include <errno.h>
5338032Speter#include <stdlib.h>
5438032Speter#include <stdio.h>
5538032Speter#include <ctype.h>
5638032Speter#include <string.h>
5738032Speter
5838032Speterstruct commands {
5938032Speter	char *c_name;
6038032Speter	int c_code;
6138032Speter	int c_ronly;
6238032Speter} com[] = {
6390792Sgshapiro	{ "bsf",	MTBSF,	1 },
6490792Sgshapiro	{ "bsr",	MTBSR,	1 },
6590792Sgshapiro	{ "eof",	MTWEOF,	0 },
6690792Sgshapiro	{ "fsf",	MTFSF,	1 },
6738032Speter	{ "fsr",	MTFSR,	1 },
6838032Speter	{ "offline",	MTOFFL,	1 },
6938032Speter	{ "rewind",	MTREW,	1 },
7038032Speter	{ "rewoffl",	MTOFFL,	1 },
7138032Speter	{ "status",	MTNOP,	1 },
7290792Sgshapiro	{ "weof",	MTWEOF,	0 },
7390792Sgshapiro	{ NULL }
74120256Sgshapiro};
7538032Speter
76120256Sgshapirovoid err __P((const char *, ...));
77120256Sgshapirovoid printreg __P((char *, u_int, char *));
78120256Sgshapirovoid status __P((struct mtget *));
79120256Sgshapirovoid usage __P((void));
80120256Sgshapiro
81120256Sgshapiroint
82120256Sgshapiromain(argc, argv)
83120256Sgshapiro	int argc;
84120256Sgshapiro	char *argv[];
85120256Sgshapiro{
86120256Sgshapiro	register struct commands *comp;
87120256Sgshapiro	struct mtget mt_status;
88120256Sgshapiro	struct mtop mt_com;
89120256Sgshapiro	int ch, len, mtfd;
9090792Sgshapiro	char *p, *tape;
9194334Sgshapiro
9294334Sgshapiro	if ((tape = getenv("TAPE")) == NULL)
9390792Sgshapiro		tape = DEFTAPE;
9490792Sgshapiro
95111823Sgshapiro	while ((ch = getopt(argc, argv, "f:t:")) != EOF)
9690792Sgshapiro		switch(ch) {
9790792Sgshapiro		case 'f':
9890792Sgshapiro		case 't':
9990792Sgshapiro			tape = optarg;
10090792Sgshapiro			break;
10190792Sgshapiro		case '?':
10290792Sgshapiro		default:
10390792Sgshapiro			usage();
10490792Sgshapiro		}
10590792Sgshapiro	argc -= optind;
10690792Sgshapiro	argv += optind;
10790792Sgshapiro
10890792Sgshapiro	if (argc < 1 || argc > 2)
10990792Sgshapiro		usage();
11090792Sgshapiro
11190792Sgshapiro	len = strlen(p = *argv++);
11290792Sgshapiro	for (comp = com;; comp++) {
11390792Sgshapiro		if (comp->c_name == NULL)
11490792Sgshapiro			err("%s: unknown command", p);
11590792Sgshapiro		if (strncmp(p, comp->c_name, len) == 0)
11690792Sgshapiro			break;
11790792Sgshapiro	}
11890792Sgshapiro	if ((mtfd = open(tape, comp->c_ronly ? O_RDONLY : O_RDWR)) < 0)
11990792Sgshapiro		err("%s: %s", tape, strerror(errno));
12090792Sgshapiro	if (comp->c_code != MTNOP) {
12190792Sgshapiro		mt_com.mt_op = comp->c_code;
12290792Sgshapiro		if (*argv) {
12390792Sgshapiro			mt_com.mt_count = strtol(*argv, &p, 10);
12490792Sgshapiro			if (mt_com.mt_count <= 0 || *p)
12590792Sgshapiro				err("%s: illegal count", *argv);
12690792Sgshapiro		}
12790792Sgshapiro		else
12890792Sgshapiro			mt_com.mt_count = 1;
12990792Sgshapiro		if (ioctl(mtfd, MTIOCTOP, &mt_com) < 0)
13090792Sgshapiro			err("%s: %s: %s", tape, comp->c_name, strerror(errno));
13190792Sgshapiro	} else {
13290792Sgshapiro		if (ioctl(mtfd, MTIOCGET, &mt_status) < 0)
13390792Sgshapiro			err("%s", strerror(errno));
13490792Sgshapiro		status(&mt_status);
13590792Sgshapiro	}
13690792Sgshapiro	exit (0);
13790792Sgshapiro	/* NOTREACHED */
13890792Sgshapiro}
13990792Sgshapiro
14090792Sgshapiro#ifdef vax
14190792Sgshapiro#include <vax/mba/mtreg.h>
14294334Sgshapiro#include <vax/mba/htreg.h>
14364562Sgshapiro
14490792Sgshapiro#include <vax/uba/utreg.h>
14590792Sgshapiro#include <vax/uba/tmreg.h>
14690792Sgshapiro#undef b_repcnt		/* argh */
14790792Sgshapiro#include <vax/uba/tsreg.h>
14890792Sgshapiro#endif
14964562Sgshapiro
15064562Sgshapiro#ifdef sun
15164562Sgshapiro#include <sundev/tmreg.h>
15264562Sgshapiro#include <sundev/arreg.h>
15364562Sgshapiro#endif
154110560Sgshapiro
15590792Sgshapiro#ifdef tahoe
15690792Sgshapiro#include <tahoe/vba/cyreg.h>
15790792Sgshapiro#endif
15890792Sgshapiro
15990792Sgshapirostruct tape_desc {
16038032Speter	short	t_type;		/* type of magtape device */
16190792Sgshapiro	char	*t_name;	/* printing name */
16290792Sgshapiro	char	*t_dsbits;	/* "drive status" register */
16390792Sgshapiro	char	*t_erbits;	/* "error" register */
16490792Sgshapiro} tapes[] = {
16590792Sgshapiro#ifdef vax
16690792Sgshapiro	{ MT_ISTS,	"ts11",		0,		TSXS0_BITS },
16780785Sgshapiro	{ MT_ISHT,	"tm03",		HTDS_BITS,	HTER_BITS },
16890792Sgshapiro	{ MT_ISTM,	"tm11",		0,		TMER_BITS },
16990792Sgshapiro	{ MT_ISMT,	"tu78",		MTDS_BITS,	0 },
17090792Sgshapiro	{ MT_ISUT,	"tu45",		UTDS_BITS,	UTER_BITS },
17190792Sgshapiro#endif
17290792Sgshapiro#ifdef sun
17390792Sgshapiro	{ MT_ISCPC,	"TapeMaster",	TMS_BITS,	0 },
17490792Sgshapiro	{ MT_ISAR,	"Archive",	ARCH_CTRL_BITS,	ARCH_BITS },
17590792Sgshapiro#endif
17690792Sgshapiro#ifdef tahoe
17790792Sgshapiro	{ MT_ISCY,	"cipher",	CYS_BITS,	CYCW_BITS },
17890792Sgshapiro#endif
17990792Sgshapiro	{ 0 }
18090792Sgshapiro};
18190792Sgshapiro
18290792Sgshapiro/*
18390792Sgshapiro * Interpret the status buffer returned
18490792Sgshapiro */
18590792Sgshapirovoid
18690792Sgshapirostatus(bp)
18790792Sgshapiro	register struct mtget *bp;
18890792Sgshapiro{
18990792Sgshapiro	register struct tape_desc *mt;
19090792Sgshapiro
19190792Sgshapiro	for (mt = tapes;; mt++) {
19290792Sgshapiro		if (mt->t_type == 0) {
19390792Sgshapiro			(void)printf("%d: unknown tape drive type\n",
19490792Sgshapiro			    bp->mt_type);
19590792Sgshapiro			return;
19690792Sgshapiro		}
19790792Sgshapiro		if (mt->t_type == bp->mt_type)
19890792Sgshapiro			break;
19990792Sgshapiro	}
20090792Sgshapiro	(void)printf("%s tape drive, residual=%d\n", mt->t_name, bp->mt_resid);
20190792Sgshapiro	printreg("ds", bp->mt_dsreg, mt->t_dsbits);
20290792Sgshapiro	printreg("\ner", bp->mt_erreg, mt->t_erbits);
20390792Sgshapiro	(void)putchar('\n');
20490792Sgshapiro}
20590792Sgshapiro
20690792Sgshapiro/*
20790792Sgshapiro * Print a register a la the %b format of the kernel's printf.
20890792Sgshapiro */
20990792Sgshapirovoid
21090792Sgshapiroprintreg(s, v, bits)
21190792Sgshapiro	char *s;
21290792Sgshapiro	register u_int v;
21390792Sgshapiro	register char *bits;
21490792Sgshapiro{
21590792Sgshapiro	register int i, any = 0;
21690792Sgshapiro	register char c;
21790792Sgshapiro
21890792Sgshapiro	if (bits && *bits == 8)
219110560Sgshapiro		printf("%s=%o", s, v);
22090792Sgshapiro	else
22190792Sgshapiro		printf("%s=%x", s, v);
22290792Sgshapiro	bits++;
22390792Sgshapiro	if (v && bits) {
22490792Sgshapiro		putchar('<');
22590792Sgshapiro		while (i = *bits++) {
22690792Sgshapiro			if (v & (1 << (i-1))) {
22790792Sgshapiro				if (any)
22890792Sgshapiro					putchar(',');
22990792Sgshapiro				any = 1;
23090792Sgshapiro				for (; (c = *bits) > 32; bits++)
23190792Sgshapiro					putchar(c);
23290792Sgshapiro			} else
23390792Sgshapiro				for (; *bits > 32; bits++)
23490792Sgshapiro					;
23590792Sgshapiro		}
23690792Sgshapiro		putchar('>');
23790792Sgshapiro	}
23890792Sgshapiro}
23990792Sgshapiro
24090792Sgshapirovoid
241112810Sgshapirousage()
24290792Sgshapiro{
24390792Sgshapiro	(void)fprintf(stderr, "usage: mt [-f device] command [ count ]\n");
24490792Sgshapiro	exit(1);
24590792Sgshapiro}
24690792Sgshapiro
24790792Sgshapiro#if __STDC__
24890792Sgshapiro#include <stdarg.h>
24990792Sgshapiro#else
25090792Sgshapiro#include <varargs.h>
25190792Sgshapiro#endif
25290792Sgshapiro
25390792Sgshapirovoid
25490792Sgshapiro#if __STDC__
25590792Sgshapiroerr(const char *fmt, ...)
25690792Sgshapiro#else
25790792Sgshapiroerr(fmt, va_alist)
25890792Sgshapiro	char *fmt;
25990792Sgshapiro        va_dcl
26090792Sgshapiro#endif
26190792Sgshapiro{
26290792Sgshapiro	va_list ap;
26390792Sgshapiro#if __STDC__
26490792Sgshapiro	va_start(ap, fmt);
26590792Sgshapiro#else
26690792Sgshapiro	va_start(ap);
26790792Sgshapiro#endif
26890792Sgshapiro	(void)fprintf(stderr, "mt: ");
26990792Sgshapiro	(void)vfprintf(stderr, fmt, ap);
27090792Sgshapiro	va_end(ap);
27190792Sgshapiro	(void)fprintf(stderr, "\n");
27290792Sgshapiro	exit(1);
27390792Sgshapiro	/* NOTREACHED */
27490792Sgshapiro}
27590792Sgshapiro