xref: /csrg-svn/sbin/dump/dumprmt.c (revision 32455)
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*32455Sbostic static char sccsid[] = "@(#)dumprmt.c	5.5 (Berkeley) 10/22/87";
922039Sdist #endif not lint
1022039Sdist 
116884Ssam #include <sys/param.h>
126645Ssam #include <sys/mtio.h>
136645Ssam #include <sys/ioctl.h>
1417538Sralph #include <sys/socket.h>
1517538Sralph #include <sys/inode.h>
166645Ssam 
179306Ssam #include <netinet/in.h>
189306Ssam 
199306Ssam #include <stdio.h>
2016376Skarels #include <pwd.h>
219306Ssam #include <netdb.h>
2223544Smckusick #include <protocols/dumprestore.h>
239306Ssam 
246645Ssam #define	TS_CLOSED	0
256645Ssam #define	TS_OPEN		1
266645Ssam 
276645Ssam static	int rmtstate = TS_CLOSED;
286645Ssam int	rmtape;
296645Ssam int	rmtconnaborted();
306645Ssam char	*rmtpeer;
316645Ssam 
3217538Sralph extern int ntrec;		/* blocking factor on tape */
3317538Sralph 
346645Ssam rmthost(host)
356645Ssam 	char *host;
366645Ssam {
376645Ssam 
386645Ssam 	rmtpeer = host;
3913032Ssam 	signal(SIGPIPE, rmtconnaborted);
406645Ssam 	rmtgetconn();
416645Ssam 	if (rmtape < 0)
4217538Sralph 		return (0);
4317538Sralph 	return (1);
446645Ssam }
456645Ssam 
466645Ssam rmtconnaborted()
476645Ssam {
486645Ssam 
4917538Sralph 	fprintf(stderr, "rdump: Lost connection to remote host.\n");
506884Ssam 	exit(1);
516645Ssam }
526645Ssam 
536645Ssam rmtgetconn()
546645Ssam {
559306Ssam 	static struct servent *sp = 0;
5616376Skarels 	struct passwd *pw;
5716376Skarels 	char *name = "root";
5817538Sralph 	int size;
596645Ssam 
609306Ssam 	if (sp == 0) {
619306Ssam 		sp = getservbyname("shell", "tcp");
629306Ssam 		if (sp == 0) {
639306Ssam 			fprintf(stderr, "rdump: shell/tcp: unknown service\n");
649306Ssam 			exit(1);
659306Ssam 		}
669306Ssam 	}
6716376Skarels 	pw = getpwuid(getuid());
6816376Skarels 	if (pw && pw->pw_name)
6916376Skarels 		name = pw->pw_name;
7016376Skarels 	rmtape = rcmd(&rmtpeer, sp->s_port, name, name, "/etc/rmt", 0);
7117538Sralph 	size = ntrec * TP_BSIZE;
7218493Smckusick 	while (size > TP_BSIZE &&
7318493Smckusick 	    setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0)
7418493Smckusick 		size -= TP_BSIZE;
756645Ssam }
766645Ssam 
776645Ssam rmtopen(tape, mode)
786645Ssam 	char *tape;
796645Ssam 	int mode;
806645Ssam {
816645Ssam 	char buf[256];
826645Ssam 
83*32455Sbostic 	(void)sprintf(buf, "O%s\n%d\n", tape, mode);
846645Ssam 	rmtstate = TS_OPEN;
8524836Smckusick 	return (rmtcall(tape, buf));
866645Ssam }
876645Ssam 
886645Ssam rmtclose()
896645Ssam {
906645Ssam 
916645Ssam 	if (rmtstate != TS_OPEN)
926645Ssam 		return;
936645Ssam 	rmtcall("close", "C\n");
946645Ssam 	rmtstate = TS_CLOSED;
956645Ssam }
966645Ssam 
976645Ssam rmtread(buf, count)
986645Ssam 	char *buf;
996645Ssam 	int count;
1006645Ssam {
1016645Ssam 	char line[30];
1026645Ssam 	int n, i, cc;
1036884Ssam 	extern errno;
1046645Ssam 
105*32455Sbostic 	(void)sprintf(line, "R%d\n", count);
1066645Ssam 	n = rmtcall("read", line);
1076884Ssam 	if (n < 0) {
1086884Ssam 		errno = n;
1096645Ssam 		return (-1);
1106884Ssam 	}
1116645Ssam 	for (i = 0; i < n; i += cc) {
1126645Ssam 		cc = read(rmtape, buf+i, n - i);
1136884Ssam 		if (cc <= 0) {
1146645Ssam 			rmtconnaborted();
1156884Ssam 		}
1166645Ssam 	}
1176645Ssam 	return (n);
1186645Ssam }
1196645Ssam 
1206645Ssam rmtwrite(buf, count)
1216645Ssam 	char *buf;
1226645Ssam 	int count;
1236645Ssam {
1246645Ssam 	char line[30];
1256645Ssam 
126*32455Sbostic 	(void)sprintf(line, "W%d\n", count);
1276645Ssam 	write(rmtape, line, strlen(line));
1286645Ssam 	write(rmtape, buf, count);
1296645Ssam 	return (rmtreply("write"));
1306645Ssam }
1316645Ssam 
1326645Ssam rmtwrite0(count)
1336645Ssam 	int count;
1346645Ssam {
1356645Ssam 	char line[30];
1366645Ssam 
137*32455Sbostic 	(void)sprintf(line, "W%d\n", count);
1386645Ssam 	write(rmtape, line, strlen(line));
1396645Ssam }
1406645Ssam 
1416645Ssam rmtwrite1(buf, count)
1426645Ssam 	char *buf;
1436645Ssam 	int count;
1446645Ssam {
1456645Ssam 
1466645Ssam 	write(rmtape, buf, count);
1476645Ssam }
1486645Ssam 
1496645Ssam rmtwrite2()
1506645Ssam {
1516645Ssam 	int i;
1526645Ssam 
1536645Ssam 	return (rmtreply("write"));
1546645Ssam }
1556645Ssam 
1566645Ssam rmtseek(offset, pos)
1576645Ssam 	int offset, pos;
1586645Ssam {
1596645Ssam 	char line[80];
1606645Ssam 
161*32455Sbostic 	(void)sprintf(line, "L%d\n%d\n", offset, pos);
1626645Ssam 	return (rmtcall("seek", line));
1636645Ssam }
1646645Ssam 
1656645Ssam struct	mtget mts;
1666645Ssam 
1676645Ssam struct mtget *
1686645Ssam rmtstatus()
1696645Ssam {
1706645Ssam 	register int i;
1716645Ssam 	register char *cp;
1726645Ssam 
1736645Ssam 	if (rmtstate != TS_OPEN)
1746645Ssam 		return (0);
1756645Ssam 	rmtcall("status", "S\n");
1766645Ssam 	for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++)
1776645Ssam 		*cp++ = rmtgetb();
1786645Ssam 	return (&mts);
1796645Ssam }
1806645Ssam 
1816645Ssam rmtioctl(cmd, count)
1826645Ssam 	int cmd, count;
1836645Ssam {
1846645Ssam 	char buf[256];
1856645Ssam 
1866645Ssam 	if (count < 0)
1876645Ssam 		return (-1);
188*32455Sbostic 	(void)sprintf(buf, "I%d\n%d\n", cmd, count);
18913545Ssam 	return (rmtcall("ioctl", buf));
1906645Ssam }
1916645Ssam 
1926645Ssam rmtcall(cmd, buf)
1936645Ssam 	char *cmd, *buf;
1946645Ssam {
1956645Ssam 
1966645Ssam 	if (write(rmtape, buf, strlen(buf)) != strlen(buf))
1976645Ssam 		rmtconnaborted();
1986645Ssam 	return (rmtreply(cmd));
1996645Ssam }
2006645Ssam 
2016645Ssam rmtreply(cmd)
2026645Ssam 	char *cmd;
2036645Ssam {
2046645Ssam 	register int c;
2056645Ssam 	char code[30], emsg[BUFSIZ];
2066645Ssam 
2076645Ssam 	rmtgets(code, sizeof (code));
2086645Ssam 	if (*code == 'E' || *code == 'F') {
2096645Ssam 		rmtgets(emsg, sizeof (emsg));
2106645Ssam 		msg("%s: %s\n", cmd, emsg, code + 1);
2116645Ssam 		if (*code == 'F') {
2126645Ssam 			rmtstate = TS_CLOSED;
2136645Ssam 			return (-1);
2146645Ssam 		}
2156645Ssam 		return (-1);
2166645Ssam 	}
2176645Ssam 	if (*code != 'A') {
2186645Ssam 		msg("Protocol to remote tape server botched (code %s?).\n",
2196645Ssam 		    code);
2206645Ssam 		rmtconnaborted();
2216645Ssam 	}
2226645Ssam 	return (atoi(code + 1));
2236645Ssam }
2246645Ssam 
2256645Ssam rmtgetb()
2266645Ssam {
2276645Ssam 	char c;
2286645Ssam 
2296645Ssam 	if (read(rmtape, &c, 1) != 1)
2306645Ssam 		rmtconnaborted();
2316645Ssam 	return (c);
2326645Ssam }
2336645Ssam 
2346645Ssam rmtgets(cp, len)
2356645Ssam 	char *cp;
2366645Ssam 	int len;
2376645Ssam {
2386645Ssam 
2396645Ssam 	while (len > 1) {
2406645Ssam 		*cp = rmtgetb();
2416645Ssam 		if (*cp == '\n') {
2426645Ssam 			cp[1] = 0;
2436645Ssam 			return;
2446645Ssam 		}
2456645Ssam 		cp++;
2466645Ssam 		len--;
2476645Ssam 	}
2486645Ssam 	msg("Protocol to remote tape server botched (in rmtgets).\n");
2496645Ssam 	rmtconnaborted();
2506645Ssam }
251