wmii

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

commit a4e2ab7b599a750a2f033ee18da975abd37b3136
parent 72c7d317e210eb8777bbe401052311347f288280
Author: Kris Maglione <bsdaemon@wmii.de>
Date:   Sat, 17 Jun 2006 07:32:49 -0400

Merge in diffs for fs2.c and libixp


Diffstat:
cmd/wm/Makefile | 2+-
cmd/wm/bar.c | 32+++++++++++++++++---------------
cmd/wm/client.c | 20++++++++++----------
cmd/wm/event.c | 2+-
cmd/wm/fs.c | 34+++++++++++++++++-----------------
cmd/wm/fs2.c | 388++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
cmd/wm/view.c | 39++++++++++++++++++++++++++++++++++++++-
cmd/wm/wm.c | 33++++++++++++++-------------------
cmd/wm/wm.h | 67+++++++++++++++++++++++++++++++++++++++++++------------------------
cmd/wmiir.c | 9+++++++--
libixp/client.c | 44++++++++++++++++++++++----------------------
libixp/convert.c | 36++++++++++++++++++++----------------
libixp/intmap.c | 23+++++++++++++++++++++--
libixp/ixp.h | 244+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
libixp/message.c | 46+++++++++++++++++++++++-----------------------
libixp/request.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
libixp/server.c | 52++++++++++++++--------------------------------------
libixp/transport.c | 2+-
18 files changed, 757 insertions(+), 398 deletions(-)

