1: /*- 2: * Copyright (c) 1980 The Regents of the University of California. 3: * All rights reserved. 4: * 5: * Redistribution and use in source and binary forms, with or without 6: * modification, are permitted provided that the following conditions 7: * are met: 8: * 1. Redistributions of source code must retain the above copyright 9: * notice, this list of conditions and the following disclaimer. 10: * 2. Redistributions in binary form must reproduce the above copyright 11: * notice, this list of conditions and the following disclaimer in the 12: * documentation and/or other materials provided with the distribution. 13: * 3. All advertising materials mentioning features or use of this software 14: * must display the following acknowledgement: 15: * This product includes software developed by the University of 16: * California, Berkeley and its contributors. 17: * 4. Neither the name of the University nor the names of its contributors 18: * may be used to endorse or promote products derived from this software 19: * without specific prior written permission. 20: * 21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31: * SUCH DAMAGE. 32: */ 33: 34: #if !defined(lint) && defined(DOSCCS) 35: static char sccsid[] = "@(#)dumprmt.c 1.2 (2.11BSD GTE) 12/7/94"; 36: #endif 37: 38: #include <sys/param.h> 39: #include <sys/mtio.h> 40: #include <sys/ioctl.h> 41: #include <sys/socket.h> 42: #include <sys/inode.h> 43: #include <signal.h> 44: #include <netinet/in.h> 45: #include <netdb.h> 46: #include <protocols/dumprestor.h> 47: #include <pwd.h> 48: #include <stdio.h> 49: 50: #define TS_CLOSED 0 51: #define TS_OPEN 1 52: 53: #define rmtstate rstate 54: static int rmtstate = TS_CLOSED; 55: int rmtape; 56: void rmtgetconn(); 57: void rmtconnaborted(); 58: int rmtreply(); 59: int rmtgetb(); 60: void rmtgets(); 61: int rmtcall(); 62: char *rmtpeer; 63: 64: extern void msg(); 65: 66: int 67: rmthost(host) 68: char *host; 69: { 70: 71: rmtpeer = host; 72: signal(SIGPIPE, rmtconnaborted); 73: rmtgetconn(); 74: if (rmtape < 0) 75: return (0); 76: return (1); 77: } 78: 79: void 80: rmtconnaborted() 81: { 82: 83: fprintf(stderr, "rdump: Lost connection to remote host.\n"); 84: exit(1); 85: } 86: 87: void 88: rmtgetconn() 89: { 90: static struct servent *sp = 0; 91: struct passwd *pw; 92: char *name = "root"; 93: int size; 94: 95: if (sp == 0) { 96: sp = getservbyname("shell", "tcp"); 97: if (sp == 0) { 98: fprintf(stderr, "rdump: shell/tcp: unknown service\n"); 99: exit(1); 100: } 101: } 102: pw = getpwuid(getuid()); 103: if (pw && pw->pw_name) 104: name = pw->pw_name; 105: rmtape = rcmd(&rmtpeer, sp->s_port, name, name, "rmt", 0); 106: size = NTREC * DEV_BSIZE; 107: while (size > DEV_BSIZE && 108: setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 109: size -= DEV_BSIZE; 110: } 111: 112: int 113: rmtopen(tape, mode) 114: char *tape; 115: int mode; 116: { 117: char buf[256]; 118: 119: (void)sprintf(buf, "O%s\n%d\n", tape, mode); 120: rmtstate = TS_OPEN; 121: return (rmtcall(tape, buf)); 122: } 123: 124: void 125: rmtclose() 126: { 127: 128: if (rmtstate != TS_OPEN) 129: return; 130: rmtcall("close", "C\n"); 131: rmtstate = TS_CLOSED; 132: } 133: 134: int 135: rmtwrite(buf, count) 136: char *buf; 137: int count; 138: { 139: char line[30]; 140: 141: (void)sprintf(line, "W%d\n", count); 142: write(rmtape, line, strlen(line)); 143: write(rmtape, buf, count); 144: return (rmtreply("write")); 145: } 146: 147: int 148: rmtcall(cmd, buf) 149: char *cmd, *buf; 150: { 151: 152: if (write(rmtape, buf, strlen(buf)) != strlen(buf)) 153: rmtconnaborted(); 154: return (rmtreply(cmd)); 155: } 156: 157: int 158: rmtreply(cmd) 159: char *cmd; 160: { 161: char code[30], emsg[BUFSIZ]; 162: 163: rmtgets(code, sizeof (code)); 164: if (*code == 'E' || *code == 'F') { 165: rmtgets(emsg, sizeof (emsg)); 166: msg("%s: %s\n", cmd, emsg, code + 1); 167: if (*code == 'F') { 168: rmtstate = TS_CLOSED; 169: return (-1); 170: } 171: return (-1); 172: } 173: if (*code != 'A') { 174: msg("Protocol to remote tape server botched (code %s?).\n", 175: code); 176: rmtconnaborted(); 177: } 178: return (atoi(code + 1)); 179: } 180: 181: int 182: rmtgetb() 183: { 184: char c; 185: 186: if (read(rmtape, &c, 1) != 1) 187: rmtconnaborted(); 188: return (c); 189: } 190: 191: void 192: rmtgets(cp, len) 193: char *cp; 194: int len; 195: { 196: 197: while (len > 1) { 198: *cp = rmtgetb(); 199: if (*cp == '\n') { 200: cp[1] = 0; 201: return; 202: } 203: cp++; 204: len--; 205: } 206: msg("Protocol to remote tape server botched (in rmtgets).\n"); 207: rmtconnaborted(); 208: }