1*19983Smckusick static char *sccsid = "@(#)dumprmt.c 1.10 (Berkeley) 05/07/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); 63*19983Smckusick #ifdef notdef /* broken */ 6417538Sralph size = ntrec * TP_BSIZE; 6518493Smckusick while (size > TP_BSIZE && 6618493Smckusick setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 6718493Smckusick size -= TP_BSIZE; 68*19983Smckusick #endif notdef 696645Ssam } 706645Ssam 716645Ssam rmtopen(tape, mode) 726645Ssam char *tape; 736645Ssam int mode; 746645Ssam { 756645Ssam char buf[256]; 766645Ssam 776645Ssam sprintf(buf, "O%s\n%d\n", tape, mode); 786645Ssam rmtcall(tape, buf); 796645Ssam rmtstate = TS_OPEN; 806645Ssam } 816645Ssam 826645Ssam rmtclose() 836645Ssam { 846645Ssam 856645Ssam if (rmtstate != TS_OPEN) 866645Ssam return; 876645Ssam rmtcall("close", "C\n"); 886645Ssam rmtstate = TS_CLOSED; 896645Ssam } 906645Ssam 916645Ssam rmtread(buf, count) 926645Ssam char *buf; 936645Ssam int count; 946645Ssam { 956645Ssam char line[30]; 966645Ssam int n, i, cc; 976884Ssam extern errno; 986645Ssam 996645Ssam sprintf(line, "R%d\n", count); 1006645Ssam n = rmtcall("read", line); 1016884Ssam if (n < 0) { 1026884Ssam errno = n; 1036645Ssam return (-1); 1046884Ssam } 1056645Ssam for (i = 0; i < n; i += cc) { 1066645Ssam cc = read(rmtape, buf+i, n - i); 1076884Ssam if (cc <= 0) { 1086645Ssam rmtconnaborted(); 1096884Ssam } 1106645Ssam } 1116645Ssam return (n); 1126645Ssam } 1136645Ssam 1146645Ssam rmtwrite(buf, count) 1156645Ssam char *buf; 1166645Ssam int count; 1176645Ssam { 1186645Ssam char line[30]; 1196645Ssam 1206645Ssam sprintf(line, "W%d\n", count); 1216645Ssam write(rmtape, line, strlen(line)); 1226645Ssam write(rmtape, buf, count); 1236645Ssam return (rmtreply("write")); 1246645Ssam } 1256645Ssam 1266645Ssam rmtwrite0(count) 1276645Ssam int count; 1286645Ssam { 1296645Ssam char line[30]; 1306645Ssam 1316645Ssam sprintf(line, "W%d\n", count); 1326645Ssam write(rmtape, line, strlen(line)); 1336645Ssam } 1346645Ssam 1356645Ssam rmtwrite1(buf, count) 1366645Ssam char *buf; 1376645Ssam int count; 1386645Ssam { 1396645Ssam 1406645Ssam write(rmtape, buf, count); 1416645Ssam } 1426645Ssam 1436645Ssam rmtwrite2() 1446645Ssam { 1456645Ssam int i; 1466645Ssam 1476645Ssam return (rmtreply("write")); 1486645Ssam } 1496645Ssam 1506645Ssam rmtseek(offset, pos) 1516645Ssam int offset, pos; 1526645Ssam { 1536645Ssam char line[80]; 1546645Ssam 1556645Ssam sprintf(line, "L%d\n%d\n", offset, pos); 1566645Ssam return (rmtcall("seek", line)); 1576645Ssam } 1586645Ssam 1596645Ssam struct mtget mts; 1606645Ssam 1616645Ssam struct mtget * 1626645Ssam rmtstatus() 1636645Ssam { 1646645Ssam register int i; 1656645Ssam register char *cp; 1666645Ssam 1676645Ssam if (rmtstate != TS_OPEN) 1686645Ssam return (0); 1696645Ssam rmtcall("status", "S\n"); 1706645Ssam for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++) 1716645Ssam *cp++ = rmtgetb(); 1726645Ssam return (&mts); 1736645Ssam } 1746645Ssam 1756645Ssam rmtioctl(cmd, count) 1766645Ssam int cmd, count; 1776645Ssam { 1786645Ssam char buf[256]; 1796645Ssam 1806645Ssam if (count < 0) 1816645Ssam return (-1); 1826645Ssam sprintf(buf, "I%d\n%d\n", cmd, count); 18313545Ssam return (rmtcall("ioctl", buf)); 1846645Ssam } 1856645Ssam 1866645Ssam rmtcall(cmd, buf) 1876645Ssam char *cmd, *buf; 1886645Ssam { 1896645Ssam 1906645Ssam if (write(rmtape, buf, strlen(buf)) != strlen(buf)) 1916645Ssam rmtconnaborted(); 1926645Ssam return (rmtreply(cmd)); 1936645Ssam } 1946645Ssam 1956645Ssam rmtreply(cmd) 1966645Ssam char *cmd; 1976645Ssam { 1986645Ssam register int c; 1996645Ssam char code[30], emsg[BUFSIZ]; 2006645Ssam 2016645Ssam rmtgets(code, sizeof (code)); 2026645Ssam if (*code == 'E' || *code == 'F') { 2036645Ssam rmtgets(emsg, sizeof (emsg)); 2046645Ssam msg("%s: %s\n", cmd, emsg, code + 1); 2056645Ssam if (*code == 'F') { 2066645Ssam rmtstate = TS_CLOSED; 2076645Ssam return (-1); 2086645Ssam } 2096645Ssam return (-1); 2106645Ssam } 2116645Ssam if (*code != 'A') { 2126645Ssam msg("Protocol to remote tape server botched (code %s?).\n", 2136645Ssam code); 2146645Ssam rmtconnaborted(); 2156645Ssam } 2166645Ssam return (atoi(code + 1)); 2176645Ssam } 2186645Ssam 2196645Ssam rmtgetb() 2206645Ssam { 2216645Ssam char c; 2226645Ssam 2236645Ssam if (read(rmtape, &c, 1) != 1) 2246645Ssam rmtconnaborted(); 2256645Ssam return (c); 2266645Ssam } 2276645Ssam 2286645Ssam rmtgets(cp, len) 2296645Ssam char *cp; 2306645Ssam int len; 2316645Ssam { 2326645Ssam 2336645Ssam while (len > 1) { 2346645Ssam *cp = rmtgetb(); 2356645Ssam if (*cp == '\n') { 2366645Ssam cp[1] = 0; 2376645Ssam return; 2386645Ssam } 2396645Ssam cp++; 2406645Ssam len--; 2416645Ssam } 2426645Ssam msg("Protocol to remote tape server botched (in rmtgets).\n"); 2436645Ssam rmtconnaborted(); 2446645Ssam } 245