wmii

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

commit a4c81cb8f199af385920f71ea1d0ce7df8ae1c2c
parent f4ae1968071cbc35646c19dcf97443e448110252
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Tue,  7 Feb 2006 11:26:00 +0100

proceeded with wmiifs, now I know how to do it


Diffstat:
cmd/wmiifs.c | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 128 insertions(+), 38 deletions(-)

diff --git a/cmd/wmiifs.c b/cmd/wmiifs.c @@ -24,20 +24,13 @@ enum { Fctl }; -typedef struct Bind Bind; -struct Bind { - unsigned int fid; - IXPClient c; -}; - typedef struct Mount Mount; struct Mount { unsigned short id; char wname[IXP_MAX_FLEN]; char address[256]; - Bind **bind; - size_t bindsz; - size_t nbind; + IXPClient client; + IXPConn *respond; }; Qid root_qid; @@ -46,8 +39,12 @@ static IXPServer srv; static Mount **mount = nil; static size_t mountsz = 0; static size_t nmount = 0; +static unsigned char *msg[IXP_MAX_MSG]; + +static void rx_fcall(IXPConn *c); static char version[] = "wmiifs - " VERSION ", (C)opyright MMIV-MMVI Anselm R. Garbe\n"; +static char Enoserv[] = "server not found"; static void usage() @@ -66,6 +63,70 @@ mount_of_name(char *name) return nil; } +static void +xunmount(Mount *mnt) +{ + cext_array_detach((void **)mount, mnt, &mountsz); + nmount--; + ixp_client_deinit(&mnt->client); + free(mnt); +} + +static void +xclose_mount(IXPConn *c) +{ + size_t i; + cext_array_detach((void **)srv.conn, c, &srv.connsz); + for(i = 0; i < nmount; i++) + if(mount[i]->respond == c) { + xunmount(mount[i]); + break; + } + if(c->map) { + for(i = 0; (i < c->mapsz) && c->map[i]; i++) + free(c->map[i]); + free(c->map); + } + if(c->pend) { + for(i = 0; (i < c->pendsz) && c->pend[i]; i++) + free(c->pend[i]); + free(c->pend); + } + free(c); +} + + +static char * +xmount(char *arg) +{ + static unsigned int id = 1; + char *address = arg; + char *wname = strchr(address, ' '); + Mount *mnt; + + *wname = 0; + wname++; + + if(!address || !wname || !*address || !*wname) + return Enoserv; + + mnt = cext_emallocz(sizeof(Mount)); + cext_strlcpy(mnt->wname, wname, sizeof(mnt->wname)); + cext_strlcpy(mnt->address, address, sizeof(mnt->address)); + mount = (Mount **)cext_array_attach((void **)mount, mnt, sizeof(Mount *), &mountsz); + nmount++; + + /* open socket */ + if(ixp_client_init(&mnt->client, mnt->address, id++) == -1) { + xunmount(mnt); + return Enoserv; + } + + mnt->respond = ixp_server_open_conn(&srv, mnt->client.fd, rx_fcall, xclose_mount); + + return nil; +} + static int index_of_id(unsigned short id) { @@ -157,6 +218,7 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk) static char * xwalk(IXPConn *c, Fcall *fcall) { + static unsigned short tag = 0; unsigned short nwqid = 0; Qid dir = root_qid; IXPMap *m; @@ -169,30 +231,25 @@ xwalk(IXPConn *c, Fcall *fcall) if(fcall->nwname) { dir = m->qid; if((mnt = mount_of_name(fcall->wname[0])) && (fcall->nwname > 1)) { - Bind *b = cext_emallocz(sizeof(Bind)); - int i; + unsigned int i; - mnt->bind = (Bind **)cext_array_attach((void **)mnt->bind, b, sizeof(Bind *), &mnt->bindsz); - mnt->nbind++; - - /* open socket */ - if(ixp_client_init(&b->c, mnt->address, mnt->nbind - 1) == -1) - return Enofile; + ixp_fcall_to_msg(fcall, msg, IXP_MAX_MSG); + ixp_msg_to_fcall(msg, IXP_MAX_MSG, &mnt->client.fcall); + fcall->tag = mnt->client.fcall.tag = tag++; - b->c.fcall.id = TWALK; - b->c.fcall.fid = fcall->fid; - b->c.fcall.newfid = fcall->newfid; - b->c.fcall.nwname = fcall->nwname - 1; + mnt->client.fcall.nwname = fcall->nwname - 1; for(i = 1; i < fcall->nwname; i++) - cext_strlcpy(b->c.fcall.wname[i - 1], fcall->wname[i], sizeof(b->c.fcall.wname[i - 1])); + cext_strlcpy(mnt->client.fcall.wname[i - 1], fcall->wname[i], + sizeof(mnt->client.fcall.wname[i - 1])); - if(ixp_client_do_fcall(&b->c) == -1); - /* TODO: unbind client, also in other cases, THINK */ - - !mkqid(&dir, fcall->wname[0], &fcall->wqid[0], True); - for(i = 0; i < b->c.fcall.nwname; i++) - fcall->wqid[i + 1] = b->c.fcall.wqid[i]; - nwqid = i + 1; + i = ixp_fcall_to_msg(&mnt->client.fcall, msg, IXP_MAX_MSG); + mnt->client.errstr = 0; + if(ixp_send_message(mnt->client.fd, msg, i, &mnt->client.errstr) != i) { + xclose_mount(mnt->respond); + return Enofile; + } + ixp_server_enqueue_fcall(mnt->respond, fcall); + return nil; } else { for(nwqid = 0; (nwqid < fcall->nwname) @@ -383,6 +440,7 @@ xstat(IXPConn *c, Fcall *fcall) static char * xwrite(IXPConn *c, Fcall *fcall) { + char *err; char buf[256]; IXPMap *m = ixp_server_fid2map(c, fcall->fid); @@ -390,13 +448,19 @@ xwrite(IXPConn *c, Fcall *fcall) return Enofid; switch (qpath_type(m->qid.path)) { case Fctl: - if(fcall->count == 4) { - memcpy(buf, fcall->data, 4); - buf[4] = 0; - if(!strncmp(buf, "quit", 5)) { - srv.running = 0; - break; - } + if(fcall->count > sizeof(buf) - 1) + return Enocommand; + memcpy(buf, fcall->data, fcall->count); + buf[fcall->count] = 0; + if(!strncmp(buf, "quit", 5)) { + srv.running = 0; + break; + } + else if(!strncmp(buf, "mount ", 6)) { + err = xmount(&buf[6]); + if(err) + return err; + break; } return Enocommand; break; @@ -410,7 +474,33 @@ xwrite(IXPConn *c, Fcall *fcall) } static void -do_fcall(IXPConn *c) +rx_fcall(IXPConn *c) +{ + static Fcall fcall; + unsigned int msize; + char *errstr; + + if((msize = ixp_server_receive_fcall(c, &fcall))) { + /*fprintf(stderr, "fcall=%d\n", fcall.id);*/ + switch(fcall.id) { + case TVERSION: errstr = wmii_ixp_version(c, &fcall); break; + case TATTACH: errstr = wmii_ixp_attach(c, &fcall); break; + case TWALK: errstr = xwalk(c, &fcall); break; + case TREMOVE: errstr = xremove(c, &fcall); break; + case TOPEN: errstr = xopen(c, &fcall); break; + case TREAD: errstr = xread(c, &fcall); break; + case TWRITE: errstr = xwrite(c, &fcall); break; + case TCLUNK: errstr = wmii_ixp_clunk(c, &fcall); break; + case TSTAT: errstr = xstat(c, &fcall); break; + default: errstr = Enofunc; break; + } + if(errstr) + ixp_server_respond_error(c, &fcall, errstr); + } +} + +static void +tx_fcall(IXPConn *c) { static Fcall fcall; unsigned int msize; @@ -441,7 +531,7 @@ new_ixp_conn(IXPConn *c) int fd = ixp_accept_sock(c->fd); if(fd >= 0) - ixp_server_open_conn(c->srv, fd, do_fcall, ixp_server_close_conn); + ixp_server_open_conn(c->srv, fd, tx_fcall, ixp_server_close_conn); } static void