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:
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;