BSD 4_4_Lite2 release
[unix-history] / usr / src / sbin / dump / dumprmt.c
index 67d82cb..9c5273e 100644 (file)
-static char *sccsid = "@(#)dumprmt.c   1.6 (Berkeley) %G%";
+/*-
+ * 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dumprmt.c  8.3 (Berkeley) 4/28/95";
+#endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/mtio.h>
 #include <sys/ioctl.h>
 
 #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/in.h>
+#include <netinet/tcp.h>
 
 
-#include <stdio.h>
+#include <protocols/dumprestore.h>
+
+#include <ctype.h>
+#include <err.h>
 #include <netdb.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 "dump.h"
 
 #define        TS_CLOSED       0
 #define        TS_OPEN         1
 
 static int rmtstate = TS_CLOSED;
 
 #define        TS_CLOSED       0
 #define        TS_OPEN         1
 
 static int rmtstate = TS_CLOSED;
-int    rmtape;
-int    rmtconnaborted();
-char   *rmtpeer;
+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 *));
 
 
+extern int ntrec;              /* blocking factor on tape */
+
+int
 rmthost(host)
        char *host;
 {
 
 rmthost(host)
        char *host;
 {
 
-       rmtpeer = host;
+       rmtpeer = malloc(strlen(host) + 1);
+       if (rmtpeer)
+               strcpy(rmtpeer, host);
+       else
+               rmtpeer = host;
        signal(SIGPIPE, rmtconnaborted);
        rmtgetconn();
        if (rmtape < 0)
        signal(SIGPIPE, rmtconnaborted);
        rmtgetconn();
        if (rmtape < 0)
-               exit(1);
+               return (0);
+       return (1);
 }
 
 }
 
+static void
 rmtconnaborted()
 {
 
 rmtconnaborted()
 {
 
-       fprintf(stderr, "Lost connection to remote host.\n");
-       exit(1);
+       errx(1, "Lost connection to remote host.");
 }
 
 }
 
+void
 rmtgetconn()
 {
 rmtgetconn()
 {
-       static struct servent *sp = 0;
-
-       if (sp == 0) {
+       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");
                sp = getservbyname("shell", "tcp");
-               if (sp == 0) {
-                       fprintf(stderr, "rdump: shell/tcp: unknown service\n");
+               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);
                        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 = ntrec * 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);
                }
        }
                }
        }
-       rmtape = rcmd(&rmtpeer, sp->s_port, "root", "root", "/etc/rmt", 0);
+       return (1);
 }
 
 }
 
+int
 rmtopen(tape, mode)
        char *tape;
        int mode;
 {
        char buf[256];
 
 rmtopen(tape, mode)
        char *tape;
        int mode;
 {
        char buf[256];
 
-       sprintf(buf, "O%s\n%d\n", tape, mode);
-       rmtcall(tape, buf);
+       (void)sprintf(buf, "O%s\n%d\n", tape, mode);
        rmtstate = TS_OPEN;
        rmtstate = TS_OPEN;
+       return (rmtcall(tape, buf));
 }
 
 }
 
+void
 rmtclose()
 {
 
 rmtclose()
 {
 
@@ -69,6 +199,7 @@ rmtclose()
        rmtstate = TS_CLOSED;
 }
 
        rmtstate = TS_CLOSED;
 }
 
+int
 rmtread(buf, count)
        char *buf;
        int count;
 rmtread(buf, count)
        char *buf;
        int count;
@@ -77,7 +208,7 @@ rmtread(buf, count)
        int n, i, cc;
        extern errno;
 
        int n, i, cc;
        extern errno;
 
-       sprintf(line, "R%d\n", count);
+       (void)sprintf(line, "R%d\n", count);
        n = rmtcall("read", line);
        if (n < 0) {
                errno = n;
        n = rmtcall("read", line);
        if (n < 0) {
                errno = n;
@@ -92,27 +223,30 @@ rmtread(buf, count)
        return (n);
 }
 
        return (n);
 }
 
+int
 rmtwrite(buf, count)
        char *buf;
        int count;
 {
        char line[30];
 
 rmtwrite(buf, count)
        char *buf;
        int count;
 {
        char line[30];
 
-       sprintf(line, "W%d\n", count);
+       (void)sprintf(line, "W%d\n", count);
        write(rmtape, line, strlen(line));
        write(rmtape, buf, count);
        return (rmtreply("write"));
 }
 
        write(rmtape, line, strlen(line));
        write(rmtape, buf, count);
        return (rmtreply("write"));
 }
 
+void
 rmtwrite0(count)
        int count;
 {
        char line[30];
 
 rmtwrite0(count)
        int count;
 {
        char line[30];
 
-       sprintf(line, "W%d\n", count);
+       (void)sprintf(line, "W%d\n", count);
        write(rmtape, line, strlen(line));
 }
 
        write(rmtape, line, strlen(line));
 }
 
