xref: /plan9-contrib/sys/src/9/port/devsrv.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include	"u.h"
23e12c5d1SDavid du Colombier #include	"../port/lib.h"
33e12c5d1SDavid du Colombier #include	"mem.h"
43e12c5d1SDavid du Colombier #include	"dat.h"
53e12c5d1SDavid du Colombier #include	"fns.h"
63e12c5d1SDavid du Colombier #include	"../port/error.h"
73e12c5d1SDavid du Colombier 
83e12c5d1SDavid du Colombier #include	"devtab.h"
93e12c5d1SDavid du Colombier 
103e12c5d1SDavid du Colombier typedef struct Srv Srv;
113e12c5d1SDavid du Colombier struct Srv
123e12c5d1SDavid du Colombier {
133e12c5d1SDavid du Colombier 	char	name[NAMELEN];
143e12c5d1SDavid du Colombier 	char	owner[NAMELEN];
153e12c5d1SDavid du Colombier 	ulong	perm;
163e12c5d1SDavid du Colombier 	Chan	*chan;
173e12c5d1SDavid du Colombier 	Srv	*link;
183e12c5d1SDavid du Colombier 	ulong	path;
193e12c5d1SDavid du Colombier };
203e12c5d1SDavid du Colombier 
213e12c5d1SDavid du Colombier static QLock	srvlk;
223e12c5d1SDavid du Colombier static Srv	*srv;
233e12c5d1SDavid du Colombier static int	path;
243e12c5d1SDavid du Colombier 
253e12c5d1SDavid du Colombier int
263e12c5d1SDavid du Colombier srvgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
273e12c5d1SDavid du Colombier {
283e12c5d1SDavid du Colombier 	Srv *sp;
293e12c5d1SDavid du Colombier 
303e12c5d1SDavid du Colombier 	USED(tab);
313e12c5d1SDavid du Colombier 	USED(ntab);
323e12c5d1SDavid du Colombier 	qlock(&srvlk);
333e12c5d1SDavid du Colombier 	for(sp = srv; sp && s; sp = sp->link)
343e12c5d1SDavid du Colombier 		s--;
353e12c5d1SDavid du Colombier 
363e12c5d1SDavid du Colombier 	if(sp == 0) {
373e12c5d1SDavid du Colombier 		qunlock(&srvlk);
383e12c5d1SDavid du Colombier 		return -1;
393e12c5d1SDavid du Colombier 	}
403e12c5d1SDavid du Colombier 	devdir(c, (Qid){sp->path, 0}, sp->name, 0, sp->owner, sp->perm, dp);
413e12c5d1SDavid du Colombier 	qunlock(&srvlk);
423e12c5d1SDavid du Colombier 	return 1;
433e12c5d1SDavid du Colombier }
443e12c5d1SDavid du Colombier 
453e12c5d1SDavid du Colombier void
463e12c5d1SDavid du Colombier srvinit(void)
473e12c5d1SDavid du Colombier {
483e12c5d1SDavid du Colombier 	path = 1;
493e12c5d1SDavid du Colombier }
503e12c5d1SDavid du Colombier 
513e12c5d1SDavid du Colombier void
523e12c5d1SDavid du Colombier srvreset(void)
533e12c5d1SDavid du Colombier {
543e12c5d1SDavid du Colombier }
553e12c5d1SDavid du Colombier 
563e12c5d1SDavid du Colombier Chan*
573e12c5d1SDavid du Colombier srvattach(char *spec)
583e12c5d1SDavid du Colombier {
593e12c5d1SDavid du Colombier 	return devattach('s', spec);
603e12c5d1SDavid du Colombier }
613e12c5d1SDavid du Colombier 
623e12c5d1SDavid du Colombier Chan*
633e12c5d1SDavid du Colombier srvclone(Chan *c, Chan *nc)
643e12c5d1SDavid du Colombier {
653e12c5d1SDavid du Colombier 	return devclone(c, nc);
663e12c5d1SDavid du Colombier }
673e12c5d1SDavid du Colombier 
683e12c5d1SDavid du Colombier int
693e12c5d1SDavid du Colombier srvwalk(Chan *c, char *name)
703e12c5d1SDavid du Colombier {
713e12c5d1SDavid du Colombier 	return devwalk(c, name, 0, 0, srvgen);
723e12c5d1SDavid du Colombier }
733e12c5d1SDavid du Colombier 
743e12c5d1SDavid du Colombier void
753e12c5d1SDavid du Colombier srvstat(Chan *c, char *db)
763e12c5d1SDavid du Colombier {
773e12c5d1SDavid du Colombier 	devstat(c, db, 0, 0, srvgen);
783e12c5d1SDavid du Colombier }
793e12c5d1SDavid du Colombier 
803e12c5d1SDavid du Colombier Chan*
813e12c5d1SDavid du Colombier srvopen(Chan *c, int omode)
823e12c5d1SDavid du Colombier {
833e12c5d1SDavid du Colombier 	Srv *sp;
843e12c5d1SDavid du Colombier 
853e12c5d1SDavid du Colombier 	if(c->qid.path == CHDIR){
863e12c5d1SDavid du Colombier 		if(omode != OREAD)
873e12c5d1SDavid du Colombier 			error(Eisdir);
883e12c5d1SDavid du Colombier 		c->mode = omode;
893e12c5d1SDavid du Colombier 		c->flag |= COPEN;
903e12c5d1SDavid du Colombier 		c->offset = 0;
913e12c5d1SDavid du Colombier 		return c;
923e12c5d1SDavid du Colombier 	}
933e12c5d1SDavid du Colombier 	qlock(&srvlk);
943e12c5d1SDavid du Colombier 	if(waserror()){
953e12c5d1SDavid du Colombier 		qunlock(&srvlk);
963e12c5d1SDavid du Colombier 		nexterror();
973e12c5d1SDavid du Colombier 	}
983e12c5d1SDavid du Colombier 
993e12c5d1SDavid du Colombier 	for(sp = srv; sp; sp = sp->link)
1003e12c5d1SDavid du Colombier 		if(sp->path == c->qid.path)
1013e12c5d1SDavid du Colombier 			break;
1023e12c5d1SDavid du Colombier 
1033e12c5d1SDavid du Colombier 	if(sp == 0 || sp->chan == 0)
1043e12c5d1SDavid du Colombier 		error(Eshutdown);
1053e12c5d1SDavid du Colombier 
1063e12c5d1SDavid du Colombier 	if(omode&OTRUNC)
1073e12c5d1SDavid du Colombier 		error(Eperm);
1083e12c5d1SDavid du Colombier 	if(omode!=sp->chan->mode && sp->chan->mode!=ORDWR)
1093e12c5d1SDavid du Colombier 		error(Eperm);
1103e12c5d1SDavid du Colombier 
1113e12c5d1SDavid du Colombier 	close(c);
1123e12c5d1SDavid du Colombier 	incref(sp->chan);
1133e12c5d1SDavid du Colombier 	qunlock(&srvlk);
1143e12c5d1SDavid du Colombier 	poperror();
1153e12c5d1SDavid du Colombier 	return sp->chan;
1163e12c5d1SDavid du Colombier }
1173e12c5d1SDavid du Colombier 
1183e12c5d1SDavid du Colombier void
1193e12c5d1SDavid du Colombier srvcreate(Chan *c, char *name, int omode, ulong perm)
1203e12c5d1SDavid du Colombier {
1213e12c5d1SDavid du Colombier 	Srv *sp;
1223e12c5d1SDavid du Colombier 
1233e12c5d1SDavid du Colombier 	if(omode != OWRITE)
1243e12c5d1SDavid du Colombier 		error(Eperm);
1253e12c5d1SDavid du Colombier 
1263e12c5d1SDavid du Colombier 	sp = malloc(sizeof(Srv));
1273e12c5d1SDavid du Colombier 	if(sp == 0)
1283e12c5d1SDavid du Colombier 		error(Enomem);
1293e12c5d1SDavid du Colombier 
1303e12c5d1SDavid du Colombier 	qlock(&srvlk);
1313e12c5d1SDavid du Colombier 	if(waserror()){
1323e12c5d1SDavid du Colombier 		qunlock(&srvlk);
1333e12c5d1SDavid du Colombier 		nexterror();
1343e12c5d1SDavid du Colombier 	}
1353e12c5d1SDavid du Colombier 	sp->path = path++;
1363e12c5d1SDavid du Colombier 	sp->link = srv;
1373e12c5d1SDavid du Colombier 	c->qid.path = sp->path;
1383e12c5d1SDavid du Colombier 	srv = sp;
1393e12c5d1SDavid du Colombier 	qunlock(&srvlk);
1403e12c5d1SDavid du Colombier 	poperror();
1413e12c5d1SDavid du Colombier 
1423e12c5d1SDavid du Colombier 	strncpy(sp->name, name, NAMELEN);
1433e12c5d1SDavid du Colombier 	strncpy(sp->owner, u->p->user, NAMELEN);
1443e12c5d1SDavid du Colombier 	sp->perm = perm&0777;
1453e12c5d1SDavid du Colombier 
1463e12c5d1SDavid du Colombier 	c->flag |= COPEN;
1473e12c5d1SDavid du Colombier 	c->mode = OWRITE;
1483e12c5d1SDavid du Colombier }
1493e12c5d1SDavid du Colombier 
1503e12c5d1SDavid du Colombier void
1513e12c5d1SDavid du Colombier srvremove(Chan *c)
1523e12c5d1SDavid du Colombier {
1533e12c5d1SDavid du Colombier 	Srv *sp, **l;
1543e12c5d1SDavid du Colombier 
1553e12c5d1SDavid du Colombier 	if(c->qid.path == CHDIR)
1563e12c5d1SDavid du Colombier 		error(Eperm);
1573e12c5d1SDavid du Colombier 
1583e12c5d1SDavid du Colombier 	qlock(&srvlk);
1593e12c5d1SDavid du Colombier 	if(waserror()){
1603e12c5d1SDavid du Colombier 		qunlock(&srvlk);
1613e12c5d1SDavid du Colombier 		nexterror();
1623e12c5d1SDavid du Colombier 	}
1633e12c5d1SDavid du Colombier 	l = &srv;
1643e12c5d1SDavid du Colombier 	for(sp = *l; sp; sp = sp->link) {
1653e12c5d1SDavid du Colombier 		if(sp->path == c->qid.path)
1663e12c5d1SDavid du Colombier 			break;
1673e12c5d1SDavid du Colombier 
168*219b2ee8SDavid du Colombier 		l = &sp->link;
1693e12c5d1SDavid du Colombier 	}
1703e12c5d1SDavid du Colombier 	if(sp == 0)
1713e12c5d1SDavid du Colombier 		error(Enonexist);
1723e12c5d1SDavid du Colombier 
1733e12c5d1SDavid du Colombier 	if(strcmp(sp->name, "boot") == 0)
1743e12c5d1SDavid du Colombier 		error(Eperm);
1753e12c5d1SDavid du Colombier 
1763e12c5d1SDavid du Colombier 	*l = sp->link;
1773e12c5d1SDavid du Colombier 	qunlock(&srvlk);
1783e12c5d1SDavid du Colombier 	poperror();
1793e12c5d1SDavid du Colombier 
1803e12c5d1SDavid du Colombier 	if(sp->chan)
1813e12c5d1SDavid du Colombier 		close(sp->chan);
1823e12c5d1SDavid du Colombier 	free(sp);
1833e12c5d1SDavid du Colombier }
1843e12c5d1SDavid du Colombier 
1853e12c5d1SDavid du Colombier void
1863e12c5d1SDavid du Colombier srvwstat(Chan *c, char *dp)
1873e12c5d1SDavid du Colombier {
1883e12c5d1SDavid du Colombier 	USED(c, dp);
1893e12c5d1SDavid du Colombier 	error(Egreg);
1903e12c5d1SDavid du Colombier }
1913e12c5d1SDavid du Colombier 
1923e12c5d1SDavid du Colombier void
1933e12c5d1SDavid du Colombier srvclose(Chan *c)
1943e12c5d1SDavid du Colombier {
1953e12c5d1SDavid du Colombier 	USED(c);
1963e12c5d1SDavid du Colombier }
1973e12c5d1SDavid du Colombier 
1983e12c5d1SDavid du Colombier long
1993e12c5d1SDavid du Colombier srvread(Chan *c, void *va, long n, ulong offset)
2003e12c5d1SDavid du Colombier {
2013e12c5d1SDavid du Colombier 	USED(offset);
2023e12c5d1SDavid du Colombier 	isdir(c);
2033e12c5d1SDavid du Colombier 	return devdirread(c, va, n, 0, 0, srvgen);
2043e12c5d1SDavid du Colombier }
2053e12c5d1SDavid du Colombier 
2063e12c5d1SDavid du Colombier long
2073e12c5d1SDavid du Colombier srvwrite(Chan *c, void *va, long n, ulong offset)
2083e12c5d1SDavid du Colombier {
2093e12c5d1SDavid du Colombier 	Srv *sp;
2103e12c5d1SDavid du Colombier 	Chan *c1;
2113e12c5d1SDavid du Colombier 	int fd;
2123e12c5d1SDavid du Colombier 	char buf[32];
2133e12c5d1SDavid du Colombier 
2143e12c5d1SDavid du Colombier 	USED(offset);
2153e12c5d1SDavid du Colombier 	if(n >= sizeof buf)
2163e12c5d1SDavid du Colombier 		error(Egreg);
2173e12c5d1SDavid du Colombier 	memmove(buf, va, n);	/* so we can NUL-terminate */
2183e12c5d1SDavid du Colombier 	buf[n] = 0;
2193e12c5d1SDavid du Colombier 	fd = strtoul(buf, 0, 0);
2203e12c5d1SDavid du Colombier 
2213e12c5d1SDavid du Colombier 	c1 = fdtochan(fd, -1, 0, 1);	/* error check only */
2223e12c5d1SDavid du Colombier 
2233e12c5d1SDavid du Colombier 	qlock(&srvlk);
2243e12c5d1SDavid du Colombier 	if(waserror()) {
2253e12c5d1SDavid du Colombier 		qunlock(&srvlk);
2263e12c5d1SDavid du Colombier 		close(c1);
2273e12c5d1SDavid du Colombier 		nexterror();
2283e12c5d1SDavid du Colombier 	}
2293e12c5d1SDavid du Colombier 	for(sp = srv; sp; sp = sp->link)
2303e12c5d1SDavid du Colombier 		if(sp->path == c->qid.path)
2313e12c5d1SDavid du Colombier 			break;
2323e12c5d1SDavid du Colombier 
2333e12c5d1SDavid du Colombier 	if(sp == 0)
2343e12c5d1SDavid du Colombier 		error(Enonexist);
2353e12c5d1SDavid du Colombier 
2363e12c5d1SDavid du Colombier 	if(sp->chan)
2373e12c5d1SDavid du Colombier 		panic("srvwrite");
2383e12c5d1SDavid du Colombier 
2393e12c5d1SDavid du Colombier 	sp->chan = c1;
2403e12c5d1SDavid du Colombier 	qunlock(&srvlk);
2413e12c5d1SDavid du Colombier 	poperror();
2423e12c5d1SDavid du Colombier 	return n;
2433e12c5d1SDavid du Colombier }
244