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