henesyinit from lsubb0c8bdb6 years agoHistory
298 lines · 4.8 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <fcall.h>#include <auth.h>#include <thread.h>#include <9p.h>#include <b.h> typedef struct Ramfile	Ramfile; struct Ramfile {	char*	data;	int	ndata;};  static char	Ebad[] = "something bad happened";static char	Enomem[] = "no memory";static char*	addr;static char*	vname; static voidfsattach(Req* r){	if (r->srv->auth != nil && authattach(r) < 0)		return;	respond(r, nil);} static voidfsopen(Req* r){	Ramfile*rf;	File*	file; 	if (r->fid->qid.type&QTAUTH)		sysfatal("fsopen for an AUTH file. fixme: add respond/return\n");	file = r->fid->file;	if (r->ifcall.mode&OTRUNC){		rf = file->aux;		if(rf){			rf->ndata = 0;			file->length = 0;		}	}	respond(r, nil);} static voidfscreate(Req* r){	File *file;	char* name;	char* uid;	int mode;	Ramfile *rf;	File* f; 	file = r->fid->file;	name = r->ifcall.name;	uid = r->fid->uid;	mode = r->fid->file->mode & 0x777 & r->ifcall.perm;	mode |= (r->ifcall.perm & ~0x777);	if(f = createfile(file, name, uid, mode, 0)){		rf = emalloc9p(sizeof *rf);		f->aux = rf;		closefile(r->fid->file);		r->fid->file = f;		r->ofcall.qid = f->qid;		respond(r, nil);	} else		responderror(r);} static voidfsread(Req* r){	File* file;	long count;	vlong offset;	Ramfile*rf; 	if (r->fid->qid.type&QTAUTH){		authread(r);		return;	}	file = r->fid->file;	rf = file->aux;	offset = r->ifcall.offset;	count = r->ifcall.count;	if (offset >= rf->ndata){		count = 0;	} else {		if(offset+count >= rf->ndata)			count = rf->ndata - offset;		memmove(r->ofcall.data, rf->data+offset, count);	}	r->ofcall.count = count;	respond(r, nil);} static voidfswrite(Req* r){	File*	file;	long	count;	vlong	offset;	Ramfile*rf;	void*	v; 	if (r->fid->qid.type&QTAUTH){		authwrite(r);		return;	}	file = r->fid->file;	rf = file->aux;	offset = r->ifcall.offset;	count = r->ifcall.count;	if(offset+count >= rf->ndata){		v = realloc(rf->data, offset+count);		if(v == nil){			respond(r, Enomem);			return;		} else {			rf->data = v;			rf->ndata = offset+count;			file->length = rf->ndata;		}	}	if (r->ofcall.count = count)		memmove(rf->data+offset, r->ifcall.data, count);	respond(r, nil);} static voidfswstat(Req* r){	if (r->d.name && r->d.name[0] && strcmp(r->fid->file->name, r->d.name)){		free(r->fid->file->name);		r->fid->file->name = estrdup9p(r->d.name);	}	if (r->d.uid && r->d.uid[0]){		free(r->fid->file->uid);		r->fid->file->uid = estrdup9p(r->d.uid);	}	if (r->d.gid && r->d.gid[0]){		free(r->fid->file->gid);		r->fid->file->gid = estrdup9p(r->d.gid);	}	if (~(ulong)r->d.mode)		r->fid->file->mode = r->d.mode;	respond(r, nil);} static voidfsclunk(Fid* fid){ 	if (fid->qid.type&QTAUTH)		authdestroy(fid);} static intislocal(char* addr){	static char*	l = nil;	if (addr == nil)		return 1;	if (!strncmp(addr, "::", 2) || !strncmp(addr, "127.0.0.1", 8))		return 1;	if (l == nil)		l = getenv("sysaddr");	if (l && !strncmp(addr, l, strlen(l)))		return 1;	return 0;} static voidbauth9p(Req* r){	if (islocal(r->srv->addr)) {		r->srv->auth = nil;	// no auth here any more		respond(r, "auth no required for local peers");	} else		auth9p(r);} static Srv sfs={	.auth	=	bauth9p,	.attach	=	fsattach,	.open	=	fsopen,	.create	=	fscreate,	.read	=	fsread,	.wstat	=	fswstat,	.write	=	fswrite,	.destroyfid = 	fsclunk,}; static voidfreefile(File *f){	Ramfile *rf; 	rf = f->aux;	if(rf){		f->aux = nil;		free(rf->data);		free(rf);	}} static voidannounceproc(void*){	int	afd = -1;	char*	cnstr; 	cnstr = strchr(vname, ' ');	if (cnstr)		*cnstr++ = 0; 	for(;;){		afd = announcevol(afd, addr, vname, cnstr);		sleep(10 * 1000);	}} voidusage(void){	fprint(2, "usage: %s [-abcAD] [-s srv] [-m mnt] [-n addr] [-V vol]\n", argv0);	exits("usage");}  voidthreadmain(int argc, char **argv){	char*	mnt;	char*	srv;	int	mflag; 	srv = nil;	mnt = nil;	mflag = MREPL|MCREATE;	ARGBEGIN{	case 'a':		mflag = MAFTER|MCREATE;		break;	case 'b':		mflag = MBEFORE|MCREATE;		break;	case 'c':		mflag = MREPL|MCREATE;		break;	case 'A':		sfs.auth = nil;		break;	case 'd':		chatty9p++;		break;	case 's':		srv = EARGF(usage());		break;	case 'm':		mnt = EARGF(usage());		break;	case 'n':		addr = EARGF(usage());		break;	case 'V':		vname = EARGF(usage());		break;	default:		usage();	}ARGEND; 	if(argc!= 0)		usage();	if (getenv("local"))		sfs.auth = nil;	if (srv == nil && mnt == nil && addr == nil){		sfs.auth = nil;		mnt = "/tmp";	}	if (!chatty9p)		rfork(RFNOTEG);	sfs.tree =  alloctree(nil, nil, DMDIR|0755, freefile);	if (addr != nil){		threadlistensrv(&sfs, addr);	}	if (srv != nil || mnt != nil)		threadpostmountsrv(&sfs, srv, mnt, mflag);	if (addr != nil && vname != nil)		proccreate(announceproc, 0, 8*1024);	threadexits(nil);}