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*46587Storek static char sccsid[] = "@(#)dumprmt.c 5.9 (Berkeley) 02/23/91"; 9*46587Storek #endif /* not lint */ 1022039Sdist 116884Ssam #include <sys/param.h> 126645Ssam #include <sys/mtio.h> 136645Ssam #include <sys/ioctl.h> 1417538Sralph #include <sys/socket.h> 1540098Smckusick #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> 23*46587Storek #include <stdlib.h> 24*46587Storek #include <string.h> 2537946Sbostic #include "pathnames.h" 269306Ssam 276645Ssam #define TS_CLOSED 0 286645Ssam #define TS_OPEN 1 296645Ssam 306645Ssam static int rmtstate = TS_CLOSED; 316645Ssam int rmtape; 32*46587Storek void rmtgetconn(); 33*46587Storek void rmtconnaborted(); 34*46587Storek int rmtreply(); 35*46587Storek int rmtgetb(); 36*46587Storek void rmtgets(); 37*46587Storek int rmtcall(); 386645Ssam char *rmtpeer; 396645Ssam 4017538Sralph extern int ntrec; /* blocking factor on tape */ 41*46587Storek extern void msg(); 4217538Sralph 43*46587Storek int 446645Ssam rmthost(host) 456645Ssam char *host; 466645Ssam { 476645Ssam 486645Ssam rmtpeer = host; 4913032Ssam signal(SIGPIPE, rmtconnaborted); 506645Ssam rmtgetconn(); 516645Ssam if (rmtape < 0) 5217538Sralph return (0); 5317538Sralph return (1); 546645Ssam } 556645Ssam 56*46587Storek void 576645Ssam rmtconnaborted() 586645Ssam { 596645Ssam 6017538Sralph fprintf(stderr, "rdump: Lost connection to remote host.\n"); 616884Ssam exit(1); 626645Ssam } 636645Ssam 64*46587Storek void 656645Ssam rmtgetconn() 666645Ssam { 679306Ssam static struct servent *sp = 0; 6816376Skarels struct passwd *pw; 6916376Skarels char *name = "root"; 7017538Sralph int size; 716645Ssam 729306Ssam if (sp == 0) { 739306Ssam sp = getservbyname("shell", "tcp"); 749306Ssam if (sp == 0) { 759306Ssam fprintf(stderr, "rdump: shell/tcp: unknown service\n"); 769306Ssam exit(1); 779306Ssam } 789306Ssam } 7916376Skarels pw = getpwuid(getuid()); 8016376Skarels if (pw && pw->pw_name) 8116376Skarels name = pw->pw_name; 8237946Sbostic rmtape = rcmd(&rmtpeer, sp->s_port, name, name, _PATH_RMT, 0); 8317538Sralph size = ntrec * TP_BSIZE; 8418493Smckusick while (size > TP_BSIZE && 8518493Smckusick setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 8618493Smckusick size -= TP_BSIZE; 876645Ssam } 886645Ssam 89*46587Storek int 906645Ssam rmtopen(tape, mode) 916645Ssam char *tape; 926645Ssam int mode; 936645Ssam { 946645Ssam char buf[256]; 956645Ssam 9632455Sbostic (void)sprintf(buf, "O%s\n%d\n", tape, mode); 976645Ssam rmtstate = TS_OPEN; 9824836Smckusick return (rmtcall(tape, buf)); 996645Ssam } 1006645Ssam 101*46587Storek void 1026645Ssam rmtclose() 1036645Ssam { 1046645Ssam 1056645Ssam if (rmtstate != TS_OPEN) 1066645Ssam return; 1076645Ssam rmtcall("close", "C\n"); 1086645Ssam rmtstate = TS_CLOSED; 1096645Ssam } 1106645Ssam 111*46587Storek int 1126645Ssam rmtread(buf, count) 1136645Ssam char *buf; 1146645Ssam int count; 1156645Ssam { 1166645Ssam char line[30]; 1176645Ssam int n, i, cc; 1186884Ssam extern errno; 1196645Ssam 12032455Sbostic (void)sprintf(line, "R%d\n", count); 1216645Ssam n = rmtcall("read", line); 1226884Ssam if (n < 0) { 1236884Ssam errno = n; 1246645Ssam return (-1); 1256884Ssam } 1266645Ssam for (i = 0; i < n; i += cc) { 1276645Ssam cc = read(rmtape, buf+i, n - i); 1286884Ssam if (cc <= 0) { 1296645Ssam rmtconnaborted(); 1306884Ssam } 1316645Ssam } 1326645Ssam return (n); 1336645Ssam } 1346645Ssam 135*46587Storek int 1366645Ssam rmtwrite(buf, count) 1376645Ssam char *buf; 1386645Ssam int count; 1396645Ssam { 1406645Ssam char line[30]; 1416645Ssam 14232455Sbostic (void)sprintf(line, "W%d\n", count); 1436645Ssam write(rmtape, line, strlen(line)); 1446645Ssam write(rmtape, buf, count); 1456645Ssam return (rmtreply("write")); 1466645Ssam } 1476645Ssam 148*46587Storek void 1496645Ssam rmtwrite0(count) 1506645Ssam int count; 1516645Ssam { 1526645Ssam char line[30]; 1536645Ssam 15432455Sbostic (void)sprintf(line, "W%d\n", count); 1556645Ssam write(rmtape, line, strlen(line)); 1566645Ssam } 1576645Ssam 158*46587Storek void 1596645Ssam rmtwrite1(buf, count) 1606645Ssam char *buf; 1616645Ssam int count; 1626645Ssam { 1636645Ssam 1646645Ssam write(rmtape, buf, count); 1656645Ssam } 1666645Ssam 167*46587Storek int 1686645Ssam rmtwrite2() 1696645Ssam { 1706645Ssam 1716645Ssam return (rmtreply("write")); 1726645Ssam } 1736645Ssam 174*46587Storek int 1756645Ssam rmtseek(offset, pos) 1766645Ssam int offset, pos; 1776645Ssam { 1786645Ssam char line[80]; 1796645Ssam 18032455Sbostic (void)sprintf(line, "L%d\n%d\n", offset, pos); 1816645Ssam return (rmtcall("seek", line)); 1826645Ssam } 1836645Ssam 1846645Ssam struct mtget mts; 1856645Ssam 1866645Ssam struct mtget * 1876645Ssam rmtstatus() 1886645Ssam { 1896645Ssam register int i; 1906645Ssam register char *cp; 1916645Ssam 1926645Ssam if (rmtstate != TS_OPEN) 1936645Ssam return (0); 1946645Ssam rmtcall("status", "S\n"); 1956645Ssam for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++) 1966645Ssam *cp++ = rmtgetb(); 1976645Ssam return (&mts); 1986645Ssam } 1996645Ssam 200*46587Storek int 2016645Ssam rmtioctl(cmd, count) 2026645Ssam int cmd, count; 2036645Ssam { 2046645Ssam char buf[256]; 2056645Ssam 2066645Ssam if (count < 0) 2076645Ssam return (-1); 20832455Sbostic (void)sprintf(buf, "I%d\n%d\n", cmd, count); 20913545Ssam return (rmtcall("ioctl", buf)); 2106645Ssam } 2116645Ssam 212*46587Storek int 2136645Ssam rmtcall(cmd, buf) 2146645Ssam char *cmd, *buf; 2156645Ssam { 2166645Ssam 2176645Ssam if (write(rmtape, buf, strlen(buf)) != strlen(buf)) 2186645Ssam rmtconnaborted(); 2196645Ssam return (rmtreply(cmd)); 2206645Ssam } 2216645Ssam 222*46587Storek int 2236645Ssam rmtreply(cmd) 2246645Ssam char *cmd; 2256645Ssam { 2266645Ssam char code[30], emsg[BUFSIZ]; 2276645Ssam 2286645Ssam rmtgets(code, sizeof (code)); 2296645Ssam if (*code == 'E' || *code == 'F') { 2306645Ssam rmtgets(emsg, sizeof (emsg)); 2316645Ssam msg("%s: %s\n", cmd, emsg, code + 1); 2326645Ssam if (*code == 'F') { 2336645Ssam rmtstate = TS_CLOSED; 2346645Ssam return (-1); 2356645Ssam } 2366645Ssam return (-1); 2376645Ssam } 2386645Ssam if (*code != 'A') { 2396645Ssam msg("Protocol to remote tape server botched (code %s?).\n", 2406645Ssam code); 2416645Ssam rmtconnaborted(); 2426645Ssam } 2436645Ssam return (atoi(code + 1)); 2446645Ssam } 2456645Ssam 246*46587Storek int 2476645Ssam rmtgetb() 2486645Ssam { 2496645Ssam char c; 2506645Ssam 2516645Ssam if (read(rmtape, &c, 1) != 1) 2526645Ssam rmtconnaborted(); 2536645Ssam return (c); 2546645Ssam } 2556645Ssam 256*46587Storek void 2576645Ssam rmtgets(cp, len) 2586645Ssam char *cp; 2596645Ssam int len; 2606645Ssam { 2616645Ssam 2626645Ssam while (len > 1) { 2636645Ssam *cp = rmtgetb(); 2646645Ssam if (*cp == '\n') { 2656645Ssam cp[1] = 0; 2666645Ssam return; 2676645Ssam } 2686645Ssam cp++; 2696645Ssam len--; 2706645Ssam } 2716645Ssam msg("Protocol to remote tape server botched (in rmtgets).\n"); 2726645Ssam rmtconnaborted(); 2736645Ssam } 274