mirror of
https://github.com/0intro/wmii
synced 2025-01-09 20:02:01 +03:00
Commiting changes to fs2.c and request.c. Not commiting required changes to other files yet.
This commit is contained in:
parent
87eb4561ce
commit
ad38c92e9f
311
cmd/wm/fs2.c
311
cmd/wm/fs2.c
@ -1,28 +1,41 @@
|
||||
/* So, here's the begining of my idea of fs.c. Before you think it, yes, it's
|
||||
* still braindamaged. I'm certain that more simplicification is possible, but
|
||||
* my brain seems fried every time I try to work it out. Think of this a draft
|
||||
* in preparation for a draft. The basic idea here is to keep everything regarding
|
||||
* to directory structure in one place. Everything should be done in lookup_file,
|
||||
* including finding all files in a dir for a stat and finding files to walk to,
|
||||
* as well as associating a file with a pointer and id.
|
||||
*
|
||||
* I think that I could possibly save quite a few lines of code in lookup_file
|
||||
* with a function to create the FileId struct and push it onto the list. We'll see.
|
||||
* I need to sleep on it some more.
|
||||
*
|
||||
* Comments are, of course, welcome, but if you don't see where I'm going with this,
|
||||
* I don't know of how much help they'll be.
|
||||
*
|
||||
* This, btw, doesn't compile due to a lack of header files for cext_emallocz,
|
||||
* Client, lbar, etc.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "wm.h"
|
||||
P9Srv p9srv = {
|
||||
.open= fs_open,
|
||||
.walk= fs_walk,
|
||||
.read= fs_read,
|
||||
.stat= fs_stat,
|
||||
.write= fs_write,
|
||||
.attach=fs_attach,
|
||||
.create=fs_create,
|
||||
.remove=fs_remove
|
||||
};
|
||||
|
||||
#define QID(t, i) (((long long)((t)&0xFF)<<32)|((i)&0xFFFFFFFF))
|
||||
#define TYPE(q) ((q)>>32&0xFF)
|
||||
#define ID(q) ((q)&0xFFFFFFFF)
|
||||
|
||||
static char Enoperm[] = "permission denied";
|
||||
static char Enofile[] = "file not found";
|
||||
//static char Efidinuse[] = "fid in use";
|
||||
//static char Enomode[] = "mode not supported";
|
||||
//static char Enofunc[] = "function not supported";
|
||||
//static char Enocommand[] = "command not supported";
|
||||
//static char Ebadvalue[] = "bad value";
|
||||
|
||||
enum { FsRoot, FsDClient, FsDClients, FsDLBar,
|
||||
FsDRBar, FsDSClient, FsDTag, FsDTags,
|
||||
|
||||
FsFBar, FsFCNorm, FsFCSel, FsFCctl,
|
||||
FsFCindex, FsFColRules, FsFEvent, FsFFont,
|
||||
FsFKeys, FsFRctl, FsFTagRules, FsFTctl,
|
||||
FsFTindex, FsFprops, RsFFont
|
||||
};
|
||||
|
||||
typedef struct Dirtab Dirtab;
|
||||
struct Dirtab
|
||||
{
|
||||
@ -32,26 +45,21 @@ struct Dirtab
|
||||
unsigned int perm;
|
||||
};
|
||||
|
||||
#define nil ((void *)0)
|
||||
|
||||
#define QID(t, i) (((long long)((t)&0xFF)<<32)|((i)&0xFFFFFFFF))
|
||||
#define TYPE(q) ((q)>>32&0xFF)
|
||||
#define ID(q) ((q)&0xFFFFFFFF)
|
||||
|
||||
enum { DMDIR, DMAPPEND, QTDIR, QTFILE, QTAPPEND };
|
||||
enum { FsRoot, FsDClient, FsDClients, FsDLBar,
|
||||
FsDRBar, FsDSClient, FsDTag, FsDTags,
|
||||
|
||||
FsFBar, FsFCNorm, FsFCSel, FsFCctl,
|
||||
FsFCindex, FsFColRules, FsFEvent, FsFFont,
|
||||
FsFKeys, FsFRctl, FsFTagRules, FsFTctl,
|
||||
FsFTindex, FsFprops, RsFFont
|
||||
typedef struct FileId FileId;
|
||||
struct FileId {
|
||||
FileId *next;
|
||||
void *ref;
|
||||
unsigned int id;
|
||||
unsigned int index;
|
||||
Dirtab tab;
|
||||
};
|
||||
|
||||
Dirtab *dirtab[] =
|
||||
{
|
||||
[FsRoot] (Dirtab [])
|
||||
{{".", QTDIR, FsRoot, 0500|DMDIR },
|
||||
static void dostat(Stat *s, unsigned int len, FileId *f);
|
||||
FileId *free_fileid = nil;
|
||||
|
||||
static Dirtab
|
||||
dirtabroot[]= {{".", QTDIR, FsRoot, 0500|DMDIR },
|
||||
{"rbar", QTDIR, FsDRBar, 0700|DMDIR },
|
||||
{"lbar", QTDIR, FsDLBar, 0700|DMDIR },
|
||||
{"client", QTDIR, FsDClients, 0500|DMDIR },
|
||||
@ -65,52 +73,40 @@ Dirtab *dirtab[] =
|
||||
{"normcolors", QTFILE, FsFCNorm, 0600 },
|
||||
{"selcolors", QTFILE, FsFCSel, 0600 },
|
||||
{nil}},
|
||||
[FsDRBar] (Dirtab [])
|
||||
{{".", QTDIR, FsDRBar, 0700|DMDIR },
|
||||
{"", QTFILE, FsFBar, 0600 },
|
||||
{nil}},
|
||||
[FsDLBar] (Dirtab [])
|
||||
{{".", QTDIR, FsDRBar, 0700|DMDIR },
|
||||
{"", QTFILE, FsFBar, 0600 },
|
||||
{nil}},
|
||||
[FsDClients] (Dirtab [])
|
||||
{{".", QTDIR, FsDClients, 0500|DMDIR },
|
||||
{"", QTDIR, FsDClient, 0500|DMDIR },
|
||||
{nil}},
|
||||
[FsDClient] (Dirtab [])
|
||||
{{".", QTFILE, FsDClient, 0500|DMDIR },
|
||||
dirtabclient[]= {{".", QTFILE, FsDClient, 0500|DMDIR },
|
||||
{"ctl", QTAPPEND, FsFCctl, 0200|DMAPPEND },
|
||||
{"props", QTFILE, FsFprops, 0400 },
|
||||
{nil}},
|
||||
[FsDSClient] (Dirtab [])
|
||||
{{".", QTDIR, FsDClient, 0500|DMDIR },
|
||||
dirtabsclient[]={{".", QTDIR, FsDClient, 0500|DMDIR },
|
||||
{"ctl", QTAPPEND, FsFCctl, 0200|DMAPPEND },
|
||||
{"index", QTFILE, FsFCindex, 0400 },
|
||||
{"props", QTFILE, FsFprops, 0400 },
|
||||
{nil}},
|
||||
[FsDTags] (Dirtab [])
|
||||
{{".", QTDIR, FsDTags, 0500|DMDIR },
|
||||
dirtabbar[]= {{".", QTDIR, FsDRBar, 0700|DMDIR },
|
||||
{"", QTFILE, FsFBar, 0600 },
|
||||
{nil}},
|
||||
dirtabclients[]={{".", QTDIR, FsDClients, 0500|DMDIR },
|
||||
{"", QTDIR, FsDClient, 0500|DMDIR },
|
||||
{nil}},
|
||||
dirtabtags[]= {{".", QTDIR, FsDTags, 0500|DMDIR },
|
||||
{"", QTDIR, FsDTag, 0500|DMDIR },
|
||||
{nil}},
|
||||
[FsDTag] (Dirtab [])
|
||||
{{".", QTDIR, FsDTag, 0500|DMDIR },
|
||||
dirtabtag[]= {{".", QTDIR, FsDTag, 0500|DMDIR },
|
||||
{"ctl", QTAPPEND, FsFTctl, 0200|DMAPPEND },
|
||||
{"index", QTFILE, FsFTindex, 0400 },
|
||||
{nil}}
|
||||
{nil}};
|
||||
static Dirtab *dirtab[] = {
|
||||
[FsRoot] dirtabroot,
|
||||
[FsDRBar] dirtabbar,
|
||||
[FsDLBar] dirtabbar,
|
||||
[FsDClients] dirtabclients,
|
||||
[FsDClient] dirtabclient,
|
||||
[FsDSClient] dirtabsclient,
|
||||
[FsDTags] dirtabtags,
|
||||
[FsDTag] dirtabtag
|
||||
};
|
||||
|
||||
typedef struct FileId FileId;
|
||||
struct FileId {
|
||||
FileId *next;
|
||||
void *ref;
|
||||
unsigned int id;
|
||||
unsigned int index;
|
||||
Dirtab tab;
|
||||
};
|
||||
|
||||
FileId *free_fileid = nil;
|
||||
|
||||
FileId *
|
||||
static FileId *
|
||||
get_file() {
|
||||
FileId *temp;
|
||||
if(!free_fileid) {
|
||||
@ -126,17 +122,20 @@ get_file() {
|
||||
return temp;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
free_file(FileId *f) {
|
||||
free(f->tab.name);
|
||||
f->next = free_fileid;
|
||||
free_fileid = f;
|
||||
}
|
||||
|
||||
FileId *
|
||||
static FileId *
|
||||
lookup_file(FileId *parent, char *name)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i, id;
|
||||
Client *c;
|
||||
View *v;
|
||||
Bar *b;
|
||||
|
||||
if(!(parent->tab.perm & DMDIR))
|
||||
return nil;
|
||||
@ -160,10 +159,10 @@ lookup_file(FileId *parent, char *name)
|
||||
temp->ref = rbar;
|
||||
break;
|
||||
case FsFColRules:
|
||||
temp->ref = crules;
|
||||
temp->ref = vrule;
|
||||
break;
|
||||
case FsFTagRules:
|
||||
temp->ref = trules;
|
||||
temp->ref = trule;
|
||||
break;
|
||||
}
|
||||
if(name)
|
||||
@ -172,9 +171,8 @@ lookup_file(FileId *parent, char *name)
|
||||
if(!*dir->name) { /* strlen(dir->name) == 0 */
|
||||
switch(parent->tab.type) {
|
||||
case FsDClients:
|
||||
Client *c;
|
||||
if(!name || !strncmp(name, "sel", 4)) {
|
||||
if(sel && sel->sel && (c = sel->sel->sel->client)) {
|
||||
if((c = sel_client())) {
|
||||
temp = get_file();
|
||||
*last = temp;
|
||||
last = &temp->next;
|
||||
@ -184,33 +182,28 @@ lookup_file(FileId *parent, char *name)
|
||||
temp->tab = *dirtab[FsDSClient];
|
||||
temp->tab.name = strdup("sel");
|
||||
}
|
||||
if(name)
|
||||
goto LastItem;
|
||||
}else{
|
||||
if(name) {
|
||||
i = (unsigned int)strtol(name, &name, 10);
|
||||
id = (unsigned int)strtol(name, &name, 10);
|
||||
if(*name)
|
||||
continue;
|
||||
}
|
||||
|
||||
for(c=client; c; c=c->next) {
|
||||
if(!name || c->index == i) {
|
||||
temp = get_file();
|
||||
*last = temp;
|
||||
last = &temp->next;
|
||||
temp->ref = c;
|
||||
temp->id = c->id;
|
||||
temp->tab = *dirtab[FsDClient];
|
||||
asprintf(&temp->tab.name, "%d", c->index);
|
||||
if(name)
|
||||
goto LastItem;
|
||||
}
|
||||
if(name && c->id != id)
|
||||
continue;
|
||||
temp = get_file();
|
||||
*last = temp;
|
||||
last = &temp->next;
|
||||
temp->ref = c;
|
||||
temp->id = c->id;
|
||||
temp->tab = *dirtab[FsDClient];
|
||||
asprintf(&temp->tab.name, "%d", i);
|
||||
if(name)
|
||||
goto LastItem;
|
||||
}
|
||||
if(name)
|
||||
goto LastItem; /* label doesn't exist */
|
||||
}
|
||||
case FsDTags:
|
||||
View *v;
|
||||
if(!name || !strncmp(name, "sel", 4)) {
|
||||
if(sel) {
|
||||
temp = get_file();
|
||||
@ -221,25 +214,20 @@ lookup_file(FileId *parent, char *name)
|
||||
temp->tab = *dirtab[FsDTag];
|
||||
temp->tab.name = strdup("sel");
|
||||
}
|
||||
if(name)
|
||||
goto LastItem;
|
||||
}else{
|
||||
for(v=view; v; v=v->next) {
|
||||
if(!name || !strcmp(name, v->name)) {
|
||||
temp = get_file();
|
||||
*last = temp;
|
||||
last = &temp->next;
|
||||
temp->rev = v;
|
||||
temp->id = v->id;
|
||||
temp->name = strdup(v->name);
|
||||
if(name)
|
||||
goto LastItem;
|
||||
}
|
||||
if(name && strcmp(name, v->name))
|
||||
continue;
|
||||
temp = get_file();
|
||||
*last = temp;
|
||||
last = &temp->next;
|
||||
temp->ref = v;
|
||||
temp->id = v->id;
|
||||
temp->tab.name = strdup(v->name);
|
||||
}
|
||||
}
|
||||
case FsDRBar:
|
||||
case FsDLBar:
|
||||
Bar *b;
|
||||
for(b=parent->ref; b; b=b->next) {
|
||||
if(!name || strcmp(name, b->name)) {
|
||||
temp = get_file();
|
||||
@ -248,10 +236,12 @@ lookup_file(FileId *parent, char *name)
|
||||
temp->ref = b;
|
||||
temp->id = b->id;
|
||||
temp->tab = dirtab[FsDRBar][1];
|
||||
temp->tab.name = strdup(bar->name);
|
||||
temp->tab.name = strdup(b->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(name)
|
||||
goto LastItem;
|
||||
}
|
||||
}
|
||||
LastItem:
|
||||
@ -259,6 +249,7 @@ LastItem:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* XXX This leaks FileIds */
|
||||
void
|
||||
fs_walk(Req *r) {
|
||||
FileId *f = r->fid->aux, *nf, **fi;
|
||||
@ -268,13 +259,14 @@ fs_walk(Req *r) {
|
||||
if(!strncmp(r->ifcall.wname[i], "..", 3)) {
|
||||
if(f->next) f=f->next;
|
||||
}else{
|
||||
nf = lookup_file(f, r->ircall.wname[i]);
|
||||
nf = lookup_file(f, r->ifcall.wname[i]);
|
||||
if(!nf)
|
||||
break;
|
||||
nf->next = f;
|
||||
f = nf;
|
||||
}
|
||||
r->ofcall.wqid[i] = QID(f->tab.type, f->id);
|
||||
r->ofcall.wqid[i].type = f->tab.qtype;
|
||||
r->ofcall.wqid[i].path = QID(f->tab.type, f->id);
|
||||
}
|
||||
if(i < r->ifcall.nwname) {
|
||||
for(; f != r->fid->aux; f=nf) {
|
||||
@ -284,40 +276,45 @@ fs_walk(Req *r) {
|
||||
respond(r, Enofile);
|
||||
}
|
||||
|
||||
r->newfid->aux = f;
|
||||
if(r->ifcall.fid != r->ifcall.newfid) {
|
||||
r->newfid.aux = f;
|
||||
for(fi=&r->newfid.aux; *fi != r->fid.aux; fi=&(*fi)->next);
|
||||
for(fi=(void *)&r->newfid->aux;
|
||||
*fi != r->fid->aux;
|
||||
fi=&(*fi)->next);
|
||||
for(; *fi; fi=&(*fi)->next) {
|
||||
nf = get_file();
|
||||
*nf = **fi;
|
||||
*fi = nf;
|
||||
}
|
||||
}else
|
||||
r->fid.aux = f;
|
||||
}
|
||||
|
||||
r->fid.qid = r->ofcall.qid = r->ofcall.nwqid[i-1];
|
||||
if(r->ifcall.nwname == 0)
|
||||
r->newfid->qid = r->fid->qid;
|
||||
else
|
||||
r->newfid->qid = r->ofcall.wqid[i-1];
|
||||
r->ofcall.nwqid = i;
|
||||
r->fid.aux = f;
|
||||
respond(r);
|
||||
respond(r, nil);
|
||||
}
|
||||
|
||||
/* All of this stat stuf is ugly. */
|
||||
void
|
||||
fs_stat(Req *r) {
|
||||
Stat s;
|
||||
int size = IXP_MAX_STAT;
|
||||
void *buf = cext_emallocz(size);
|
||||
r->ofcall.stat = buf;
|
||||
int size;
|
||||
unsigned char *buf;
|
||||
|
||||
dostat(&s, 0, r->fid->aux);
|
||||
r->ofcall.nstat = size = ixp_sizeof_stat(&s);
|
||||
buf = cext_emallocz(size);
|
||||
r->ofcall.stat = buf;
|
||||
|
||||
ixp_pack_stat(&buf, &size, &s);
|
||||
r->ofcall.nstat = IXP_MAX_STAT - size;
|
||||
respond(r);
|
||||
respond(r, nil);
|
||||
}
|
||||
|
||||
void
|
||||
fs_read(Req *r) {
|
||||
void *buf;
|
||||
unsigned char *buf;
|
||||
unsigned int n, offset = 0;
|
||||
int size;
|
||||
FileId *f = r->fid->aux, *tf;
|
||||
@ -325,16 +322,17 @@ fs_read(Req *r) {
|
||||
if(f->tab.perm & DMDIR) {
|
||||
Stat s;
|
||||
offset = 0;
|
||||
size = r->ifcall->count;
|
||||
size = r->ifcall.count;
|
||||
buf = cext_emallocz(size);
|
||||
f.ofcall.data = buf;
|
||||
r->ofcall.data = buf;
|
||||
|
||||
f = lookup_file(f, nil);
|
||||
for(; f; f=f->next) {
|
||||
/* f->tab.name == "."; goto next */
|
||||
for(f=f->next; f; f=f->next) {
|
||||
dostat(&s, 0, f);
|
||||
n = ixp_sizeof_stat(s);
|
||||
n = ixp_sizeof_stat(&s);
|
||||
offset += n;
|
||||
if(offset >= f->ifcall.offset) {
|
||||
if(offset >= r->ifcall.offset) {
|
||||
if(size < n)
|
||||
break;
|
||||
ixp_pack_stat(&buf, &size, &s);
|
||||
@ -346,25 +344,66 @@ fs_read(Req *r) {
|
||||
free_file(tf);
|
||||
}
|
||||
|
||||
f.ofcall.size = f.ifcall.size - size;
|
||||
respond(f, nil);
|
||||
r->ofcall.count = r->ifcall.count - size;
|
||||
respond(r, nil);
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fs_attach(Req *r) {
|
||||
FileId *f = cext_emallocz(sizeof(FileId));
|
||||
f->tab = dirtab[FsRoot][0];
|
||||
f->tab.name = strdup("/");
|
||||
r->fid->aux = f;
|
||||
r->fid->qid.type = f->tab.qtype;
|
||||
r->fid->qid.path = QID(f->tab.type, 0);
|
||||
r->ofcall.qid = r->fid->qid;
|
||||
respond(r, nil);
|
||||
}
|
||||
|
||||
void
|
||||
fs_remove(Req *r) {
|
||||
respond(r, "not implemented");
|
||||
}
|
||||
|
||||
void
|
||||
fs_write(Req *r) {
|
||||
respond(r, "not implemented");
|
||||
}
|
||||
|
||||
void
|
||||
fs_open(Req *r) {
|
||||
if(!r->ifcall.mode == OREAD)
|
||||
respond(r, Enoperm);
|
||||
r->fid->omode = OREAD;
|
||||
respond(r, nil);
|
||||
}
|
||||
|
||||
void
|
||||
fs_create(Req *r) {
|
||||
respond(r, "not implemented");
|
||||
}
|
||||
|
||||
void
|
||||
write_event(char *buf) {
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
dostat(Stat *s, unsigned int len, FileId *f) {
|
||||
s->type = 0;
|
||||
s->dev = 0;
|
||||
s->qid.path = QID(f->tab.type, f->id);
|
||||
s->qid.vers = 0;
|
||||
s->qid.version = 0;
|
||||
s->qid.type = f->tab.qtype;
|
||||
s->mode = f->tab.perm;
|
||||
s->atime = clock;
|
||||
s->mtime = clock;
|
||||
s->atime = time(nil);
|
||||
s->mtime = time(nil);
|
||||
s->length = len;
|
||||
s->name = f->tab.name;
|
||||
s->uid = user;
|
||||
s->gid = user;
|
||||
s->muid = user;
|
||||
/* XXX This genenv should be called once */
|
||||
s->uid = getenv("USER");
|
||||
s->gid = getenv("USER");
|
||||
s->muid = getenv("USER");
|
||||
}
|
||||
|
201
libixp/request.c
201
libixp/request.c
@ -1,73 +1,89 @@
|
||||
enum { TAG_BUCKETS = 64;
|
||||
FID_BUCKETS = 64; }
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include "ixp.h"
|
||||
|
||||
typedef struct Fid {
|
||||
unsigned long fid;
|
||||
unsigned char omode;
|
||||
char *uid;
|
||||
Qid qid;
|
||||
void *aux;
|
||||
static void ixp_handle_req(Req *r);
|
||||
|
||||
/* Implementation specific */
|
||||
/* Do not use */
|
||||
|
||||
unsigned long ofid;
|
||||
} Fid;
|
||||
|
||||
struct IXPConn {
|
||||
IXPConn *next;
|
||||
IXPServer *srv;
|
||||
void *aux;
|
||||
int fd;
|
||||
void (*read) (IXPConn *);
|
||||
void (*close) (IXPConn *);
|
||||
};
|
||||
|
||||
struct P9Conn {
|
||||
void *
|
||||
createfid(Intmap *map, int fid) {
|
||||
Fid *f = cext_emallocz(sizeof(Fid));
|
||||
f->fid = fid;
|
||||
f->omode = -1;
|
||||
f->map = map;
|
||||
if(caninsertkey(map, fid, f))
|
||||
return f;
|
||||
free(f);
|
||||
return nil;
|
||||
}
|
||||
int
|
||||
destroyfid(Intmap *map, unsigned long fid) {
|
||||
Fid *f;
|
||||
if(!(f = deletekey(map, fid)))
|
||||
return 0;
|
||||
free(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Req *
|
||||
ixp_server_receive_req(IXPConn *c)
|
||||
static char
|
||||
Eduptag[] = "tag in use",
|
||||
Edupfid[] = "fid in use",
|
||||
Enofunc[] = "function not implemented",
|
||||
Ebotch[] = "9P protocol botch",
|
||||
Enofile[] = "the requested file does not exist",
|
||||
Enofid[] = "fid does not exist",
|
||||
Enotdir[] = "not a directory",
|
||||
Eisdir[] = "cannot perform operation on a directory";
|
||||
|
||||
enum { TAG_BUCKETS = 64,
|
||||
FID_BUCKETS = 64 };
|
||||
|
||||
typedef struct P9Conn {
|
||||
Intmap tagmap;
|
||||
void *taghash[TAG_BUCKETS];
|
||||
Intmap fidmap;
|
||||
void *fidhash[FID_BUCKETS];
|
||||
P9Srv *srv;
|
||||
unsigned int msize;
|
||||
unsigned char *buf;
|
||||
} P9Conn;
|
||||
|
||||
void
|
||||
ixp_server_handle_fcall(IXPConn *c)
|
||||
{
|
||||
Fcall fcall;
|
||||
P9Client *pc = c->aux;
|
||||
P9Conn *pc = c->aux;
|
||||
Req *req;
|
||||
unsigned int msize;
|
||||
char *errstr = nil;
|
||||
|
||||
if(!(msize = ixp_recv_message(c->fd, msg, IXP_MAX_MSG, &errstr)))
|
||||
if(!(msize = ixp_recv_message(c->fd, pc->buf, pc->msize, &errstr)))
|
||||
goto Fail;
|
||||
if(!(msize = ixp_msg2fcall(&fcall, msg, IXP_MAX_MSG)))
|
||||
if(!(msize = ixp_msg2fcall(&fcall, pc->buf, IXP_MAX_MSG)))
|
||||
goto Fail;
|
||||
|
||||
req = cext_emallocz(sizeof(Req));
|
||||
req->conn = c;
|
||||
req->ifcall = fcall;
|
||||
|
||||
if(lookupkey(pc->tagmap, fcall->tag)) {
|
||||
respond(req, Edupdag);
|
||||
return nil;
|
||||
}
|
||||
if(lookupkey(&pc->tagmap, fcall.tag))
|
||||
return respond(req, Eduptag);
|
||||
|
||||
insertkey(pc->tagmap, fcall.id, req);
|
||||
return req;
|
||||
insertkey(&pc->tagmap, fcall.tag, req);
|
||||
return ixp_handle_req(req);
|
||||
|
||||
Fail:
|
||||
ixp_close_conn(c);
|
||||
return nil;
|
||||
ixp_server_close_conn(c);
|
||||
}
|
||||
|
||||
void
|
||||
ixp_handle_fcall(IXPConn *c)
|
||||
static void
|
||||
ixp_handle_req(Req *r)
|
||||
{
|
||||
Req *r;
|
||||
unsigned int msize;
|
||||
P9Conn *pc = c->aux;
|
||||
P9Conn *pc = r->conn->aux;
|
||||
P9Srv *srv = pc->srv;
|
||||
|
||||
if(!(r = ixp_server_receive_fcall(c, &fcall)))
|
||||
return;
|
||||
|
||||
switch(r->ifcall.id) {
|
||||
switch(r->ifcall.type) {
|
||||
default:
|
||||
respond(r, Enofunc);
|
||||
break;
|
||||
@ -84,18 +100,18 @@ ixp_handle_fcall(IXPConn *c)
|
||||
respond(r, nil);
|
||||
break;
|
||||
case TATTACH:
|
||||
if(!(r->fid = createfid(pc->fid_hash, r->ifcall.fid)))
|
||||
if(!(r->fid = createfid(&pc->fidmap, r->ifcall.fid)))
|
||||
return respond(r, Edupfid);
|
||||
/* attach is a required function */
|
||||
srv->attach(r);
|
||||
break;
|
||||
case TCLUNK:
|
||||
if(!destroyfid(pc, r->ifcall.fid))
|
||||
if(!destroyfid(&pc->fidmap, r->ifcall.fid))
|
||||
return respond(r, Enofid);
|
||||
respond(r, nil);
|
||||
break;
|
||||
case TCREATE:
|
||||
if(!(r->fid = lookupkey(pc->fid_hash, r->ifcall.fid)))
|
||||
if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid)))
|
||||
return respond(r, Enofid);
|
||||
if(r->fid->omode != -1)
|
||||
return respond(r, Ebotch);
|
||||
@ -106,54 +122,56 @@ ixp_handle_fcall(IXPConn *c)
|
||||
pc->srv->create(r);
|
||||
break;
|
||||
case TOPEN:
|
||||
if(!(r->fid = lookupkey(pc->fid_hash, r->ifcall.fid)))
|
||||
if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid)))
|
||||
return respond(r, Enofid);
|
||||
if((r->fid.qid.type&QTDIR) && (r->fcall.mode|ORCLOSE) != (OREAD|ORCLOSE))
|
||||
if((r->fid->qid.type&QTDIR) && (r->ifcall.mode|ORCLOSE) != (OREAD|ORCLOSE))
|
||||
return respond(r, Eisdir);
|
||||
r->ofcall.qid = r->fid.qid;
|
||||
r->ofcall.qid = r->fid->qid;
|
||||
if(!pc->srv->open)
|
||||
return respond(r, Enofunc);
|
||||
pc->srv->open(r);
|
||||
break;
|
||||
case TREAD:
|
||||
if(!(r->fid = lookupkey(pc->fid_hash, r->ifcall.fid)))
|
||||
if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid)))
|
||||
return respond(r, Enofid);
|
||||
if(r->fid.omode == -1)
|
||||
if(r->fid->omode == -1)
|
||||
return respond(r, Ebotch);
|
||||
if(!pc->srv->read)
|
||||
return respond(r, Enofunc);
|
||||
pc->srv->read(r);
|
||||
break;
|
||||
case TREMOVE:
|
||||
if(!(r->fid = lookupkey(pc->fid_hash, r->ifcall.fid)))
|
||||
if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid)))
|
||||
return respond(r, Enofid);
|
||||
if(!pc->srv->remove)
|
||||
return respond(r, Enofunc);
|
||||
pc->src->remove(r);
|
||||
pc->srv->remove(r);
|
||||
break;
|
||||
case TSTAT:
|
||||
if(!(r->fid = lookupkey(pc->fid_hash, r->ifcall.fid)))
|
||||
if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid)))
|
||||
return respond(r, Enofid);
|
||||
if(!pc->srv->stat)
|
||||
return respond(r, Enofunc);
|
||||
pc->srv->stat(r);
|
||||
break;
|
||||
case TWALK:
|
||||
if(!(r->fid = lookupkey(pc->fid_hash, r->ifcall.fid)))
|
||||
if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid)))
|
||||
return respond(r, Enofid);
|
||||
if(r->fid->omode != -1)
|
||||
return respond(r, "cannot walk from an open fid");
|
||||
if(r->ifcall.nwname && !(r->fid->qid.type&QTDIR))
|
||||
return respond(r, Enotdir);
|
||||
if((r->ifcall.fid != r->ifcall.newfid) &&
|
||||
!(r->newfid = createfid(pc->fid_hash, r->ifcall.newfid)))
|
||||
return respond(r, Edupfid);
|
||||
if((r->ifcall.fid != r->ifcall.newfid)) {
|
||||
if(!(r->newfid = createfid(&pc->fidmap, r->ifcall.newfid)))
|
||||
return respond(r, Edupfid);
|
||||
}else
|
||||
r->newfid = r->fid;
|
||||
if(!pc->srv->walk)
|
||||
return respond(r, Enofunc);
|
||||
pc->srv->walk(r);
|
||||
break;
|
||||
case TWRITE:
|
||||
if(!(r->fid = lookupkey(pc->fid_hash, r->ifcall.fid)))
|
||||
if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid)))
|
||||
return respond(r, Enofid);
|
||||
if((r->fid->omode&3) != OWRITE && (r->fid->omode&3) != ORDWR)
|
||||
return respond(r, "write on fid not opened for writing");
|
||||
@ -170,7 +188,8 @@ respond(Req *r, char *error) {
|
||||
P9Conn *pc = r->conn->aux;
|
||||
switch(r->ifcall.type) {
|
||||
default:
|
||||
cext_assert(!"Respond called on unsupported fcall type");
|
||||
if(!error)
|
||||
cext_assert(!"Respond called on unsupported fcall type");
|
||||
break;
|
||||
case TVERSION:
|
||||
cext_assert(!error);
|
||||
@ -180,7 +199,7 @@ respond(Req *r, char *error) {
|
||||
break;
|
||||
case TATTACH:
|
||||
if(error)
|
||||
destroyfid(r->fid);
|
||||
destroyfid(r->fid->map, r->fid->fid);
|
||||
break;
|
||||
case TOPEN:
|
||||
case TCREATE:
|
||||
@ -191,12 +210,12 @@ respond(Req *r, char *error) {
|
||||
break;
|
||||
case TWALK:
|
||||
if(error || r->ofcall.nwqid < r->ifcall.nwname) {
|
||||
if(r->ifcall.fid != r->ifcall.newfid)
|
||||
destroyfid(r->newfid);
|
||||
if(r->ifcall.fid != r->ifcall.newfid && r->newfid)
|
||||
destroyfid(r->newfid->map, r->newfid->fid);
|
||||
if(!error && r->ofcall.nwqid == 0)
|
||||
error = Enofile;
|
||||
}else{
|
||||
if(f->ofcall.nwqid == 0)
|
||||
if(r->ofcall.nwqid == 0)
|
||||
r->newfid->qid = r->fid->qid;
|
||||
else
|
||||
r->newfid->qid = r->ofcall.wqid[r->ofcall.nwqid-1];
|
||||
@ -219,14 +238,46 @@ respond(Req *r, char *error) {
|
||||
r->ofcall.ename = error;
|
||||
}
|
||||
|
||||
ixp_server_respond_fcall(r->conn, r->ofcall);
|
||||
/* XXX Check if conn is still open */
|
||||
ixp_server_respond_fcall(r->conn, &r->ofcall);
|
||||
|
||||
deletekey(pc->tag_pool, r->tag);;
|
||||
switch(r->ofcall.type) {
|
||||
case RSTAT:
|
||||
free(r->ofcall.stat);
|
||||
break;
|
||||
case RREAD:
|
||||
free(r->ofcall.data);
|
||||
break;
|
||||
}
|
||||
switch(r->ifcall.type) {
|
||||
case TWALK:
|
||||
free(r->ifcall.wname[0]);
|
||||
break;
|
||||
case TWRITE:
|
||||
free(r->ifcall.data);
|
||||
}
|
||||
|
||||
deletekey(&pc->tagmap, r->ifcall.tag);;
|
||||
free(r);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
ixp_void_request(void *r) {
|
||||
/* generate flush request */
|
||||
}
|
||||
|
||||
static void
|
||||
ixp_void_fid(void *f) {
|
||||
/* generate clunk request */
|
||||
}
|
||||
|
||||
static void
|
||||
ixp_cleanup_conn(IXPConn *c) {
|
||||
P9Conn *pc = c->aux;
|
||||
freemap(&pc->tagmap, ixp_void_request);
|
||||
freemap(&pc->fidmap, ixp_void_fid);
|
||||
free(pc->buf);
|
||||
free(pc);
|
||||
}
|
||||
|
||||
void
|
||||
@ -238,8 +289,12 @@ serve_9pcon(IXPConn *c) {
|
||||
P9Conn *pc = cext_emallocz(sizeof(P9Conn));
|
||||
pc->srv = c->aux;
|
||||
|
||||
initmap(&pc->tagmap, TAG_BUCKETS, &pc->tag_hash);
|
||||
initmap(&pc->fidmap, FID_BUCKETS, &pc->fid_hash);
|
||||
/* XXX */
|
||||
pc->msize = 1024;
|
||||
pc->buf = cext_emallocz(pc->msize);
|
||||
|
||||
ixp_server_open_conn(c->srv, fd, pc, ixp_handle_fcall, ixp_cleanup_conn);
|
||||
initmap(&pc->tagmap, TAG_BUCKETS, &pc->taghash);
|
||||
initmap(&pc->fidmap, FID_BUCKETS, &pc->fidhash);
|
||||
|
||||
ixp_server_open_conn(c->srv, fd, pc, ixp_server_handle_fcall, ixp_cleanup_conn);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user