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