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