Blame


1 27909800 2021-07-26 op /*
2 27909800 2021-07-26 op * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 27909800 2021-07-26 op *
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.
7 27909800 2021-07-26 op *
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.
15 27909800 2021-07-26 op */
16 27909800 2021-07-26 op
17 27909800 2021-07-26 op #include "compat.h"
18 27909800 2021-07-26 op
19 27909800 2021-07-26 op #include <sys/types.h>
20 27909800 2021-07-26 op #include <sys/socket.h>
21 27909800 2021-07-26 op
22 27909800 2021-07-26 op #include <netdb.h>
23 27909800 2021-07-26 op
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>
36 27909800 2021-07-26 op
37 4e83b30f 2021-12-14 op #include "9pclib.h"
38 27909800 2021-07-26 op #include "kamid.h"
39 27909800 2021-07-26 op #include "log.h"
40 27909800 2021-07-26 op #include "utils.h"
41 27909800 2021-07-26 op
42 9991b526 2021-08-01 op #define DEBUG_PACKETS 0
43 9991b526 2021-08-01 op
44 01d4b7a4 2021-07-29 op #define PROMPT "=% "
45 27909800 2021-07-26 op
46 27909800 2021-07-26 op /* flags */
47 27909800 2021-07-26 op int verbose;
48 27909800 2021-07-26 op int tls;
49 27909800 2021-07-26 op const char *keypath;
50 27909800 2021-07-26 op const char *crtpath;
51 27909800 2021-07-26 op const char *host;
52 27909800 2021-07-26 op const char *port;
53 27909800 2021-07-26 op
54 27909800 2021-07-26 op /* state */
55 27909800 2021-07-26 op struct tls_config *tlsconf;
56 27909800 2021-07-26 op struct tls *ctx;
57 9d5307de 2021-07-27 op struct bufferevent *bev, *inbev;
58 27909800 2021-07-26 op
59 27909800 2021-07-26 op static void ATTR_DEAD usage(int);
60 27909800 2021-07-26 op
61 27909800 2021-07-26 op static void sig_handler(int, short, void *);
62 27909800 2021-07-26 op
63 27909800 2021-07-26 op static int openconn(void);
64 9d5307de 2021-07-27 op static void mark_nonblock(int);
65 27909800 2021-07-26 op
66 27909800 2021-07-26 op static void tls_readcb(int, short, void *);
67 27909800 2021-07-26 op static void tls_writecb(int, short, void *);
68 27909800 2021-07-26 op
69 27909800 2021-07-26 op static void client_read(struct bufferevent *, void *);
70 27909800 2021-07-26 op static void client_write(struct bufferevent *, void *);
71 27909800 2021-07-26 op static void client_error(struct bufferevent *, short, void *);
72 27909800 2021-07-26 op
73 9d5307de 2021-07-27 op static void repl_read(struct bufferevent *, void *);
74 9d5307de 2021-07-27 op static void repl_error(struct bufferevent *, short, void *);
75 afaad60e 2021-07-29 op
76 afaad60e 2021-07-29 op static void excmd_version(const char **, int);
77 afaad60e 2021-07-29 op static void excmd_attach(const char **, int);
78 25359fc4 2021-07-30 op static void excmd_clunk(const char **, int);
79 5ed7f718 2021-07-30 op static void excmd_flush(const char **, int);
80 29bc9fe5 2021-08-01 op static void excmd_walk(const char ** , int);
81 f16f7555 2021-12-15 op static void excmd_open(const char ** , int);
82 f16f7555 2021-12-15 op static void excmd_read(const char ** , int);
83 9d5307de 2021-07-27 op static void excmd(const char **, int);
84 27909800 2021-07-26 op
85 9cb5f957 2021-07-29 op static const char *pp_qid_type(uint8_t);
86 9cb5f957 2021-07-29 op static void pp_qid(const uint8_t *, uint32_t);
87 ff3a2c18 2021-07-29 op static void pp_msg(uint32_t, uint8_t, uint16_t, const uint8_t *);
88 de678634 2021-07-28 op static void handle_9p(const uint8_t *, size_t);
89 5c57fb10 2021-07-26 op static void clr(void);
90 27909800 2021-07-26 op static void prompt(void);
91 27909800 2021-07-26 op
92 27909800 2021-07-26 op static void ATTR_DEAD
93 27909800 2021-07-26 op usage(int ret)
94 27909800 2021-07-26 op {
95 27909800 2021-07-26 op fprintf(stderr,
96 27909800 2021-07-26 op "usage: %s [-chv] [-C crt] [-K key] [-H host] [-P port]\n",
97 27909800 2021-07-26 op getprogname());
98 27909800 2021-07-26 op fprintf(stderr, PACKAGE_NAME " suite version " PACKAGE_VERSION "\n");
99 27909800 2021-07-26 op exit(ret);
100 27909800 2021-07-26 op }
101 27909800 2021-07-26 op
102 27909800 2021-07-26 op static void
103 27909800 2021-07-26 op sig_handler(int sig, short event, void *d)
104 27909800 2021-07-26 op {
105 27909800 2021-07-26 op /*
106 27909800 2021-07-26 op * Normal signal handler rules don't apply because libevent
107 27909800 2021-07-26 op * decouples for us.
108 27909800 2021-07-26 op */
109 27909800 2021-07-26 op
110 27909800 2021-07-26 op switch (sig) {
111 27909800 2021-07-26 op case SIGINT:
112 27909800 2021-07-26 op case SIGTERM:
113 5c57fb10 2021-07-26 op clr();
114 5c57fb10 2021-07-26 op log_warnx("Shutting down...");
115 27909800 2021-07-26 op event_loopbreak();
116 27909800 2021-07-26 op return;
117 27909800 2021-07-26 op default:
118 27909800 2021-07-26 op fatalx("unexpected signal %d", sig);
119 27909800 2021-07-26 op }
120 27909800 2021-07-26 op }
121 27909800 2021-07-26 op
122 27909800 2021-07-26 op static int
123 27909800 2021-07-26 op openconn(void)
124 27909800 2021-07-26 op {
125 27909800 2021-07-26 op struct addrinfo hints, *res, *res0;
126 27909800 2021-07-26 op int error;
127 27909800 2021-07-26 op int save_errno;
128 27909800 2021-07-26 op int s;
129 27909800 2021-07-26 op const char *cause = NULL;
130 27909800 2021-07-26 op
131 27909800 2021-07-26 op memset(&hints, 0, sizeof(hints));
132 27909800 2021-07-26 op hints.ai_family = AF_UNSPEC;
133 27909800 2021-07-26 op hints.ai_socktype = SOCK_STREAM;
134 27909800 2021-07-26 op if ((error = getaddrinfo(host, port, &hints, &res0))) {
135 27909800 2021-07-26 op warnx("%s", gai_strerror(error));
136 27909800 2021-07-26 op return -1;
137 27909800 2021-07-26 op }
138 27909800 2021-07-26 op
139 27909800 2021-07-26 op s = -1;
140 27909800 2021-07-26 op for (res = res0; res; res = res->ai_next) {
141 27909800 2021-07-26 op s = socket(res->ai_family, res->ai_socktype,
142 27909800 2021-07-26 op res->ai_protocol);
143 27909800 2021-07-26 op if (s == -1) {
144 27909800 2021-07-26 op cause = "socket";
145 27909800 2021-07-26 op continue;
146 27909800 2021-07-26 op }
147 27909800 2021-07-26 op
148 27909800 2021-07-26 op if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
149 27909800 2021-07-26 op cause = "connect";
150 27909800 2021-07-26 op save_errno = errno;
151 27909800 2021-07-26 op close(s);
152 27909800 2021-07-26 op errno = save_errno;
153 27909800 2021-07-26 op s = -1;
154 27909800 2021-07-26 op continue;
155 27909800 2021-07-26 op }
156 27909800 2021-07-26 op
157 27909800 2021-07-26 op break;
158 27909800 2021-07-26 op }
159 27909800 2021-07-26 op
160 27909800 2021-07-26 op freeaddrinfo(res0);
161 27909800 2021-07-26 op
162 27909800 2021-07-26 op if (s == -1)
163 27909800 2021-07-26 op warn("%s", cause);
164 27909800 2021-07-26 op
165 27909800 2021-07-26 op return s;
166 9d5307de 2021-07-27 op }
167 9d5307de 2021-07-27 op
168 9d5307de 2021-07-27 op static void
169 9d5307de 2021-07-27 op mark_nonblock(int fd)
170 9d5307de 2021-07-27 op {
171 9d5307de 2021-07-27 op int flags;
172 9d5307de 2021-07-27 op
173 9d5307de 2021-07-27 op if ((flags = fcntl(fd, F_GETFL)) == -1)
174 9d5307de 2021-07-27 op fatal("fcntl(F_GETFL)");
175 9d5307de 2021-07-27 op if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
176 9d5307de 2021-07-27 op fatal("fcntl(F_SETFL)");
177 27909800 2021-07-26 op }
178 27909800 2021-07-26 op
179 27909800 2021-07-26 op static void
180 27909800 2021-07-26 op tls_readcb(int fd, short event, void *d)
181 27909800 2021-07-26 op {
182 27909800 2021-07-26 op struct bufferevent *bufev = d;
183 27909800 2021-07-26 op char buf[IBUF_READ_SIZE];
184 27909800 2021-07-26 op int what = EVBUFFER_READ;
185 27909800 2021-07-26 op int howmuch = IBUF_READ_SIZE;
186 27909800 2021-07-26 op ssize_t ret;
187 27909800 2021-07-26 op size_t len;
188 27909800 2021-07-26 op
189 27909800 2021-07-26 op if (event == EV_TIMEOUT) {
190 27909800 2021-07-26 op what |= EVBUFFER_TIMEOUT;
191 27909800 2021-07-26 op goto err;
192 27909800 2021-07-26 op }
193 27909800 2021-07-26 op
194 27909800 2021-07-26 op if (bufev->wm_read.high != 0)
195 27909800 2021-07-26 op howmuch = MIN(sizeof(buf), bufev->wm_read.high);
196 27909800 2021-07-26 op
197 27909800 2021-07-26 op switch (ret = tls_read(ctx, buf, howmuch)) {
198 27909800 2021-07-26 op case TLS_WANT_POLLIN:
199 27909800 2021-07-26 op case TLS_WANT_POLLOUT:
200 27909800 2021-07-26 op goto retry;
201 27909800 2021-07-26 op case -1:
202 27909800 2021-07-26 op what |= EVBUFFER_ERROR;
203 27909800 2021-07-26 op goto err;
204 27909800 2021-07-26 op }
205 27909800 2021-07-26 op len = ret;
206 27909800 2021-07-26 op
207 27909800 2021-07-26 op if (len == 0) {
208 27909800 2021-07-26 op what |= EVBUFFER_EOF;
209 27909800 2021-07-26 op goto err;
210 27909800 2021-07-26 op }
211 27909800 2021-07-26 op
212 27909800 2021-07-26 op if (evbuffer_add(bufev->input, buf, len) == -1) {
213 27909800 2021-07-26 op what |= EVBUFFER_ERROR;
214 27909800 2021-07-26 op goto err;
215 27909800 2021-07-26 op }
216 27909800 2021-07-26 op
217 27909800 2021-07-26 op event_add(&bufev->ev_read, NULL);
218 27909800 2021-07-26 op
219 27909800 2021-07-26 op len = EVBUFFER_LENGTH(bufev->input);
220 27909800 2021-07-26 op if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
221 27909800 2021-07-26 op return;
222 27909800 2021-07-26 op if (bufev->readcb != NULL)
223 27909800 2021-07-26 op (*bufev->readcb)(bufev, bufev->cbarg);
224 27909800 2021-07-26 op return;
225 27909800 2021-07-26 op
226 27909800 2021-07-26 op retry:
227 27909800 2021-07-26 op event_add(&bufev->ev_read, NULL);
228 27909800 2021-07-26 op return;
229 27909800 2021-07-26 op
230 27909800 2021-07-26 op err:
231 27909800 2021-07-26 op (*bufev->errorcb)(bufev, what, bufev->cbarg);
232 27909800 2021-07-26 op }
233 27909800 2021-07-26 op
234 27909800 2021-07-26 op static void
235 27909800 2021-07-26 op tls_writecb(int fd, short event, void *d)
236 27909800 2021-07-26 op {
237 27909800 2021-07-26 op struct bufferevent *bufev = d;
238 27909800 2021-07-26 op ssize_t ret;
239 9991b526 2021-08-01 op size_t len;
240 27909800 2021-07-26 op short what = EVBUFFER_WRITE;
241 9991b526 2021-08-01 op void *data;
242 27909800 2021-07-26 op
243 27909800 2021-07-26 op if (event == EV_TIMEOUT) {
244 27909800 2021-07-26 op what |= EVBUFFER_TIMEOUT;
245 27909800 2021-07-26 op goto err;
246 27909800 2021-07-26 op }
247 27909800 2021-07-26 op
248 9991b526 2021-08-01 op len = EVBUFFER_LENGTH(bufev->output);
249 9991b526 2021-08-01 op if (len != 0) {
250 9991b526 2021-08-01 op data = EVBUFFER_DATA(bufev->output);
251 9991b526 2021-08-01 op
252 9991b526 2021-08-01 op #if DEBUG_PACKETS
253 9991b526 2021-08-01 op hexdump("outgoing msg", data, len);
254 9991b526 2021-08-01 op #endif
255 9991b526 2021-08-01 op
256 9991b526 2021-08-01 op switch (ret = tls_write(ctx, data, len)) {
257 27909800 2021-07-26 op case TLS_WANT_POLLIN:
258 27909800 2021-07-26 op case TLS_WANT_POLLOUT:
259 27909800 2021-07-26 op goto retry;
260 27909800 2021-07-26 op case -1:
261 27909800 2021-07-26 op what |= EVBUFFER_ERROR;
262 27909800 2021-07-26 op goto err;
263 27909800 2021-07-26 op }
264 27909800 2021-07-26 op evbuffer_drain(bufev->output, ret);
265 27909800 2021-07-26 op }
266 27909800 2021-07-26 op
267 27909800 2021-07-26 op if (EVBUFFER_LENGTH(bufev->output) != 0)
268 27909800 2021-07-26 op event_add(&bufev->ev_write, NULL);
269 27909800 2021-07-26 op
270 27909800 2021-07-26 op if (bufev->writecb != NULL &&
271 27909800 2021-07-26 op EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low)
272 27909800 2021-07-26 op (*bufev->writecb)(bufev, bufev->cbarg);
273 27909800 2021-07-26 op return;
274 27909800 2021-07-26 op
275 27909800 2021-07-26 op retry:
276 27909800 2021-07-26 op event_add(&bufev->ev_write, NULL);
277 27909800 2021-07-26 op return;
278 27909800 2021-07-26 op err:
279 27909800 2021-07-26 op (*bufev->errorcb)(bufev, what, bufev->cbarg);
280 27909800 2021-07-26 op }
281 27909800 2021-07-26 op
282 27909800 2021-07-26 op static void
283 9991b526 2021-08-01 op client_read(struct bufferevent *bev, void *d)
284 27909800 2021-07-26 op {
285 27909800 2021-07-26 op struct evbuffer *src = EVBUFFER_INPUT(bev);
286 27909800 2021-07-26 op uint32_t len;
287 9991b526 2021-08-01 op uint8_t *data;
288 27909800 2021-07-26 op
289 27909800 2021-07-26 op for (;;) {
290 ba4a37ea 2021-07-28 op if (EVBUFFER_LENGTH(src) < sizeof(len))
291 27909800 2021-07-26 op return;
292 27909800 2021-07-26 op
293 9991b526 2021-08-01 op data = EVBUFFER_DATA(src);
294 9991b526 2021-08-01 op
295 9991b526 2021-08-01 op memcpy(&len, data, sizeof(len));
296 27909800 2021-07-26 op len = le32toh(len);
297 c26e4201 2021-08-01 op
298 c26e4201 2021-08-01 op if (len < HEADERSIZE)
299 c26e4201 2021-08-01 op fatal("incoming message is too small! (%d bytes)",
300 c26e4201 2021-08-01 op len);
301 27909800 2021-07-26 op
302 27909800 2021-07-26 op if (len > EVBUFFER_LENGTH(src))
303 27909800 2021-07-26 op return;
304 27909800 2021-07-26 op
305 9991b526 2021-08-01 op #if DEBUG_PACKETS
306 9991b526 2021-08-01 op hexdump("incoming msg", data, len);
307 9991b526 2021-08-01 op #endif
308 9991b526 2021-08-01 op
309 9991b526 2021-08-01 op handle_9p(data, len);
310 27909800 2021-07-26 op evbuffer_drain(src, len);
311 27909800 2021-07-26 op }
312 27909800 2021-07-26 op }
313 27909800 2021-07-26 op
314 27909800 2021-07-26 op static void
315 27909800 2021-07-26 op client_write(struct bufferevent *bev, void *data)
316 27909800 2021-07-26 op {
317 27909800 2021-07-26 op return; /* nothing to do */
318 27909800 2021-07-26 op }
319 27909800 2021-07-26 op
320 27909800 2021-07-26 op static void
321 27909800 2021-07-26 op client_error(struct bufferevent *bev, short err, void *data)
322 27909800 2021-07-26 op {
323 27909800 2021-07-26 op if (err & EVBUFFER_ERROR)
324 27909800 2021-07-26 op fatal("buffer event error");
325 27909800 2021-07-26 op
326 27909800 2021-07-26 op if (err & EVBUFFER_EOF) {
327 5c57fb10 2021-07-26 op clr();
328 27909800 2021-07-26 op log_info("EOF");
329 27909800 2021-07-26 op event_loopbreak();
330 27909800 2021-07-26 op return;
331 27909800 2021-07-26 op }
332 27909800 2021-07-26 op
333 5c57fb10 2021-07-26 op clr();
334 27909800 2021-07-26 op log_warnx("unknown event error");
335 27909800 2021-07-26 op event_loopbreak();
336 27909800 2021-07-26 op }
337 27909800 2021-07-26 op
338 27909800 2021-07-26 op static void
339 9d5307de 2021-07-27 op repl_read(struct bufferevent *bev, void *d)
340 27909800 2021-07-26 op {
341 9d5307de 2021-07-27 op size_t len;
342 9d5307de 2021-07-27 op int argc;
343 9d5307de 2021-07-27 op const char *argv[10], **ap;
344 9d5307de 2021-07-27 op char *line;
345 27909800 2021-07-26 op
346 9d5307de 2021-07-27 op line = evbuffer_readln(bev->input, &len, EVBUFFER_EOL_LF);
347 9d5307de 2021-07-27 op if (line == NULL)
348 9d5307de 2021-07-27 op return;
349 27909800 2021-07-26 op
350 9d5307de 2021-07-27 op for (argc = 0, ap = argv; ap < &argv[9] &&
351 9d5307de 2021-07-27 op (*ap = strsep(&line, " \t")) != NULL;) {
352 9d5307de 2021-07-27 op if (**ap != '\0')
353 9d5307de 2021-07-27 op ap++, argc++;
354 27909800 2021-07-26 op }
355 27909800 2021-07-26 op
356 9d5307de 2021-07-27 op clr();
357 9d5307de 2021-07-27 op excmd(argv, argc);
358 9d5307de 2021-07-27 op prompt();
359 9d5307de 2021-07-27 op
360 27909800 2021-07-26 op free(line);
361 9d5307de 2021-07-27 op }
362 9d5307de 2021-07-27 op
363 9d5307de 2021-07-27 op static void
364 9d5307de 2021-07-27 op repl_error(struct bufferevent *bev, short error, void *d)
365 9d5307de 2021-07-27 op {
366 9d5307de 2021-07-27 op fatalx("an error occurred");
367 ed61de84 2021-07-30 op }
368 ed61de84 2021-07-30 op
369 4e83b30f 2021-12-14 op static inline void
370 4e83b30f 2021-12-14 op do_send(void)
371 ed61de84 2021-07-30 op {
372 4e83b30f 2021-12-14 op bufferevent_write_buffer(bev, evb);
373 27909800 2021-07-26 op }
374 27909800 2021-07-26 op
375 afaad60e 2021-07-29 op /* version [version-str] */
376 afaad60e 2021-07-29 op static void
377 afaad60e 2021-07-29 op excmd_version(const char **argv, int argc)
378 9d5307de 2021-07-27 op {
379 afaad60e 2021-07-29 op const char *s;
380 afaad60e 2021-07-29 op
381 afaad60e 2021-07-29 op s = VERSION9P;
382 afaad60e 2021-07-29 op if (argc == 2)
383 afaad60e 2021-07-29 op s = argv[1];
384 afaad60e 2021-07-29 op
385 4e83b30f 2021-12-14 op tversion(s, MSIZE9P);
386 4e83b30f 2021-12-14 op do_send();
387 afaad60e 2021-07-29 op }
388 afaad60e 2021-07-29 op
389 afaad60e 2021-07-29 op /* attach fid uname aname */
390 afaad60e 2021-07-29 op static void
391 afaad60e 2021-07-29 op excmd_attach(const char **argv, int argc)
392 afaad60e 2021-07-29 op {
393 4e83b30f 2021-12-14 op uint32_t fid;
394 4e83b30f 2021-12-14 op const char *errstr;
395 9d5307de 2021-07-27 op
396 afaad60e 2021-07-29 op if (argc != 4)
397 afaad60e 2021-07-29 op goto usage;
398 9d5307de 2021-07-27 op
399 afaad60e 2021-07-29 op fid = strtonum(argv[1], 0, UINT32_MAX, &errstr);
400 afaad60e 2021-07-29 op if (errstr != NULL) {
401 afaad60e 2021-07-29 op log_warnx("fid is %s: %s", errstr, argv[1]);
402 afaad60e 2021-07-29 op return;
403 afaad60e 2021-07-29 op }
404 9d5307de 2021-07-27 op
405 4e83b30f 2021-12-14 op tattach(fid, NOFID, argv[2], argv[3]);
406 4e83b30f 2021-12-14 op do_send();
407 afaad60e 2021-07-29 op return;
408 9cb5f957 2021-07-29 op
409 afaad60e 2021-07-29 op usage:
410 afaad60e 2021-07-29 op log_warnx("usage: attach fid uname aname");
411 afaad60e 2021-07-29 op }
412 9cb5f957 2021-07-29 op
413 25359fc4 2021-07-30 op /* clunk fid */
414 afaad60e 2021-07-29 op static void
415 25359fc4 2021-07-30 op excmd_clunk(const char **argv, int argc)
416 25359fc4 2021-07-30 op {
417 4e83b30f 2021-12-14 op uint32_t fid;
418 25359fc4 2021-07-30 op const char *errstr;
419 25359fc4 2021-07-30 op
420 25359fc4 2021-07-30 op if (argc != 2)
421 25359fc4 2021-07-30 op goto usage;
422 25359fc4 2021-07-30 op
423 25359fc4 2021-07-30 op fid = strtonum(argv[1], 0, UINT32_MAX, &errstr);
424 25359fc4 2021-07-30 op if (errstr != NULL) {
425 25359fc4 2021-07-30 op log_warnx("fid is %s: %s", errstr, argv[1]);
426 25359fc4 2021-07-30 op return;
427 25359fc4 2021-07-30 op }
428 25359fc4 2021-07-30 op
429 4e83b30f 2021-12-14 op tclunk(fid);
430 4e83b30f 2021-12-14 op do_send();
431 25359fc4 2021-07-30 op return;
432 25359fc4 2021-07-30 op
433 25359fc4 2021-07-30 op usage:
434 25359fc4 2021-07-30 op log_warnx("usage: clunk fid");
435 5ed7f718 2021-07-30 op }
436 5ed7f718 2021-07-30 op
437 5ed7f718 2021-07-30 op /* flush oldtag */
438 5ed7f718 2021-07-30 op static void
439 5ed7f718 2021-07-30 op excmd_flush(const char **argv, int argc)
440 5ed7f718 2021-07-30 op {
441 5ed7f718 2021-07-30 op uint16_t oldtag;
442 5ed7f718 2021-07-30 op const char *errstr;
443 5ed7f718 2021-07-30 op
444 5ed7f718 2021-07-30 op if (argc != 2)
445 5ed7f718 2021-07-30 op goto usage;
446 5ed7f718 2021-07-30 op
447 5ed7f718 2021-07-30 op oldtag = strtonum(argv[1], 0, UINT16_MAX, &errstr);
448 5ed7f718 2021-07-30 op if (errstr != NULL) {
449 5ed7f718 2021-07-30 op log_warnx("oldtag is %s: %s", errstr, argv[1]);
450 5ed7f718 2021-07-30 op return;
451 5ed7f718 2021-07-30 op }
452 5ed7f718 2021-07-30 op
453 4e83b30f 2021-12-14 op tflush(oldtag);
454 4e83b30f 2021-12-14 op do_send();
455 5ed7f718 2021-07-30 op return;
456 5ed7f718 2021-07-30 op
457 5ed7f718 2021-07-30 op usage:
458 5ed7f718 2021-07-30 op log_warnx("usage: flush oldtag");
459 25359fc4 2021-07-30 op }
460 25359fc4 2021-07-30 op
461 29bc9fe5 2021-08-01 op /* walk fid newfid wnames... */
462 25359fc4 2021-07-30 op static void
463 29bc9fe5 2021-08-01 op excmd_walk(const char **argv, int argc)
464 29bc9fe5 2021-08-01 op {
465 4e83b30f 2021-12-14 op uint32_t fid, newfid;
466 29bc9fe5 2021-08-01 op const char *errstr;
467 29bc9fe5 2021-08-01 op
468 29bc9fe5 2021-08-01 op if (argc < 3)
469 29bc9fe5 2021-08-01 op goto usage;
470 29bc9fe5 2021-08-01 op
471 29bc9fe5 2021-08-01 op fid = strtonum(argv[1], 0, UINT32_MAX, &errstr);
472 29bc9fe5 2021-08-01 op if (errstr != NULL) {
473 29bc9fe5 2021-08-01 op log_warnx("fid is %s: %s", errstr, argv[1]);
474 29bc9fe5 2021-08-01 op return;
475 29bc9fe5 2021-08-01 op }
476 29bc9fe5 2021-08-01 op
477 29bc9fe5 2021-08-01 op newfid = strtonum(argv[2], 0, UINT32_MAX, &errstr);
478 29bc9fe5 2021-08-01 op if (errstr != NULL) {
479 29bc9fe5 2021-08-01 op log_warnx("newfid is %s: %s", errstr, argv[1]);
480 29bc9fe5 2021-08-01 op return;
481 29bc9fe5 2021-08-01 op }
482 29bc9fe5 2021-08-01 op
483 4e83b30f 2021-12-14 op twalk(fid, newfid, argv + 3, argc - 3);
484 4e83b30f 2021-12-14 op do_send();
485 29bc9fe5 2021-08-01 op return;
486 29bc9fe5 2021-08-01 op
487 29bc9fe5 2021-08-01 op usage:
488 29bc9fe5 2021-08-01 op log_warnx("usage: walk fid newfid wnames...");
489 f16f7555 2021-12-15 op }
490 f16f7555 2021-12-15 op
491 f16f7555 2021-12-15 op /* open fid mode [flag] */
492 f16f7555 2021-12-15 op static void
493 f16f7555 2021-12-15 op excmd_open(const char **argv, int argc)
494 f16f7555 2021-12-15 op {
495 f16f7555 2021-12-15 op const char *errstr;
496 f16f7555 2021-12-15 op uint32_t fid;
497 f16f7555 2021-12-15 op uint8_t mode = 0;
498 f16f7555 2021-12-15 op
499 f16f7555 2021-12-15 op if (argc != 3 && argc != 4)
500 f16f7555 2021-12-15 op goto usage;
501 f16f7555 2021-12-15 op
502 f16f7555 2021-12-15 op fid = strtonum(argv[1], 0, UINT32_MAX, &errstr);
503 f16f7555 2021-12-15 op if (errstr != NULL) {
504 f16f7555 2021-12-15 op log_warnx("fid is %s: %s", errstr, argv[1]);
505 f16f7555 2021-12-15 op return;
506 f16f7555 2021-12-15 op }
507 f16f7555 2021-12-15 op
508 f16f7555 2021-12-15 op /* parse mode */
509 f16f7555 2021-12-15 op if (!strcmp("read", argv[2]) || !strcmp("r", argv[2]))
510 f16f7555 2021-12-15 op mode = KOREAD;
511 f16f7555 2021-12-15 op else if (!strcmp("write", argv[2]) || !strcmp("w", argv[2]))
512 f16f7555 2021-12-15 op mode = KOWRITE;
513 f16f7555 2021-12-15 op else if (!strcmp("readwrite", argv[2]) || !strcmp("rw", argv[2]))
514 f16f7555 2021-12-15 op mode = KORDWR;
515 f16f7555 2021-12-15 op else {
516 f16f7555 2021-12-15 op log_warnx("invalid mode %s", argv[2]);
517 f16f7555 2021-12-15 op return;
518 f16f7555 2021-12-15 op }
519 f16f7555 2021-12-15 op
520 f16f7555 2021-12-15 op /* parse flag */
521 f16f7555 2021-12-15 op if (argv[3] != NULL) {
522 f16f7555 2021-12-15 op if (!strcmp("trunc", argv[3]))
523 f16f7555 2021-12-15 op mode |= KOTRUNC;
524 f16f7555 2021-12-15 op else if (!strcmp("rclose", argv[3]))
525 f16f7555 2021-12-15 op mode |= KORCLOSE;
526 f16f7555 2021-12-15 op else {
527 f16f7555 2021-12-15 op log_warnx("invalid flag %s", argv[3]);
528 f16f7555 2021-12-15 op return;
529 f16f7555 2021-12-15 op }
530 f16f7555 2021-12-15 op }
531 f16f7555 2021-12-15 op
532 f16f7555 2021-12-15 op topen(fid, mode);
533 f16f7555 2021-12-15 op do_send();
534 f16f7555 2021-12-15 op return;
535 f16f7555 2021-12-15 op
536 f16f7555 2021-12-15 op usage:
537 f16f7555 2021-12-15 op log_warnx("usage: open fid mode [flag]");
538 f16f7555 2021-12-15 op }
539 f16f7555 2021-12-15 op
540 f16f7555 2021-12-15 op /* read fid offset count */
541 f16f7555 2021-12-15 op static void
542 f16f7555 2021-12-15 op excmd_read(const char **argv, int argc)
543 f16f7555 2021-12-15 op {
544 f16f7555 2021-12-15 op uint64_t off;
545 f16f7555 2021-12-15 op uint32_t fid, count;
546 f16f7555 2021-12-15 op const char *errstr;
547 f16f7555 2021-12-15 op
548 f16f7555 2021-12-15 op if (argc != 4)
549 f16f7555 2021-12-15 op goto usage;
550 f16f7555 2021-12-15 op
551 f16f7555 2021-12-15 op fid = strtonum(argv[1], 0, UINT32_MAX, &errstr);
552 f16f7555 2021-12-15 op if (errstr != NULL) {
553 f16f7555 2021-12-15 op log_warnx("fid is %s: %s", errstr, argv[1]);
554 f16f7555 2021-12-15 op return;
555 f16f7555 2021-12-15 op }
556 f16f7555 2021-12-15 op
557 f16f7555 2021-12-15 op /* should really be UNT64_MAX but it fails... */
558 f16f7555 2021-12-15 op off = strtonum(argv[2], -1, UINT32_MAX, &errstr);
559 f16f7555 2021-12-15 op if (errstr != NULL) {
560 f16f7555 2021-12-15 op log_warnx("offset is %s: %s", errstr, argv[2]);
561 f16f7555 2021-12-15 op return;
562 f16f7555 2021-12-15 op }
563 f16f7555 2021-12-15 op
564 f16f7555 2021-12-15 op count = strtonum(argv[3], 0, UINT32_MAX, &errstr);
565 f16f7555 2021-12-15 op if (errstr != NULL) {
566 f16f7555 2021-12-15 op log_warnx("count is %s: %s", errstr, argv[3]);
567 f16f7555 2021-12-15 op return;
568 f16f7555 2021-12-15 op }
569 f16f7555 2021-12-15 op
570 f16f7555 2021-12-15 op tread(fid, off, count);
571 f16f7555 2021-12-15 op do_send();
572 f16f7555 2021-12-15 op return;
573 f16f7555 2021-12-15 op
574 f16f7555 2021-12-15 op usage:
575 f16f7555 2021-12-15 op log_warnx("usage: read fid offset count");
576 29bc9fe5 2021-08-01 op }
577 29bc9fe5 2021-08-01 op
578 29bc9fe5 2021-08-01 op static void
579 afaad60e 2021-07-29 op excmd(const char **argv, int argc)
580 afaad60e 2021-07-29 op {
581 afaad60e 2021-07-29 op struct cmd {
582 afaad60e 2021-07-29 op const char *name;
583 afaad60e 2021-07-29 op void (*fn)(const char **, int);
584 afaad60e 2021-07-29 op } cmds[] = {
585 6b93b2b7 2021-07-29 op {"version", excmd_version},
586 6b93b2b7 2021-07-29 op {"attach", excmd_attach},
587 25359fc4 2021-07-30 op {"clunk", excmd_clunk},
588 5ed7f718 2021-07-30 op {"flush", excmd_flush},
589 29bc9fe5 2021-08-01 op {"walk", excmd_walk},
590 f16f7555 2021-12-15 op {"open", excmd_open},
591 f16f7555 2021-12-15 op {"read", excmd_read},
592 afaad60e 2021-07-29 op };
593 afaad60e 2021-07-29 op size_t i;
594 afaad60e 2021-07-29 op
595 a8802990 2021-07-30 op if (argc == 0)
596 a8802990 2021-07-30 op return;
597 a8802990 2021-07-30 op
598 afaad60e 2021-07-29 op for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i) {
599 afaad60e 2021-07-29 op if (!strcmp(cmds[i].name, argv[0])) {
600 afaad60e 2021-07-29 op cmds[i].fn(argv, argc);
601 afaad60e 2021-07-29 op return;
602 afaad60e 2021-07-29 op }
603 ff3a2c18 2021-07-29 op }
604 afaad60e 2021-07-29 op
605 afaad60e 2021-07-29 op log_warnx("Unknown command %s", *argv);
606 ff3a2c18 2021-07-29 op }
607 ff3a2c18 2021-07-29 op
608 9cb5f957 2021-07-29 op static const char *
609 9cb5f957 2021-07-29 op pp_qid_type(uint8_t type)
610 9cb5f957 2021-07-29 op {
611 9cb5f957 2021-07-29 op switch (type) {
612 6b93b2b7 2021-07-29 op case QTDIR: return "dir";
613 6b93b2b7 2021-07-29 op case QTAPPEND: return "append-only";
614 6b93b2b7 2021-07-29 op case QTEXCL: return "exclusive";
615 6b93b2b7 2021-07-29 op case QTMOUNT: return "mounted-channel";
616 6b93b2b7 2021-07-29 op case QTAUTH: return "authentication";
617 6b93b2b7 2021-07-29 op case QTTMP: return "non-backed-up";
618 9cb5f957 2021-07-29 op case QTSYMLINK: return "symlink";
619 6b93b2b7 2021-07-29 op case QTFILE: return "file";
620 9cb5f957 2021-07-29 op }
621 9cb5f957 2021-07-29 op
622 9cb5f957 2021-07-29 op return "unknown";
623 9cb5f957 2021-07-29 op }
624 9cb5f957 2021-07-29 op
625 ff3a2c18 2021-07-29 op static void
626 9cb5f957 2021-07-29 op pp_qid(const uint8_t *d, uint32_t len)
627 9cb5f957 2021-07-29 op {
628 9cb5f957 2021-07-29 op uint64_t path;
629 9cb5f957 2021-07-29 op uint32_t vers;
630 9cb5f957 2021-07-29 op uint8_t type;
631 9cb5f957 2021-07-29 op
632 9cb5f957 2021-07-29 op if (len < 13) {
633 9cb5f957 2021-07-29 op printf("invalid");
634 9cb5f957 2021-07-29 op return;
635 9cb5f957 2021-07-29 op }
636 9cb5f957 2021-07-29 op
637 d28f26db 2021-07-31 op type = *d++;
638 9cb5f957 2021-07-29 op
639 9cb5f957 2021-07-29 op memcpy(&vers, d, sizeof(vers));
640 9cb5f957 2021-07-29 op d += sizeof(vers);
641 4fa53a98 2021-07-29 op vers = le64toh(vers);
642 9cb5f957 2021-07-29 op
643 d28f26db 2021-07-31 op memcpy(&path, d, sizeof(path));
644 d28f26db 2021-07-31 op d += sizeof(path);
645 d28f26db 2021-07-31 op path = le64toh(path);
646 9cb5f957 2021-07-29 op
647 787867cb 2021-07-30 op printf("qid{path=%"PRIu64" version=%"PRIu32" type=0x%x\"%s\"}",
648 9cb5f957 2021-07-29 op path, vers, type, pp_qid_type(type));
649 9cb5f957 2021-07-29 op }
650 9cb5f957 2021-07-29 op
651 9cb5f957 2021-07-29 op static void
652 ff3a2c18 2021-07-29 op pp_msg(uint32_t len, uint8_t type, uint16_t tag, const uint8_t *d)
653 ff3a2c18 2021-07-29 op {
654 f16f7555 2021-12-15 op uint32_t msize, iounit, count;
655 f16f7555 2021-12-15 op uint16_t slen;
656 f16f7555 2021-12-15 op char *v;
657 ff3a2c18 2021-07-29 op
658 ff3a2c18 2021-07-29 op printf("len=%"PRIu32" type=%d[%s] tag=0x%x[%d] ", len,
659 ff3a2c18 2021-07-29 op type, pp_msg_type(type), tag, tag);
660 ff3a2c18 2021-07-29 op
661 ff3a2c18 2021-07-29 op len -= HEADERSIZE;
662 ff3a2c18 2021-07-29 op
663 ff3a2c18 2021-07-29 op switch (type) {
664 ff3a2c18 2021-07-29 op case Rversion:
665 ff3a2c18 2021-07-29 op if (len < 6) {
666 ff3a2c18 2021-07-29 op printf("invalid: not enough space for msize "
667 ff3a2c18 2021-07-29 op "and version provided.");
668 ff3a2c18 2021-07-29 op break;
669 ff3a2c18 2021-07-29 op }
670 ff3a2c18 2021-07-29 op
671 ff3a2c18 2021-07-29 op memcpy(&msize, d, sizeof(msize));
672 ff3a2c18 2021-07-29 op d += sizeof(msize);
673 ff3a2c18 2021-07-29 op len -= sizeof(msize);
674 ff3a2c18 2021-07-29 op msize = le32toh(msize);
675 ff3a2c18 2021-07-29 op
676 ff3a2c18 2021-07-29 op memcpy(&slen, d, sizeof(slen));
677 ff3a2c18 2021-07-29 op d += sizeof(slen);
678 ff3a2c18 2021-07-29 op len -= sizeof(slen);
679 0a4b3ca8 2021-07-30 op slen = le16toh(slen);
680 ff3a2c18 2021-07-29 op
681 ff3a2c18 2021-07-29 op if (len != slen) {
682 ff3a2c18 2021-07-29 op printf("invalid: version string length doesn't "
683 ff3a2c18 2021-07-29 op "match. Got %d; want %d", slen, len);
684 ff3a2c18 2021-07-29 op break;
685 ff3a2c18 2021-07-29 op }
686 ff3a2c18 2021-07-29 op
687 ff3a2c18 2021-07-29 op printf("msize=%"PRIu32" version[%"PRIu16"]=\"",
688 ff3a2c18 2021-07-29 op msize, slen);
689 ff3a2c18 2021-07-29 op fwrite(d, 1, slen, stdout);
690 ff3a2c18 2021-07-29 op printf("\"");
691 ff3a2c18 2021-07-29 op
692 ff3a2c18 2021-07-29 op break;
693 2ba6253c 2021-07-29 op
694 9cb5f957 2021-07-29 op case Rattach:
695 9cb5f957 2021-07-29 op pp_qid(d, len);
696 8e504ac0 2021-07-30 op break;
697 8e504ac0 2021-07-30 op
698 25359fc4 2021-07-30 op case Rclunk:
699 25359fc4 2021-07-30 op if (len != 0)
700 25359fc4 2021-07-30 op printf("invalid Rclunk: %"PRIu32" extra bytes", len);
701 25359fc4 2021-07-30 op break;
702 25359fc4 2021-07-30 op
703 5ed7f718 2021-07-30 op case Rflush:
704 5ed7f718 2021-07-30 op if (len != 0)
705 5ed7f718 2021-07-30 op printf("invalid Rflush: %"PRIu32" extra bytes", len);
706 ef44416c 2021-08-01 op break;
707 ef44416c 2021-08-01 op
708 ef44416c 2021-08-01 op case Rwalk:
709 ef44416c 2021-08-01 op if (len < 2) {
710 ef44416c 2021-08-01 op printf("invaild Rwalk: less than two bytes (%d)",
711 ef44416c 2021-08-01 op (int)len);
712 ef44416c 2021-08-01 op break;
713 ef44416c 2021-08-01 op }
714 ef44416c 2021-08-01 op
715 ef44416c 2021-08-01 op memcpy(&slen, d, sizeof(slen));
716 ef44416c 2021-08-01 op d += sizeof(slen);
717 ef44416c 2021-08-01 op len -= sizeof(slen);
718 ef44416c 2021-08-01 op slen = le16toh(slen);
719 ef44416c 2021-08-01 op
720 ef44416c 2021-08-01 op if (len != QIDSIZE * slen) {
721 ef44416c 2021-08-01 op printf("invalid Rwalk: wanted %d bytes for %d qids "
722 ef44416c 2021-08-01 op "but got %"PRIu32" bytes instead",
723 ef44416c 2021-08-01 op QIDSIZE*slen, slen, len);
724 ef44416c 2021-08-01 op break;
725 ef44416c 2021-08-01 op }
726 ef44416c 2021-08-01 op
727 ef44416c 2021-08-01 op printf("nwqid=%"PRIu16, slen);
728 ef44416c 2021-08-01 op
729 ef44416c 2021-08-01 op for (; slen != 0; slen--) {
730 ef44416c 2021-08-01 op printf(" ");
731 ef44416c 2021-08-01 op pp_qid(d, len);
732 ef44416c 2021-08-01 op d += QIDSIZE;
733 ef44416c 2021-08-01 op len -= QIDSIZE;
734 ef44416c 2021-08-01 op }
735 ef44416c 2021-08-01 op
736 5ed7f718 2021-07-30 op break;
737 5ed7f718 2021-07-30 op
738 f16f7555 2021-12-15 op case Ropen:
739 f16f7555 2021-12-15 op if (len != QIDSIZE + 4) {
740 f16f7555 2021-12-15 op printf("invalid Ropen: expected %d bytes; "
741 f16f7555 2021-12-15 op "got %u\n", QIDSIZE + 4, len);
742 f16f7555 2021-12-15 op break;
743 f16f7555 2021-12-15 op }
744 f16f7555 2021-12-15 op
745 f16f7555 2021-12-15 op pp_qid(d, len);
746 f16f7555 2021-12-15 op d += QIDSIZE;
747 f16f7555 2021-12-15 op len -= QIDSIZE;
748 f16f7555 2021-12-15 op
749 f16f7555 2021-12-15 op memcpy(&iounit, d, sizeof(iounit));
750 f16f7555 2021-12-15 op d += sizeof(iounit);
751 f16f7555 2021-12-15 op len -= sizeof(iounit);
752 f16f7555 2021-12-15 op iounit = le32toh(iounit);
753 f16f7555 2021-12-15 op printf(" iounit=%"PRIu32, iounit);
754 f16f7555 2021-12-15 op break;
755 f16f7555 2021-12-15 op
756 f16f7555 2021-12-15 op case Rread:
757 f16f7555 2021-12-15 op if (len < sizeof(count)) {
758 f16f7555 2021-12-15 op printf("invalid Rread: expected %zu bytes at least; "
759 f16f7555 2021-12-15 op "got %u\n", sizeof(count), len);
760 f16f7555 2021-12-15 op break;
761 f16f7555 2021-12-15 op }
762 f16f7555 2021-12-15 op
763 f16f7555 2021-12-15 op memcpy(&count, d, sizeof(count));
764 f16f7555 2021-12-15 op d += sizeof(count);
765 f16f7555 2021-12-15 op len -= sizeof(count);
766 f16f7555 2021-12-15 op count = le32toh(count);
767 f16f7555 2021-12-15 op
768 f16f7555 2021-12-15 op if (len != count) {
769 f16f7555 2021-12-15 op printf("invalid Rread: expected %d data bytes; "
770 f16f7555 2021-12-15 op "got %u\n", count, len);
771 f16f7555 2021-12-15 op break;
772 f16f7555 2021-12-15 op }
773 f16f7555 2021-12-15 op
774 f16f7555 2021-12-15 op /* allocates three extra bytes, oh well... */
775 f16f7555 2021-12-15 op if ((v = calloc(count + 1, 4)) == NULL)
776 f16f7555 2021-12-15 op fatal("calloc");
777 f16f7555 2021-12-15 op strvisx(v, d, count, VIS_SAFE | VIS_TAB | VIS_NL | VIS_CSTYLE);
778 f16f7555 2021-12-15 op printf("data=%s", v);
779 f16f7555 2021-12-15 op free(v);
780 f16f7555 2021-12-15 op
781 f16f7555 2021-12-15 op break;
782 f16f7555 2021-12-15 op
783 8e504ac0 2021-07-30 op case Rerror:
784 8e504ac0 2021-07-30 op memcpy(&slen, d, sizeof(slen));
785 8e504ac0 2021-07-30 op d += sizeof(slen);
786 8e504ac0 2021-07-30 op len -= sizeof(slen);
787 8e504ac0 2021-07-30 op slen = le16toh(slen);
788 8e504ac0 2021-07-30 op
789 8e504ac0 2021-07-30 op if (slen != len) {
790 8e504ac0 2021-07-30 op printf("invalid: error string length doesn't "
791 8e504ac0 2021-07-30 op "match. Got %d; want %d", slen, len);
792 8e504ac0 2021-07-30 op break;
793 8e504ac0 2021-07-30 op }
794 8e504ac0 2021-07-30 op
795 8e504ac0 2021-07-30 op printf("error=\"");
796 8e504ac0 2021-07-30 op fwrite(d, 1, slen, stdout);
797 8e504ac0 2021-07-30 op printf("\"");
798 8e504ac0 2021-07-30 op
799 9cb5f957 2021-07-29 op break;
800 9cb5f957 2021-07-29 op
801 2ba6253c 2021-07-29 op default:
802 f16f7555 2021-12-15 op if ((v = calloc(len + 1, 4)) == NULL)
803 f16f7555 2021-12-15 op fatal("calloc");
804 f16f7555 2021-12-15 op strvisx(v, d, len, VIS_SAFE | VIS_TAB | VIS_NL | VIS_CSTYLE);
805 f16f7555 2021-12-15 op printf("body=%s", v);
806 f16f7555 2021-12-15 op free(v);
807 9d5307de 2021-07-27 op }
808 ff3a2c18 2021-07-29 op
809 ff3a2c18 2021-07-29 op printf("\n");
810 9d5307de 2021-07-27 op }
811 9d5307de 2021-07-27 op
812 9d5307de 2021-07-27 op static void
813 de16f136 2021-07-28 op handle_9p(const uint8_t *data, size_t size)
814 27909800 2021-07-26 op {
815 de16f136 2021-07-28 op uint32_t len;
816 de16f136 2021-07-28 op uint16_t tag;
817 de16f136 2021-07-28 op uint8_t type;
818 27909800 2021-07-26 op
819 de16f136 2021-07-28 op assert(size >= HEADERSIZE);
820 de678634 2021-07-28 op
821 de16f136 2021-07-28 op memcpy(&len, data, sizeof(len));
822 de16f136 2021-07-28 op data += sizeof(len);
823 de16f136 2021-07-28 op
824 de16f136 2021-07-28 op memcpy(&type, data, sizeof(type));
825 de16f136 2021-07-28 op data += sizeof(type);
826 de16f136 2021-07-28 op
827 de16f136 2021-07-28 op memcpy(&tag, data, sizeof(tag));
828 de16f136 2021-07-28 op data += sizeof(tag);
829 de16f136 2021-07-28 op
830 de16f136 2021-07-28 op len = le32toh(len);
831 27909800 2021-07-26 op /* type is one byte long, no endianness issues */
832 de16f136 2021-07-28 op tag = le16toh(tag);
833 27909800 2021-07-26 op
834 5c57fb10 2021-07-26 op clr();
835 ff3a2c18 2021-07-29 op pp_msg(len, type, tag, data);
836 27909800 2021-07-26 op prompt();
837 27909800 2021-07-26 op }
838 27909800 2021-07-26 op
839 27909800 2021-07-26 op static void
840 5c57fb10 2021-07-26 op clr(void)
841 5c57fb10 2021-07-26 op {
842 5c57fb10 2021-07-26 op printf("\r");
843 5c57fb10 2021-07-26 op fflush(stdout);
844 5c57fb10 2021-07-26 op }
845 5c57fb10 2021-07-26 op
846 5c57fb10 2021-07-26 op static void
847 27909800 2021-07-26 op prompt(void)
848 27909800 2021-07-26 op {
849 27909800 2021-07-26 op printf("%s", PROMPT);
850 27909800 2021-07-26 op fflush(stdout);
851 27909800 2021-07-26 op }
852 27909800 2021-07-26 op
853 27909800 2021-07-26 op int
854 27909800 2021-07-26 op main(int argc, char **argv)
855 27909800 2021-07-26 op {
856 9d5307de 2021-07-27 op int ch, sock, handshake;
857 9d5307de 2021-07-27 op struct event ev_sigint, ev_sigterm;
858 27909800 2021-07-26 op
859 27909800 2021-07-26 op signal(SIGPIPE, SIG_IGN);
860 27909800 2021-07-26 op
861 27909800 2021-07-26 op while ((ch = getopt(argc, argv, "C:cH:hK:P:v")) != -1) {
862 27909800 2021-07-26 op switch (ch) {
863 27909800 2021-07-26 op case 'C':
864 27909800 2021-07-26 op crtpath = optarg;
865 27909800 2021-07-26 op break;
866 27909800 2021-07-26 op case 'c':
867 27909800 2021-07-26 op tls = 1;
868 27909800 2021-07-26 op break;
869 27909800 2021-07-26 op case 'H':
870 27909800 2021-07-26 op host = optarg;
871 27909800 2021-07-26 op break;
872 27909800 2021-07-26 op case 'h':
873 27909800 2021-07-26 op usage(0);
874 27909800 2021-07-26 op break;
875 27909800 2021-07-26 op case 'K':
876 27909800 2021-07-26 op keypath = optarg;
877 27909800 2021-07-26 op break;
878 27909800 2021-07-26 op case 'P':
879 27909800 2021-07-26 op port = optarg;
880 27909800 2021-07-26 op break;
881 27909800 2021-07-26 op case 'v':
882 27909800 2021-07-26 op verbose = 1;
883 27909800 2021-07-26 op break;
884 27909800 2021-07-26 op default:
885 27909800 2021-07-26 op usage(1);
886 27909800 2021-07-26 op }
887 27909800 2021-07-26 op }
888 27909800 2021-07-26 op
889 27909800 2021-07-26 op if (host == NULL)
890 27909800 2021-07-26 op host = "localhost";
891 27909800 2021-07-26 op if (port == NULL)
892 27909800 2021-07-26 op port = "1337";
893 27909800 2021-07-26 op
894 27909800 2021-07-26 op argc -= optind;
895 27909800 2021-07-26 op argv += optind;
896 27909800 2021-07-26 op
897 27909800 2021-07-26 op if (argc != 0)
898 27909800 2021-07-26 op usage(1);
899 27909800 2021-07-26 op /* if (!tls || (crtpath != NULL || keypath != NULL)) */
900 27909800 2021-07-26 op /* usage(1); */
901 27909800 2021-07-26 op if (!tls)
902 27909800 2021-07-26 op errx(1, "must enable tls (for now)");
903 27909800 2021-07-26 op
904 27909800 2021-07-26 op log_init(1, LOG_DAEMON);
905 27909800 2021-07-26 op log_setverbose(verbose);
906 27909800 2021-07-26 op log_procinit(getprogname());
907 27909800 2021-07-26 op
908 27909800 2021-07-26 op if ((tlsconf = tls_config_new()) == NULL)
909 27909800 2021-07-26 op fatalx("tls_config_new");
910 27909800 2021-07-26 op tls_config_insecure_noverifycert(tlsconf);
911 27909800 2021-07-26 op tls_config_insecure_noverifyname(tlsconf);
912 27909800 2021-07-26 op if (tls_config_set_keypair_file(tlsconf, crtpath, keypath) == -1)
913 27909800 2021-07-26 op fatalx("can't load certs (%s, %s)", crtpath, keypath);
914 27909800 2021-07-26 op
915 27909800 2021-07-26 op if ((ctx = tls_client()) == NULL)
916 27909800 2021-07-26 op fatal("tls_client");
917 27909800 2021-07-26 op if (tls_configure(ctx, tlsconf) == -1)
918 27909800 2021-07-26 op fatalx("tls_configure: %s", tls_error(ctx));
919 27909800 2021-07-26 op
920 27909800 2021-07-26 op log_info("connecting to %s:%s...", host, port);
921 27909800 2021-07-26 op
922 27909800 2021-07-26 op if ((sock = openconn()) == -1)
923 27909800 2021-07-26 op fatalx("can't connect to %s:%s", host, port);
924 27909800 2021-07-26 op
925 27909800 2021-07-26 op if (tls_connect_socket(ctx, sock, host) == -1)
926 27909800 2021-07-26 op fatalx("tls_connect_socket: %s", tls_error(ctx));
927 27909800 2021-07-26 op
928 27909800 2021-07-26 op for (handshake = 0; !handshake;) {
929 27909800 2021-07-26 op switch (tls_handshake(ctx)) {
930 27909800 2021-07-26 op case -1:
931 27909800 2021-07-26 op fatalx("tls_handshake: %s", tls_error(ctx));
932 27909800 2021-07-26 op case 0:
933 27909800 2021-07-26 op handshake = 1;
934 27909800 2021-07-26 op break;
935 27909800 2021-07-26 op }
936 27909800 2021-07-26 op }
937 27909800 2021-07-26 op
938 27909800 2021-07-26 op log_info("connected!");
939 27909800 2021-07-26 op
940 9d5307de 2021-07-27 op mark_nonblock(sock);
941 9d5307de 2021-07-27 op
942 27909800 2021-07-26 op event_init();
943 27909800 2021-07-26 op
944 4e83b30f 2021-12-14 op /* initialize global evb */
945 4e83b30f 2021-12-14 op if ((evb = evbuffer_new()) == NULL)
946 4e83b30f 2021-12-14 op fatal("evbuffer_new");
947 4e83b30f 2021-12-14 op
948 27909800 2021-07-26 op signal_set(&ev_sigint, SIGINT, sig_handler, NULL);
949 27909800 2021-07-26 op signal_set(&ev_sigterm, SIGINT, sig_handler, NULL);
950 27909800 2021-07-26 op
951 27909800 2021-07-26 op signal_add(&ev_sigint, NULL);
952 27909800 2021-07-26 op signal_add(&ev_sigterm, NULL);
953 27909800 2021-07-26 op
954 27909800 2021-07-26 op bev = bufferevent_new(sock, client_read, client_write, client_error,
955 27909800 2021-07-26 op NULL);
956 27909800 2021-07-26 op if (bev == NULL)
957 27909800 2021-07-26 op fatal("bufferevent_new");
958 27909800 2021-07-26 op
959 27909800 2021-07-26 op /* setup tls/io */
960 27909800 2021-07-26 op event_set(&bev->ev_read, sock, EV_READ, tls_readcb, bev);
961 27909800 2021-07-26 op event_set(&bev->ev_write, sock, EV_WRITE, tls_writecb, bev);
962 27909800 2021-07-26 op
963 27909800 2021-07-26 op bufferevent_enable(bev, EV_READ|EV_WRITE);
964 27909800 2021-07-26 op
965 9d5307de 2021-07-27 op mark_nonblock(0);
966 9d5307de 2021-07-27 op inbev = bufferevent_new(0, repl_read, NULL, repl_error, NULL);
967 9d5307de 2021-07-27 op bufferevent_enable(inbev, EV_READ);
968 27909800 2021-07-26 op
969 27909800 2021-07-26 op prompt();
970 27909800 2021-07-26 op event_dispatch();
971 27909800 2021-07-26 op
972 27909800 2021-07-26 op bufferevent_free(bev);
973 27909800 2021-07-26 op tls_free(ctx);
974 27909800 2021-07-26 op tls_config_free(tlsconf);
975 27909800 2021-07-26 op close(sock);
976 27909800 2021-07-26 op
977 27909800 2021-07-26 op return 0;
978 27909800 2021-07-26 op }