9scripts/patches/zrv.patch

685 lines
13 KiB
Diff

diff -r 096538d64724 sys/include/libc.h
--- a/sys/include/libc.h Sun Feb 28 16:36:42 2021 -0800
+++ b/sys/include/libc.h Mon Mar 01 09:28:04 2021 -0800
@@ -624,6 +624,7 @@
RFPROC = (1<<4),
RFMEM = (1<<5),
RFNOWAIT = (1<<6),
+ RFCSRVG = (1<<9),
RFCNAMEG = (1<<10),
RFCENVG = (1<<11),
RFCFDG = (1<<12),
diff -r 096538d64724 sys/src/9/port/auth.c
--- a/sys/src/9/port/auth.c Sun Feb 28 16:36:42 2021 -0800
+++ b/sys/src/9/port/auth.c Mon Mar 01 09:28:04 2021 -0800
@@ -141,6 +141,7 @@
renameuser(eve, buf);
srvrenameuser(eve, buf);
+ zrvrenameuser(eve, buf);
shrrenameuser(eve, buf);
kstrdup(&eve, buf);
procsetuser(buf);
diff -r 096538d64724 sys/src/9/port/devroot.c
--- a/sys/src/9/port/devroot.c Sun Feb 28 16:36:42 2021 -0800
+++ b/sys/src/9/port/devroot.c Mon Mar 01 09:28:04 2021 -0800
@@ -108,6 +108,7 @@
addrootdir("root");
addrootdir("srv");
addrootdir("shr");
+ addrootdir("zrv");
}
static Chan*
diff -r 096538d64724 sys/src/9/port/devsrv.c
--- a/sys/src/9/port/devsrv.c Sun Feb 28 16:36:42 2021 -0800
+++ b/sys/src/9/port/devsrv.c Mon Mar 01 09:28:04 2021 -0800
@@ -6,19 +6,7 @@
#include "../port/error.h"
-typedef struct Srv Srv;
-struct Srv
-{
- char *name;
- char *owner;
- ulong perm;
- Chan *chan;
- Srv *link;
- ulong path;
-};
-
static QLock srvlk;
-static Srv *srv;
static int qidpath;
static Srv*
@@ -26,7 +14,7 @@
{
Srv *sp;
- for(sp = srv; sp != nil; sp = sp->link) {
+ for(sp = up->sgrp->srvgrp; sp != nil; sp = sp->link) {
if(sp->path == qidpath || (name != nil && strcmp(sp->name, name) == 0))
return sp;
}
@@ -48,7 +36,7 @@
if(name != nil)
sp = srvlookup(name, -1);
else {
- for(sp = srv; sp != nil && s > 0; sp = sp->link)
+ for(sp = up->sgrp->srvgrp; sp != nil && s > 0; sp = sp->link)
s--;
}
if(sp == nil || (name != nil && (strlen(sp->name) >= sizeof(up->genbuf)))) {
@@ -95,7 +83,7 @@
s = nil;
qlock(&srvlk);
- for(sp = srv; sp != nil; sp = sp->link) {
+ for(sp = up->sgrp->srvgrp; sp != nil; sp = sp->link) {
if(sp->chan == c){
s = malloc(3+strlen(sp->name)+1);
if(s != nil)
@@ -183,8 +171,8 @@
c->qid.path = sp->path;
c->qid.type = QTFILE;
- sp->link = srv;
- srv = sp;
+ sp->link = up->sgrp->srvgrp;
+ up->sgrp->srvgrp = sp;
qunlock(&srvlk);
poperror();
@@ -208,7 +196,7 @@
qunlock(&srvlk);
nexterror();
}
- l = &srv;
+ l = &up->sgrp->srvgrp;
for(sp = *l; sp != nil; sp = *l) {
if(sp->path == c->qid.path)
break;
@@ -378,12 +366,30 @@
};
void
+closesgrp(Sgrp *sg)
+{
+ Srv *sp;
+ Srv *tsp;
+
+ if(decref(sg) == 0){
+ sp = sg->srvgrp;
+ while(sp!=nil){
+ tsp=sp;
+ sp=sp->link;
+ free(tsp);
+ }
+ free(sg);
+ }
+ return;
+}
+
+void
srvrenameuser(char *old, char *new)
{
Srv *sp;
qlock(&srvlk);
- for(sp = srv; sp != nil; sp = sp->link) {
+ for(sp = up->sgrp->srvgrp; sp != nil; sp = sp->link) {
if(sp->owner != nil && strcmp(old, sp->owner) == 0)
kstrdup(&sp->owner, new);
}
diff -r 096538d64724 sys/src/9/port/devzrv.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/src/9/port/devzrv.c Mon Mar 01 09:28:04 2021 -0800
@@ -0,0 +1,380 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+
+static QLock srvlk;
+static Srv *srv;
+static int qidpath;
+
+static Srv*
+srvlookup(char *name, ulong qidpath)
+{
+ Srv *sp;
+
+ for(sp = srv; sp != nil; sp = sp->link) {
+ if(sp->path == qidpath || (name != nil && strcmp(sp->name, name) == 0))
+ return sp;
+ }
+ return nil;
+}
+
+static int
+srvgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
+{
+ Srv *sp;
+ Qid q;
+
+ if(s == DEVDOTDOT){
+ devdir(c, c->qid, "#z", 0, eve, 0555, dp);
+ return 1;
+ }
+
+ qlock(&srvlk);
+ if(name != nil)
+ sp = srvlookup(name, -1);
+ else {
+ for(sp = srv; sp != nil && s > 0; sp = sp->link)
+ s--;
+ }
+ if(sp == nil || (name != nil && (strlen(sp->name) >= sizeof(up->genbuf)))) {
+ qunlock(&srvlk);
+ return -1;
+ }
+ mkqid(&q, sp->path, 0, QTFILE);
+ /* make sure name string continues to exist after we release lock */
+ kstrcpy(up->genbuf, sp->name, sizeof up->genbuf);
+ devdir(c, q, up->genbuf, 0, sp->owner, sp->perm, dp);
+ qunlock(&srvlk);
+ return 1;
+}
+
+static void
+srvinit(void)
+{
+ qidpath = 1;
+}
+
+static Chan*
+srvattach(char *spec)
+{
+ return devattach('z', spec);
+}
+
+static Walkqid*
+srvwalk(Chan *c, Chan *nc, char **name, int nname)
+{
+ return devwalk(c, nc, name, nname, 0, 0, srvgen);
+}
+
+static int
+srvstat(Chan *c, uchar *db, int n)
+{
+ return devstat(c, db, n, 0, 0, srvgen);
+}
+
+char*
+zrvname(Chan *c)
+{
+ Srv *sp;
+ char *s;
+
+ s = nil;
+ qlock(&srvlk);
+ for(sp = srv; sp != nil; sp = sp->link) {
+ if(sp->chan == c){
+ s = malloc(3+strlen(sp->name)+1);
+ if(s != nil)
+ sprint(s, "#z/%s", sp->name);
+ break;
+ }
+ }
+ qunlock(&srvlk);
+ return s;
+}
+
+static Chan*
+srvopen(Chan *c, int omode)
+{
+ Srv *sp;
+ Chan *nc;
+
+ if(c->qid.type == QTDIR){
+ if(omode & ORCLOSE)
+ error(Eperm);
+ if(omode != OREAD)
+ error(Eisdir);
+ c->mode = omode;
+ c->flag |= COPEN;
+ c->offset = 0;
+ return c;
+ }
+ qlock(&srvlk);
+ if(waserror()){
+ qunlock(&srvlk);
+ nexterror();
+ }
+
+ sp = srvlookup(nil, c->qid.path);
+ if(sp == nil || sp->chan == nil)
+ error(Eshutdown);
+
+ if(omode&OTRUNC)
+ error(Eexist);
+ if(openmode(omode)!=sp->chan->mode && sp->chan->mode!=ORDWR)
+ error(Eperm);
+ devpermcheck(sp->owner, sp->perm, omode);
+
+ nc = sp->chan;
+ incref(nc);
+
+ qunlock(&srvlk);
+ poperror();
+
+ cclose(c);
+ return nc;
+}
+
+static Chan*
+srvcreate(Chan *c, char *name, int omode, ulong perm)
+{
+ Srv *sp;
+
+ if(openmode(omode) != OWRITE)
+ error(Eperm);
+
+ if(strlen(name) >= sizeof(up->genbuf))
+ error(Etoolong);
+
+ sp = smalloc(sizeof *sp);
+ kstrdup(&sp->name, name);
+ kstrdup(&sp->owner, up->user);
+
+ qlock(&srvlk);
+ if(waserror()){
+ qunlock(&srvlk);
+ free(sp->owner);
+ free(sp->name);
+ free(sp);
+ nexterror();
+ }
+ if(srvlookup(name, -1) != nil)
+ error(Eexist);
+
+ sp->perm = perm&0777;
+ sp->path = qidpath++;
+
+ c->qid.path = sp->path;
+ c->qid.type = QTFILE;
+
+ sp->link = srv;
+ srv = sp;
+
+ qunlock(&srvlk);
+ poperror();
+
+ c->flag |= COPEN;
+ c->mode = OWRITE;
+
+ return c;
+}
+
+static void
+srvremove(Chan *c)
+{
+ Srv *sp, **l;
+
+ if(c->qid.type == QTDIR)
+ error(Eperm);
+
+ qlock(&srvlk);
+ if(waserror()){
+ qunlock(&srvlk);
+ nexterror();
+ }
+ l = &srv;
+ for(sp = *l; sp != nil; sp = *l) {
+ if(sp->path == c->qid.path)
+ break;
+ l = &sp->link;
+ }
+ if(sp == nil)
+ error(Enonexist);
+
+ /*
+ * Only eve can remove system services.
+ */
+ if(strcmp(sp->owner, eve) == 0 && !iseve())
+ error(Eperm);
+
+ /*
+ * No removing personal services.
+ */
+ if((sp->perm&7) != 7 && strcmp(sp->owner, up->user) && !iseve())
+ error(Eperm);
+
+ *l = sp->link;
+ sp->link = nil;
+
+ qunlock(&srvlk);
+ poperror();
+
+ if(sp->chan != nil)
+ cclose(sp->chan);
+ free(sp->owner);
+ free(sp->name);
+ free(sp);
+}
+
+static int
+srvwstat(Chan *c, uchar *dp, int n)
+{
+ char *strs;
+ Srv *sp;
+ Dir d;
+
+ if(c->qid.type & QTDIR)
+ error(Eperm);
+
+ strs = smalloc(n);
+ if(waserror()){
+ free(strs);
+ nexterror();
+ }
+ n = convM2D(dp, n, &d, strs);
+ if(n == 0)
+ error(Eshortstat);
+
+ qlock(&srvlk);
+ if(waserror()){
+ qunlock(&srvlk);
+ nexterror();
+ }
+
+ sp = srvlookup(nil, c->qid.path);
+ if(sp == nil)
+ error(Enonexist);
+
+ if(strcmp(sp->owner, up->user) != 0 && !iseve())
+ error(Eperm);
+
+ if(d.name != nil && *d.name && strcmp(sp->name, d.name) != 0) {
+ if(strchr(d.name, '/') != nil)
+ error(Ebadchar);
+ if(strlen(d.name) >= sizeof(up->genbuf))
+ error(Etoolong);
+ kstrdup(&sp->name, d.name);
+ }
+ if(d.uid != nil && *d.uid)
+ kstrdup(&sp->owner, d.uid);
+ if(d.mode != ~0UL)
+ sp->perm = d.mode & 0777;
+
+ qunlock(&srvlk);
+ poperror();
+
+ free(strs);
+ poperror();
+
+ return n;
+}
+
+static void
+srvclose(Chan *c)
+{
+ /*
+ * in theory we need to override any changes in removability
+ * since open, but since all that's checked is the owner,
+ * which is immutable, all is well.
+ */
+ if(c->flag & CRCLOSE){
+ if(waserror())
+ return;
+ srvremove(c);
+ poperror();
+ }
+}
+
+static long
+srvread(Chan *c, void *va, long n, vlong)
+{
+ isdir(c);
+ return devdirread(c, va, n, 0, 0, srvgen);
+}
+
+static long
+srvwrite(Chan *c, void *va, long n, vlong)
+{
+ Srv *sp;
+ Chan *c1;
+ int fd;
+ char buf[32];
+
+ if(n >= sizeof buf)
+ error(Etoobig);
+ memmove(buf, va, n); /* so we can NUL-terminate */
+ buf[n] = 0;
+ fd = strtoul(buf, 0, 0);
+
+ c1 = fdtochan(fd, -1, 0, 1); /* error check and inc ref */
+
+ qlock(&srvlk);
+ if(waserror()) {
+ qunlock(&srvlk);
+ cclose(c1);
+ nexterror();
+ }
+ if(c1->flag & (CCEXEC|CRCLOSE))
+ error("posted fd has remove-on-close or close-on-exec");
+ if(c1->qid.type & QTAUTH)
+ error("cannot post auth file in zrv");
+ sp = srvlookup(nil, c->qid.path);
+ if(sp == nil)
+ error(Enonexist);
+
+ if(sp->chan != nil)
+ error(Ebadusefd);
+
+ sp->chan = c1;
+
+ qunlock(&srvlk);
+ poperror();
+ return n;
+}
+
+Dev zrvdevtab = {
+ 'z',
+ "zrv",
+
+ devreset,
+ srvinit,
+ devshutdown,
+ srvattach,
+ srvwalk,
+ srvstat,
+ srvopen,
+ srvcreate,
+ srvclose,
+ srvread,
+ devbread,
+ srvwrite,
+ devbwrite,
+ srvremove,
+ srvwstat,
+};
+
+void
+zrvrenameuser(char *old, char *new)
+{
+ Srv *sp;
+
+ qlock(&srvlk);
+ for(sp = srv; sp != nil; sp = sp->link) {
+ if(sp->owner != nil && strcmp(old, sp->owner) == 0)
+ kstrdup(&sp->owner, new);
+ }
+ qunlock(&srvlk);
+}
+
diff -r 096538d64724 sys/src/9/port/portdat.h
--- a/sys/src/9/port/portdat.h Sun Feb 28 16:36:42 2021 -0800
+++ b/sys/src/9/port/portdat.h Mon Mar 01 09:28:04 2021 -0800
@@ -44,6 +44,8 @@
typedef struct Segment Segment;
typedef struct Segio Segio;
typedef struct Sema Sema;
+typedef struct Sgrp Sgrp;
+typedef struct Srv Srv;
typedef struct Timer Timer;
typedef struct Timers Timers;
typedef struct Uart Uart;
@@ -468,6 +470,21 @@
Page *pghash[PGHSIZE]; /* page cache */
};
+struct Srv
+{
+ char *name;
+ char *owner;
+ ulong perm;
+ Chan *chan;
+ Srv *link;
+ ulong path;
+};
+
+struct Sgrp
+{
+ Ref;
+ Srv *srvgrp;
+};
struct Pgrp
{
@@ -576,6 +593,7 @@
RFPROC = (1<<4),
RFMEM = (1<<5),
RFNOWAIT = (1<<6),
+ RFCSRVG = (1<<9),
RFCNAMEG = (1<<10),
RFCENVG = (1<<11),
RFCFDG = (1<<12),
@@ -678,6 +696,7 @@
Egrp *egrp; /* Environment group */
Fgrp *fgrp; /* File descriptor group */
Rgrp *rgrp; /* Rendez group */
+ Sgrp *sgrp; /* Srv group */
Fgrp *closingfgrp; /* used during teardown */
diff -r 096538d64724 sys/src/9/port/portfns.h
--- a/sys/src/9/port/portfns.h Sun Feb 28 16:36:42 2021 -0800
+++ b/sys/src/9/port/portfns.h Mon Mar 01 09:28:04 2021 -0800
@@ -34,6 +34,7 @@
void closefgrp(Fgrp*);
void closepgrp(Pgrp*);
void closergrp(Rgrp*);
+void closesgrp(Sgrp*);
long clrfpintr(void);
void cmderror(Cmdbuf*, char*);
int cmount(Chan**, Chan*, int, char*);
@@ -340,6 +341,8 @@
void splxpc(int);
char* srvname(Chan*);
void srvrenameuser(char*, char*);
+char* zrvname(Chan*);
+void zrvrenameuser(char*, char*);
void shrrenameuser(char*, char*);
int swapcount(uintptr);
int swapfull(void);
diff -r 096538d64724 sys/src/9/port/proc.c
--- a/sys/src/9/port/proc.c Sun Feb 28 16:36:42 2021 -0800
+++ b/sys/src/9/port/proc.c Mon Mar 01 09:28:04 2021 -0800
@@ -1092,6 +1092,7 @@
Egrp *egrp;
Rgrp *rgrp;
Pgrp *pgrp;
+ Sgrp *sgrp;
Chan *dot;
void (*pt)(Proc*, int, vlong);
@@ -1122,6 +1123,13 @@
closeegrp(egrp);
if(rgrp != nil)
closergrp(rgrp);
+ /* sgrp is nilled out here because closefgrp may need srvclose */
+ qlock(&up->debug);
+ sgrp = up->sgrp;
+ up->sgrp = nil;
+ qunlock(&up->debug);
+ if(sgrp != nil)
+ closesgrp(sgrp);
if(dot != nil)
cclose(dot);
if(pgrp != nil)
diff -r 096538d64724 sys/src/9/port/sysproc.c
--- a/sys/src/9/port/sysproc.c Sun Feb 28 16:36:42 2021 -0800
+++ b/sys/src/9/port/sysproc.c Mon Mar 01 09:28:04 2021 -0800
@@ -32,6 +32,7 @@
Pgrp *opg;
Rgrp *org;
Egrp *oeg;
+ Sgrp *osg;
ulong pid, flag;
Mach *wm;
@@ -71,6 +72,12 @@
up->rgrp = newrgrp();
closergrp(org);
}
+ if(flag & RFCSRVG) {
+ osg = up->sgrp;
+ up->sgrp = smalloc(sizeof(Sgrp));
+ up->sgrp->ref = 1;
+ closesgrp(osg);
+ }
if(flag & (RFENVG|RFCENVG)) {
oeg = up->egrp;
up->egrp = smalloc(sizeof(Egrp));
@@ -187,6 +194,15 @@
p->rgrp = up->rgrp;
}
+ /* Srv group */
+ if(flag & RFCSRVG) {
+ p->sgrp = smalloc(sizeof(Sgrp));
+ p->sgrp->ref = 1;
+ } else {
+ p->sgrp = up->sgrp;
+ incref(p->sgrp);
+ }
+
/* Environment group */
if(flag & (RFENVG|RFCENVG)) {
p->egrp = smalloc(sizeof(Egrp));
diff -r 096538d64724 sys/src/9/port/userinit.c
--- a/sys/src/9/port/userinit.c Sun Feb 28 16:36:42 2021 -0800
+++ b/sys/src/9/port/userinit.c Mon Mar 01 09:28:04 2021 -0800
@@ -31,6 +31,8 @@
up->pgrp = newpgrp();
up->egrp = smalloc(sizeof(Egrp));
up->egrp->ref = 1;
+ up->sgrp = smalloc(sizeof(Sgrp));
+ up->sgrp->ref = 1;
up->fgrp = dupfgrp(nil);
up->rgrp = newrgrp();
diff -r 096538d64724 sys/src/cmd/rc/plan9.c
--- a/sys/src/cmd/rc/plan9.c Sun Feb 28 16:36:42 2021 -0800
+++ b/sys/src/cmd/rc/plan9.c Mon Mar 01 09:28:04 2021 -0800
@@ -81,11 +81,13 @@
arg|=RFFDG; break;
case 'F':
arg|=RFCFDG; break;
+ case 'V':
+ arg|=RFCSRVG; break;
}
break;
default:
Usage:
- pfmt(err, "Usage: %s [fnesFNEm]\n", runq->argv->words->word);
+ pfmt(err, "Usage: %s [fnesFNEmV]\n", runq->argv->words->word);
setstatus("rfork usage");
poplist();
return;