1: /* 2: * Copyright (c) 1980 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: #ifndef lint 8: static char sccsid[] = "@(#)dumprmt.c 5.4 (Berkeley) 12/11/85"; 9: #endif not lint 10: 11: #include <sys/param.h> 12: #include <sys/mtio.h> 13: #include <sys/ioctl.h> 14: #include <sys/socket.h> 15: #include <sys/inode.h> 16: 17: #include <netinet/in.h> 18: 19: #include <stdio.h> 20: #include <pwd.h> 21: #include <netdb.h> 22: #include <protocols/dumprestore.h> 23: 24: #define TS_CLOSED 0 25: #define TS_OPEN 1 26: 27: static int rmtstate = TS_CLOSED; 28: int rmtape; 29: int rmtconnaborted(); 30: char *rmtpeer; 31: 32: extern int ntrec; /* blocking factor on tape */ 33: 34: rmthost(host) 35: char *host; 36: { 37: 38: rmtpeer = host; 39: signal(SIGPIPE, rmtconnaborted); 40: rmtgetconn(); 41: if (rmtape < 0) 42: return (0); 43: return (1); 44: } 45: 46: rmtconnaborted() 47: { 48: 49: fprintf(stderr, "rdump: Lost connection to remote host.\n"); 50: exit(1); 51: } 52: 53: rmtgetconn() 54: { 55: static struct servent *sp = 0; 56: struct passwd *pw; 57: char *name = "root"; 58: int size; 59: 60: if (sp == 0) { 61: sp = getservbyname("shell", "tcp"); 62: if (sp == 0) { 63: fprintf(stderr, "rdump: shell/tcp: unknown service\n"); 64: exit(1); 65: } 66: } 67: pw = getpwuid(getuid()); 68: if (pw && pw->pw_name) 69: name = pw->pw_name; 70: rmtape = rcmd(&rmtpeer, sp->s_port, name, name, "/etc/rmt", 0); 71: size = ntrec * TP_BSIZE; 72: while (size > TP_BSIZE && 73: setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 74: size -= TP_BSIZE; 75: } 76: 77: rmtopen(tape, mode) 78: char *tape; 79: int mode; 80: { 81: char buf[256]; 82: 83: sprintf(buf, "O%s\n%d\n", tape, mode); 84: rmtstate = TS_OPEN; 85: return (rmtcall(tape, buf)); 86: } 87: 88: rmtclose() 89: { 90: 91: if (rmtstate != TS_OPEN) 92: return; 93: rmtcall("close", "C\n"); 94: rmtstate = TS_CLOSED; 95: } 96: 97: rmtread(buf, count) 98: char *buf; 99: int count; 100: { 101: char line[30]; 102: int n, i, cc; 103: extern errno; 104: 105: sprintf(line, "R%d\n", count); 106: n = rmtcall("read", line); 107: if (n < 0) { 108: errno = n; 109: return (-1); 110: } 111: for (i = 0; i < n; i += cc) { 112: cc = read(rmtape, buf+i, n - i); 113: if (cc <= 0) { 114: rmtconnaborted(); 115: } 116: } 117: return (n); 118: } 119: 120: rmtwrite(buf, count) 121: char *buf; 122: int count; 123: { 124: char line[30]; 125: 126: sprintf(line, "W%d\n", count); 127: write(rmtape, line, strlen(line)); 128: write(rmtape, buf, count); 129: return (rmtreply("write")); 130: } 131: 132: rmtwrite0(count) 133: int count; 134: { 135: char line[30]; 136: 137: sprintf(line, "W%d\n", count); 138: write(rmtape, line, strlen(line)); 139: } 140: 141: rmtwrite1(buf, count) 142: char *buf; 143: int count; 144: { 145: 146: write(rmtape, buf, count); 147: } 148: 149: rmtwrite2() 150: { 151: int i; 152: 153: return (rmtreply("write")); 154: } 155: 156: rmtseek(offset, pos) 157: int offset, pos; 158: { 159: char line[80]; 160: 161: sprintf(line, "L%d\n%d\n", offset, pos); 162: return (rmtcall("seek", line)); 163: } 164: 165: struct mtget mts; 166: 167: struct mtget * 168: rmtstatus() 169: { 170: register int i; 171: register char *cp; 172: 173: if (rmtstate != TS_OPEN) 174: return (0); 175: rmtcall("status", "S\n"); 176: for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++) 177: *cp++ = rmtgetb(); 178: return (&mts); 179: } 180: 181: rmtioctl(cmd, count) 182: int cmd, count; 183: { 184: char buf[256]; 185: 186: if (count < 0) 187: return (-1); 188: sprintf(buf, "I%d\n%d\n", cmd, count); 189: return (rmtcall("ioctl", buf)); 190: } 191: 192: rmtcall(cmd, buf) 193: char *cmd, *buf; 194: { 195: 196: if (write(rmtape, buf, strlen(buf)) != strlen(buf)) 197: rmtconnaborted(); 198: return (rmtreply(cmd)); 199: } 200: 201: rmtreply(cmd) 202: char *cmd; 203: { 204: register int c; 205: char code[30], emsg[BUFSIZ]; 206: 207: rmtgets(code, sizeof (code)); 208: if (*code == 'E' || *code == 'F') { 209: rmtgets(emsg, sizeof (emsg)); 210: msg("%s: %s\n", cmd, emsg, code + 1); 211: if (*code == 'F') { 212: rmtstate = TS_CLOSED; 213: return (-1); 214: } 215: return (-1); 216: } 217: if (*code != 'A') { 218: msg("Protocol to remote tape server botched (code %s?).\n", 219: code); 220: rmtconnaborted(); 221: } 222: return (atoi(code + 1)); 223: } 224: 225: rmtgetb() 226: { 227: char c; 228: 229: if (read(rmtape, &c, 1) != 1) 230: rmtconnaborted(); 231: return (c); 232: } 233: 234: rmtgets(cp, len) 235: char *cp; 236: int len; 237: { 238: 239: while (len > 1) { 240: *cp = rmtgetb(); 241: if (*cp == '\n') { 242: cp[1] = 0; 243: return; 244: } 245: cp++; 246: len--; 247: } 248: msg("Protocol to remote tape server botched (in rmtgets).\n"); 249: rmtconnaborted(); 250: }