rmt.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Has three locks (for stdin, stdout, and the tape)
* that are passed by signals and received by sigpause().
*/
#include <stdio.h>
#include <locale.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <setjmp.h>
#include <stdlib.h>
#include <unistd.h>
/*
* Support for Version 1 of the extended RMT protocol:
* Placing RMTIVERSION (-1) into the mt_op field of the ioctl ('I')
* request will return the current version of the RMT protocol that
* the server supports. For servers that don't support Version 1,
* an error is returned and the client knows to only use Version 0
* (stock BSD) calls, which include mt_op values in the range of [0-7].
*
* Note: The RMTIVERSION request must be made in order for the extended
* protocol commands to be recognized.
*/
#define RMTIVERSION -1
#define RMT_VERSION 1
/*
* These requests are made to the extended RMT protocol by specifying the
* new 'i' command of RMT Protocol Version 1. They are intended to allow
* an intelligent client to communicate with both BSD and Solaris RMT
* servers heterogeneously. The 'i' command taks an mtop structure as
* argument, exactly like the 'I' command does.
*/
#define RMTICACHE 0
#define RMTINOCACHE 1
#define RMTIRETEN 2
#define RMTIERASE 3
#define RMTIEOM 4
#define RMTINBSF 5
/*
* These requests are made to the extended RMT protocol by specifying the
* new 's' command of RMT Protocol Version 1. They are intended to allow
* an intelligent client to obtain "mt status" information with both BSD
* and Solaris RMT servers heterogeneously. They return the requested
* piece of the mtget structure as an ascii integer. The request is made
* by sending the required character immediately after the 's' character
* without any trailing newline. A single ascii integer is returned, else
* an error is returned.
*/
#define MAXCHILD 1
static int children;
static int tape = -1;
static size_t maxrecsize = 0;
static char *record;
#define SSIZE 64
static char device[MAXPATHLEN];
static char key;
#ifdef __STDC__
#else
static void respond();
static void getstring();
static void checkbuf();
#endif
static void
int sig;
{
switch (sig) {
default: return;
}
}
int argc;
char *argv[];
{
int saverr;
size_t n, i;
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
if (argc > 1) {
exit(1);
}
(void) sigemptyset(&maskall);
(void) sigemptyset(&cmdmask);
switch (key) {
case 'L': /* lseek */
(void) sigsuspend(&tapemask);
(void) sigsuspend(&sendmask);
break;
case 'I': /* ioctl */
case 'i': { /* extended version ioctl */
int bad = 0;
if (key == 'i') {
/*
* Map the supported compatibility defines
* into real ioctl values.
*/
case RMTICACHE:
case RMTINOCACHE: /* not support on Sun */
bad = 1;
break;
case RMTIRETEN:
break;
case RMTIERASE:
break;
case RMTIEOM:
break;
case RMTINBSF:
break;
default:
bad = 1;
break;
}
}
if (bad) {
} else {
(void) sigsuspend(&tapemask);
} else {
(char *)&mtop);
}
(void) sigsuspend(&sendmask);
saverr);
}
break;
}
case 'S': /* status */
case 's': { /* extended status */
char skey;
if (key == 's') {
continue;
}
(void) sigsuspend(&tapemask);
errno = 0;
(void) sigsuspend(&sendmask);
if (rval < 0)
else {
switch (skey) {
case MTS_TYPE:
saverr);
break;
case MTS_DSREG:
saverr);
break;
case MTS_ERREG:
saverr);
break;
case MTS_RESID:
saverr);
break;
case MTS_FILENO:
saverr);
break;
case MTS_BLKNO:
saverr);
break;
case MTS_FLAGS:
saverr);
break;
case MTS_BF:
saverr);
break;
default:
break;
}
} else {
saverr);
sizeof (mtget));
}
}
break;
}
case 'W':
checkbuf(n);
#ifdef lint
cc = 0;
#endif
if (cc <= 0) {
"rmtd");
exit(2);
}
}
(void) sigsuspend(&tapemask);
(void) sigsuspend(&sendmask);
break;
case 'R':
checkbuf(n);
(void) sigsuspend(&tapemask);
(void) sigsuspend(&sendmask);
break;
default:
"rmtd", key);
/*FALLTHROUGH*/
case 'C':
case 'O':
/* rendezvous back into a single process */
(void) sigsuspend(&tapemask);
(void) sigsuspend(&sendmask);
(void) sigemptyset(&newmask);
(void) sigsuspend(&newmask);
}
while (children > 0) {
;
}
if (key == 'C') {
continue;
}
exit(3);
/*
* Due to incompatibilities in the
* assignment of mode bits between
* BSD and System V, we strip all
* we also want to handle things larger
* than 2GB, so we also force O_LARGEFILE.
*/
if (tape >= 0) /* fork off */
}
(void) sigsuspend(&cmdmask);
continue;
}
(void) sigsuspend(&cmdmask);
}
exit(0);
#ifdef lint
return (0);
#endif
}
static void
int Errno;
{
if (rval < 0) {
} else {
}
}
static void
char *cp;
{
cp--; /* nullify first increment */
do {
cp++;
exit(0);
*cp = '\0';
}
static void
{
if (size <= maxrecsize)
return;
if (record != 0)
size, "rmtd");
exit(4);
}
maxrecsize = size;
}