code: plan9front

Download patch

ref: cd64b7129c81102c811b3df9a32ceb4004420f54
parent: 34dab15f408e8c272af406010b2bc6e5f7b1c473
author: Jacob Moody <moody@posixcafe.org>
date: Sun Jul 10 09:13:03 EDT 2022

auth/box: -s, -. flags

-. decides where we chdir to before execing, we can't
sit where we are because our directory may not exist.
If not specified we go to '/'.

-s is used to source a rc script instead of execing cmd.
This is primarily to enable:
	'#!/bin/auth/box -s'
Shebang line size is a bit tight(32), so we have this shorthand
to use rc along with setting up the required namespace components.

--- a/sys/man/8/auth
+++ b/sys/man/8/auth
@@ -296,7 +296,11 @@
 the child namespace; the
 .B -e
 flag specifies a string of driver
-characters to keep.
+characters to keep. The
+.B -s
+flag gives a base set of namespace
+components, ones expected by rc, then passes
+the first argument as a script file to rc.
 .PP
 .I As
 executes
--- a/sys/src/cmd/auth/box.c
+++ b/sys/src/cmd/auth/box.c
@@ -10,11 +10,11 @@
 	char dash[4] = { '-' };
 
 	if(debug){
-		if(flag & MCREATE){
+		if(flag & MCREATE)
 			dash[2] = 'c';
-			flag &= ~MCREATE;
-		}
+
 		switch(flag){
+		case MCREATE|MREPL:
 		case MREPL:
 			dash[0] = ' ';
 			if(dash[2] == 'c')
@@ -133,10 +133,24 @@
 		sysfatal("/mnt/d mount setup: %r");
 }
 
+static char *parts[256];
+static int  mflags[nelem(parts)];
+static int  nparts;
+static char *rc[] = { "/bin/rc", nil , nil};
+
+static void
+push(char *path, int flag)
+{
+	if(nparts == nelem(parts))
+		sysfatal("component overflow");
+	parts[nparts] = path;
+	mflags[nparts++] = flag;
+}
+
 void
 usage(void)
 {
-	fprint(2, "usage %s: [ -d ] [ -r file ] [ -c dir ] [ -e devs ] cmd args...\n", argv0);
+	fprint(2, "usage %s: [ -d ] [ -r file ] [ -c dir ] [ -e devs ] [ -. path ] cmd args...\n", argv0);
 	exits("usage");
 }
 
@@ -143,16 +157,16 @@
 void
 main(int argc, char **argv)
 {
-	char *b;
-	Dir *d;
 	char devs[1024];
 	int dfd;
-	char *parts[256];
-	int mflags[256];
-	int nparts;
+	char *path;
+	char *a;
+	int sflag;
 
 	nparts = 0;
+	path = "/";
 	memset(devs, 0, sizeof devs);
+	sflag = 0;
 	ARGBEGIN{
 	case 'D':
 		debug++;
@@ -160,35 +174,48 @@
 		debug++;
 		break;
 	case 'r':
-		parts[nparts] = EARGF(usage());
-		mflags[nparts++] = MREPL;
+		a = EARGF(usage());
+		push(a, MREPL);
 		break;
 	case 'c':
-		parts[nparts] = EARGF(usage());
-		mflags[nparts++] = MCREATE|MREPL;
+		a = EARGF(usage());
+		push(a, MREPL|MCREATE);
 		break;
 	case 'e':
 		snprint(devs, sizeof devs, "%s%s", devs, EARGF(usage()));
 		break;
+	case '.':
+		path = EARGF(usage());
+		break;
+	case 's':
+		sflag = 1;
+		break;
 	default:
 		usage();
 		break;
 	}ARGEND
+
 	if(argc == 0)
 		usage();
 
-	b = argv[0];
-	d = dirstat(b);
-	if(d == nil){
-		b = smprint("/bin/%s", b);
-		d = dirstat(b);
-		if(d == nil)
-			sysfatal("could not stat %s %r", argv[0]);
+	if(sflag){
+		snprint(devs, sizeof devs, "%s%s", devs, "|d");
+		push("/srv", MREPL|MCREATE);
+		push("/env", MREPL|MCREATE);
+		push("/rc", MREPL);
+		push("/bin", MREPL);
+		push(argv[0], MREPL);
+		rc[1] = argv[0];
+		argv = rc;
+	} else {
+		if(access(argv[0], AEXIST) == -1){
+			if((argv[0] = smprint("/bin/%s", argv[0])) == nil)
+				sysfatal("smprint: %r");
+			if(access(argv[0], AEXIST) == -1)
+				sysfatal("could not stat %s %r", argv[0]);
+		}
+		push(argv[0], MREPL);
 	}
-	free(d);
-	parts[nparts] = b;
-	mflags[nparts++] = MREPL;
-	argv[0] = b;
 
 	rfork(RFNAMEG|RFFDG);
 	skelfs();
@@ -210,5 +237,9 @@
 			sysfatal("could not write chdev: %r");
 	}
 	close(dfd);
+
+	if(chdir(path) < 0)
+		sysfatal("can not cd to %s", path);
 	exec(argv[0], argv);
+	sysfatal("exec: %r");
 }