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