rmtlib.c revision fe0e7ec4d916b05b52d8c7cc8a3e6a1b28e77b6f
/*LINTLIBRARY*/
/*PROTOLIB1*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
/* line below is from UCB 5.4 12/11/85 */
#pragma ident "%Z%%M% %I% %E% SMI"
#include <myrcmd.h>
#include <stdio.h>
#include <locale.h>
#include <ctype.h>
#include <pwd.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <netdb.h>
#include <locale.h>
#include <stdlib.h>
#include <errno.h>
#include <rmt.h>
#include <libintl.h>
#define sv_handler sa_handler
#define TS_CLOSED 0
#define TS_OPEN 1
static int rmtape = -1;
static int rmtversion = 0;
static char *rmtpeer, *rmtpeer_malloc;
#ifdef __STDC__
static void rmtmsg(const char *, ...); /* package print routine */
static void rmtconnaborted(int);
static void rmtgetconn(void);
static int rmtstatus_extended(struct mtget *);
static int rmtioctl_extended(int, long);
static int map_extended_ioctl(int);
static int okname(char *);
static int rmtcall(char *, char *);
static int rmtreply(char *);
static void rmtgets(char *, int);
static void (*print)(const char *, ...); /* print routine */
static void (*Exit)(int); /* exit routine */
#else
static void rmtmsg();
static void rmtconnaborted();
static void rmtgetconn();
static int okname();
static int rmtstatus_extended();
static int rmtioctl_extended();
static int map_extended_ioctl();
static int rmtcall();
static int rmtreply();
static int rmtpush();
static void rmtgets();
static void (*print)();
static void (*Exit)();
#endif
/*
* Get a program-specific print and exit routine into
* the package. This is primarily for dump's benefit.
* This routine is optional -- if not called the two
* default to fprintf(stderr) and exit.
*/
#ifdef __STDC__
void
void (*errmsg)(const char *, ...), /* print routine */
void (*errexit)(int)) /* exit routine */
#else
void
#endif
{
}
int
{
#ifdef __STDC__
if (print == (void (*)(const char *, ...))0)
#else
if (print == (void (*)())0)
#endif
#ifdef __STDC__
if (Exit == (void (*)(int))0)
#else
if (Exit == (void (*)())0)
#endif
rmtape = -1;
}
if (rmtpeer_malloc)
(void) free(rmtpeer_malloc);
if (rmtpeer == (char *)0)
return (0);
rmtgetconn();
if (rmtape < 0)
return (0);
return (1);
}
/*ARGSUSED*/
static void
rmtconnaborted(int sig)
{
Exit(1);
}
static void
#ifdef __STDC__
rmtgetconn(void)
#else
#endif
{
if (sp == 0) {
if (sp == 0) {
Exit(1);
}
if (pwd == 0) {
"Cannot find password entry for uid %d\n"),
getuid());
Exit(1);
}
}
/* Was strrchr(), be consistent with dump */
if (host) {
*host++ = 0;
Exit(1);
} else {
}
/* Was strrchr() - be consistent with dump and restore */
if (device)
*device = 0; /* throw away device name */
/*
* myrcmd() replaces the contents of rmtpeer with a pointer
* to a static copy of the canonical host name. However,
* since we never refer to rmtpeer again (other than to
* overwrite it in the next rmthost() invocation), we don't
* really care.
*/
/* LINTED sp->s_port is an int, even though port numbers are 1..65535 */
if (rmtape < 0) {
if (*myrcmd_stderr)
} else {
sizeof (size)) < 0)
}
}
static int
{
char *cp;
uchar_t c;
"invalid user name %s\n"), cp0);
return (0);
}
}
return (1);
}
int
{
char buf[256];
int fd;
if (fd != -1) {
/* see if the rmt server supports the extended protocol */
/*
* Some rmt daemons apparently close the connection
* when they get a bogus ioctl. See 1210852 (ignore
* the evaluation). Make sure we can still talk to
* the device, re-opening it if necessary.
*/
if (rmtversion < 1) {
rmtclose();
rmtgetconn();
rmtversion = 0;
}
}
}
return (fd);
}
void
#ifdef __STDC__
rmtclose(void)
#else
rmtclose()
#endif
{
return;
}
int
{
int n, i, cc;
if (rmtversion > 0)
return (rmtstatus_extended(mt));
if (n < 0) {
return (-1);
}
if ((unsigned)n > sizeof (*mt)) {
"rmtstatus: expected response size %d, got %d\n"),
sizeof (struct mtget), n);
"This means the remote rmt daemon is not compatible.\n"));
rmtconnaborted(0);
}
i = 0;
while (i < n) {
if (cc <= 0)
rmtconnaborted(0);
i += cc;
}
return (n);
}
static int
{
return (-1);
return (0);
}
int
{
char line[30];
int n, i, cc;
if (n < 0) {
return (-1);
}
if (n > count) {
"rmtread: expected response size %d, got %d\n"),
count, n);
"This means the remote rmt daemon is not compatible.\n"));
rmtconnaborted(0);
}
i = 0;
while (i < n) {
if (cc <= 0)
rmtconnaborted(0);
i += cc;
}
return (n);
}
int
{
int retval;
if (retval <= 0)
return (-1);
if (retval <= 0)
return (-1);
return (rmtreply("write"));
}
int
{
int retval;
do {
return (retval);
}
int
{
char line[80];
}
int
{
char buf[256];
int xcmd;
if (count < 0)
return (-1);
}
/*
* Map from the standard Sun ioctl commands into the extended version,
* if possible.
*/
static int
map_extended_ioctl(int cmd)
{
int xcmd;
if (rmtversion <= 0)
return (-1); /* extended protocol not supported */
switch (cmd) {
case MTRETEN:
xcmd = 2;
break;
case MTERASE:
xcmd = 3;
break;
case MTEOM:
xcmd = 4;
break;
case MTNBSF:
xcmd = 5;
break;
default:
break;
}
return (xcmd);
}
static int
{
char buf[256];
}
static int
{
rmtconnaborted(0);
}
static int
{
/*
* don't print error message for ioctl or status;
* or if we are opening up a full path (i.e. device)
* and the tape is not loaded (EIO error)
*/
if (*code == 'F') {
return (-1);
}
return (-1);
}
if (*code != 'A') {
"Protocol to remote tape server botched (code %s?).\n"),
code);
rmtconnaborted(0);
}
}
static void
{
int i, n;
for (i = 0; i < n; i++)
if (cp[i] == '\n')
break;
n = i + 1; /* characters to read at once */
for (i = 0; i < len; i += n, n = 1) {
if (n <= 0)
rmtconnaborted(0);
cp += n;
return;
}
}
"Protocol to remote tape server botched (in rmtgets).\n"));
rmtconnaborted(0);
}
#ifdef __STDC__
#include <stdarg.h>
/* VARARGS1 */
static void
{
}
#else
#include <varargs.h>
/* VARARGS */
static void
{
char *fmt;
}
#endif