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