2 ce3844d2 2021-12-14 op * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
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.
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.
17 ce3844d2 2021-12-14 op #include "compat.h"
19 ce3844d2 2021-12-14 op #include <sys/types.h>
20 ce3844d2 2021-12-14 op #include <sys/socket.h>
22 423f02f5 2021-12-28 cage #include <assert.h>
23 3f03529f 2021-12-28 op #include <errno.h>
24 ce3844d2 2021-12-14 op #include <netdb.h>
25 ce3844d2 2021-12-14 op #include <limits.h>
26 ce3844d2 2021-12-14 op #include <stdio.h>
27 ce3844d2 2021-12-14 op #include <stdlib.h>
28 ce3844d2 2021-12-14 op #include <string.h>
29 ce3844d2 2021-12-14 op #include <syslog.h>
30 ce3844d2 2021-12-14 op #include <tls.h>
31 ce3844d2 2021-12-14 op #include <unistd.h>
33 423f02f5 2021-12-28 cage #if HAVE_LIBREADLINE
34 ce3844d2 2021-12-14 op #include <readline/readline.h>
35 ce3844d2 2021-12-14 op #include <readline/history.h>
38 423f02f5 2021-12-28 cage #ifndef nitems
39 423f02f5 2021-12-28 cage #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
42 ce3844d2 2021-12-14 op #include "9pclib.h"
43 ce3844d2 2021-12-14 op #include "kamid.h"
44 ce3844d2 2021-12-14 op #include "utils.h"
45 ce3844d2 2021-12-14 op #include "log.h"
49 ce3844d2 2021-12-14 op const char *crtpath;
50 ce3844d2 2021-12-14 op const char *keypath;
53 ce3844d2 2021-12-14 op struct tls_config *tlsconf;
54 ce3844d2 2021-12-14 op struct tls *ctx;
56 423f02f5 2021-12-28 cage struct evbuffer *buf;
57 423f02f5 2021-12-28 cage struct evbuffer *dirbuf;
58 423f02f5 2021-12-28 cage uint32_t msize;
61 ce3844d2 2021-12-14 op #define PWDFID 0
63 423f02f5 2021-12-28 cage #define ASSERT_EMPTYBUF() assert(EVBUFFER_LENGTH(buf) == 0)
65 423f02f5 2021-12-28 cage #if HAVE_LIBREADLINE
67 688f54f0 2021-12-14 op read_line(const char *prompt)
72 688f54f0 2021-12-14 op if ((line = readline(prompt)) == NULL)
74 688f54f0 2021-12-14 op /* XXX: trim spaces? */
75 688f54f0 2021-12-14 op if (*line == '\0') {
80 688f54f0 2021-12-14 op add_history(line);
85 688f54f0 2021-12-14 op read_line(const char *prompt)
87 688f54f0 2021-12-14 op char *ch, *line = NULL;
88 688f54f0 2021-12-14 op size_t linesize = 0;
89 688f54f0 2021-12-14 op ssize_t linelen;
91 423f02f5 2021-12-28 cage printf("%s", prompt);
92 423f02f5 2021-12-28 cage fflush(stdout);
94 688f54f0 2021-12-14 op linelen = getline(&line, &linesize, stdin);
95 688f54f0 2021-12-14 op if (linelen == -1)
98 688f54f0 2021-12-14 op if ((ch = strchr(line, '\n')) != NULL)
104 a97ec9eb 2021-12-23 op static void __dead
105 ce3844d2 2021-12-14 op usage(int ret)
107 ce3844d2 2021-12-14 op fprintf(stderr, "usage: %s [-c] host[:port] [path]\n",
108 ce3844d2 2021-12-14 op getprogname());
109 ce3844d2 2021-12-14 op fprintf(stderr, PACKAGE_NAME " suite version " PACKAGE VERSION "\n");
114 423f02f5 2021-12-28 cage do_send(void)
116 3f03529f 2021-12-28 op const void *buf;
117 3f03529f 2021-12-28 op size_t nbytes;
120 423f02f5 2021-12-28 cage while (EVBUFFER_LENGTH(evb) != 0) {
121 3f03529f 2021-12-28 op buf = EVBUFFER_DATA(evb);
122 3f03529f 2021-12-28 op nbytes = EVBUFFER_LENGTH(evb);
124 3f03529f 2021-12-28 op if (ctx == NULL) {
125 3f03529f 2021-12-28 op r = write(sock, buf, nbytes);
126 3f03529f 2021-12-28 op if (r == 0 || r == -1)
127 3f03529f 2021-12-28 op errx(1, "EOF");
129 3f03529f 2021-12-28 op r = tls_write(ctx, buf, nbytes);
130 3f03529f 2021-12-28 op if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT)
133 3f03529f 2021-12-28 op errx(1, "tls: %s", tls_error(ctx));
136 3f03529f 2021-12-28 op evbuffer_drain(evb, r);
140 423f02f5 2021-12-28 cage static void
141 423f02f5 2021-12-28 cage mustread(void *d, size_t len)
145 423f02f5 2021-12-28 cage while (len != 0) {
146 3f03529f 2021-12-28 op if (ctx == NULL) {
147 3f03529f 2021-12-28 op r = read(sock, d, len);
148 3f03529f 2021-12-28 op if (r == 0 || r == -1)
149 3f03529f 2021-12-28 op errx(1, "EOF");
151 3f03529f 2021-12-28 op r = tls_read(ctx, d, len);
152 3f03529f 2021-12-28 op if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT)
155 3f03529f 2021-12-28 op errx(1, "tls: %s", tls_error(ctx));
163 423f02f5 2021-12-28 cage static void
164 423f02f5 2021-12-28 cage recv_msg(void)
166 3f03529f 2021-12-28 op uint32_t len, l;
167 423f02f5 2021-12-28 cage char tmp[BUFSIZ];
169 423f02f5 2021-12-28 cage mustread(&len, sizeof(len));
170 423f02f5 2021-12-28 cage len = le32toh(len);
171 423f02f5 2021-12-28 cage if (len < HEADERSIZE)
172 423f02f5 2021-12-28 cage errx(1, "read message of invalid length %d", len);
174 423f02f5 2021-12-28 cage len -= 4; /* skip the length just read */
176 423f02f5 2021-12-28 cage while (len != 0) {
177 3f03529f 2021-12-28 op l = MIN(len, sizeof(tmp));
178 3f03529f 2021-12-28 op mustread(tmp, l);
180 3f03529f 2021-12-28 op evbuffer_add(buf, tmp, l);
184 423f02f5 2021-12-28 cage static uint64_t
185 423f02f5 2021-12-28 cage np_read64(struct evbuffer *buf)
187 423f02f5 2021-12-28 cage uint64_t n;
189 423f02f5 2021-12-28 cage evbuffer_remove(buf, &n, sizeof(n));
190 423f02f5 2021-12-28 cage return le64toh(n);
193 423f02f5 2021-12-28 cage static uint32_t
194 423f02f5 2021-12-28 cage np_read32(struct evbuffer *buf)
196 423f02f5 2021-12-28 cage uint32_t n;
198 423f02f5 2021-12-28 cage evbuffer_remove(buf, &n, sizeof(n));
199 423f02f5 2021-12-28 cage return le32toh(n);
202 423f02f5 2021-12-28 cage static uint16_t
203 423f02f5 2021-12-28 cage np_read16(struct evbuffer *buf)
205 423f02f5 2021-12-28 cage uint16_t n;
207 423f02f5 2021-12-28 cage evbuffer_remove(buf, &n, sizeof(n));
208 423f02f5 2021-12-28 cage return le16toh(n);
211 423f02f5 2021-12-28 cage static uint16_t
212 423f02f5 2021-12-28 cage np_read8(struct evbuffer *buf)
216 423f02f5 2021-12-28 cage evbuffer_remove(buf, &n, sizeof(n));
220 423f02f5 2021-12-28 cage static char *
221 423f02f5 2021-12-28 cage np_readstr(struct evbuffer *buf)
223 423f02f5 2021-12-28 cage uint16_t len;
226 423f02f5 2021-12-28 cage len = np_read16(buf);
227 423f02f5 2021-12-28 cage assert(EVBUFFER_LENGTH(buf) >= len);
229 423f02f5 2021-12-28 cage if ((str = calloc(1, len+1)) == NULL)
230 423f02f5 2021-12-28 cage err(1, "calloc");
231 423f02f5 2021-12-28 cage evbuffer_remove(buf, str, len);
232 423f02f5 2021-12-28 cage return str;
235 423f02f5 2021-12-28 cage static void
236 423f02f5 2021-12-28 cage np_read_qid(struct evbuffer *buf, struct qid *qid)
238 423f02f5 2021-12-28 cage assert(EVBUFFER_LENGTH(buf) >= QIDSIZE);
240 423f02f5 2021-12-28 cage qid->type = np_read8(buf);
241 423f02f5 2021-12-28 cage qid->vers = np_read32(buf);
242 423f02f5 2021-12-28 cage qid->path = np_read64(buf);
245 423f02f5 2021-12-28 cage static void
246 423f02f5 2021-12-28 cage expect(uint8_t type)
250 423f02f5 2021-12-28 cage t = np_read8(buf);
251 423f02f5 2021-12-28 cage if (t == type)
254 423f02f5 2021-12-28 cage if (t == Terror) {
257 423f02f5 2021-12-28 cage err = np_readstr(buf);
258 423f02f5 2021-12-28 cage errx(1, "expected %s, got error %s",
259 423f02f5 2021-12-28 cage pp_msg_type(type), err);
262 423f02f5 2021-12-28 cage errx(1, "expected %s, got msg type %s",
263 423f02f5 2021-12-28 cage pp_msg_type(type), pp_msg_type(t));
266 423f02f5 2021-12-28 cage static void
267 423f02f5 2021-12-28 cage expect2(uint8_t type, uint16_t tag)
269 423f02f5 2021-12-28 cage uint16_t t;
271 423f02f5 2021-12-28 cage expect(type);
273 423f02f5 2021-12-28 cage t = np_read16(buf);
274 423f02f5 2021-12-28 cage if (t == tag)
277 423f02f5 2021-12-28 cage errx(1, "expected tag 0x%x, got 0x%x", tag, t);
280 423f02f5 2021-12-28 cage static void
281 ce3844d2 2021-12-14 op do_version(void)
283 423f02f5 2021-12-28 cage char *version;
285 ce3844d2 2021-12-14 op tversion(VERSION9P, MSIZE9P);
287 423f02f5 2021-12-28 cage recv_msg();
288 423f02f5 2021-12-28 cage expect2(Rversion, NOTAG);
290 423f02f5 2021-12-28 cage msize = np_read32(buf);
291 423f02f5 2021-12-28 cage version = np_readstr(buf);
293 423f02f5 2021-12-28 cage if (msize > MSIZE9P)
294 423f02f5 2021-12-28 cage errx(1, "got unexpected msize: %d", msize);
295 423f02f5 2021-12-28 cage if (strcmp(version, VERSION9P))
296 423f02f5 2021-12-28 cage errx(1, "unexpected 9p version: %s", version);
298 423f02f5 2021-12-28 cage free(version);
299 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
303 ce3844d2 2021-12-14 op do_attach(const char *path)
305 423f02f5 2021-12-28 cage const char *user;
306 423f02f5 2021-12-28 cage struct qid qid;
308 ce3844d2 2021-12-14 op if (path == NULL)
310 423f02f5 2021-12-28 cage if ((user = getenv("USER")) == NULL)
311 423f02f5 2021-12-28 cage user = "flan";
313 423f02f5 2021-12-28 cage tattach(PWDFID, NOFID, user, path);
315 423f02f5 2021-12-28 cage recv_msg();
316 423f02f5 2021-12-28 cage expect2(Rattach, iota_tag);
317 423f02f5 2021-12-28 cage np_read_qid(buf, &qid);
319 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
322 423f02f5 2021-12-28 cage static uint32_t
323 423f02f5 2021-12-28 cage do_open(uint32_t fid, uint8_t mode)
325 423f02f5 2021-12-28 cage struct qid qid;
326 423f02f5 2021-12-28 cage uint32_t iounit;
328 423f02f5 2021-12-28 cage topen(fid, mode);
330 423f02f5 2021-12-28 cage recv_msg();
331 423f02f5 2021-12-28 cage expect2(Ropen, iota_tag);
333 423f02f5 2021-12-28 cage np_read_qid(buf, &qid);
334 423f02f5 2021-12-28 cage iounit = np_read32(buf);
336 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
338 423f02f5 2021-12-28 cage return iounit;
342 423f02f5 2021-12-28 cage do_clunk(uint32_t fid)
344 423f02f5 2021-12-28 cage tclunk(fid);
346 423f02f5 2021-12-28 cage recv_msg();
347 423f02f5 2021-12-28 cage expect2(Rclunk, iota_tag);
349 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
352 423f02f5 2021-12-28 cage static void
353 423f02f5 2021-12-28 cage dup_fid(int fid, int nfid)
355 423f02f5 2021-12-28 cage uint16_t nwqid;
357 423f02f5 2021-12-28 cage twalk(fid, nfid, NULL, 0);
359 423f02f5 2021-12-28 cage recv_msg();
360 423f02f5 2021-12-28 cage expect2(Rwalk, iota_tag);
362 423f02f5 2021-12-28 cage nwqid = np_read16(buf);
363 423f02f5 2021-12-28 cage assert(nwqid == 0);
365 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
368 423f02f5 2021-12-28 cage static void
369 3f03529f 2021-12-28 op do_tls_connect(const char *host, const char *port)
371 ce3844d2 2021-12-14 op int handshake;
373 ce3844d2 2021-12-14 op if ((tlsconf = tls_config_new()) == NULL)
374 ce3844d2 2021-12-14 op fatalx("tls_config_new");
375 ce3844d2 2021-12-14 op tls_config_insecure_noverifycert(tlsconf);
376 ce3844d2 2021-12-14 op tls_config_insecure_noverifyname(tlsconf);
377 ce3844d2 2021-12-14 op if (tls_config_set_keypair_file(tlsconf, crtpath, keypath) == -1)
378 ce3844d2 2021-12-14 op fatalx("can't load certs (%s, %s)", crtpath, keypath);
380 ce3844d2 2021-12-14 op if ((ctx = tls_client()) == NULL)
381 ce3844d2 2021-12-14 op fatal("tls_client");
382 ce3844d2 2021-12-14 op if (tls_configure(ctx, tlsconf) == -1)
383 ce3844d2 2021-12-14 op fatalx("tls_configure: %s", tls_error(ctx));
385 ce3844d2 2021-12-14 op if (tls_connect(ctx, host, port) == -1)
386 ce3844d2 2021-12-14 op fatalx("can't connect to %s:%s: %s", host, port,
387 ce3844d2 2021-12-14 op tls_error(ctx));
389 ce3844d2 2021-12-14 op for (handshake = 0; !handshake;) {
390 ce3844d2 2021-12-14 op switch (tls_handshake(ctx)) {
392 ce3844d2 2021-12-14 op fatalx("tls_handshake: %s", tls_error(ctx));
394 ce3844d2 2021-12-14 op handshake = 1;
401 3f03529f 2021-12-28 op do_ctxt_connect(const char *host, const char *port)
403 3f03529f 2021-12-28 op struct addrinfo hints, *res, *res0;
404 3f03529f 2021-12-28 op int error, saved_errno;
405 3f03529f 2021-12-28 op const char *cause = NULL;
407 3f03529f 2021-12-28 op memset(&hints, 0, sizeof(hints));
408 3f03529f 2021-12-28 op hints.ai_family = AF_UNSPEC;
409 3f03529f 2021-12-28 op hints.ai_socktype = SOCK_STREAM;
410 3f03529f 2021-12-28 op error = getaddrinfo(host, port, &hints, &res0);
412 3f03529f 2021-12-28 op errx(1, "%s", gai_strerror(error));
415 3f03529f 2021-12-28 op for (res = res0; res != NULL; res = res->ai_next) {
416 3f03529f 2021-12-28 op sock = socket(res->ai_family, res->ai_socktype,
417 3f03529f 2021-12-28 op res->ai_protocol);
418 3f03529f 2021-12-28 op if (sock == -1) {
419 3f03529f 2021-12-28 op cause = "socket";
423 3f03529f 2021-12-28 op if (connect(sock, res->ai_addr, res->ai_addrlen) == -1) {
424 3f03529f 2021-12-28 op cause = "connect";
425 3f03529f 2021-12-28 op saved_errno = errno;
427 3f03529f 2021-12-28 op errno = saved_errno;
435 3f03529f 2021-12-28 op if (sock == -1)
436 3f03529f 2021-12-28 op err(1, "%s", cause);
437 3f03529f 2021-12-28 op freeaddrinfo(res0);
441 3f03529f 2021-12-28 op do_connect(const char *connspec, const char *path)
443 3f03529f 2021-12-28 op char *host, *colon;
444 3f03529f 2021-12-28 op const char *port;
446 3f03529f 2021-12-28 op host = xstrdup(connspec);
447 3f03529f 2021-12-28 op if ((colon = strchr(host, ':')) != NULL) {
448 3f03529f 2021-12-28 op *colon = '\0';
449 3f03529f 2021-12-28 op port = ++colon;
451 3f03529f 2021-12-28 op port = "1337";
453 3f03529f 2021-12-28 op printf("connecting to %s:%s...", host, port);
454 3f03529f 2021-12-28 op fflush(stdout);
457 3f03529f 2021-12-28 op do_tls_connect(host, port);
459 3f03529f 2021-12-28 op do_ctxt_connect(host, port);
461 ce3844d2 2021-12-14 op printf(" done!\n");
463 ce3844d2 2021-12-14 op do_version();
464 ce3844d2 2021-12-14 op do_attach(path);
469 423f02f5 2021-12-28 cage static void
470 423f02f5 2021-12-28 cage cmd_bell(int argc, const char **argv)
472 423f02f5 2021-12-28 cage if (argc == 0) {
473 423f02f5 2021-12-28 cage bell = !bell;
475 423f02f5 2021-12-28 cage puts("bell mode enabled");
477 423f02f5 2021-12-28 cage puts("bell mode disabled");
481 423f02f5 2021-12-28 cage if (argc != 1)
482 423f02f5 2021-12-28 cage goto usage;
484 423f02f5 2021-12-28 cage if (!strcmp(*argv, "on")) {
486 423f02f5 2021-12-28 cage puts("bell mode enabled");
490 423f02f5 2021-12-28 cage if (!strcmp(*argv, "off")) {
492 423f02f5 2021-12-28 cage puts("bell mode disabled");
497 423f02f5 2021-12-28 cage printf("bell [on | off]\n");
500 423f02f5 2021-12-28 cage static void
501 423f02f5 2021-12-28 cage cmd_bye(int argc, const char **argv)
503 423f02f5 2021-12-28 cage log_warnx("bye\n");
507 423f02f5 2021-12-28 cage static void
508 17388298 2021-12-28 op cmd_lcd(int argc, const char **argv)
510 17388298 2021-12-28 op const char *dir;
512 17388298 2021-12-28 op if (argc > 1) {
513 17388298 2021-12-28 op printf("lcd takes only one argument\n");
517 17388298 2021-12-28 op if (argc == 1)
520 17388298 2021-12-28 op if (argc == 0 && (dir = getenv("HOME")) == NULL) {
521 17388298 2021-12-28 op printf("HOME is not defined\n");
525 17388298 2021-12-28 op if (chdir(dir) == -1)
526 17388298 2021-12-28 op printf("cd: %s: %s\n", dir, strerror(errno));
530 6150fab3 2021-12-28 op cmd_lpwd(int argc, const char **argv)
532 6150fab3 2021-12-28 op char path[PATH_MAX];
534 6150fab3 2021-12-28 op if (getcwd(path, sizeof(path)) == NULL) {
535 6150fab3 2021-12-28 op printf("lpwd: %s\n", strerror(errno));
539 6150fab3 2021-12-28 op printf("%s\n", path);
543 423f02f5 2021-12-28 cage cmd_ls(int argc, const char **argv)
545 423f02f5 2021-12-28 cage uint64_t off = 0;
546 423f02f5 2021-12-28 cage uint32_t len;
548 423f02f5 2021-12-28 cage if (argc != 0) {
549 423f02f5 2021-12-28 cage printf("ls don't take arguments (yet)\n");
553 423f02f5 2021-12-28 cage dup_fid(PWDFID, 1);
554 423f02f5 2021-12-28 cage do_open(1, KOREAD);
556 423f02f5 2021-12-28 cage evbuffer_drain(dirbuf, EVBUFFER_LENGTH(dirbuf));
559 423f02f5 2021-12-28 cage tread(1, off, BUFSIZ);
561 423f02f5 2021-12-28 cage recv_msg();
562 423f02f5 2021-12-28 cage expect2(Rread, iota_tag);
564 423f02f5 2021-12-28 cage len = np_read32(buf);
565 423f02f5 2021-12-28 cage if (len == 0)
568 423f02f5 2021-12-28 cage evbuffer_add_buffer(dirbuf, buf);
569 423f02f5 2021-12-28 cage off += len;
571 423f02f5 2021-12-28 cage ASSERT_EMPTYBUF();
574 423f02f5 2021-12-28 cage while (EVBUFFER_LENGTH(dirbuf) != 0) {
575 423f02f5 2021-12-28 cage struct qid qid;
576 423f02f5 2021-12-28 cage uint64_t len;
577 423f02f5 2021-12-28 cage uint16_t size;
578 423f02f5 2021-12-28 cage char *name;
580 423f02f5 2021-12-28 cage size = np_read16(dirbuf);
581 423f02f5 2021-12-28 cage assert(size <= EVBUFFER_LENGTH(dirbuf));
583 423f02f5 2021-12-28 cage np_read16(dirbuf); /* skip type */
584 423f02f5 2021-12-28 cage np_read32(dirbuf); /* skip dev */
586 423f02f5 2021-12-28 cage np_read_qid(dirbuf, &qid);
587 423f02f5 2021-12-28 cage printf("%s ", pp_qid_type(qid.type));
589 423f02f5 2021-12-28 cage np_read32(dirbuf); /* skip mode */
590 423f02f5 2021-12-28 cage np_read32(dirbuf); /* skip atime */
591 423f02f5 2021-12-28 cage np_read32(dirbuf); /* skip mtime */
593 423f02f5 2021-12-28 cage len = np_read64(dirbuf);
594 423f02f5 2021-12-28 cage printf("%llu ", (unsigned long long)len);
596 423f02f5 2021-12-28 cage name = np_readstr(dirbuf);
597 423f02f5 2021-12-28 cage printf("%s\n", name);
598 423f02f5 2021-12-28 cage free(name);
600 423f02f5 2021-12-28 cage free(np_readstr(dirbuf)); /* skip uid */
601 423f02f5 2021-12-28 cage free(np_readstr(dirbuf)); /* skip gid */
602 423f02f5 2021-12-28 cage free(np_readstr(dirbuf)); /* skip muid */
605 423f02f5 2021-12-28 cage do_clunk(1);
608 423f02f5 2021-12-28 cage static void
609 423f02f5 2021-12-28 cage cmd_verbose(int argc, const char **argv)
611 423f02f5 2021-12-28 cage if (argc == 0) {
612 423f02f5 2021-12-28 cage log_setverbose(!log_getverbose());
613 423f02f5 2021-12-28 cage if (log_getverbose())
614 423f02f5 2021-12-28 cage puts("verbose mode enabled");
616 423f02f5 2021-12-28 cage puts("verbose mode disabled");
620 423f02f5 2021-12-28 cage if (argc != 1)
621 423f02f5 2021-12-28 cage goto usage;
623 423f02f5 2021-12-28 cage if (!strcmp(*argv, "on")) {
624 423f02f5 2021-12-28 cage log_setverbose(1);
625 423f02f5 2021-12-28 cage puts("verbose mode enabled");
629 423f02f5 2021-12-28 cage if (!strcmp(*argv, "off")) {
630 423f02f5 2021-12-28 cage log_setverbose(0);
631 423f02f5 2021-12-28 cage puts("verbose mode disabled");
636 423f02f5 2021-12-28 cage printf("verbose [on | off]\n");
639 423f02f5 2021-12-28 cage static void
640 423f02f5 2021-12-28 cage excmd(int argc, const char **argv)
642 423f02f5 2021-12-28 cage struct cmd {
643 423f02f5 2021-12-28 cage const char *name;
644 423f02f5 2021-12-28 cage void (*fn)(int, const char **);
645 423f02f5 2021-12-28 cage } cmds[] = {
646 423f02f5 2021-12-28 cage {"bell", cmd_bell},
647 423f02f5 2021-12-28 cage {"bye", cmd_bye},
648 17388298 2021-12-28 op {"lcd", cmd_lcd},
649 6150fab3 2021-12-28 op {"lpwd", cmd_lpwd},
650 423f02f5 2021-12-28 cage {"ls", cmd_ls},
651 423f02f5 2021-12-28 cage {"quit", cmd_bye},
652 423f02f5 2021-12-28 cage {"verbose", cmd_verbose},
656 423f02f5 2021-12-28 cage if (argc == 0)
658 423f02f5 2021-12-28 cage for (i = 0; i < nitems(cmds); ++i) {
659 423f02f5 2021-12-28 cage if (!strcmp(cmds[i].name, *argv)) {
660 423f02f5 2021-12-28 cage cmds[i].fn(argc-1, argv+1);
665 423f02f5 2021-12-28 cage log_warnx("unknown command %s", *argv);
669 ce3844d2 2021-12-14 op main(int argc, char **argv)
673 ce3844d2 2021-12-14 op log_init(1, LOG_DAEMON);
674 423f02f5 2021-12-28 cage log_setverbose(0);
675 ce3844d2 2021-12-14 op log_procinit(getprogname());
677 ce3844d2 2021-12-14 op while ((ch = getopt(argc, argv, "C:cK:")) != -1) {
678 ce3844d2 2021-12-14 op switch (ch) {
680 ce3844d2 2021-12-14 op crtpath = optarg;
686 ce3844d2 2021-12-14 op keypath = optarg;
692 ce3844d2 2021-12-14 op argc -= optind;
693 ce3844d2 2021-12-14 op argv += optind;
695 ce3844d2 2021-12-14 op if (argc == 0)
698 ce3844d2 2021-12-14 op if ((evb = evbuffer_new()) == NULL)
699 ce3844d2 2021-12-14 op fatal("evbuffer_new");
701 423f02f5 2021-12-28 cage if ((buf = evbuffer_new()) == NULL)
702 423f02f5 2021-12-28 cage fatal("evbuffer_new");
704 423f02f5 2021-12-28 cage if ((dirbuf = evbuffer_new()) == NULL)
705 423f02f5 2021-12-28 cage fatal("evbuferr_new");
707 ce3844d2 2021-12-14 op do_connect(argv[0], argv[1]);
709 423f02f5 2021-12-28 cage /* cmd_ls(0, NULL); */
712 423f02f5 2021-12-28 cage int argc = 0;
713 423f02f5 2021-12-28 cage char *line, *argv[16] = {0}, **ap;
715 423f02f5 2021-12-28 cage if ((line = read_line("kamiftp> ")) == NULL)
718 423f02f5 2021-12-28 cage for (argc = 0, ap = argv; ap < &argv[15] &&
719 423f02f5 2021-12-28 cage (*ap = strsep(&line, " \t")) != NULL;) {
720 423f02f5 2021-12-28 cage if (**ap != '\0')
721 423f02f5 2021-12-28 cage ap++, argc++;
723 423f02f5 2021-12-28 cage excmd(argc, (const char **)argv);
725 423f02f5 2021-12-28 cage if (bell) {
726 423f02f5 2021-12-28 cage printf("\a");
727 423f02f5 2021-12-28 cage fflush(stdout);
730 423f02f5 2021-12-28 cage free(line);
733 ce3844d2 2021-12-14 op printf("\n");