diff options
| author | scottr <scottr@NetBSD.org> | 1996-03-05 20:39:32 +0000 |
|---|---|---|
| committer | scottr <scottr@NetBSD.org> | 1996-03-05 20:39:32 +0000 |
| commit | 41c2cff5ab3215f0b00a9ab0dd5017dbb8395ae7 (patch) | |
| tree | 62fe5ed9f2ef07a3650807540bfe539f9db76113 | |
| parent | 3020e66dd5881ffef4e22eae21932dbde06a37dd (diff) | |
Add remote tape capabilities.
| -rw-r--r-- | bin/mt/mt.1 | 11 | ||||
| -rw-r--r-- | bin/mt/mt.c | 41 | ||||
| -rw-r--r-- | bin/mt/mt.h | 51 | ||||
| -rw-r--r-- | bin/mt/mtrmt.c | 304 | ||||
| -rw-r--r-- | bin/mt/pathnames.h | 38 |
5 files changed, 435 insertions, 10 deletions
diff --git a/bin/mt/mt.1 b/bin/mt/mt.1 index e134616b776..0f23ed44d04 100644 --- a/bin/mt/mt.1 +++ b/bin/mt/mt.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: mt.1,v 1.6 1995/08/22 19:36:00 jtc Exp $ +.\" $NetBSD: mt.1,v 1.7 1996/03/05 20:39:42 scottr Exp $ .\" .\" Copyright (c) 1981, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -56,6 +56,15 @@ Note that .Ar tapename must reference a raw (not block) tape device. +If +.Ar tapename +is of the form +.Dq host:tapename , +or +.Dq user@host:tapename , +.Nm mt +writes to the named tape device on the remote host using +.Xr rmt 8 . .Pp The available commands are listed below. Only as many characters as are required to uniquely identify a command diff --git a/bin/mt/mt.c b/bin/mt/mt.c index aa82d1a3546..2552acd7514 100644 --- a/bin/mt/mt.c +++ b/bin/mt/mt.c @@ -1,4 +1,4 @@ -/* $NetBSD: mt.c,v 1.8 1995/09/28 07:18:20 tls Exp $ */ +/* $NetBSD: mt.c,v 1.9 1996/03/05 20:39:32 scottr Exp $ */ /* * Copyright (c) 1980, 1993 @@ -43,7 +43,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)mt.c 8.2 (Berkeley) 6/6/93"; #else -static char rcsid[] = "$NetBSD: mt.c,v 1.8 1995/09/28 07:18:20 tls Exp $"; +static char rcsid[] = "$NetBSD: mt.c,v 1.9 1996/03/05 20:39:32 scottr Exp $"; #endif #endif /* not lint */ @@ -61,6 +61,8 @@ static char rcsid[] = "$NetBSD: mt.c,v 1.8 1995/09/28 07:18:20 tls Exp $"; #include <ctype.h> #include <string.h> +#include "mt.h" + struct commands { char *c_name; int c_code; @@ -86,6 +88,8 @@ void printreg __P((char *, u_int, char *)); void status __P((struct mtget *)); void usage __P((void)); +char *host = NULL; /* remote host (if any) */ + int main(argc, argv) int argc; @@ -116,6 +120,15 @@ main(argc, argv) if (argc < 1 || argc > 2) usage(); + if (strchr(tape, ':')) { + host = tape; + tape = strchr(host, ':'); + *tape++ = '\0'; + if (rmthost(host) == 0) + exit(X_ABORT); + } + (void)setuid(getuid()); /* rmthost() is the only reason to be setuid */ + len = strlen(p = *argv++); for (comp = com;; comp++) { if (comp->c_name == NULL) @@ -123,7 +136,8 @@ main(argc, argv) if (strncmp(p, comp->c_name, len) == 0) break; } - if ((mtfd = open(tape, comp->c_ronly ? O_RDONLY : O_RDWR)) < 0) + if ((mtfd = host ? rmtopen(tape, 2) : + open(tape, O_WRONLY|O_CREAT, 0666)) < 0) err(2, "%s", tape); if (comp->c_code != MTNOP) { mt_com.mt_op = comp->c_code; @@ -134,14 +148,23 @@ main(argc, argv) } else mt_com.mt_count = 1; - if (ioctl(mtfd, MTIOCTOP, &mt_com) < 0) + if ((host ? rmtioctl(mt_com.mt_op, mt_com.mt_count) : + ioctl(mtfd, MTIOCTOP, &mt_com)) < 0) err(2, "%s: %s", tape, comp->c_name); } else { - if (ioctl(mtfd, MTIOCGET, &mt_status) < 0) - err(2, "ioctl MTIOCGET"); - status(&mt_status); + if (host) { + status(rmtstatus()); + } else { + if (ioctl(mtfd, MTIOCGET, &mt_status) < 0) + err(2, "ioctl MTIOCGET"); + status(&mt_status); + } } - exit (0); + + if (host) + rmtclose(); + + exit(X_FINOK); /* NOTREACHED */ } @@ -232,5 +255,5 @@ void usage() { (void)fprintf(stderr, "usage: mt [-f device] command [ count ]\n"); - exit(1); + exit(X_USAGE); } diff --git a/bin/mt/mt.h b/bin/mt/mt.h new file mode 100644 index 00000000000..3d6dc221022 --- /dev/null +++ b/bin/mt/mt.h @@ -0,0 +1,51 @@ +/* $NetBSD: mt.h,v 1.1 1996/03/05 20:39:36 scottr Exp $ */ + +/*- + * Copyright (c) 1980, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* rmt routines */ +void rmtclose __P((void)); +int rmthost __P((char *host)); +int rmtopen __P((char *tape, int mode)); +int rmtioctl __P((int command, int count)); +struct mtget *rmtstatus __P((void)); + +void interrupt __P((int signo)); /* in case operator bangs on console */ + +/* + * Exit status codes + */ +#define X_FINOK 0 /* normal exit */ +#define X_USAGE 1 /* invalid usage, no action performed */ +#define X_REWRITE 2 /* restart writing from the check point */ +#define X_ABORT 3 /* abort dump; don't attempt checkpointing */ diff --git a/bin/mt/mtrmt.c b/bin/mt/mtrmt.c new file mode 100644 index 00000000000..c5510d1c1aa --- /dev/null +++ b/bin/mt/mtrmt.c @@ -0,0 +1,304 @@ +/* $NetBSD: mtrmt.c,v 1.1 1996/03/05 20:39:38 scottr Exp $ */ + +/*- + * Copyright (c) 1980, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * This was unceremoniously ripped out of usr.sbin/dump/dumprmt.c: + * + * static char sccsid[] = "@(#)dumprmt.c 8.1 (Berkeley) 6/5/93"; + * + */ + +#include <sys/param.h> +#include <sys/mtio.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/time.h> +#ifdef sunos +#include <sys/vnode.h> + +#include <ufs/inode.h> +#else +#include <ufs/ufs/dinode.h> +#endif + +#include <netinet/in.h> +#include <netinet/tcp.h> + +#include <protocols/dumprestore.h> + +#include <ctype.h> +#include <err.h> +#include <netdb.h> +#include <pwd.h> +#include <signal.h> +#include <stdio.h> +#ifdef __STDC__ +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#endif + +#include "pathnames.h" +#include "mt.h" + +#define TS_CLOSED 0 +#define TS_OPEN 1 + +static int rmtstate = TS_CLOSED; +static int rmtape; +static char *rmtpeer; + +static int okname __P((char *)); +static int rmtcall __P((char *, char *)); +static void rmtconnaborted __P((/* int, int */)); +static int rmtgetb __P((void)); +static void rmtgetconn __P((void)); +static void rmtgets __P((char *, int)); +static int rmtreply __P((char *)); + +int +rmthost(host) + char *host; +{ + + rmtpeer = malloc(strlen(host) + 1); + if (rmtpeer) + strcpy(rmtpeer, host); + else + rmtpeer = host; + signal(SIGPIPE, rmtconnaborted); + rmtgetconn(); + if (rmtape < 0) + return (0); + return (1); +} + +static void +rmtconnaborted() +{ + + errx(1, "Lost connection to remote host."); +} + +void +rmtgetconn() +{ + register char *cp; + static struct servent *sp = NULL; + static struct passwd *pwd = NULL; +#ifdef notdef + static int on = 1; +#endif + char *tuser; + int size; + int maxseg; + + if (sp == NULL) { + sp = getservbyname("shell", "tcp"); + if (sp == NULL) + errx(1, "shell/tcp: unknown service"); + pwd = getpwuid(getuid()); + if (pwd == NULL) + errx(1, "who are you?"); + } + if ((cp = strchr(rmtpeer, '@')) != NULL) { + tuser = rmtpeer; + *cp = '\0'; + if (!okname(tuser)) + exit(1); + rmtpeer = ++cp; + } else + tuser = pwd->pw_name; + rmtape = rcmd(&rmtpeer, (u_short)sp->s_port, pwd->pw_name, tuser, + _PATH_RMT, (int *)0); + size = TP_BSIZE; + if (size > 60 * 1024) /* XXX */ + size = 60 * 1024; + /* Leave some space for rmt request/response protocol */ + size += 2 * 1024; + while (size > TP_BSIZE && + setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) + size -= TP_BSIZE; + (void)setsockopt(rmtape, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)); + maxseg = 1024; + if (setsockopt(rmtape, IPPROTO_TCP, TCP_MAXSEG, + &maxseg, sizeof (maxseg)) < 0) + perror("TCP_MAXSEG setsockopt"); + +#ifdef notdef + if (setsockopt(rmtape, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on)) < 0) + perror("TCP_NODELAY setsockopt"); +#endif +} + +static int +okname(cp0) + char *cp0; +{ + register char *cp; + register int c; + + for (cp = cp0; *cp; cp++) { + c = *cp; + if (!isascii(c) || !(isalnum(c) || c == '_' || c == '-')) { + warnx("invalid user name: %s", cp0); + return (0); + } + } + return (1); +} + +int +rmtopen(tape, mode) + char *tape; + int mode; +{ + char buf[256]; + + (void)sprintf(buf, "O%s\n%d\n", tape, mode); + rmtstate = TS_OPEN; + return (rmtcall(tape, buf)); +} + +void +rmtclose() +{ + + if (rmtstate != TS_OPEN) + return; + rmtcall("close", "C\n"); + rmtstate = TS_CLOSED; +} + +struct mtget mts; + +struct mtget * +rmtstatus() +{ + register int i; + register char *cp; + + if (rmtstate != TS_OPEN) + return (NULL); + rmtcall("status", "S\n"); + for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++) + *cp++ = rmtgetb(); + return (&mts); +} + +int +rmtioctl(cmd, count) + int cmd, count; +{ + char buf[256]; + + if (count < 0) + return (-1); + (void)sprintf(buf, "I%d\n%d\n", cmd, count); + return (rmtcall("ioctl", buf)); +} + +static int +rmtcall(cmd, buf) + char *cmd, *buf; +{ + + if (write(rmtape, buf, strlen(buf)) != strlen(buf)) + rmtconnaborted(); + return (rmtreply(cmd)); +} + +static int +rmtreply(cmd) + char *cmd; +{ + register char *cp; + char code[30], emsg[BUFSIZ]; + + rmtgets(code, sizeof (code)); + if (*code == 'E' || *code == 'F') { + rmtgets(emsg, sizeof (emsg)); + warnx("%s: %s", cmd, emsg); + if (*code == 'F') { + rmtstate = TS_CLOSED; + return (-1); + } + return (-1); + } + if (*code != 'A') { + /* Kill trailing newline */ + cp = code + strlen(code); + if (cp > code && *--cp == '\n') + *cp = '\0'; + + warnx("Protocol to remote tape server botched (code \"%s\").\n", + code); + rmtconnaborted(); + } + return (atoi(code + 1)); +} + +int +rmtgetb() +{ + char c; + + if (read(rmtape, &c, 1) != 1) + rmtconnaborted(); + return (c); +} + +/* Get a line (guaranteed to have a trailing newline). */ +void +rmtgets(line, len) + char *line; + int len; +{ + register char *cp = line; + + while (len > 1) { + *cp = rmtgetb(); + if (*cp == '\n') { + cp[1] = '\0'; + return; + } + cp++; + len--; + } + *cp = '\0'; + warnx("Protocol to remote tape server botched.\n"); + warnx("(rmtgets got \"%s\").\n", line); + rmtconnaborted(); +} diff --git a/bin/mt/pathnames.h b/bin/mt/pathnames.h new file mode 100644 index 00000000000..608baabf2f9 --- /dev/null +++ b/bin/mt/pathnames.h @@ -0,0 +1,38 @@ +/* $NetBSD: pathnames.h,v 1.1 1996/03/05 20:39:40 scottr Exp $ */ + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <paths.h> + +#define _PATH_RMT "/etc/rmt" |
