147082Smckusick /*- 247082Smckusick * Copyright (c) 1980 The Regents of the University of California. 347082Smckusick * All rights reserved. 447082Smckusick * 547082Smckusick * %sccs.include.redist.c% 622039Sdist */ 76645Ssam 822039Sdist #ifndef lint 9*50498Smckusick static char sccsid[] = "@(#)dumprmt.c 5.12 (Berkeley) 07/23/91"; 1046587Storek #endif /* not lint */ 1122039Sdist 12*50498Smckusick #ifdef sunos 13*50498Smckusick #include <stdio.h> 14*50498Smckusick #include <ctype.h> 156884Ssam #include <sys/param.h> 166645Ssam #include <sys/mtio.h> 176645Ssam #include <sys/ioctl.h> 1817538Sralph #include <sys/socket.h> 19*50498Smckusick #include <sys/stat.h> 20*50498Smckusick #include <sys/time.h> 21*50498Smckusick #include <sys/dir.h> 22*50498Smckusick #include <sys/vnode.h> 23*50498Smckusick #include <ufs/inode.h> 24*50498Smckusick #else 25*50498Smckusick #include <sys/param.h> 26*50498Smckusick #include <sys/mtio.h> 27*50498Smckusick #include <sys/ioctl.h> 28*50498Smckusick #include <sys/socket.h> 2940098Smckusick #include <ufs/dinode.h> 30*50498Smckusick #include <stdio.h> 31*50498Smckusick #endif 3246795Sbostic #include <signal.h> 336645Ssam 349306Ssam #include <netinet/in.h> 359306Ssam 369306Ssam #include <netdb.h> 3723544Smckusick #include <protocols/dumprestore.h> 3837946Sbostic #include <pwd.h> 3946795Sbostic #ifdef __STDC__ 4046795Sbostic #include <unistd.h> 4146587Storek #include <stdlib.h> 4246587Storek #include <string.h> 4346795Sbostic #endif 4437946Sbostic #include "pathnames.h" 459306Ssam 466645Ssam #define TS_CLOSED 0 476645Ssam #define TS_OPEN 1 486645Ssam 496645Ssam static int rmtstate = TS_CLOSED; 506645Ssam int rmtape; 5146587Storek void rmtgetconn(); 5246587Storek void rmtconnaborted(); 5346587Storek int rmtreply(); 5446587Storek int rmtgetb(); 5546587Storek void rmtgets(); 5646587Storek int rmtcall(); 576645Ssam char *rmtpeer; 586645Ssam 5917538Sralph extern int ntrec; /* blocking factor on tape */ 6046587Storek extern void msg(); 6117538Sralph 6246587Storek int 636645Ssam rmthost(host) 646645Ssam char *host; 656645Ssam { 666645Ssam 676645Ssam rmtpeer = host; 6813032Ssam signal(SIGPIPE, rmtconnaborted); 696645Ssam rmtgetconn(); 706645Ssam if (rmtape < 0) 7117538Sralph return (0); 7217538Sralph return (1); 736645Ssam } 746645Ssam 7546587Storek void 766645Ssam rmtconnaborted() 776645Ssam { 786645Ssam 7917538Sralph fprintf(stderr, "rdump: Lost connection to remote host.\n"); 806884Ssam exit(1); 816645Ssam } 826645Ssam 8346587Storek void 846645Ssam rmtgetconn() 856645Ssam { 869306Ssam static struct servent *sp = 0; 8716376Skarels struct passwd *pw; 8816376Skarels char *name = "root"; 8917538Sralph int size; 906645Ssam 919306Ssam if (sp == 0) { 929306Ssam sp = getservbyname("shell", "tcp"); 939306Ssam if (sp == 0) { 949306Ssam fprintf(stderr, "rdump: shell/tcp: unknown service\n"); 959306Ssam exit(1); 969306Ssam } 979306Ssam } 9816376Skarels pw = getpwuid(getuid()); 9916376Skarels if (pw && pw->pw_name) 10016376Skarels name = pw->pw_name; 10137946Sbostic rmtape = rcmd(&rmtpeer, sp->s_port, name, name, _PATH_RMT, 0); 10217538Sralph size = ntrec * TP_BSIZE; 10318493Smckusick while (size > TP_BSIZE && 10418493Smckusick setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 10518493Smckusick size -= TP_BSIZE; 1066645Ssam } 1076645Ssam 10846587Storek int 1096645Ssam rmtopen(tape, mode) 1106645Ssam char *tape; 1116645Ssam int mode; 1126645Ssam { 1136645Ssam char buf[256]; 1146645Ssam 11532455Sbostic (void)sprintf(buf, "O%s\n%d\n", tape, mode); 1166645Ssam rmtstate = TS_OPEN; 11724836Smckusick return (rmtcall(tape, buf)); 1186645Ssam } 1196645Ssam 12046587Storek void 1216645Ssam rmtclose() 1226645Ssam { 1236645Ssam 1246645Ssam if (rmtstate != TS_OPEN) 1256645Ssam return; 1266645Ssam rmtcall("close", "C\n"); 1276645Ssam rmtstate = TS_CLOSED; 1286645Ssam } 1296645Ssam 13046587Storek int 1316645Ssam rmtread(buf, count) 1326645Ssam char *buf; 1336645Ssam int count; 1346645Ssam { 1356645Ssam char line[30]; 1366645Ssam int n, i, cc; 1376884Ssam extern errno; 1386645Ssam 13932455Sbostic (void)sprintf(line, "R%d\n", count); 1406645Ssam n = rmtcall("read", line); 1416884Ssam if (n < 0) { 1426884Ssam errno = n; 1436645Ssam return (-1); 1446884Ssam } 1456645Ssam for (i = 0; i < n; i += cc) { 1466645Ssam cc = read(rmtape, buf+i, n - i); 1476884Ssam if (cc <= 0) { 1486645Ssam rmtconnaborted(); 1496884Ssam } 1506645Ssam } 1516645Ssam return (n); 1526645Ssam } 1536645Ssam 15446587Storek int 1556645Ssam rmtwrite(buf, count) 1566645Ssam char *buf; 1576645Ssam int count; 1586645Ssam { 1596645Ssam char line[30]; 1606645Ssam 16132455Sbostic (void)sprintf(line, "W%d\n", count); 1626645Ssam write(rmtape, line, strlen(line)); 1636645Ssam write(rmtape, buf, count); 1646645Ssam return (rmtreply("write")); 1656645Ssam } 1666645Ssam 16746587Storek void 1686645Ssam rmtwrite0(count) 1696645Ssam int count; 1706645Ssam { 1716645Ssam char line[30]; 1726645Ssam 17332455Sbostic (void)sprintf(line, "W%d\n", count); 1746645Ssam write(rmtape, line, strlen(line)); 1756645Ssam } 1766645Ssam 17746587Storek void 1786645Ssam rmtwrite1(buf, count) 1796645Ssam char *buf; 1806645Ssam int count; 1816645Ssam { 1826645Ssam 1836645Ssam write(rmtape, buf, count); 1846645Ssam } 1856645Ssam 18646587Storek int 1876645Ssam rmtwrite2() 1886645Ssam { 1896645Ssam 1906645Ssam return (rmtreply("write")); 1916645Ssam } 1926645Ssam 19346587Storek int 1946645Ssam rmtseek(offset, pos) 1956645Ssam int offset, pos; 1966645Ssam { 1976645Ssam char line[80]; 1986645Ssam 19932455Sbostic (void)sprintf(line, "L%d\n%d\n", offset, pos); 2006645Ssam return (rmtcall("seek", line)); 2016645Ssam } 2026645Ssam 2036645Ssam struct mtget mts; 2046645Ssam 2056645Ssam struct mtget * 2066645Ssam rmtstatus() 2076645Ssam { 2086645Ssam register int i; 2096645Ssam register char *cp; 2106645Ssam 2116645Ssam if (rmtstate != TS_OPEN) 2126645Ssam return (0); 2136645Ssam rmtcall("status", "S\n"); 2146645Ssam for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++) 2156645Ssam *cp++ = rmtgetb(); 2166645Ssam return (&mts); 2176645Ssam } 2186645Ssam 21946587Storek int 2206645Ssam rmtioctl(cmd, count) 2216645Ssam int cmd, count; 2226645Ssam { 2236645Ssam char buf[256]; 2246645Ssam 2256645Ssam if (count < 0) 2266645Ssam return (-1); 22732455Sbostic (void)sprintf(buf, "I%d\n%d\n", cmd, count); 22813545Ssam return (rmtcall("ioctl", buf)); 2296645Ssam } 2306645Ssam 23146587Storek int 2326645Ssam rmtcall(cmd, buf) 2336645Ssam char *cmd, *buf; 2346645Ssam { 2356645Ssam 2366645Ssam if (write(rmtape, buf, strlen(buf)) != strlen(buf)) 2376645Ssam rmtconnaborted(); 2386645Ssam return (rmtreply(cmd)); 2396645Ssam } 2406645Ssam 24146587Storek int 2426645Ssam rmtreply(cmd) 2436645Ssam char *cmd; 2446645Ssam { 2456645Ssam char code[30], emsg[BUFSIZ]; 2466645Ssam 2476645Ssam rmtgets(code, sizeof (code)); 2486645Ssam if (*code == 'E' || *code == 'F') { 2496645Ssam rmtgets(emsg, sizeof (emsg)); 2506645Ssam msg("%s: %s\n", cmd, emsg, code + 1); 2516645Ssam if (*code == 'F') { 2526645Ssam rmtstate = TS_CLOSED; 2536645Ssam return (-1); 2546645Ssam } 2556645Ssam return (-1); 2566645Ssam } 2576645Ssam if (*code != 'A') { 2586645Ssam msg("Protocol to remote tape server botched (code %s?).\n", 2596645Ssam code); 2606645Ssam rmtconnaborted(); 2616645Ssam } 2626645Ssam return (atoi(code + 1)); 2636645Ssam } 2646645Ssam 26546587Storek int 2666645Ssam rmtgetb() 2676645Ssam { 2686645Ssam char c; 2696645Ssam 2706645Ssam if (read(rmtape, &c, 1) != 1) 2716645Ssam rmtconnaborted(); 2726645Ssam return (c); 2736645Ssam } 2746645Ssam 27546587Storek void 2766645Ssam rmtgets(cp, len) 2776645Ssam char *cp; 2786645Ssam int len; 2796645Ssam { 2806645Ssam 2816645Ssam while (len > 1) { 2826645Ssam *cp = rmtgetb(); 2836645Ssam if (*cp == '\n') { 2846645Ssam cp[1] = 0; 2856645Ssam return; 2866645Ssam } 2876645Ssam cp++; 2886645Ssam len--; 2896645Ssam } 2906645Ssam msg("Protocol to remote tape server botched (in rmtgets).\n"); 2916645Ssam rmtconnaborted(); 2926645Ssam } 293