xref: /csrg-svn/sbin/dump/dumprmt.c (revision 47082)
1*47082Smckusick /*-
2*47082Smckusick  * Copyright (c) 1980 The Regents of the University of California.
3*47082Smckusick  * All rights reserved.
4*47082Smckusick  *
5*47082Smckusick  * %sccs.include.redist.c%
622039Sdist  */
76645Ssam 
822039Sdist #ifndef lint
9*47082Smckusick static char sccsid[] = "@(#)dumprmt.c	5.11 (Berkeley) 03/07/91";
1046587Storek #endif /* not lint */
1122039Sdist 
126884Ssam #include <sys/param.h>
136645Ssam #include <sys/mtio.h>
146645Ssam #include <sys/ioctl.h>
1517538Sralph #include <sys/socket.h>
1640098Smckusick #include <ufs/dinode.h>
1746795Sbostic #include <signal.h>
186645Ssam 
199306Ssam #include <netinet/in.h>
209306Ssam 
219306Ssam #include <netdb.h>
2223544Smckusick #include <protocols/dumprestore.h>
2337946Sbostic #include <pwd.h>
2437946Sbostic #include <stdio.h>
2546795Sbostic #ifdef __STDC__
2646795Sbostic #include <unistd.h>
2746587Storek #include <stdlib.h>
2846587Storek #include <string.h>
2946795Sbostic #endif
3037946Sbostic #include "pathnames.h"
319306Ssam 
326645Ssam #define	TS_CLOSED	0
336645Ssam #define	TS_OPEN		1
346645Ssam 
356645Ssam static	int rmtstate = TS_CLOSED;
366645Ssam int	rmtape;
3746587Storek void	rmtgetconn();
3846587Storek void	rmtconnaborted();
3946587Storek int	rmtreply();
4046587Storek int	rmtgetb();
4146587Storek void	rmtgets();
4246587Storek int	rmtcall();
436645Ssam char	*rmtpeer;
446645Ssam 
4517538Sralph extern int ntrec;		/* blocking factor on tape */
4646587Storek extern void msg();
4717538Sralph 
4846587Storek int
496645Ssam rmthost(host)
506645Ssam 	char *host;
516645Ssam {
526645Ssam 
536645Ssam 	rmtpeer = host;
5413032Ssam 	signal(SIGPIPE, rmtconnaborted);
556645Ssam 	rmtgetconn();
566645Ssam 	if (rmtape < 0)
5717538Sralph 		return (0);
5817538Sralph 	return (1);
596645Ssam }
606645Ssam 
6146587Storek void
626645Ssam rmtconnaborted()
636645Ssam {
646645Ssam 
6517538Sralph 	fprintf(stderr, "rdump: Lost connection to remote host.\n");
666884Ssam 	exit(1);
676645Ssam }
686645Ssam 
6946587Storek void
706645Ssam rmtgetconn()
716645Ssam {
729306Ssam 	static struct servent *sp = 0;
7316376Skarels 	struct passwd *pw;
7416376Skarels 	char *name = "root";
7517538Sralph 	int size;
766645Ssam 
779306Ssam 	if (sp == 0) {
789306Ssam 		sp = getservbyname("shell", "tcp");
799306Ssam 		if (sp == 0) {
809306Ssam 			fprintf(stderr, "rdump: shell/tcp: unknown service\n");
819306Ssam 			exit(1);
829306Ssam 		}
839306Ssam 	}
8416376Skarels 	pw = getpwuid(getuid());
8516376Skarels 	if (pw && pw->pw_name)
8616376Skarels 		name = pw->pw_name;
8737946Sbostic 	rmtape = rcmd(&rmtpeer, sp->s_port, name, name, _PATH_RMT, 0);
8817538Sralph 	size = ntrec * TP_BSIZE;
8918493Smckusick 	while (size > TP_BSIZE &&
9018493Smckusick 	    setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0)
9118493Smckusick 		size -= TP_BSIZE;
926645Ssam }
936645Ssam 
9446587Storek int
956645Ssam rmtopen(tape, mode)
966645Ssam 	char *tape;
976645Ssam 	int mode;
986645Ssam {
996645Ssam 	char buf[256];
1006645Ssam 
10132455Sbostic 	(void)sprintf(buf, "O%s\n%d\n", tape, mode);
1026645Ssam 	rmtstate = TS_OPEN;
10324836Smckusick 	return (rmtcall(tape, buf));
1046645Ssam }
1056645Ssam 
10646587Storek void
1076645Ssam rmtclose()
1086645Ssam {
1096645Ssam 
1106645Ssam 	if (rmtstate != TS_OPEN)
1116645Ssam 		return;
1126645Ssam 	rmtcall("close", "C\n");
1136645Ssam 	rmtstate = TS_CLOSED;
1146645Ssam }
1156645Ssam 
11646587Storek int
1176645Ssam rmtread(buf, count)
1186645Ssam 	char *buf;
1196645Ssam 	int count;
1206645Ssam {
1216645Ssam 	char line[30];
1226645Ssam 	int n, i, cc;
1236884Ssam 	extern errno;
1246645Ssam 
12532455Sbostic 	(void)sprintf(line, "R%d\n", count);
1266645Ssam 	n = rmtcall("read", line);
1276884Ssam 	if (n < 0) {
1286884Ssam 		errno = n;
1296645Ssam 		return (-1);
1306884Ssam 	}
1316645Ssam 	for (i = 0; i < n; i += cc) {
1326645Ssam 		cc = read(rmtape, buf+i, n - i);
1336884Ssam 		if (cc <= 0) {
1346645Ssam 			rmtconnaborted();
1356884Ssam 		}
1366645Ssam 	}
1376645Ssam 	return (n);
1386645Ssam }
1396645Ssam 
14046587Storek int
1416645Ssam rmtwrite(buf, count)
1426645Ssam 	char *buf;
1436645Ssam 	int count;
1446645Ssam {
1456645Ssam 	char line[30];
1466645Ssam 
14732455Sbostic 	(void)sprintf(line, "W%d\n", count);
1486645Ssam 	write(rmtape, line, strlen(line));
1496645Ssam 	write(rmtape, buf, count);
1506645Ssam 	return (rmtreply("write"));
1516645Ssam }
1526645Ssam 
15346587Storek void
1546645Ssam rmtwrite0(count)
1556645Ssam 	int count;
1566645Ssam {
1576645Ssam 	char line[30];
1586645Ssam 
15932455Sbostic 	(void)sprintf(line, "W%d\n", count);
1606645Ssam 	write(rmtape, line, strlen(line));
1616645Ssam }
1626645Ssam 
16346587Storek void
1646645Ssam rmtwrite1(buf, count)
1656645Ssam 	char *buf;
1666645Ssam 	int count;
1676645Ssam {
1686645Ssam 
1696645Ssam 	write(rmtape, buf, count);
1706645Ssam }
1716645Ssam 
17246587Storek int
1736645Ssam rmtwrite2()
1746645Ssam {
1756645Ssam 
1766645Ssam 	return (rmtreply("write"));
1776645Ssam }
1786645Ssam 
17946587Storek int
1806645Ssam rmtseek(offset, pos)
1816645Ssam 	int offset, pos;
1826645Ssam {
1836645Ssam 	char line[80];
1846645Ssam 
18532455Sbostic 	(void)sprintf(line, "L%d\n%d\n", offset, pos);
1866645Ssam 	return (rmtcall("seek", line));
1876645Ssam }
1886645Ssam 
1896645Ssam struct	mtget mts;
1906645Ssam 
1916645Ssam struct mtget *
1926645Ssam rmtstatus()
1936645Ssam {
1946645Ssam 	register int i;
1956645Ssam 	register char *cp;
1966645Ssam 
1976645Ssam 	if (rmtstate != TS_OPEN)
1986645Ssam 		return (0);
1996645Ssam 	rmtcall("status", "S\n");
2006645Ssam 	for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++)
2016645Ssam 		*cp++ = rmtgetb();
2026645Ssam 	return (&mts);
2036645Ssam }
2046645Ssam 
20546587Storek int
2066645Ssam rmtioctl(cmd, count)
2076645Ssam 	int cmd, count;
2086645Ssam {
2096645Ssam 	char buf[256];
2106645Ssam 
2116645Ssam 	if (count < 0)
2126645Ssam 		return (-1);
21332455Sbostic 	(void)sprintf(buf, "I%d\n%d\n", cmd, count);
21413545Ssam 	return (rmtcall("ioctl", buf));
2156645Ssam }
2166645Ssam 
21746587Storek int
2186645Ssam rmtcall(cmd, buf)
2196645Ssam 	char *cmd, *buf;
2206645Ssam {
2216645Ssam 
2226645Ssam 	if (write(rmtape, buf, strlen(buf)) != strlen(buf))
2236645Ssam 		rmtconnaborted();
2246645Ssam 	return (rmtreply(cmd));
2256645Ssam }
2266645Ssam 
22746587Storek int
2286645Ssam rmtreply(cmd)
2296645Ssam 	char *cmd;
2306645Ssam {
2316645Ssam 	char code[30], emsg[BUFSIZ];
2326645Ssam 
2336645Ssam 	rmtgets(code, sizeof (code));
2346645Ssam 	if (*code == 'E' || *code == 'F') {
2356645Ssam 		rmtgets(emsg, sizeof (emsg));
2366645Ssam 		msg("%s: %s\n", cmd, emsg, code + 1);
2376645Ssam 		if (*code == 'F') {
2386645Ssam 			rmtstate = TS_CLOSED;
2396645Ssam 			return (-1);
2406645Ssam 		}
2416645Ssam 		return (-1);
2426645Ssam 	}
2436645Ssam 	if (*code != 'A') {
2446645Ssam 		msg("Protocol to remote tape server botched (code %s?).\n",
2456645Ssam 		    code);
2466645Ssam 		rmtconnaborted();
2476645Ssam 	}
2486645Ssam 	return (atoi(code + 1));
2496645Ssam }
2506645Ssam 
25146587Storek int
2526645Ssam rmtgetb()
2536645Ssam {
2546645Ssam 	char c;
2556645Ssam 
2566645Ssam 	if (read(rmtape, &c, 1) != 1)
2576645Ssam 		rmtconnaborted();
2586645Ssam 	return (c);
2596645Ssam }
2606645Ssam 
26146587Storek void
2626645Ssam rmtgets(cp, len)
2636645Ssam 	char *cp;
2646645Ssam 	int len;
2656645Ssam {
2666645Ssam 
2676645Ssam 	while (len > 1) {
2686645Ssam 		*cp = rmtgetb();
2696645Ssam 		if (*cp == '\n') {
2706645Ssam 			cp[1] = 0;
2716645Ssam 			return;
2726645Ssam 		}
2736645Ssam 		cp++;
2746645Ssam 		len--;
2756645Ssam 	}
2766645Ssam 	msg("Protocol to remote tape server botched (in rmtgets).\n");
2776645Ssam 	rmtconnaborted();
2786645Ssam }
279