xref: /plan9/sys/src/lib9p/ramfs.c (revision 22a127bbfe4dd304949cc596400de973c0138e31)
13ff48bf5SDavid du Colombier #include <u.h>
23ff48bf5SDavid du Colombier #include <libc.h>
33ff48bf5SDavid du Colombier #include <auth.h>
43ff48bf5SDavid du Colombier #include <fcall.h>
53ff48bf5SDavid du Colombier #include <thread.h>
63ff48bf5SDavid du Colombier #include <9p.h>
73ff48bf5SDavid du Colombier 
83ff48bf5SDavid du Colombier static char Ebad[] = "something bad happened";
93ff48bf5SDavid du Colombier static char Enomem[] = "no memory";
103ff48bf5SDavid du Colombier 
113ff48bf5SDavid du Colombier typedef struct Ramfile	Ramfile;
123ff48bf5SDavid du Colombier struct Ramfile {
133ff48bf5SDavid du Colombier 	char *data;
143ff48bf5SDavid du Colombier 	int ndata;
153ff48bf5SDavid du Colombier };
163ff48bf5SDavid du Colombier 
173ff48bf5SDavid du Colombier void
fsread(Req * r)183ff48bf5SDavid du Colombier fsread(Req *r)
193ff48bf5SDavid du Colombier {
203ff48bf5SDavid du Colombier 	Ramfile *rf;
213ff48bf5SDavid du Colombier 	vlong offset;
223ff48bf5SDavid du Colombier 	long count;
233ff48bf5SDavid du Colombier 
243ff48bf5SDavid du Colombier 	rf = r->fid->file->aux;
253ff48bf5SDavid du Colombier 	offset = r->ifcall.offset;
263ff48bf5SDavid du Colombier 	count = r->ifcall.count;
273ff48bf5SDavid du Colombier 
283ff48bf5SDavid du Colombier //print("read %ld %lld\n", *count, offset);
293ff48bf5SDavid du Colombier 	if(offset >= rf->ndata){
303ff48bf5SDavid du Colombier 		r->ofcall.count = 0;
313ff48bf5SDavid du Colombier 		respond(r, nil);
323ff48bf5SDavid du Colombier 		return;
333ff48bf5SDavid du Colombier 	}
343ff48bf5SDavid du Colombier 
353ff48bf5SDavid du Colombier 	if(offset+count >= rf->ndata)
363ff48bf5SDavid du Colombier 		count = rf->ndata - offset;
373ff48bf5SDavid du Colombier 
383ff48bf5SDavid du Colombier 	memmove(r->ofcall.data, rf->data+offset, count);
393ff48bf5SDavid du Colombier 	r->ofcall.count = count;
403ff48bf5SDavid du Colombier 	respond(r, nil);
413ff48bf5SDavid du Colombier }
423ff48bf5SDavid du Colombier 
433ff48bf5SDavid du Colombier void
fswrite(Req * r)443ff48bf5SDavid du Colombier fswrite(Req *r)
453ff48bf5SDavid du Colombier {
463ff48bf5SDavid du Colombier 	void *v;
473ff48bf5SDavid du Colombier 	Ramfile *rf;
483ff48bf5SDavid du Colombier 	vlong offset;
493ff48bf5SDavid du Colombier 	long count;
503ff48bf5SDavid du Colombier 
513ff48bf5SDavid du Colombier 	rf = r->fid->file->aux;
523ff48bf5SDavid du Colombier 	offset = r->ifcall.offset;
533ff48bf5SDavid du Colombier 	count = r->ifcall.count;
543ff48bf5SDavid du Colombier 
553ff48bf5SDavid du Colombier 	if(offset+count >= rf->ndata){
563ff48bf5SDavid du Colombier 		v = realloc(rf->data, offset+count);
573ff48bf5SDavid du Colombier 		if(v == nil){
583ff48bf5SDavid du Colombier 			respond(r, Enomem);
593ff48bf5SDavid du Colombier 			return;
603ff48bf5SDavid du Colombier 		}
613ff48bf5SDavid du Colombier 		rf->data = v;
623ff48bf5SDavid du Colombier 		rf->ndata = offset+count;
633ff48bf5SDavid du Colombier 		r->fid->file->length = rf->ndata;
643ff48bf5SDavid du Colombier 	}
653ff48bf5SDavid du Colombier 	memmove(rf->data+offset, r->ifcall.data, count);
663ff48bf5SDavid du Colombier 	r->ofcall.count = count;
673ff48bf5SDavid du Colombier 	respond(r, nil);
683ff48bf5SDavid du Colombier }
693ff48bf5SDavid du Colombier 
703ff48bf5SDavid du Colombier void
fscreate(Req * r)713ff48bf5SDavid du Colombier fscreate(Req *r)
723ff48bf5SDavid du Colombier {
733ff48bf5SDavid du Colombier 	Ramfile *rf;
743ff48bf5SDavid du Colombier 	File *f;
753ff48bf5SDavid du Colombier 
763ff48bf5SDavid du Colombier 	if(f = createfile(r->fid->file, r->ifcall.name, r->fid->uid, r->ifcall.perm, nil)){
773ff48bf5SDavid du Colombier 		rf = emalloc9p(sizeof *rf);
783ff48bf5SDavid du Colombier 		f->aux = rf;
793ff48bf5SDavid du Colombier 		r->fid->file = f;
803ff48bf5SDavid du Colombier 		r->ofcall.qid = f->qid;
813ff48bf5SDavid du Colombier 		respond(r, nil);
823ff48bf5SDavid du Colombier 		return;
833ff48bf5SDavid du Colombier 	}
843ff48bf5SDavid du Colombier 	respond(r, Ebad);
853ff48bf5SDavid du Colombier }
863ff48bf5SDavid du Colombier 
873ff48bf5SDavid du Colombier void
fsopen(Req * r)883ff48bf5SDavid du Colombier fsopen(Req *r)
893ff48bf5SDavid du Colombier {
903ff48bf5SDavid du Colombier 	Ramfile *rf;
913ff48bf5SDavid du Colombier 
923ff48bf5SDavid du Colombier 	rf = r->fid->file->aux;
933ff48bf5SDavid du Colombier 
943ff48bf5SDavid du Colombier 	if(rf && (r->ifcall.mode&OTRUNC)){
953ff48bf5SDavid du Colombier 		rf->ndata = 0;
963ff48bf5SDavid du Colombier 		r->fid->file->length = 0;
973ff48bf5SDavid du Colombier 	}
983ff48bf5SDavid du Colombier 
993ff48bf5SDavid du Colombier 	respond(r, nil);
1003ff48bf5SDavid du Colombier }
1013ff48bf5SDavid du Colombier 
1023ff48bf5SDavid du Colombier void
fsdestroyfile(File * f)1033ff48bf5SDavid du Colombier fsdestroyfile(File *f)
1043ff48bf5SDavid du Colombier {
1053ff48bf5SDavid du Colombier 	Ramfile *rf;
1063ff48bf5SDavid du Colombier 
1073ff48bf5SDavid du Colombier //fprint(2, "clunk\n");
1083ff48bf5SDavid du Colombier 	rf = f->aux;
1093ff48bf5SDavid du Colombier 	if(rf){
1103ff48bf5SDavid du Colombier 		free(rf->data);
1113ff48bf5SDavid du Colombier 		free(rf);
1123ff48bf5SDavid du Colombier 	}
1133ff48bf5SDavid du Colombier }
1143ff48bf5SDavid du Colombier 
1153ff48bf5SDavid du Colombier Srv fs = {
1163ff48bf5SDavid du Colombier 	.open=	fsopen,
1173ff48bf5SDavid du Colombier 	.read=	fsread,
1183ff48bf5SDavid du Colombier 	.write=	fswrite,
1193ff48bf5SDavid du Colombier 	.create=	fscreate,
1203ff48bf5SDavid du Colombier };
1213ff48bf5SDavid du Colombier 
1223ff48bf5SDavid du Colombier void
usage(void)1233ff48bf5SDavid du Colombier usage(void)
1243ff48bf5SDavid du Colombier {
1253ff48bf5SDavid du Colombier 	fprint(2, "usage: ramfs [-D] [-s srvname] [-m mtpt]\n");
1263ff48bf5SDavid du Colombier 	exits("usage");
1273ff48bf5SDavid du Colombier }
1283ff48bf5SDavid du Colombier 
1293ff48bf5SDavid du Colombier void
main(int argc,char ** argv)1303ff48bf5SDavid du Colombier main(int argc, char **argv)
1313ff48bf5SDavid du Colombier {
132*22a127bbSDavid du Colombier 	char *addr = nil;
1333ff48bf5SDavid du Colombier 	char *srvname = nil;
1343ff48bf5SDavid du Colombier 	char *mtpt = nil;
1353ff48bf5SDavid du Colombier 	Qid q;
1363ff48bf5SDavid du Colombier 
1373ff48bf5SDavid du Colombier 	fs.tree = alloctree(nil, nil, DMDIR|0777, fsdestroyfile);
1383ff48bf5SDavid du Colombier 	q = fs.tree->root->qid;
1393ff48bf5SDavid du Colombier 
1403ff48bf5SDavid du Colombier 	ARGBEGIN{
1413ff48bf5SDavid du Colombier 	case 'D':
1423ff48bf5SDavid du Colombier 		chatty9p++;
1433ff48bf5SDavid du Colombier 		break;
144*22a127bbSDavid du Colombier 	case 'a':
145*22a127bbSDavid du Colombier 		addr = EARGF(usage());
146*22a127bbSDavid du Colombier 		break;
1473ff48bf5SDavid du Colombier 	case 's':
1483ff48bf5SDavid du Colombier 		srvname = EARGF(usage());
1493ff48bf5SDavid du Colombier 		break;
1503ff48bf5SDavid du Colombier 	case 'm':
1513ff48bf5SDavid du Colombier 		mtpt = EARGF(usage());
1523ff48bf5SDavid du Colombier 		break;
1533ff48bf5SDavid du Colombier 	default:
1543ff48bf5SDavid du Colombier 		usage();
1553ff48bf5SDavid du Colombier 	}ARGEND;
1563ff48bf5SDavid du Colombier 
1573ff48bf5SDavid du Colombier 	if(argc)
1583ff48bf5SDavid du Colombier 		usage();
1593ff48bf5SDavid du Colombier 
1603ff48bf5SDavid du Colombier 	if(chatty9p)
1613ff48bf5SDavid du Colombier 		fprint(2, "ramsrv.nopipe %d srvname %s mtpt %s\n", fs.nopipe, srvname, mtpt);
162*22a127bbSDavid du Colombier 	if(addr == nil && srvname == nil && mtpt == nil)
163*22a127bbSDavid du Colombier 		sysfatal("must specify -a, -s, or -m option");
164*22a127bbSDavid du Colombier 	if(addr)
165*22a127bbSDavid du Colombier 		listensrv(&fs, addr);
1663ff48bf5SDavid du Colombier 
167*22a127bbSDavid du Colombier 	if(srvname || mtpt)
1683ff48bf5SDavid du Colombier 		postmountsrv(&fs, srvname, mtpt, MREPL|MCREATE);
1693ff48bf5SDavid du Colombier 	exits(0);
1703ff48bf5SDavid du Colombier }
171