122039Sdist /* 222039Sdist * Copyright (c) 1980 Regents of the University of California. 322039Sdist * All rights reserved. The Berkeley software License Agreement 422039Sdist * specifies the terms and conditions for redistribution. 522039Sdist */ 66645Ssam 722039Sdist #ifndef lint 8*32455Sbostic static char sccsid[] = "@(#)dumprmt.c 5.5 (Berkeley) 10/22/87"; 922039Sdist #endif not lint 1022039Sdist 116884Ssam #include <sys/param.h> 126645Ssam #include <sys/mtio.h> 136645Ssam #include <sys/ioctl.h> 1417538Sralph #include <sys/socket.h> 1517538Sralph #include <sys/inode.h> 166645Ssam 179306Ssam #include <netinet/in.h> 189306Ssam 199306Ssam #include <stdio.h> 2016376Skarels #include <pwd.h> 219306Ssam #include <netdb.h> 2223544Smckusick #include <protocols/dumprestore.h> 239306Ssam 246645Ssam #define TS_CLOSED 0 256645Ssam #define TS_OPEN 1 266645Ssam 276645Ssam static int rmtstate = TS_CLOSED; 286645Ssam int rmtape; 296645Ssam int rmtconnaborted(); 306645Ssam char *rmtpeer; 316645Ssam 3217538Sralph extern int ntrec; /* blocking factor on tape */ 3317538Sralph 346645Ssam rmthost(host) 356645Ssam char *host; 366645Ssam { 376645Ssam 386645Ssam rmtpeer = host; 3913032Ssam signal(SIGPIPE, rmtconnaborted); 406645Ssam rmtgetconn(); 416645Ssam if (rmtape < 0) 4217538Sralph return (0); 4317538Sralph return (1); 446645Ssam } 456645Ssam 466645Ssam rmtconnaborted() 476645Ssam { 486645Ssam 4917538Sralph fprintf(stderr, "rdump: Lost connection to remote host.\n"); 506884Ssam exit(1); 516645Ssam } 526645Ssam 536645Ssam rmtgetconn() 546645Ssam { 559306Ssam static struct servent *sp = 0; 5616376Skarels struct passwd *pw; 5716376Skarels char *name = "root"; 5817538Sralph int size; 596645Ssam 609306Ssam if (sp == 0) { 619306Ssam sp = getservbyname("shell", "tcp"); 629306Ssam if (sp == 0) { 639306Ssam fprintf(stderr, "rdump: shell/tcp: unknown service\n"); 649306Ssam exit(1); 659306Ssam } 669306Ssam } 6716376Skarels pw = getpwuid(getuid()); 6816376Skarels if (pw && pw->pw_name) 6916376Skarels name = pw->pw_name; 7016376Skarels rmtape = rcmd(&rmtpeer, sp->s_port, name, name, "/etc/rmt", 0); 7117538Sralph size = ntrec * TP_BSIZE; 7218493Smckusick while (size > TP_BSIZE && 7318493Smckusick setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 7418493Smckusick size -= TP_BSIZE; 756645Ssam } 766645Ssam 776645Ssam rmtopen(tape, mode) 786645Ssam char *tape; 796645Ssam int mode; 806645Ssam { 816645Ssam char buf[256]; 826645Ssam 83*32455Sbostic (void)sprintf(buf, "O%s\n%d\n", tape, mode); 846645Ssam rmtstate = TS_OPEN; 8524836Smckusick return (rmtcall(tape, buf)); 866645Ssam } 876645Ssam 886645Ssam rmtclose() 896645Ssam { 906645Ssam 916645Ssam if (rmtstate != TS_OPEN) 926645Ssam return; 936645Ssam rmtcall("close", "C\n"); 946645Ssam rmtstate = TS_CLOSED; 956645Ssam } 966645Ssam 976645Ssam rmtread(buf, count) 986645Ssam char *buf; 996645Ssam int count; 1006645Ssam { 1016645Ssam char line[30]; 1026645Ssam int n, i, cc; 1036884Ssam extern errno; 1046645Ssam 105*32455Sbostic (void)sprintf(line, "R%d\n", count); 1066645Ssam n = rmtcall("read", line); 1076884Ssam if (n < 0) { 1086884Ssam errno = n; 1096645Ssam return (-1); 1106884Ssam } 1116645Ssam for (i = 0; i < n; i += cc) { 1126645Ssam cc = read(rmtape, buf+i, n - i); 1136884Ssam if (cc <= 0) { 1146645Ssam rmtconnaborted(); 1156884Ssam } 1166645Ssam } 1176645Ssam return (n); 1186645Ssam } 1196645Ssam 1206645Ssam rmtwrite(buf, count) 1216645Ssam char *buf; 1226645Ssam int count; 1236645Ssam { 1246645Ssam char line[30]; 1256645Ssam 126*32455Sbostic (void)sprintf(line, "W%d\n", count); 1276645Ssam write(rmtape, line, strlen(line)); 1286645Ssam write(rmtape, buf, count); 1296645Ssam return (rmtreply("write")); 1306645Ssam } 1316645Ssam 1326645Ssam rmtwrite0(count) 1336645Ssam int count; 1346645Ssam { 1356645Ssam char line[30]; 1366645Ssam 137*32455Sbostic (void)sprintf(line, "W%d\n", count); 1386645Ssam write(rmtape, line, strlen(line)); 1396645Ssam } 1406645Ssam 1416645Ssam rmtwrite1(buf, count) 1426645Ssam char *buf; 1436645Ssam int count; 1446645Ssam { 1456645Ssam 1466645Ssam write(rmtape, buf, count); 1476645Ssam } 1486645Ssam 1496645Ssam rmtwrite2() 1506645Ssam { 1516645Ssam int i; 1526645Ssam 1536645Ssam return (rmtreply("write")); 1546645Ssam } 1556645Ssam 1566645Ssam rmtseek(offset, pos) 1576645Ssam int offset, pos; 1586645Ssam { 1596645Ssam char line[80]; 1606645Ssam 161*32455Sbostic (void)sprintf(line, "L%d\n%d\n", offset, pos); 1626645Ssam return (rmtcall("seek", line)); 1636645Ssam } 1646645Ssam 1656645Ssam struct mtget mts; 1666645Ssam 1676645Ssam struct mtget * 1686645Ssam rmtstatus() 1696645Ssam { 1706645Ssam register int i; 1716645Ssam register char *cp; 1726645Ssam 1736645Ssam if (rmtstate != TS_OPEN) 1746645Ssam return (0); 1756645Ssam rmtcall("status", "S\n"); 1766645Ssam for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++) 1776645Ssam *cp++ = rmtgetb(); 1786645Ssam return (&mts); 1796645Ssam } 1806645Ssam 1816645Ssam rmtioctl(cmd, count) 1826645Ssam int cmd, count; 1836645Ssam { 1846645Ssam char buf[256]; 1856645Ssam 1866645Ssam if (count < 0) 1876645Ssam return (-1); 188*32455Sbostic (void)sprintf(buf, "I%d\n%d\n", cmd, count); 18913545Ssam return (rmtcall("ioctl", buf)); 1906645Ssam } 1916645Ssam 1926645Ssam rmtcall(cmd, buf) 1936645Ssam char *cmd, *buf; 1946645Ssam { 1956645Ssam 1966645Ssam if (write(rmtape, buf, strlen(buf)) != strlen(buf)) 1976645Ssam rmtconnaborted(); 1986645Ssam return (rmtreply(cmd)); 1996645Ssam } 2006645Ssam 2016645Ssam rmtreply(cmd) 2026645Ssam char *cmd; 2036645Ssam { 2046645Ssam register int c; 2056645Ssam char code[30], emsg[BUFSIZ]; 2066645Ssam 2076645Ssam rmtgets(code, sizeof (code)); 2086645Ssam if (*code == 'E' || *code == 'F') { 2096645Ssam rmtgets(emsg, sizeof (emsg)); 2106645Ssam msg("%s: %s\n", cmd, emsg, code + 1); 2116645Ssam if (*code == 'F') { 2126645Ssam rmtstate = TS_CLOSED; 2136645Ssam return (-1); 2146645Ssam } 2156645Ssam return (-1); 2166645Ssam } 2176645Ssam if (*code != 'A') { 2186645Ssam msg("Protocol to remote tape server botched (code %s?).\n", 2196645Ssam code); 2206645Ssam rmtconnaborted(); 2216645Ssam } 2226645Ssam return (atoi(code + 1)); 2236645Ssam } 2246645Ssam 2256645Ssam rmtgetb() 2266645Ssam { 2276645Ssam char c; 2286645Ssam 2296645Ssam if (read(rmtape, &c, 1) != 1) 2306645Ssam rmtconnaborted(); 2316645Ssam return (c); 2326645Ssam } 2336645Ssam 2346645Ssam rmtgets(cp, len) 2356645Ssam char *cp; 2366645Ssam int len; 2376645Ssam { 2386645Ssam 2396645Ssam while (len > 1) { 2406645Ssam *cp = rmtgetb(); 2416645Ssam if (*cp == '\n') { 2426645Ssam cp[1] = 0; 2436645Ssam return; 2446645Ssam } 2456645Ssam cp++; 2466645Ssam len--; 2476645Ssam } 2486645Ssam msg("Protocol to remote tape server botched (in rmtgets).\n"); 2496645Ssam rmtconnaborted(); 2506645Ssam } 251