Blame


1 ce3844d2 2021-12-14 op /*
2 ce3844d2 2021-12-14 op * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 ce3844d2 2021-12-14 op *
4 ce3844d2 2021-12-14 op * Permission to use, copy, modify, and distribute this software for any
5 ce3844d2 2021-12-14 op * purpose with or without fee is hereby granted, provided that the above
6 ce3844d2 2021-12-14 op * copyright notice and this permission notice appear in all copies.
7 ce3844d2 2021-12-14 op *
8 ce3844d2 2021-12-14 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 ce3844d2 2021-12-14 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 ce3844d2 2021-12-14 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 ce3844d2 2021-12-14 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 ce3844d2 2021-12-14 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 ce3844d2 2021-12-14 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 ce3844d2 2021-12-14 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 ce3844d2 2021-12-14 op */
16 ce3844d2 2021-12-14 op
17 ce3844d2 2021-12-14 op #include "compat.h"
18 ce3844d2 2021-12-14 op
19 ce3844d2 2021-12-14 op #include <sys/types.h>
20 ce3844d2 2021-12-14 op #include <sys/socket.h>
21 ce3844d2 2021-12-14 op
22 423f02f5 2021-12-28 cage #include <assert.h>
23 ce3844d2 2021-12-14 op #include <netdb.h>
24 ce3844d2 2021-12-14 op #include <limits.h>
25 ce3844d2 2021-12-14 op #include <stdio.h>
26 ce3844d2 2021-12-14 op #include <stdlib.h>
27 ce3844d2 2021-12-14 op #include <string.h>
28 ce3844d2 2021-12-14 op #include <syslog.h>
29 ce3844d2 2021-12-14 op #include <tls.h>
30 ce3844d2 2021-12-14 op #include <unistd.h>
31 ce3844d2 2021-12-14 op
32 423f02f5 2021-12-28 cage #if HAVE_LIBREADLINE
33 ce3844d2 2021-12-14 op #include <readline/readline.h>
34 ce3844d2 2021-12-14 op #include <readline/history.h>
35 688f54f0 2021-12-14 op #endif
36 ce3844d2 2021-12-14 op
37 423f02f5 2021-12-28 cage #ifndef nitems
38 423f02f5 2021-12-28 cage #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
39 423f02f5 2021-12-28 cage #endif
40 423f02f5 2021-12-28 cage
41 ce3844d2 2021-12-14 op #include "9pclib.h"
42 ce3844d2 2021-12-14 op #include "kamid.h"
43 ce3844d2 2021-12-14 op #include "utils.h"
44 ce3844d2 2021-12-14 op #include "log.h"
45 ce3844d2 2021-12-14 op
46 ce3844d2 2021-12-14 op /* flags */
47 ce3844d2 2021-12-14 op int tls;
48 ce3844d2 2021-12-14 op const char *crtpath;
49 ce3844d2 2021-12-14 op const char *keypath;
50 ce3844d2 2021-12-14 op
51 ce3844d2 2021-12-14 op /* state */
52 ce3844d2 2021-12-14 op struct tls_config *tlsconf;
53 ce3844d2 2021-12-14 op struct tls *ctx;
54 ce3844d2 2021-12-14 op int sock;
55 423f02f5 2021-12-28 cage struct evbuffer *buf;
56 423f02f5 2021-12-28 cage struct evbuffer *dirbuf;
57 423f02f5 2021-12-28 cage uint32_t msize;
58 423f02f5 2021-12-28 cage int bell;
59 ce3844d2 2021-12-14 op
60 ce3844d2 2021-12-14 op #define PWDFID 0
61 ce3844d2 2021-12-14 op
62 423f02f5 2021-12-28 cage #define ASSERT_EMPTYBUF() assert(EVBUFFER_LENGTH(buf) == 0)
63 423f02f5 2021-12-28 cage
64 423f02f5 2021-12-28 cage #if HAVE_LIBREADLINE
65 688f54f0 2021-12-14 op static char *
66 688f54f0 2021-12-14 op read_line(const char *prompt)
67 688f54f0 2021-12-14 op {
68 688f54f0 2021-12-14 op char *line;
69 688f54f0 2021-12-14 op
70 688f54f0 2021-12-14 op again:
71 688f54f0 2021-12-14 op if ((line = readline(prompt)) == NULL)
72 688f54f0 2021-12-14 op return NULL;
73 688f54f0 2021-12-14 op /* XXX: trim spaces? */
74 688f54f0 2021-12-14 op if (*line == '\0') {
75 688f54f0 2021-12-14 op free(line);
76 688f54f0 2021-12-14 op goto again;
77 688f54f0 2021-12-14 op }
78 688f54f0 2021-12-14 op
79 688f54f0 2021-12-14 op add_history(line);
80 688f54f0 2021-12-14 op return line;
81 688f54f0 2021-12-14 op }
82 688f54f0 2021-12-14 op #else
83 688f54f0 2021-12-14 op static char *
84 688f54f0 2021-12-14 op read_line(const char *prompt)
85 688f54f0 2021-12-14 op {
86 688f54f0 2021-12-14 op char *ch, *line = NULL;
87 688f54f0 2021-12-14 op size_t linesize = 0;
88 688f54f0 2021-12-14 op ssize_t linelen;
89 688f54f0 2021-12-14 op
90 423f02f5 2021-12-28 cage printf("%s", prompt);
91 423f02f5 2021-12-28 cage fflush(stdout);
92 423f02f5 2021-12-28 cage
93 688f54f0 2021-12-14 op linelen = getline(&line, &linesize, stdin);
94 688f54f0 2021-12-14 op if (linelen == -1)
95 688f54f0 2021-12-14 op return NULL;
96 688f54f0 2021-12-14 op
97 688f54f0 2021-12-14 op if ((ch = strchr(line, '\n')) != NULL)
98 688f54f0 2021-12-14 op *ch = '\0';
99 688f54f0 2021-12-14 op return line;
100 688f54f0 2021-12-14 op }
101 688f54f0 2021-12-14 op #endif
102 688f54f0 2021-12-14 op
103 a97ec9eb 2021-12-23 op static void __dead
104 ce3844d2 2021-12-14 op usage(int ret)
105 ce3844d2 2021-12-14 op {
106 ce3844d2 2021-12-14 op fprintf(stderr, "usage: %s [-c] host[:port] [path]\n",
107 ce3844d2 2021-12-14 op getprogname());
108 ce3844d2 2021-12-14 op fprintf(stderr, PACKAGE_NAME " suite version " PACKAGE VERSION "\n");
109 ce3844d2 2021-12-14 op exit(ret);
110 ce3844d2 2021-12-14 op }
111 ce3844d2 2021-12-14 op
112 ce3844d2 2021-12-14 op static void
113 423f02f5 2021-12-28 cage do_send(void)
114 423f02f5 2021-12-28 cage {
115 423f02f5 2021-12-28 cage ssize_t r;
116 423f02f5 2021-12-28 cage
117 423f02f5 2021-12-28 cage while (EVBUFFER_LENGTH(evb) != 0) {
118 423f02f5 2021-12-28 cage r = tls_write(ctx, EVBUFFER_DATA(evb), EVBUFFER_LENGTH(evb));
119 423f02f5 2021-12-28 cage switch (r) {
120 423f02f5 2021-12-28 cage case TLS_WANT_POLLIN:
121 423f02f5 2021-12-28 cage case TLS_WANT_POLLOUT:
122 423f02f5 2021-12-28 cage continue;
123 423f02f5 2021-12-28 cage case -1:
124 423f02f5 2021-12-28 cage errx(1, "tls: %s", tls_error(ctx));
125 423f02f5 2021-12-28 cage default:
126 423f02f5 2021-12-28 cage evbuffer_drain(evb, r);
127 423f02f5 2021-12-28 cage }
128 423f02f5 2021-12-28 cage }
129 423f02f5 2021-12-28 cage }
130 423f02f5 2021-12-28 cage
131 423f02f5 2021-12-28 cage static void
132 423f02f5 2021-12-28 cage mustread(void *d, size_t len)
133 423f02f5 2021-12-28 cage {
134 423f02f5 2021-12-28 cage ssize_t r;
135 423f02f5 2021-12-28 cage
136 423f02f5 2021-12-28 cage while (len != 0) {
137 423f02f5 2021-12-28 cage switch (r = tls_read(ctx, d, len)) {
138 423f02f5 2021-12-28 cage case TLS_WANT_POLLIN:
139 423f02f5 2021-12-28 cage case TLS_WANT_POLLOUT:
140 423f02f5 2021-12-28 cage continue;
141 423f02f5 2021-12-28 cage case -1:
142 423f02f5 2021-12-28 cage errx(1, "tls: %s", tls_error(ctx));
143 423f02f5 2021-12-28 cage default:
144 423f02f5 2021-12-28 cage d += r;
145 423f02f5 2021-12-28 cage len -= r;
146 423f02f5 2021-12-28 cage }
147 423f02f5 2021-12-28 cage }
148 423f02f5 2021-12-28 cage }
149 423f02f5 2021-12-28 cage
150 423f02f5 2021-12-28 cage static void
151 423f02f5 2021-12-28 cage recv_msg(void)
152 423f02f5 2021-12-28 cage {
153 423f02f5 2021-12-28 cage uint32_t len;
154 423f02f5 2021-12-28 cage ssize_t r;
155 423f02f5 2021-12-28 cage char tmp[BUFSIZ];
156 423f02f5 2021-12-28 cage
157 423f02f5 2021-12-28 cage mustread(&len, sizeof(len));
158 423f02f5 2021-12-28 cage len = le32toh(len);
159 423f02f5 2021-12-28 cage if (len < HEADERSIZE)
160 423f02f5 2021-12-28 cage errx(1, "read message of invalid length %d", len);
161 423f02f5 2021-12-28 cage
162 423f02f5 2021-12-28 cage len -= 4; /* skip the length just read */
163 423f02f5 2021-12-28 cage
164 423f02f5 2021-12-28 cage while (len != 0) {
165 423f02f5 2021-12-28 cage switch (r = tls_read(ctx, tmp, sizeof(tmp))) {
166 423f02f5 2021-12-28 cage case TLS_WANT_POLLIN:
167 423f02f5 2021-12-28 cage case TLS_WANT_POLLOUT:
168 423f02f5 2021-12-28 cage continue;
169 423f02f5 2021-12-28 cage case -1:
170 423f02f5 2021-12-28 cage errx(1, "tls: %s", tls_error(ctx));
171 423f02f5 2021-12-28 cage default:
172 423f02f5 2021-12-28 cage len -= r;
173 423f02f5 2021-12-28 cage evbuffer_add(buf, tmp, r);
174 423f02f5 2021-12-28 cage }
175 423f02f5 2021-12-28 cage }
176 423f02f5 2021-12-28 cage }
177 423f02f5 2021-12-28 cage
178 423f02f5 2021-12-28 cage static uint64_t
179 423f02f5 2021-12-28 cage np_read64(struct evbuffer *buf)
180 423f02f5 2021-12-28 cage {
181 423f02f5 2021-12-28 cage uint64_t n;
182 423f02f5 2021-12-28 cage
183 423f02f5 2021-12-28 cage evbuffer_remove(buf, &n, sizeof(n));
184 423f02f5 2021-12-28 cage return le64toh(n);
185 423f02f5 2021-12-28 cage }
186 423f02f5 2021-12-28 cage
187 423f02f5 2021-12-28 cage static uint32_t
188 423f02f5 2021-12-28 cage np_read32(struct evbuffer *buf)
189 423f02f5 2021-12-28 cage {
190 423f02f5 2021-12-28 cage uint32_t n;
191 423f02f5 2021-12-28 cage
192 423f02f5 2021-12-28 cage evbuffer_remove(buf, &n, sizeof(n));
193 423f02f5 2021-12-28 cage return le32toh(n);
194 423f02f5 2021-12-28 cage }
195 423f02f5 2021-12-28 cage
196 423f02f5 2021-12-28 cage static uint16_t
197 423f02f5 2021-12-28 cage np_read16(struct evbuffer *buf)
198 423f02f5 2021-12-28 cage {
199 423f02f5 2021-12-28 cage uint16_t n;
200 423f02f5 2021-12-28 cage
201 423f02f5 2021-12-28 cage evbuffer_remove(buf, &n, sizeof(n));
202 423f02f5 2021-12-28 cage return le16toh(n);
203 423f02f5 2021-12-28 cage }
204 423f02f5 2021-12-28 cage
205 423f02f5 2021-12-28 cage static uint16_t
206 423f02f5 2021-12-28 cage np_read8(struct evbuffer *buf)
207 423f02f5 2021-12-28 cage {
208 423f02f5 2021-12-28 cage uint8_t n;
209 423f02f5 2021-12-28 cage
210 423f02f5 2021-12-28 cage evbuffer_remove(buf, &n, sizeof(n));
211 423f02f5 2021-12-28 cage return n;
212 423f02f5 2021-12-28 cage }
213 423f02f5 2021-12-28 cage
214 423f02f5 2021-12-28 cage static char *
215 423f02f5 2021-12-28 cage np_readstr(struct evbuffer *buf)
216 423f02f5 2021-12-28 cage {
217 423f02f5 2021-12-28 cage uint16_t len;
218 423f02f5 2021-12-28 cage char *str;
219 423f02f5 2021-12-28 cage
220 423f02f5 2021-12-28 cage len = np_read16(buf);
221 423f02f5 2021-12-28 cage assert(EVBUFFER_LENGTH(buf) >= len);
222 423f02f5 2021-12-28 cage
223 423f02f5 2021-12-28 cage if ((str = calloc(1, len+1)) == NULL)
224 423f02f5 2021-12-28 cage err(1, "calloc");
225 423f02f5 2021-12-28 cage evbuffer_remove(buf, str, len);
226 423f02f5 2021-12-28 cage return str;
227 423f02f5 2021-12-28 cage }
228 423f02f5 2021-12-28 cage
229 423f02f5 2021-12-28 cage static void
230 423f02f5 2021-12-28 cage np_read_qid(struct evbuffer *buf, struct qid *qid)
231 423f02f5 2021-12-28 cage {
232 423f02f5 2021-12-28 cage assert(EVBUFFER_LENGTH(buf) >= QIDSIZE);
233 423f02f5 2021-12-28 cage
234 423f02f5 2021-12-28 cage qid->type = np_read8(buf);
235 423f02f5 2021-12-28 cage qid->vers = np_read32(buf);
236 423f02f5 2021-12-28 cage qid->path = np_read64(buf);
237 423f02f5 2021-12-28 cage }
238 423f02f5 2021-12-28 cage
239 423f02f5 2021-12-28 cage static void
240 423f02f5 2021-12-28 cage expect(uint8_t type)
241 423f02f5 2021-12-28 cage {
242 423f02f5 2021-12-28 cage uint8_t t;
243 423f02f5 2021-12-28 cage
244 423f02f5 2021-12-28 cage t = np_read8(buf);
245 423f02f5 2021-12-28 cage if (t == type)
246 423f02f5 2021-12-28 cage return;
247 423f02f5 2021-12-28 cage
248 423f02f5 2021-12-28 cage if (t == Terror) {
249 423f02f5 2021-12-28 cage char *err;
250 423f02f5 2021-12-28 cage
251 423f02f5 2021-12-28 cage err = np_readstr(buf);
252 423f02f5 2021-12-28 cage errx(1, "expected %s, got error %s",
253 423f02f5 2021-12-28 cage pp_msg_type(type), err);
254 423f02f5 2021-12-28 cage }
255 423f02f5 2021-12-28 cage
256 423f02f5 2021-12-28 cage errx(1, "expected %s, got msg type %s",
257 423f02f5 2021-12-28 cage pp_msg_type(type), pp_msg_type(t));
258 423f02f5 2021-12-28 cage }
259 423f02f5 2021-12-28 cage
260 423f02f5 2021-12-28 cage static void
261 423f02f5 2021-12-28 cage expect2(uint8_t type, uint16_t tag)
262 423f02f5 2021-12-28 cage {
263 423f02f5 2021-12-28 cage uint16_t t;
264 423f02f5 2021-12-28 cage
265 423f02f5 2021-12-28 cage expect(type);
266 423f02f5 2021-12-28 cage
267 423f02f5 2021-12-28 cage t = np_read16(buf);
268 423f02f5 2021-12-28 cage if (t == tag)
269 423f02f5 2021-12-28 cage return;
270 423f02f5 2021-12-28 cage
271 423f02f5 2021-12-28 cage errx(1, "expected tag 0x%x, got 0x%x", tag, t);
272 423f02f5 2021-12-28 cage }
273 423f02f5 2021-12-28 cage
274 423f02f5 2021-12-28 cage static void
275 ce3844d2 2021-12-14 op do_version(void)
276 ce3844d2 2021-12-14 op {
277 423f02f5 2021-12-28 cage char *version;
278 423f02f5 2021-12-28 cage
279 ce3844d2 2021-12-14 op tversion(VERSION9P, MSIZE9P);
280 423f02f5 2021-12-28 cage do_send();
281 423f02f5 2021-12-28 cage recv_msg();
282 423f02f5 2021-12-28 cage expect2(Rversion, NOTAG);
283 423f02f5 2021-12-28 cage
284 423f02f5 2021-12-28 cage msize = np_read32(buf);
285 423f02f5 2021-12-28 cage version = np_readstr(buf);
286 423f02f5 2021-12-28 cage
287 423f02f5 2021-12-28 cage if (msize > MSIZE9P)
288 423f02f5 2021-12-28 cage errx(1, "got unexpected msize: %d", msize);
289 423f02f5 2021-12-28 cage if (strcmp(version, VERSION9P))
290 423f02f5 2021-12-28 cage errx(1, "unexpected 9p version: %s", version);
291 423f02f5 2021-12-28 cage
292 423f02f5 2021-12-28 cage free(version);
293 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
294 ce3844d2 2021-12-14 op }
295 ce3844d2 2021-12-14 op
296 ce3844d2 2021-12-14 op static void
297 ce3844d2 2021-12-14 op do_attach(const char *path)
298 ce3844d2 2021-12-14 op {
299 423f02f5 2021-12-28 cage const char *user;
300 423f02f5 2021-12-28 cage struct qid qid;
301 423f02f5 2021-12-28 cage
302 ce3844d2 2021-12-14 op if (path == NULL)
303 ce3844d2 2021-12-14 op path = "/";
304 423f02f5 2021-12-28 cage if ((user = getenv("USER")) == NULL)
305 423f02f5 2021-12-28 cage user = "flan";
306 ce3844d2 2021-12-14 op
307 423f02f5 2021-12-28 cage tattach(PWDFID, NOFID, user, path);
308 423f02f5 2021-12-28 cage do_send();
309 423f02f5 2021-12-28 cage recv_msg();
310 423f02f5 2021-12-28 cage expect2(Rattach, iota_tag);
311 423f02f5 2021-12-28 cage np_read_qid(buf, &qid);
312 423f02f5 2021-12-28 cage
313 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
314 423f02f5 2021-12-28 cage }
315 423f02f5 2021-12-28 cage
316 423f02f5 2021-12-28 cage static uint32_t
317 423f02f5 2021-12-28 cage do_open(uint32_t fid, uint8_t mode)
318 423f02f5 2021-12-28 cage {
319 423f02f5 2021-12-28 cage struct qid qid;
320 423f02f5 2021-12-28 cage uint32_t iounit;
321 423f02f5 2021-12-28 cage
322 423f02f5 2021-12-28 cage topen(fid, mode);
323 423f02f5 2021-12-28 cage do_send();
324 423f02f5 2021-12-28 cage recv_msg();
325 423f02f5 2021-12-28 cage expect2(Ropen, iota_tag);
326 423f02f5 2021-12-28 cage
327 423f02f5 2021-12-28 cage np_read_qid(buf, &qid);
328 423f02f5 2021-12-28 cage iounit = np_read32(buf);
329 423f02f5 2021-12-28 cage
330 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
331 423f02f5 2021-12-28 cage
332 423f02f5 2021-12-28 cage return iounit;
333 ce3844d2 2021-12-14 op }
334 ce3844d2 2021-12-14 op
335 ce3844d2 2021-12-14 op static void
336 423f02f5 2021-12-28 cage do_clunk(uint32_t fid)
337 423f02f5 2021-12-28 cage {
338 423f02f5 2021-12-28 cage tclunk(fid);
339 423f02f5 2021-12-28 cage do_send();
340 423f02f5 2021-12-28 cage recv_msg();
341 423f02f5 2021-12-28 cage expect2(Rclunk, iota_tag);
342 423f02f5 2021-12-28 cage
343 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
344 423f02f5 2021-12-28 cage }
345 423f02f5 2021-12-28 cage
346 423f02f5 2021-12-28 cage static void
347 423f02f5 2021-12-28 cage dup_fid(int fid, int nfid)
348 423f02f5 2021-12-28 cage {
349 423f02f5 2021-12-28 cage uint16_t nwqid;
350 423f02f5 2021-12-28 cage
351 423f02f5 2021-12-28 cage twalk(fid, nfid, NULL, 0);
352 423f02f5 2021-12-28 cage do_send();
353 423f02f5 2021-12-28 cage recv_msg();
354 423f02f5 2021-12-28 cage expect2(Rwalk, iota_tag);
355 423f02f5 2021-12-28 cage
356 423f02f5 2021-12-28 cage nwqid = np_read16(buf);
357 423f02f5 2021-12-28 cage assert(nwqid == 0);
358 423f02f5 2021-12-28 cage
359 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
360 423f02f5 2021-12-28 cage }
361 423f02f5 2021-12-28 cage
362 423f02f5 2021-12-28 cage static void
363 ce3844d2 2021-12-14 op do_connect(const char *connspec, const char *path)
364 ce3844d2 2021-12-14 op {
365 ce3844d2 2021-12-14 op int handshake;
366 ce3844d2 2021-12-14 op char *host, *colon;
367 ce3844d2 2021-12-14 op const char *port;
368 ce3844d2 2021-12-14 op
369 ce3844d2 2021-12-14 op host = xstrdup(connspec);
370 ce3844d2 2021-12-14 op if ((colon = strchr(host, ':')) != NULL) {
371 ce3844d2 2021-12-14 op *colon = '\0';
372 ce3844d2 2021-12-14 op port = ++colon;
373 ce3844d2 2021-12-14 op } else
374 ce3844d2 2021-12-14 op port = "1337";
375 ce3844d2 2021-12-14 op
376 ce3844d2 2021-12-14 op if (!tls)
377 ce3844d2 2021-12-14 op fatalx("non-tls mode is not supported");
378 ce3844d2 2021-12-14 op
379 ce3844d2 2021-12-14 op if ((tlsconf = tls_config_new()) == NULL)
380 ce3844d2 2021-12-14 op fatalx("tls_config_new");
381 ce3844d2 2021-12-14 op tls_config_insecure_noverifycert(tlsconf);
382 ce3844d2 2021-12-14 op tls_config_insecure_noverifyname(tlsconf);
383 ce3844d2 2021-12-14 op if (tls_config_set_keypair_file(tlsconf, crtpath, keypath) == -1)
384 ce3844d2 2021-12-14 op fatalx("can't load certs (%s, %s)", crtpath, keypath);
385 ce3844d2 2021-12-14 op
386 ce3844d2 2021-12-14 op if ((ctx = tls_client()) == NULL)
387 ce3844d2 2021-12-14 op fatal("tls_client");
388 ce3844d2 2021-12-14 op if (tls_configure(ctx, tlsconf) == -1)
389 ce3844d2 2021-12-14 op fatalx("tls_configure: %s", tls_error(ctx));
390 ce3844d2 2021-12-14 op
391 ce3844d2 2021-12-14 op printf("connecting to %s:%s...", host, port);
392 ce3844d2 2021-12-14 op fflush(stdout);
393 ce3844d2 2021-12-14 op
394 ce3844d2 2021-12-14 op if (tls_connect(ctx, host, port) == -1)
395 ce3844d2 2021-12-14 op fatalx("can't connect to %s:%s: %s", host, port,
396 ce3844d2 2021-12-14 op tls_error(ctx));
397 ce3844d2 2021-12-14 op
398 ce3844d2 2021-12-14 op for (handshake = 0; !handshake;) {
399 ce3844d2 2021-12-14 op switch (tls_handshake(ctx)) {
400 ce3844d2 2021-12-14 op case -1:
401 ce3844d2 2021-12-14 op fatalx("tls_handshake: %s", tls_error(ctx));
402 ce3844d2 2021-12-14 op case 0:
403 ce3844d2 2021-12-14 op handshake = 1;
404 ce3844d2 2021-12-14 op break;
405 ce3844d2 2021-12-14 op }
406 ce3844d2 2021-12-14 op }
407 ce3844d2 2021-12-14 op
408 ce3844d2 2021-12-14 op printf(" done!\n");
409 ce3844d2 2021-12-14 op
410 ce3844d2 2021-12-14 op do_version();
411 ce3844d2 2021-12-14 op do_attach(path);
412 ce3844d2 2021-12-14 op
413 ce3844d2 2021-12-14 op free(host);
414 ce3844d2 2021-12-14 op }
415 ce3844d2 2021-12-14 op
416 423f02f5 2021-12-28 cage static void
417 423f02f5 2021-12-28 cage cmd_bell(int argc, const char **argv)
418 423f02f5 2021-12-28 cage {
419 423f02f5 2021-12-28 cage if (argc == 0) {
420 423f02f5 2021-12-28 cage bell = !bell;
421 423f02f5 2021-12-28 cage if (bell)
422 423f02f5 2021-12-28 cage puts("bell mode enabled");
423 423f02f5 2021-12-28 cage else
424 423f02f5 2021-12-28 cage puts("bell mode disabled");
425 423f02f5 2021-12-28 cage return;
426 423f02f5 2021-12-28 cage }
427 423f02f5 2021-12-28 cage
428 423f02f5 2021-12-28 cage if (argc != 1)
429 423f02f5 2021-12-28 cage goto usage;
430 423f02f5 2021-12-28 cage
431 423f02f5 2021-12-28 cage if (!strcmp(*argv, "on")) {
432 423f02f5 2021-12-28 cage bell = 1;
433 423f02f5 2021-12-28 cage puts("bell mode enabled");
434 423f02f5 2021-12-28 cage return;
435 423f02f5 2021-12-28 cage }
436 423f02f5 2021-12-28 cage
437 423f02f5 2021-12-28 cage if (!strcmp(*argv, "off")) {
438 423f02f5 2021-12-28 cage bell = 0;
439 423f02f5 2021-12-28 cage puts("bell mode disabled");
440 423f02f5 2021-12-28 cage return;
441 423f02f5 2021-12-28 cage }
442 423f02f5 2021-12-28 cage
443 423f02f5 2021-12-28 cage usage:
444 423f02f5 2021-12-28 cage printf("bell [on | off]\n");
445 423f02f5 2021-12-28 cage }
446 423f02f5 2021-12-28 cage
447 423f02f5 2021-12-28 cage static void
448 423f02f5 2021-12-28 cage cmd_bye(int argc, const char **argv)
449 423f02f5 2021-12-28 cage {
450 423f02f5 2021-12-28 cage log_warnx("bye\n");
451 423f02f5 2021-12-28 cage exit(0);
452 423f02f5 2021-12-28 cage }
453 423f02f5 2021-12-28 cage
454 423f02f5 2021-12-28 cage static void
455 423f02f5 2021-12-28 cage cmd_ls(int argc, const char **argv)
456 423f02f5 2021-12-28 cage {
457 423f02f5 2021-12-28 cage uint64_t off = 0;
458 423f02f5 2021-12-28 cage uint32_t len;
459 423f02f5 2021-12-28 cage
460 423f02f5 2021-12-28 cage if (argc != 0) {
461 423f02f5 2021-12-28 cage printf("ls don't take arguments (yet)\n");
462 423f02f5 2021-12-28 cage return;
463 423f02f5 2021-12-28 cage }
464 423f02f5 2021-12-28 cage
465 423f02f5 2021-12-28 cage dup_fid(PWDFID, 1);
466 423f02f5 2021-12-28 cage do_open(1, KOREAD);
467 423f02f5 2021-12-28 cage
468 423f02f5 2021-12-28 cage evbuffer_drain(dirbuf, EVBUFFER_LENGTH(dirbuf));
469 423f02f5 2021-12-28 cage
470 423f02f5 2021-12-28 cage for (;;) {
471 423f02f5 2021-12-28 cage tread(1, off, BUFSIZ);
472 423f02f5 2021-12-28 cage do_send();
473 423f02f5 2021-12-28 cage recv_msg();
474 423f02f5 2021-12-28 cage expect2(Rread, iota_tag);
475 423f02f5 2021-12-28 cage
476 423f02f5 2021-12-28 cage len = np_read32(buf);
477 423f02f5 2021-12-28 cage if (len == 0)
478 423f02f5 2021-12-28 cage break;
479 423f02f5 2021-12-28 cage
480 423f02f5 2021-12-28 cage evbuffer_add_buffer(dirbuf, buf);
481 423f02f5 2021-12-28 cage off += len;
482 423f02f5 2021-12-28 cage
483 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
484 423f02f5 2021-12-28 cage }
485 423f02f5 2021-12-28 cage
486 423f02f5 2021-12-28 cage while (EVBUFFER_LENGTH(dirbuf) != 0) {
487 423f02f5 2021-12-28 cage struct qid qid;
488 423f02f5 2021-12-28 cage uint64_t len;
489 423f02f5 2021-12-28 cage uint16_t size;
490 423f02f5 2021-12-28 cage char *name;
491 423f02f5 2021-12-28 cage
492 423f02f5 2021-12-28 cage size = np_read16(dirbuf);
493 423f02f5 2021-12-28 cage assert(size <= EVBUFFER_LENGTH(dirbuf));
494 423f02f5 2021-12-28 cage
495 423f02f5 2021-12-28 cage np_read16(dirbuf); /* skip type */
496 423f02f5 2021-12-28 cage np_read32(dirbuf); /* skip dev */
497 423f02f5 2021-12-28 cage
498 423f02f5 2021-12-28 cage np_read_qid(dirbuf, &qid);
499 423f02f5 2021-12-28 cage printf("%s ", pp_qid_type(qid.type));
500 423f02f5 2021-12-28 cage
501 423f02f5 2021-12-28 cage np_read32(dirbuf); /* skip mode */
502 423f02f5 2021-12-28 cage np_read32(dirbuf); /* skip atime */
503 423f02f5 2021-12-28 cage np_read32(dirbuf); /* skip mtime */
504 423f02f5 2021-12-28 cage
505 423f02f5 2021-12-28 cage len = np_read64(dirbuf);
506 423f02f5 2021-12-28 cage printf("%llu ", (unsigned long long)len);
507 423f02f5 2021-12-28 cage
508 423f02f5 2021-12-28 cage name = np_readstr(dirbuf);
509 423f02f5 2021-12-28 cage printf("%s\n", name);
510 423f02f5 2021-12-28 cage free(name);
511 423f02f5 2021-12-28 cage
512 423f02f5 2021-12-28 cage free(np_readstr(dirbuf)); /* skip uid */
513 423f02f5 2021-12-28 cage free(np_readstr(dirbuf)); /* skip gid */
514 423f02f5 2021-12-28 cage free(np_readstr(dirbuf)); /* skip muid */
515 423f02f5 2021-12-28 cage }
516 423f02f5 2021-12-28 cage
517 423f02f5 2021-12-28 cage do_clunk(1);
518 423f02f5 2021-12-28 cage }
519 423f02f5 2021-12-28 cage
520 423f02f5 2021-12-28 cage static void
521 423f02f5 2021-12-28 cage cmd_verbose(int argc, const char **argv)
522 423f02f5 2021-12-28 cage {
523 423f02f5 2021-12-28 cage if (argc == 0) {
524 423f02f5 2021-12-28 cage log_setverbose(!log_getverbose());
525 423f02f5 2021-12-28 cage if (log_getverbose())
526 423f02f5 2021-12-28 cage puts("verbose mode enabled");
527 423f02f5 2021-12-28 cage else
528 423f02f5 2021-12-28 cage puts("verbose mode disabled");
529 423f02f5 2021-12-28 cage return;
530 423f02f5 2021-12-28 cage }
531 423f02f5 2021-12-28 cage
532 423f02f5 2021-12-28 cage if (argc != 1)
533 423f02f5 2021-12-28 cage goto usage;
534 423f02f5 2021-12-28 cage
535 423f02f5 2021-12-28 cage if (!strcmp(*argv, "on")) {
536 423f02f5 2021-12-28 cage log_setverbose(1);
537 423f02f5 2021-12-28 cage puts("verbose mode enabled");
538 423f02f5 2021-12-28 cage return;
539 423f02f5 2021-12-28 cage }
540 423f02f5 2021-12-28 cage
541 423f02f5 2021-12-28 cage if (!strcmp(*argv, "off")) {
542 423f02f5 2021-12-28 cage log_setverbose(0);
543 423f02f5 2021-12-28 cage puts("verbose mode disabled");
544 423f02f5 2021-12-28 cage return;
545 423f02f5 2021-12-28 cage }
546 423f02f5 2021-12-28 cage
547 423f02f5 2021-12-28 cage usage:
548 423f02f5 2021-12-28 cage printf("verbose [on | off]\n");
549 423f02f5 2021-12-28 cage }
550 423f02f5 2021-12-28 cage
551 423f02f5 2021-12-28 cage static void
552 423f02f5 2021-12-28 cage excmd(int argc, const char **argv)
553 423f02f5 2021-12-28 cage {
554 423f02f5 2021-12-28 cage struct cmd {
555 423f02f5 2021-12-28 cage const char *name;
556 423f02f5 2021-12-28 cage void (*fn)(int, const char **);
557 423f02f5 2021-12-28 cage } cmds[] = {
558 423f02f5 2021-12-28 cage {"bell", cmd_bell},
559 423f02f5 2021-12-28 cage {"bye", cmd_bye},
560 423f02f5 2021-12-28 cage {"ls", cmd_ls},
561 423f02f5 2021-12-28 cage {"quit", cmd_bye},
562 423f02f5 2021-12-28 cage {"verbose", cmd_verbose},
563 423f02f5 2021-12-28 cage };
564 423f02f5 2021-12-28 cage size_t i;
565 423f02f5 2021-12-28 cage
566 423f02f5 2021-12-28 cage if (argc == 0)
567 423f02f5 2021-12-28 cage return;
568 423f02f5 2021-12-28 cage for (i = 0; i < nitems(cmds); ++i) {
569 423f02f5 2021-12-28 cage if (!strcmp(cmds[i].name, *argv)) {
570 423f02f5 2021-12-28 cage cmds[i].fn(argc-1, argv+1);
571 423f02f5 2021-12-28 cage return;
572 423f02f5 2021-12-28 cage }
573 423f02f5 2021-12-28 cage }
574 423f02f5 2021-12-28 cage
575 423f02f5 2021-12-28 cage log_warnx("unknown command %s", *argv);
576 423f02f5 2021-12-28 cage }
577 423f02f5 2021-12-28 cage
578 ce3844d2 2021-12-14 op int
579 ce3844d2 2021-12-14 op main(int argc, char **argv)
580 ce3844d2 2021-12-14 op {
581 ce3844d2 2021-12-14 op int ch;
582 ce3844d2 2021-12-14 op
583 ce3844d2 2021-12-14 op log_init(1, LOG_DAEMON);
584 423f02f5 2021-12-28 cage log_setverbose(0);
585 ce3844d2 2021-12-14 op log_procinit(getprogname());
586 ce3844d2 2021-12-14 op
587 ce3844d2 2021-12-14 op while ((ch = getopt(argc, argv, "C:cK:")) != -1) {
588 ce3844d2 2021-12-14 op switch (ch) {
589 ce3844d2 2021-12-14 op case 'C':
590 ce3844d2 2021-12-14 op crtpath = optarg;
591 ce3844d2 2021-12-14 op break;
592 ce3844d2 2021-12-14 op case 'c':
593 ce3844d2 2021-12-14 op tls = 1;
594 ce3844d2 2021-12-14 op break;
595 ce3844d2 2021-12-14 op case 'K':
596 ce3844d2 2021-12-14 op keypath = optarg;
597 ce3844d2 2021-12-14 op break;
598 ce3844d2 2021-12-14 op default:
599 ce3844d2 2021-12-14 op usage(1);
600 ce3844d2 2021-12-14 op }
601 ce3844d2 2021-12-14 op }
602 ce3844d2 2021-12-14 op argc -= optind;
603 ce3844d2 2021-12-14 op argv += optind;
604 ce3844d2 2021-12-14 op
605 ce3844d2 2021-12-14 op if (argc == 0)
606 ce3844d2 2021-12-14 op usage(1);
607 ce3844d2 2021-12-14 op
608 ce3844d2 2021-12-14 op if ((evb = evbuffer_new()) == NULL)
609 ce3844d2 2021-12-14 op fatal("evbuffer_new");
610 ce3844d2 2021-12-14 op
611 423f02f5 2021-12-28 cage if ((buf = evbuffer_new()) == NULL)
612 423f02f5 2021-12-28 cage fatal("evbuffer_new");
613 423f02f5 2021-12-28 cage
614 423f02f5 2021-12-28 cage if ((dirbuf = evbuffer_new()) == NULL)
615 423f02f5 2021-12-28 cage fatal("evbuferr_new");
616 423f02f5 2021-12-28 cage
617 ce3844d2 2021-12-14 op do_connect(argv[0], argv[1]);
618 ce3844d2 2021-12-14 op
619 423f02f5 2021-12-28 cage /* cmd_ls(0, NULL); */
620 423f02f5 2021-12-28 cage
621 ce3844d2 2021-12-14 op for (;;) {
622 423f02f5 2021-12-28 cage int argc = 0;
623 423f02f5 2021-12-28 cage char *line, *argv[16] = {0}, **ap;
624 ce3844d2 2021-12-14 op
625 423f02f5 2021-12-28 cage if ((line = read_line("kamiftp> ")) == NULL)
626 ce3844d2 2021-12-14 op break;
627 423f02f5 2021-12-28 cage
628 423f02f5 2021-12-28 cage for (argc = 0, ap = argv; ap < &argv[15] &&
629 423f02f5 2021-12-28 cage (*ap = strsep(&line, " \t")) != NULL;) {
630 423f02f5 2021-12-28 cage if (**ap != '\0')
631 423f02f5 2021-12-28 cage ap++, argc++;
632 423f02f5 2021-12-28 cage }
633 423f02f5 2021-12-28 cage excmd(argc, (const char **)argv);
634 423f02f5 2021-12-28 cage
635 423f02f5 2021-12-28 cage if (bell) {
636 423f02f5 2021-12-28 cage printf("\a");
637 423f02f5 2021-12-28 cage fflush(stdout);
638 423f02f5 2021-12-28 cage }
639 423f02f5 2021-12-28 cage
640 423f02f5 2021-12-28 cage free(line);
641 ce3844d2 2021-12-14 op }
642 ce3844d2 2021-12-14 op
643 ce3844d2 2021-12-14 op printf("\n");
644 ce3844d2 2021-12-14 op }