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