1*47082Smckusick /*- 2*47082Smckusick * Copyright (c) 1980 The Regents of the University of California. 3*47082Smckusick * All rights reserved. 4*47082Smckusick * 5*47082Smckusick * %sccs.include.redist.c% 622039Sdist */ 76645Ssam 822039Sdist #ifndef lint 9*47082Smckusick static char sccsid[] = "@(#)dumprmt.c 5.11 (Berkeley) 03/07/91"; 1046587Storek #endif /* not lint */ 1122039Sdist 126884Ssam #include <sys/param.h> 136645Ssam #include <sys/mtio.h> 146645Ssam #include <sys/ioctl.h> 1517538Sralph #include <sys/socket.h> 1640098Smckusick #include <ufs/dinode.h> 1746795Sbostic #include <signal.h> 186645Ssam 199306Ssam #include <netinet/in.h> 209306Ssam 219306Ssam #include <netdb.h> 2223544Smckusick #include <protocols/dumprestore.h> 2337946Sbostic #include <pwd.h> 2437946Sbostic #include <stdio.h> 2546795Sbostic #ifdef __STDC__ 2646795Sbostic #include <unistd.h> 2746587Storek #include <stdlib.h> 2846587Storek #include <string.h> 2946795Sbostic #endif 3037946Sbostic #include "pathnames.h" 319306Ssam 326645Ssam #define TS_CLOSED 0 336645Ssam #define TS_OPEN 1 346645Ssam 356645Ssam static int rmtstate = TS_CLOSED; 366645Ssam int rmtape; 3746587Storek void rmtgetconn(); 3846587Storek void rmtconnaborted(); 3946587Storek int rmtreply(); 4046587Storek int rmtgetb(); 4146587Storek void rmtgets(); 4246587Storek int rmtcall(); 436645Ssam char *rmtpeer; 446645Ssam 4517538Sralph extern int ntrec; /* blocking factor on tape */ 4646587Storek extern void msg(); 4717538Sralph 4846587Storek int 496645Ssam rmthost(host) 506645Ssam char *host; 516645Ssam { 526645Ssam 536645Ssam rmtpeer = host; 5413032Ssam signal(SIGPIPE, rmtconnaborted); 556645Ssam rmtgetconn(); 566645Ssam if (rmtape < 0) 5717538Sralph return (0); 5817538Sralph return (1); 596645Ssam } 606645Ssam 6146587Storek void 626645Ssam rmtconnaborted() 636645Ssam { 646645Ssam 6517538Sralph fprintf(stderr, "rdump: Lost connection to remote host.\n"); 666884Ssam exit(1); 676645Ssam } 686645Ssam 6946587Storek void 706645Ssam rmtgetconn() 716645Ssam { 729306Ssam static struct servent *sp = 0; 7316376Skarels struct passwd *pw; 7416376Skarels char *name = "root"; 7517538Sralph int size; 766645Ssam 779306Ssam if (sp == 0) { 789306Ssam sp = getservbyname("shell", "tcp"); 799306Ssam if (sp == 0) { 809306Ssam fprintf(stderr, "rdump: shell/tcp: unknown service\n"); 819306Ssam exit(1); 829306Ssam } 839306Ssam } 8416376Skarels pw = getpwuid(getuid()); 8516376Skarels if (pw && pw->pw_name) 8616376Skarels name = pw->pw_name; 8737946Sbostic rmtape = rcmd(&rmtpeer, sp->s_port, name, name, _PATH_RMT, 0); 8817538Sralph size = ntrec * TP_BSIZE; 8918493Smckusick while (size > TP_BSIZE && 9018493Smckusick setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 9118493Smckusick size -= TP_BSIZE; 926645Ssam } 936645Ssam 9446587Storek int 956645Ssam rmtopen(tape, mode) 966645Ssam char *tape; 976645Ssam int mode; 986645Ssam { 996645Ssam char buf[256]; 1006645Ssam 10132455Sbostic (void)sprintf(buf, "O%s\n%d\n", tape, mode); 1026645Ssam rmtstate = TS_OPEN; 10324836Smckusick return (rmtcall(tape, buf)); 1046645Ssam } 1056645Ssam 10646587Storek void 1076645Ssam rmtclose() 1086645Ssam { 1096645Ssam 1106645Ssam if (rmtstate != TS_OPEN) 1116645Ssam return; 1126645Ssam rmtcall("close", "C\n"); 1136645Ssam rmtstate = TS_CLOSED; 1146645Ssam } 1156645Ssam 11646587Storek int 1176645Ssam rmtread(buf, count) 1186645Ssam char *buf; 1196645Ssam int count; 1206645Ssam { 1216645Ssam char line[30]; 1226645Ssam int n, i, cc; 1236884Ssam extern errno; 1246645Ssam 12532455Sbostic (void)sprintf(line, "R%d\n", count); 1266645Ssam n = rmtcall("read", line); 1276884Ssam if (n < 0) { 1286884Ssam errno = n; 1296645Ssam return (-1); 1306884Ssam } 1316645Ssam for (i = 0; i < n; i += cc) { 1326645Ssam cc = read(rmtape, buf+i, n - i); 1336884Ssam if (cc <= 0) { 1346645Ssam rmtconnaborted(); 1356884Ssam } 1366645Ssam } 1376645Ssam return (n); 1386645Ssam } 1396645Ssam 14046587Storek int 1416645Ssam rmtwrite(buf, count) 1426645Ssam char *buf; 1436645Ssam int count; 1446645Ssam { 1456645Ssam char line[30]; 1466645Ssam 14732455Sbostic (void)sprintf(line, "W%d\n", count); 1486645Ssam write(rmtape, line, strlen(line)); 1496645Ssam write(rmtape, buf, count); 1506645Ssam return (rmtreply("write")); 1516645Ssam } 1526645Ssam 15346587Storek void 1546645Ssam rmtwrite0(count) 1556645Ssam int count; 1566645Ssam { 1576645Ssam char line[30]; 1586645Ssam 15932455Sbostic (void)sprintf(line, "W%d\n", count); 1606645Ssam write(rmtape, line, strlen(line)); 1616645Ssam } 1626645Ssam 16346587Storek void 1646645Ssam rmtwrite1(buf, count) 1656645Ssam char *buf; 1666645Ssam int count; 1676645Ssam { 1686645Ssam 1696645Ssam write(rmtape, buf, count); 1706645Ssam } 1716645Ssam 17246587Storek int 1736645Ssam rmtwrite2() 1746645Ssam { 1756645Ssam 1766645Ssam return (rmtreply("write")); 1776645Ssam } 1786645Ssam 17946587Storek int 1806645Ssam rmtseek(offset, pos) 1816645Ssam int offset, pos; 1826645Ssam { 1836645Ssam char line[80]; 1846645Ssam 18532455Sbostic (void)sprintf(line, "L%d\n%d\n", offset, pos); 1866645Ssam return (rmtcall("seek", line)); 1876645Ssam } 1886645Ssam 1896645Ssam struct mtget mts; 1906645Ssam 1916645Ssam struct mtget * 1926645Ssam rmtstatus() 1936645Ssam { 1946645Ssam register int i; 1956645Ssam register char *cp; 1966645Ssam 1976645Ssam if (rmtstate != TS_OPEN) 1986645Ssam return (0); 1996645Ssam rmtcall("status", "S\n"); 2006645Ssam for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++) 2016645Ssam *cp++ = rmtgetb(); 2026645Ssam return (&mts); 2036645Ssam } 2046645Ssam 20546587Storek int 2066645Ssam rmtioctl(cmd, count) 2076645Ssam int cmd, count; 2086645Ssam { 2096645Ssam char buf[256]; 2106645Ssam 2116645Ssam if (count < 0) 2126645Ssam return (-1); 21332455Sbostic (void)sprintf(buf, "I%d\n%d\n", cmd, count); 21413545Ssam return (rmtcall("ioctl", buf)); 2156645Ssam } 2166645Ssam 21746587Storek int 2186645Ssam rmtcall(cmd, buf) 2196645Ssam char *cmd, *buf; 2206645Ssam { 2216645Ssam 2226645Ssam if (write(rmtape, buf, strlen(buf)) != strlen(buf)) 2236645Ssam rmtconnaborted(); 2246645Ssam return (rmtreply(cmd)); 2256645Ssam } 2266645Ssam 22746587Storek int 2286645Ssam rmtreply(cmd) 2296645Ssam char *cmd; 2306645Ssam { 2316645Ssam char code[30], emsg[BUFSIZ]; 2326645Ssam 2336645Ssam rmtgets(code, sizeof (code)); 2346645Ssam if (*code == 'E' || *code == 'F') { 2356645Ssam rmtgets(emsg, sizeof (emsg)); 2366645Ssam msg("%s: %s\n", cmd, emsg, code + 1); 2376645Ssam if (*code == 'F') { 2386645Ssam rmtstate = TS_CLOSED; 2396645Ssam return (-1); 2406645Ssam } 2416645Ssam return (-1); 2426645Ssam } 2436645Ssam if (*code != 'A') { 2446645Ssam msg("Protocol to remote tape server botched (code %s?).\n", 2456645Ssam code); 2466645Ssam rmtconnaborted(); 2476645Ssam } 2486645Ssam return (atoi(code + 1)); 2496645Ssam } 2506645Ssam 25146587Storek int 2526645Ssam rmtgetb() 2536645Ssam { 2546645Ssam char c; 2556645Ssam 2566645Ssam if (read(rmtape, &c, 1) != 1) 2576645Ssam rmtconnaborted(); 2586645Ssam return (c); 2596645Ssam } 2606645Ssam 26146587Storek void 2626645Ssam rmtgets(cp, len) 2636645Ssam char *cp; 2646645Ssam int len; 2656645Ssam { 2666645Ssam 2676645Ssam while (len > 1) { 2686645Ssam *cp = rmtgetb(); 2696645Ssam if (*cp == '\n') { 2706645Ssam cp[1] = 0; 2716645Ssam return; 2726645Ssam } 2736645Ssam cp++; 2746645Ssam len--; 2756645Ssam } 2766645Ssam msg("Protocol to remote tape server botched (in rmtgets).\n"); 2776645Ssam rmtconnaborted(); 2786645Ssam } 279