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