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