#include <sys/types.h>#include <sys/stat.h> #include <unistd.h>#include <fcntl.h>#include <err.h> #include <stdlib.h>#include <stdint.h>#include <stdio.h>#include <string.h>#include <stdarg.h>#include <errno.h> #include "libc.h"#include "fcall.h"#include "9pfs.h"#include "util.h" char *calls2str[] = { [Tversion]= "Tversion", [Tauth]= "Tauth", [Tattach]= "Tattach", [Terror]= "Terror", [Tflush]= "Tflush", [Twalk]= "Twalk", [Topen]= "Topen", [Tcreate]= "Tcreate", [Tread]= "Tread", [Twrite]= "Twrite", [Tclunk]= "Tclunk", [Tremove]= "Tremove", [Tstat]= "Tstat", [Twstat]= "Twstat", [Rversion]= "Rversion", [Rauth]= "Rauth", [Rattach]= "Rattach", [Rerror]= "Rerror", [Rflush]= "Rflush", [Rwalk]= "Rwalk", [Ropen]= "Ropen", [Rcreate]= "Rcreate", [Rread]= "Rread", [Rwrite]= "Rwrite", [Rclunk]= "Rclunk", [Rremove]= "Rremove", [Rstat]= "Rstat", [Rwstat]= "Rwstat"}; void *tbuf, *rbuf;FFid *fidhash[NHASH];FDir *dirhash[NHASH]; FFid *lookupfid(u32int, int);FFid *uniqfid(void); voidinit9p(void){ unsigned int seed; int rfd; if((rfd = open("/dev/urandom", O_RDONLY)) == -1) err(1, "Could not open /dev/random"); if(read(rfd, &seed, sizeof(seed)) != sizeof(seed)) err(1, "Bad /dev/random read"); close(rfd); srandom(seed);} static intdo9p(Fcall *t, Fcall *r){ int n; if(t->type == Tversion) t->tag = (ushort)~0; else t->tag = random(); if((n = convS2M(t, tbuf, msize)) == 0){ r->ename = "Bad S2M conversion"; goto err; } if(write(outfd, tbuf, n) != n){ r->ename = "Bad 9p write"; goto err; } if((n = read9pmsg(infd, rbuf, msize)) == -1){ r->ename = "Bad 9p read"; goto err; } if(convM2S(rbuf, n, r) != n){ r->ename = "Bad M2S conversion"; goto err; } if(r->tag != t->tag) errx(1, "tag mismatch"); if(r->type != t->type+1){ r->ename = "Bad 9p reply type"; goto err; } return 0; err: r->type = Rerror; return -1;} int_9pversion(u32int m){ Fcall tver, rver; msize = m; tver.type = Tversion; tver.msize = m; tver.version = VERSION9P; tbuf = erealloc(tbuf, m); rbuf = erealloc(rbuf, m); if(do9p(&tver, &rver) != 0) errx(1, "Could not establish version: %s", rver.ename); if(rver.msize != m){ msize = rver.msize; tbuf = erealloc(tbuf, msize); rbuf = erealloc(rbuf, msize); } return msize;} FFid*_9pauth(u32int afid, char *uname, char *aname){ FFid *f; Fcall tauth, rauth; tauth.type = Tauth; tauth.afid = afid; tauth.uname = uname; tauth.aname = aname; if(do9p(&tauth, &rauth) == -1) errx(1, "Could not establish authentication: %s", rauth.ename); f = lookupfid(afid, PUT); f->path = "AUTHFID"; f->fid = afid; f->qid = rauth.aqid; f->iounit = msize - IOHDRSZ; return f;} FFid*_9pattach(u32int fid, u32int afid, char* uname, char *aname){ FFid *f; Fcall tattach, rattach; tattach.type = Tattach; tattach.fid = fid; tattach.afid = afid; tattach.uname = uname; tattach.aname = aname; if(do9p(&tattach, &rattach) == -1) errx(1, "Could not attach"); f = lookupfid(fid, PUT); f->path = ""; f->fid = fid; f->qid = rattach.qid; return f;} FFid*_9pwalkr(FFid *r, char *path){ FFid *f; Fcall twalk, rwalk; char **s, *buf, *bp; buf = bp = estrdup(path); f = NULL; twalk.type = Twalk; twalk.newfid = r->fid; while(bp != NULL){ FFid *oldf = NULL; for(s = twalk.wname; s < twalk.wname + MAXWELEM && bp != NULL; s++) *s = strsep(&bp, "/"); twalk.fid = twalk.newfid; oldf = f; f = uniqfid(); twalk.newfid = f->fid; twalk.nwname = s - twalk.wname; if(do9p(&twalk, &rwalk) == -1 || rwalk.nwqid < twalk.nwname){ _9pclunk(oldf); if(lookupfid(f->fid, DEL) != FDEL) errx(1, "Fid %d not found in hash", f->fid); free(buf); return NULL; } _9pclunk(oldf); } f->qid = rwalk.wqid[rwalk.nwqid - 1]; free(buf); return f;} FFid*_9pwalk(const char *path){ FFid *f; char *pnew; if(*path == '\0' || strcmp(path, "/") == 0) return fidclone(rootfid); pnew = estrdup(path); if((f = _9pwalkr(rootfid, pnew+1)) == NULL){ free(pnew); return NULL; } f->path = pnew; return f;} Dir*_9pstat(FFid *f){ Dir *d; Fcall tstat, rstat; tstat.type = Tstat; tstat.fid = f->fid; if(do9p(&tstat, &rstat) == -1) return NULL; d = emalloc(sizeof(*d) + rstat.nstat); if(convM2D(rstat.stat, rstat.nstat, d, (char*)(d+1)) != rstat.nstat){ free(d); return NULL; } return d;} int_9pwstat(FFid *f, Dir *d){ Fcall twstat, rwstat; uchar *st; int n; n = sizeD2M(d); st = emalloc(n); if(convD2M(d, st, n) != n){ free(st); return -1; } twstat.type = Twstat; twstat.fid = f->fid; twstat.nstat = n; twstat.stat = st; if(do9p(&twstat, &rwstat) == -1){ free(st); return -1; } free(st); return 0;} int_9popen(FFid *f){ Fcall topen, ropen; topen.type = Topen; topen.fid = f->fid; topen.mode = f->mode; if(do9p(&topen, &ropen) == -1) return -1; f->qid = ropen.qid; if(ropen.iounit != 0 && ropen.iounit < msize) f->iounit = ropen.iounit; else f->iounit = msize; f->iounit -= IOHDRSZ; return 0;} FFid*_9pcreate(FFid *f, char *name, int perm, int isdir){ Fcall tcreate, rcreate; perm &= 0777; if(isdir) perm |= DMDIR; tcreate.type = Tcreate; tcreate.fid = f->fid; tcreate.name = name; tcreate.perm = perm; tcreate.mode = f->mode; if(do9p(&tcreate, &rcreate) == -1){ _9pclunk(f); return NULL; } if(rcreate.iounit != 0 && rcreate.iounit < msize) f->iounit = rcreate.iounit; else f->iounit = msize; f->iounit -= IOHDRSZ; f->qid = rcreate.qid; return f;} int_9premove(FFid *f){ Fcall tremove, rremove; if(f == NULL) return 0; tremove.type = Tremove; tremove.fid = f->fid; if(do9p(&tremove, &rremove) == -1){ _9pclunk(f); return -1; } if(lookupfid(f->fid, DEL) != FDEL) errx(1, "Fid %d not found in hash", f->fid); return 0;} static longdirpackage(uchar *buf, long ts, Dir **d){ char *s; long ss, i, n, nn, m; *d = nil; if(ts <= 0) return 0; /* * first find number of all stats, check they look like stats, & size all associated strings */ ss = 0; n = 0; for(i = 0; i < ts; i += m){ m = BIT16SZ + GBIT16(&buf[i]); if(statcheck(&buf[i], m) < 0) break; ss += m; n++; } if(i != ts) return -1; *d = malloc(n * sizeof(Dir) + ss); if(*d == nil) return -1; /* * then convert all buffers */ s = (char*)*d + n * sizeof(Dir); nn = 0; for(i = 0; i < ts; i += m){ m = BIT16SZ + GBIT16((uchar*)&buf[i]); if(nn >= n || convM2D(&buf[i], m, *d + nn, s) != m){ free(*d); *d = nil; return -1; } nn++; s += m; } return nn;} intdircmp(const void *v1, const void *v2){ return strcmp(((Dir*)v1)->name, ((Dir*)v2)->name);} long_9pdirread(FFid *f, Dir **d){ FDir *fdir; char *buf; int t; u32int n; long bufsize, r; DPRINT("_9pdirread on %s\n", f->path); n = f->iounit; bufsize = DIRMAX; buf = emalloc(bufsize); r = 0; while((t = _9pread(f, buf+r, n)) > 0){ r += t; if(r > bufsize - n){ bufsize += DIRMAX; buf = erealloc(buf, bufsize); } } if(r <= 0){ free(buf); return r; } r = dirpackage((uchar*)buf, r, d); fdir = lookupdir(f->path, PUT); fdir->dirs = *d; fdir->ndirs = r; qsort(fdir->dirs, fdir->ndirs, sizeof(*fdir->dirs), dircmp); free(buf); return r;} int_9pread(FFid *f, char *buf, u32int n){ Fcall tread, rread; u32int tot; if(n == 0) return 0; tread.type = Tread; tread.fid = f->fid; tot = 0; while(n > 0){ DPRINT("_9pread n is %d\n", n); tread.offset = f->offset; tread.count = n < f->iounit ? n : f->iounit; if(do9p(&tread, &rread) == -1) { DPRINT("_9pread encountered error: %s\n", rread.ename); return -1; } memcpy(buf+tot, rread.data, rread.count); f->offset += rread.count; tot += rread.count; if(rread.count < tread.count) break; n -= rread.count; } DPRINT("_9pread ending n is %d, tot is %d\n", n, tot); return tot;} int_9pwrite(FFid *f, char *buf, u32int n){ Fcall twrite, rwrite; u32int tot; if(n == 0) return 0; twrite.type = Twrite; twrite.fid = f->fid; tot = 0; while(n > 0){ DPRINT("_9pwrite n is %d\n", n); twrite.offset = f->offset; twrite.count = n < f->iounit ? n : f->iounit; twrite.data = buf+tot; if(do9p(&twrite, &rwrite) == -1) return -1; f->offset += rwrite.count; tot += rwrite.count; if(rwrite.count < twrite.count) break; n -= rwrite.count; } DPRINT("_9pwrite ending n is %d, tot is %d\n", n, tot); return tot;} int_9pclunk(FFid *f){ Fcall tclunk, rclunk; if(f == NULL) return 0; tclunk.type = Tclunk; tclunk.fid = f->fid; if(lookupfid(f->fid, DEL) != FDEL) errx(1, "Fid %d not found in hash", f->fid); return do9p(&tclunk, &rclunk);} FFid*uniqfid(void){ FFid *f; u32int fid; do fid = random(); while((f = lookupfid(fid, PUT)) == NULL); return f;} Lines 1–500 of 610. Load more
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <err.h> #include <stdlib.h> #include <stdint.h> #include <stdio.h> #include <string.h> #include <stdarg.h> #include <errno.h> #include "libc.h" #include "fcall.h" #include "9pfs.h" #include "util.h" char *calls2str[] = { [Tversion]= "Tversion", [Tauth]= "Tauth", [Tattach]= "Tattach", [Terror]= "Terror", [Tflush]= "Tflush", [Twalk]= "Twalk", [Topen]= "Topen", [Tcreate]= "Tcreate", [Tread]= "Tread", [Twrite]= "Twrite", [Tclunk]= "Tclunk", [Tremove]= "Tremove", [Tstat]= "Tstat", [Twstat]= "Twstat", [Rversion]= "Rversion", [Rauth]= "Rauth", [Rattach]= "Rattach", [Rerror]= "Rerror", [Rflush]= "Rflush", [Rwalk]= "Rwalk", [Ropen]= "Ropen", [Rcreate]= "Rcreate", [Rread]= "Rread", [Rwrite]= "Rwrite", [Rclunk]= "Rclunk", [Rremove]= "Rremove", [Rstat]= "Rstat", [Rwstat]= "Rwstat" }; void *tbuf, *rbuf; FFid *fidhash[NHASH]; FDir *dirhash[NHASH]; FFid *lookupfid(u32int, int); FFid *uniqfid(void); void init9p(void) { unsigned int seed; int rfd; if((rfd = open("/dev/urandom", O_RDONLY)) == -1) err(1, "Could not open /dev/random"); if(read(rfd, &seed, sizeof(seed)) != sizeof(seed)) err(1, "Bad /dev/random read"); close(rfd); srandom(seed); } static int do9p(Fcall *t, Fcall *r) { int n; if(t->type == Tversion) t->tag = (ushort)~0; else t->tag = random(); if((n = convS2M(t, tbuf, msize)) == 0){ r->ename = "Bad S2M conversion"; goto err; } if(write(outfd, tbuf, n) != n){ r->ename = "Bad 9p write"; goto err; } if((n = read9pmsg(infd, rbuf, msize)) == -1){ r->ename = "Bad 9p read"; goto err; } if(convM2S(rbuf, n, r) != n){ r->ename = "Bad M2S conversion"; goto err; } if(r->tag != t->tag) errx(1, "tag mismatch"); if(r->type != t->type+1){ r->ename = "Bad 9p reply type"; goto err; } return 0; err: r->type = Rerror; return -1; } int _9pversion(u32int m) { Fcall tver, rver; msize = m; tver.type = Tversion; tver.msize = m; tver.version = VERSION9P; tbuf = erealloc(tbuf, m); rbuf = erealloc(rbuf, m); if(do9p(&tver, &rver) != 0) errx(1, "Could not establish version: %s", rver.ename); if(rver.msize != m){ msize = rver.msize; tbuf = erealloc(tbuf, msize); rbuf = erealloc(rbuf, msize); } return msize; } FFid* _9pauth(u32int afid, char *uname, char *aname) { FFid *f; Fcall tauth, rauth; tauth.type = Tauth; tauth.afid = afid; tauth.uname = uname; tauth.aname = aname; if(do9p(&tauth, &rauth) == -1) errx(1, "Could not establish authentication: %s", rauth.ename); f = lookupfid(afid, PUT); f->path = "AUTHFID"; f->fid = afid; f->qid = rauth.aqid; f->iounit = msize - IOHDRSZ; return f; } FFid* _9pattach(u32int fid, u32int afid, char* uname, char *aname) { FFid *f; Fcall tattach, rattach; tattach.type = Tattach; tattach.fid = fid; tattach.afid = afid; tattach.uname = uname; tattach.aname = aname; if(do9p(&tattach, &rattach) == -1) errx(1, "Could not attach"); f = lookupfid(fid, PUT); f->path = ""; f->fid = fid; f->qid = rattach.qid; return f; } FFid* _9pwalkr(FFid *r, char *path) { FFid *f; Fcall twalk, rwalk; char **s, *buf, *bp; buf = bp = estrdup(path); f = NULL; twalk.type = Twalk; twalk.newfid = r->fid; while(bp != NULL){ FFid *oldf = NULL; for(s = twalk.wname; s < twalk.wname + MAXWELEM && bp != NULL; s++) *s = strsep(&bp, "/"); twalk.fid = twalk.newfid; oldf = f; f = uniqfid(); twalk.newfid = f->fid; twalk.nwname = s - twalk.wname; if(do9p(&twalk, &rwalk) == -1 || rwalk.nwqid < twalk.nwname){ _9pclunk(oldf); if(lookupfid(f->fid, DEL) != FDEL) errx(1, "Fid %d not found in hash", f->fid); free(buf); return NULL; } _9pclunk(oldf); } f->qid = rwalk.wqid[rwalk.nwqid - 1]; free(buf); return f; } FFid* _9pwalk(const char *path) { FFid *f; char *pnew; if(*path == '\0' || strcmp(path, "/") == 0) return fidclone(rootfid); pnew = estrdup(path); if((f = _9pwalkr(rootfid, pnew+1)) == NULL){ free(pnew); return NULL; } f->path = pnew; return f; } Dir* _9pstat(FFid *f) { Dir *d; Fcall tstat, rstat; tstat.type = Tstat; tstat.fid = f->fid; if(do9p(&tstat, &rstat) == -1) return NULL; d = emalloc(sizeof(*d) + rstat.nstat); if(convM2D(rstat.stat, rstat.nstat, d, (char*)(d+1)) != rstat.nstat){ free(d); return NULL; } return d; } int _9pwstat(FFid *f, Dir *d) { Fcall twstat, rwstat; uchar *st; int n; n = sizeD2M(d); st = emalloc(n); if(convD2M(d, st, n) != n){ free(st); return -1; } twstat.type = Twstat; twstat.fid = f->fid; twstat.nstat = n; twstat.stat = st; if(do9p(&twstat, &rwstat) == -1){ free(st); return -1; } free(st); return 0; } int _9popen(FFid *f) { Fcall topen, ropen; topen.type = Topen; topen.fid = f->fid; topen.mode = f->mode; if(do9p(&topen, &ropen) == -1) return -1; f->qid = ropen.qid; if(ropen.iounit != 0 && ropen.iounit < msize) f->iounit = ropen.iounit; else f->iounit = msize; f->iounit -= IOHDRSZ; return 0; } FFid* _9pcreate(FFid *f, char *name, int perm, int isdir) { Fcall tcreate, rcreate; perm &= 0777; if(isdir) perm |= DMDIR; tcreate.type = Tcreate; tcreate.fid = f->fid; tcreate.name = name; tcreate.perm = perm; tcreate.mode = f->mode; if(do9p(&tcreate, &rcreate) == -1){ _9pclunk(f); return NULL; } if(rcreate.iounit != 0 && rcreate.iounit < msize) f->iounit = rcreate.iounit; else f->iounit = msize; f->iounit -= IOHDRSZ; f->qid = rcreate.qid; return f; } int _9premove(FFid *f) { Fcall tremove, rremove; if(f == NULL) return 0; tremove.type = Tremove; tremove.fid = f->fid; if(do9p(&tremove, &rremove) == -1){ _9pclunk(f); return -1; } if(lookupfid(f->fid, DEL) != FDEL) errx(1, "Fid %d not found in hash", f->fid); return 0; } static long dirpackage(uchar *buf, long ts, Dir **d) { char *s; long ss, i, n, nn, m; *d = nil; if(ts <= 0) return 0; /* * first find number of all stats, check they look like stats, & size all associated strings */ ss = 0; n = 0; for(i = 0; i < ts; i += m){ m = BIT16SZ + GBIT16(&buf[i]); if(statcheck(&buf[i], m) < 0) break; ss += m; n++; } if(i != ts) return -1; *d = malloc(n * sizeof(Dir) + ss); if(*d == nil) return -1; /* * then convert all buffers */ s = (char*)*d + n * sizeof(Dir); nn = 0; for(i = 0; i < ts; i += m){ m = BIT16SZ + GBIT16((uchar*)&buf[i]); if(nn >= n || convM2D(&buf[i], m, *d + nn, s) != m){ free(*d); *d = nil; return -1; } nn++; s += m; } return nn; } int dircmp(const void *v1, const void *v2) { return strcmp(((Dir*)v1)->name, ((Dir*)v2)->name); } long _9pdirread(FFid *f, Dir **d) { FDir *fdir; char *buf; int t; u32int n; long bufsize, r; DPRINT("_9pdirread on %s\n", f->path); n = f->iounit; bufsize = DIRMAX; buf = emalloc(bufsize); r = 0; while((t = _9pread(f, buf+r, n)) > 0){ r += t; if(r > bufsize - n){ bufsize += DIRMAX; buf = erealloc(buf, bufsize); } } if(r <= 0){ free(buf); return r; } r = dirpackage((uchar*)buf, r, d); fdir = lookupdir(f->path, PUT); fdir->dirs = *d; fdir->ndirs = r; qsort(fdir->dirs, fdir->ndirs, sizeof(*fdir->dirs), dircmp); free(buf); return r; } int _9pread(FFid *f, char *buf, u32int n) { Fcall tread, rread; u32int tot; if(n == 0) return 0; tread.type = Tread; tread.fid = f->fid; tot = 0; while(n > 0){ DPRINT("_9pread n is %d\n", n); tread.offset = f->offset; tread.count = n < f->iounit ? n : f->iounit; if(do9p(&tread, &rread) == -1) { DPRINT("_9pread encountered error: %s\n", rread.ename); return -1; } memcpy(buf+tot, rread.data, rread.count); f->offset += rread.count; tot += rread.count; if(rread.count < tread.count) break; n -= rread.count; } DPRINT("_9pread ending n is %d, tot is %d\n", n, tot); return tot; } int _9pwrite(FFid *f, char *buf, u32int n) { Fcall twrite, rwrite; u32int tot; if(n == 0) return 0; twrite.type = Twrite; twrite.fid = f->fid; tot = 0; while(n > 0){ DPRINT("_9pwrite n is %d\n", n); twrite.offset = f->offset; twrite.count = n < f->iounit ? n : f->iounit; twrite.data = buf+tot; if(do9p(&twrite, &rwrite) == -1) return -1; f->offset += rwrite.count; tot += rwrite.count; if(rwrite.count < twrite.count) break; n -= rwrite.count; } DPRINT("_9pwrite ending n is %d, tot is %d\n", n, tot); return tot; } int _9pclunk(FFid *f) { Fcall tclunk, rclunk; if(f == NULL) return 0; tclunk.type = Tclunk; tclunk.fid = f->fid; if(lookupfid(f->fid, DEL) != FDEL) errx(1, "Fid %d not found in hash", f->fid); return do9p(&tclunk, &rclunk); } FFid* uniqfid(void) { FFid *f; u32int fid; do fid = random(); while((f = lookupfid(fid, PUT)) == NULL); return f; }