V8/usr/net/face/work.c
#include "fserv.h"
#include "errno.h"
#include "neta.h"
extern char *buf, *nbuf;
extern int myfd, wrcnt, rdcnt;
extern struct rcva y, nilrcv;
doput(x)
struct senda *x;
{
y.trannum = x->trannum;
if(x->tag == 0) {
debug("put got 0");
respond(EIO);
dumpstate();
return;
}
clrnetf(x->tag);
respond(0);
}
doget(x)
struct senda *x;
{ netf *p;
y.trannum = x->trannum;
p = getnetf(x->dev, x->ino);
if(p == 0) {
respond(EIO);
return;
}
debug2("\tget %d %d 0%o %d %d %s\n", p->dev, p->ino,
p->statb.st_mode, p->statb.st_uid, p->statb.st_gid, p->name);
y.mode = p->statb.st_mode;
y.tag = p->tag;
y.nlink = p->statb.st_nlink;
y.uid = hostuid(&p->statb);
y.gid = hostgid(&p->statb);
y.size = p->statb.st_size;
respond(0);
}
dofree(x) /* means rmt thinks nlink == 0 */
struct senda *x;
{
y.trannum = x->trannum;
respond(0);
}
doupdat(x)
struct senda *x;
{ netf *p;
int i;
y.trannum = x->trannum;
p = gettag(x->tag);
if(p == 0) {
respond(EIO);
return;
}
debug2("\tupdat 0%o %d %d\n", p->statb.st_mode, p->statb.st_uid, p->statb.st_gid);
debug2("\t\t0%o %d %d\n", x->mode, x->uid, x->gid);
if(p->name == 0) { /* of course this can't happen */
debug("\tname 0 tag %d\n", p->tag);
respond(EIO);
dumpstate();
return;
}
y.mode = p->statb.st_mode;
y.nlink = p->statb.st_nlink;
y.uid = hostuid(&p->statb);
y.gid = hostgid(&p->statb);
y.size = p->statb.st_size;
if(hisdev(p->statb.st_dev) != p->dev || p->ino != p->statb.st_ino) {
debug("\tdev oops\n");
dumpstate();
}
respond(0);
}
doread(x)
struct senda *x;
{ netf *p;
int n, offset = 0;
y.trannum = x->trannum;
p = gettag(x->tag);
if(p == 0) {
respond(EIO);
return;
}
if(seeknetf(p, x->offset) < 0)
perror("\tread lseek");
getbuf(x->count);
n = readnetf(p, buf, x->count);
debug1("\tread got %d wanted %d\n", n, x->count);
if(n < 0) {
y.count = n;
respond(EIO);
return;
}
y.count = n - offset;
respond(0);
(void) write(myfd, buf + offset, (unsigned) n - offset);
wrcnt += n;
}
dowrite(x)
struct senda *x;
{ netf *p;
int n;
y.trannum = x->trannum;
if(x->count == 0)
respond(EACCES);
getbuf(x->count);
if((n = read(myfd, buf, x->count)) != x->count) {
debug("\twrite expected %d got %d\n", x->count, n);
rdcnt += n;
respond(EIO);
dumpstate();
return;
}
respond(EACCES);
}
dotrunc(x)
struct senda *x;
{
y.trannum = x->trannum;
respond(0);
}
dostat(x)
struct senda *x;
{ netf *p;
y.trannum = x->trannum;
debug2("\tstat %d\n", x->tag);
p = gettag(x->tag);
if(p == 0) {
respond(EIO);
return;
}
debug2("\tlstat %s ", p->name);
debug2("0%o %d %d\n", p->statb.st_mode, p->statb.st_uid, p->statb.st_gid);
y.mode = p->statb.st_mode;
y.nlink = p->statb.st_nlink;
y.uid = hostuid(&p->statb);
y.gid = hostgid(&p->statb);
debug2("\thostuid(%d) = %d\n", p->statb.st_uid, y.uid);
debug2("\tgid %d\n", y.gid);
y.size = p->statb.st_size;
y.tm[0] = p->statb.st_atime;
y.tm[1] = p->statb.st_mtime;
y.tm[2] = p->statb.st_ctime;
if(hisdev(p->statb.st_dev) != p->dev || p->ino != p->statb.st_ino) {
debug("\toops dev or ino\n");
dumpstate();
}
respond(0);
}
donami(x)
struct senda *x;
{ netf *p, *q;
int fd, i, nlink = 0;
y.trannum = x->trannum;
getbuf(x->count);
if((i = read(myfd, buf, x->count)) != x->count) {
rdcnt += i;
respond(EIO);
return;
}
rdcnt += i;
p = gettag(x->tag);
if(p == 0) {
respond(EIO);
return;
}
debug1("\tcdir %s 0%o %d %d\n", p->name, p->statb.st_mode,
p->statb.st_uid, p->statb.st_gid);
if(ftype(p) != S_IFDIR) {
respond(ENOTDIR);
return;
}
if(noaccess(x, &p->statb, S_IEXEC)) {
respond(EACCES);
return;
}
fixnbuf(p->name, x->count, buf, x->flags);
debug2("\tnami %s (%d)\n", nbuf, x->flags);
q = newnetf(nbuf);
if(q != 0) {
debug2("\tfound\n");
errno = 0;
y.ino = q->ino;
y.tag = q->tag;
y.dev = q->dev;
y.mode = q->statb.st_mode;
y.nlink = q->statb.st_nlink;
y.uid = hostuid(&q->statb);
y.gid = hostgid(&q->statb);
y.size = q->statb.st_size;
if(isroot(q) && strncmp(buf, ".", x->count)) {
debug2("NROOT %s\n", buf);
y.flags = NROOT;
}
if(x->flags == NDEL) {
debug1("\tnodelete\n");
respond(EPERM);
return;
}
respond(0);
return;
} else {
y.flags = NOMATCH;
if(x->flags == NLINK) {
debug1("\tnolink %d %d %d\n", x->uid,
p->statb.st_uid, p->statb.st_gid);
respond(EPERM);
return;
} else if(x->flags == NCREAT) {
debug1("\tnami creat 0%o %s\n", x->mode, nbuf);
debug1("\tnoaccess\n");
respond(EACCES);
return;
}
respond(ENOENT);
}
}