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*40098Smckusick static char sccsid[] = "@(#)dumprmt.c 5.8 (Berkeley) 02/15/90"; 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> 15*40098Smckusick #include <ufs/dinode.h> 166645Ssam 179306Ssam #include <netinet/in.h> 189306Ssam 199306Ssam #include <netdb.h> 2023544Smckusick #include <protocols/dumprestore.h> 2137946Sbostic #include <pwd.h> 2237946Sbostic #include <stdio.h> 2337946Sbostic #include "pathnames.h" 249306Ssam 256645Ssam #define TS_CLOSED 0 266645Ssam #define TS_OPEN 1 276645Ssam 286645Ssam static int rmtstate = TS_CLOSED; 296645Ssam int rmtape; 306645Ssam int rmtconnaborted(); 316645Ssam char *rmtpeer; 326645Ssam 3317538Sralph extern int ntrec; /* blocking factor on tape */ 3417538Sralph 356645Ssam rmthost(host) 366645Ssam char *host; 376645Ssam { 386645Ssam 396645Ssam rmtpeer = host; 4013032Ssam signal(SIGPIPE, rmtconnaborted); 416645Ssam rmtgetconn(); 426645Ssam if (rmtape < 0) 4317538Sralph return (0); 4417538Sralph return (1); 456645Ssam } 466645Ssam 476645Ssam rmtconnaborted() 486645Ssam { 496645Ssam 5017538Sralph fprintf(stderr, "rdump: Lost connection to remote host.\n"); 516884Ssam exit(1); 526645Ssam } 536645Ssam 546645Ssam rmtgetconn() 556645Ssam { 569306Ssam static struct servent *sp = 0; 5716376Skarels struct passwd *pw; 5816376Skarels char *name = "root"; 5917538Sralph int size; 606645Ssam 619306Ssam if (sp == 0) { 629306Ssam sp = getservbyname("shell", "tcp"); 639306Ssam if (sp == 0) { 649306Ssam fprintf(stderr, "rdump: shell/tcp: unknown service\n"); 659306Ssam exit(1); 669306Ssam } 679306Ssam } 6816376Skarels pw = getpwuid(getuid()); 6916376Skarels if (pw && pw->pw_name) 7016376Skarels name = pw->pw_name; 7137946Sbostic rmtape = rcmd(&rmtpeer, sp->s_port, name, name, _PATH_RMT, 0); 7217538Sralph size = ntrec * TP_BSIZE; 7318493Smckusick while (size > TP_BSIZE && 7418493Smckusick setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 7518493Smckusick size -= TP_BSIZE; 766645Ssam } 776645Ssam 786645Ssam rmtopen(tape, mode) 796645Ssam char *tape; 806645Ssam int mode; 816645Ssam { 826645Ssam char buf[256]; 836645Ssam 8432455Sbostic (void)sprintf(buf, "O%s\n%d\n", tape, mode); 856645Ssam rmtstate = TS_OPEN; 8624836Smckusick return (rmtcall(tape, buf)); 876645Ssam } 886645Ssam 896645Ssam rmtclose() 906645Ssam { 916645Ssam 926645Ssam if (rmtstate != TS_OPEN) 936645Ssam return; 946645Ssam rmtcall("close", "C\n"); 956645Ssam rmtstate = TS_CLOSED; 966645Ssam } 976645Ssam 986645Ssam rmtread(buf, count) 996645Ssam char *buf; 1006645Ssam int count; 1016645Ssam { 1026645Ssam char line[30]; 1036645Ssam int n, i, cc; 1046884Ssam extern errno; 1056645Ssam 10632455Sbostic (void)sprintf(line, "R%d\n", count); 1076645Ssam n = rmtcall("read", line); 1086884Ssam if (n < 0) { 1096884Ssam errno = n; 1106645Ssam return (-1); 1116884Ssam } 1126645Ssam for (i = 0; i < n; i += cc) { 1136645Ssam cc = read(rmtape, buf+i, n - i); 1146884Ssam if (cc <= 0) { 1156645Ssam rmtconnaborted(); 1166884Ssam } 1176645Ssam } 1186645Ssam return (n); 1196645Ssam } 1206645Ssam 1216645Ssam rmtwrite(buf, count) 1226645Ssam char *buf; 1236645Ssam int count; 1246645Ssam { 1256645Ssam char line[30]; 1266645Ssam 12732455Sbostic (void)sprintf(line, "W%d\n", count); 1286645Ssam write(rmtape, line, strlen(line)); 1296645Ssam write(rmtape, buf, count); 1306645Ssam return (rmtreply("write")); 1316645Ssam } 1326645Ssam 1336645Ssam rmtwrite0(count) 1346645Ssam int count; 1356645Ssam { 1366645Ssam char line[30]; 1376645Ssam 13832455Sbostic (void)sprintf(line, "W%d\n", count); 1396645Ssam write(rmtape, line, strlen(line)); 1406645Ssam } 1416645Ssam 1426645Ssam rmtwrite1(buf, count) 1436645Ssam char *buf; 1446645Ssam int count; 1456645Ssam { 1466645Ssam 1476645Ssam write(rmtape, buf, count); 1486645Ssam } 1496645Ssam 1506645Ssam rmtwrite2() 1516645Ssam { 1526645Ssam int i; 1536645Ssam 1546645Ssam return (rmtreply("write")); 1556645Ssam } 1566645Ssam 1576645Ssam rmtseek(offset, pos) 1586645Ssam int offset, pos; 1596645Ssam { 1606645Ssam char line[80]; 1616645Ssam 16232455Sbostic (void)sprintf(line, "L%d\n%d\n", offset, pos); 1636645Ssam return (rmtcall("seek", line)); 1646645Ssam } 1656645Ssam 1666645Ssam struct mtget mts; 1676645Ssam 1686645Ssam struct mtget * 1696645Ssam rmtstatus() 1706645Ssam { 1716645Ssam register int i; 1726645Ssam register char *cp; 1736645Ssam 1746645Ssam if (rmtstate != TS_OPEN) 1756645Ssam return (0); 1766645Ssam rmtcall("status", "S\n"); 1776645Ssam for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++) 1786645Ssam *cp++ = rmtgetb(); 1796645Ssam return (&mts); 1806645Ssam } 1816645Ssam 1826645Ssam rmtioctl(cmd, count) 1836645Ssam int cmd, count; 1846645Ssam { 1856645Ssam char buf[256]; 1866645Ssam 1876645Ssam if (count < 0) 1886645Ssam return (-1); 18932455Sbostic (void)sprintf(buf, "I%d\n%d\n", cmd, count); 19013545Ssam return (rmtcall("ioctl", buf)); 1916645Ssam } 1926645Ssam 1936645Ssam rmtcall(cmd, buf) 1946645Ssam char *cmd, *buf; 1956645Ssam { 1966645Ssam 1976645Ssam if (write(rmtape, buf, strlen(buf)) != strlen(buf)) 1986645Ssam rmtconnaborted(); 1996645Ssam return (rmtreply(cmd)); 2006645Ssam } 2016645Ssam 2026645Ssam rmtreply(cmd) 2036645Ssam char *cmd; 2046645Ssam { 2056645Ssam register int c; 2066645Ssam char code[30], emsg[BUFSIZ]; 2076645Ssam 2086645Ssam rmtgets(code, sizeof (code)); 2096645Ssam if (*code == 'E' || *code == 'F') { 2106645Ssam rmtgets(emsg, sizeof (emsg)); 2116645Ssam msg("%s: %s\n", cmd, emsg, code + 1); 2126645Ssam if (*code == 'F') { 2136645Ssam rmtstate = TS_CLOSED; 2146645Ssam return (-1); 2156645Ssam } 2166645Ssam return (-1); 2176645Ssam } 2186645Ssam if (*code != 'A') { 2196645Ssam msg("Protocol to remote tape server botched (code %s?).\n", 2206645Ssam code); 2216645Ssam rmtconnaborted(); 2226645Ssam } 2236645Ssam return (atoi(code + 1)); 2246645Ssam } 2256645Ssam 2266645Ssam rmtgetb() 2276645Ssam { 2286645Ssam char c; 2296645Ssam 2306645Ssam if (read(rmtape, &c, 1) != 1) 2316645Ssam rmtconnaborted(); 2326645Ssam return (c); 2336645Ssam } 2346645Ssam 2356645Ssam rmtgets(cp, len) 2366645Ssam char *cp; 2376645Ssam int len; 2386645Ssam { 2396645Ssam 2406645Ssam while (len > 1) { 2416645Ssam *cp = rmtgetb(); 2426645Ssam if (*cp == '\n') { 2436645Ssam cp[1] = 0; 2446645Ssam return; 2456645Ssam } 2466645Ssam cp++; 2476645Ssam len--; 2486645Ssam } 2496645Ssam msg("Protocol to remote tape server botched (in rmtgets).\n"); 2506645Ssam rmtconnaborted(); 2516645Ssam } 252