386BSD 0.1 development
authorWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Fri, 19 Apr 1991 20:53:05 +0000 (12:53 -0800)
committerWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Fri, 19 Apr 1991 20:53:05 +0000 (12:53 -0800)
Work on file usr/src/usr.sbin/rmt/rmt.c
Work on file usr/src/usr.sbin/rmt/rmt.8

Co-Authored-By: Lynne Greer Jolitz <ljolitz@cardio.ucsf.edu>
Synthesized-from: 386BSD-0.1

usr/src/usr.sbin/rmt/rmt.8 [new file with mode: 0644]
usr/src/usr.sbin/rmt/rmt.c [new file with mode: 0644]

diff --git a/usr/src/usr.sbin/rmt/rmt.8 b/usr/src/usr.sbin/rmt/rmt.8
new file mode 100644 (file)
index 0000000..86d2cf9
--- /dev/null
@@ -0,0 +1,217 @@
+.\" Copyright (c) 1983, 1991 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.8      6.5 (Berkeley) 3/16/91
+.\"
+.Dd March 16, 1991
+.Dt RMT 8
+.Os BSD 4.2
+.Sh NAME
+.Nm rmt
+.Nd remote magtape protocol module
+.Sh SYNOPSIS
+.Nm rmt
+.Sh DESCRIPTION
+.Nm Rmt
+is a program used by the remote dump and restore programs
+in manipulating a magnetic tape drive through an interprocess
+communication connection.
+.Nm Rmt
+is normally started up with an
+.Xr rexec 3
+or
+.Xr rcmd 3
+call.
+.Pp
+The 
+.Nm rmt
+program accepts requests specific to the manipulation of
+magnetic tapes, performs the commands, then responds with
+a status indication.  All responses are in
+.Tn ASCII
+and in
+one of two forms. 
+Successful commands have responses of:
+.Bd -filled -offset indent
+.Sm off
+.Sy A Ar number No \en
+.Sm on
+.Ed
+.Pp
+.Ar Number
+is an
+.Tn ASCII
+representation of a decimal number.
+Unsuccessful commands are responded to with:
+.Bd -filled -offset indent
+.Sm off
+.Xo Sy E Ar error-number
+.No \en Ar error-message
+.No \en
+.Xc
+.Sm on
+.Ed
+.Pp
+.Ar Error-number
+is one of the possible error
+numbers described in
+.Xr intro 2
+and
+.Ar error-message
+is the corresponding error string as printed
+from a call to
+.Xr perror 3 .
+The protocol is comprised of the
+following commands, which are sent as indicated - no spaces are supplied
+between the command and its arguments, or between its arguments, and
+.Ql \en
+indicates that a newline should be supplied:
+.Bl -tag -width Ds
+.Sm off
+.It Xo Sy \&O Ar device
+.No \en Ar mode No \en
+.Xc
+Open the specified 
+.Ar device
+using the indicated
+.Ar mode .
+.Ar Device
+is a full pathname and
+.Ar mode
+is an
+.Tn ASCII
+representation of a decimal
+number suitable for passing to
+.Xr open 2 .
+If a device had already been opened, it is
+closed before a new open is performed.
+.It Xo Sy C Ar device No \en
+.Xc
+Close the currently open device.  The
+.Ar device
+specified is ignored.
+.It Xo Sy L
+.Ar whence No \en
+.Ar offset No \en
+.Xc
+.Sm on
+Perform an
+.Xr lseek 2
+operation using the specified parameters.
+The response value is that returned from the
+.Xr lseek
+call.
+.Sm off
+.It Sy W Ar count No \en
+.Sm on
+Write data onto the open device.
+.Nm Rmt
+reads
+.Ar count
+bytes from the connection, aborting if
+a premature end-of-file is encountered.
+The response value is that returned from
+the
+.Xr write 2
+call.
+.Sm off
+.It Sy R Ar count No \en
+.Sm on
+Read
+.Ar count
+bytes of data from the open device.
+If
+.Ar count
+exceeds the size of the data buffer (10 kilobytes), it is
+truncated to the data buffer size.
+.Nm rmt
+then performs the requested 
+.Xr read 2
+and responds with 
+.Sm off
+.Sy A Ar count-read No \en
+.Sm on
+if the read was
+successful; otherwise an error in the
+standard format is returned.  If the read
+was successful, the data read is then sent.
+.Sm off
+.It Xo Sy I Ar operation
+.No \en Ar count No \en
+.Xc
+.Sm on
+Perform a
+.Dv MTIOCOP
+.Xr ioctl 2
+command using the specified parameters.
+The parameters are interpreted as the
+.Tn ASCII
+representations of the decimal values
+to place in the 
+.Ar mt_op
+and
+.Ar mt_count
+fields of the structure used in the
+.Xr ioctl
+call.  The return value is the
+.Ar count
+parameter when the operation is successful.
+.It Sy S
+Return the status of the open device, as
+obtained with a
+.Dv MTIOCGET
+.Xr ioctl
+call.  If the operation was successful,
+an ``ack'' is sent with the size of the
+status buffer, then the status buffer is
+sent (in binary).
+.El
+.Sm on
+.Pp
+Any other command causes 
+.Nm rmt
+to exit.
+.Sh DIAGNOSTICS
+All responses are of the form described above.
+.Sh SEE ALSO
+.Xr rcmd 3 ,
+.Xr rexec 3 ,
+.Xr mtio 4 ,
+.Xr rdump 8 ,
+.Xr rrestore 8
+.Sh BUGS
+People tempted to use this for a remote file access protocol
+are discouraged.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
diff --git a/usr/src/usr.sbin/rmt/rmt.c b/usr/src/usr.sbin/rmt/rmt.c
new file mode 100644 (file)
index 0000000..3a4d621
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 1983 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.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1983 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)rmt.c      5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * rmt
+ */
+#include <stdio.h>
+#include <sgtty.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/mtio.h>
+#include <errno.h>
+#include <string.h>
+
+int    tape = -1;
+
+char   *record;
+int    maxrecsize = -1;
+char   *checkbuf();
+
+#define        SSIZE   64
+char   device[SSIZE];
+char   count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
+
+char   resp[BUFSIZ];
+
+long   lseek();
+
+FILE   *debug;
+#define        DEBUG(f)        if (debug) fprintf(debug, f)
+#define        DEBUG1(f,a)     if (debug) fprintf(debug, f, a)
+#define        DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2)
+
+main(argc, argv)
+       int argc;
+       char **argv;
+{
+       int rval;
+       char c;
+       int n, i, cc;
+
+       argc--, argv++;
+       if (argc > 0) {
+               debug = fopen(*argv, "w");
+               if (debug == 0)
+                       exit(1);
+               (void) setbuf(debug, (char *)0);
+       }
+top:
+       errno = 0;
+       rval = 0;
+       if (read(0, &c, 1) != 1)
+               exit(0);
+       switch (c) {
+
+       case 'O':
+               if (tape >= 0)
+                       (void) close(tape);
+               getstring(device); getstring(mode);
+               DEBUG2("rmtd: O %s %s\n", device, mode);
+               tape = open(device, atoi(mode));
+               if (tape < 0)
+                       goto ioerror;
+               goto respond;
+
+       case 'C':
+               DEBUG("rmtd: C\n");
+               getstring(device);              /* discard */
+               if (close(tape) < 0)
+                       goto ioerror;
+               tape = -1;
+               goto respond;
+
+       case 'L':
+               getstring(count); getstring(pos);
+               DEBUG2("rmtd: L %s %s\n", count, pos);
+               rval = lseek(tape, (long) atoi(count), atoi(pos));
+               if (rval < 0)
+                       goto ioerror;
+               goto respond;
+
+       case 'W':
+               getstring(count);
+               n = atoi(count);
+               DEBUG1("rmtd: W %s\n", count);
+               record = checkbuf(record, n);
+               for (i = 0; i < n; i += cc) {
+                       cc = read(0, &record[i], n - i);
+                       if (cc <= 0) {
+                               DEBUG("rmtd: premature eof\n");
+                               exit(2);
+                       }
+               }
+               rval = write(tape, record, n);
+               if (rval < 0)
+                       goto ioerror;
+               goto respond;
+
+       case 'R':
+               getstring(count);
+               DEBUG1("rmtd: R %s\n", count);
+               n = atoi(count);
+               record = checkbuf(record, n);
+               rval = read(tape, record, n);
+               if (rval < 0)
+                       goto ioerror;
+               (void) sprintf(resp, "A%d\n", rval);
+               (void) write(1, resp, strlen(resp));
+               (void) write(1, record, rval);
+               goto top;
+
+       case 'I':
+               getstring(op); getstring(count);
+               DEBUG2("rmtd: I %s %s\n", op, count);
+               { struct mtop mtop;
+                 mtop.mt_op = atoi(op);
+                 mtop.mt_count = atoi(count);
+                 if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
+                       goto ioerror;
+                 rval = mtop.mt_count;
+               }
+               goto respond;
+
+       case 'S':               /* status */
+               DEBUG("rmtd: S\n");
+               { struct mtget mtget;
+                 if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
+                       goto ioerror;
+                 rval = sizeof (mtget);
+                 (void) sprintf(resp, "A%d\n", rval);
+                 (void) write(1, resp, strlen(resp));
+                 (void) write(1, (char *)&mtget, sizeof (mtget));
+                 goto top;
+               }
+
+       default:
+               DEBUG1("rmtd: garbage command %c\n", c);
+               exit(3);
+       }
+respond:
+       DEBUG1("rmtd: A %d\n", rval);
+       (void) sprintf(resp, "A%d\n", rval);
+       (void) write(1, resp, strlen(resp));
+       goto top;
+ioerror:
+       error(errno);
+       goto top;
+}
+
+getstring(bp)
+       char *bp;
+{
+       int i;
+       char *cp = bp;
+
+       for (i = 0; i < SSIZE; i++) {
+               if (read(0, cp+i, 1) != 1)
+                       exit(0);
+               if (cp[i] == '\n')
+                       break;
+       }
+       cp[i] = '\0';
+}
+
+char *
+checkbuf(record, size)
+       char *record;
+       int size;
+{
+       extern char *malloc();
+
+       if (size <= maxrecsize)
+               return (record);
+       if (record != 0)
+               free(record);
+       record = malloc(size);
+       if (record == 0) {
+               DEBUG("rmtd: cannot allocate buffer space\n");
+               exit(4);
+       }
+       maxrecsize = size;
+       while (size > 1024 &&
+              setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0)
+               size -= 1024;
+       return (record);
+}
+
+error(num)
+       int num;
+{
+
+       DEBUG2("rmtd: E %d (%s)\n", num, strerror(num));
+       (void) sprintf(resp, "E%d\n%s\n", num, strerror(num));
+       (void) write(1, resp, strlen(resp));
+}