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