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