2 27909800 2021-07-26 op * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
4 27909800 2021-07-26 op * Permission to use, copy, modify, and distribute this software for any
5 27909800 2021-07-26 op * purpose with or without fee is hereby granted, provided that the above
6 27909800 2021-07-26 op * copyright notice and this permission notice appear in all copies.
8 27909800 2021-07-26 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 27909800 2021-07-26 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 27909800 2021-07-26 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 27909800 2021-07-26 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 27909800 2021-07-26 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 27909800 2021-07-26 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 27909800 2021-07-26 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 27909800 2021-07-26 op #include "compat.h"
19 27909800 2021-07-26 op #include <sys/types.h>
20 27909800 2021-07-26 op #include <sys/socket.h>
22 27909800 2021-07-26 op #include <netdb.h>
24 27909800 2021-07-26 op #include <assert.h>
25 27909800 2021-07-26 op #include <endian.h>
26 27909800 2021-07-26 op #include <errno.h>
27 9d5307de 2021-07-27 op #include <fcntl.h>
28 27909800 2021-07-26 op #include <inttypes.h>
29 27909800 2021-07-26 op #include <signal.h>
30 27909800 2021-07-26 op #include <stdio.h>
31 27909800 2021-07-26 op #include <stdlib.h>
32 27909800 2021-07-26 op #include <string.h>
33 27909800 2021-07-26 op #include <syslog.h>
34 27909800 2021-07-26 op #include <tls.h>
35 27909800 2021-07-26 op #include <unistd.h>
37 27909800 2021-07-26 op #include "kamid.h"
38 27909800 2021-07-26 op #include "log.h"
39 27909800 2021-07-26 op #include "utils.h"
41 9991b526 2021-08-01 op #define DEBUG_PACKETS 0
43 01d4b7a4 2021-07-29 op #define PROMPT "=% "
48 27909800 2021-07-26 op const char *keypath;
49 27909800 2021-07-26 op const char *crtpath;
50 27909800 2021-07-26 op const char *host;
51 27909800 2021-07-26 op const char *port;
54 27909800 2021-07-26 op struct tls_config *tlsconf;
55 27909800 2021-07-26 op struct tls *ctx;
56 9d5307de 2021-07-27 op struct bufferevent *bev, *inbev;
58 27909800 2021-07-26 op static void ATTR_DEAD usage(int);
60 27909800 2021-07-26 op static void sig_handler(int, short, void *);
62 27909800 2021-07-26 op static int openconn(void);
63 9d5307de 2021-07-27 op static void mark_nonblock(int);
65 27909800 2021-07-26 op static void tls_readcb(int, short, void *);
66 27909800 2021-07-26 op static void tls_writecb(int, short, void *);
68 27909800 2021-07-26 op static void client_read(struct bufferevent *, void *);
69 27909800 2021-07-26 op static void client_write(struct bufferevent *, void *);
70 27909800 2021-07-26 op static void client_error(struct bufferevent *, short, void *);
72 9d5307de 2021-07-27 op static void repl_read(struct bufferevent *, void *);
73 9d5307de 2021-07-27 op static void repl_error(struct bufferevent *, short, void *);
74 de678634 2021-07-28 op static void write_hdr(uint32_t, uint8_t, uint16_t);
75 ed61de84 2021-07-30 op static void write_hdr_auto(uint32_t, uint8_t);
76 6c3acfa1 2021-07-29 op static void write_str(uint16_t, const char *);
77 29bc9fe5 2021-08-01 op static void write_str_auto(const char *);
78 6c3acfa1 2021-07-29 op static void write_fid(uint32_t);
79 5ed7f718 2021-07-30 op static void write_tag(uint16_t);
81 afaad60e 2021-07-29 op static void excmd_version(const char **, int);
82 afaad60e 2021-07-29 op static void excmd_attach(const char **, int);
83 25359fc4 2021-07-30 op static void excmd_clunk(const char **, int);
84 5ed7f718 2021-07-30 op static void excmd_flush(const char **, int);
85 29bc9fe5 2021-08-01 op static void excmd_walk(const char ** , int);
86 9d5307de 2021-07-27 op static void excmd(const char **, int);
88 9cb5f957 2021-07-29 op static const char *pp_qid_type(uint8_t);
89 9cb5f957 2021-07-29 op static void pp_qid(const uint8_t *, uint32_t);
90 ff3a2c18 2021-07-29 op static void pp_msg(uint32_t, uint8_t, uint16_t, const uint8_t *);
91 de678634 2021-07-28 op static void handle_9p(const uint8_t *, size_t);
92 5c57fb10 2021-07-26 op static void clr(void);
93 27909800 2021-07-26 op static void prompt(void);
95 27909800 2021-07-26 op static void ATTR_DEAD
96 27909800 2021-07-26 op usage(int ret)
98 27909800 2021-07-26 op fprintf(stderr,
99 27909800 2021-07-26 op "usage: %s [-chv] [-C crt] [-K key] [-H host] [-P port]\n",
100 27909800 2021-07-26 op getprogname());
101 27909800 2021-07-26 op fprintf(stderr, PACKAGE_NAME " suite version " PACKAGE_VERSION "\n");
106 27909800 2021-07-26 op sig_handler(int sig, short event, void *d)
109 27909800 2021-07-26 op * Normal signal handler rules don't apply because libevent
110 27909800 2021-07-26 op * decouples for us.
113 27909800 2021-07-26 op switch (sig) {
115 27909800 2021-07-26 op case SIGTERM:
117 5c57fb10 2021-07-26 op log_warnx("Shutting down...");
118 27909800 2021-07-26 op event_loopbreak();
121 27909800 2021-07-26 op fatalx("unexpected signal %d", sig);
126 27909800 2021-07-26 op openconn(void)
128 27909800 2021-07-26 op struct addrinfo hints, *res, *res0;
130 27909800 2021-07-26 op int save_errno;
132 27909800 2021-07-26 op const char *cause = NULL;
134 27909800 2021-07-26 op memset(&hints, 0, sizeof(hints));
135 27909800 2021-07-26 op hints.ai_family = AF_UNSPEC;
136 27909800 2021-07-26 op hints.ai_socktype = SOCK_STREAM;
137 27909800 2021-07-26 op if ((error = getaddrinfo(host, port, &hints, &res0))) {
138 27909800 2021-07-26 op warnx("%s", gai_strerror(error));
143 27909800 2021-07-26 op for (res = res0; res; res = res->ai_next) {
144 27909800 2021-07-26 op s = socket(res->ai_family, res->ai_socktype,
145 27909800 2021-07-26 op res->ai_protocol);
146 27909800 2021-07-26 op if (s == -1) {
147 27909800 2021-07-26 op cause = "socket";
151 27909800 2021-07-26 op if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
152 27909800 2021-07-26 op cause = "connect";
153 27909800 2021-07-26 op save_errno = errno;
155 27909800 2021-07-26 op errno = save_errno;
163 27909800 2021-07-26 op freeaddrinfo(res0);
166 27909800 2021-07-26 op warn("%s", cause);
172 9d5307de 2021-07-27 op mark_nonblock(int fd)
176 9d5307de 2021-07-27 op if ((flags = fcntl(fd, F_GETFL)) == -1)
177 9d5307de 2021-07-27 op fatal("fcntl(F_GETFL)");
178 9d5307de 2021-07-27 op if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
179 9d5307de 2021-07-27 op fatal("fcntl(F_SETFL)");
183 27909800 2021-07-26 op tls_readcb(int fd, short event, void *d)
185 27909800 2021-07-26 op struct bufferevent *bufev = d;
186 27909800 2021-07-26 op char buf[IBUF_READ_SIZE];
187 27909800 2021-07-26 op int what = EVBUFFER_READ;
188 27909800 2021-07-26 op int howmuch = IBUF_READ_SIZE;
192 27909800 2021-07-26 op if (event == EV_TIMEOUT) {
193 27909800 2021-07-26 op what |= EVBUFFER_TIMEOUT;
197 27909800 2021-07-26 op if (bufev->wm_read.high != 0)
198 27909800 2021-07-26 op howmuch = MIN(sizeof(buf), bufev->wm_read.high);
200 27909800 2021-07-26 op switch (ret = tls_read(ctx, buf, howmuch)) {
201 27909800 2021-07-26 op case TLS_WANT_POLLIN:
202 27909800 2021-07-26 op case TLS_WANT_POLLOUT:
205 27909800 2021-07-26 op what |= EVBUFFER_ERROR;
210 27909800 2021-07-26 op if (len == 0) {
211 27909800 2021-07-26 op what |= EVBUFFER_EOF;
215 27909800 2021-07-26 op if (evbuffer_add(bufev->input, buf, len) == -1) {
216 27909800 2021-07-26 op what |= EVBUFFER_ERROR;
220 27909800 2021-07-26 op event_add(&bufev->ev_read, NULL);
222 27909800 2021-07-26 op len = EVBUFFER_LENGTH(bufev->input);
223 27909800 2021-07-26 op if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
225 27909800 2021-07-26 op if (bufev->readcb != NULL)
226 27909800 2021-07-26 op (*bufev->readcb)(bufev, bufev->cbarg);
230 27909800 2021-07-26 op event_add(&bufev->ev_read, NULL);
234 27909800 2021-07-26 op (*bufev->errorcb)(bufev, what, bufev->cbarg);
238 27909800 2021-07-26 op tls_writecb(int fd, short event, void *d)
240 27909800 2021-07-26 op struct bufferevent *bufev = d;
243 27909800 2021-07-26 op short what = EVBUFFER_WRITE;
246 27909800 2021-07-26 op if (event == EV_TIMEOUT) {
247 27909800 2021-07-26 op what |= EVBUFFER_TIMEOUT;
251 9991b526 2021-08-01 op len = EVBUFFER_LENGTH(bufev->output);
252 9991b526 2021-08-01 op if (len != 0) {
253 9991b526 2021-08-01 op data = EVBUFFER_DATA(bufev->output);
255 9991b526 2021-08-01 op #if DEBUG_PACKETS
256 9991b526 2021-08-01 op hexdump("outgoing msg", data, len);
259 9991b526 2021-08-01 op switch (ret = tls_write(ctx, data, len)) {
260 27909800 2021-07-26 op case TLS_WANT_POLLIN:
261 27909800 2021-07-26 op case TLS_WANT_POLLOUT:
264 27909800 2021-07-26 op what |= EVBUFFER_ERROR;
267 27909800 2021-07-26 op evbuffer_drain(bufev->output, ret);
270 27909800 2021-07-26 op if (EVBUFFER_LENGTH(bufev->output) != 0)
271 27909800 2021-07-26 op event_add(&bufev->ev_write, NULL);
273 27909800 2021-07-26 op if (bufev->writecb != NULL &&
274 27909800 2021-07-26 op EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low)
275 27909800 2021-07-26 op (*bufev->writecb)(bufev, bufev->cbarg);
279 27909800 2021-07-26 op event_add(&bufev->ev_write, NULL);
282 27909800 2021-07-26 op (*bufev->errorcb)(bufev, what, bufev->cbarg);
286 9991b526 2021-08-01 op client_read(struct bufferevent *bev, void *d)
288 27909800 2021-07-26 op struct evbuffer *src = EVBUFFER_INPUT(bev);
289 27909800 2021-07-26 op uint32_t len;
290 9991b526 2021-08-01 op uint8_t *data;
293 ba4a37ea 2021-07-28 op if (EVBUFFER_LENGTH(src) < sizeof(len))
296 9991b526 2021-08-01 op data = EVBUFFER_DATA(src);
298 9991b526 2021-08-01 op memcpy(&len, data, sizeof(len));
299 27909800 2021-07-26 op len = le32toh(len);
301 c26e4201 2021-08-01 op if (len < HEADERSIZE)
302 c26e4201 2021-08-01 op fatal("incoming message is too small! (%d bytes)",
305 27909800 2021-07-26 op if (len > EVBUFFER_LENGTH(src))
308 9991b526 2021-08-01 op #if DEBUG_PACKETS
309 9991b526 2021-08-01 op hexdump("incoming msg", data, len);
312 9991b526 2021-08-01 op handle_9p(data, len);
313 27909800 2021-07-26 op evbuffer_drain(src, len);
318 27909800 2021-07-26 op client_write(struct bufferevent *bev, void *data)
320 27909800 2021-07-26 op return; /* nothing to do */
324 27909800 2021-07-26 op client_error(struct bufferevent *bev, short err, void *data)
326 27909800 2021-07-26 op if (err & EVBUFFER_ERROR)
327 27909800 2021-07-26 op fatal("buffer event error");
329 27909800 2021-07-26 op if (err & EVBUFFER_EOF) {
331 27909800 2021-07-26 op log_info("EOF");
332 27909800 2021-07-26 op event_loopbreak();
337 27909800 2021-07-26 op log_warnx("unknown event error");
338 27909800 2021-07-26 op event_loopbreak();
342 9d5307de 2021-07-27 op repl_read(struct bufferevent *bev, void *d)
346 9d5307de 2021-07-27 op const char *argv[10], **ap;
349 9d5307de 2021-07-27 op line = evbuffer_readln(bev->input, &len, EVBUFFER_EOL_LF);
350 9d5307de 2021-07-27 op if (line == NULL)
353 9d5307de 2021-07-27 op for (argc = 0, ap = argv; ap < &argv[9] &&
354 9d5307de 2021-07-27 op (*ap = strsep(&line, " \t")) != NULL;) {
355 9d5307de 2021-07-27 op if (**ap != '\0')
356 9d5307de 2021-07-27 op ap++, argc++;
360 9d5307de 2021-07-27 op excmd(argv, argc);
367 9d5307de 2021-07-27 op repl_error(struct bufferevent *bev, short error, void *d)
369 9d5307de 2021-07-27 op fatalx("an error occurred");
373 de678634 2021-07-28 op write_hdr(uint32_t len, uint8_t type, uint16_t tag)
375 3d28d0a7 2021-07-29 op len += HEADERSIZE;
377 de678634 2021-07-28 op log_debug("enqueuing a packet; len=%"PRIu32" type=%d[%s] tag=%d",
378 de678634 2021-07-28 op len, type, pp_msg_type(type), tag);
380 de678634 2021-07-28 op len = htole32(len);
381 9d5307de 2021-07-27 op /* type is one byte, no endiannes issues */
382 de678634 2021-07-28 op tag = htole16(tag);
384 de678634 2021-07-28 op bufferevent_write(bev, &len, sizeof(len));
385 de678634 2021-07-28 op bufferevent_write(bev, &type, sizeof(type));
386 de678634 2021-07-28 op bufferevent_write(bev, &tag, sizeof(tag));
390 ed61de84 2021-07-30 op write_hdr_auto(uint32_t len, uint8_t type)
392 ed61de84 2021-07-30 op static uint16_t tag = 0;
394 ed61de84 2021-07-30 op if (++tag == NOTAG)
397 ed61de84 2021-07-30 op write_hdr(len, type, tag);
401 de678634 2021-07-28 op write_str(uint16_t len, const char *str)
403 2bf43d27 2021-07-28 op uint16_t l = len;
405 de678634 2021-07-28 op len = htole16(len);
406 de678634 2021-07-28 op bufferevent_write(bev, &len, sizeof(len));
407 2bf43d27 2021-07-28 op bufferevent_write(bev, str, l);
411 29bc9fe5 2021-08-01 op write_str_auto(const char *str)
413 29bc9fe5 2021-08-01 op write_str(strlen(str), str);
417 6c3acfa1 2021-07-29 op write_fid(uint32_t fid)
419 6c3acfa1 2021-07-29 op fid = htole32(fid);
420 6c3acfa1 2021-07-29 op bufferevent_write(bev, &fid, sizeof(fid));
424 5ed7f718 2021-07-30 op write_tag(uint16_t tag)
426 5ed7f718 2021-07-30 op tag = htole16(tag);
427 5ed7f718 2021-07-30 op bufferevent_write(bev, &tag, sizeof(tag));
430 afaad60e 2021-07-29 op /* version [version-str] */
432 afaad60e 2021-07-29 op excmd_version(const char **argv, int argc)
434 afaad60e 2021-07-29 op uint32_t len, msize;
436 afaad60e 2021-07-29 op const char *s;
438 afaad60e 2021-07-29 op s = VERSION9P;
439 afaad60e 2021-07-29 op if (argc == 2)
442 afaad60e 2021-07-29 op sl = strlen(s);
444 afaad60e 2021-07-29 op /* msize[4] version[s] */
445 afaad60e 2021-07-29 op len = 4 + sizeof(sl) + sl;
446 afaad60e 2021-07-29 op write_hdr(len, Tversion, NOTAG);
448 afaad60e 2021-07-29 op msize = htole32(MSIZE9P);
449 afaad60e 2021-07-29 op bufferevent_write(bev, &msize, sizeof(msize));
451 afaad60e 2021-07-29 op write_str(sl, s);
454 afaad60e 2021-07-29 op /* attach fid uname aname */
456 afaad60e 2021-07-29 op excmd_attach(const char **argv, int argc)
458 9cb5f957 2021-07-29 op uint32_t len, fid;
459 9cb5f957 2021-07-29 op uint16_t sl, tl;
460 9cb5f957 2021-07-29 op const char *s, *t, *errstr;
462 afaad60e 2021-07-29 op if (argc != 4)
465 afaad60e 2021-07-29 op fid = strtonum(argv[1], 0, UINT32_MAX, &errstr);
466 afaad60e 2021-07-29 op if (errstr != NULL) {
467 afaad60e 2021-07-29 op log_warnx("fid is %s: %s", errstr, argv[1]);
472 afaad60e 2021-07-29 op sl = strlen(s);
474 afaad60e 2021-07-29 op tl = strlen(t);
476 afaad60e 2021-07-29 op /* fid[4] afid[4] uname[s] aname[s] */
477 afaad60e 2021-07-29 op len = 4 + 4 + sizeof(sl) + sl + sizeof(tl) + tl;
478 ed61de84 2021-07-30 op write_hdr_auto(len, Tattach);
479 afaad60e 2021-07-29 op write_fid(fid);
480 afaad60e 2021-07-29 op write_fid(NOFID);
481 afaad60e 2021-07-29 op write_str(sl, s);
482 afaad60e 2021-07-29 op write_str(tl, t);
487 afaad60e 2021-07-29 op log_warnx("usage: attach fid uname aname");
490 25359fc4 2021-07-30 op /* clunk fid */
492 25359fc4 2021-07-30 op excmd_clunk(const char **argv, int argc)
494 25359fc4 2021-07-30 op uint32_t len, fid;
495 25359fc4 2021-07-30 op const char *errstr;
497 25359fc4 2021-07-30 op if (argc != 2)
500 25359fc4 2021-07-30 op fid = strtonum(argv[1], 0, UINT32_MAX, &errstr);
501 25359fc4 2021-07-30 op if (errstr != NULL) {
502 25359fc4 2021-07-30 op log_warnx("fid is %s: %s", errstr, argv[1]);
507 25359fc4 2021-07-30 op len = sizeof(fid);
508 25359fc4 2021-07-30 op write_hdr_auto(len, Tclunk);
509 25359fc4 2021-07-30 op write_fid(fid);
513 25359fc4 2021-07-30 op log_warnx("usage: clunk fid");
516 5ed7f718 2021-07-30 op /* flush oldtag */
518 5ed7f718 2021-07-30 op excmd_flush(const char **argv, int argc)
520 5ed7f718 2021-07-30 op uint32_t len;
521 5ed7f718 2021-07-30 op uint16_t oldtag;
522 5ed7f718 2021-07-30 op const char *errstr;
524 5ed7f718 2021-07-30 op if (argc != 2)
527 5ed7f718 2021-07-30 op oldtag = strtonum(argv[1], 0, UINT16_MAX, &errstr);
528 5ed7f718 2021-07-30 op if (errstr != NULL) {
529 5ed7f718 2021-07-30 op log_warnx("oldtag is %s: %s", errstr, argv[1]);
533 5ed7f718 2021-07-30 op /* oldtag[2] */
534 5ed7f718 2021-07-30 op len = sizeof(oldtag);
535 5ed7f718 2021-07-30 op write_hdr_auto(len, Tflush);
536 5ed7f718 2021-07-30 op write_tag(oldtag);
540 5ed7f718 2021-07-30 op log_warnx("usage: flush oldtag");
543 29bc9fe5 2021-08-01 op /* walk fid newfid wnames... */
545 29bc9fe5 2021-08-01 op excmd_walk(const char **argv, int argc)
548 e8774f89 2021-08-01 op uint32_t len, fid, newfid;
549 29bc9fe5 2021-08-01 op const char *errstr;
551 29bc9fe5 2021-08-01 op if (argc < 3)
554 29bc9fe5 2021-08-01 op /* fid[4] newfid[4] nwname[2] nwname*(wname[s]) */
556 29bc9fe5 2021-08-01 op /* two bytes for wnames count */
557 29bc9fe5 2021-08-01 op len = sizeof(fid) + sizeof(newfid) + 2;
558 29bc9fe5 2021-08-01 op for (i = 3; i < argc; ++i)
559 29bc9fe5 2021-08-01 op len += 2 + strlen(argv[i]);
561 29bc9fe5 2021-08-01 op fid = strtonum(argv[1], 0, UINT32_MAX, &errstr);
562 29bc9fe5 2021-08-01 op if (errstr != NULL) {
563 29bc9fe5 2021-08-01 op log_warnx("fid is %s: %s", errstr, argv[1]);
567 29bc9fe5 2021-08-01 op newfid = strtonum(argv[2], 0, UINT32_MAX, &errstr);
568 29bc9fe5 2021-08-01 op if (errstr != NULL) {
569 29bc9fe5 2021-08-01 op log_warnx("newfid is %s: %s", errstr, argv[1]);
573 29bc9fe5 2021-08-01 op write_hdr_auto(len, Twalk);
574 29bc9fe5 2021-08-01 op write_fid(fid);
575 29bc9fe5 2021-08-01 op write_fid(newfid);
576 29bc9fe5 2021-08-01 op write_tag(argc - 3);
577 29bc9fe5 2021-08-01 op for (i = 3; i < argc; ++i)
578 29bc9fe5 2021-08-01 op write_str_auto(argv[i]);
583 29bc9fe5 2021-08-01 op log_warnx("usage: walk fid newfid wnames...");
587 afaad60e 2021-07-29 op excmd(const char **argv, int argc)
590 afaad60e 2021-07-29 op const char *name;
591 afaad60e 2021-07-29 op void (*fn)(const char **, int);
593 6b93b2b7 2021-07-29 op {"version", excmd_version},
594 6b93b2b7 2021-07-29 op {"attach", excmd_attach},
595 25359fc4 2021-07-30 op {"clunk", excmd_clunk},
596 5ed7f718 2021-07-30 op {"flush", excmd_flush},
597 29bc9fe5 2021-08-01 op {"walk", excmd_walk},
601 a8802990 2021-07-30 op if (argc == 0)
604 afaad60e 2021-07-29 op for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i) {
605 afaad60e 2021-07-29 op if (!strcmp(cmds[i].name, argv[0])) {
606 afaad60e 2021-07-29 op cmds[i].fn(argv, argc);
611 afaad60e 2021-07-29 op log_warnx("Unknown command %s", *argv);
614 9cb5f957 2021-07-29 op static const char *
615 9cb5f957 2021-07-29 op pp_qid_type(uint8_t type)
617 9cb5f957 2021-07-29 op switch (type) {
618 6b93b2b7 2021-07-29 op case QTDIR: return "dir";
619 6b93b2b7 2021-07-29 op case QTAPPEND: return "append-only";
620 6b93b2b7 2021-07-29 op case QTEXCL: return "exclusive";
621 6b93b2b7 2021-07-29 op case QTMOUNT: return "mounted-channel";
622 6b93b2b7 2021-07-29 op case QTAUTH: return "authentication";
623 6b93b2b7 2021-07-29 op case QTTMP: return "non-backed-up";
624 9cb5f957 2021-07-29 op case QTSYMLINK: return "symlink";
625 6b93b2b7 2021-07-29 op case QTFILE: return "file";
628 9cb5f957 2021-07-29 op return "unknown";
632 9cb5f957 2021-07-29 op pp_qid(const uint8_t *d, uint32_t len)
634 9cb5f957 2021-07-29 op uint64_t path;
635 9cb5f957 2021-07-29 op uint32_t vers;
636 9cb5f957 2021-07-29 op uint8_t type;
638 9cb5f957 2021-07-29 op if (len < 13) {
639 9cb5f957 2021-07-29 op printf("invalid");
645 9cb5f957 2021-07-29 op memcpy(&vers, d, sizeof(vers));
646 9cb5f957 2021-07-29 op d += sizeof(vers);
647 4fa53a98 2021-07-29 op vers = le64toh(vers);
649 d28f26db 2021-07-31 op memcpy(&path, d, sizeof(path));
650 d28f26db 2021-07-31 op d += sizeof(path);
651 d28f26db 2021-07-31 op path = le64toh(path);
653 787867cb 2021-07-30 op printf("qid{path=%"PRIu64" version=%"PRIu32" type=0x%x\"%s\"}",
654 9cb5f957 2021-07-29 op path, vers, type, pp_qid_type(type));
658 ff3a2c18 2021-07-29 op pp_msg(uint32_t len, uint8_t type, uint16_t tag, const uint8_t *d)
660 ff3a2c18 2021-07-29 op uint32_t msize;
661 ff3a2c18 2021-07-29 op uint16_t slen;
663 ff3a2c18 2021-07-29 op printf("len=%"PRIu32" type=%d[%s] tag=0x%x[%d] ", len,
664 ff3a2c18 2021-07-29 op type, pp_msg_type(type), tag, tag);
666 ff3a2c18 2021-07-29 op len -= HEADERSIZE;
668 ff3a2c18 2021-07-29 op switch (type) {
669 ff3a2c18 2021-07-29 op case Rversion:
670 ff3a2c18 2021-07-29 op if (len < 6) {
671 ff3a2c18 2021-07-29 op printf("invalid: not enough space for msize "
672 ff3a2c18 2021-07-29 op "and version provided.");
676 ff3a2c18 2021-07-29 op memcpy(&msize, d, sizeof(msize));
677 ff3a2c18 2021-07-29 op d += sizeof(msize);
678 ff3a2c18 2021-07-29 op len -= sizeof(msize);
679 ff3a2c18 2021-07-29 op msize = le32toh(msize);
681 ff3a2c18 2021-07-29 op memcpy(&slen, d, sizeof(slen));
682 ff3a2c18 2021-07-29 op d += sizeof(slen);
683 ff3a2c18 2021-07-29 op len -= sizeof(slen);
684 0a4b3ca8 2021-07-30 op slen = le16toh(slen);
686 ff3a2c18 2021-07-29 op if (len != slen) {
687 ff3a2c18 2021-07-29 op printf("invalid: version string length doesn't "
688 ff3a2c18 2021-07-29 op "match. Got %d; want %d", slen, len);
692 ff3a2c18 2021-07-29 op printf("msize=%"PRIu32" version[%"PRIu16"]=\"",
693 ff3a2c18 2021-07-29 op msize, slen);
694 ff3a2c18 2021-07-29 op fwrite(d, 1, slen, stdout);
695 ff3a2c18 2021-07-29 op printf("\"");
699 9cb5f957 2021-07-29 op case Rattach:
700 9cb5f957 2021-07-29 op pp_qid(d, len);
704 25359fc4 2021-07-30 op if (len != 0)
705 25359fc4 2021-07-30 op printf("invalid Rclunk: %"PRIu32" extra bytes", len);
709 5ed7f718 2021-07-30 op if (len != 0)
710 5ed7f718 2021-07-30 op printf("invalid Rflush: %"PRIu32" extra bytes", len);
714 ef44416c 2021-08-01 op if (len < 2) {
715 ef44416c 2021-08-01 op printf("invaild Rwalk: less than two bytes (%d)",
720 ef44416c 2021-08-01 op memcpy(&slen, d, sizeof(slen));
721 ef44416c 2021-08-01 op d += sizeof(slen);
722 ef44416c 2021-08-01 op len -= sizeof(slen);
723 ef44416c 2021-08-01 op slen = le16toh(slen);
725 ef44416c 2021-08-01 op if (len != QIDSIZE * slen) {
726 ef44416c 2021-08-01 op printf("invalid Rwalk: wanted %d bytes for %d qids "
727 ef44416c 2021-08-01 op "but got %"PRIu32" bytes instead",
728 ef44416c 2021-08-01 op QIDSIZE*slen, slen, len);
732 ef44416c 2021-08-01 op printf("nwqid=%"PRIu16, slen);
734 ef44416c 2021-08-01 op for (; slen != 0; slen--) {
736 ef44416c 2021-08-01 op pp_qid(d, len);
737 ef44416c 2021-08-01 op d += QIDSIZE;
738 ef44416c 2021-08-01 op len -= QIDSIZE;
744 8e504ac0 2021-07-30 op memcpy(&slen, d, sizeof(slen));
745 8e504ac0 2021-07-30 op d += sizeof(slen);
746 8e504ac0 2021-07-30 op len -= sizeof(slen);
747 8e504ac0 2021-07-30 op slen = le16toh(slen);
749 8e504ac0 2021-07-30 op if (slen != len) {
750 8e504ac0 2021-07-30 op printf("invalid: error string length doesn't "
751 8e504ac0 2021-07-30 op "match. Got %d; want %d", slen, len);
755 8e504ac0 2021-07-30 op printf("error=\"");
756 8e504ac0 2021-07-30 op fwrite(d, 1, slen, stdout);
757 8e504ac0 2021-07-30 op printf("\"");
762 2ba6253c 2021-07-29 op printf("unknown command type");
765 ff3a2c18 2021-07-29 op printf("\n");
769 de16f136 2021-07-28 op handle_9p(const uint8_t *data, size_t size)
771 de16f136 2021-07-28 op uint32_t len;
772 de16f136 2021-07-28 op uint16_t tag;
773 de16f136 2021-07-28 op uint8_t type;
775 de16f136 2021-07-28 op assert(size >= HEADERSIZE);
777 de16f136 2021-07-28 op memcpy(&len, data, sizeof(len));
778 de16f136 2021-07-28 op data += sizeof(len);
780 de16f136 2021-07-28 op memcpy(&type, data, sizeof(type));
781 de16f136 2021-07-28 op data += sizeof(type);
783 de16f136 2021-07-28 op memcpy(&tag, data, sizeof(tag));
784 de16f136 2021-07-28 op data += sizeof(tag);
786 de16f136 2021-07-28 op len = le32toh(len);
787 27909800 2021-07-26 op /* type is one byte long, no endianness issues */
788 de16f136 2021-07-28 op tag = le16toh(tag);
791 ff3a2c18 2021-07-29 op pp_msg(len, type, tag, data);
798 5c57fb10 2021-07-26 op printf("\r");
799 5c57fb10 2021-07-26 op fflush(stdout);
805 27909800 2021-07-26 op printf("%s", PROMPT);
806 27909800 2021-07-26 op fflush(stdout);
810 27909800 2021-07-26 op main(int argc, char **argv)
812 9d5307de 2021-07-27 op int ch, sock, handshake;
813 9d5307de 2021-07-27 op struct event ev_sigint, ev_sigterm;
815 27909800 2021-07-26 op signal(SIGPIPE, SIG_IGN);
817 27909800 2021-07-26 op while ((ch = getopt(argc, argv, "C:cH:hK:P:v")) != -1) {
818 27909800 2021-07-26 op switch (ch) {
820 27909800 2021-07-26 op crtpath = optarg;
826 27909800 2021-07-26 op host = optarg;
832 27909800 2021-07-26 op keypath = optarg;
835 27909800 2021-07-26 op port = optarg;
845 27909800 2021-07-26 op if (host == NULL)
846 27909800 2021-07-26 op host = "localhost";
847 27909800 2021-07-26 op if (port == NULL)
848 27909800 2021-07-26 op port = "1337";
850 27909800 2021-07-26 op argc -= optind;
851 27909800 2021-07-26 op argv += optind;
853 27909800 2021-07-26 op if (argc != 0)
855 27909800 2021-07-26 op /* if (!tls || (crtpath != NULL || keypath != NULL)) */
856 27909800 2021-07-26 op /* usage(1); */
858 27909800 2021-07-26 op errx(1, "must enable tls (for now)");
860 27909800 2021-07-26 op log_init(1, LOG_DAEMON);
861 27909800 2021-07-26 op log_setverbose(verbose);
862 27909800 2021-07-26 op log_procinit(getprogname());
864 27909800 2021-07-26 op if ((tlsconf = tls_config_new()) == NULL)
865 27909800 2021-07-26 op fatalx("tls_config_new");
866 27909800 2021-07-26 op tls_config_insecure_noverifycert(tlsconf);
867 27909800 2021-07-26 op tls_config_insecure_noverifyname(tlsconf);
868 27909800 2021-07-26 op if (tls_config_set_keypair_file(tlsconf, crtpath, keypath) == -1)
869 27909800 2021-07-26 op fatalx("can't load certs (%s, %s)", crtpath, keypath);
871 27909800 2021-07-26 op if ((ctx = tls_client()) == NULL)
872 27909800 2021-07-26 op fatal("tls_client");
873 27909800 2021-07-26 op if (tls_configure(ctx, tlsconf) == -1)
874 27909800 2021-07-26 op fatalx("tls_configure: %s", tls_error(ctx));
876 27909800 2021-07-26 op log_info("connecting to %s:%s...", host, port);
878 27909800 2021-07-26 op if ((sock = openconn()) == -1)
879 27909800 2021-07-26 op fatalx("can't connect to %s:%s", host, port);
881 27909800 2021-07-26 op if (tls_connect_socket(ctx, sock, host) == -1)
882 27909800 2021-07-26 op fatalx("tls_connect_socket: %s", tls_error(ctx));
884 27909800 2021-07-26 op for (handshake = 0; !handshake;) {
885 27909800 2021-07-26 op switch (tls_handshake(ctx)) {
887 27909800 2021-07-26 op fatalx("tls_handshake: %s", tls_error(ctx));
889 27909800 2021-07-26 op handshake = 1;
894 27909800 2021-07-26 op log_info("connected!");
896 9d5307de 2021-07-27 op mark_nonblock(sock);
898 27909800 2021-07-26 op event_init();
900 27909800 2021-07-26 op signal_set(&ev_sigint, SIGINT, sig_handler, NULL);
901 27909800 2021-07-26 op signal_set(&ev_sigterm, SIGINT, sig_handler, NULL);
903 27909800 2021-07-26 op signal_add(&ev_sigint, NULL);
904 27909800 2021-07-26 op signal_add(&ev_sigterm, NULL);
906 27909800 2021-07-26 op bev = bufferevent_new(sock, client_read, client_write, client_error,
908 27909800 2021-07-26 op if (bev == NULL)
909 27909800 2021-07-26 op fatal("bufferevent_new");
911 27909800 2021-07-26 op /* setup tls/io */
912 27909800 2021-07-26 op event_set(&bev->ev_read, sock, EV_READ, tls_readcb, bev);
913 27909800 2021-07-26 op event_set(&bev->ev_write, sock, EV_WRITE, tls_writecb, bev);
915 27909800 2021-07-26 op bufferevent_enable(bev, EV_READ|EV_WRITE);
917 9d5307de 2021-07-27 op mark_nonblock(0);
918 9d5307de 2021-07-27 op inbev = bufferevent_new(0, repl_read, NULL, repl_error, NULL);
919 9d5307de 2021-07-27 op bufferevent_enable(inbev, EV_READ);
922 27909800 2021-07-26 op event_dispatch();
924 27909800 2021-07-26 op bufferevent_free(bev);
925 27909800 2021-07-26 op tls_free(ctx);
926 27909800 2021-07-26 op tls_config_free(tlsconf);