mirror of https://github.com/0intro/wmii
Same story as before.
This commit is contained in:
parent
a4cf1b6fde
commit
c8bff01914
167
cmd/wm/fs2.c
167
cmd/wm/fs2.c
|
@ -12,7 +12,8 @@ P9Srv p9srv = {
|
||||||
.write= fs_write,
|
.write= fs_write,
|
||||||
.attach=fs_attach,
|
.attach=fs_attach,
|
||||||
.create=fs_create,
|
.create=fs_create,
|
||||||
.remove=fs_remove
|
.remove=fs_remove,
|
||||||
|
.freefid=fs_freefid
|
||||||
};
|
};
|
||||||
|
|
||||||
#define QID(t, i) (((long long)((t)&0xFF)<<32)|((i)&0xFFFFFFFF))
|
#define QID(t, i) (((long long)((t)&0xFF)<<32)|((i)&0xFFFFFFFF))
|
||||||
|
@ -133,6 +134,16 @@ get_file() {
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convenience func: */
|
||||||
|
/* ugly, though... */
|
||||||
|
FileId *
|
||||||
|
push_file(FileId ***last) {
|
||||||
|
FileId *ret = get_file();
|
||||||
|
**last = ret;
|
||||||
|
*last = &ret->next;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_file(FileId *f) {
|
free_file(FileId *f) {
|
||||||
if(--f->nref)
|
if(--f->nref)
|
||||||
|
@ -161,117 +172,101 @@ lookup_file(FileId *parent, char *name)
|
||||||
if(!(parent->tab.perm & DMDIR))
|
if(!(parent->tab.perm & DMDIR))
|
||||||
return nil;
|
return nil;
|
||||||
Dirtab *dir = dirtab[parent->tab.type];
|
Dirtab *dir = dirtab[parent->tab.type];
|
||||||
FileId *ret = nil, *temp, **last = &ret;
|
FileId *ret = nil, *file, **last = &ret;
|
||||||
|
|
||||||
for(; dir->name; dir++) {
|
for(; dir->name; dir++) {
|
||||||
|
/* Dynamic dirs */
|
||||||
if(!*dir->name) { /* strlen(dir->name) == 0 */
|
if(!*dir->name) { /* strlen(dir->name) == 0 */
|
||||||
switch(parent->tab.type) {
|
switch(parent->tab.type) {
|
||||||
case FsDClients:
|
case FsDClients:
|
||||||
if(!name || !strncmp(name, "sel", 4)) {
|
if(!name || !strncmp(name, "sel", 4)) {
|
||||||
if((c = sel_client())) {
|
if((c = sel_client())) {
|
||||||
temp = get_file();
|
file = push_file(&last);
|
||||||
*last = temp;
|
file->ref = c;
|
||||||
last = &temp->next;
|
file->id = c->id;
|
||||||
temp->ref = c;
|
file->index = idx_of_client(c);
|
||||||
temp->id = c->id;
|
file->tab = *dirtab[FsDSClient];
|
||||||
temp->index = idx_of_client(c);
|
file->tab.name = strdup("sel");
|
||||||
temp->tab = *dirtab[FsDSClient];
|
}if(name) goto LastItem;
|
||||||
temp->tab.name = strdup("sel");
|
|
||||||
}
|
|
||||||
if(name)
|
|
||||||
goto LastItem;
|
|
||||||
}
|
}
|
||||||
if(name) {
|
if(name) {
|
||||||
id = (unsigned int)strtol(name, &name, 10);
|
id = (unsigned int)strtol(name, &name, 10);
|
||||||
if(*name)
|
if(*name) goto NextItem;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i=0;
|
i=0;
|
||||||
for(c=client; c; c=c->next, i++) {
|
for(c=client; c; c=c->next, i++) {
|
||||||
if(name && i != id)
|
if(!name || i == id) {
|
||||||
continue;
|
file = push_file(&last);
|
||||||
temp = get_file();
|
file->ref = c;
|
||||||
*last = temp;
|
file->id = c->id;
|
||||||
last = &temp->next;
|
file->tab = *dir;
|
||||||
temp->ref = c;
|
asprintf(&file->tab.name, "%d", i);
|
||||||
temp->id = c->id;
|
if(name) goto LastItem;
|
||||||
temp->tab = *dir;
|
}
|
||||||
asprintf(&temp->tab.name, "%d", i);
|
|
||||||
if(name)
|
|
||||||
goto LastItem;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FsDTags:
|
case FsDTags:
|
||||||
if(!name || !strncmp(name, "sel", 4)) {
|
if(!name || !strncmp(name, "sel", 4)) {
|
||||||
if(sel) {
|
if(sel) {
|
||||||
temp = get_file();
|
file = push_file(&last);
|
||||||
*last = temp;
|
file->ref = sel;
|
||||||
last = &temp->next;
|
file->id = sel->id;
|
||||||
temp->ref = sel;
|
file->tab = *dir;
|
||||||
temp->id = sel->id;
|
file->tab.name = strdup("sel");
|
||||||
temp->tab = *dir;
|
}if(name) goto LastItem;
|
||||||
temp->tab.name = strdup("sel");
|
|
||||||
}
|
|
||||||
if(name)
|
|
||||||
goto LastItem;
|
|
||||||
}
|
}
|
||||||
for(v=view; v; v=v->next) {
|
for(v=view; v; v=v->next) {
|
||||||
if(name && strcmp(name, v->name))
|
if(!name || !strcmp(name, v->name)) {
|
||||||
continue;
|
file = push_file(&last);
|
||||||
temp = get_file();
|
file->ref = v;
|
||||||
*last = temp;
|
file->id = v->id;
|
||||||
last = &temp->next;
|
file->tab = *dir;
|
||||||
temp->ref = v;
|
file->tab.name = strdup(v->name);
|
||||||
temp->id = v->id;
|
if(name) goto LastItem;
|
||||||
temp->tab = *dir;
|
}
|
||||||
temp->tab.name = strdup(v->name);
|
|
||||||
if(name)
|
|
||||||
goto LastItem;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FsDRBar:
|
case FsDRBar:
|
||||||
case FsDLBar:
|
case FsDLBar:
|
||||||
for(b=parent->ref; b; b=b->next) {
|
for(b=parent->ref; b; b=b->next) {
|
||||||
if(!name || strcmp(name, b->name)) {
|
if(!name || !strcmp(name, b->name)) {
|
||||||
temp = get_file();
|
file = push_file(&last);
|
||||||
*last = temp;
|
file->ref = b;
|
||||||
last = &temp->next;
|
file->id = b->id;
|
||||||
temp->ref = b;
|
file->tab = *dir;
|
||||||
temp->id = b->id;
|
file->tab.name = strdup(b->name);
|
||||||
temp->tab = *dir;
|
if(name) goto LastItem;
|
||||||
temp->tab.name = strdup(b->name);
|
|
||||||
if(name)
|
|
||||||
goto LastItem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}else
|
}else /* Static dirs */
|
||||||
if(!name || !strcmp(name, dir->name)) {
|
if(!name || !strcmp(name, dir->name)) {
|
||||||
temp = get_file();
|
file = push_file(&last);
|
||||||
*last = temp;
|
file->id = 0;
|
||||||
last = &temp->next;
|
file->ref = nil;
|
||||||
temp->id = 0;
|
file->tab = *dir;
|
||||||
temp->ref = nil;
|
|
||||||
temp->tab = *dir;
|
|
||||||
|
|
||||||
switch(temp->tab.type) {
|
/* Special considerations: */
|
||||||
|
switch(file->tab.type) {
|
||||||
case FsDLBar:
|
case FsDLBar:
|
||||||
temp->ref = lbar;
|
file->ref = lbar;
|
||||||
break;
|
break;
|
||||||
case FsDRBar:
|
case FsDRBar:
|
||||||
temp->ref = rbar;
|
file->ref = rbar;
|
||||||
break;
|
break;
|
||||||
case FsFColRules:
|
case FsFColRules:
|
||||||
temp->ref = vrule;
|
file->ref = vrule;
|
||||||
break;
|
break;
|
||||||
case FsFTagRules:
|
case FsFTagRules:
|
||||||
temp->ref = trule;
|
file->ref = trule;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(name)
|
if(name) goto LastItem;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
NextItem:
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
LastItem:
|
LastItem:
|
||||||
*last = nil;
|
*last = nil;
|
||||||
|
@ -301,27 +296,28 @@ fs_walk(Req *r) {
|
||||||
r->ofcall.wqid[i].type = f->tab.qtype;
|
r->ofcall.wqid[i].type = f->tab.qtype;
|
||||||
r->ofcall.wqid[i].path = QID(f->tab.type, f->id);
|
r->ofcall.wqid[i].path = QID(f->tab.type, f->id);
|
||||||
}
|
}
|
||||||
|
/* XXX: This will not be necessary once a free_fid
|
||||||
|
* function is implemented */
|
||||||
if(i < r->ifcall.nwname) {
|
if(i < r->ifcall.nwname) {
|
||||||
while((nf = f)) {
|
while((nf = f)) {
|
||||||
f=f->next;
|
f=f->next;
|
||||||
free_file(nf);
|
free_file(nf);
|
||||||
}
|
}
|
||||||
return respond(r, Enofile);
|
return respond(r, Enofile);
|
||||||
}else
|
}
|
||||||
|
|
||||||
|
/* Remove refs for r->fid if no new fid */
|
||||||
|
/* If Fids were ref counted, this could be
|
||||||
|
* done in their decref function */
|
||||||
if(r->ifcall.fid == r->ifcall.newfid) {
|
if(r->ifcall.fid == r->ifcall.newfid) {
|
||||||
nf=r->fid->aux;
|
nf=r->fid->aux;
|
||||||
r->fid->aux = f;
|
r->fid->aux = f;
|
||||||
for(; nf; nf=f) {
|
for(; nf; nf=f) {
|
||||||
f = nf->next;
|
f = nf->next;
|
||||||
free(nf);
|
free_file(nf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(r->ifcall.nwname == 0)
|
|
||||||
r->newfid->qid = r->fid->qid;
|
|
||||||
else
|
|
||||||
r->newfid->qid = r->ofcall.wqid[i-1];
|
|
||||||
r->newfid->aux = f;
|
r->newfid->aux = f;
|
||||||
r->ofcall.nwqid = i;
|
r->ofcall.nwqid = i;
|
||||||
respond(r, nil);
|
respond(r, nil);
|
||||||
|
@ -361,7 +357,7 @@ fs_read(Req *r) {
|
||||||
buf = cext_emallocz(size);
|
buf = cext_emallocz(size);
|
||||||
r->ofcall.data = buf;
|
r->ofcall.data = buf;
|
||||||
|
|
||||||
f = lookup_file(f, nil);
|
tf = f = lookup_file(f, nil);
|
||||||
/* Note: f->tab.name == "."; goto next */
|
/* Note: f->tab.name == "."; goto next */
|
||||||
for(f=f->next; f; f=f->next) {
|
for(f=f->next; f; f=f->next) {
|
||||||
dostat(&s, 0, f);
|
dostat(&s, 0, f);
|
||||||
|
@ -374,9 +370,9 @@ fs_read(Req *r) {
|
||||||
offset += n;
|
offset += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
while((tf = f)) {
|
while((f = tf)) {
|
||||||
f = f->next;
|
tf = tf->next;
|
||||||
free_file(tf);
|
free_file(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
r->ofcall.count = r->ifcall.count - size;
|
r->ofcall.count = r->ifcall.count - size;
|
||||||
|
@ -408,6 +404,15 @@ fs_open(Req *r) {
|
||||||
respond(r, nil);
|
respond(r, nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fs_freefid(Fid *f) {
|
||||||
|
FileId *id = f->aux, *tid;
|
||||||
|
while((tid = id)) {
|
||||||
|
id = id->next;
|
||||||
|
free_file(tid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fs_remove(Req *r) {
|
fs_remove(Req *r) {
|
||||||
respond(r, "not implemented");
|
respond(r, "not implemented");
|
||||||
|
|
|
@ -31,7 +31,7 @@ static char
|
||||||
Edupfid[] = "fid in use",
|
Edupfid[] = "fid in use",
|
||||||
Enofunc[] = "function not implemented",
|
Enofunc[] = "function not implemented",
|
||||||
Ebotch[] = "9P protocol botch",
|
Ebotch[] = "9P protocol botch",
|
||||||
Enofile[] = "the requested file does not exist",
|
Enofile[] = "file does not exist",
|
||||||
Enofid[] = "fid does not exist",
|
Enofid[] = "fid does not exist",
|
||||||
Enotdir[] = "not a directory",
|
Enotdir[] = "not a directory",
|
||||||
Eisdir[] = "cannot perform operation on a directory";
|
Eisdir[] = "cannot perform operation on a directory";
|
||||||
|
@ -82,6 +82,7 @@ ixp_handle_req(Req *r)
|
||||||
{
|
{
|
||||||
P9Conn *pc = r->conn->aux;
|
P9Conn *pc = r->conn->aux;
|
||||||
P9Srv *srv = pc->srv;
|
P9Srv *srv = pc->srv;
|
||||||
|
Fid *f;
|
||||||
|
|
||||||
switch(r->ifcall.type) {
|
switch(r->ifcall.type) {
|
||||||
default:
|
default:
|
||||||
|
@ -106,8 +107,11 @@ ixp_handle_req(Req *r)
|
||||||
srv->attach(r);
|
srv->attach(r);
|
||||||
break;
|
break;
|
||||||
case TCLUNK:
|
case TCLUNK:
|
||||||
if(!destroyfid(&pc->fidmap, r->ifcall.fid))
|
if(!(f=deletekey(&pc->fidmap, r->ifcall.fid)))
|
||||||
return respond(r, Enofid);
|
return respond(r, Enofid);
|
||||||
|
if(pc->srv->freefid)
|
||||||
|
pc->srv->freefid(f);
|
||||||
|
free(f);
|
||||||
respond(r, nil);
|
respond(r, nil);
|
||||||
break;
|
break;
|
||||||
case TCREATE:
|
case TCREATE:
|
||||||
|
@ -193,6 +197,7 @@ respond(Req *r, char *error) {
|
||||||
break;
|
break;
|
||||||
case TVERSION:
|
case TVERSION:
|
||||||
cext_assert(!error);
|
cext_assert(!error);
|
||||||
|
free(r->ifcall.version);
|
||||||
pc->msize = (r->ofcall.msize < IXP_MAX_MSG) ? r->ofcall.msize : IXP_MAX_MSG;
|
pc->msize = (r->ofcall.msize < IXP_MAX_MSG) ? r->ofcall.msize : IXP_MAX_MSG;
|
||||||
free(pc->buf);
|
free(pc->buf);
|
||||||
pc->buf = cext_emallocz(r->ofcall.msize);
|
pc->buf = cext_emallocz(r->ofcall.msize);
|
||||||
|
@ -200,6 +205,8 @@ respond(Req *r, char *error) {
|
||||||
case TATTACH:
|
case TATTACH:
|
||||||
if(error)
|
if(error)
|
||||||
destroyfid(r->fid->map, r->fid->fid);
|
destroyfid(r->fid->map, r->fid->fid);
|
||||||
|
free(r->ifcall.uname);
|
||||||
|
free(r->ifcall.aname);
|
||||||
break;
|
break;
|
||||||
case TOPEN:
|
case TOPEN:
|
||||||
case TCREATE:
|
case TCREATE:
|
||||||
|
@ -207,6 +214,7 @@ respond(Req *r, char *error) {
|
||||||
r->fid->omode = r->ofcall.mode;
|
r->fid->omode = r->ofcall.mode;
|
||||||
r->fid->qid = r->ofcall.qid;
|
r->fid->qid = r->ofcall.qid;
|
||||||
}
|
}
|
||||||
|
free(r->ifcall.name);
|
||||||
r->ofcall.iounit = pc->msize - sizeof(unsigned long);
|
r->ofcall.iounit = pc->msize - sizeof(unsigned long);
|
||||||
break;
|
break;
|
||||||
case TWALK:
|
case TWALK:
|
||||||
|
@ -221,12 +229,15 @@ respond(Req *r, char *error) {
|
||||||
else
|
else
|
||||||
r->newfid->qid = r->ofcall.wqid[r->ofcall.nwqid-1];
|
r->newfid->qid = r->ofcall.wqid[r->ofcall.nwqid-1];
|
||||||
}
|
}
|
||||||
|
free(*r->ifcall.wname);
|
||||||
|
break;
|
||||||
|
case TWRITE:
|
||||||
|
free(r->ifcall.data);
|
||||||
break;
|
break;
|
||||||
case TCLUNK:
|
case TCLUNK:
|
||||||
case TREAD:
|
case TREAD:
|
||||||
case TREMOVE:
|
case TREMOVE:
|
||||||
case TSTAT:
|
case TSTAT:
|
||||||
case TWRITE:
|
|
||||||
break;
|
break;
|
||||||
/* Still to be implemented: flush, wstat, auth */
|
/* Still to be implemented: flush, wstat, auth */
|
||||||
}
|
}
|
||||||
|
@ -250,13 +261,6 @@ respond(Req *r, char *error) {
|
||||||
free(r->ofcall.data);
|
free(r->ofcall.data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch(r->ifcall.type) {
|
|
||||||
case TWALK:
|
|
||||||
free(*r->ifcall.wname);
|
|
||||||
break;
|
|
||||||
case TWRITE:
|
|
||||||
free(r->ifcall.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
deletekey(&pc->tagmap, r->ifcall.tag);;
|
deletekey(&pc->tagmap, r->ifcall.tag);;
|
||||||
free(r);
|
free(r);
|
||||||
|
|
Loading…
Reference in New Issue