+void
 rmtwrite1(buf, count)
        char *buf;
        int count;
 rmtwrite1(buf, count)
        char *buf;
        int count;
@@ -121,19 +255,20 @@ rmtwrite1(buf, count)
        write(rmtape, buf, count);
 }
 
        write(rmtape, buf, count);
 }
 
+int
 rmtwrite2()
 {
 rmtwrite2()
 {
-       int i;
 
        return (rmtreply("write"));
 }
 
 
        return (rmtreply("write"));
 }
 
+int
 rmtseek(offset, pos)
        int offset, pos;
 {
        char line[80];
 
 rmtseek(offset, pos)
        int offset, pos;
 {
        char line[80];
 
-       sprintf(line, "L%d\n%d\n", offset, pos);
+       (void)sprintf(line, "L%d\n%d\n", offset, pos);
        return (rmtcall("seek", line));
 }
 
        return (rmtcall("seek", line));
 }
 
@@ -146,13 +281,14 @@ rmtstatus()
        register char *cp;
 
        if (rmtstate != TS_OPEN)
        register char *cp;
 
        if (rmtstate != TS_OPEN)
-               return (0);
+               return (NULL);
        rmtcall("status", "S\n");
        for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++)
                *cp++ = rmtgetb();
        return (&mts);
 }
 
        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;
 {
 rmtioctl(cmd, count)
        int cmd, count;
 {
@@ -160,10 +296,11 @@ rmtioctl(cmd, count)
 
        if (count < 0)
                return (-1);
 
        if (count < 0)
                return (-1);
-       sprintf(buf, "I%d\n%d\n", cmd, count);
+       (void)sprintf(buf, "I%d\n%d\n", cmd, count);
        return (rmtcall("ioctl", buf));
 }
 
        return (rmtcall("ioctl", buf));
 }
 
+static int
 rmtcall(cmd, buf)
        char *cmd, *buf;
 {
 rmtcall(cmd, buf)
        char *cmd, *buf;
 {
@@ -173,16 +310,17 @@ rmtcall(cmd, buf)
        return (rmtreply(cmd));
 }
 
        return (rmtreply(cmd));
 }
 
+static int
 rmtreply(cmd)
        char *cmd;
 {
 rmtreply(cmd)
        char *cmd;
 {
-       register int c;
+       register char *cp;
        char code[30], emsg[BUFSIZ];
 
        rmtgets(code, sizeof (code));
        if (*code == 'E' || *code == 'F') {
                rmtgets(emsg, sizeof (emsg));
        char code[30], emsg[BUFSIZ];
 
        rmtgets(code, sizeof (code));
        if (*code == 'E' || *code == 'F') {
                rmtgets(emsg, sizeof (emsg));
-               msg("%s: %s\n", cmd, emsg, code + 1);
+               msg("%s: %s", cmd, emsg);
                if (*code == 'F') {
                        rmtstate = TS_CLOSED;
                        return (-1);
                if (*code == 'F') {
                        rmtstate = TS_CLOSED;
                        return (-1);
@@ -190,13 +328,19 @@ rmtreply(cmd)
                return (-1);
        }
        if (*code != 'A') {
                return (-1);
        }
        if (*code != 'A') {
-               msg("Protocol to remote tape server botched (code %s?).\n",
+               /* Kill trailing newline */
+               cp = code + strlen(code);
+               if (cp > code && *--cp == '\n')
+                       *cp = '\0';
+
+               msg("Protocol to remote tape server botched (code \"%s\").\n",
                    code);
                rmtconnaborted();
        }
        return (atoi(code + 1));
 }
 
                    code);
                rmtconnaborted();
        }
        return (atoi(code + 1));
 }
 
+int
 rmtgetb()
 {
        char c;
 rmtgetb()
 {
        char c;
@@ -206,20 +350,25 @@ rmtgetb()
        return (c);
 }
 
        return (c);
 }
 
-rmtgets(cp, len)
-       char *cp;
+/* Get a line (guaranteed to have a trailing newline). */
+void
+rmtgets(line, len)
+       char *line;
        int len;
 {
        int len;
 {
+       register char *cp = line;
 
        while (len > 1) {
                *cp = rmtgetb();
                if (*cp == '\n') {
 
        while (len > 1) {
                *cp = rmtgetb();
                if (*cp == '\n') {
-                       cp[1] = 0;
+                       cp[1] = '\0';
                        return;
                }
                cp++;
                len--;
        }
                        return;
                }
                cp++;
                len--;
        }
-       msg("Protocol to remote tape server botched (in rmtgets).\n");
+       *cp = '\0';
+       msg("Protocol to remote tape server botched.\n");
+       msg("(rmtgets got \"%s\").\n", line);
        rmtconnaborted();
 }
        rmtconnaborted();
 }