commit - f96f265a4a599a3a77fc85419281063454271d1f
commit + 7ee9de09935049e0aa2c5b3f87c821833edda1fe
blob - 9f0db8fb1c41e00eff1e5a7be402ce6d2792f47e
blob + 51a88157347e91e52d0ed7f33d0bcba2f740042b
--- ftp.c
+++ ftp.c
#include <readline/history.h>
#endif
+#ifndef nitems
+#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
+#endif
+
#include "9pclib.h"
#include "kamid.h"
#include "utils.h"
struct tls *ctx;
int sock;
struct evbuffer *buf;
+struct evbuffer *dirbuf;
uint32_t msize;
#define PWDFID 0
}
static uint64_t
-np_read64(void)
+np_read64(struct evbuffer *buf)
{
uint64_t n;
}
static uint32_t
-np_read32(void)
+np_read32(struct evbuffer *buf)
{
uint32_t n;
}
static uint16_t
-np_read16(void)
+np_read16(struct evbuffer *buf)
{
uint16_t n;
}
static uint16_t
-np_read8(void)
+np_read8(struct evbuffer *buf)
{
uint8_t n;
}
static char *
-np_readstr(void)
+np_readstr(struct evbuffer *buf)
{
uint16_t len;
char *str;
- len = np_read16();
+ len = np_read16(buf);
assert(EVBUFFER_LENGTH(buf) >= len);
if ((str = calloc(1, len+1)) == NULL)
}
static void
-np_read_qid(struct qid *qid)
+np_read_qid(struct evbuffer *buf, struct qid *qid)
{
assert(EVBUFFER_LENGTH(buf) >= QIDSIZE);
- qid->type = np_read8();
- qid->vers = np_read32();
- qid->path = np_read64();
+ qid->type = np_read8(buf);
+ qid->vers = np_read32(buf);
+ qid->path = np_read64(buf);
}
static void
{
uint8_t t;
- t = np_read8();
+ t = np_read8(buf);
if (t == type)
return;
if (t == Terror) {
char *err;
- err = np_readstr();
+ err = np_readstr(buf);
errx(1, "expected %s, got error %s",
pp_msg_type(type), err);
}
expect(type);
- t = np_read16();
+ t = np_read16(buf);
if (t == tag)
return;
recv_msg();
expect2(Rversion, NOTAG);
- msize = np_read32();
- version = np_readstr();
+ msize = np_read32(buf);
+ version = np_readstr(buf);
if (msize > MSIZE9P)
errx(1, "got unexpected msize: %d", msize);
do_send();
recv_msg();
expect2(Rattach, iota_tag);
- np_read_qid(&qid);
+ np_read_qid(buf, &qid);
+
ASSERT_EMPTYBUF();
}
+static uint32_t
+do_open(uint32_t fid, uint8_t mode)
+{
+ struct qid qid;
+ uint32_t iounit;
+
+ topen(fid, mode);
+ do_send();
+ recv_msg();
+ expect2(Ropen, iota_tag);
+
+ np_read_qid(buf, &qid);
+ iounit = np_read32(buf);
+
+ ASSERT_EMPTYBUF();
+
+ return iounit;
+}
+
static void
+do_clunk(uint32_t fid)
+{
+ tclunk(fid);
+ do_send();
+ recv_msg();
+ expect2(Rclunk, iota_tag);
+
+ ASSERT_EMPTYBUF();
+}
+
+static void
+dup_fid(int fid, int nfid)
+{
+ uint16_t nwqid;
+
+ twalk(fid, nfid, NULL, 0);
+ do_send();
+ recv_msg();
+ expect2(Rwalk, iota_tag);
+
+ nwqid = np_read16(buf);
+ assert(nwqid == 0);
+
+ ASSERT_EMPTYBUF();
+}
+
+static void
do_connect(const char *connspec, const char *path)
{
int handshake;
do_attach(path);
free(host);
+}
+
+static void
+cmd_ls(int argc, const char **argv)
+{
+ uint64_t off = 0;
+ uint32_t len;
+
+ if (argc != 0) {
+ printf("ls don't take arguments (yet)\n");
+ return;
+ }
+
+ dup_fid(PWDFID, 1);
+ do_open(1, KOREAD);
+
+ evbuffer_drain(dirbuf, EVBUFFER_LENGTH(dirbuf));
+
+ for (;;) {
+ tread(1, off, BUFSIZ);
+ do_send();
+ recv_msg();
+ expect2(Rread, iota_tag);
+
+ len = np_read32(buf);
+ if (len == 0)
+ break;
+
+ evbuffer_add_buffer(dirbuf, buf);
+ off += len;
+
+ ASSERT_EMPTYBUF();
+ }
+
+ while (EVBUFFER_LENGTH(dirbuf) != 0) {
+ struct qid qid;
+ uint64_t len;
+ uint16_t size;
+ char *name;
+
+ size = np_read16(dirbuf);
+ assert(size <= EVBUFFER_LENGTH(dirbuf));
+
+ np_read16(dirbuf); /* skip type */
+ np_read32(dirbuf); /* skip dev */
+
+ np_read_qid(dirbuf, &qid);
+ printf("%s ", pp_qid_type(qid.type));
+
+ np_read32(dirbuf); /* skip mode */
+ np_read32(dirbuf); /* skip atime */
+ np_read32(dirbuf); /* skip mtime */
+
+ len = np_read64(dirbuf);
+ printf("%llu ", (unsigned long long)len);
+
+ name = np_readstr(dirbuf);
+ printf("%s\n", name);
+ free(name);
+
+ free(np_readstr(dirbuf)); /* skip uid */
+ free(np_readstr(dirbuf)); /* skip gid */
+ free(np_readstr(dirbuf)); /* skip muid */
+ }
+
+ do_clunk(1);
}
+static void
+excmd(int argc, const char **argv)
+{
+ struct cmd {
+ const char *name;
+ void (*fn)(int, const char **);
+ } cmds[] = {
+ {"ls", cmd_ls},
+ };
+ size_t i;
+
+ if (argc == 0)
+ return;
+ for (i = 0; i < nitems(cmds); ++i) {
+ if (!strcmp(cmds[i].name, *argv)) {
+ cmds[i].fn(argc-1, argv+1);
+ return;
+ }
+ }
+
+ log_warnx("unknown command %s", *argv);
+}
+
int
main(int argc, char **argv)
{
if ((buf = evbuffer_new()) == NULL)
fatal("evbuffer_new");
+ if ((dirbuf = evbuffer_new()) == NULL)
+ fatal("evbuferr_new");
+
do_connect(argv[0], argv[1]);
+ /* cmd_ls(0, NULL); */
+
for (;;) {
- char *line;
+ int argc = 0;
+ char *line, *argv[16] = {0}, **ap;
if ((line = read_line("kamiftp> ")) == NULL)
break;
- printf("read: %s\n", line);
+
+ for (argc = 0, ap = argv; ap < &argv[15] &&
+ (*ap = strsep(&line, " \t")) != NULL;) {
+ if (**ap != '\0')
+ ap++, argc++;
+ }
+ excmd(argc, argv);
+
free(line);
}