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*46795Sbostic static char sccsid[] = "@(#)dumprmt.c 5.10 (Berkeley) 02/28/91"; 946587Storek #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> 16*46795Sbostic #include <signal.h> 176645Ssam 189306Ssam #include <netinet/in.h> 199306Ssam 209306Ssam #include <netdb.h> 2123544Smckusick #include <protocols/dumprestore.h> 2237946Sbostic #include <pwd.h> 2337946Sbostic #include <stdio.h> 24*46795Sbostic #ifdef __STDC__ 25*46795Sbostic #include <unistd.h> 2646587Storek #include <stdlib.h> 2746587Storek #include <string.h> 28*46795Sbostic #endif 2937946Sbostic #include "pathnames.h" 309306Ssam 316645Ssam #define TS_CLOSED 0 326645Ssam #define TS_OPEN 1 336645Ssam 346645Ssam static int rmtstate = TS_CLOSED; 356645Ssam int rmtape; 3646587Storek void rmtgetconn(); 3746587Storek void rmtconnaborted(); 3846587Storek int rmtreply(); 3946587Storek int rmtgetb(); 4046587Storek void rmtgets(); 4146587Storek int rmtcall(); 426645Ssam char *rmtpeer; 436645Ssam 4417538Sralph extern int ntrec; /* blocking factor on tape */ 4546587Storek extern void msg(); 4617538Sralph 4746587Storek int 486645Ssam rmthost(host) 496645Ssam char *host; 506645Ssam { 516645Ssam 526645Ssam rmtpeer = host; 5313032Ssam signal(SIGPIPE, rmtconnaborted); 546645Ssam rmtgetconn(); 556645Ssam if (rmtape < 0) 5617538Sralph return (0); 5717538Sralph return (1); 586645Ssam } 596645Ssam 6046587Storek void 616645Ssam rmtconnaborted() 626645Ssam { 636645Ssam 6417538Sralph fprintf(stderr, "rdump: Lost connection to remote host.\n"); 656884Ssam exit(1); 666645Ssam } 676645Ssam 6846587Storek void 696645Ssam rmtgetconn() 706645Ssam { 719306Ssam static struct servent *sp = 0; 7216376Skarels struct passwd *pw; 7316376Skarels char *name = "root"; 7417538Sralph int size; 756645Ssam 769306Ssam if (sp == 0) { 779306Ssam sp = getservbyname("shell", "tcp"); 789306Ssam if (sp == 0) { 799306Ssam fprintf(stderr, "rdump: shell/tcp: unknown service\n"); 809306Ssam exit(1); 819306Ssam } 829306Ssam } 8316376Skarels pw = getpwuid(getuid()); 8416376Skarels if (pw && pw->pw_name) 8516376Skarels name = pw->pw_name; 8637946Sbostic rmtape = rcmd(&rmtpeer, sp->s_port, name, name, _PATH_RMT, 0); 8717538Sralph size = ntrec * TP_BSIZE; 8818493Smckusick while (size > TP_BSIZE && 8918493Smckusick setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 9018493Smckusick size -= TP_BSIZE; 916645Ssam } 926645Ssam 9346587Storek int 946645Ssam rmtopen(tape, mode) 956645Ssam char *tape; 966645Ssam int mode; 976645Ssam { 986645Ssam char buf[256]; 996645Ssam 10032455Sbostic (void)sprintf(buf, "O%s\n%d\n", tape, mode); 1016645Ssam rmtstate = TS_OPEN; 10224836Smckusick return (rmtcall(tape, buf)); 1036645Ssam } 1046645Ssam 10546587Storek void 1066645Ssam rmtclose() 1076645Ssam { 1086645Ssam 1096645Ssam if (rmtstate != TS_OPEN) 1106645Ssam return; 1116645Ssam rmtcall("close", "C\n"); 1126645Ssam rmtstate = TS_CLOSED; 1136645Ssam } 1146645Ssam 11546587Storek int 1166645Ssam rmtread(buf, count) 1176645Ssam char *buf; 1186645Ssam int count; 1196645Ssam { 1206645Ssam char line[30]; 1216645Ssam int n, i, cc; 1226884Ssam extern errno; 1236645Ssam 12432455Sbostic (void)sprintf(line, "R%d\n", count); 1256645Ssam n = rmtcall("read", line); 1266884Ssam if (n < 0) { 1276884Ssam errno = n; 1286645Ssam return (-1); 1296884Ssam } 1306645Ssam for (i = 0; i < n; i += cc) { 1316645Ssam cc = read(rmtape, buf+i, n - i); 1326884Ssam if (cc <= 0) { 1336645Ssam rmtconnaborted(); 1346884Ssam } 1356645Ssam } 1366645Ssam return (n); 1376645Ssam } 1386645Ssam 13946587Storek int 1406645Ssam rmtwrite(buf, count) 1416645Ssam char *buf; 1426645Ssam int count; 1436645Ssam { 1446645Ssam char line[30]; 1456645Ssam 14632455Sbostic (void)sprintf(line, "W%d\n", count); 1476645Ssam write(rmtape, line, strlen(line)); 1486645Ssam write(rmtape, buf, count); 1496645Ssam return (rmtreply("write")); 1506645Ssam } 1516645Ssam 15246587Storek void 1536645Ssam rmtwrite0(count) 1546645Ssam int count; 1556645Ssam { 1566645Ssam char line[30]; 1576645Ssam 15832455Sbostic (void)sprintf(line, "W%d\n", count); 1596645Ssam write(rmtape, line, strlen(line)); 1606645Ssam } 1616645Ssam 16246587Storek void 1636645Ssam rmtwrite1(buf, count) 1646645Ssam char *buf; 1656645Ssam int count; 1666645Ssam { 1676645Ssam 1686645Ssam write(rmtape, buf, count); 1696645Ssam } 1706645Ssam 17146587Storek int 1726645Ssam rmtwrite2() 1736645Ssam { 1746645Ssam 1756645Ssam return (rmtreply("write")); 1766645Ssam } 1776645Ssam 17846587Storek int 1796645Ssam rmtseek(offset, pos) 1806645Ssam int offset, pos; 1816645Ssam { 1826645Ssam char line[80]; 1836645Ssam 18432455Sbostic (void)sprintf(line, "L%d\n%d\n", offset, pos); 1856645Ssam return (rmtcall("seek", line)); 1866645Ssam } 1876645Ssam 1886645Ssam struct mtget mts; 1896645Ssam 1906645Ssam struct mtget * 1916645Ssam rmtstatus() 1926645Ssam { 1936645Ssam register int i; 1946645Ssam register char *cp; 1956645Ssam 1966645Ssam if (rmtstate != TS_OPEN) 1976645Ssam return (0); 1986645Ssam rmtcall("status", "S\n"); 1996645Ssam for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++) 2006645Ssam *cp++ = rmtgetb(); 2016645Ssam return (&mts); 2026645Ssam } 2036645Ssam 20446587Storek int 2056645Ssam rmtioctl(cmd, count) 2066645Ssam int cmd, count; 2076645Ssam { 2086645Ssam char buf[256]; 2096645Ssam 2106645Ssam if (count < 0) 2116645Ssam return (-1); 21232455Sbostic (void)sprintf(buf, "I%d\n%d\n", cmd, count); 21313545Ssam return (rmtcall("ioctl", buf)); 2146645Ssam } 2156645Ssam 21646587Storek int 2176645Ssam rmtcall(cmd, buf) 2186645Ssam char *cmd, *buf; 2196645Ssam { 2206645Ssam 2216645Ssam if (write(rmtape, buf, strlen(buf)) != strlen(buf)) 2226645Ssam rmtconnaborted(); 2236645Ssam return (rmtreply(cmd)); 2246645Ssam } 2256645Ssam 22646587Storek int 2276645Ssam rmtreply(cmd) 2286645Ssam char *cmd; 2296645Ssam { 2306645Ssam char code[30], emsg[BUFSIZ]; 2316645Ssam 2326645Ssam rmtgets(code, sizeof (code)); 2336645Ssam if (*code == 'E' || *code == 'F') { 2346645Ssam rmtgets(emsg, sizeof (emsg)); 2356645Ssam msg("%s: %s\n", cmd, emsg, code + 1); 2366645Ssam if (*code == 'F') { 2376645Ssam rmtstate = TS_CLOSED; 2386645Ssam return (-1); 2396645Ssam } 2406645Ssam return (-1); 2416645Ssam } 2426645Ssam if (*code != 'A') { 2436645Ssam msg("Protocol to remote tape server botched (code %s?).\n", 2446645Ssam code); 2456645Ssam rmtconnaborted(); 2466645Ssam } 2476645Ssam return (atoi(code + 1)); 2486645Ssam } 2496645Ssam 25046587Storek int 2516645Ssam rmtgetb() 2526645Ssam { 2536645Ssam char c; 2546645Ssam 2556645Ssam if (read(rmtape, &c, 1) != 1) 2566645Ssam rmtconnaborted(); 2576645Ssam return (c); 2586645Ssam } 2596645Ssam 26046587Storek void 2616645Ssam rmtgets(cp, len) 2626645Ssam char *cp; 2636645Ssam int len; 2646645Ssam { 2656645Ssam 2666645Ssam while (len > 1) { 2676645Ssam *cp = rmtgetb(); 2686645Ssam if (*cp == '\n') { 2696645Ssam cp[1] = 0; 2706645Ssam return; 2716645Ssam } 2726645Ssam cp++; 2736645Ssam len--; 2746645Ssam } 2756645Ssam msg("Protocol to remote tape server botched (in rmtgets).\n"); 2766645Ssam rmtconnaborted(); 2776645Ssam } 278