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