mirror of
https://github.com/0intro/wmii
synced 2024-12-26 05:16:59 +03:00
Merge in diffs for fs2.c and libixp
This commit is contained in:
parent
72c7d317e2
commit
a4e2ab7b59
@ -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}
|
||||
|
||||
|
32
cmd/wm/bar.c
32
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;
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
34
cmd/wm/fs.c
34
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);
|
||||
}
|
||||
|
392
cmd/wm/fs2.c
392
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 FsFBorder:
|
||||
asprintf((void *)&r->ofcall.data, "%d", def.border);
|
||||
if(!r->ifcall.offset)
|
||||
r->ofcall.count = strlen(r->ofcall.data);
|
||||
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:
|
||||
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 */
|
||||
@ -480,17 +528,12 @@ 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);
|
||||
}
|
||||
respond(r, Enoperm);
|
||||
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, 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
|
||||
|
@ -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];
|
||||
|
33
cmd/wm/wm.c
33
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;
|
||||
|
||||
|
67
cmd/wm/wm.h
67
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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
244
libixp/ixp.h
244
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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user