mt.c revision 23693
11590Srgrimes/*
21590Srgrimes * Copyright (c) 1980, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes * 3. All advertising materials mentioning features or use of this software
141590Srgrimes *    must display the following acknowledgement:
151590Srgrimes *	This product includes software developed by the University of
161590Srgrimes *	California, Berkeley and its contributors.
171590Srgrimes * 4. Neither the name of the University nor the names of its contributors
181590Srgrimes *    may be used to endorse or promote products derived from this software
191590Srgrimes *    without specific prior written permission.
201590Srgrimes *
211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311590Srgrimes * SUCH DAMAGE.
321590Srgrimes */
331590Srgrimes
341590Srgrimes#ifndef lint
351590Srgrimesstatic char copyright[] =
361590Srgrimes"@(#) Copyright (c) 1980, 1993\n\
371590Srgrimes	The Regents of the University of California.  All rights reserved.\n";
381590Srgrimes#endif /* not lint */
391590Srgrimes
401590Srgrimes#ifndef lint
4123693Speterstatic char sccsid[] = "@(#)mt.c	8.2 (Berkeley) 5/4/95";
421590Srgrimes#endif /* not lint */
431590Srgrimes
441590Srgrimes/*
451590Srgrimes * mt --
461590Srgrimes *   magnetic tape manipulation program
471590Srgrimes */
481590Srgrimes#include <sys/types.h>
491590Srgrimes#include <sys/ioctl.h>
501590Srgrimes#include <sys/mtio.h>
5123693Speter
5223693Speter#include <ctype.h>
5323693Speter#include <errno.h>
541590Srgrimes#include <fcntl.h>
5523693Speter#include <stdio.h>
561590Srgrimes#include <stdlib.h>
571590Srgrimes#include <string.h>
5823693Speter#include <unistd.h>
591590Srgrimes
607913Sjoerg/* the appropriate sections of <sys/mtio.h> are also #ifdef'd for FreeBSD */
617913Sjoerg#if defined(__FreeBSD__)
627913Sjoerg/* c_flags */
637913Sjoerg#define NEED_2ARGS	0x01
647929Sjoerg#define ZERO_ALLOWED	0x02
657929Sjoerg#define IS_DENSITY	0x04
669541Sjoerg#define DISABLE_THIS	0x08
677913Sjoerg#endif /* defined(__FreeBSD__) */
687913Sjoerg
691590Srgrimesstruct commands {
701590Srgrimes	char *c_name;
711590Srgrimes	int c_code;
721590Srgrimes	int c_ronly;
737913Sjoerg#if defined(__FreeBSD__)
747913Sjoerg	int c_flags;
757913Sjoerg#endif /* defined(__FreeBSD__) */
761590Srgrimes} com[] = {
771590Srgrimes	{ "bsf",	MTBSF,	1 },
781590Srgrimes	{ "bsr",	MTBSR,	1 },
799541Sjoerg#if defined(__FreeBSD__)
809541Sjoerg	/* XXX FreeBSD considered "eof" dangerous, since it's being
819541Sjoerg	   confused with "eom" (and is an alias for "weof" anyway) */
829541Sjoerg	{ "eof",	MTWEOF, 0, DISABLE_THIS },
839541Sjoerg#else
849541Sjoerg	{ "eof",	MTWEOF, 0 },
859541Sjoerg#endif
861590Srgrimes	{ "fsf",	MTFSF,	1 },
871590Srgrimes	{ "fsr",	MTFSR,	1 },
881590Srgrimes	{ "offline",	MTOFFL,	1 },
891590Srgrimes	{ "rewind",	MTREW,	1 },
901590Srgrimes	{ "rewoffl",	MTOFFL,	1 },
911590Srgrimes	{ "status",	MTNOP,	1 },
921590Srgrimes	{ "weof",	MTWEOF,	0 },
937913Sjoerg#if defined(__FreeBSD__)
947913Sjoerg	{ "erase",	MTERASE, 0 },
957913Sjoerg	{ "blocksize",	MTSETBSIZ, 0, NEED_2ARGS|ZERO_ALLOWED },
967929Sjoerg	{ "density",	MTSETDNSTY, 0, NEED_2ARGS|ZERO_ALLOWED|IS_DENSITY },
977913Sjoerg	{ "eom",	MTEOD, 1 },
987913Sjoerg	{ "comp",	MTCOMP, 0, NEED_2ARGS|ZERO_ALLOWED },
9913401Sjoerg	{ "retension",	MTRETENS, 1 },
1007913Sjoerg#endif /* defined(__FreeBSD__) */
1011590Srgrimes	{ NULL }
1021590Srgrimes};
1031590Srgrimes
1041590Srgrimesvoid err __P((const char *, ...));
1051590Srgrimesvoid printreg __P((char *, u_int, char *));
1061590Srgrimesvoid status __P((struct mtget *));
1071590Srgrimesvoid usage __P((void));
1087913Sjoerg#if defined (__FreeBSD__)
1097913Sjoergvoid st_status (struct mtget *);
1107929Sjoergint stringtodens (const char *s);
1117929Sjoergconst char *denstostring (int d);
1129541Sjoergvoid warn_eof __P((void));
1137913Sjoerg#endif /* defined (__FreeBSD__) */
1141590Srgrimes
1151590Srgrimesint
1161590Srgrimesmain(argc, argv)
1171590Srgrimes	int argc;
1181590Srgrimes	char *argv[];
1191590Srgrimes{
1201590Srgrimes	register struct commands *comp;
1211590Srgrimes	struct mtget mt_status;
1221590Srgrimes	struct mtop mt_com;
1231590Srgrimes	int ch, len, mtfd;
1241590Srgrimes	char *p, *tape;
1251590Srgrimes
1261590Srgrimes	if ((tape = getenv("TAPE")) == NULL)
1271590Srgrimes		tape = DEFTAPE;
1281590Srgrimes
1291590Srgrimes	while ((ch = getopt(argc, argv, "f:t:")) != EOF)
1301590Srgrimes		switch(ch) {
1311590Srgrimes		case 'f':
1321590Srgrimes		case 't':
1331590Srgrimes			tape = optarg;
1341590Srgrimes			break;
1351590Srgrimes		case '?':
1361590Srgrimes		default:
1371590Srgrimes			usage();
1381590Srgrimes		}
1391590Srgrimes	argc -= optind;
1401590Srgrimes	argv += optind;
1411590Srgrimes
1421590Srgrimes	if (argc < 1 || argc > 2)
1431590Srgrimes		usage();
1441590Srgrimes
1451590Srgrimes	len = strlen(p = *argv++);
1461590Srgrimes	for (comp = com;; comp++) {
1471590Srgrimes		if (comp->c_name == NULL)
1481590Srgrimes			err("%s: unknown command", p);
1491590Srgrimes		if (strncmp(p, comp->c_name, len) == 0)
1501590Srgrimes			break;
1511590Srgrimes	}
1527913Sjoerg#if defined(__FreeBSD__)
1537913Sjoerg	if((comp->c_flags & NEED_2ARGS) && argc != 2)
1547913Sjoerg		usage();
1559541Sjoerg	if(comp->c_flags & DISABLE_THIS) {
1569541Sjoerg		warn_eof();
1579541Sjoerg	}
1587913Sjoerg#endif /* defined(__FreeBSD__) */
1591590Srgrimes	if ((mtfd = open(tape, comp->c_ronly ? O_RDONLY : O_RDWR)) < 0)
1601590Srgrimes		err("%s: %s", tape, strerror(errno));
1611590Srgrimes	if (comp->c_code != MTNOP) {
1621590Srgrimes		mt_com.mt_op = comp->c_code;
1631590Srgrimes		if (*argv) {
1647913Sjoerg#if defined (__FreeBSD__)
1657929Sjoerg			if (!isdigit(**argv) &&
1667929Sjoerg			    comp->c_flags & IS_DENSITY) {
1677929Sjoerg				const char *dcanon;
1687929Sjoerg				mt_com.mt_count = stringtodens(*argv);
1697929Sjoerg				if (mt_com.mt_count == 0)
1707929Sjoerg					err("%s: unknown density", *argv);
1717929Sjoerg				dcanon = denstostring(mt_com.mt_count);
1727929Sjoerg				if (strcmp(dcanon, *argv) != 0)
1737929Sjoerg					printf(
1747929Sjoerg					"Using \"%s\" as an alias for %s\n",
1757929Sjoerg					       *argv, dcanon);
1767929Sjoerg				p = "";
1777929Sjoerg			} else
1787929Sjoerg				/* allow for hex numbers; useful for density */
1797929Sjoerg				mt_com.mt_count = strtol(*argv, &p, 0);
1807913Sjoerg#else
1811590Srgrimes			mt_com.mt_count = strtol(*argv, &p, 10);
1827913Sjoerg#endif /* defined(__FreeBSD__) */
1837913Sjoerg			if (mt_com.mt_count <=
1847913Sjoerg#if defined (__FreeBSD__)
1857913Sjoerg			    ((comp->c_flags & ZERO_ALLOWED)? -1: 0)
1867913Sjoerg#else
1877913Sjoerg			    0
1887913Sjoerg#endif /* defined (__FreeBSD__) */
1897913Sjoerg			    || *p)
1901590Srgrimes				err("%s: illegal count", *argv);
1911590Srgrimes		}
1921590Srgrimes		else
1931590Srgrimes			mt_com.mt_count = 1;
1941590Srgrimes		if (ioctl(mtfd, MTIOCTOP, &mt_com) < 0)
1951590Srgrimes			err("%s: %s: %s", tape, comp->c_name, strerror(errno));
1961590Srgrimes	} else {
1971590Srgrimes		if (ioctl(mtfd, MTIOCGET, &mt_status) < 0)
1981590Srgrimes			err("%s", strerror(errno));
1991590Srgrimes		status(&mt_status);
2001590Srgrimes	}
2011590Srgrimes	exit (0);
2021590Srgrimes	/* NOTREACHED */
2031590Srgrimes}
2041590Srgrimes
2051590Srgrimes#ifdef vax
2061590Srgrimes#include <vax/mba/mtreg.h>
2071590Srgrimes#include <vax/mba/htreg.h>
2081590Srgrimes
2091590Srgrimes#include <vax/uba/utreg.h>
2101590Srgrimes#include <vax/uba/tmreg.h>
2111590Srgrimes#undef b_repcnt		/* argh */
2121590Srgrimes#include <vax/uba/tsreg.h>
2131590Srgrimes#endif
2141590Srgrimes
2151590Srgrimes#ifdef sun
2161590Srgrimes#include <sundev/tmreg.h>
2171590Srgrimes#include <sundev/arreg.h>
2181590Srgrimes#endif
2191590Srgrimes
2201590Srgrimes#ifdef tahoe
2211590Srgrimes#include <tahoe/vba/cyreg.h>
2221590Srgrimes#endif
2231590Srgrimes
22414176Sjoerg#ifdef __FreeBSD__
22514176Sjoerg#include <machine/wtio.h>
22614176Sjoerg#endif
22714176Sjoerg
2281590Srgrimesstruct tape_desc {
2291590Srgrimes	short	t_type;		/* type of magtape device */
2301590Srgrimes	char	*t_name;	/* printing name */
2311590Srgrimes	char	*t_dsbits;	/* "drive status" register */
2321590Srgrimes	char	*t_erbits;	/* "error" register */
2331590Srgrimes} tapes[] = {
2341590Srgrimes#ifdef vax
2351590Srgrimes	{ MT_ISTS,	"ts11",		0,		TSXS0_BITS },
2361590Srgrimes	{ MT_ISHT,	"tm03",		HTDS_BITS,	HTER_BITS },
2371590Srgrimes	{ MT_ISTM,	"tm11",		0,		TMER_BITS },
2381590Srgrimes	{ MT_ISMT,	"tu78",		MTDS_BITS,	0 },
2391590Srgrimes	{ MT_ISUT,	"tu45",		UTDS_BITS,	UTER_BITS },
2401590Srgrimes#endif
2411590Srgrimes#ifdef sun
2421590Srgrimes	{ MT_ISCPC,	"TapeMaster",	TMS_BITS,	0 },
2431590Srgrimes	{ MT_ISAR,	"Archive",	ARCH_CTRL_BITS,	ARCH_BITS },
2441590Srgrimes#endif
2451590Srgrimes#ifdef tahoe
2461590Srgrimes	{ MT_ISCY,	"cipher",	CYS_BITS,	CYCW_BITS },
2471590Srgrimes#endif
2487913Sjoerg#if defined (__FreeBSD__)
2497913Sjoerg	/*
25014176Sjoerg	 * XXX This is weird.  The st driver reports the tape drive
2517913Sjoerg	 * as 0x7 (MT_ISAR - Sun/Archive compatible); the wt driver
2527913Sjoerg	 * either reports MT_ISVIPER1 for an Archive tape, or 0x11
2537913Sjoerg	 * (MT_ISMFOUR) for other tapes.
2547913Sjoerg	 * XXX for the wt driver, rely on it behaving like a "standard"
2557913Sjoerg	 * magtape driver.
2567913Sjoerg	 */
2577913Sjoerg	{ MT_ISAR,	"SCSI tape drive", 0,		0 },
25814176Sjoerg	{ MT_ISVIPER1,	"Archive Viper", WTDS_BITS, WTER_BITS },
25914176Sjoerg	{ MT_ISMFOUR,	"Wangtek",	 WTDS_BITS, WTER_BITS },
2607913Sjoerg#endif /* defined (__FreeBSD__) */
2611590Srgrimes	{ 0 }
2621590Srgrimes};
2631590Srgrimes
2641590Srgrimes/*
2651590Srgrimes * Interpret the status buffer returned
2661590Srgrimes */
2671590Srgrimesvoid
2681590Srgrimesstatus(bp)
2691590Srgrimes	register struct mtget *bp;
2701590Srgrimes{
2711590Srgrimes	register struct tape_desc *mt;
2721590Srgrimes
2731590Srgrimes	for (mt = tapes;; mt++) {
2741590Srgrimes		if (mt->t_type == 0) {
2751590Srgrimes			(void)printf("%d: unknown tape drive type\n",
2761590Srgrimes			    bp->mt_type);
2771590Srgrimes			return;
2781590Srgrimes		}
2791590Srgrimes		if (mt->t_type == bp->mt_type)
2801590Srgrimes			break;
2811590Srgrimes	}
2827913Sjoerg#if defined (__FreeBSD__)
2837913Sjoerg	if(mt->t_type == MT_ISAR)
2847913Sjoerg		st_status(bp);
2857913Sjoerg	else {
2867913Sjoerg#endif /* defined (__FreeBSD__) */
2871590Srgrimes	(void)printf("%s tape drive, residual=%d\n", mt->t_name, bp->mt_resid);
28814176Sjoerg	printreg("ds", (unsigned short)bp->mt_dsreg, mt->t_dsbits);
28914176Sjoerg	printreg("\ner", (unsigned short)bp->mt_erreg, mt->t_erbits);
2901590Srgrimes	(void)putchar('\n');
2917913Sjoerg#if defined (__FreeBSD__)
2927913Sjoerg	}
2937913Sjoerg#endif /* defined (__FreeBSD__) */
2941590Srgrimes}
2951590Srgrimes
2961590Srgrimes/*
2971590Srgrimes * Print a register a la the %b format of the kernel's printf.
2981590Srgrimes */
2991590Srgrimesvoid
3001590Srgrimesprintreg(s, v, bits)
3011590Srgrimes	char *s;
3021590Srgrimes	register u_int v;
3031590Srgrimes	register char *bits;
3041590Srgrimes{
3051590Srgrimes	register int i, any = 0;
3061590Srgrimes	register char c;
3071590Srgrimes
3081590Srgrimes	if (bits && *bits == 8)
3091590Srgrimes		printf("%s=%o", s, v);
3101590Srgrimes	else
3111590Srgrimes		printf("%s=%x", s, v);
31211608Sbde	if (!bits)
31311608Sbde		return;
3141590Srgrimes	bits++;
3151590Srgrimes	if (v && bits) {
3161590Srgrimes		putchar('<');
3171590Srgrimes		while (i = *bits++) {
3181590Srgrimes			if (v & (1 << (i-1))) {
3191590Srgrimes				if (any)
3201590Srgrimes					putchar(',');
3211590Srgrimes				any = 1;
3221590Srgrimes				for (; (c = *bits) > 32; bits++)
3231590Srgrimes					putchar(c);
3241590Srgrimes			} else
3251590Srgrimes				for (; *bits > 32; bits++)
3261590Srgrimes					;
3271590Srgrimes		}
3281590Srgrimes		putchar('>');
3291590Srgrimes	}
3301590Srgrimes}
3311590Srgrimes
3321590Srgrimesvoid
3331590Srgrimesusage()
3341590Srgrimes{
3351590Srgrimes	(void)fprintf(stderr, "usage: mt [-f device] command [ count ]\n");
3361590Srgrimes	exit(1);
3371590Srgrimes}
3381590Srgrimes
3391590Srgrimes#if __STDC__
3401590Srgrimes#include <stdarg.h>
3411590Srgrimes#else
3421590Srgrimes#include <varargs.h>
3431590Srgrimes#endif
3441590Srgrimes
3451590Srgrimesvoid
3461590Srgrimes#if __STDC__
3471590Srgrimeserr(const char *fmt, ...)
3481590Srgrimes#else
3491590Srgrimeserr(fmt, va_alist)
3501590Srgrimes	char *fmt;
3511590Srgrimes        va_dcl
3521590Srgrimes#endif
3531590Srgrimes{
3541590Srgrimes	va_list ap;
3551590Srgrimes#if __STDC__
3561590Srgrimes	va_start(ap, fmt);
3571590Srgrimes#else
3581590Srgrimes	va_start(ap);
3591590Srgrimes#endif
3601590Srgrimes	(void)fprintf(stderr, "mt: ");
3611590Srgrimes	(void)vfprintf(stderr, fmt, ap);
3621590Srgrimes	va_end(ap);
3631590Srgrimes	(void)fprintf(stderr, "\n");
3641590Srgrimes	exit(1);
3651590Srgrimes	/* NOTREACHED */
3661590Srgrimes}
3677913Sjoerg
3687913Sjoerg#if defined (__FreeBSD__)
3697913Sjoerg
3707913Sjoergstruct densities {
3717913Sjoerg	int dens;
3727913Sjoerg	const char *name;
3737913Sjoerg} dens [] = {
3747929Sjoerg	{ 0x1,  "X3.22-1983" },
3757929Sjoerg	{ 0x2,  "X3.39-1986" },
3767929Sjoerg	{ 0x3,  "X3.54-1986" },
3777929Sjoerg	{ 0x5,  "X3.136-1986" },
3787929Sjoerg	{ 0x6,  "X3.157-1987" },
3797929Sjoerg	{ 0x7,  "X3.116-1986" },
3807929Sjoerg	{ 0x8,  "X3.158-1986" },
3817929Sjoerg	{ 0x9,  "X3B5/87-099" },
3827929Sjoerg	{ 0xA,  "X3B5/86-199" },
3837929Sjoerg	{ 0xB,  "X3.56-1986" },
3847929Sjoerg	{ 0xC,  "HI-TC1" },
3857929Sjoerg	{ 0xD,  "HI-TC2" },
3867929Sjoerg	{ 0xF,  "QIC-120" },
3877929Sjoerg	{ 0x10, "QIC-150" },
3887929Sjoerg	{ 0x11, "QIC-320" },
3897929Sjoerg	{ 0x12, "QIC-1350" },
3907913Sjoerg	{ 0x13, "X3B5/88-185A" },
3917929Sjoerg	{ 0x14, "X3.202-1991" },
3927929Sjoerg	{ 0x15, "ECMA TC17" },
3937929Sjoerg	{ 0x16, "X3.193-1990" },
3947929Sjoerg	{ 0x17, "X3B5/91-174" },
3957913Sjoerg	{ 0, 0 }
3967913Sjoerg};
3977913Sjoerg
3987913Sjoergconst char *
3997929Sjoergdenstostring(int d)
4007913Sjoerg{
4017913Sjoerg	static char buf[20];
4027913Sjoerg	struct densities *sd;
4037913Sjoerg
4047913Sjoerg	for (sd = dens; sd->dens; sd++)
4057913Sjoerg		if (sd->dens == d)
4067913Sjoerg			break;
4077913Sjoerg	if (sd->dens == 0) {
4087929Sjoerg		sprintf(buf, "0x%02x", d);
4097913Sjoerg		return buf;
4107929Sjoerg	} else
4117913Sjoerg		return sd->name;
4127913Sjoerg}
4137913Sjoerg
4147929Sjoergint
4157929Sjoergstringtodens(const char *s)
4167929Sjoerg{
4177929Sjoerg	struct densities *sd;
4187929Sjoerg	size_t l = strlen(s);
4197929Sjoerg
4207929Sjoerg	for (sd = dens; sd->dens; sd++)
4217929Sjoerg		if (strncasecmp(sd->name, s, l) == 0)
4227929Sjoerg			break;
4237929Sjoerg	return sd->dens;
4247929Sjoerg}
4257929Sjoerg
4267929Sjoerg
4277913Sjoergconst char *
4287913Sjoerggetblksiz(int bs)
4297913Sjoerg{
4307913Sjoerg	static char buf[25];
4317913Sjoerg	if (bs == 0)
4327913Sjoerg		return "variable";
4337913Sjoerg	else {
4347913Sjoerg		sprintf(buf, "= %d bytes", bs);
4357913Sjoerg		return buf;
4367913Sjoerg	}
4377913Sjoerg}
4387913Sjoerg
4397913Sjoerg
4407913Sjoergvoid
4417913Sjoergst_status(struct mtget *bp)
4427913Sjoerg{
4437929Sjoerg	printf("Present Mode:   Density = %-12s Blocksize %s\n",
4447929Sjoerg	       denstostring(bp->mt_density), getblksiz(bp->mt_blksiz));
4457913Sjoerg	printf("---------available modes---------\n");
4467929Sjoerg	printf("Mode 0:         Density = %-12s Blocksize %s\n",
4477929Sjoerg	       denstostring(bp->mt_density0), getblksiz(bp->mt_blksiz0));
4487929Sjoerg	printf("Mode 1:         Density = %-12s Blocksize %s\n",
4497929Sjoerg	       denstostring(bp->mt_density1), getblksiz(bp->mt_blksiz1));
4507929Sjoerg	printf("Mode 2:         Density = %-12s Blocksize %s\n",
4517929Sjoerg	       denstostring(bp->mt_density2), getblksiz(bp->mt_blksiz2));
4527929Sjoerg	printf("Mode 3:         Density = %-12s Blocksize %s\n",
4537929Sjoerg	       denstostring(bp->mt_density3), getblksiz(bp->mt_blksiz3));
4547913Sjoerg}
4557913Sjoerg
4569541Sjoergvoid
4579541Sjoergwarn_eof(void)
4589541Sjoerg{
4599541Sjoerg	fprintf(stderr,
4609541Sjoerg		"The \"eof\" command has been disabled.\n"
4619541Sjoerg		"Use \"weof\" if you really want to write end-of-file marks,\n"
4629541Sjoerg		"or \"eom\" if you rather want to skip to the end of "
4639541Sjoerg		"recorded medium.\n");
4649541Sjoerg	exit(1);
4659541Sjoerg}
4669541Sjoerg
4677913Sjoerg#endif /* defined (__FreeBSD__) */
468