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