commit - 787867cbdb6eafe614889ebdd51e1a23c070eeba
commit + e60f4e082904c3982680ca9fdf3b656c5b0763ae
blob - 33380480735abc28f6587eb70b03c0a63b7e6705
blob + a0c6397fec1ebb3b54d13b2f26ab560033d3712d
--- client.c
+++ client.c
#include <endian.h>
#include <errno.h>
#include <fcntl.h>
-#include <inttypes.h>
#include <pwd.h>
#include <signal.h>
#include <stdlib.h>
static void np_error(uint16_t, const char *);
static void np_errno(uint16_t);
-static void handle_message(struct imsg *, size_t);
+static void tversion(struct np_msg_header *, const uint8_t *, size_t);
+static void tattach(struct np_msg_header *, const uint8_t *, size_t);
+static void handle_message(struct imsg *, size_t);
ATTR_DEAD void
client(int debug, int verbose)
}
static void
-handle_message(struct imsg *imsg, size_t len)
+tversion(struct np_msg_header *hdr, const uint8_t *data, size_t len)
{
- struct np_msg_header hdr;
- struct qid *qid;
- struct fid *f;
- int fd;
- uint32_t fid;
- uint16_t slen;
- uint8_t *data, *dot;
- char buf[16];
+ uint16_t slen;
+ const uint8_t *dot;
+ char buf[16];
- parse_message(imsg->data, len, &hdr, &data);
- len -= HEADERSIZE;
-
- log_debug("got request: len=%d type=%d[%s] tag=%d",
- hdr.len, hdr.type, pp_msg_type(hdr.type), hdr.tag);
-
- if (!handshaked && hdr.type != Tversion)
+ if (handshaked)
goto err;
- switch (hdr.type) {
- case Tversion:
- if (handshaked)
- goto err;
+ /* msize[4] + version[s] */
+ if (len < 6)
+ goto err;
- /* msize[4] + version[s] */
- if (len < 6)
- goto err;
+ memcpy(&msize, data, sizeof(msize));
+ data += sizeof(msize);
+ msize = le32toh(msize);
- memcpy(&msize, data, sizeof(msize));
- data += sizeof(msize);
- msize = le32toh(msize);
+ memcpy(&slen, data, sizeof(slen));
+ data += sizeof(slen);
+ slen = le16toh(slen);
- memcpy(&slen, data, sizeof(slen));
- data += sizeof(slen);
- slen = le16toh(slen);
+ if ((dot = memchr(data, '.', slen)) != NULL)
+ slen -= dot - data;
- if ((dot = memchr(data, '.', slen)) != NULL)
- slen -= dot - data;
+ if (slen != strlen(VERSION9P) ||
+ memcmp(data, VERSION9P, slen) != 0 ||
+ msize == 0) {
+ slen = MIN(slen, sizeof(buf)-1);
+ memcpy(buf, data, slen);
+ buf[slen] = '\0';
+ log_warnx("unknown 9P version string: [%d]\"%s\", "
+ "want " VERSION9P,
+ slen, buf);
+ np_version(hdr->tag, MSIZE9P, "unknown");
+ return;
+ }
- if (slen != strlen(VERSION9P) ||
- memcmp(data, VERSION9P, slen) != 0 ||
- msize == 0) {
- slen = MIN(slen, sizeof(buf)-1);
- memcpy(buf, data, slen);
- buf[slen] = '\0';
- log_warnx("unknown 9P version string: [%d]\"%s\", "
- "want " VERSION9P,
- slen, buf);
- np_version(hdr.tag, MSIZE9P, "unknown");
- return;
- }
+ handshaked = 1;
- handshaked = 1;
+ msize = MIN(msize, MSIZE9P);
+ client_send_listener(IMSG_MSIZE, &msize, sizeof(msize));
+ np_version(hdr->tag, msize, VERSION9P);
+ return;
- msize = MIN(msize, MSIZE9P);
- client_send_listener(IMSG_MSIZE, &msize, sizeof(msize));
- np_version(hdr.tag, msize, VERSION9P);
- break;
+err:
+ client_send_listener(IMSG_CLOSE, NULL, 0);
+ client_shutdown();
+}
- case Tattach:
- if (attached) {
- np_error(hdr.tag, "already attached");
- return;
- }
+static void
+tattach(struct np_msg_header *hdr, const uint8_t *data, size_t len)
+{
+ struct qid *qid;
+ struct fid *f;
+ uint32_t fid;
+ int fd;
- /* fid[4] afid[4] uname[s] aname[s] */
-
- /* for the moment, happily ignore afid */
+ if (attached) {
+ np_error(hdr->tag, "already attached");
+ return;
+ }
- if ((fd = open("/", O_DIRECTORY)) == -1) {
- np_errno(hdr.tag);
- return;
- }
+ /* fid[4] afid[4] uname[s] aname[s] */
- if ((qid = new_qid(fd)) == NULL) {
- close(fd);
- np_error(hdr.tag, "no memory");
- return;
- }
+ /* for the moment, happily ignore afid */
- memcpy(&fid, data, sizeof(fid));
- data += sizeof(fid);
- fid = le32toh(fid);
+ if ((fd = open("/", O_DIRECTORY)) == -1) {
+ np_errno(hdr->tag);
+ return;
+ }
- if ((f = new_fid(qid, fid)) == NULL) {
- close(qid->fd);
- free(qid);
- np_error(hdr.tag, "no memory");
- return;
- }
+ if ((qid = new_qid(fd)) == NULL) {
+ close(fd);
+ np_error(hdr->tag, "no memory");
+ return;
+ }
- log_debug("qid{path=%"PRIu64" vers=%d type=0x%x}",
- qid->path, qid->vers, qid->type);
- np_attach(hdr.tag, qid);
- attached = 1;
+ memcpy(&fid, data, sizeof(fid));
+ data += sizeof(fid);
+ fid = le32toh(fid);
- break;
-
- default:
- /* for now, log the request and reply with an error. */
- np_error(hdr.tag, "Not supported.");
- break;
+ if ((f = new_fid(qid, fid)) == NULL) {
+ close(qid->fd);
+ free(qid);
+ np_error(hdr->tag, "no memory");
+ return;
}
+ np_attach(hdr->tag, qid);
+ attached = 1;
return;
+}
-err:
- client_send_listener(IMSG_CLOSE, NULL, 0);
- client_shutdown();
+static void
+handle_message(struct imsg *imsg, size_t len)
+{
+ struct msg {
+ uint8_t type;
+ void (*fn)(struct np_msg_header *, const uint8_t *, size_t);
+ } msgs[] = {
+ {Tversion, tversion},
+ {Tattach, tattach},
+ };
+ struct np_msg_header hdr;
+ size_t i;
+ uint8_t *data;
+
+ parse_message(imsg->data, len, &hdr, &data);
+ len -= HEADERSIZE;
+
+ log_debug("got request: len=%d type=%d[%s] tag=%d",
+ hdr.len, hdr.type, pp_msg_type(hdr.type), hdr.tag);
+
+ if (!handshaked && hdr.type != Tversion) {
+ client_send_listener(IMSG_CLOSE, NULL, 0);
+ client_shutdown();
+ return;
+ }
+
+ for (i = 0; i < sizeof(msgs)/sizeof(msgs[0]); ++i) {
+ if (msgs[i].type != hdr.type)
+ continue;
+
+ msgs[i].fn(&hdr, data, len);
+ return;
+ }
+
+ np_error(hdr.tag, "Not supported.");
}