wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit 3448ec0f3614229e6f64f6b43ebb54f21b959d32
parent 19e2bc7aac0d10b6fdbf21997440ad1c121cd17b
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Sat, 28 Jan 2006 22:06:08 +0200

removed IXPTFunc crap from ixp2, simplified server stuff to a bare minimum


Diffstat:
cmd/wmiibar2.c | 344+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
libixp2/ixp.h | 140+++++++++++++++++++++++++++++++++++++------------------------------------------
libixp2/server.c | 119++++++++++++-------------------------------------------------------------------
3 files changed, 286 insertions(+), 317 deletions(-)

diff --git a/cmd/wmiibar2.c b/cmd/wmiibar2.c @@ -16,6 +16,7 @@ #include <X11/cursorfont.h> #include <X11/Xproto.h> #include <X11/Xutil.h> +#include <sys/socket.h> #include "../libixp2/ixp.h" #include "blitz.h" @@ -50,7 +51,11 @@ struct Map { unsigned int fid; Qid qid; Map *next; -}; +}; +typedef struct { + Map *maps; + Fcall fcall; +} Req; typedef struct { char data[256]; @@ -60,10 +65,12 @@ typedef struct { unsigned long border; } Item; +static unsigned char *msg[IXP_MAX_MSG]; +char *errstr = 0; static size_t nitem = 0; static size_t itemsz = 0; static Item **item = 0; -static char *sockfile = nil; +static char *address = nil; static pid_t mypid = 0; static IXPServer srv = { 0 }; static Qid root_qid; @@ -106,7 +113,7 @@ static void exit_cleanup() { if(mypid == getpid()) - unlink(sockfile); + unlink(address); } static void @@ -186,7 +193,7 @@ qid_to_name(Qid *qid) static int name_to_type(char *name) { - const char *errstr; + const char *err; unsigned int i; if(!name || !name[0] || !strncmp(name, "..", 3)) return Droot; @@ -202,8 +209,8 @@ name_to_type(char *name) return Fevent; if(!strncmp(name, "color", 6)) return Fcolor; - i = (unsigned short) cext_strtonum(name, 1, 0xffff, &errstr); - if(!errstr && i <= nitem) + i = (unsigned short) cext_strtonum(name, 1, 0xffff, &err); + if(!err && (i <= nitem)) return Ditem; return -1; } @@ -219,7 +226,7 @@ fid_to_map(Map *maps, unsigned int fid) static int mkqid(Qid *dir, char *wname, Qid *new) { - const char *errstr; + const char *err; int type = name_to_type(wname); unsigned short i = qpath_item(dir->path); @@ -239,8 +246,8 @@ mkqid(Qid *dir, char *wname, Qid *new) else if(!strncmp(wname, "new", 4)) new->path = mkqpath(Ditem, nitem); else { - unsigned short i = cext_strtonum(wname, 1, 0xffff, &errstr); - if(i >= nitem) + unsigned short i = cext_strtonum(wname, 1, 0xffff, &err); + if(err || (i >= nitem)) return -1; new->path = mkqpath(Ditem, i); } @@ -258,91 +265,91 @@ mkqid(Qid *dir, char *wname, Qid *new) } static int -xversion(IXPServer *s, IXPConn * c) +xversion(Req *r) { - if(strncmp(s->fcall.version, IXP_VERSION, strlen(IXP_VERSION))) { - s->errstr = "9P versions differ"; + if(strncmp(r->fcall.version, IXP_VERSION, strlen(IXP_VERSION))) { + errstr = "9P versions differ"; return -1; - } else if(s->fcall.maxmsg > IXP_MAX_MSG) - s->fcall.maxmsg = IXP_MAX_MSG; - s->fcall.id = RVERSION; + } else if(r->fcall.maxmsg > IXP_MAX_MSG) + r->fcall.maxmsg = IXP_MAX_MSG; + r->fcall.id = RVERSION; return 0; } static int -xattach(IXPServer *s, IXPConn *c) +xattach(Req *r) { - Map *maps = c->aux; + Map *maps = r->maps; Map *new = cext_emallocz(sizeof(Map)); - c->aux = new; + r->maps = new; new->next = maps; new->qid = root_qid; - new->fid = s->fcall.fid; - s->fcall.id = RATTACH; - s->fcall.qid = root_qid; + new->fid = r->fcall.fid; + r->fcall.id = RATTACH; + r->fcall.qid = root_qid; return 0; } static int -xwalk(IXPServer *s, IXPConn *c) +xwalk(Req *r) { unsigned short nwqid = 0; Qid dir = root_qid; Map *map; - if(!(map = fid_to_map(c->aux, s->fcall.fid))) { - s->errstr = "no dir associated with fid"; + if(!(map = fid_to_map(r->maps, r->fcall.fid))) { + errstr = "no dir associated with fid"; return -1; } - if(s->fcall.fid != s->fcall.newfid - && (fid_to_map(c->aux, s->fcall.newfid))) { - s->errstr = "fid alreay in use"; + if(r->fcall.fid != r->fcall.newfid + && (fid_to_map(r->maps, r->fcall.newfid))) { + errstr = "fid alreay in use"; return -1; } - if(s->fcall.nwname) { + if(r->fcall.nwname) { dir = map->qid; - for(nwqid = 0; (nwqid < s->fcall.nwname) - && !mkqid(&dir, s->fcall.wname[nwqid], &s->fcall.wqid[nwqid]); nwqid++) - dir = s->fcall.wqid[nwqid]; + for(nwqid = 0; (nwqid < r->fcall.nwname) + && !mkqid(&dir, r->fcall.wname[nwqid], &r->fcall.wqid[nwqid]); nwqid++) + dir = r->fcall.wqid[nwqid]; if(!nwqid) { - s->errstr = "file not found"; + errstr = "file not found"; return -1; } } /* a fid will only be valid, if the walk was complete */ - if(nwqid == s->fcall.nwname) { - if(s->fcall.fid != s->fcall.newfid) { - Map *maps = c->aux; - map = c->aux = cext_emallocz(sizeof(Map)); + if(nwqid == r->fcall.nwname) { + if(r->fcall.fid != r->fcall.newfid) { + Map *maps = r->maps; + map = r->maps = cext_emallocz(sizeof(Map)); map->next = maps; } map->qid = dir; - map->fid = s->fcall.newfid; + map->fid = r->fcall.newfid; } - s->fcall.id = RWALK; - s->fcall.nwqid = nwqid; + r->fcall.id = RWALK; + r->fcall.nwqid = nwqid; return 0; } static int -xopen(IXPServer *s, IXPConn *c) +xopen(Req *r) { - Map *map = fid_to_map(c->aux, s->fcall.fid); + Map *map = fid_to_map(r->maps, r->fcall.fid); if(!map) { - s->errstr = "invalid fid"; + errstr = "invalid fid"; return -1; } - if(!(s->fcall.mode | IXP_OREAD) && !(s->fcall.mode | IXP_OWRITE)) { - fprintf(stderr, "got mode 0x%x\n", s->fcall.mode); - s->errstr = "mode not supported"; + if(!(r->fcall.mode | IXP_OREAD) && !(r->fcall.mode | IXP_OWRITE)) { + fprintf(stderr, "got mode 0x%x\n", r->fcall.mode); + errstr = "mode not supported"; return -1; } - s->fcall.id = ROPEN; - s->fcall.qid = map->qid; - s->fcall.iounit = - s->fcall.maxmsg - (sizeof(unsigned char) + sizeof(unsigned short) + 2 * sizeof(unsigned int)); + r->fcall.id = ROPEN; + r->fcall.qid = map->qid; + r->fcall.iounit = + r->fcall.maxmsg - (sizeof(unsigned char) + sizeof(unsigned short) + 2 * sizeof(unsigned int)); return 0; } @@ -362,62 +369,61 @@ mkstat(Stat *stat, Qid *dir, char *name, unsigned long long length, unsigned int } static int -xremove(IXPServer *s, IXPConn *c) +xremove(Req *r) { - Map *map = fid_to_map(c->aux, s->fcall.fid); + Map *map = fid_to_map(r->maps, r->fcall.fid); unsigned short i; if(!map) { - s->errstr = "invalid fid"; + errstr = "invalid fid"; return -1; } i = qpath_item(map->qid.path); - s->fcall.id = RREMOVE; if((qpath_type(map->qid.path) == Ditem) && i && (i < nitem)) { Item *it = item[i]; detach_item(it); free(it); + r->fcall.id = RREMOVE; return 0; } - s->errstr = "permission denied"; + errstr = "permission denied"; return -1; } static int -xread(IXPServer *s, IXPConn *c) +xread(Req *r) { Stat stat; - Map *map = fid_to_map(c->aux, s->fcall.fid); - unsigned char *p = s->fcall.data; + Map *map = fid_to_map(r->maps, r->fcall.fid); + unsigned char *p = r->fcall.data; unsigned short i; char buf[32]; if(!map) { - s->errstr = "invalid fid"; + errstr = "invalid fid"; return -1; } i = qpath_item(map->qid.path); - s->fcall.id = RREAD; - s->fcall.count = 0; /* EOF by default */ - if(!s->fcall.offset) { + r->fcall.count = 0; /* EOF by default */ + if(!r->fcall.offset) { switch (qpath_type(map->qid.path)) { case Droot: if(align == SOUTH || align == NORTH) - s->fcall.count = mkstat(&stat, &root_qid, "display", 6, DMREAD | DMWRITE); + r->fcall.count = mkstat(&stat, &root_qid, "display", 6, DMREAD | DMWRITE); else - s->fcall.count = mkstat(&stat, &root_qid, "display", 5, DMREAD | DMWRITE); /* none */ + r->fcall.count = mkstat(&stat, &root_qid, "display", 5, DMREAD | DMWRITE); /* none */ p = ixp_enc_stat(p, &stat); - s->fcall.count += mkstat(&stat, &root_qid, "font", strlen(font), DMREAD | DMWRITE); + r->fcall.count += mkstat(&stat, &root_qid, "font", strlen(font), DMREAD | DMWRITE); p = ixp_enc_stat(p, &stat); - s->fcall.count += mkstat(&stat, &root_qid, "new", 0, DMDIR | DMREAD | DMEXEC); + r->fcall.count += mkstat(&stat, &root_qid, "new", 0, DMDIR | DMREAD | DMEXEC); p = ixp_enc_stat(p, &stat); - s->fcall.count += mkstat(&stat, &root_qid, "event", 0, DMREAD); + r->fcall.count += mkstat(&stat, &root_qid, "event", 0, DMREAD); p = ixp_enc_stat(p, &stat); - s->fcall.count += mkstat(&stat, &root_qid, "default", 0, DMDIR | DMREAD | DMEXEC); + r->fcall.count += mkstat(&stat, &root_qid, "default", 0, DMDIR | DMREAD | DMEXEC); p = ixp_enc_stat(p, &stat); for(i = 1; i < nitem; i++) { snprintf(buf, sizeof(buf), "%u", i); - s->fcall.count += mkstat(&stat, &root_qid, buf, 0, DMDIR | DMREAD | DMEXEC); + r->fcall.count += mkstat(&stat, &root_qid, buf, 0, DMDIR | DMREAD | DMEXEC); p = ixp_enc_stat(p, &stat); } break; @@ -425,7 +431,7 @@ xread(IXPServer *s, IXPConn *c) if(i > nitem) goto error_xread; if(!i) { - s->fcall.count = mkstat(&stat, &root_qid, "color", 24, DMREAD | DMWRITE); + r->fcall.count = mkstat(&stat, &root_qid, "color", 24, DMREAD | DMWRITE); p = ixp_enc_stat(p, &stat); break; } @@ -433,9 +439,9 @@ xread(IXPServer *s, IXPConn *c) if(i == nitem) new_item(); Qid dir = {IXP_QTDIR, 0, mkqpath(Ditem, i)}; - s->fcall.count = mkstat(&stat, &dir, "color", 24, DMREAD | DMWRITE); + r->fcall.count = mkstat(&stat, &dir, "color", 24, DMREAD | DMWRITE); p = ixp_enc_stat(p, &stat); - s->fcall.count += mkstat(&stat, &dir, "data", strlen(item[i]->data), DMREAD | DMWRITE); + r->fcall.count += mkstat(&stat, &dir, "data", strlen(item[i]->data), DMREAD | DMWRITE); p = ixp_enc_stat(p, &stat); } break; @@ -443,21 +449,21 @@ xread(IXPServer *s, IXPConn *c) switch(align) { case SOUTH: memcpy(p, "south", 5); - s->fcall.count = 5; + r->fcall.count = 5; break; case NORTH: memcpy(p, "north", 5); - s->fcall.count = 5; + r->fcall.count = 5; break; default: memcpy(p, "none", 4); - s->fcall.count = 4; + r->fcall.count = 4; break; } break; case Ffont: - if((s->fcall.count = strlen(font))) - memcpy(p, font, s->fcall.count); + if((r->fcall.count = strlen(font))) + memcpy(p, font, r->fcall.count); break; case Fevent: break; @@ -466,95 +472,94 @@ xread(IXPServer *s, IXPConn *c) new_item(); if(i >= nitem) goto error_xread; - if((s->fcall.count = strlen(item[i]->data))) - memcpy(p, item[i]->data, s->fcall.count); + if((r->fcall.count = strlen(item[i]->data))) + memcpy(p, item[i]->data, r->fcall.count); break; case Fcolor: if(i == nitem) new_item(); if(i >= nitem) goto error_xread; - if((s->fcall.count = strlen(item[i]->color))) - memcpy(p, item[i]->color, s->fcall.count); + if((r->fcall.count = strlen(item[i]->color))) + memcpy(p, item[i]->color, r->fcall.count); break; default: error_xread: - s->errstr = "invalid read request"; + errstr = "invalid read request"; return -1; break; } } - + r->fcall.id = RREAD; return 0; } static int -xstat(IXPServer *s, IXPConn *c) +xstat(Req *r) { - Map *map = fid_to_map(c->aux, s->fcall.fid); + Map *map = fid_to_map(r->maps, r->fcall.fid); unsigned short i; Qid dir; if(!map) { - s->errstr = "invalid fid"; + errstr = "invalid fid"; return -1; } dir.version = 0; dir.type = IXP_QTDIR; dir.path = mkqpath(Ditem, i); - s->fcall.id = RSTAT; switch (qpath_type(map->qid.path)) { case Droot: case Ditem: - mkstat(&s->fcall.stat, &root_qid, qid_to_name(&map->qid), 0, DMDIR | DMREAD | DMEXEC); + mkstat(&r->fcall.stat, &root_qid, qid_to_name(&map->qid), 0, DMDIR | DMREAD | DMEXEC); break; case Fdisplay: if(align == SOUTH || align == NORTH) - mkstat(&s->fcall.stat, &root_qid, qid_to_name(&map->qid), 6, DMREAD | DMWRITE); + mkstat(&r->fcall.stat, &root_qid, qid_to_name(&map->qid), 6, DMREAD | DMWRITE); else - mkstat(&s->fcall.stat, &root_qid, qid_to_name(&map->qid), 5, DMREAD | DMWRITE); + mkstat(&r->fcall.stat, &root_qid, qid_to_name(&map->qid), 5, DMREAD | DMWRITE); break; case Fevent: - mkstat(&s->fcall.stat, &root_qid, qid_to_name(&map->qid), 0, DMREAD); + mkstat(&r->fcall.stat, &root_qid, qid_to_name(&map->qid), 0, DMREAD); break; case Ffont: - mkstat(&s->fcall.stat, &root_qid, qid_to_name(&map->qid), strlen(font), DMREAD | DMWRITE); + mkstat(&r->fcall.stat, &root_qid, qid_to_name(&map->qid), strlen(font), DMREAD | DMWRITE); break; case Fdata: - mkstat(&s->fcall.stat, &dir, qid_to_name(&map->qid), strlen(item[i]->data), DMREAD | DMWRITE); + mkstat(&r->fcall.stat, &dir, qid_to_name(&map->qid), strlen(item[i]->data), DMREAD | DMWRITE); break; case Fcolor: - mkstat(&s->fcall.stat, &dir, qid_to_name(&map->qid), 24, DMREAD | DMWRITE); + mkstat(&r->fcall.stat, &dir, qid_to_name(&map->qid), 24, DMREAD | DMWRITE); break; default: - s->errstr = "invalid stat request"; + errstr = "invalid stat request"; return -1; break; } + r->fcall.id = RSTAT; return 0; } static int -xwrite(IXPServer *s, IXPConn *c) +xwrite(Req *r) { char buf[256]; - Map *map = fid_to_map(c->aux, s->fcall.fid); + Map *map = fid_to_map(r->maps, r->fcall.fid); unsigned short i; if(!map) { - s->errstr = "invalid fid"; + errstr = "invalid fid"; return -1; } i = qpath_item(map->qid.path); - s->fcall.id = RWRITE; switch (qpath_type(map->qid.path)) { case Fdisplay: - if(s->fcall.count > 5) + if(r->fcall.count > 5) goto error_xwrite; - memcpy(buf, s->fcall.data, s->fcall.count); - buf[s->fcall.count] = 0; + memcpy(buf, r->fcall.data, r->fcall.count); + buf[r->fcall.count] = 0; if(!blitz_strtoalign(&align, buf)) goto error_xwrite; /* TODO: resize/hide */ @@ -562,20 +567,20 @@ xwrite(IXPServer *s, IXPConn *c) case Ffont: if(font) free(font); - font = cext_emallocz(s->fcall.count + 1); - memcpy(font, s->fcall.data, s->fcall.count); + font = cext_emallocz(r->fcall.count + 1); + memcpy(font, r->fcall.data, r->fcall.count); /* TODO: XQueryFont */ break; case Fdata: { - unsigned int len = s->fcall.count; + unsigned int len = r->fcall.count; if(i == nitem) new_item(); if(!i || (i >= nitem)) goto error_xwrite; if(len >= sizeof(item[i]->data)) len = sizeof(item[i]->data) - 1; - memcpy(item[i]->data, s->fcall.data, len); + memcpy(item[i]->data, r->fcall.data, len); item[i]->data[len] = 0; /* TODO: redraw */ } @@ -583,70 +588,118 @@ xwrite(IXPServer *s, IXPConn *c) case Fcolor: if(i == nitem) new_item(); - if((i >= nitem) || (s->fcall.count >= 24)) + if((i >= nitem) || (r->fcall.count >= 24)) goto error_xwrite; - memcpy(item[i]->color, s->fcall.data, s->fcall.count); - item[i]->color[s->fcall.count] = 0; + memcpy(item[i]->color, r->fcall.data, r->fcall.count); + item[i]->color[r->fcall.count] = 0; /* TODO: update color */ break; default: error_xwrite: - s->errstr = "invalid write request"; + errstr = "invalid write request"; return -1; break; } + r->fcall.id = RWRITE; return 0; } static int -xclunk(IXPServer *s, IXPConn *c) +xclunk(Req *r) { - Map *maps = c->aux; - Map *m, *map = fid_to_map(maps, s->fcall.fid); + Map *maps = r->maps; + Map *m, *map = fid_to_map(r->maps, r->fcall.fid); if(!map) { - s->errstr = "invalid fid"; + errstr = "invalid fid"; return -1; } if(maps == map) - c->aux = maps = maps->next; + r->maps = maps = maps->next; else { for(m = maps; m && m->next != map; m = m->next); m->next = map->next; } free(map); - s->fcall.id = RCLUNK; + r->fcall.id = RCLUNK; return 0; } static void -freeconn(IXPServer *s, IXPConn *c) +handle_9p_req(IXPServer *s, IXPConn *c) { - Map *m, *maps = c->aux; + Req *r = c->aux; + unsigned int msize; + int ret; + errstr = 0; + if(!(msize = ixp_recv_message(c->fd, msg, IXP_MAX_MSG, &errstr))) { + ixp_server_free_conn(s, c); + return; + } + /*fprintf(stderr, "msize=%d\n", msize);*/ + if((msize = ixp_msg_to_fcall(msg, IXP_MAX_MSG, &r->fcall))) { + switch(r->fcall.id) { + case TVERSION: ret = xversion(r); break; + case TATTACH: ret = xattach(r); break; + case TWALK: ret = xwalk(r); break; + case TREMOVE: ret = xremove(r); break; + case TOPEN: ret = xopen(r); break; + case TREAD: ret = xread(r); break; + case TWRITE: ret = xwrite(r); break; + case TCLUNK: ret = xclunk(r); break; + case TSTAT: ret = xstat(r); break; + default: + goto error_do9p; + break; + } + } + if(ret == -1) { +error_do9p: + /*fprintf(stderr, "function id=%d\n", s->fcall.id);*/ + if(!errstr) + errstr = "function not supported"; + r->fcall.id = RERROR; + cext_strlcpy(r->fcall.errstr, errstr, sizeof(r->fcall.errstr)); + } + msize = ixp_fcall_to_msg(&r->fcall, msg, IXP_MAX_MSG); + if(ixp_send_message(c->fd, msg, msize, &errstr) != msize) + ixp_server_free_conn(s, c); +} - while((m = maps)) { - c->aux = maps = maps->next; - free(m); - } +static void +close_9p_conn(IXPServer *s, IXPConn *c) +{ + Req *r = c->aux; + + if(r) { + Map *m, *maps = r->maps; + while((m = maps)) { + r->maps = maps = maps->next; + free(m); + } + free(r); + } + c->aux = nil; + shutdown(c->fd, SHUT_RDWR); + close(c->fd); } -static IXPTFunc funcs[] = { - {TVERSION, xversion}, - {TATTACH, xattach}, - {TWALK, xwalk}, - {TREMOVE, xremove}, - {TOPEN, xopen}, - {TREAD, xread}, - {TWRITE, xwrite}, - {TCLUNK, xclunk}, - {TSTAT, xstat}, - {0, 0} -}; +static void +new_9p_conn(IXPServer *s, IXPConn *c) +{ + IXPConn *new = ixp_server_alloc_conn(s); + if(new && ((new->fd = ixp_accept_sock(c->fd)) >= 0)) { + new->read = handle_9p_req; + new->close = close_9p_conn; + new->aux = cext_emallocz(sizeof(Req)); + } +} int main(int argc, char *argv[]) { int i; + IXPConn *c; /* command line args */ for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) { @@ -657,7 +710,7 @@ main(int argc, char *argv[]) break; case 'a': if(i + 1 < argc) - sockfile = argv[++i]; + address = argv[++i]; else usage(); break; @@ -675,10 +728,20 @@ main(int argc, char *argv[]) XSetErrorHandler(dummy_error_handler); screen_num = DefaultScreen(dpy); - if(ixp_server_init(&srv, sockfile, funcs, freeconn) == -1) { - fprintf(stderr, "wmiibar: fatal: %s\n", srv.errstr); - exit(1); - } + if(!address) { + fprintf(stderr, "%s\n", "wmiibar: no socket address provided"); + exit(1); + } + ixp_server_init(&srv); + c = ixp_server_alloc_conn(&srv); + if((c->fd = ixp_create_sock(address, &errstr)) < 0) { + fprintf(stderr, "wmiibar: fatal: %s\n", errstr); + exit(1); + } + c->read = new_9p_conn; + c->close = close_9p_conn; + /* TODO: add X conn */ + root_qid.type = IXP_QTDIR; root_qid.version = 0; root_qid.path = mkqpath(Droot, 0); @@ -691,9 +754,8 @@ main(int argc, char *argv[]) font = strdup("fixed"); - ixp_server_loop(&srv); - if(srv.errstr) { - fprintf(stderr, "wmiibar: fatal: %s\n", srv.errstr); + if((errstr = ixp_server_loop(&srv))) { + fprintf(stderr, "wmiibar: fatal: %s\n", errstr); ixp_server_deinit(&srv); exit(1); } diff --git a/libixp2/ixp.h b/libixp2/ixp.h @@ -1,6 +1,6 @@ /* - * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. + *(C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> + *See LICENSE file for license details. */ #include <sys/types.h> @@ -17,7 +17,7 @@ #define IXP_MAX_FLEN 128 #define IXP_MAX_ULEN 32 #define IXP_MAX_STAT 64 -#define IXP_MAX_WELEM 16 /* MAXWELEM */ +#define IXP_MAX_WELEM 16 /*MAXWELEM */ #define IXP_MAX_TFUNCS 14 @@ -68,7 +68,7 @@ muid[ s ] */ -/* 9P message types */ +/*9P message types */ enum { TVERSION = 100, RVERSION, @@ -100,19 +100,19 @@ enum { RWSTAT, }; -/* borrowed from libc.h of Plan 9 */ -#define DMDIR 0x80000000 /* mode bit for directories */ -#define DMAPPEND 0x40000000 /* mode bit for append only files */ -#define DMEXCL 0x20000000 /* mode bit for exclusive use files */ -#define DMMOUNT 0x10000000 /* mode bit for mounted channel */ -#define DMAUTH 0x08000000 /* mode bit for authentication file */ -#define DMTMP 0x04000000 /* mode bit for non-backed-up file */ +/*borrowed from libc.h of Plan 9 */ +#define DMDIR 0x80000000 /*mode bit for directories */ +#define DMAPPEND 0x40000000 /*mode bit for append only files */ +#define DMEXCL 0x20000000 /*mode bit for exclusive use files */ +#define DMMOUNT 0x10000000 /*mode bit for mounted channel */ +#define DMAUTH 0x08000000 /*mode bit for authentication file */ +#define DMTMP 0x04000000 /*mode bit for non-backed-up file */ -#define DMREAD 0x4<<6 /* mode bit for read permission */ -#define DMWRITE 0x2<<6 /* mode bit for write permission */ -#define DMEXEC 0x1<<6 /* mode bit for execute permission */ +#define DMREAD 0x4<<6 /*mode bit for read permission */ +#define DMWRITE 0x2<<6 /*mode bit for write permission */ +#define DMEXEC 0x1<<6 /*mode bit for execute permission */ -/* modes */ +/*modes */ enum { IXP_OREAD = 0x00, IXP_OWRITE = 0x01, @@ -125,7 +125,7 @@ enum { IXP_OAPPEND = 0x80, }; -/* qid.types */ +/*qid.types */ enum { IXP_QTDIR = 0x80, IXP_QTAPPEND = 0x40, @@ -138,8 +138,8 @@ enum { IXP_QTFILE = 0x00, }; -#define IXP_NOTAG (unsigned short)~0U /* Dummy tag */ -#define IXP_NOFID (unsigned int)~0 /* No auth */ +#define IXP_NOTAG (unsigned short)~0U /*Dummy tag */ +#define IXP_NOFID (unsigned int)~0 /*No auth */ typedef struct { unsigned char type; @@ -147,7 +147,7 @@ typedef struct { unsigned long long path; } Qid; -/* stat structure */ +/*stat structure */ typedef struct { unsigned short type; unsigned int dev; @@ -166,55 +166,47 @@ typedef struct { unsigned char id; unsigned short tag; unsigned int fid; - unsigned int maxmsg; /* Tversion, Rversion */ - char version[IXP_MAX_VERSION]; /* Tversion, Rversion */ - unsigned short oldtag; /* Tflush */ - char errstr[IXP_MAX_ERROR]; /* Rerror */ - Qid qid; /* Rattach, Ropen, Rcreate */ - unsigned int iounit; /* Ropen, Rcreate */ - Qid aqid; /* Rauth */ - unsigned int afid; /* Tauth, Tattach */ - char uname[IXP_MAX_ULEN]; /* Tauth, Tattach */ - char aname[IXP_MAX_FLEN]; /* Tauth, Tattach */ - unsigned int perm; /* Tcreate */ - char name[IXP_MAX_FLEN]; /* Tcreate */ - unsigned char mode; /* Tcreate, Topen */ - unsigned int newfid; /* Twalk */ - unsigned short nwname; /* Twalk */ - char wname[IXP_MAX_WELEM][IXP_MAX_FLEN]; /* Twalk */ - unsigned short nwqid; /* Rwalk */ - Qid wqid[IXP_MAX_WELEM]; /* Rwalk */ - unsigned long long offset; /* Tread, Twrite */ - unsigned int count; /* Tread, Twrite, Rread */ - Stat stat; /* Rstat */ - unsigned short nstat; /* Twstat, Rstat */ - unsigned char data[IXP_MAX_MSG]; /* Twrite, Rread, Twstat, - * Rstat */ + unsigned int maxmsg; /*Tversion, Rversion */ + char version[IXP_MAX_VERSION]; /*Tversion, Rversion */ + unsigned short oldtag; /*Tflush */ + char errstr[IXP_MAX_ERROR]; /*Rerror */ + Qid qid; /*Rattach, Ropen, Rcreate */ + unsigned int iounit; /*Ropen, Rcreate */ + Qid aqid; /*Rauth */ + unsigned int afid; /*Tauth, Tattach */ + char uname[IXP_MAX_ULEN]; /*Tauth, Tattach */ + char aname[IXP_MAX_FLEN]; /*Tauth, Tattach */ + unsigned int perm; /*Tcreate */ + char name[IXP_MAX_FLEN]; /*Tcreate */ + unsigned char mode; /*Tcreate, Topen */ + unsigned int newfid; /*Twalk */ + unsigned short nwname; /*Twalk */ + char wname[IXP_MAX_WELEM][IXP_MAX_FLEN]; /*Twalk */ + unsigned short nwqid; /*Rwalk */ + Qid wqid[IXP_MAX_WELEM]; /*Rwalk */ + unsigned long long offset; /*Tread, Twrite */ + unsigned int count; /*Tread, Twrite, Rread */ + Stat stat; /*Rstat */ + unsigned short nstat; /*Twstat, Rstat */ + unsigned char data[IXP_MAX_MSG]; /*Twrite, Rread, Twstat, + *Rstat */ } Fcall; typedef struct IXPServer IXPServer; typedef struct IXPConn IXPConn; -typedef struct { - unsigned char id; - int (*tfunc) (IXPServer *, IXPConn *); -} IXPTFunc; struct IXPConn { int fd; - int dont_close; void (*read) (IXPServer *, IXPConn *); + void (*close) (IXPServer *, IXPConn *); void *aux; }; struct IXPServer { int running; IXPConn conn[IXP_MAX_CONN]; - void (*freeconn) (IXPServer *, IXPConn *); int maxfd; fd_set rd; - IXPTFunc *funcs; - Fcall fcall; - char *errstr; }; typedef struct { @@ -226,21 +218,21 @@ typedef struct { } IXPClient; /* client.c */ -int ixp_client_init(IXPClient * c, char *address); -void ixp_client_deinit(IXPClient * c); -int ixp_client_remove(IXPClient * c, unsigned int newfid, char *filepath); -int ixp_client_create(IXPClient * c, unsigned int dirfid, char *name, +int ixp_client_init(IXPClient *c, char *address); +void ixp_client_deinit(IXPClient *c); +int ixp_client_remove(IXPClient *c, unsigned int newfid, char *filepath); +int ixp_client_create(IXPClient *c, unsigned int dirfid, char *name, unsigned int perm, unsigned char mode); -int ixp_client_walk(IXPClient * c, unsigned int newfid, char *filepath); -int ixp_client_open(IXPClient * c, unsigned int newfid, char *filepath, +int ixp_client_walk(IXPClient *c, unsigned int newfid, char *filepath); +int ixp_client_open(IXPClient *c, unsigned int newfid, char *filepath, unsigned char mode); -int ixp_client_read(IXPClient * c, unsigned int fid, +int ixp_client_read(IXPClient *c, unsigned int fid, unsigned long long offset, void *result, unsigned int res_len); -int ixp_client_write(IXPClient * c, unsigned int fid, +int ixp_client_write(IXPClient *c, unsigned int fid, unsigned long long offset, unsigned int count, unsigned char *data); -int ixp_client_close(IXPClient * c, unsigned int fid); +int ixp_client_close(IXPClient *c, unsigned int fid); /* convert.c */ void *ixp_enc_u8(unsigned char *msg, unsigned char val); @@ -262,26 +254,24 @@ void *ixp_enc_prefix(unsigned char *msg, unsigned int size, unsigned char id, unsigned short tag); void *ixp_dec_prefix(unsigned char *msg, unsigned int *size, unsigned char *id, unsigned short *tag); -void *ixp_enc_qid(unsigned char *msg, Qid * qid); -void *ixp_dec_qid(unsigned char *msg, Qid * qid); -void *ixp_enc_stat(unsigned char *msg, Stat * stat); -void *ixp_dec_stat(unsigned char *msg, Stat * stat); +void *ixp_enc_qid(unsigned char *msg, Qid *qid); +void *ixp_dec_qid(unsigned char *msg, Qid *qid); +void *ixp_enc_stat(unsigned char *msg, Stat *stat); +void *ixp_dec_stat(unsigned char *msg, Stat *stat); /* message.c */ -unsigned short ixp_sizeof_stat(Stat * stat); -unsigned int ixp_fcall_to_msg(Fcall * fcall, void *msg, +unsigned short ixp_sizeof_stat(Stat *stat); +unsigned int ixp_fcall_to_msg(Fcall *fcall, void *msg, unsigned int msglen); unsigned int ixp_msg_to_fcall(void *msg, unsigned int msglen, - Fcall * fcall); + Fcall *fcall); /* server.c */ -IXPConn *ixp_server_add_conn(IXPServer * s, int fd, int dont_close, - void (*read) (IXPServer *, IXPConn *)); -void ixp_server_rm_conn(IXPServer * s, IXPConn * c); -void ixp_server_loop(IXPServer * s); -int ixp_server_init(IXPServer * s, char *address, IXPTFunc * funcs, - void (*freeconn) (IXPServer *, IXPConn *)); -void ixp_server_deinit(IXPServer * s); +IXPConn *ixp_server_alloc_conn(IXPServer *s); +void ixp_server_free_conn(IXPServer *s, IXPConn *c); +char *ixp_server_loop(IXPServer *s); +void ixp_server_init(IXPServer *s); +void ixp_server_deinit(IXPServer *s); /* socket.c */ int ixp_connect_sock(char *address); diff --git a/libixp2/server.c b/libixp2/server.c @@ -18,10 +18,9 @@ #include "cext.h" static IXPConn zero_conn = { -1, 0, 0, 0 }; -static unsigned char msg[IXP_MAX_MSG]; -static IXPConn * -next_free_conn(IXPServer * s) +IXPConn * +ixp_server_alloc_conn(IXPServer *s) { int i; for(i = 0; i < IXP_MAX_CONN; i++) @@ -31,7 +30,7 @@ next_free_conn(IXPServer * s) } static void -prepare_select(IXPServer * s) +prepare_select(IXPServer *s) { int i; FD_ZERO(&s->rd); @@ -46,40 +45,15 @@ prepare_select(IXPServer * s) } void -ixp_server_rm_conn(IXPServer * s, IXPConn * c) -{ - if(!c->dont_close) { - shutdown(c->fd, SHUT_RDWR); - close(c->fd); - } - if(s->freeconn) - s->freeconn(s, c); - *c = zero_conn; -} - -static IXPConn * -init_conn(IXPConn * c, int fd, int dont_close, - void (*read) (IXPServer *, IXPConn *)) +ixp_server_free_conn(IXPServer *s, IXPConn *c) { + if(c->close) + c->close(s, c); *c = zero_conn; - c->fd = fd; - c->dont_close = dont_close; - c->read = read; - return c; -} - -IXPConn * -ixp_server_add_conn(IXPServer * s, int fd, int dont_close, - void (*read) (IXPServer *, IXPConn *)) -{ - IXPConn *c = next_free_conn(s); - if(!c) - return nil; - return init_conn(c, fd, dont_close, read); } static void -handle_conns(IXPServer * s) +handle_conns(IXPServer *s) { int i; for(i = 0; i < IXP_MAX_CONN; i++) { @@ -91,56 +65,11 @@ handle_conns(IXPServer * s) } } -static void -server_client_read(IXPServer * s, IXPConn * c) -{ - unsigned int i, msize; - int ret; - s->errstr = 0; - if(!(msize = ixp_recv_message(c->fd, msg, IXP_MAX_MSG, &s->errstr))) { - ixp_server_rm_conn(s, c); - return; - } - /*fprintf(stderr, "msize=%d\n", msize);*/ - if((msize = ixp_msg_to_fcall(msg, IXP_MAX_MSG, &s->fcall))) { - for(i = 0; s->funcs && s->funcs[i].id; i++) { - if(s->funcs[i].id == s->fcall.id) { - ret = s->funcs[i].tfunc(s, c); - if(ret == -1) - break; - msize = ixp_fcall_to_msg(&s->fcall, msg, s->fcall.maxmsg); - /*fprintf(stderr, "msize=%d\n", msize);*/ - if(ixp_send_message(c->fd, msg, msize, &s->errstr) != msize) - break; - return; - } - } - } - /*fprintf(stderr, "function id=%d\n", s->fcall.id);*/ - if(!s->errstr) - s->errstr = "function not supported"; - s->fcall.id = RERROR; - cext_strlcpy(s->fcall.errstr, s->errstr, sizeof(s->fcall.errstr)); - msize = ixp_fcall_to_msg(&s->fcall, msg, IXP_MAX_MSG); - if(ixp_send_message(c->fd, msg, msize, &s->errstr) != msize) - ixp_server_rm_conn(s, c); -} - -static void -server_read(IXPServer * s, IXPConn * c) -{ - int fd; - IXPConn *new = next_free_conn(s); - if(new && ((fd = ixp_accept_sock(c->fd)) >= 0)) - init_conn(new, fd, 0, server_client_read); -} - -void -ixp_server_loop(IXPServer * s) +char * +ixp_server_loop(IXPServer *s) { int r; s->running = 1; - s->errstr = 0; /* main loop */ while(s->running) { @@ -150,40 +79,28 @@ ixp_server_loop(IXPServer * s) r = select(s->maxfd + 1, &s->rd, 0, 0, 0); if(r == -1 && errno == EINTR) continue; - if(r < 0) { - s->errstr = "fatal select error"; - break; /* allow cleanups in IXP using app */ - } else if(r > 0) + if(r < 0) + return "fatal select error"; + else if(r > 0) handle_conns(s); } + return nil; } -int -ixp_server_init(IXPServer * s, char *address, IXPTFunc * funcs, - void (*freeconn) (IXPServer *, IXPConn *)) +void +ixp_server_init(IXPServer *s) { - int fd, i; - s->funcs = funcs; - s->freeconn = freeconn; - s->errstr = 0; - if(!address) { - s->errstr = "no socket address provided or invalid directory"; - return -1; - } - if((fd = ixp_create_sock(address, &s->errstr)) < 0) - return -1; + size_t i; for(i = 0; i < IXP_MAX_CONN; i++) s->conn[i] = zero_conn; - ixp_server_add_conn(s, fd, 0, server_read); - return 0; } void -ixp_server_deinit(IXPServer * s) +ixp_server_deinit(IXPServer *s) { int i; /* shut down server */ for(i = 0; i < IXP_MAX_CONN; i++) if(s->conn[i].fd >= 0) - ixp_server_rm_conn(s, &s->conn[i]); + ixp_server_free_conn(s, &s->conn[i]); }