1*18493Smckusick static char *sccsid = "@(#)dumprmt.c 1.9 (Berkeley) 03/24/85"; 26645Ssam 36884Ssam #include <sys/param.h> 46645Ssam #include <sys/mtio.h> 56645Ssam #include <sys/ioctl.h> 617538Sralph #include <sys/socket.h> 717538Sralph #include <sys/inode.h> 86645Ssam 99306Ssam #include <netinet/in.h> 109306Ssam 119306Ssam #include <stdio.h> 1216376Skarels #include <pwd.h> 139306Ssam #include <netdb.h> 1417538Sralph #include <dumprestor.h> 159306Ssam 166645Ssam #define TS_CLOSED 0 176645Ssam #define TS_OPEN 1 186645Ssam 196645Ssam static int rmtstate = TS_CLOSED; 206645Ssam int rmtape; 216645Ssam int rmtconnaborted(); 226645Ssam char *rmtpeer; 236645Ssam 2417538Sralph extern int ntrec; /* blocking factor on tape */ 2517538Sralph 266645Ssam rmthost(host) 276645Ssam char *host; 286645Ssam { 296645Ssam 306645Ssam rmtpeer = host; 3113032Ssam signal(SIGPIPE, rmtconnaborted); 326645Ssam rmtgetconn(); 336645Ssam if (rmtape < 0) 3417538Sralph return (0); 3517538Sralph return (1); 366645Ssam } 376645Ssam 386645Ssam rmtconnaborted() 396645Ssam { 406645Ssam 4117538Sralph fprintf(stderr, "rdump: Lost connection to remote host.\n"); 426884Ssam exit(1); 436645Ssam } 446645Ssam 456645Ssam rmtgetconn() 466645Ssam { 479306Ssam static struct servent *sp = 0; 4816376Skarels struct passwd *pw; 4916376Skarels char *name = "root"; 5017538Sralph int size; 516645Ssam 529306Ssam if (sp == 0) { 539306Ssam sp = getservbyname("shell", "tcp"); 549306Ssam if (sp == 0) { 559306Ssam fprintf(stderr, "rdump: shell/tcp: unknown service\n"); 569306Ssam exit(1); 579306Ssam } 589306Ssam } 5916376Skarels pw = getpwuid(getuid()); 6016376Skarels if (pw && pw->pw_name) 6116376Skarels name = pw->pw_name; 6216376Skarels rmtape = rcmd(&rmtpeer, sp->s_port, name, name, "/etc/rmt", 0); 6317538Sralph size = ntrec * TP_BSIZE; 64*18493Smckusick while (size > TP_BSIZE && 65*18493Smckusick setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 66*18493Smckusick size -= TP_BSIZE; 676645Ssam } 686645Ssam 696645Ssam rmtopen(tape, mode) 706645Ssam char *tape; 716645Ssam int mode; 726645Ssam { 736645Ssam char buf[256]; 746645Ssam 756645Ssam sprintf(buf, "O%s\n%d\n", tape, mode); 766645Ssam rmtcall(tape, buf); 776645Ssam rmtstate = TS_OPEN; 786645Ssam } 796645Ssam 806645Ssam rmtclose() 816645Ssam { 826645Ssam 836645Ssam if (rmtstate != TS_OPEN) 846645Ssam return; 856645Ssam rmtcall("close", "C\n"); 866645Ssam rmtstate = TS_CLOSED; 876645Ssam } 886645Ssam 896645Ssam rmtread(buf, count) 906645Ssam char *buf; 916645Ssam int count; 926645Ssam { 936645Ssam char line[30]; 946645Ssam int n, i, cc; 956884Ssam extern errno; 966645Ssam 976645Ssam sprintf(line, "R%d\n", count); 986645Ssam n = rmtcall("read", line); 996884Ssam if (n < 0) { 1006884Ssam errno = n; 1016645Ssam return (-1); 1026884Ssam } 1036645Ssam for (i = 0; i < n; i += cc) { 1046645Ssam cc = read(rmtape, buf+i, n - i); 1056884Ssam if (cc <= 0) { 1066645Ssam rmtconnaborted(); 1076884Ssam } 1086645Ssam } 1096645Ssam return (n); 1106645Ssam } 1116645Ssam 1126645Ssam rmtwrite(buf, count) 1136645Ssam char *buf; 1146645Ssam int count; 1156645Ssam { 1166645Ssam char line[30]; 1176645Ssam 1186645Ssam sprintf(line, "W%d\n", count); 1196645Ssam write(rmtape, line, strlen(line)); 1206645Ssam write(rmtape, buf, count); 1216645Ssam return (rmtreply("write")); 1226645Ssam } 1236645Ssam 1246645Ssam rmtwrite0(count) 1256645Ssam int count; 1266645Ssam { 1276645Ssam char line[30]; 1286645Ssam 1296645Ssam sprintf(line, "W%d\n", count); 1306645Ssam write(rmtape, line, strlen(line)); 1316645Ssam } 1326645Ssam 1336645Ssam rmtwrite1(buf, count) 1346645Ssam char *buf; 1356645Ssam int count; 1366645Ssam { 1376645Ssam 1386645Ssam write(rmtape, buf, count); 1396645Ssam } 1406645Ssam 1416645Ssam rmtwrite2() 1426645Ssam { 1436645Ssam int i; 1446645Ssam 1456645Ssam return (rmtreply("write")); 1466645Ssam } 1476645Ssam 1486645Ssam rmtseek(offset, pos) 1496645Ssam int offset, pos; 1506645Ssam { 1516645Ssam char line[80]; 1526645Ssam 1536645Ssam sprintf(line, "L%d\n%d\n", offset, pos); 1546645Ssam return (rmtcall("seek", line)); 1556645Ssam } 1566645Ssam 1576645Ssam struct mtget mts; 1586645Ssam 1596645Ssam struct mtget * 1606645Ssam rmtstatus() 1616645Ssam { 1626645Ssam register int i; 1636645Ssam register char *cp; 1646645Ssam 1656645Ssam if (rmtstate != TS_OPEN) 1666645Ssam return (0); 1676645Ssam rmtcall("status", "S\n"); 1686645Ssam for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++) 1696645Ssam *cp++ = rmtgetb(); 1706645Ssam return (&mts); 1716645Ssam } 1726645Ssam 1736645Ssam rmtioctl(cmd, count) 1746645Ssam int cmd, count; 1756645Ssam { 1766645Ssam char buf[256]; 1776645Ssam 1786645Ssam if (count < 0) 1796645Ssam return (-1); 1806645Ssam sprintf(buf, "I%d\n%d\n", cmd, count); 18113545Ssam return (rmtcall("ioctl", buf)); 1826645Ssam } 1836645Ssam 1846645Ssam rmtcall(cmd, buf) 1856645Ssam char *cmd, *buf; 1866645Ssam { 1876645Ssam 1886645Ssam if (write(rmtape, buf, strlen(buf)) != strlen(buf)) 1896645Ssam rmtconnaborted(); 1906645Ssam return (rmtreply(cmd)); 1916645Ssam } 1926645Ssam 1936645Ssam rmtreply(cmd) 1946645Ssam char *cmd; 1956645Ssam { 1966645Ssam register int c; 1976645Ssam char code[30], emsg[BUFSIZ]; 1986645Ssam 1996645Ssam rmtgets(code, sizeof (code)); 2006645Ssam if (*code == 'E' || *code == 'F') { 2016645Ssam rmtgets(emsg, sizeof (emsg)); 2026645Ssam msg("%s: %s\n", cmd, emsg, code + 1); 2036645Ssam if (*code == 'F') { 2046645Ssam rmtstate = TS_CLOSED; 2056645Ssam return (-1); 2066645Ssam } 2076645Ssam return (-1); 2086645Ssam } 2096645Ssam if (*code != 'A') { 2106645Ssam msg("Protocol to remote tape server botched (code %s?).\n", 2116645Ssam code); 2126645Ssam rmtconnaborted(); 2136645Ssam } 2146645Ssam return (atoi(code + 1)); 2156645Ssam } 2166645Ssam 2176645Ssam rmtgetb() 2186645Ssam { 2196645Ssam char c; 2206645Ssam 2216645Ssam if (read(rmtape, &c, 1) != 1) 2226645Ssam rmtconnaborted(); 2236645Ssam return (c); 2246645Ssam } 2256645Ssam 2266645Ssam rmtgets(cp, len) 2276645Ssam char *cp; 2286645Ssam int len; 2296645Ssam { 2306645Ssam 2316645Ssam while (len > 1) { 2326645Ssam *cp = rmtgetb(); 2336645Ssam if (*cp == '\n') { 2346645Ssam cp[1] = 0; 2356645Ssam return; 2366645Ssam } 2376645Ssam cp++; 2386645Ssam len--; 2396645Ssam } 2406645Ssam msg("Protocol to remote tape server botched (in rmtgets).\n"); 2416645Ssam rmtconnaborted(); 2426645Ssam } 243