xref: /csrg-svn/sbin/dump/dumprmt.c (revision 54044)
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