xref: /original-bsd/sbin/dump/dumprmt.c (revision 4c3b28fe)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 static char sccsid[] = "@(#)dumprmt.c	5.8 (Berkeley) 02/15/90";
9 #endif not lint
10 
11 #include <sys/param.h>
12 #include <sys/mtio.h>
13 #include <sys/ioctl.h>
14 #include <sys/socket.h>
15 #include <ufs/dinode.h>
16 
17 #include <netinet/in.h>
18 
19 #include <netdb.h>
20 #include <protocols/dumprestore.h>
21 #include <pwd.h>
22 #include <stdio.h>
23 #include "pathnames.h"
24 
25 #define	TS_CLOSED	0
26 #define	TS_OPEN		1
27 
28 static	int rmtstate = TS_CLOSED;
29 int	rmtape;
30 int	rmtconnaborted();
31 char	*rmtpeer;
32 
33 extern int ntrec;		/* blocking factor on tape */
34 
35 rmthost(host)
36 	char *host;
37 {
38 
39 	rmtpeer = host;
40 	signal(SIGPIPE, rmtconnaborted);
41 	rmtgetconn();
42 	if (rmtape < 0)
43 		return (0);
44 	return (1);
45 }
46 
47 rmtconnaborted()
48 {
49 
50 	fprintf(stderr, "rdump: Lost connection to remote host.\n");
51 	exit(1);
52 }
53 
54 rmtgetconn()
55 {
56 	static struct servent *sp = 0;
57 	struct passwd *pw;
58 	char *name = "root";
59 	int size;
60 
61 	if (sp == 0) {
62 		sp = getservbyname("shell", "tcp");
63 		if (sp == 0) {
64 			fprintf(stderr, "rdump: shell/tcp: unknown service\n");
65 			exit(1);
66 		}
67 	}
68 	pw = getpwuid(getuid());
69 	if (pw && pw->pw_name)
70 		name = pw->pw_name;
71 	rmtape = rcmd(&rmtpeer, sp->s_port, name, name, _PATH_RMT, 0);
72 	size = ntrec * TP_BSIZE;
73 	while (size > TP_BSIZE &&
74 	    setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0)
75 		size -= TP_BSIZE;
76 }
77 
78 rmtopen(tape, mode)
79 	char *tape;
80 	int mode;
81 {
82 	char buf[256];
83 
84 	(void)sprintf(buf, "O%s\n%d\n", tape, mode);
85 	rmtstate = TS_OPEN;
86 	return (rmtcall(tape, buf));
87 }
88 
89 rmtclose()
90 {
91 
92 	if (rmtstate != TS_OPEN)
93 		return;
94 	rmtcall("close", "C\n");
95 	rmtstate = TS_CLOSED;
96 }
97 
98 rmtread(buf, count)
99 	char *buf;
100 	int count;
101 {
102 	char line[30];
103 	int n, i, cc;
104 	extern errno;
105 
106 	(void)sprintf(line, "R%d\n", count);
107 	n = rmtcall("read", line);
108 	if (n < 0) {
109 		errno = n;
110 		return (-1);
111 	}
112 	for (i = 0; i < n; i += cc) {
113 		cc = read(rmtape, buf+i, n - i);
114 		if (cc <= 0) {
115 			rmtconnaborted();
116 		}
117 	}
118 	return (n);
119 }
120 
121 rmtwrite(buf, count)
122 	char *buf;
123 	int count;
124 {
125 	char line[30];
126 
127 	(void)sprintf(line, "W%d\n", count);
128 	write(rmtape, line, strlen(line));
129 	write(rmtape, buf, count);
130 	return (rmtreply("write"));
131 }
132 
133 rmtwrite0(count)
134 	int count;
135 {
136 	char line[30];
137 
138 	(void)sprintf(line, "W%d\n", count);
139 	write(rmtape, line, strlen(line));
140 }
141 
142 rmtwrite1(buf, count)
143 	char *buf;
144 	int count;
145 {
146 
147 	write(rmtape, buf, count);
148 }
149 
150 rmtwrite2()
151 {
152 	int i;
153 
154 	return (rmtreply("write"));
155 }
156 
157 rmtseek(offset, pos)
158 	int offset, pos;
159 {
160 	char line[80];
161 
162 	(void)sprintf(line, "L%d\n%d\n", offset, pos);
163 	return (rmtcall("seek", line));
164 }
165 
166 struct	mtget mts;
167 
168 struct mtget *
169 rmtstatus()
170 {
171 	register int i;
172 	register char *cp;
173 
174 	if (rmtstate != TS_OPEN)
175 		return (0);
176 	rmtcall("status", "S\n");
177 	for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++)
178 		*cp++ = rmtgetb();
179 	return (&mts);
180 }
181 
182 rmtioctl(cmd, count)
183 	int cmd, count;
184 {
185 	char buf[256];
186 
187 	if (count < 0)
188 		return (-1);
189 	(void)sprintf(buf, "I%d\n%d\n", cmd, count);
190 	return (rmtcall("ioctl", buf));
191 }
192 
193 rmtcall(cmd, buf)
194 	char *cmd, *buf;
195 {
196 
197 	if (write(rmtape, buf, strlen(buf)) != strlen(buf))
198 		rmtconnaborted();
199 	return (rmtreply(cmd));
200 }
201 
202 rmtreply(cmd)
203 	char *cmd;
204 {
205 	register int c;
206 	char code[30], emsg[BUFSIZ];
207 
208 	rmtgets(code, sizeof (code));
209 	if (*code == 'E' || *code == 'F') {
210 		rmtgets(emsg, sizeof (emsg));
211 		msg("%s: %s\n", cmd, emsg, code + 1);
212 		if (*code == 'F') {
213 			rmtstate = TS_CLOSED;
214 			return (-1);
215 		}
216 		return (-1);
217 	}
218 	if (*code != 'A') {
219 		msg("Protocol to remote tape server botched (code %s?).\n",
220 		    code);
221 		rmtconnaborted();
222 	}
223 	return (atoi(code + 1));
224 }
225 
226 rmtgetb()
227 {
228 	char c;
229 
230 	if (read(rmtape, &c, 1) != 1)
231 		rmtconnaborted();
232 	return (c);
233 }
234 
235 rmtgets(cp, len)
236 	char *cp;
237 	int len;
238 {
239 
240 	while (len > 1) {
241 		*cp = rmtgetb();
242 		if (*cp == '\n') {
243 			cp[1] = 0;
244 			return;
245 		}
246 		cp++;
247 		len--;
248 	}
249 	msg("Protocol to remote tape server botched (in rmtgets).\n");
250 	rmtconnaborted();
251 }
252