#include "all.h"
#include <fcall.h>
/* 9p2 */
int version(Chan*, Fcall*, Fcall*);
int attach(Chan*, Fcall*, Fcall*);
int walk(Chan*, Fcall*, Fcall*);
int fs_open(Chan*, Fcall*, Fcall*);
int fs_create(Chan*, Fcall*, Fcall*);
int fs_read(Chan*, Fcall*, Fcall*, uchar*);
int fs_write(Chan*, Fcall*, Fcall*);
int fs_remove(Chan*, Fcall*, Fcall*);
int
con_session(void)
{
Fcall in, ou;
int err;
memset(&in, 0, sizeof(in));
memset(&ou, 0, sizeof(ou));
in.type = Tversion;
in.version = VERSION9P;
in.msize = MAXDAT + IOHDRSZ;
rlock(&mainlock);
err = version(cons.chan, &in, &ou);
runlock(&mainlock);
return err;
}
int
con_attach(int fid, char *uid, char *arg)
{
Fcall in, ou;
int err;
memset(&in, 0, sizeof(in));
memset(&ou, 0, sizeof(ou));
in.type = Tattach;
in.fid = fid;
in.uname = uid;
in.aname = arg;
rlock(&mainlock);
err = attach(cons.chan, &in, &ou);
runlock(&mainlock);
return err;
}
int
con_clone(int fid1, int fid2)
{
Fcall in, ou;
int err;
memset(&in, 0, sizeof(in));
memset(&ou, 0, sizeof(ou));
in.type = Twalk;
in.fid = fid1;
in.newfid = fid2;
in.nwname = 0;
rlock(&mainlock);
err = walk(cons.chan, &in, &ou);
runlock(&mainlock);
return err;
}
int
con_walk(int fid, char *name)
{
Fcall in, ou;
int err;
memset(&in, 0, sizeof(in));
memset(&ou, 0, sizeof(ou));
in.type = Twalk;
in.fid = fid;
in.newfid = fid;
in.wname[0] = name;
in.nwname = 1;
rlock(&mainlock);
err = walk(cons.chan, &in, &ou);
runlock(&mainlock);
return err;
}
int
con_open(int fid, int mode)
{
Fcall in, ou;
int err;
memset(&in, 0, sizeof(in));
memset(&ou, 0, sizeof(ou));
in.type = Topen;
in.fid = fid;
in.mode = mode;
rlock(&mainlock);
err = fs_open(cons.chan, &in, &ou);
runlock(&mainlock);
return err;
}
int
con_create(int fid, char *name, int uid, int gid, long perm, int mode)
{
Fcall in, ou;
int err;
cons.uid = uid; /* beyond ugly */
cons.gid = gid;
memset(&in, 0, sizeof(in));
memset(&ou, 0, sizeof(ou));
in.type = Tcreate;
in.fid = fid;
in.mode = mode;
in.perm = perm;
in.name = name;
rlock(&mainlock);
err = fs_create(cons.chan, &in, &ou);
runlock(&mainlock);
return err;
}
int
con_read(int fid, char *data, Off offset, int count)
{
Fcall in, ou;
int err;
memset(&in, 0, sizeof(in));
memset(&ou, 0, sizeof(ou));
in.type = Tread;
in.fid = fid;
in.offset = offset;
in.count = count;
rlock(&mainlock);
err = fs_read(cons.chan, &in, &ou, (uchar*)data);
runlock(&mainlock);
return err ? 0 : ou.count;
}
int
con_write(int fid, char *data, Off offset, int count)
{
Fcall in, ou;
int err;
memset(&in, 0, sizeof(in));
memset(&ou, 0, sizeof(ou));
in.type = Twrite;
in.fid = fid;
in.offset = offset;
in.count = count;
in.data = data;
rlock(&mainlock);
err = fs_write(cons.chan, &in, &ou);
runlock(&mainlock);
return err ? 0 : ou.count;
}
int
con_remove(int fid)
{
Fcall in, ou;
int err;
memset(&in, 0, sizeof(in));
memset(&ou, 0, sizeof(ou));
in.type = Tremove;
in.fid = fid;
rlock(&mainlock);
err = fs_remove(cons.chan, &in, &ou);
runlock(&mainlock);
return err;
}
int
doclri(File *f)
{
Iobuf *p, *p1;
Dentry *d, *d1;
int err;
err = 0;
p = 0;
p1 = 0;
if(f->fs->dev->type == Devro) {
err = Eronly;
goto out;
}
/*
* check on parent directory of file to be deleted
*/
if(f->wpath == 0 || f->wpath->addr == f->addr) {
err = Ephase;
goto out;
}
p1 = getbuf(f->fs->dev, f->wpath->addr, Brd);
d1 = getdir(p1, f->wpath->slot);
if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
err = Ephase;
goto out;
}
accessdir(p1, d1, FWRITE, 0);
putbuf(p1);
p1 = 0;
/*
* check on file to be deleted
*/
p = getbuf(f->fs->dev, f->addr, Brd);
d = getdir(p, f->slot);
/*
* do it
*/
memset(d, 0, sizeof(Dentry));
settag(p, Tdir, QPNONE);
freewp(f->wpath);
freefp(f);
out:
if(p1)
putbuf(p1);
if(p)
putbuf(p);
return err;
}
static int
f_fstat(Chan *cp, Fcall *in, Fcall *ou)
{
File *f;
Iobuf *p;
Dentry *d;
int i, err;
err = 0;
if(CHAT(cp)) {
fprint(2, "c_fstat %d\n", cp->chan);
fprint(2, "\tfid = %d\n", in->fid);
}
p = 0;
f = filep(cp, in->fid, 0);
if(!f) {
err = Efid;
goto out;
}
p = getbuf(f->fs->dev, f->addr, Brd);
d = getdir(p, f->slot);
if(d == 0)
goto out;
print("name = %.*s\n", NAMELEN, d->name);
print("uid = %d; gid = %d; muid = %d\n", d->uid, d->gid, d->muid);
print("size = %lld; qid = %llux/%lux\n", (Wideoff)d->size,
(Wideoff)d->qid.path, d->qid.version);
print("atime = %ld; mtime = %ld\n", d->atime, d->mtime);
print("dblock =");
for(i=0; i<NDBLOCK; i++)
print(" %lld", (Wideoff)d->dblock[i]);
for (i = 0; i < NIBLOCK; i++)
print("; iblocks[%d] = %lld", i, (Wideoff)d->iblocks[i]);
print("\n\n");
out:
if(p)
putbuf(p);
ou->fid = in->fid;
if(f)
qunlock(f);
return err;
}
int
con_fstat(int fid)
{
Fcall in, ou;
int err;
memset(&in, 0, sizeof(in));
memset(&ou, 0, sizeof(ou));
in.type = Tstat;
in.fid = fid;
rlock(&mainlock);
err = f_fstat(cons.chan, &in, &ou);
runlock(&mainlock);
return err;
}
static int
f_clri(Chan *cp, Fcall *in, Fcall *ou)
{
File *f;
int err;
if(CHAT(cp)) {
fprint(2, "c_clri %d\n", cp->chan);
fprint(2, "\tfid = %d\n", in->fid);
}
f = filep(cp, in->fid, 0);
if(!f) {
err = Efid;
goto out;
}
err = doclri(f);
out:
ou->fid = in->fid;
if(f)
qunlock(f);
return err;
}
int
con_clri(int fid)
{
Fcall in, ou;
int err;
memset(&in, 0, sizeof(in));
memset(&ou, 0, sizeof(ou));
in.type = Tremove;
in.fid = fid;
rlock(&mainlock);
err = f_clri(cons.chan, &in, &ou);
runlock(&mainlock);
return err;
}