|
|
1.1 root 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
8: static char sccsid[] = "@(#)dumprmt.c 5.8 (Berkeley) 2/15/90";
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 "pathnames.h"
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:
33: extern int ntrec; /* blocking factor on tape */
34:
35: rmthost(host)
36: char *host;
37: {
38:
39: rmtpeer = host;
40: signal(SIGPIPE, rmtconnaborted);
41: rmtgetconn();
42: if (rmtape < 0)
43: return (0);
44: return (1);
45: }
46:
47: rmtconnaborted()
48: {
49:
50: fprintf(stderr, "rdump: Lost connection to remote host.\n");
51: exit(1);
52: }
53:
54: rmtgetconn()
55: {
56: static struct servent *sp = 0;
57: struct passwd *pw;
58: char *name = "root";
59: int size;
60:
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: }
68: pw = getpwuid(getuid());
69: if (pw && pw->pw_name)
70: name = pw->pw_name;
71: rmtape = rcmd(&rmtpeer, sp->s_port, name, name, _PATH_RMT, 0);
72: size = ntrec * TP_BSIZE;
73: while (size > TP_BSIZE &&
74: setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0)
75: size -= TP_BSIZE;
76: }
77:
78: rmtopen(tape, mode)
79: char *tape;
80: int mode;
81: {
82: char buf[256];
83:
84: (void)sprintf(buf, "O%s\n%d\n", tape, mode);
85: rmtstate = TS_OPEN;
86: return (rmtcall(tape, buf));
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;
104: extern errno;
105:
106: (void)sprintf(line, "R%d\n", count);
107: n = rmtcall("read", line);
108: if (n < 0) {
109: errno = n;
110: return (-1);
111: }
112: for (i = 0; i < n; i += cc) {
113: cc = read(rmtape, buf+i, n - i);
114: if (cc <= 0) {
115: rmtconnaborted();
116: }
117: }
118: return (n);
119: }
120:
121: rmtwrite(buf, count)
122: char *buf;
123: int count;
124: {
125: char line[30];
126:
127: (void)sprintf(line, "W%d\n", count);
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:
138: (void)sprintf(line, "W%d\n", count);
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:
162: (void)sprintf(line, "L%d\n%d\n", offset, pos);
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);
189: (void)sprintf(buf, "I%d\n%d\n", cmd, count);
190: return (rmtcall("ioctl", buf));
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.