diff --git a/cmd/wm/Makefile b/cmd/wm/Makefile @@ -9,7 +9,7 @@ LDFLAGS += -L../../liblitz -llitz -L../../libixp -lixp -L../../libcext -lcext - # Solaris # LDFLAGS += -lsocket -SRC = area.c bar.c client.c column.c event.c frame.c fs.c geom.c \ +SRC = area.c bar.c client.c column.c event.c frame.c fs2.c geom.c \ key.c mouse.c rule.c view.c wm.c OBJ = ${SRC:.c=.o} diff --git a/cmd/wm/bar.c b/cmd/wm/bar.c @@ -27,10 +27,12 @@ create_bar(char *name) b->id = id++; cext_strlcpy(b->name, name, sizeof(b->name)); - cext_strlcpy(b->colstr, def.normcolor, sizeof(b->colstr)); - b->color = def.norm; + cext_strlcpy(b->color.string, def.normcolor.string, sizeof(b->color.string)); + b->color.col = def.normcolor.col; - for(i=&bar; *i && (strcmp((*i)->name, name) < 0); i=&(*i)->next); + for(i=&lbar; *i; i=&(*i)->next) + if(strcmp((*i)->name, name) < 0) + break; b->next = *i; *i = b; @@ -41,7 +43,7 @@ void destroy_bar(Bar *b) { Bar **i; - for(i=&bar; *i && *i != b; i=&(*i)->next); + for(i=&lbar; *i && *i != b; i=&(*i)->next); *i = b->next; b->next = free_bars; @@ -98,14 +100,14 @@ draw_bar() d.rect.x = d.rect.y = 0; d.font = blitzfont; - d.color = def.norm; + d.color = def.normcolor.col; blitz_drawlabel(&d); blitz_drawborder(&d); - if(!bar) + if(!lbar) goto MapBar; - for(b=bar; b && (w < brect.width); b=b->next, size++) { + for(b=lbar; b && (w < brect.width); b=b->next, size++) { b->rect.x = 0; b->rect.y = 0; b->rect.width = brect.height; @@ -118,21 +120,21 @@ draw_bar() if(b) { /* give all bars same width */ for(; b; b=b->next, size++); w = brect.width / size; - for(b=bar; b; b=b->next) { + for(b=lbar; b; b=b->next) { b->rect.x = i * w; b->rect.width = w; } } - else { /* expand bar properly */ - for(exp = bar; exp && exp->next; exp=exp->next); + else { /* expand lbar properly */ + for(exp = lbar; exp && exp->next; exp=exp->next); if(exp) exp->rect.width += (brect.width - w); - for(b=bar; b->next; b=b->next) + for(b=lbar; b->next; b=b->next) b->next->rect.x = b->rect.x + b->rect.width; } - for(b=bar; b; b=b->next) { - d.color = b->color; + for(b=lbar; b; b=b->next) { + d.color = b->color.col; d.rect = b->rect; d.data = b->data; if(b == exp) @@ -154,7 +156,7 @@ bar_of_name(const char *name) Bar *b; cext_strlcpy(buf, name, sizeof(buf)); - for(b=bar; b && strncmp(b->name, name, sizeof(b->name)); b=b->next); + for(b=lbar; b && strncmp(b->name, name, sizeof(b->name)); b=b->next); return b; } @@ -162,6 +164,6 @@ Bar * bar_of_id(unsigned short id) { Bar *b; - for(b=bar; b && b->id != id; b=b->next); + for(b=lbar; b && b->id != id; b=b->next); return b; } diff --git a/cmd/wm/client.c b/cmd/wm/client.c @@ -293,10 +293,10 @@ draw_client(Client *c) d.font = blitzfont; d.gc = c->gc; - if(sel_screen && (c == sel_client())) - d.color = def.sel; + if(sel_screen && (c == sel_client())) + d.color = def.selcolor.col; else - d.color = def.norm; + d.color = def.normcolor.col; /* draw border */ if(def.border) { @@ -323,17 +323,17 @@ draw_client(Client *c) d.data = buf; if(f->area->sel == f) - d.color = def.sel; + d.color = def.selcolor.col; else - d.color = def.norm; + d.color = def.normcolor.col; blitz_drawlabel(&d); blitz_drawborder(&d); d.rect.x = 0; - if(sel_screen && (c == sel_client())) - d.color = def.sel; + if(sel_screen && (c == sel_client())) + d.color = def.selcolor.col; else - d.color = def.norm; + d.color = def.normcolor.col; /* tag bar */ d.rect.width = d.rect.height + blitz_textwidth(&blitzfont, c->tags); @@ -874,7 +874,7 @@ match_tags(Client *c, const char *prop) Rule *r; regmatch_t tmpregm; - for(r=trule; r; r=r->next) + for(r=def.tagrules.rule; r; r=r->next) if(!regexec(&r->regex, prop, 1, &tmpregm, 0)) if(!strlen(c->tags) || !strncmp(c->tags, "nil", 4)) apply_tags(c, r->value); @@ -883,7 +883,7 @@ match_tags(Client *c, const char *prop) void apply_rules(Client *c) { - if(def.tagrules) + if(def.tagrules.string) match_tags(c, c->props); if(!strlen(c->tags)) diff --git a/cmd/wm/event.c b/cmd/wm/event.c @@ -73,7 +73,7 @@ handle_buttonrelease(XEvent *e) XButtonPressedEvent *ev = &e->xbutton; static char buf[32]; if(ev->window == barwin) { - for(b=bar; b; b=b->next) + for(b=lbar; b; b=b->next) if(ispointinrect(ev->x, ev->y, &b->rect)) { snprintf(buf, sizeof(buf), "BarClick %s %d\n", b->name, ev->button); diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c @@ -1186,11 +1186,11 @@ xread(IXPConn *c, Fcall *fcall) break; case FsFselcolors: if((fcall->count = strlen(def.selcolor))) - memcpy(p, def.selcolor, fcall->count); + memcpy(p, def.selcolor.string, fcall->count); break; case FsFnormcolors: if((fcall->count = strlen(def.normcolor))) - memcpy(p, def.normcolor, fcall->count); + memcpy(p, def.normcolor.string, fcall->count); break; case FsFkeys: fcall->count = def.keys ? strlen(def.keys) : 0; @@ -1382,18 +1382,18 @@ xwrite(IXPConn *c, Fcall *fcall) if((fcall->count != 23) || (fcall->data[0] != '#') || (fcall->data[8] != '#') || (fcall->data[16] != '#')) return Ebadvalue; - memcpy(def.selcolor, fcall->data, fcall->count); - def.selcolor[fcall->count] = 0; - blitz_loadcolor(&def.sel, def.selcolor); + memcpy(def.selcolor.string, fcall->data, fcall->count); + def.selcolor.string[fcall->count] = 0; + blitz_loadcolor(&def.selcolor.col, def.selcolor.string); draw_clients(); break; case FsFnormcolors: if((fcall->count != 23) || (fcall->data[0] != '#') || (fcall->data[8] != '#') || (fcall->data[16] != '#')) return Ebadvalue; - memcpy(def.normcolor, fcall->data, fcall->count); - def.normcolor[fcall->count] = 0; - blitz_loadcolor(&def.norm, def.normcolor); + memcpy(def.normcolor.string, fcall->data, fcall->count); + def.normcolor.string[fcall->count] = 0; + blitz_loadcolor(&def.normcolor.col, def.normcolor.string); draw_clients(); break; case FsFkeys: @@ -1411,9 +1411,9 @@ xwrite(IXPConn *c, Fcall *fcall) def.keys[fcall->offset + fcall->count] = 0; break; case FsFtagrules: - if(def.tagrulessz < fcall->offset + fcall->count + 1) { - def.tagrulessz = fcall->offset + fcall->count + 1; - tmp = cext_emallocz(def.tagrulessz); + if(def.tagrules.size < fcall->offset + fcall->count + 1) { + def.tagrules.size = fcall->offset + fcall->count + 1; + tmp = cext_emallocz(def.tagrules.size); len = def.tagrules ? strlen(def.tagrules) : 0; if(len) { memcpy(tmp, def.tagrules, len); @@ -1425,9 +1425,9 @@ xwrite(IXPConn *c, Fcall *fcall) def.tagrules[fcall->offset + fcall->count] = 0; break; case FsFcolrules: - if(def.colrulessz < fcall->offset + fcall->count + 1) { - def.colrulessz = fcall->offset + fcall->count + 1; - tmp = cext_emallocz(def.colrulessz); + if(def.colrules.size < fcall->offset + fcall->count + 1) { + def.colrules.size = fcall->offset + fcall->count + 1; + tmp = cext_emallocz(def.colrules.size); len = def.colrules ? strlen(def.colrules) : 0; if(len) { memcpy(tmp, def.colrules, len); @@ -1528,13 +1528,13 @@ xclunk(IXPConn *c, Fcall *fcall) if(type == FsFkeys) update_keys(); else if(type == FsFtagrules) { - update_rules(&trule, def.tagrules); + update_rules(&def.tagrules.rule, def.tagrules.string); for(cl=client; cl; cl=cl->next) apply_rules(cl); update_views(); } else if(type == FsFcolrules) { - update_rules(&vrule, def.colrules); + update_rules(&def.colrules.rule, def.colrules.string); } if(c->map == m) c->map = m->next; @@ -1607,5 +1607,5 @@ new_ixp_conn(IXPConn *c) int fd = accept(c->fd, nil, nil); if(fd >= 0) - ixp_server_open_conn(c->srv, fd, do_fcall, ixp_server_close_conn); + ixp_server_open_conn(c->srv, fd, do_fcall, nil); } diff --git a/cmd/wm/fs2.c b/cmd/wm/fs2.c @@ -4,44 +4,8 @@ #include <time.h> #include "wm.h" -P9Srv p9srv = { - .open= fs_open, - .walk= fs_walk, - .read= fs_read, - .stat= fs_stat, - .write= fs_write, - .clunk= fs_clunk, - .attach=fs_attach, - .create=fs_create, - .remove=fs_remove, - .freefid=fs_freefid -}; - -#define QID(t, i) (((long long)((t)&0xFF)<<32)|((i)&0xFFFFFFFF)) -/* Will I ever need these macros? - * I don't think so. */ -#define TYPE(q) ((q)>>32&0xFF) -#define ID(q) ((q)&0xFFFFFFFF) - -static char - Enoperm[] = "permission denied", - Enofile[] = "file not found", - Eisdir[] = "file is a directory", - Ebadvalue[] = "bad value", - Enocommand[] = "command not supported"; -//static char Efidinuse[] = "fid in use"; -//static char Enomode[] = "mode not supported"; -//static char Enofunc[] = "function not supported"; - -enum { FsRoot, FsDClient, FsDClients, FsDLBar, - FsDRBar, FsDSClient, FsDTag, FsDTags, - - FsFBar, FsFBorder, FsFCNorm, FsFCSel, - FsFCctl, FsFCindex, FsFColRules, FsFEvent, - FsFFont, FsFKeys, FsFRctl, FsFTagRules, - FsFTctl, FsFTindex, FsFprops, RsFFont -}; +/* Datatypes: */ typedef struct Dirtab Dirtab; struct Dirtab { char *name; @@ -56,6 +20,7 @@ struct FileId { union { void *ref; Bar *bar; + Bar **bar_p; View *view; Client *client; Rules *rule; @@ -67,15 +32,65 @@ struct FileId { unsigned short nref; }; +/* Function prototypes */ static void dostat(Stat *s, unsigned int len, FileId *f); + +/* Error messages */ +static char + Enoperm[] = "permission denied", + Enofile[] = "file not found", + Ebadvalue[] = "bad value", + Einterrupted[] = "interrupted", + Enocommand[] = "command not supported"; +/* Old error messages: + Eisdir[] = "file is a directory", + Efidinuse[] = "fid in use", + Enomode[] = "mode not supported", + Enofunc[] = "function not supported", +*/ + +/* Constants */ +enum { /* Dirs */ + FsRoot, FsDClient, FsDClients, FsDBar, + FsDSClient, FsDTag, FsDTags, + /* Files */ + FsFBar, FsFBorder, FsFCNorm, FsFCSel, + FsFCctl, FsFCindex, FsFColRules, FsFCtags, + FsFEvent, FsFFont, FsFKeys, FsFRctl, + FsFTagRules, FsFTctl, FsFTindex, FsFprops, + RsFFont +}; + +/* QID Macros */ +#define QID(t, i) (((long long)((t)&0xFF)<<32)|((i)&0xFFFFFFFF)) +/* Will I ever need these macros? + * I don't think so. */ +#define TYPE(q) ((q)>>32&0xFF) +#define ID(q) ((q)&0xFFFFFFFF) + +/* Global vars */ FileId *free_fileid = nil; +Req *pending_event_reads = nil; +P9Srv p9srv = { + .open= fs_open, + .walk= fs_walk, + .read= fs_read, + .stat= fs_stat, + .write= fs_write, + .clunk= fs_clunk, + .flush= fs_flush, + .attach=fs_attach, + .create=fs_create, + .remove=fs_remove, + .freefid=fs_freefid +}; /* ad-hoc file tree. Empty names ("") indicate a dynamic entry to be filled * in by lookup_file */ static Dirtab dirtabroot[]= {{".", QTDIR, FsRoot, 0500|DMDIR }, - {"rbar", QTDIR, FsDRBar, 0700|DMDIR }, - {"lbar", QTDIR, FsDLBar, 0700|DMDIR }, + {"rbar", QTDIR, FsDBar, 0700|DMDIR }, + {"lbar", QTDIR, FsDBar, 0700|DMDIR }, {"client", QTDIR, FsDClients, 0500|DMDIR }, {"tag", QTDIR, FsDTags, 0500|DMDIR }, {"ctl", QTAPPEND, FsFRctl, 0600|DMAPPEND }, @@ -93,14 +108,16 @@ dirtabclients[]={{".", QTDIR, FsDClients, 0500|DMDIR }, {nil}}, dirtabclient[]= {{".", QTDIR, FsDClient, 0500|DMDIR }, {"ctl", QTAPPEND, FsFCctl, 0200|DMAPPEND }, + {"tags", QTFILE, FsFCtags, 0600 }, {"props", QTFILE, FsFprops, 0400 }, {nil}}, dirtabsclient[]={{".", QTDIR, FsDSClient, 0500|DMDIR }, {"ctl", QTAPPEND, FsFCctl, 0200|DMAPPEND }, {"index", QTFILE, FsFCindex, 0400 }, + {"tags", QTFILE, FsFCtags, 0600 }, {"props", QTFILE, FsFprops, 0400 }, {nil}}, -dirtabbar[]= {{".", QTDIR, FsDRBar, 0700|DMDIR }, +dirtabbar[]= {{".", QTDIR, FsDBar, 0700|DMDIR }, {"", QTFILE, FsFBar, 0600 }, {nil}}, dirtabtags[]= {{".", QTDIR, FsDTags, 0500|DMDIR }, @@ -115,8 +132,7 @@ dirtabtag[]= {{".", QTDIR, FsDTag, 0500|DMDIR }, * since otherwise we would need to use compound literals */ static Dirtab *dirtab[] = { [FsRoot] dirtabroot, - [FsDRBar] dirtabbar, - [FsDLBar] dirtabbar, + [FsDBar] dirtabbar, [FsDClients] dirtabclients, [FsDClient] dirtabclient, [FsDSClient] dirtabsclient, @@ -198,7 +214,9 @@ lookup_file(FileId *parent, char *name) case FsDClients: if(!name || !strncmp(name, "sel", 4)) { if((c = sel_client())) { - file = push_file(&last); + file = get_file(); + *last = file; + last = &file->next; file->ref = c; file->id = c->id; file->index = idx_of_client(c); @@ -214,7 +232,9 @@ lookup_file(FileId *parent, char *name) i=0; for(c=client; c; c=c->next, i++) { if(!name || i == id) { - file = push_file(&last); + file = get_file(); + *last = file; + last = &file->next; file->ref = c; file->id = c->id; file->tab = *dir; @@ -226,7 +246,9 @@ lookup_file(FileId *parent, char *name) case FsDTags: if(!name || !strncmp(name, "sel", 4)) { if(sel) { - file = push_file(&last); + file = get_file(); + *last = file; + last = &file->next; file->ref = sel; file->id = sel->id; file->tab = *dir; @@ -235,7 +257,9 @@ lookup_file(FileId *parent, char *name) } for(v=view; v; v=v->next) { if(!name || !strcmp(name, v->name)) { - file = push_file(&last); + file = get_file(); + *last = file; + last = &file->next; file->ref = v; file->id = v->id; file->tab = *dir; @@ -244,11 +268,12 @@ lookup_file(FileId *parent, char *name) } } break; - case FsDRBar: - case FsDLBar: - for(b=parent->ref; b; b=b->next) { + case FsDBar: + for(b=*parent->bar_p; b; b=b->next) { if(!name || !strcmp(name, b->name)) { - file = push_file(&last); + file = get_file(); + *last = file; + last = &file->next; file->ref = b; file->id = b->id; file->tab = *dir; @@ -260,18 +285,21 @@ lookup_file(FileId *parent, char *name) } }else /* Static dirs */ if(!name || !strcmp(name, dir->name)) { - file = push_file(&last); + file = get_file(); + *last = file; + last = &file->next; file->id = 0; file->ref = parent->ref; file->tab = *dir; + file->tab.name = strdup(file->tab.name); /* Special considerations: */ switch(file->tab.type) { - case FsDLBar: - file->ref = lbar; - break; - case FsDRBar: - file->ref = rbar; + case FsDBar: + if(!strncmp(file->tab.name, "lbar", 5)) + file->ref = &lbar; + else + file->ref = &rbar; break; case FsFColRules: file->ref = &def.colrules; @@ -315,6 +343,7 @@ fs_walk(Req *r) { nf = lookup_file(f, r->ifcall.wname[i]); if(!nf) break; + cext_assert(!nf->next); nf->next = f; f = nf; } @@ -336,8 +365,8 @@ fs_walk(Req *r) { if(r->ifcall.fid == r->ifcall.newfid) { nf=r->fid->aux; r->fid->aux = f; - for(; nf; nf=f) { - f = nf->next; + while((nf = f)) { + f=f->next; free_file(nf); } } @@ -347,7 +376,6 @@ fs_walk(Req *r) { respond(r, nil); } -/* All of this stat stuf is ugly. */ void fs_stat(Req *r) { Stat s; @@ -363,6 +391,7 @@ fs_stat(Req *r) { respond(r, nil); } +/* This should be moved to libixp */ static void write_buf(Req *r, void *buf, unsigned int len) { if(r->ifcall.offset >= len) @@ -385,7 +414,7 @@ void fs_read(Req *r) { unsigned char *buf; FileId *f, *tf; - unsigned int n, offset; + int n, offset; int size; offset = 0; @@ -411,8 +440,8 @@ fs_read(Req *r) { offset += n; } - for(; f; f = tf) { - tf = f->next; + while((f = tf)) { + tf=tf->next; free_file(f); } @@ -437,11 +466,32 @@ fs_read(Req *r) { case FsFFont: write_buf(r, (void *)def.font, strlen(def.font)); return respond(r, nil); + case FsFCtags: + write_buf(r, (void *)f->client->tags, strlen(f->client->tags)); + return respond(r, nil); + case FsFCindex: + if(r->ifcall.offset) + return respond(r, nil); + n = asprintf((char **)&r->ofcall.data, "%d", f->index); + cext_assert(n >= 0); + r->ofcall.count = n; + return respond(r, nil); case FsFBorder: - asprintf((void *)&r->ofcall.data, "%d", def.border); - if(!r->ifcall.offset) - r->ofcall.count = strlen(r->ofcall.data); + if(r->ifcall.offset) + return respond(r, nil); + n = asprintf((char **)&r->ofcall.data, "%d", def.border); + cext_assert(n >= 0); + r->ofcall.count = n; return respond(r, nil); + case FsFTindex: + buf = view_index(f->view); + n = strlen(buf); + write_buf(r, (void *)buf, n); + return respond(r, nil); + case FsFEvent: + r->aux = pending_event_reads; + pending_event_reads = r; + return; } /* XXX: This should be taken care of by open */ /* should probably be an assertion in the future */ @@ -461,8 +511,6 @@ fs_attach(Req *r) { respond(r, nil); } -/* XXX: fs_* functions below here are yet to be properly implemented */ - void fs_open(Req *r) { /* XXX */ @@ -481,16 +529,11 @@ fs_freefid(Fid *f) { } void -fs_remove(Req *r) { - respond(r, "not implemented"); -} - -void fs_clunk(Req *r) { Client *c; FileId *f = r->fid->aux; - switch(r->ifcall.type) { + switch(f->tab.type) { case FsFTagRules: update_rules(&f->rule->rule, f->rule->string); /* no break */ @@ -499,10 +542,19 @@ fs_clunk(Req *r) { apply_rules(c); update_views(); break; + case FsFKeys: + update_keys(); + break; + case FsFCtags: + apply_tags(f->client, f->client->tags); + update_views(); + draw_client(f->client); + break; } respond(r, nil); } +/* This should be moved to libixp */ void write_to_buf(Req *r, void *buf, unsigned int *len, unsigned int max) { unsigned int offset, count; @@ -517,8 +569,7 @@ write_to_buf(Req *r, void *buf, unsigned int *len, unsigned int max) { if(max && (count > max - offset)) count = max - offset; - if(r->fid->omode&OTRUNC || (offset + count > *len)) - *len = offset + count; + *len = offset + count; if(max == 0) { *(void **)buf = realloc(*(void **)buf, *len); @@ -529,6 +580,34 @@ write_to_buf(Req *r, void *buf, unsigned int *len, unsigned int max) { memcpy(buf + offset, r->ifcall.data, count); } +/* This should be moved to libixp */ +void +data_to_cstring(Req *r) { + unsigned int i; + if(r->ifcall.count) { + for(i=0; i < r->ifcall.count; i++) + if(r->ifcall.data[i] == '\n') + break; + if(i == r->ifcall.count) + r->ifcall.data = realloc(r->ifcall.data, ++i); + cext_assert(r->ifcall.data); + r->ifcall.data[i] = '\0'; + } +} + +/* This should be moved to liblitz */ +int +parse_colors(char **buf, int *buflen, Color *col) { + unsigned int i; + if(*buflen < 23 || 3 != sscanf(*buf, "#%06x #%06x #%06x", &i,&i,&i)) + return 0; + (*buflen) -= 23; + bcopy(*buf, col->string, 23); + blitz_loadcolor(&col->col, col->string); + return 1; +} + +/* This function needs to be seriously cleaned up */ void fs_write(Req *r) { FileId *f; @@ -536,64 +615,129 @@ fs_write(Req *r) { unsigned int i; f = r->fid->aux; - if(f->tab.perm & DMDIR) { - respond(r, Eisdir); - }else{ - switch(f->tab.type) { - case FsFColRules: - case FsFTagRules: - write_to_buf(r, &f->rule->string, &f->rule->size, 0); - return respond(r, nil); - case FsFKeys: - write_to_buf(r, &def.keys, &def.keyssz, 0); - return respond(r, nil); - case FsFFont: - i=strlen(def.font); - write_to_buf(r, &def.font, &i, 0); - return respond(r, nil); - case FsFBorder: - /* fix me! */ - buf = realloc(r->ifcall.data, r->ifcall.count + 1); - cext_assert(buf); - buf[r->ifcall.count] = '\0'; - i = (unsigned int)strtol(r->ifcall.data, &buf, 10); - if(*buf) - return respond(r, Ebadvalue); - def.border = i; - return respond(r, nil); - case FsFCSel: - case FsFCNorm: - if((r->ifcall.count != 23) || - (3 != sscanf(r->ifcall.data, "#%06x #%06x #%06x", &i,&i,&i))) - return respond(r, Ebadvalue); - r->ofcall.count = 23; - bcopy(r->ifcall.data, f->col->string, 23); - blitz_loadcolor(&f->col->col, f->col->string); - draw_clients(); - return respond(r, nil); - case FsFRctl: - if(!strncmp(r->ifcall.data, "quit", 5)) - srv.running = 0; - else if(!strncmp(buf, "view ", 5)) - select_view(&r->ifcall.data[5]); - else - return respond(r, Enocommand); - r->ofcall.msize = r->ifcall.msize; - return respond(r, nil); + switch(f->tab.type) { + case FsFColRules: + case FsFTagRules: + write_to_buf(r, &f->rule->string, &f->rule->size, 0); + return respond(r, nil); + case FsFKeys: + write_to_buf(r, &def.keys, &def.keyssz, 0); + return respond(r, nil); + case FsFFont: + data_to_cstring(r); + i=strlen(def.font); + write_to_buf(r, &def.font, &i, 0); + def.font[i] = '\0'; + r->ofcall.count = i- r->ifcall.offset; + return respond(r, nil); + case FsFCtags: + data_to_cstring(r); + i=strlen(f->client->tags); + write_to_buf(r, &f->client->tags, &i, 255); + f->client->tags[i] = '\0'; + r->ofcall.count = i- r->ifcall.offset; + return respond(r, nil); + case FsFBorder: + data_to_cstring(r); + i = (unsigned int)strtol(r->ifcall.data, &buf, 10); + if(*buf) + return respond(r, Ebadvalue); + def.border = i; + return respond(r, nil); + case FsFBar: + /* XXX: This should validate after each write */ + i = strlen(f->bar->buf); + write_to_buf(r, &f->bar->buf, &i, 279); + f->bar->buf[i] = '\0'; + r->ofcall.count = i- r->ifcall.offset; + return respond(r, nil); + case FsFCSel: + case FsFCNorm: + /* XXX: This allows for junk after the color string */ + data_to_cstring(r); + buf = r->ifcall.data; + i = r->ifcall.count; + if(!parse_colors((char **)&buf, &i, f->col)) + return respond(r, Ebadvalue); + draw_clients(); + r->ofcall.count = r->ifcall.count - i; + return respond(r, nil); + case FsFRctl: + data_to_cstring(r); + + /* XXX: This needs to be moved to client_message(char *) */ + if(!strncmp(r->ifcall.data, "quit", 5)) + srv.running = 0; + else if(!strncmp(r->ifcall.data, "view ", 5)) + select_view(&r->ifcall.data[5]); + else + return respond(r, Enocommand); + r->ofcall.count = r->ifcall.count; + return respond(r, nil); + case FsFEvent: + /* XXX: r->ifcall.count could be very large */ + buf = cext_emallocz(r->ifcall.count + 1); + bcopy(r->ifcall.data, buf, r->ifcall.count); + write_event(buf); + free(buf); + r->ofcall.count = r->ifcall.count; + return respond(r, nil); + } + respond(r, Enoperm); +} + +void +fs_flush(Req *r) { + Req **t; + for(t=&pending_event_reads; *t; t=(Req **)&(*t)->aux) { + if(*t == r->oldreq) { + *t = (*t)->aux; + respond(r->oldreq, Einterrupted); + break; } - respond(r, Enoperm); } + respond(r, nil); } void fs_create(Req *r) { + FileId *f = r->fid->aux; + switch(f->tab.type) { + default: + /* XXX: This should be taken care of by the library */ + return respond(r, Enoperm); + case FsDBar: + if(!strlen(r->ifcall.name)) + return respond(r, Ebadvalue); + create_bar(r->ifcall.name); + f = lookup_file(f, r->ifcall.name); + if(!f) + return respond(r, Enofile); + r->ofcall.qid.type = f->tab.qtype; + r->ofcall.qid.path = QID(f->tab.type, f->id); + free_file(f); + respond(r, nil); + break; + } +} + +void +fs_remove(Req *r) { respond(r, "not implemented"); } -/* XXX: Shuts up the linker, but is yet to be written */ void write_event(char *buf) { - return; + Req **r; + unsigned int len = strlen(buf); + if(!len) + return; + for(r=&pending_event_reads; *r; *r=(*r)->aux) { + /* XXX: It would be nice if strdup wasn't necessary here */ + (*r)->ofcall.data = strdup(buf); + (*r)->ofcall.count = len; + respond(*r, nil); + } } static void diff --git a/cmd/wm/view.c b/cmd/wm/view.c @@ -337,6 +337,43 @@ is_view_of(Client *c, View *v) return False; } +/* XXX: This will need cleanup */ +unsigned char * +view_index(View *v) { + enum { BUF_MAX = 8092 }; + static unsigned char buf[BUF_MAX]; + unsigned int a_i, buf_i, n; + int len; + Frame *f; + Area *a; + + len = BUF_MAX; + buf_i = 0; + for((a = v->area), (a_i = 0); a; (a=a->next), (a_i++)) { + for(f=a->frame; f && len > 0; f=f->anext) { + XRectangle *r = &f->rect; + if(a_i == 0) + n = snprintf(&buf[buf_i], len, "~ %d %d %d %d %d %s\n", + idx_of_client(f->client), + r->x, r->y, r->width, r->height, + f->client->props); + else + n = snprintf(&buf[buf_i], len, "%d %d %d %s\n", + a_i, idx_of_client(f->client), + r->width, f->client->props); + buf_i += n; + len -= n; + } + } + return buf; +} + +/* XXX: This will need cleanup too */ +int +view_message(View *v, char *message) { + return 0; +} + static Bool is_empty(View *v) { @@ -391,7 +428,7 @@ newcolw_of_view(View *v) unsigned int i, n; regmatch_t tmpregm; - for(r=vrule; r; r=r->next) { + for(r=def.colrules.rule; r; r=r->next) { if(!regexec(&r->regex, v->name, 1, &tmpregm, 0)) { char buf[256]; char *toks[16]; diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c @@ -148,7 +148,7 @@ init_screen() gcv.subwindow_mode = IncludeInferiors; gcv.function = GXxor; - gcv.foreground = def.sel.bg; + gcv.foreground = def.selcolor.col.bg; gcv.plane_mask = AllPlanes; gcv.graphics_exposures = False; xorgc = XCreateGC(dpy, root, GCForeground | GCGraphicsExposures | @@ -245,7 +245,7 @@ main(int argc, char *argv[]) dpy = XOpenDisplay(0); if(!dpy) { - fprintf(stderr, "%s", "wmiiwm: cannot open display\n"); + fputs("wmiiwm: cannot open display\n", stderr); exit(1); } screen = DefaultScreen(dpy); @@ -259,8 +259,7 @@ main(int argc, char *argv[]) XSync(dpy, False); if(other_wm_running) { - fprintf(stderr, - "wmiiwm: another window manager is already running\n"); + fputs("wmiiwm: another window manager is already running\n", stderr); exit(1); } if(checkwm) { @@ -281,36 +280,32 @@ main(int argc, char *argv[]) } /* IXP server */ - ixp_server_open_conn(&srv, i, new_ixp_conn, ixp_server_close_conn); - root_qid.qid.dir_type = FsDroot; - root_qid.type = IXP_QTDIR; - root_qid.version = 0; - root_qid.ptype = FsDroot; + ixp_server_open_conn(&srv, i, &p9srv, serve_9pcon, nil); /* X server */ - ixp_server_open_conn(&srv, ConnectionNumber(dpy), check_x_event, nil); + ixp_server_open_conn(&srv, ConnectionNumber(dpy), nil, check_x_event, nil); init_x_event_handler(); blitz_x11_init(dpy); view = nil; client = nil; sel = nil; - bar = nil; + lbar = nil; key = nil; - def.colrules = nil; - def.colrulessz = 0; - def.tagrules = nil; - def.tagrulessz = 0; + def.colrules.string = nil; + def.colrules.size = 0; + def.tagrules.string = nil; + def.tagrules.size = 0; def.keys = nil; def.keyssz = 0; def.font = strdup(BLITZ_FONT); def.border = 2; def.colmode = Coldefault; - cext_strlcpy(def.selcolor, BLITZ_SELCOLORS, sizeof(def.selcolor)); - blitz_loadcolor(&def.sel, def.selcolor); - cext_strlcpy(def.normcolor, BLITZ_NORMCOLORS, sizeof(def.normcolor)); - blitz_loadcolor(&def.norm, def.normcolor); + cext_strlcpy(def.selcolor.string, BLITZ_SELCOLORS, sizeof(def.selcolor.string)); + blitz_loadcolor(&def.selcolor.col, def.selcolor.string); + cext_strlcpy(def.normcolor.string, BLITZ_NORMCOLORS, sizeof(def.normcolor.string)); + blitz_loadcolor(&def.normcolor.col, def.normcolor.string); cext_strlcpy(def.grabmod, "Mod1", sizeof(def.grabmod)); def.mod = Mod1Mask; diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h @@ -42,6 +42,7 @@ enum { }; /* 8-bit qid.path.type */ +/* enum { FsDroot, FsDdef, @@ -74,18 +75,15 @@ enum { FsFindex, FsLast }; +*/ enum { MIN_COLWIDTH = 64 }; enum { WM_PROTOCOL_DELWIN = 1 }; typedef struct View View; -#define VIEW(p) ((View *)(p)) typedef struct Area Area; -#define AREA(p) ((Area *)(p)) typedef struct Frame Frame; -#define FRAME(p) ((Frame *)(p)) typedef struct Client Client; -#define CLIENT(p) ((Client *)(p)) struct View { View *next; @@ -156,33 +154,46 @@ struct Key { KeyCode key; }; -#define BAR(p) ((Bar *)(p)) +typedef struct Color { + char string[24]; + BlitzColor col; +} Color; + typedef struct Bar Bar; struct Bar { Bar *next; + char buf[280]; char name[256]; char data[256]; - char colstr[24]; + Color color; unsigned short id; - BlitzColor color; XRectangle rect; }; +typedef struct Rule Rule; +struct Rule { + Rule *next; + regex_t regex; + char value[256]; +}; + +typedef struct Rules { + Rule *rule; + char *string; + unsigned int size; +} Rules; + /* default values */ typedef struct { - char selcolor[24]; - char normcolor[24]; + Color selcolor; + Color normcolor; char *font; - BlitzColor sel; - BlitzColor norm; unsigned int border; unsigned int snap; char *keys; unsigned int keyssz; - char *tagrules; - unsigned int tagrulessz; - char *colrules; - unsigned int colrulessz; + Rules tagrules; + Rules colrules; char grabmod[5]; unsigned long mod; int colmode; @@ -203,22 +214,16 @@ typedef struct { } PackedQid; /* global variables */ -typedef struct Rule Rule; -struct Rule { - Rule *next; - regex_t regex; - char value[256]; -}; /* global variables */ View *view; Client *client; Key *key; -Bar *bar; -Rule *trule; -Rule *vrule; +Bar *lbar; +Bar *rbar; View *sel; +P9Srv p9srv; Display *dpy; int screen; Window root; @@ -317,6 +322,19 @@ int idx_of_frame(Frame *f); Frame *frame_of_id(Area *a, unsigned short id); Client *frame_of_win(Window w); +/* fs2.c */ +void fs_attach(Req *r); +void fs_clunk(Req *r); +void fs_create(Req *r); +void fs_flush(Req *r); +void fs_freefid(Fid *f); +void fs_open(Req *r); +void fs_read(Req *r); +void fs_remove(Req *r); +void fs_stat(Req *r); +void fs_walk(Req *r); +void fs_write(Req *r); + /* fs.c */ unsigned long long pack_qpath(unsigned char type, unsigned short i1, unsigned short i2, unsigned short i3); @@ -357,6 +375,7 @@ void attach_to_view(View *v, Client *c); Client *sel_client_of_view(View *v); void restack_view(View *v); View *view_of_name(const char *name); +unsigned char * view_index(View *v); void destroy_view(View *v); void update_views(); unsigned int newcolw_of_view(View *v); diff --git a/cmd/wmiir.c b/cmd/wmiir.c @@ -176,6 +176,9 @@ static int xdir(char *file, int details) { unsigned int fid = c.root_fid << 2; + /* XXX: buffer overflow */ + Stat *s = cext_emallocz(sizeof(Stat)); + unsigned char *buf; int count; static unsigned char result[IXP_MAX_MSG]; void *data = nil; @@ -185,8 +188,10 @@ xdir(char *file, int details) fprintf(stderr, "wmiir: cannot stat file '%s': %s\n", file, c.errstr); return -1; } - if(!(c.fcall.stat.mode & IXP_DMDIR)) { - print_stat(&c.fcall.stat, details); + buf = c.fcall.stat; + ixp_unpack_stat(&buf, s); + if(!(s->mode & IXP_DMDIR)) { + print_stat(s, details); fflush(stdout); return 0; } diff --git a/libixp/client.c b/libixp/client.c @@ -26,8 +26,8 @@ ixp_client_do_fcall(IXPClient *c) c->errstr = "received bad message"; return -1; } - if(c->fcall.id == RERROR) { - c->errstr = c->fcall.errstr; + if(c->fcall.type == RERROR) { + c->errstr = c->fcall.ename; return -1; } return 0; @@ -40,31 +40,31 @@ ixp_client_dial(IXPClient *c, char *sockfile, unsigned int rootfid) c->errstr = "cannot connect server"; return -1; } - c->fcall.id = TVERSION; + c->fcall.type = TVERSION; c->fcall.tag = IXP_NOTAG; - c->fcall.maxmsg = IXP_MAX_MSG; - cext_strlcpy(c->fcall.version, IXP_VERSION, sizeof(c->fcall.version)); + c->fcall.msize = IXP_MAX_MSG; + c->fcall.version = strdup(IXP_VERSION); if(ixp_client_do_fcall(c) == -1) { - fprintf(stderr, "error: %s\n", c->fcall.errstr); + fprintf(stderr, "error: %s\n", c->fcall.ename); ixp_client_hangup(c); return -1; } if(strncmp(c->fcall.version, IXP_VERSION, strlen(IXP_VERSION))) { - fprintf(stderr, "error: %s\n", c->fcall.errstr); + fprintf(stderr, "error: %s\n", c->fcall.ename); c->errstr = "9P versions differ"; ixp_client_hangup(c); return -1; /* we cannot handle this version */ } c->root_fid = rootfid; - c->fcall.id = TATTACH; + c->fcall.type = TATTACH; c->fcall.tag = IXP_NOTAG; c->fcall.fid = c->root_fid; c->fcall.afid = IXP_NOFID; - cext_strlcpy(c->fcall.uname, getenv("USER"), sizeof(c->fcall.uname)); - c->fcall.aname[0] = 0; + c->fcall.uname = strdup(getenv("USER")); + c->fcall.aname = strdup(""); if(ixp_client_do_fcall(c) == -1) { - fprintf(stderr, "error: %s\n", c->fcall.errstr); + fprintf(stderr, "error: %s\n", c->fcall.ename); ixp_client_hangup(c); return -1; } @@ -77,7 +77,7 @@ ixp_client_remove(IXPClient *c, unsigned int newfid, char *filepath) { if(ixp_client_walk(c, newfid, filepath) == -1) return -1; - c->fcall.id = TREMOVE; + c->fcall.type = TREMOVE; c->fcall.tag = IXP_NOTAG; c->fcall.fid = newfid; return ixp_client_do_fcall(c); @@ -87,10 +87,10 @@ int ixp_client_create(IXPClient *c, unsigned int dirfid, char *name, unsigned int perm, unsigned char mode) { - c->fcall.id = TCREATE; + c->fcall.type = TCREATE; c->fcall.tag = IXP_NOTAG; c->fcall.fid = dirfid; - cext_strlcpy(c->fcall.name, name, sizeof(c->fcall.name)); + c->fcall.name = strdup(name); c->fcall.perm = perm; c->fcall.mode = mode; return ixp_client_do_fcall(c); @@ -101,15 +101,15 @@ ixp_client_walk(IXPClient *c, unsigned int newfid, char *filepath) { unsigned int i; char *wname[IXP_MAX_WELEM]; - c->fcall.id = TWALK; + c->fcall.type = TWALK; c->fcall.fid = c->root_fid; c->fcall.newfid = newfid; if(filepath) { - cext_strlcpy(c->fcall.name, filepath, sizeof(c->fcall.name)); + c->fcall.name = strdup(filepath); c->fcall.nwname = cext_tokenize(wname, IXP_MAX_WELEM, c->fcall.name, '/'); for(i = 0; i < c->fcall.nwname; i++) - cext_strlcpy(c->fcall.wname[i], wname[i], sizeof(c->fcall.wname[i])); + c->fcall.wname[i] = strdup(wname[i]); } return ixp_client_do_fcall(c); } @@ -120,7 +120,7 @@ ixp_client_stat(IXPClient *c, unsigned int newfid, char *filepath) if(ixp_client_walk(c, newfid, filepath) == -1) return -1; - c->fcall.id = TSTAT; + c->fcall.type = TSTAT; c->fcall.tag = IXP_NOTAG; c->fcall.fid = newfid; return ixp_client_do_fcall(c); @@ -129,7 +129,7 @@ ixp_client_stat(IXPClient *c, unsigned int newfid, char *filepath) int ixp_client_open(IXPClient *c, unsigned int newfid, unsigned char mode) { - c->fcall.id = TOPEN; + c->fcall.type = TOPEN; c->fcall.tag = IXP_NOTAG; c->fcall.fid = newfid; c->fcall.mode = mode; @@ -151,7 +151,7 @@ ixp_client_read(IXPClient *c, unsigned int fid, unsigned long long offset, { unsigned int bytes = c->fcall.iounit; - c->fcall.id = TREAD; + c->fcall.type = TREAD; c->fcall.tag = IXP_NOTAG; c->fcall.fid = fid; c->fcall.offset = offset; @@ -171,7 +171,7 @@ ixp_client_write(IXPClient *c, unsigned int fid, c->errstr = "iounit exceeded"; return -1; } - c->fcall.id = TWRITE; + c->fcall.type = TWRITE; c->fcall.tag = IXP_NOTAG; c->fcall.fid = fid; c->fcall.offset = offset; @@ -185,7 +185,7 @@ ixp_client_write(IXPClient *c, unsigned int fid, int ixp_client_close(IXPClient *c, unsigned int fid) { - c->fcall.id = TCLUNK; + c->fcall.type = TCLUNK; c->fcall.tag = IXP_NOTAG; c->fcall.fid = fid; return ixp_client_do_fcall(c); diff --git a/libixp/convert.c b/libixp/convert.c @@ -102,6 +102,11 @@ ixp_unpack_strings(unsigned char **msg, unsigned short n, char **strings) { s += len; size += len + 1; /* for '\0' */ } + if(!size) { + /* So we don't try to free some random value */ + *strings = nil; + return; + } /* XXX: we don't really need mallocz here */ s = cext_emallocz(size); for(i=0; i < n; i++) { @@ -115,20 +120,17 @@ ixp_unpack_strings(unsigned char **msg, unsigned short n, char **strings) { } void -ixp_unpack_string(unsigned char **msg, char *string, unsigned short stringlen, - unsigned short *len) +ixp_unpack_string(unsigned char **msg, char **string, unsigned short *len) { ixp_unpack_u16(msg, len); + *string = nil; if (!*len) return; - if (*len > stringlen - 1) { - /* might never happen if stringlen == IXP_MAX_MSG */ - string[0] = 0; - } else { - memcpy(string, *msg, *len); - string[*len] = 0; - *msg += *len; - } + /* XXX we don't really need emallocz here */ + *string = cext_emallocz(*len+1); + memcpy(*string, *msg, *len); + string[*len] = 0; + *msg += *len; } void @@ -141,9 +143,11 @@ ixp_pack_data(unsigned char **msg, int *msize, unsigned char *data, unsigned int } void -ixp_unpack_data(unsigned char **msg, unsigned char *data, unsigned int datalen) +ixp_unpack_data(unsigned char **msg, unsigned char **data, unsigned int datalen) { - memcpy(data, *msg, datalen); + /* XXX: this could be too large a number */ + *data = cext_emallocz(datalen); + memcpy(*data, *msg, datalen); *msg += datalen; } @@ -212,8 +216,8 @@ ixp_unpack_stat(unsigned char **msg, Stat * stat) ixp_unpack_u32(msg, &stat->atime); ixp_unpack_u32(msg, &stat->mtime); ixp_unpack_u64(msg, &stat->length); - ixp_unpack_string(msg, stat->name, sizeof(stat->name), &dummy); - ixp_unpack_string(msg, stat->uid, sizeof(stat->uid), &dummy); - ixp_unpack_string(msg, stat->gid, sizeof(stat->gid), &dummy); - ixp_unpack_string(msg, stat->muid, sizeof(stat->muid), &dummy); + ixp_unpack_string(msg, &stat->name, &dummy); + ixp_unpack_string(msg, &stat->uid, &dummy); + ixp_unpack_string(msg, &stat->gid, &dummy); + ixp_unpack_string(msg, &stat->muid, &dummy); } diff --git a/libixp/intmap.c b/libixp/intmap.c @@ -1,8 +1,14 @@ /* This file is derived from src/lib9p/intmap.c from plan9port */ /* See LICENCE.p9p for terms of use */ #include <stdlib.h> -#include <ixp.h> -#define USED(v) +#include "ixp.h" +#define USED(v) if(v){}else{} + +struct Intlist { + unsigned long id; + void* aux; + Intlist* link; +}; static unsigned long hashid(Intmap *map, unsigned long id) @@ -50,6 +56,19 @@ freemap(Intmap *map, void (*destroy)(void*)) } } } +void +execmap(Intmap *map, void (*run)(void*)) +{ + int i; + Intlist *p, *nlink; + + for(i=0; i<map->nhash; i++){ + for(p=map->hash[i]; p; p=nlink){ + nlink = p->link; + run(p->aux); + } + } +} void* lookupkey(Intmap *map, unsigned long id) diff --git a/libixp/ixp.h b/libixp/ixp.h @@ -10,17 +10,16 @@ #define IXP_NOTAG (unsigned short)~0U /*Dummy tag */ #define IXP_NOFID (unsigned int)~0 /*No auth */ -enum { IXP_MAX_VERSION = 32 }; -enum { IXP_MAX_ERROR = 128 }; -enum { IXP_MAX_CACHE = 32 }; -enum { IXP_MAX_MSG = 8192 }; -enum { IXP_MAX_FLEN = 128 }; -enum { IXP_MAX_ULEN = 32 }; -enum { IXP_MAX_WELEM = 16 }; +enum { IXP_MAX_VERSION = 32, + IXP_MAX_ERROR = 128, + IXP_MAX_CACHE = 32, + IXP_MAX_MSG = 8192, + IXP_MAX_FLEN = 128, + IXP_MAX_ULEN = 32, + IXP_MAX_WELEM = 16 }; /* 9P message types */ -enum { - TVERSION = 100, +enum { TVERSION = 100, RVERSION, TAUTH = 102, RAUTH, @@ -51,8 +50,7 @@ enum { }; /* borrowed from libc.h of Plan 9 */ -enum { - IXP_DMDIR = 0x80000000, /* mode bit for directories */ +enum { IXP_DMDIR = 0x80000000, /* mode bit for directories */ IXP_DMAPPEND = 0x40000000, /* mode bit for append only files */ IXP_DMEXCL = 0x20000000, /* mode bit for exclusive use files */ IXP_DMMOUNT = 0x10000000, /* mode bit for mounted channel */ @@ -64,8 +62,7 @@ enum { }; /* modes */ -enum { - IXP_OREAD = 0x00, +enum { IXP_OREAD = 0x00, IXP_OWRITE = 0x01, IXP_ORDWR = 0x02, IXP_OEXEC = 0x03, @@ -77,8 +74,7 @@ enum { }; /* qid.types */ -enum { - IXP_QTDIR = 0x80, +enum { IXP_QTDIR = 0x80, IXP_QTAPPEND = 0x40, IXP_QTEXCL = 0x20, IXP_QTMOUNT = 0x10, @@ -89,6 +85,52 @@ enum { IXP_QTFILE = 0x00, }; +/* from libc.h in p9p */ +enum { OREAD = 0, /* open for read */ + OWRITE = 1, /* write */ + ORDWR = 2, /* read and write */ + OEXEC = 3, /* execute, == read but check execute permission */ + OTRUNC = 16, /* or'ed in (except for exec), truncate file first */ + OCEXEC = 32, /* or'ed in, close on exec */ + ORCLOSE = 64, /* or'ed in, remove on close */ + ODIRECT = 128, /* or'ed in, direct access */ + ONONBLOCK = 256, /* or'ed in, non-blocking call */ + OEXCL = 0x1000, /* or'ed in, exclusive use (create only) */ + OLOCK = 0x2000, /* or'ed in, lock after opening */ + OAPPEND = 0x4000 /* or'ed in, append only */ +}; + +/* bits in Qid.type */ +enum { QTDIR = 0x80, /* type bit for directories */ + QTAPPEND = 0x40, /* type bit for append only files */ + QTEXCL = 0x20, /* type bit for exclusive use files */ + QTMOUNT = 0x10, /* type bit for mounted channel */ + QTAUTH = 0x08, /* type bit for authentication file */ + QTTMP = 0x04, /* type bit for non-backed-up file */ + QTSYMLINK = 0x02, /* type bit for symbolic link */ + QTFILE = 0x00 /* type bits for plain file */ +}; + +/* bits in Dir.mode */ +enum { DMDIR = 0x80000000, /* mode bit for directories */ + DMAPPEND = 0x40000000, /* mode bit for append only files */ + DMEXCL = 0x20000000, /* mode bit for exclusive use files */ + DMMOUNT = 0x10000000, /* mode bit for mounted channel */ + DMAUTH = 0x08000000, /* mode bit for authentication file */ + DMTMP = 0x04000000, /* mode bit for non-backed-up file */ + DMSYMLINK = 0x02000000, /* mode bit for symbolic link (Unix, 9P2000.u) */ + DMDEVICE = 0x00800000, /* mode bit for device file (Unix, 9P2000.u) */ + DMNAMEDPIPE = 0x00200000, /* mode bit for named pipe (Unix, 9P2000.u) */ + DMSOCKET = 0x00100000, /* mode bit for socket (Unix, 9P2000.u) */ + DMSETUID = 0x00080000, /* mode bit for setuid (Unix, 9P2000.u) */ + DMSETGID = 0x00040000, /* mode bit for setgid (Unix, 9P2000.u) */ + + DMREAD = 0x4, /* mode bit for read permission */ + DMWRITE = 0x2, /* mode bit for write permission */ + DMEXEC = 0x1 /* mode bit for execute permission */ +}; + + typedef struct Qid Qid; struct Qid { unsigned char type; @@ -99,7 +141,7 @@ struct Qid { }; /* stat structure */ -typedef struct { +typedef struct Stat { unsigned short type; unsigned int dev; Qid qid; @@ -107,39 +149,65 @@ typedef struct { unsigned int atime; unsigned int mtime; unsigned long long length; - char name[IXP_MAX_FLEN]; - char uid[IXP_MAX_ULEN]; - char gid[IXP_MAX_ULEN]; - char muid[IXP_MAX_ULEN]; + char *name; + char *uid; + char *gid; + char *muid; } Stat; -typedef struct { - unsigned char id; +/* from fcall(3) in plan9port */ +typedef struct Fcall { + unsigned char type; 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];/* 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 */ + union { + struct { /* Tversion, Rversion */ + unsigned int msize; + char *version; + }; + struct { /* Tflush */ + unsigned short oldtag; + }; + struct { /* Rerror */ + char *ename; + }; + struct { /* Ropen, Rcreate */ + Qid qid; /* +Rattach */ + unsigned int iounit; + }; + struct { /* Rauth */ + Qid aqid; + }; + struct { /* Tauth, Tattach */ + unsigned int afid; + char *uname; + char *aname; + }; + struct { /* Tcreate */ + unsigned int perm; + char *name; + unsigned char mode; /* +Topen */ + }; + struct { /* Twalk */ + unsigned int newfid; + unsigned short nwname; + char *wname[IXP_MAX_WELEM]; + }; + struct { /* Rwalk */ + unsigned short nwqid; + Qid wqid[IXP_MAX_WELEM]; + }; + struct { /* Twrite */ + long long offset; /* +Tread */ + /* +Rread */ + unsigned int count; /* +Tread */ + unsigned char *data; + }; + struct { /* Twstat, Rstat */ + unsigned short nstat; + unsigned char *stat; + }; + }; } Fcall; typedef struct IXPServer IXPServer; @@ -155,29 +223,23 @@ struct IXPMap { Qid wqid[IXP_MAX_WELEM]; }; -typedef struct Intlist Intlist; -struct Intlist -{ - unsigned long id; - void* aux; - Intlist* link; -}; - -struct Intmap -{ +typedef struct Intlist Intlist; +struct Intmap { unsigned long nhash; Intlist **hash; }; struct IXPConn { - IXPConn *next; - int fd; - IXPServer *srv; - void (*read) (IXPConn *); - void (*close) (IXPConn *); - IXPMap *map; - Fcall pending; - int is_pending; + IXPServer *srv; + void *aux; + int fd; + void (*read) (IXPConn *); + void (*close) (IXPConn *); + char closed; + + /* Implementation details */ + /* do not use */ + IXPConn *next; }; struct IXPServer { @@ -187,7 +249,7 @@ struct IXPServer { fd_set rd; }; -typedef struct { +typedef struct IXPClient { int fd; unsigned int root_fid; Qid root_qid; @@ -195,6 +257,48 @@ typedef struct { char *errstr; } IXPClient; +typedef struct P9Conn P9Conn; +typedef struct Fid { + unsigned long fid; + char omode; + char *uid; + Qid qid; + void *aux; + + /* Implementation details */ + /* do not use */ + P9Conn *conn; + Intmap *map; +} Fid; + +typedef struct Req Req; +struct Req { + Fid *fid; + Fid *newfid; + Req *oldreq; + Fcall ifcall; + Fcall ofcall; + void *aux; + + /* Implementation detail */ + /* do not use */ + P9Conn *conn; +}; + +typedef struct P9Srv { + void (*attach)(Req *r); + void (*clunk)(Req *r); + void (*create)(Req *r); + void (*flush)(Req *r); + void (*open)(Req *r); + void (*read)(Req *r); + void (*remove)(Req *r); + void (*stat)(Req *r); + void (*walk)(Req *r); + void (*write)(Req *r); + void (*freefid)(Fid *f); +} P9Srv; + /* client.c */ int ixp_client_dial(IXPClient *c, char *address, unsigned int rootfid); void ixp_client_hangup(IXPClient *c); @@ -226,11 +330,10 @@ void ixp_pack_u64(unsigned char **msg, int *msize, unsigned long long val); void ixp_unpack_u64(unsigned char **msg, unsigned long long *val); void ixp_pack_string(unsigned char **msg, int *msize, const char *s); void ixp_unpack_strings(unsigned char **msg, unsigned short n, char **strings); -void ixp_unpack_string(unsigned char **msg, char *string, - unsigned short stringlen, unsigned short *len); +void ixp_unpack_string(unsigned char **msg, char **string, unsigned short *len); void ixp_pack_data(unsigned char **msg, int *msize, unsigned char *data, unsigned int datalen); -void ixp_unpack_data(unsigned char **msg, unsigned char *data, +void ixp_unpack_data(unsigned char **msg, unsigned char **data, unsigned int datalen); void ixp_pack_prefix(unsigned char *msg, unsigned int size, unsigned char id, unsigned short tag); @@ -241,9 +344,14 @@ void ixp_unpack_qid(unsigned char **msg, Qid *qid); void ixp_pack_stat(unsigned char **msg, int *msize, Stat *stat); void ixp_unpack_stat(unsigned char **msg, Stat *stat); +/* request.c */ +void respond(Req *r, char *error); +void serve_9pcon(IXPConn *c); + /* intmap.c */ void initmap(Intmap *m, unsigned long nhash, void *hash); void freemap(Intmap *map, void (*destroy)(void*)); +void execmap(Intmap *map, void (*destroy)(void*)); void* lookupkey(Intmap *map, unsigned long id); void* insertkey(Intmap *map, unsigned long id, void *v); int caninsertkey(Intmap *map, unsigned long id, void *v); @@ -255,7 +363,7 @@ unsigned int ixp_fcall2msg(void *msg, Fcall *fcall, unsigned int msglen); unsigned int ixp_msg2fcall(Fcall *call, void *msg, unsigned int msglen); /* server.c */ -IXPConn *ixp_server_open_conn(IXPServer *s, int fd, +IXPConn *ixp_server_open_conn(IXPServer *s, int fd, void *aux, void (*read)(IXPConn *c), void (*close)(IXPConn *c)); void ixp_server_close_conn(IXPConn *c); char *ixp_server_loop(IXPServer *s); diff --git a/libixp/message.c b/libixp/message.c @@ -38,10 +38,10 @@ ixp_fcall2msg(void *msg, Fcall *fcall, unsigned int msglen) int msize = msglen - i; unsigned char *p = msg + i; - switch (fcall->id) { + switch (fcall->type) { case TVERSION: case RVERSION: - ixp_pack_u32(&p, &msize, fcall->maxmsg); + ixp_pack_u32(&p, &msize, fcall->msize); ixp_pack_string(&p, &msize, fcall->version); break; case TAUTH: @@ -62,7 +62,7 @@ ixp_fcall2msg(void *msg, Fcall *fcall, unsigned int msglen) ixp_pack_string(&p, &msize, fcall->aname); break; case RERROR: - ixp_pack_string(&p, &msize, fcall->errstr); + ixp_pack_string(&p, &msize, fcall->ename); break; case TFLUSH: ixp_pack_u16(&p, &msize, fcall->oldtag); @@ -118,13 +118,13 @@ ixp_fcall2msg(void *msg, Fcall *fcall, unsigned int msglen) ixp_pack_u32(&p, &msize, fcall->fid); break; case RSTAT: - ixp_pack_u16(&p, &msize, ixp_sizeof_stat(&fcall->stat)); - ixp_pack_stat(&p, &msize, &fcall->stat); + ixp_pack_u16(&p, &msize, fcall->nstat); + ixp_pack_data(&p, &msize, fcall->stat, fcall->nstat); break; case TWSTAT: ixp_pack_u32(&p, &msize, fcall->fid); - ixp_pack_u16(&p, &msize, ixp_sizeof_stat(&fcall->stat)); - ixp_pack_stat(&p, &msize, &fcall->stat); + ixp_pack_u16(&p, &msize, fcall->nstat); + ixp_pack_data(&p, &msize, fcall->stat, fcall->nstat); break; } @@ -132,7 +132,7 @@ ixp_fcall2msg(void *msg, Fcall *fcall, unsigned int msglen) return 0; msize = msglen - msize; - ixp_pack_prefix(msg, msize, fcall->id, fcall->tag); + ixp_pack_prefix(msg, msize, fcall->type, fcall->tag); return msize; } @@ -142,20 +142,20 @@ ixp_msg2fcall(Fcall *fcall, void *msg, unsigned int msglen) unsigned int i, msize; unsigned short len; unsigned char *p = msg; - ixp_unpack_prefix(&p, &msize, &fcall->id, &fcall->tag); + ixp_unpack_prefix(&p, &msize, &fcall->type, &fcall->tag); if(msize > msglen) /* bad message */ return 0; - switch (fcall->id) { + switch (fcall->type) { case TVERSION: case RVERSION: - ixp_unpack_u32(&p, &fcall->maxmsg); - ixp_unpack_string(&p, fcall->version, sizeof(fcall->version), &len); + ixp_unpack_u32(&p, &fcall->msize); + ixp_unpack_string(&p, &fcall->version, &len); break; case TAUTH: ixp_unpack_u32(&p, &fcall->afid); - ixp_unpack_string(&p, fcall->uname, sizeof(fcall->uname), &len); - ixp_unpack_string(&p, fcall->aname, sizeof(fcall->aname), &len); + ixp_unpack_string(&p, &fcall->uname, &len); + ixp_unpack_string(&p, &fcall->aname, &len); break; case RAUTH: ixp_unpack_qid(&p, &fcall->aqid); @@ -166,11 +166,11 @@ ixp_msg2fcall(Fcall *fcall, void *msg, unsigned int msglen) case TATTACH: ixp_unpack_u32(&p, &fcall->fid); ixp_unpack_u32(&p, &fcall->afid); - ixp_unpack_string(&p, fcall->uname, sizeof(fcall->uname), &len); - ixp_unpack_string(&p, fcall->aname, sizeof(fcall->aname), &len); + ixp_unpack_string(&p, &fcall->uname, &len); + ixp_unpack_string(&p, &fcall->aname, &len); break; case RERROR: - ixp_unpack_string(&p, fcall->errstr, sizeof(fcall->errstr), &len); + ixp_unpack_string(&p, &fcall->ename, &len); break; case TFLUSH: ixp_unpack_u16(&p, &fcall->oldtag); @@ -179,7 +179,7 @@ ixp_msg2fcall(Fcall *fcall, void *msg, unsigned int msglen) ixp_unpack_u32(&p, &fcall->fid); ixp_unpack_u32(&p, &fcall->newfid); ixp_unpack_u16(&p, &fcall->nwname); - ixp_unpack_strings(&p, fcall->nwname, &fcall->wname); + ixp_unpack_strings(&p, fcall->nwname, fcall->wname); break; case RWALK: ixp_unpack_u16(&p, &fcall->nwqid); @@ -197,7 +197,7 @@ ixp_msg2fcall(Fcall *fcall, void *msg, unsigned int msglen) break; case TCREATE: ixp_unpack_u32(&p, &fcall->fid); - ixp_unpack_string(&p, fcall->name, sizeof(fcall->name), &len); + ixp_unpack_string(&p, &fcall->name, &len); ixp_unpack_u32(&p, &fcall->perm); ixp_unpack_u8(&p, &fcall->mode); break; @@ -208,13 +208,13 @@ ixp_msg2fcall(Fcall *fcall, void *msg, unsigned int msglen) break; case RREAD: ixp_unpack_u32(&p, &fcall->count); - ixp_unpack_data(&p, fcall->data, fcall->count); + ixp_unpack_data(&p, &fcall->data, fcall->count); break; case TWRITE: ixp_unpack_u32(&p, &fcall->fid); ixp_unpack_u64(&p, &fcall->offset); ixp_unpack_u32(&p, &fcall->count); - ixp_unpack_data(&p, fcall->data, fcall->count); + ixp_unpack_data(&p, &fcall->data, fcall->count); break; case RWRITE: ixp_unpack_u32(&p, &fcall->count); @@ -226,12 +226,12 @@ ixp_msg2fcall(Fcall *fcall, void *msg, unsigned int msglen) break; case RSTAT: ixp_unpack_u16(&p, &len); - ixp_unpack_stat(&p, &fcall->stat); + ixp_unpack_data(&p, &fcall->stat, len); break; case TWSTAT: ixp_unpack_u32(&p, &fcall->fid); ixp_unpack_u16(&p, &len); - ixp_unpack_stat(&p, &fcall->stat); + ixp_unpack_data(&p, &fcall->stat, len); break; } diff --git a/libixp/request.c b/libixp/request.c @@ -13,28 +13,32 @@ static char Ebotch[] = "9P protocol botch", Enofile[] = "file does not exist", Enofid[] = "fid does not exist", + Enotag[] = "tag does not exist", Enotdir[] = "not a directory", + Einterrupted[] = "interrupted", Eisdir[] = "cannot perform operation on a directory"; enum { TAG_BUCKETS = 64, FID_BUCKETS = 64 }; -typedef struct P9Conn { +struct P9Conn { Intmap tagmap; void *taghash[TAG_BUCKETS]; Intmap fidmap; void *fidhash[FID_BUCKETS]; P9Srv *srv; + IXPConn *conn; unsigned int msize; unsigned char *buf; -} P9Conn; +}; void * -createfid(Intmap *map, int fid) { +createfid(Intmap *map, int fid, P9Conn *pc) { Fid *f = cext_emallocz(sizeof(Fid)); f->fid = fid; f->omode = -1; f->map = map; + f->conn = pc; if(caninsertkey(map, fid, f)) return f; free(f); @@ -67,8 +71,9 @@ ixp_server_handle_fcall(IXPConn *c) goto Fail; req = cext_emallocz(sizeof(Req)); - req->conn = c; + req->conn = pc; req->ifcall = fcall; + pc->conn = c; if(lookupkey(&pc->tagmap, fcall.tag)) return respond(req, Eduptag); @@ -83,7 +88,7 @@ Fail: static void ixp_handle_req(Req *r) { - P9Conn *pc = r->conn->aux; + P9Conn *pc = r->conn; P9Srv *srv = pc->srv; switch(r->ifcall.type) { @@ -103,7 +108,7 @@ ixp_handle_req(Req *r) respond(r, nil); break; case TATTACH: - if(!(r->fid = createfid(&pc->fidmap, r->ifcall.fid))) + if(!(r->fid = createfid(&pc->fidmap, r->ifcall.fid, pc))) return respond(r, Edupfid); /* attach is a required function */ srv->attach(r); @@ -115,6 +120,13 @@ ixp_handle_req(Req *r) return respond(r, nil); srv->clunk(r); break; + case TFLUSH: + if(!(r->oldreq = lookupkey(&pc->tagmap, r->ifcall.oldtag))) + return respond(r, Enotag); + if(!srv->flush) + return respond(r, Enofunc); + srv->flush(r); + break; case TCREATE: if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid))) return respond(r, Enofid); @@ -167,7 +179,7 @@ ixp_handle_req(Req *r) if(r->ifcall.nwname && !(r->fid->qid.type&QTDIR)) return respond(r, Enotdir); if((r->ifcall.fid != r->ifcall.newfid)) { - if(!(r->newfid = createfid(&pc->fidmap, r->ifcall.newfid))) + if(!(r->newfid = createfid(&pc->fidmap, r->ifcall.newfid, pc))) return respond(r, Edupfid); }else r->newfid = r->fid; @@ -190,7 +202,7 @@ ixp_handle_req(Req *r) void respond(Req *r, char *error) { - P9Conn *pc = r->conn->aux; + P9Conn *pc = r->conn; switch(r->ifcall.type) { default: if(!error) @@ -238,6 +250,10 @@ respond(Req *r, char *error) { case TCLUNK: destroyfid(pc, r->fid->fid); break; + case TFLUSH: + if((r->oldreq = lookupkey(&pc->tagmap, r->ifcall.oldtag))) + respond(r->oldreq, Einterrupted); + break; case TREAD: case TREMOVE: case TSTAT: @@ -253,8 +269,8 @@ respond(Req *r, char *error) { r->ofcall.ename = error; } - /* XXX Check if conn is still open */ - ixp_server_respond_fcall(r->conn, &r->ofcall); + if(pc->conn) + ixp_server_respond_fcall(pc->conn, &r->ofcall); switch(r->ofcall.type) { case RSTAT: @@ -269,21 +285,55 @@ respond(Req *r, char *error) { free(r); } +/* XXX: This cleanup code *needs* to be cleaned up */ static void -ixp_void_request(void *r) { - /* generate flush request */ +ixp_void_request(void *t) { + unsigned int tag; + Req *r, *tr; + P9Conn *pc; + + r = t; + pc = r->conn; + /* XXX: need a better way of doing this */ + for(tag=0; lookupkey(&pc->tagmap, tag); tag++); + + tr = cext_emallocz(sizeof(Req)); + tr->conn = pc; + tr->ifcall.type = TFLUSH; + tr->ifcall.tag = tag; + tr->ifcall.oldtag = r->ifcall.tag; + ixp_handle_req(tr); } static void -ixp_void_fid(void *f) { - /* generate clunk request */ +ixp_void_fid(void *t) { + unsigned int tag; + P9Conn *pc; + Req *tr; + Fid *f; + + f = t; + pc = f->conn; + /* XXX: need a better way of doing this */ + for(tag=0; lookupkey(&pc->tagmap, tag); tag++); + + tr = cext_emallocz(sizeof(Req)); + tr->fid = f; + tr->conn = pc; + tr->ifcall.type = TCLUNK; + tr->ifcall.tag = tag; + tr->ifcall.fid = f->fid; + ixp_handle_req(tr); } static void ixp_cleanup_conn(IXPConn *c) { P9Conn *pc = c->aux; - freemap(&pc->tagmap, ixp_void_request); - freemap(&pc->fidmap, ixp_void_fid); + pc->conn = nil; + execmap(&pc->tagmap, ixp_void_request); + freemap(&pc->tagmap, nil); + execmap(&pc->fidmap, ixp_void_fid); + freemap(&pc->fidmap, nil); free(pc->buf); free(pc); } diff --git a/libixp/server.c b/libixp/server.c @@ -18,11 +18,13 @@ static unsigned char *msg[IXP_MAX_MSG]; -IXPConn *ixp_server_open_conn(IXPServer *s, int fd, void (*read)(IXPConn *c), - void (*close)(IXPConn *c)) +IXPConn * +ixp_server_open_conn(IXPServer *s, int fd, void *aux, + void (*read)(IXPConn *c), void (*close)(IXPConn *c)) { IXPConn *c = cext_emallocz(sizeof(IXPConn)); c->fd = fd; + c->aux = aux; c->srv = s; c->read = read; c->close = close; @@ -36,15 +38,14 @@ ixp_server_close_conn(IXPConn *c) { IXPServer *s = c->srv; IXPConn **tc; - IXPMap *m; for(tc=&s->conn; *tc && *tc != c; tc=&(*tc)->next); cext_assert(*tc == c); *tc = c->next; - while((m = c->map)) { - c->map = m->next; - free(m); - } - shutdown(c->fd, SHUT_RDWR); + c->closed = 1; + if(c->close) + c->close(c); + else + shutdown(c->fd, SHUT_RDWR); close(c->fd); free(c); } @@ -68,7 +69,6 @@ handle_conns(IXPServer *s) IXPConn **c; for(c=&s->conn; *c; *c && (c=&(*c)->next)) if(FD_ISSET((*c)->fd, &s->rd) && (*c)->read) - /* call read handler */ (*c)->read(*c); } @@ -93,22 +93,13 @@ ixp_server_loop(IXPServer *s) return nil; } -IXPMap * -ixp_server_fid2map(IXPConn *c, unsigned int fid) -{ - IXPMap *m; - for(m=c->map; m && m->fid != fid; m=m->next); - return m; -} - unsigned int ixp_server_receive_fcall(IXPConn *c, Fcall *fcall) { unsigned int msize; char *errstr = 0; if(!(msize = ixp_recv_message(c->fd, msg, IXP_MAX_MSG, &errstr))) { - if(c->close) - c->close(c); + ixp_server_close_conn(c); return 0; } return ixp_msg2fcall(fcall, msg, IXP_MAX_MSG); @@ -119,24 +110,10 @@ ixp_server_respond_fcall(IXPConn *c, Fcall *fcall) { char *errstr; unsigned int msize = ixp_fcall2msg(msg, fcall, IXP_MAX_MSG); + if(c->closed) + return 0; if(ixp_send_message(c->fd, msg, msize, &errstr) != msize) { - if(c->close) - c->close(c); - return -1; - } - return 0; -} - -int -ixp_server_respond_error(IXPConn *c, Fcall *fcall, char *errstr) -{ - unsigned int msize; - fcall->id = RERROR; - cext_strlcpy(fcall->errstr, errstr, sizeof(fcall->errstr)); - msize = ixp_fcall2msg(msg, fcall, IXP_MAX_MSG); - if(ixp_send_message(c->fd, msg, msize, &errstr) != msize) { - if(c->close) - c->close(c); + ixp_server_close_conn(c); return -1; } return 0; @@ -148,7 +125,6 @@ ixp_server_close(IXPServer *s) IXPConn *c, *next; for(c=s->conn; c; c=next) { next=c->next; - if(c->close) - c->close(c); + ixp_server_close_conn(c); } } diff --git a/libixp/transport.c b/libixp/transport.c @@ -64,7 +64,7 @@ ixp_recv_message(int fd, void *msg, unsigned int msglen, char **errstr) if(ixp_recv_data(fd, msg, sizeof(unsigned int), errstr) != sizeof(unsigned int)) return 0; - ixp_unpack_u32((unsigned char**)&msg, &msize); + ixp_unpack_u32((void *)&msg, &msize); if(msize > msglen) { *errstr = "invalid message header"; return 0;