xref: /386bsd/usr/src/sbin/dump/dumprmt.c (revision a2142627)
1 /*-
2  * Copyright (c) 1980 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #ifndef lint
35 static char sccsid[] = "@(#)dumprmt.c	5.11 (Berkeley) 3/7/91";
36 #endif /* not lint */
37 
38 #include <sys/param.h>
39 #include <sys/mtio.h>
40 #include <sys/ioctl.h>
41 #include <sys/socket.h>
42 #include <ufs/dinode.h>
43 #include <signal.h>
44 
45 #include <netinet/in.h>
46 
47 #include <netdb.h>
48 #include <protocols/dumprestore.h>
49 #include <pwd.h>
50 #include <stdio.h>
51 #ifdef __STDC__
52 #include <unistd.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #endif
56 #include "pathnames.h"
57 
58 #define	TS_CLOSED	0
59 #define	TS_OPEN		1
60 
61 static	int rmtstate = TS_CLOSED;
62 int	rmtape;
63 void	rmtgetconn();
64 void	rmtconnaborted();
65 int	rmtreply();
66 int	rmtgetb();
67 void	rmtgets();
68 int	rmtcall();
69 char	*rmtpeer;
70 
71 extern int ntrec;		/* blocking factor on tape */
72 extern void msg();
73 
74 int
rmthost(host)75 rmthost(host)
76 	char *host;
77 {
78 
79 	rmtpeer = host;
80 	signal(SIGPIPE, rmtconnaborted);
81 	rmtgetconn();
82 	if (rmtape < 0)
83 		return (0);
84 	return (1);
85 }
86 
87 void
rmtconnaborted()88 rmtconnaborted()
89 {
90 
91 	fprintf(stderr, "rdump: Lost connection to remote host.\n");
92 	exit(1);
93 }
94 
95 void
rmtgetconn()96 rmtgetconn()
97 {
98 	static struct servent *sp = 0;
99 	struct passwd *pw;
100 	char *name = "root";
101 	int size;
102 
103 	if (sp == 0) {
104 		sp = getservbyname("shell", "tcp");
105 		if (sp == 0) {
106 			fprintf(stderr, "rdump: shell/tcp: unknown service\n");
107 			exit(1);
108 		}
109 	}
110 	pw = getpwuid(getuid());
111 	if (pw && pw->pw_name)
112 		name = pw->pw_name;
113 	rmtape = rcmd(&rmtpeer, sp->s_port, name, name, _PATH_RMT, 0);
114 	size = ntrec * TP_BSIZE;
115 	while (size > TP_BSIZE &&
116 	    setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0)
117 		size -= TP_BSIZE;
118 }
119 
120 int
rmtopen(tape,mode)121 rmtopen(tape, mode)
122 	char *tape;
123 	int mode;
124 {
125 	char buf[256];
126 
127 	(void)sprintf(buf, "O%s\n%d\n", tape, mode);
128 	rmtstate = TS_OPEN;
129 	return (rmtcall(tape, buf));
130 }
131 
132 void
rmtclose()133 rmtclose()
134 {
135 
136 	if (rmtstate != TS_OPEN)
137 		return;
138 	rmtcall("close", "C\n");
139 	rmtstate = TS_CLOSED;
140 }
141 
142 int
rmtread(buf,count)143 rmtread(buf, count)
144 	char *buf;
145 	int count;
146 {
147 	char line[30];
148 	int n, i, cc;
149 	extern errno;
150 
151 	(void)sprintf(line, "R%d\n", count);
152 	n = rmtcall("read", line);
153 	if (n < 0) {
154 		errno = n;
155 		return (-1);
156 	}
157 	for (i = 0; i < n; i += cc) {
158 		cc = read(rmtape, buf+i, n - i);
159 		if (cc <= 0) {
160 			rmtconnaborted();
161 		}
162 	}
163 	return (n);
164 }
165 
166 int
rmtwrite(buf,count)167 rmtwrite(buf, count)
168 	char *buf;
169 	int count;
170 {
171 	char line[30];
172 
173 	(void)sprintf(line, "W%d\n", count);
174 	write(rmtape, line, strlen(line));
175 	write(rmtape, buf, count);
176 	return (rmtreply("write"));
177 }
178 
179 void
rmtwrite0(count)180 rmtwrite0(count)
181 	int count;
182 {
183 	char line[30];
184 
185 	(void)sprintf(line, "W%d\n", count);
186 	write(rmtape, line, strlen(line));
187 }
188 
189 void
rmtwrite1(buf,count)190 rmtwrite1(buf, count)
191 	char *buf;
192 	int count;
193 {
194 
195 	write(rmtape, buf, count);
196 }
197 
198 int
rmtwrite2()199 rmtwrite2()
200 {
201 
202 	return (rmtreply("write"));
203 }
204 
205 int
rmtseek(offset,pos)206 rmtseek(offset, pos)
207 	int offset, pos;
208 {
209 	char line[80];
210 
211 	(void)sprintf(line, "L%d\n%d\n", offset, pos);
212 	return (rmtcall("seek", line));
213 }
214 
215 struct	mtget mts;
216 
217 struct mtget *
rmtstatus()218 rmtstatus()
219 {
220 	register int i;
221 	register char *cp;
222 
223 	if (rmtstate != TS_OPEN)
224 		return (0);
225 	rmtcall("status", "S\n");
226 	for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++)
227 		*cp++ = rmtgetb();
228 	return (&mts);
229 }
230 
231 int
rmtioctl(cmd,count)232 rmtioctl(cmd, count)
233 	int cmd, count;
234 {
235 	char buf[256];
236 
237 	if (count < 0)
238 		return (-1);
239 	(void)sprintf(buf, "I%d\n%d\n", cmd, count);
240 	return (rmtcall("ioctl", buf));
241 }
242 
243 int
rmtcall(cmd,buf)244 rmtcall(cmd, buf)
245 	char *cmd, *buf;
246 {
247 
248 	if (write(rmtape, buf, strlen(buf)) != strlen(buf))
249 		rmtconnaborted();
250 	return (rmtreply(cmd));
251 }
252 
253 int
rmtreply(cmd)254 rmtreply(cmd)
255 	char *cmd;
256 {
257 	char code[30], emsg[BUFSIZ];
258 
259 	rmtgets(code, sizeof (code));
260 	if (*code == 'E' || *code == 'F') {
261 		rmtgets(emsg, sizeof (emsg));
262 		msg("%s: %s\n", cmd, emsg, code + 1);
263 		if (*code == 'F') {
264 			rmtstate = TS_CLOSED;
265 			return (-1);
266 		}
267 		return (-1);
268 	}
269 	if (*code != 'A') {
270 		msg("Protocol to remote tape server botched (code %s?).\n",
271 		    code);
272 		rmtconnaborted();
273 	}
274 	return (atoi(code + 1));
275 }
276 
277 int
rmtgetb()278 rmtgetb()
279 {
280 	char c;
281 
282 	if (read(rmtape, &c, 1) != 1)
283 		rmtconnaborted();
284 	return (c);
285 }
286 
287 void
rmtgets(cp,len)288 rmtgets(cp, len)
289 	char *cp;
290 	int len;
291 {
292 
293 	while (len > 1) {
294 		*cp = rmtgetb();
295 		if (*cp == '\n') {
296 			cp[1] = 0;
297 			return;
298 		}
299 		cp++;
300 		len--;
301 	}
302 	msg("Protocol to remote tape server botched (in rmtgets).\n");
303 	rmtconnaborted();
304 }
305