Blame


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