#include <stdint.h>#include <string.h>#include "c9/proto.h"#include "c9/fs.h"#include "c9/fs9p.h" enum{ Flinit = 1<<0, Flerror = 1<<1, F9init = 0, F9chdir, F9open, F9create, F9read, F9readdir, F9write, F9seek, F9stat, F9fstat, F9close, F9remove, F9rename,}; static const FS9pfd freefd ={ .offset = ~0ULL,}; #define isfree(fd) ((fd).offset == ~0ULL) static const char *f2s[] ={ [F9init] = "init", [F9chdir] = "chdir", [F9open] = "open", [F9create] = "create", [F9read] = "read", [F9readdir] = "readdir", [F9write] = "write", [F9seek] = "seek", [F9stat] = "stat", [F9fstat] = "fstat", [F9close] = "close", [F9remove] = "remove", [F9rename] = "rename",}; static intfs9pchdir(FS *fs, const char *path){ FS9p *aux = (void*)fs->aux; aux->f = F9chdir; return -1;} static intfs9popen(FS *fs, const char *name, FSmode mode){ FS9p *aux = (void*)fs->aux; aux->f = F9open; return -1;} static intfs9pcreate(FS *fs, const char *path, int perm){ FS9p *aux = (void*)fs->aux; aux->f = F9create; return -1;} static int64_tfs9pread(FS *fs, int fd, void *buf, uint64_t count){ FS9p *aux = (void*)fs->aux; aux->f = F9read; return -1;} static int64_tfs9preaddir(FS *fs, int fd, FSstat *st, int nst){ FS9p *aux = (void*)fs->aux; aux->f = F9readdir; return -1;} static int64_tfs9pwrite(FS *fs, int fd, const void *buf, uint64_t count){ FS9p *aux = (void*)fs->aux; aux->f = F9write; return -1;} static int64_tfs9pseek(FS *fs, int fd, int64_t offset, int whence){ FS9p *aux = (void*)fs->aux; aux->f = F9seek; return -1;} static intfs9pstat(FS *fs, const char *path, FSstat *st){ FS9p *aux = (void*)fs->aux; aux->f = F9stat; return -1;} static intfs9pfstat(FS *fs, int fd, FSstat *st){ FS9p *aux = (void*)fs->aux; C9tag tag; int e; aux->f = F9fstat; aux->p = st; if((e = c9stat(aux->ctx, &tag, fd)) < 0) return e; while(aux->f != -F9fstat) c9proc(aux->ctx); return 0;} static intfs9pclose(FS *fs, int fd){ FS9p *aux = (void*)fs->aux; aux->f = F9close; return -1;} static intfs9premove(FS *fs, const char *name){ FS9p *aux = (void*)fs->aux; aux->f = F9remove; return -1;} static intfs9prename(FS *fs, const char *oldpath, const char *newpath){ FS9p *aux = (void*)fs->aux; aux->f = F9rename; return -1;} static voidfs9pr(C9ctx *ctx, C9r *r){ FSstat *st; C9tag tag; FS9p *aux; FS *fs; fs = ctx->paux; aux = (void*)fs->aux; switch(r->type){ case Rversion: c9attach(ctx, &tag, FS9proot, C9nofid, "none", NULL); /* FIXME those need to be configurable */ break; case Rauth: break; case Rattach: aux->flags |= Flinit; break; case Rerror: fs->error(fs, "%s: %s", f2s[aux->f], r->error); aux->flags |= Flerror; break; case Rflush: break; case Rwalk: break; case Ropen: break; case Rcreate: break; case Rread: break; case Rwrite: break; case Rclunk: break; case Rremove: break; case Rstat: if(aux->f == F9stat || aux->f == F9fstat){ st = aux->p; st->size = r->stat.size; st->name = r->stat.name; st->uid = r->stat.uid; st->gid = r->stat.gid; st->mode = r->stat.mode; st->mtime = r->stat.mtime; aux->f = -aux->f; } break; case Rwstat: break; }} intfs9pinit(FS *fs, uint32_t msize){ FS9p *aux = (void*)fs->aux; C9error err; C9tag tag; int i; if(fs->error == NULL) return -1; if(aux == NULL || aux->ctx == NULL || aux->fds == NULL || aux->numfds < 1){ fs->error(fs, "fs9pinit: invalid aux"); return -1; } if(aux->ctx == NULL){ fs->error(fs, "fs9pinit: invalid ctx"); return -1; } fs->chdir = fs9pchdir; fs->open = fs9popen; fs->create = fs9pcreate; fs->read = fs9pread; fs->readdir = fs9preaddir; fs->write = fs9pwrite; fs->seek = fs9pseek; fs->stat = fs9pstat; fs->fstat = fs9pfstat; fs->close = fs9pclose; fs->remove = fs9premove; fs->rename = fs9prename; aux->root.offset = 0; for(i = 0; i < aux->numfds; i++) aux->fds[i] = freefd; aux->ctx->r = fs9pr; aux->ctx->paux = fs; aux->f = F9init; aux->flags = 0; if((err = c9version(aux->ctx, &tag, msize)) != 0) return err; for(;;){ if((err = c9proc(aux->ctx)) != 0) return err; if(aux->flags & Flerror) return -1; if(aux->flags & Flinit) break; } return 0;}
#include <stdint.h>
#include <string.h>
#include "c9/proto.h"
#include "c9/fs.h"
#include "c9/fs9p.h"
enum
{
Flinit = 1<<0,
Flerror = 1<<1,
F9init = 0,
F9chdir,
F9open,
F9create,
F9read,
F9readdir,
F9write,
F9seek,
F9stat,
F9fstat,
F9close,
F9remove,
F9rename,
};
static const FS9pfd freefd =
{
.offset = ~0ULL,
};
#define isfree(fd) ((fd).offset == ~0ULL)
static const char *f2s[] =
{
[F9init] = "init",
[F9chdir] = "chdir",
[F9open] = "open",
[F9create] = "create",
[F9read] = "read",
[F9readdir] = "readdir",
[F9write] = "write",
[F9seek] = "seek",
[F9stat] = "stat",
[F9fstat] = "fstat",
[F9close] = "close",
[F9remove] = "remove",
[F9rename] = "rename",
};
static int
fs9pchdir(FS *fs, const char *path)
{
FS9p *aux = (void*)fs->aux;
aux->f = F9chdir;
return -1;
}
static int
fs9popen(FS *fs, const char *name, FSmode mode)
{
FS9p *aux = (void*)fs->aux;
aux->f = F9open;
return -1;
}
static int
fs9pcreate(FS *fs, const char *path, int perm)
{
FS9p *aux = (void*)fs->aux;
aux->f = F9create;
return -1;
}
static int64_t
fs9pread(FS *fs, int fd, void *buf, uint64_t count)
{
FS9p *aux = (void*)fs->aux;
aux->f = F9read;
return -1;
}
static int64_t
fs9preaddir(FS *fs, int fd, FSstat *st, int nst)
{
FS9p *aux = (void*)fs->aux;
aux->f = F9readdir;
return -1;
}
static int64_t
fs9pwrite(FS *fs, int fd, const void *buf, uint64_t count)
{
FS9p *aux = (void*)fs->aux;
aux->f = F9write;
return -1;
}
static int64_t
fs9pseek(FS *fs, int fd, int64_t offset, int whence)
{
FS9p *aux = (void*)fs->aux;
aux->f = F9seek;
return -1;
}
static int
fs9pstat(FS *fs, const char *path, FSstat *st)
{
FS9p *aux = (void*)fs->aux;
aux->f = F9stat;
return -1;
}
static int
fs9pfstat(FS *fs, int fd, FSstat *st)
{
FS9p *aux = (void*)fs->aux;
C9tag tag;
int e;
aux->f = F9fstat;
aux->p = st;
if((e = c9stat(aux->ctx, &tag, fd)) < 0)
return e;
while(aux->f != -F9fstat)
c9proc(aux->ctx);
return 0;
}
static int
fs9pclose(FS *fs, int fd)
{
FS9p *aux = (void*)fs->aux;
aux->f = F9close;
return -1;
}
static int
fs9premove(FS *fs, const char *name)
{
FS9p *aux = (void*)fs->aux;
aux->f = F9remove;
return -1;
}
static int
fs9prename(FS *fs, const char *oldpath, const char *newpath)
{
FS9p *aux = (void*)fs->aux;
aux->f = F9rename;
return -1;
}
static void
fs9pr(C9ctx *ctx, C9r *r)
{
FSstat *st;
C9tag tag;
FS9p *aux;
FS *fs;
fs = ctx->paux;
aux = (void*)fs->aux;
switch(r->type){
case Rversion:
c9attach(ctx, &tag, FS9proot, C9nofid, "none", NULL); /* FIXME those need to be configurable */
break;
case Rauth:
break;
case Rattach:
aux->flags |= Flinit;
break;
case Rerror:
fs->error(fs, "%s: %s", f2s[aux->f], r->error);
aux->flags |= Flerror;
break;
case Rflush:
break;
case Rwalk:
break;
case Ropen:
break;
case Rcreate:
break;
case Rread:
break;
case Rwrite:
break;
case Rclunk:
break;
case Rremove:
break;
case Rstat:
if(aux->f == F9stat || aux->f == F9fstat){
st = aux->p;
st->size = r->stat.size;
st->name = r->stat.name;
st->uid = r->stat.uid;
st->gid = r->stat.gid;
st->mode = r->stat.mode;
st->mtime = r->stat.mtime;
aux->f = -aux->f;
}
break;
case Rwstat:
break;
}
}
int
fs9pinit(FS *fs, uint32_t msize)
{
FS9p *aux = (void*)fs->aux;
C9error err;
C9tag tag;
int i;
if(fs->error == NULL)
return -1;
if(aux == NULL || aux->ctx == NULL || aux->fds == NULL || aux->numfds < 1){
fs->error(fs, "fs9pinit: invalid aux");
return -1;
}
if(aux->ctx == NULL){
fs->error(fs, "fs9pinit: invalid ctx");
return -1;
}
fs->chdir = fs9pchdir;
fs->open = fs9popen;
fs->create = fs9pcreate;
fs->read = fs9pread;
fs->readdir = fs9preaddir;
fs->write = fs9pwrite;
fs->seek = fs9pseek;
fs->stat = fs9pstat;
fs->fstat = fs9pfstat;
fs->close = fs9pclose;
fs->remove = fs9premove;
fs->rename = fs9prename;
aux->root.offset = 0;
for(i = 0; i < aux->numfds; i++)
aux->fds[i] = freefd;
aux->ctx->r = fs9pr;
aux->ctx->paux = fs;
aux->f = F9init;
aux->flags = 0;
if((err = c9version(aux->ctx, &tag, msize)) != 0)
return err;
for(;;){
if((err = c9proc(aux->ctx)) != 0)
return err;
if(aux->flags & Flerror)
return -1;
if(aux->flags & Flinit)
break;
}
return 0;
}