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*54044Smckusick static char sccsid[] = "@(#)dumprmt.c 5.15 (Berkeley) 06/18/92"; 1046587Storek #endif /* not lint */ 1122039Sdist 1250498Smckusick #ifdef sunos 1350498Smckusick #include <stdio.h> 1450498Smckusick #include <ctype.h> 156884Ssam #include <sys/param.h> 166645Ssam #include <sys/mtio.h> 176645Ssam #include <sys/ioctl.h> 1817538Sralph #include <sys/socket.h> 1950498Smckusick #include <sys/stat.h> 2050498Smckusick #else 2150498Smckusick #include <sys/param.h> 2250498Smckusick #include <sys/mtio.h> 2350498Smckusick #include <sys/ioctl.h> 2450498Smckusick #include <sys/socket.h> 2553615Smckusick #include <sys/time.h> 2650498Smckusick #include <stdio.h> 2750498Smckusick #endif 28*54044Smckusick #include <ufs/ufs/dinode.h> 2946795Sbostic #include <signal.h> 306645Ssam 319306Ssam #include <netinet/in.h> 329306Ssam 339306Ssam #include <netdb.h> 3423544Smckusick #include <protocols/dumprestore.h> 3537946Sbostic #include <pwd.h> 3646795Sbostic #ifdef __STDC__ 3746795Sbostic #include <unistd.h> 3846587Storek #include <stdlib.h> 3946587Storek #include <string.h> 4046795Sbostic #endif 4137946Sbostic #include "pathnames.h" 429306Ssam 436645Ssam #define TS_CLOSED 0 446645Ssam #define TS_OPEN 1 456645Ssam 466645Ssam static int rmtstate = TS_CLOSED; 476645Ssam int rmtape; 4846587Storek void rmtgetconn(); 4946587Storek void rmtconnaborted(); 5046587Storek int rmtreply(); 5146587Storek int rmtgetb(); 5246587Storek void rmtgets(); 5346587Storek int rmtcall(); 546645Ssam char *rmtpeer; 556645Ssam 5617538Sralph extern int ntrec; /* blocking factor on tape */ 5746587Storek extern void msg(); 5817538Sralph 59*54044Smckusick extern void exit(); 60*54044Smckusick 6146587Storek int 626645Ssam rmthost(host) 636645Ssam char *host; 646645Ssam { 656645Ssam 666645Ssam rmtpeer = host; 6713032Ssam signal(SIGPIPE, rmtconnaborted); 686645Ssam rmtgetconn(); 696645Ssam if (rmtape < 0) 7017538Sralph return (0); 7117538Sralph return (1); 726645Ssam } 736645Ssam 7446587Storek void 756645Ssam rmtconnaborted() 766645Ssam { 776645Ssam 78*54044Smckusick (void) fprintf(stderr, "rdump: Lost connection to remote host.\n"); 79*54044Smckusick (void) exit(1); 806645Ssam } 816645Ssam 8246587Storek void 836645Ssam rmtgetconn() 846645Ssam { 859306Ssam static struct servent *sp = 0; 8616376Skarels struct passwd *pw; 8716376Skarels char *name = "root"; 8817538Sralph int size; 896645Ssam 909306Ssam if (sp == 0) { 919306Ssam sp = getservbyname("shell", "tcp"); 929306Ssam if (sp == 0) { 93*54044Smckusick (void) fprintf(stderr, 94*54044Smckusick "rdump: shell/tcp: unknown service\n"); 95*54044Smckusick (void) exit(1); 969306Ssam } 979306Ssam } 9816376Skarels pw = getpwuid(getuid()); 9916376Skarels if (pw && pw->pw_name) 10016376Skarels name = pw->pw_name; 101*54044Smckusick rmtape = rcmd(&rmtpeer, (u_short)sp->s_port, name, name, _PATH_RMT, 102*54044Smckusick (int *)0); 10317538Sralph size = ntrec * TP_BSIZE; 10418493Smckusick while (size > TP_BSIZE && 10518493Smckusick setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) 10618493Smckusick size -= TP_BSIZE; 1076645Ssam } 1086645Ssam 10946587Storek int 1106645Ssam rmtopen(tape, mode) 1116645Ssam char *tape; 1126645Ssam int mode; 1136645Ssam { 1146645Ssam char buf[256]; 1156645Ssam 11632455Sbostic (void)sprintf(buf, "O%s\n%d\n", tape, mode); 1176645Ssam rmtstate = TS_OPEN; 11824836Smckusick return (rmtcall(tape, buf)); 1196645Ssam } 1206645Ssam 12146587Storek void 1226645Ssam rmtclose() 1236645Ssam { 1246645Ssam 1256645Ssam if (rmtstate != TS_OPEN) 1266645Ssam return; 1276645Ssam rmtcall("close", "C\n"); 1286645Ssam rmtstate = TS_CLOSED; 1296645Ssam } 1306645Ssam 13146587Storek int 1326645Ssam rmtread(buf, count) 1336645Ssam char *buf; 1346645Ssam int count; 1356645Ssam { 1366645Ssam char line[30]; 1376645Ssam int n, i, cc; 1386884Ssam extern errno; 1396645Ssam 14032455Sbostic (void)sprintf(line, "R%d\n", count); 1416645Ssam n = rmtcall("read", line); 1426884Ssam if (n < 0) { 1436884Ssam errno = n; 1446645Ssam return (-1); 1456884Ssam } 1466645Ssam for (i = 0; i < n; i += cc) { 1476645Ssam cc = read(rmtape, buf+i, n - i); 1486884Ssam if (cc <= 0) { 1496645Ssam rmtconnaborted(); 1506884Ssam } 1516645Ssam } 1526645Ssam return (n); 1536645Ssam } 1546645Ssam 15546587Storek int 1566645Ssam rmtwrite(buf, count) 1576645Ssam char *buf; 1586645Ssam int count; 1596645Ssam { 1606645Ssam char line[30]; 1616645Ssam 16232455Sbostic (void)sprintf(line, "W%d\n", count); 1636645Ssam write(rmtape, line, strlen(line)); 1646645Ssam write(rmtape, buf, count); 1656645Ssam return (rmtreply("write")); 1666645Ssam } 1676645Ssam 16846587Storek void 1696645Ssam rmtwrite0(count) 1706645Ssam int count; 1716645Ssam { 1726645Ssam char line[30]; 1736645Ssam 17432455Sbostic (void)sprintf(line, "W%d\n", count); 1756645Ssam write(rmtape, line, strlen(line)); 1766645Ssam } 1776645Ssam 17846587Storek void 1796645Ssam rmtwrite1(buf, count) 1806645Ssam char *buf; 1816645Ssam int count; 1826645Ssam { 1836645Ssam 1846645Ssam write(rmtape, buf, count); 1856645Ssam } 1866645Ssam 18746587Storek int 1886645Ssam rmtwrite2() 1896645Ssam { 1906645Ssam 1916645Ssam return (rmtreply("write")); 1926645Ssam } 1936645Ssam 19446587Storek int 1956645Ssam rmtseek(offset, pos) 1966645Ssam int offset, pos; 1976645Ssam { 1986645Ssam char line[80]; 1996645Ssam 20032455Sbostic (void)sprintf(line, "L%d\n%d\n", offset, pos); 2016645Ssam return (rmtcall("seek", line)); 2026645Ssam } 2036645Ssam 2046645Ssam struct mtget mts; 2056645Ssam 2066645Ssam struct mtget * 2076645Ssam rmtstatus() 2086645Ssam { 2096645Ssam register int i; 2106645Ssam register char *cp; 2116645Ssam 2126645Ssam if (rmtstate != TS_OPEN) 2136645Ssam return (0); 2146645Ssam rmtcall("status", "S\n"); 2156645Ssam for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++) 2166645Ssam *cp++ = rmtgetb(); 2176645Ssam return (&mts); 2186645Ssam } 2196645Ssam 22046587Storek int 2216645Ssam rmtioctl(cmd, count) 2226645Ssam int cmd, count; 2236645Ssam { 2246645Ssam char buf[256]; 2256645Ssam 2266645Ssam if (count < 0) 2276645Ssam return (-1); 22832455Sbostic (void)sprintf(buf, "I%d\n%d\n", cmd, count); 22913545Ssam return (rmtcall("ioctl", buf)); 2306645Ssam } 2316645Ssam 23246587Storek int 2336645Ssam rmtcall(cmd, buf) 2346645Ssam char *cmd, *buf; 2356645Ssam { 2366645Ssam 2376645Ssam if (write(rmtape, buf, strlen(buf)) != strlen(buf)) 2386645Ssam rmtconnaborted(); 2396645Ssam return (rmtreply(cmd)); 2406645Ssam } 2416645Ssam 24246587Storek int 2436645Ssam rmtreply(cmd) 2446645Ssam char *cmd; 2456645Ssam { 2466645Ssam char code[30], emsg[BUFSIZ]; 2476645Ssam 2486645Ssam rmtgets(code, sizeof (code)); 2496645Ssam if (*code == 'E' || *code == 'F') { 2506645Ssam rmtgets(emsg, sizeof (emsg)); 2516645Ssam msg("%s: %s\n", cmd, emsg, code + 1); 2526645Ssam if (*code == 'F') { 2536645Ssam rmtstate = TS_CLOSED; 2546645Ssam return (-1); 2556645Ssam } 2566645Ssam return (-1); 2576645Ssam } 2586645Ssam if (*code != 'A') { 2596645Ssam msg("Protocol to remote tape server botched (code %s?).\n", 2606645Ssam code); 2616645Ssam rmtconnaborted(); 2626645Ssam } 2636645Ssam return (atoi(code + 1)); 2646645Ssam } 2656645Ssam 26646587Storek int 2676645Ssam rmtgetb() 2686645Ssam { 2696645Ssam char c; 2706645Ssam 2716645Ssam if (read(rmtape, &c, 1) != 1) 2726645Ssam rmtconnaborted(); 2736645Ssam return (c); 2746645Ssam } 2756645Ssam 27646587Storek void 2776645Ssam rmtgets(cp, len) 2786645Ssam char *cp; 2796645Ssam int len; 2806645Ssam { 2816645Ssam 2826645Ssam while (len > 1) { 2836645Ssam *cp = rmtgetb(); 2846645Ssam if (*cp == '\n') { 2856645Ssam cp[1] = 0; 2866645Ssam return; 2876645Ssam } 2886645Ssam cp++; 2896645Ssam len--; 2906645Ssam } 2916645Ssam msg("Protocol to remote tape server botched (in rmtgets).\n"); 2926645Ssam rmtconnaborted(); 2936645Ssam } 294