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