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