Blame


1 ce3844d2 2021-12-14 op /*
2 ce3844d2 2021-12-14 op * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 ce3844d2 2021-12-14 op *
4 ce3844d2 2021-12-14 op * Permission to use, copy, modify, and distribute this software for any
5 ce3844d2 2021-12-14 op * purpose with or without fee is hereby granted, provided that the above
6 ce3844d2 2021-12-14 op * copyright notice and this permission notice appear in all copies.
7 ce3844d2 2021-12-14 op *
8 ce3844d2 2021-12-14 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 ce3844d2 2021-12-14 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 ce3844d2 2021-12-14 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 ce3844d2 2021-12-14 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 ce3844d2 2021-12-14 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 ce3844d2 2021-12-14 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 ce3844d2 2021-12-14 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 ce3844d2 2021-12-14 op */
16 ce3844d2 2021-12-14 op
17 ce3844d2 2021-12-14 op #include "compat.h"
18 ce3844d2 2021-12-14 op
19 ce3844d2 2021-12-14 op #include <sys/types.h>
20 ce3844d2 2021-12-14 op #include <sys/socket.h>
21 ce3844d2 2021-12-14 op
22 423f02f5 2021-12-28 cage #include <assert.h>
23 3f03529f 2021-12-28 op #include <errno.h>
24 ce3844d2 2021-12-14 op #include <netdb.h>
25 ce3844d2 2021-12-14 op #include <limits.h>
26 ce3844d2 2021-12-14 op #include <stdio.h>
27 ce3844d2 2021-12-14 op #include <stdlib.h>
28 ce3844d2 2021-12-14 op #include <string.h>
29 ce3844d2 2021-12-14 op #include <syslog.h>
30 ce3844d2 2021-12-14 op #include <tls.h>
31 ce3844d2 2021-12-14 op #include <unistd.h>
32 ce3844d2 2021-12-14 op
33 423f02f5 2021-12-28 cage #if HAVE_LIBREADLINE
34 ce3844d2 2021-12-14 op #include <readline/readline.h>
35 ce3844d2 2021-12-14 op #include <readline/history.h>
36 688f54f0 2021-12-14 op #endif
37 ce3844d2 2021-12-14 op
38 423f02f5 2021-12-28 cage #ifndef nitems
39 423f02f5 2021-12-28 cage #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
40 423f02f5 2021-12-28 cage #endif
41 423f02f5 2021-12-28 cage
42 ce3844d2 2021-12-14 op #include "9pclib.h"
43 ce3844d2 2021-12-14 op #include "kamid.h"
44 ce3844d2 2021-12-14 op #include "utils.h"
45 ce3844d2 2021-12-14 op #include "log.h"
46 ce3844d2 2021-12-14 op
47 ce3844d2 2021-12-14 op /* flags */
48 ce3844d2 2021-12-14 op int tls;
49 ce3844d2 2021-12-14 op const char *crtpath;
50 ce3844d2 2021-12-14 op const char *keypath;
51 ce3844d2 2021-12-14 op
52 ce3844d2 2021-12-14 op /* state */
53 ce3844d2 2021-12-14 op struct tls_config *tlsconf;
54 ce3844d2 2021-12-14 op struct tls *ctx;
55 ce3844d2 2021-12-14 op int sock;
56 423f02f5 2021-12-28 cage struct evbuffer *buf;
57 423f02f5 2021-12-28 cage struct evbuffer *dirbuf;
58 423f02f5 2021-12-28 cage uint32_t msize;
59 423f02f5 2021-12-28 cage int bell;
60 ce3844d2 2021-12-14 op
61 ce3844d2 2021-12-14 op #define PWDFID 0
62 ce3844d2 2021-12-14 op
63 423f02f5 2021-12-28 cage #define ASSERT_EMPTYBUF() assert(EVBUFFER_LENGTH(buf) == 0)
64 423f02f5 2021-12-28 cage
65 423f02f5 2021-12-28 cage #if HAVE_LIBREADLINE
66 688f54f0 2021-12-14 op static char *
67 688f54f0 2021-12-14 op read_line(const char *prompt)
68 688f54f0 2021-12-14 op {
69 688f54f0 2021-12-14 op char *line;
70 688f54f0 2021-12-14 op
71 688f54f0 2021-12-14 op again:
72 688f54f0 2021-12-14 op if ((line = readline(prompt)) == NULL)
73 688f54f0 2021-12-14 op return NULL;
74 688f54f0 2021-12-14 op /* XXX: trim spaces? */
75 688f54f0 2021-12-14 op if (*line == '\0') {
76 688f54f0 2021-12-14 op free(line);
77 688f54f0 2021-12-14 op goto again;
78 688f54f0 2021-12-14 op }
79 688f54f0 2021-12-14 op
80 688f54f0 2021-12-14 op add_history(line);
81 688f54f0 2021-12-14 op return line;
82 688f54f0 2021-12-14 op }
83 688f54f0 2021-12-14 op #else
84 688f54f0 2021-12-14 op static char *
85 688f54f0 2021-12-14 op read_line(const char *prompt)
86 688f54f0 2021-12-14 op {
87 688f54f0 2021-12-14 op char *ch, *line = NULL;
88 688f54f0 2021-12-14 op size_t linesize = 0;
89 688f54f0 2021-12-14 op ssize_t linelen;
90 688f54f0 2021-12-14 op
91 423f02f5 2021-12-28 cage printf("%s", prompt);
92 423f02f5 2021-12-28 cage fflush(stdout);
93 423f02f5 2021-12-28 cage
94 688f54f0 2021-12-14 op linelen = getline(&line, &linesize, stdin);
95 688f54f0 2021-12-14 op if (linelen == -1)
96 688f54f0 2021-12-14 op return NULL;
97 688f54f0 2021-12-14 op
98 688f54f0 2021-12-14 op if ((ch = strchr(line, '\n')) != NULL)
99 688f54f0 2021-12-14 op *ch = '\0';
100 688f54f0 2021-12-14 op return line;
101 688f54f0 2021-12-14 op }
102 688f54f0 2021-12-14 op #endif
103 688f54f0 2021-12-14 op
104 a97ec9eb 2021-12-23 op static void __dead
105 ce3844d2 2021-12-14 op usage(int ret)
106 ce3844d2 2021-12-14 op {
107 ce3844d2 2021-12-14 op fprintf(stderr, "usage: %s [-c] host[:port] [path]\n",
108 ce3844d2 2021-12-14 op getprogname());
109 ce3844d2 2021-12-14 op fprintf(stderr, PACKAGE_NAME " suite version " PACKAGE VERSION "\n");
110 ce3844d2 2021-12-14 op exit(ret);
111 ce3844d2 2021-12-14 op }
112 ce3844d2 2021-12-14 op
113 ce3844d2 2021-12-14 op static void
114 423f02f5 2021-12-28 cage do_send(void)
115 423f02f5 2021-12-28 cage {
116 3f03529f 2021-12-28 op const void *buf;
117 3f03529f 2021-12-28 op size_t nbytes;
118 3f03529f 2021-12-28 op ssize_t r;
119 423f02f5 2021-12-28 cage
120 423f02f5 2021-12-28 cage while (EVBUFFER_LENGTH(evb) != 0) {
121 3f03529f 2021-12-28 op buf = EVBUFFER_DATA(evb);
122 3f03529f 2021-12-28 op nbytes = EVBUFFER_LENGTH(evb);
123 3f03529f 2021-12-28 op
124 3f03529f 2021-12-28 op if (ctx == NULL) {
125 3f03529f 2021-12-28 op r = write(sock, buf, nbytes);
126 3f03529f 2021-12-28 op if (r == 0 || r == -1)
127 3f03529f 2021-12-28 op errx(1, "EOF");
128 3f03529f 2021-12-28 op } else {
129 3f03529f 2021-12-28 op r = tls_write(ctx, buf, nbytes);
130 3f03529f 2021-12-28 op if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT)
131 3f03529f 2021-12-28 op continue;
132 3f03529f 2021-12-28 op if (r == -1)
133 3f03529f 2021-12-28 op errx(1, "tls: %s", tls_error(ctx));
134 423f02f5 2021-12-28 cage }
135 3f03529f 2021-12-28 op
136 3f03529f 2021-12-28 op evbuffer_drain(evb, r);
137 423f02f5 2021-12-28 cage }
138 423f02f5 2021-12-28 cage }
139 423f02f5 2021-12-28 cage
140 423f02f5 2021-12-28 cage static void
141 423f02f5 2021-12-28 cage mustread(void *d, size_t len)
142 423f02f5 2021-12-28 cage {
143 423f02f5 2021-12-28 cage ssize_t r;
144 423f02f5 2021-12-28 cage
145 423f02f5 2021-12-28 cage while (len != 0) {
146 3f03529f 2021-12-28 op if (ctx == NULL) {
147 3f03529f 2021-12-28 op r = read(sock, d, len);
148 3f03529f 2021-12-28 op if (r == 0 || r == -1)
149 3f03529f 2021-12-28 op errx(1, "EOF");
150 3f03529f 2021-12-28 op } else {
151 3f03529f 2021-12-28 op r = tls_read(ctx, d, len);
152 3f03529f 2021-12-28 op if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT)
153 3f03529f 2021-12-28 op continue;
154 3f03529f 2021-12-28 op if (r == -1)
155 3f03529f 2021-12-28 op errx(1, "tls: %s", tls_error(ctx));
156 423f02f5 2021-12-28 cage }
157 3f03529f 2021-12-28 op
158 3f03529f 2021-12-28 op d += r;
159 3f03529f 2021-12-28 op len -= r;
160 423f02f5 2021-12-28 cage }
161 423f02f5 2021-12-28 cage }
162 423f02f5 2021-12-28 cage
163 423f02f5 2021-12-28 cage static void
164 423f02f5 2021-12-28 cage recv_msg(void)
165 423f02f5 2021-12-28 cage {
166 3f03529f 2021-12-28 op uint32_t len, l;
167 423f02f5 2021-12-28 cage char tmp[BUFSIZ];
168 423f02f5 2021-12-28 cage
169 423f02f5 2021-12-28 cage mustread(&len, sizeof(len));
170 423f02f5 2021-12-28 cage len = le32toh(len);
171 423f02f5 2021-12-28 cage if (len < HEADERSIZE)
172 423f02f5 2021-12-28 cage errx(1, "read message of invalid length %d", len);
173 423f02f5 2021-12-28 cage
174 423f02f5 2021-12-28 cage len -= 4; /* skip the length just read */
175 423f02f5 2021-12-28 cage
176 423f02f5 2021-12-28 cage while (len != 0) {
177 3f03529f 2021-12-28 op l = MIN(len, sizeof(tmp));
178 3f03529f 2021-12-28 op mustread(tmp, l);
179 3f03529f 2021-12-28 op len -= l;
180 3f03529f 2021-12-28 op evbuffer_add(buf, tmp, l);
181 423f02f5 2021-12-28 cage }
182 423f02f5 2021-12-28 cage }
183 423f02f5 2021-12-28 cage
184 423f02f5 2021-12-28 cage static uint64_t
185 423f02f5 2021-12-28 cage np_read64(struct evbuffer *buf)
186 423f02f5 2021-12-28 cage {
187 423f02f5 2021-12-28 cage uint64_t n;
188 423f02f5 2021-12-28 cage
189 423f02f5 2021-12-28 cage evbuffer_remove(buf, &n, sizeof(n));
190 423f02f5 2021-12-28 cage return le64toh(n);
191 423f02f5 2021-12-28 cage }
192 423f02f5 2021-12-28 cage
193 423f02f5 2021-12-28 cage static uint32_t
194 423f02f5 2021-12-28 cage np_read32(struct evbuffer *buf)
195 423f02f5 2021-12-28 cage {
196 423f02f5 2021-12-28 cage uint32_t n;
197 423f02f5 2021-12-28 cage
198 423f02f5 2021-12-28 cage evbuffer_remove(buf, &n, sizeof(n));
199 423f02f5 2021-12-28 cage return le32toh(n);
200 423f02f5 2021-12-28 cage }
201 423f02f5 2021-12-28 cage
202 423f02f5 2021-12-28 cage static uint16_t
203 423f02f5 2021-12-28 cage np_read16(struct evbuffer *buf)
204 423f02f5 2021-12-28 cage {
205 423f02f5 2021-12-28 cage uint16_t n;
206 423f02f5 2021-12-28 cage
207 423f02f5 2021-12-28 cage evbuffer_remove(buf, &n, sizeof(n));
208 423f02f5 2021-12-28 cage return le16toh(n);
209 423f02f5 2021-12-28 cage }
210 423f02f5 2021-12-28 cage
211 423f02f5 2021-12-28 cage static uint16_t
212 423f02f5 2021-12-28 cage np_read8(struct evbuffer *buf)
213 423f02f5 2021-12-28 cage {
214 423f02f5 2021-12-28 cage uint8_t n;
215 423f02f5 2021-12-28 cage
216 423f02f5 2021-12-28 cage evbuffer_remove(buf, &n, sizeof(n));
217 423f02f5 2021-12-28 cage return n;
218 423f02f5 2021-12-28 cage }
219 423f02f5 2021-12-28 cage
220 423f02f5 2021-12-28 cage static char *
221 423f02f5 2021-12-28 cage np_readstr(struct evbuffer *buf)
222 423f02f5 2021-12-28 cage {
223 423f02f5 2021-12-28 cage uint16_t len;
224 423f02f5 2021-12-28 cage char *str;
225 423f02f5 2021-12-28 cage
226 423f02f5 2021-12-28 cage len = np_read16(buf);
227 423f02f5 2021-12-28 cage assert(EVBUFFER_LENGTH(buf) >= len);
228 423f02f5 2021-12-28 cage
229 423f02f5 2021-12-28 cage if ((str = calloc(1, len+1)) == NULL)
230 423f02f5 2021-12-28 cage err(1, "calloc");
231 423f02f5 2021-12-28 cage evbuffer_remove(buf, str, len);
232 423f02f5 2021-12-28 cage return str;
233 423f02f5 2021-12-28 cage }
234 423f02f5 2021-12-28 cage
235 423f02f5 2021-12-28 cage static void
236 423f02f5 2021-12-28 cage np_read_qid(struct evbuffer *buf, struct qid *qid)
237 423f02f5 2021-12-28 cage {
238 423f02f5 2021-12-28 cage assert(EVBUFFER_LENGTH(buf) >= QIDSIZE);
239 423f02f5 2021-12-28 cage
240 423f02f5 2021-12-28 cage qid->type = np_read8(buf);
241 423f02f5 2021-12-28 cage qid->vers = np_read32(buf);
242 423f02f5 2021-12-28 cage qid->path = np_read64(buf);
243 423f02f5 2021-12-28 cage }
244 423f02f5 2021-12-28 cage
245 423f02f5 2021-12-28 cage static void
246 423f02f5 2021-12-28 cage expect(uint8_t type)
247 423f02f5 2021-12-28 cage {
248 423f02f5 2021-12-28 cage uint8_t t;
249 423f02f5 2021-12-28 cage
250 423f02f5 2021-12-28 cage t = np_read8(buf);
251 423f02f5 2021-12-28 cage if (t == type)
252 423f02f5 2021-12-28 cage return;
253 423f02f5 2021-12-28 cage
254 423f02f5 2021-12-28 cage if (t == Terror) {
255 423f02f5 2021-12-28 cage char *err;
256 423f02f5 2021-12-28 cage
257 423f02f5 2021-12-28 cage err = np_readstr(buf);
258 423f02f5 2021-12-28 cage errx(1, "expected %s, got error %s",
259 423f02f5 2021-12-28 cage pp_msg_type(type), err);
260 423f02f5 2021-12-28 cage }
261 423f02f5 2021-12-28 cage
262 423f02f5 2021-12-28 cage errx(1, "expected %s, got msg type %s",
263 423f02f5 2021-12-28 cage pp_msg_type(type), pp_msg_type(t));
264 423f02f5 2021-12-28 cage }
265 423f02f5 2021-12-28 cage
266 423f02f5 2021-12-28 cage static void
267 423f02f5 2021-12-28 cage expect2(uint8_t type, uint16_t tag)
268 423f02f5 2021-12-28 cage {
269 423f02f5 2021-12-28 cage uint16_t t;
270 423f02f5 2021-12-28 cage
271 423f02f5 2021-12-28 cage expect(type);
272 423f02f5 2021-12-28 cage
273 423f02f5 2021-12-28 cage t = np_read16(buf);
274 423f02f5 2021-12-28 cage if (t == tag)
275 423f02f5 2021-12-28 cage return;
276 423f02f5 2021-12-28 cage
277 423f02f5 2021-12-28 cage errx(1, "expected tag 0x%x, got 0x%x", tag, t);
278 423f02f5 2021-12-28 cage }
279 423f02f5 2021-12-28 cage
280 423f02f5 2021-12-28 cage static void
281 ce3844d2 2021-12-14 op do_version(void)
282 ce3844d2 2021-12-14 op {
283 423f02f5 2021-12-28 cage char *version;
284 423f02f5 2021-12-28 cage
285 ce3844d2 2021-12-14 op tversion(VERSION9P, MSIZE9P);
286 423f02f5 2021-12-28 cage do_send();
287 423f02f5 2021-12-28 cage recv_msg();
288 423f02f5 2021-12-28 cage expect2(Rversion, NOTAG);
289 423f02f5 2021-12-28 cage
290 423f02f5 2021-12-28 cage msize = np_read32(buf);
291 423f02f5 2021-12-28 cage version = np_readstr(buf);
292 423f02f5 2021-12-28 cage
293 423f02f5 2021-12-28 cage if (msize > MSIZE9P)
294 423f02f5 2021-12-28 cage errx(1, "got unexpected msize: %d", msize);
295 423f02f5 2021-12-28 cage if (strcmp(version, VERSION9P))
296 423f02f5 2021-12-28 cage errx(1, "unexpected 9p version: %s", version);
297 423f02f5 2021-12-28 cage
298 423f02f5 2021-12-28 cage free(version);
299 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
300 ce3844d2 2021-12-14 op }
301 ce3844d2 2021-12-14 op
302 ce3844d2 2021-12-14 op static void
303 ce3844d2 2021-12-14 op do_attach(const char *path)
304 ce3844d2 2021-12-14 op {
305 423f02f5 2021-12-28 cage const char *user;
306 423f02f5 2021-12-28 cage struct qid qid;
307 423f02f5 2021-12-28 cage
308 ce3844d2 2021-12-14 op if (path == NULL)
309 ce3844d2 2021-12-14 op path = "/";
310 423f02f5 2021-12-28 cage if ((user = getenv("USER")) == NULL)
311 423f02f5 2021-12-28 cage user = "flan";
312 ce3844d2 2021-12-14 op
313 423f02f5 2021-12-28 cage tattach(PWDFID, NOFID, user, path);
314 423f02f5 2021-12-28 cage do_send();
315 423f02f5 2021-12-28 cage recv_msg();
316 423f02f5 2021-12-28 cage expect2(Rattach, iota_tag);
317 423f02f5 2021-12-28 cage np_read_qid(buf, &qid);
318 423f02f5 2021-12-28 cage
319 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
320 423f02f5 2021-12-28 cage }
321 423f02f5 2021-12-28 cage
322 423f02f5 2021-12-28 cage static uint32_t
323 423f02f5 2021-12-28 cage do_open(uint32_t fid, uint8_t mode)
324 423f02f5 2021-12-28 cage {
325 423f02f5 2021-12-28 cage struct qid qid;
326 423f02f5 2021-12-28 cage uint32_t iounit;
327 423f02f5 2021-12-28 cage
328 423f02f5 2021-12-28 cage topen(fid, mode);
329 423f02f5 2021-12-28 cage do_send();
330 423f02f5 2021-12-28 cage recv_msg();
331 423f02f5 2021-12-28 cage expect2(Ropen, iota_tag);
332 423f02f5 2021-12-28 cage
333 423f02f5 2021-12-28 cage np_read_qid(buf, &qid);
334 423f02f5 2021-12-28 cage iounit = np_read32(buf);
335 423f02f5 2021-12-28 cage
336 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
337 423f02f5 2021-12-28 cage
338 423f02f5 2021-12-28 cage return iounit;
339 ce3844d2 2021-12-14 op }
340 ce3844d2 2021-12-14 op
341 ce3844d2 2021-12-14 op static void
342 423f02f5 2021-12-28 cage do_clunk(uint32_t fid)
343 423f02f5 2021-12-28 cage {
344 423f02f5 2021-12-28 cage tclunk(fid);
345 423f02f5 2021-12-28 cage do_send();
346 423f02f5 2021-12-28 cage recv_msg();
347 423f02f5 2021-12-28 cage expect2(Rclunk, iota_tag);
348 423f02f5 2021-12-28 cage
349 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
350 423f02f5 2021-12-28 cage }
351 423f02f5 2021-12-28 cage
352 423f02f5 2021-12-28 cage static void
353 423f02f5 2021-12-28 cage dup_fid(int fid, int nfid)
354 423f02f5 2021-12-28 cage {
355 423f02f5 2021-12-28 cage uint16_t nwqid;
356 423f02f5 2021-12-28 cage
357 423f02f5 2021-12-28 cage twalk(fid, nfid, NULL, 0);
358 423f02f5 2021-12-28 cage do_send();
359 423f02f5 2021-12-28 cage recv_msg();
360 423f02f5 2021-12-28 cage expect2(Rwalk, iota_tag);
361 423f02f5 2021-12-28 cage
362 423f02f5 2021-12-28 cage nwqid = np_read16(buf);
363 423f02f5 2021-12-28 cage assert(nwqid == 0);
364 423f02f5 2021-12-28 cage
365 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
366 423f02f5 2021-12-28 cage }
367 423f02f5 2021-12-28 cage
368 423f02f5 2021-12-28 cage static void
369 3f03529f 2021-12-28 op do_tls_connect(const char *host, const char *port)
370 ce3844d2 2021-12-14 op {
371 ce3844d2 2021-12-14 op int handshake;
372 ce3844d2 2021-12-14 op
373 ce3844d2 2021-12-14 op if ((tlsconf = tls_config_new()) == NULL)
374 ce3844d2 2021-12-14 op fatalx("tls_config_new");
375 ce3844d2 2021-12-14 op tls_config_insecure_noverifycert(tlsconf);
376 ce3844d2 2021-12-14 op tls_config_insecure_noverifyname(tlsconf);
377 ce3844d2 2021-12-14 op if (tls_config_set_keypair_file(tlsconf, crtpath, keypath) == -1)
378 ce3844d2 2021-12-14 op fatalx("can't load certs (%s, %s)", crtpath, keypath);
379 ce3844d2 2021-12-14 op
380 ce3844d2 2021-12-14 op if ((ctx = tls_client()) == NULL)
381 ce3844d2 2021-12-14 op fatal("tls_client");
382 ce3844d2 2021-12-14 op if (tls_configure(ctx, tlsconf) == -1)
383 ce3844d2 2021-12-14 op fatalx("tls_configure: %s", tls_error(ctx));
384 ce3844d2 2021-12-14 op
385 ce3844d2 2021-12-14 op if (tls_connect(ctx, host, port) == -1)
386 ce3844d2 2021-12-14 op fatalx("can't connect to %s:%s: %s", host, port,
387 ce3844d2 2021-12-14 op tls_error(ctx));
388 ce3844d2 2021-12-14 op
389 ce3844d2 2021-12-14 op for (handshake = 0; !handshake;) {
390 ce3844d2 2021-12-14 op switch (tls_handshake(ctx)) {
391 ce3844d2 2021-12-14 op case -1:
392 ce3844d2 2021-12-14 op fatalx("tls_handshake: %s", tls_error(ctx));
393 ce3844d2 2021-12-14 op case 0:
394 ce3844d2 2021-12-14 op handshake = 1;
395 ce3844d2 2021-12-14 op break;
396 ce3844d2 2021-12-14 op }
397 ce3844d2 2021-12-14 op }
398 3f03529f 2021-12-28 op }
399 ce3844d2 2021-12-14 op
400 3f03529f 2021-12-28 op static void
401 3f03529f 2021-12-28 op do_ctxt_connect(const char *host, const char *port)
402 3f03529f 2021-12-28 op {
403 3f03529f 2021-12-28 op struct addrinfo hints, *res, *res0;
404 3f03529f 2021-12-28 op int error, saved_errno;
405 3f03529f 2021-12-28 op const char *cause = NULL;
406 3f03529f 2021-12-28 op
407 3f03529f 2021-12-28 op memset(&hints, 0, sizeof(hints));
408 3f03529f 2021-12-28 op hints.ai_family = AF_UNSPEC;
409 3f03529f 2021-12-28 op hints.ai_socktype = SOCK_STREAM;
410 3f03529f 2021-12-28 op error = getaddrinfo(host, port, &hints, &res0);
411 3f03529f 2021-12-28 op if (error)
412 3f03529f 2021-12-28 op errx(1, "%s", gai_strerror(error));
413 3f03529f 2021-12-28 op
414 3f03529f 2021-12-28 op sock = -1;
415 3f03529f 2021-12-28 op for (res = res0; res != NULL; res = res->ai_next) {
416 3f03529f 2021-12-28 op sock = socket(res->ai_family, res->ai_socktype,
417 3f03529f 2021-12-28 op res->ai_protocol);
418 3f03529f 2021-12-28 op if (sock == -1) {
419 3f03529f 2021-12-28 op cause = "socket";
420 3f03529f 2021-12-28 op continue;
421 3f03529f 2021-12-28 op }
422 3f03529f 2021-12-28 op
423 3f03529f 2021-12-28 op if (connect(sock, res->ai_addr, res->ai_addrlen) == -1) {
424 3f03529f 2021-12-28 op cause = "connect";
425 3f03529f 2021-12-28 op saved_errno = errno;
426 3f03529f 2021-12-28 op close(sock);
427 3f03529f 2021-12-28 op errno = saved_errno;
428 3f03529f 2021-12-28 op sock = -1;
429 3f03529f 2021-12-28 op continue;
430 3f03529f 2021-12-28 op }
431 3f03529f 2021-12-28 op
432 3f03529f 2021-12-28 op break;
433 3f03529f 2021-12-28 op }
434 3f03529f 2021-12-28 op
435 3f03529f 2021-12-28 op if (sock == -1)
436 3f03529f 2021-12-28 op err(1, "%s", cause);
437 3f03529f 2021-12-28 op freeaddrinfo(res0);
438 3f03529f 2021-12-28 op }
439 3f03529f 2021-12-28 op
440 3f03529f 2021-12-28 op static void
441 3f03529f 2021-12-28 op do_connect(const char *connspec, const char *path)
442 3f03529f 2021-12-28 op {
443 3f03529f 2021-12-28 op char *host, *colon;
444 3f03529f 2021-12-28 op const char *port;
445 3f03529f 2021-12-28 op
446 3f03529f 2021-12-28 op host = xstrdup(connspec);
447 3f03529f 2021-12-28 op if ((colon = strchr(host, ':')) != NULL) {
448 3f03529f 2021-12-28 op *colon = '\0';
449 3f03529f 2021-12-28 op port = ++colon;
450 3f03529f 2021-12-28 op } else
451 3f03529f 2021-12-28 op port = "1337";
452 3f03529f 2021-12-28 op
453 3f03529f 2021-12-28 op printf("connecting to %s:%s...", host, port);
454 3f03529f 2021-12-28 op fflush(stdout);
455 3f03529f 2021-12-28 op
456 3f03529f 2021-12-28 op if (tls)
457 3f03529f 2021-12-28 op do_tls_connect(host, port);
458 3f03529f 2021-12-28 op else
459 3f03529f 2021-12-28 op do_ctxt_connect(host, port);
460 3f03529f 2021-12-28 op
461 ce3844d2 2021-12-14 op printf(" done!\n");
462 ce3844d2 2021-12-14 op
463 ce3844d2 2021-12-14 op do_version();
464 ce3844d2 2021-12-14 op do_attach(path);
465 ce3844d2 2021-12-14 op
466 ce3844d2 2021-12-14 op free(host);
467 ce3844d2 2021-12-14 op }
468 ce3844d2 2021-12-14 op
469 423f02f5 2021-12-28 cage static void
470 423f02f5 2021-12-28 cage cmd_bell(int argc, const char **argv)
471 423f02f5 2021-12-28 cage {
472 423f02f5 2021-12-28 cage if (argc == 0) {
473 423f02f5 2021-12-28 cage bell = !bell;
474 423f02f5 2021-12-28 cage if (bell)
475 423f02f5 2021-12-28 cage puts("bell mode enabled");
476 423f02f5 2021-12-28 cage else
477 423f02f5 2021-12-28 cage puts("bell mode disabled");
478 423f02f5 2021-12-28 cage return;
479 423f02f5 2021-12-28 cage }
480 423f02f5 2021-12-28 cage
481 423f02f5 2021-12-28 cage if (argc != 1)
482 423f02f5 2021-12-28 cage goto usage;
483 423f02f5 2021-12-28 cage
484 423f02f5 2021-12-28 cage if (!strcmp(*argv, "on")) {
485 423f02f5 2021-12-28 cage bell = 1;
486 423f02f5 2021-12-28 cage puts("bell mode enabled");
487 423f02f5 2021-12-28 cage return;
488 423f02f5 2021-12-28 cage }
489 423f02f5 2021-12-28 cage
490 423f02f5 2021-12-28 cage if (!strcmp(*argv, "off")) {
491 423f02f5 2021-12-28 cage bell = 0;
492 423f02f5 2021-12-28 cage puts("bell mode disabled");
493 423f02f5 2021-12-28 cage return;
494 423f02f5 2021-12-28 cage }
495 423f02f5 2021-12-28 cage
496 423f02f5 2021-12-28 cage usage:
497 423f02f5 2021-12-28 cage printf("bell [on | off]\n");
498 423f02f5 2021-12-28 cage }
499 423f02f5 2021-12-28 cage
500 423f02f5 2021-12-28 cage static void
501 423f02f5 2021-12-28 cage cmd_bye(int argc, const char **argv)
502 423f02f5 2021-12-28 cage {
503 423f02f5 2021-12-28 cage log_warnx("bye\n");
504 423f02f5 2021-12-28 cage exit(0);
505 423f02f5 2021-12-28 cage }
506 423f02f5 2021-12-28 cage
507 423f02f5 2021-12-28 cage static void
508 17388298 2021-12-28 op cmd_lcd(int argc, const char **argv)
509 17388298 2021-12-28 op {
510 17388298 2021-12-28 op const char *dir;
511 17388298 2021-12-28 op
512 17388298 2021-12-28 op if (argc > 1) {
513 17388298 2021-12-28 op printf("lcd takes only one argument\n");
514 17388298 2021-12-28 op return;
515 17388298 2021-12-28 op }
516 17388298 2021-12-28 op
517 17388298 2021-12-28 op if (argc == 1)
518 17388298 2021-12-28 op dir = *argv;
519 17388298 2021-12-28 op
520 17388298 2021-12-28 op if (argc == 0 && (dir = getenv("HOME")) == NULL) {
521 17388298 2021-12-28 op printf("HOME is not defined\n");
522 17388298 2021-12-28 op return;
523 17388298 2021-12-28 op }
524 17388298 2021-12-28 op
525 17388298 2021-12-28 op if (chdir(dir) == -1)
526 17388298 2021-12-28 op printf("cd: %s: %s\n", dir, strerror(errno));
527 6150fab3 2021-12-28 op }
528 6150fab3 2021-12-28 op
529 6150fab3 2021-12-28 op static void
530 6150fab3 2021-12-28 op cmd_lpwd(int argc, const char **argv)
531 6150fab3 2021-12-28 op {
532 6150fab3 2021-12-28 op char path[PATH_MAX];
533 6150fab3 2021-12-28 op
534 6150fab3 2021-12-28 op if (getcwd(path, sizeof(path)) == NULL) {
535 6150fab3 2021-12-28 op printf("lpwd: %s\n", strerror(errno));
536 6150fab3 2021-12-28 op return;
537 6150fab3 2021-12-28 op }
538 6150fab3 2021-12-28 op
539 6150fab3 2021-12-28 op printf("%s\n", path);
540 17388298 2021-12-28 op }
541 17388298 2021-12-28 op
542 17388298 2021-12-28 op static void
543 423f02f5 2021-12-28 cage cmd_ls(int argc, const char **argv)
544 423f02f5 2021-12-28 cage {
545 423f02f5 2021-12-28 cage uint64_t off = 0;
546 423f02f5 2021-12-28 cage uint32_t len;
547 423f02f5 2021-12-28 cage
548 423f02f5 2021-12-28 cage if (argc != 0) {
549 423f02f5 2021-12-28 cage printf("ls don't take arguments (yet)\n");
550 423f02f5 2021-12-28 cage return;
551 423f02f5 2021-12-28 cage }
552 423f02f5 2021-12-28 cage
553 423f02f5 2021-12-28 cage dup_fid(PWDFID, 1);
554 423f02f5 2021-12-28 cage do_open(1, KOREAD);
555 423f02f5 2021-12-28 cage
556 423f02f5 2021-12-28 cage evbuffer_drain(dirbuf, EVBUFFER_LENGTH(dirbuf));
557 423f02f5 2021-12-28 cage
558 423f02f5 2021-12-28 cage for (;;) {
559 423f02f5 2021-12-28 cage tread(1, off, BUFSIZ);
560 423f02f5 2021-12-28 cage do_send();
561 423f02f5 2021-12-28 cage recv_msg();
562 423f02f5 2021-12-28 cage expect2(Rread, iota_tag);
563 423f02f5 2021-12-28 cage
564 423f02f5 2021-12-28 cage len = np_read32(buf);
565 423f02f5 2021-12-28 cage if (len == 0)
566 423f02f5 2021-12-28 cage break;
567 423f02f5 2021-12-28 cage
568 423f02f5 2021-12-28 cage evbuffer_add_buffer(dirbuf, buf);
569 423f02f5 2021-12-28 cage off += len;
570 423f02f5 2021-12-28 cage
571 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
572 423f02f5 2021-12-28 cage }
573 423f02f5 2021-12-28 cage
574 423f02f5 2021-12-28 cage while (EVBUFFER_LENGTH(dirbuf) != 0) {
575 423f02f5 2021-12-28 cage struct qid qid;
576 423f02f5 2021-12-28 cage uint64_t len;
577 423f02f5 2021-12-28 cage uint16_t size;
578 423f02f5 2021-12-28 cage char *name;
579 423f02f5 2021-12-28 cage
580 423f02f5 2021-12-28 cage size = np_read16(dirbuf);
581 423f02f5 2021-12-28 cage assert(size <= EVBUFFER_LENGTH(dirbuf));
582 423f02f5 2021-12-28 cage
583 423f02f5 2021-12-28 cage np_read16(dirbuf); /* skip type */
584 423f02f5 2021-12-28 cage np_read32(dirbuf); /* skip dev */
585 423f02f5 2021-12-28 cage
586 423f02f5 2021-12-28 cage np_read_qid(dirbuf, &qid);
587 423f02f5 2021-12-28 cage printf("%s ", pp_qid_type(qid.type));
588 423f02f5 2021-12-28 cage
589 423f02f5 2021-12-28 cage np_read32(dirbuf); /* skip mode */
590 423f02f5 2021-12-28 cage np_read32(dirbuf); /* skip atime */
591 423f02f5 2021-12-28 cage np_read32(dirbuf); /* skip mtime */
592 423f02f5 2021-12-28 cage
593 423f02f5 2021-12-28 cage len = np_read64(dirbuf);
594 423f02f5 2021-12-28 cage printf("%llu ", (unsigned long long)len);
595 423f02f5 2021-12-28 cage
596 423f02f5 2021-12-28 cage name = np_readstr(dirbuf);
597 423f02f5 2021-12-28 cage printf("%s\n", name);
598 423f02f5 2021-12-28 cage free(name);
599 423f02f5 2021-12-28 cage
600 423f02f5 2021-12-28 cage free(np_readstr(dirbuf)); /* skip uid */
601 423f02f5 2021-12-28 cage free(np_readstr(dirbuf)); /* skip gid */
602 423f02f5 2021-12-28 cage free(np_readstr(dirbuf)); /* skip muid */
603 423f02f5 2021-12-28 cage }
604 423f02f5 2021-12-28 cage
605 423f02f5 2021-12-28 cage do_clunk(1);
606 423f02f5 2021-12-28 cage }
607 423f02f5 2021-12-28 cage
608 423f02f5 2021-12-28 cage static void
609 423f02f5 2021-12-28 cage cmd_verbose(int argc, const char **argv)
610 423f02f5 2021-12-28 cage {
611 423f02f5 2021-12-28 cage if (argc == 0) {
612 423f02f5 2021-12-28 cage log_setverbose(!log_getverbose());
613 423f02f5 2021-12-28 cage if (log_getverbose())
614 423f02f5 2021-12-28 cage puts("verbose mode enabled");
615 423f02f5 2021-12-28 cage else
616 423f02f5 2021-12-28 cage puts("verbose mode disabled");
617 423f02f5 2021-12-28 cage return;
618 423f02f5 2021-12-28 cage }
619 423f02f5 2021-12-28 cage
620 423f02f5 2021-12-28 cage if (argc != 1)
621 423f02f5 2021-12-28 cage goto usage;
622 423f02f5 2021-12-28 cage
623 423f02f5 2021-12-28 cage if (!strcmp(*argv, "on")) {
624 423f02f5 2021-12-28 cage log_setverbose(1);
625 423f02f5 2021-12-28 cage puts("verbose mode enabled");
626 423f02f5 2021-12-28 cage return;
627 423f02f5 2021-12-28 cage }
628 423f02f5 2021-12-28 cage
629 423f02f5 2021-12-28 cage if (!strcmp(*argv, "off")) {
630 423f02f5 2021-12-28 cage log_setverbose(0);
631 423f02f5 2021-12-28 cage puts("verbose mode disabled");
632 423f02f5 2021-12-28 cage return;
633 423f02f5 2021-12-28 cage }
634 423f02f5 2021-12-28 cage
635 423f02f5 2021-12-28 cage usage:
636 423f02f5 2021-12-28 cage printf("verbose [on | off]\n");
637 423f02f5 2021-12-28 cage }
638 423f02f5 2021-12-28 cage
639 423f02f5 2021-12-28 cage static void
640 423f02f5 2021-12-28 cage excmd(int argc, const char **argv)
641 423f02f5 2021-12-28 cage {
642 423f02f5 2021-12-28 cage struct cmd {
643 423f02f5 2021-12-28 cage const char *name;
644 423f02f5 2021-12-28 cage void (*fn)(int, const char **);
645 423f02f5 2021-12-28 cage } cmds[] = {
646 423f02f5 2021-12-28 cage {"bell", cmd_bell},
647 423f02f5 2021-12-28 cage {"bye", cmd_bye},
648 17388298 2021-12-28 op {"lcd", cmd_lcd},
649 6150fab3 2021-12-28 op {"lpwd", cmd_lpwd},
650 423f02f5 2021-12-28 cage {"ls", cmd_ls},
651 423f02f5 2021-12-28 cage {"quit", cmd_bye},
652 423f02f5 2021-12-28 cage {"verbose", cmd_verbose},
653 423f02f5 2021-12-28 cage };
654 423f02f5 2021-12-28 cage size_t i;
655 423f02f5 2021-12-28 cage
656 423f02f5 2021-12-28 cage if (argc == 0)
657 423f02f5 2021-12-28 cage return;
658 423f02f5 2021-12-28 cage for (i = 0; i < nitems(cmds); ++i) {
659 423f02f5 2021-12-28 cage if (!strcmp(cmds[i].name, *argv)) {
660 423f02f5 2021-12-28 cage cmds[i].fn(argc-1, argv+1);
661 423f02f5 2021-12-28 cage return;
662 423f02f5 2021-12-28 cage }
663 423f02f5 2021-12-28 cage }
664 423f02f5 2021-12-28 cage
665 423f02f5 2021-12-28 cage log_warnx("unknown command %s", *argv);
666 423f02f5 2021-12-28 cage }
667 423f02f5 2021-12-28 cage
668 ce3844d2 2021-12-14 op int
669 ce3844d2 2021-12-14 op main(int argc, char **argv)
670 ce3844d2 2021-12-14 op {
671 ce3844d2 2021-12-14 op int ch;
672 ce3844d2 2021-12-14 op
673 ce3844d2 2021-12-14 op log_init(1, LOG_DAEMON);
674 423f02f5 2021-12-28 cage log_setverbose(0);
675 ce3844d2 2021-12-14 op log_procinit(getprogname());
676 ce3844d2 2021-12-14 op
677 ce3844d2 2021-12-14 op while ((ch = getopt(argc, argv, "C:cK:")) != -1) {
678 ce3844d2 2021-12-14 op switch (ch) {
679 ce3844d2 2021-12-14 op case 'C':
680 ce3844d2 2021-12-14 op crtpath = optarg;
681 ce3844d2 2021-12-14 op break;
682 ce3844d2 2021-12-14 op case 'c':
683 ce3844d2 2021-12-14 op tls = 1;
684 ce3844d2 2021-12-14 op break;
685 ce3844d2 2021-12-14 op case 'K':
686 ce3844d2 2021-12-14 op keypath = optarg;
687 ce3844d2 2021-12-14 op break;
688 ce3844d2 2021-12-14 op default:
689 ce3844d2 2021-12-14 op usage(1);
690 ce3844d2 2021-12-14 op }
691 ce3844d2 2021-12-14 op }
692 ce3844d2 2021-12-14 op argc -= optind;
693 ce3844d2 2021-12-14 op argv += optind;
694 ce3844d2 2021-12-14 op
695 ce3844d2 2021-12-14 op if (argc == 0)
696 ce3844d2 2021-12-14 op usage(1);
697 ce3844d2 2021-12-14 op
698 ce3844d2 2021-12-14 op if ((evb = evbuffer_new()) == NULL)
699 ce3844d2 2021-12-14 op fatal("evbuffer_new");
700 ce3844d2 2021-12-14 op
701 423f02f5 2021-12-28 cage if ((buf = evbuffer_new()) == NULL)
702 423f02f5 2021-12-28 cage fatal("evbuffer_new");
703 423f02f5 2021-12-28 cage
704 423f02f5 2021-12-28 cage if ((dirbuf = evbuffer_new()) == NULL)
705 423f02f5 2021-12-28 cage fatal("evbuferr_new");
706 423f02f5 2021-12-28 cage
707 ce3844d2 2021-12-14 op do_connect(argv[0], argv[1]);
708 ce3844d2 2021-12-14 op
709 423f02f5 2021-12-28 cage /* cmd_ls(0, NULL); */
710 423f02f5 2021-12-28 cage
711 ce3844d2 2021-12-14 op for (;;) {
712 423f02f5 2021-12-28 cage int argc = 0;
713 423f02f5 2021-12-28 cage char *line, *argv[16] = {0}, **ap;
714 ce3844d2 2021-12-14 op
715 423f02f5 2021-12-28 cage if ((line = read_line("kamiftp> ")) == NULL)
716 ce3844d2 2021-12-14 op break;
717 423f02f5 2021-12-28 cage
718 423f02f5 2021-12-28 cage for (argc = 0, ap = argv; ap < &argv[15] &&
719 423f02f5 2021-12-28 cage (*ap = strsep(&line, " \t")) != NULL;) {
720 423f02f5 2021-12-28 cage if (**ap != '\0')
721 423f02f5 2021-12-28 cage ap++, argc++;
722 423f02f5 2021-12-28 cage }
723 423f02f5 2021-12-28 cage excmd(argc, (const char **)argv);
724 423f02f5 2021-12-28 cage
725 423f02f5 2021-12-28 cage if (bell) {
726 423f02f5 2021-12-28 cage printf("\a");
727 423f02f5 2021-12-28 cage fflush(stdout);
728 423f02f5 2021-12-28 cage }
729 423f02f5 2021-12-28 cage
730 423f02f5 2021-12-28 cage free(line);
731 ce3844d2 2021-12-14 op }
732 ce3844d2 2021-12-14 op
733 ce3844d2 2021-12-14 op printf("\n");
734 ce3844d2 2021-12-14 op }