Browse Source

Plan 9 from Bell Labs 2010-02-27

David du Colombier 14 years ago
parent
commit
a0bad791c4
6 changed files with 310 additions and 13 deletions
  1. 8 10
      rc/bin/iwhois
  2. 2 2
      sys/man/4/usb
  3. 20 0
      sys/man/8/screenlock
  4. 1 1
      sys/src/9/kw/plug.words
  5. 272 0
      sys/src/cmd/screenlock.c
  6. 7 0
      sys/src/cmd/usb/serial/serial.c

+ 8 - 10
rc/bin/iwhois

@@ -63,19 +63,17 @@ fn sigexit {
 	rm -f $file
 }
 echo $person | telnet -nr tcp!$machine!whois > $file
-x=`{ sed -n '
-	s/.*Whois Server: (.*)/\1/p
-	s;.*ReferralServer: whois://(.*);\1;p
-	' $file }
-switch($x){
-case ''
+x=`{ sed -n -e 's/.*Whois Server: (.*)/\1/p' \
+	-e 's;.*ReferralServer: whois://(.*)(:43)?;\1;p' $file }
+switch($#x){
+case 0
 	;			# e.g., for .ca
-case *' '*
-	echo $0: buggery: $x >[1=2]
-	exit botch
-case *
+case 1
 	# chase the referral chain
 	echo $person | telnet -nr tcp!$x!whois > $file
+case *
+#	echo $0: buggery: `{echo $x | tr ' ' '\12' | sort -u} >[1=2]
+	echo $person | telnet -nr tcp!^$x(1)^!whois > $file
 }
 if (test ! -s $file) {
 	echo $0: broken whois server tcp!$x!whois returned no data >[1=2]

+ 2 - 2
sys/man/4/usb

@@ -271,13 +271,13 @@ provides a file system (usually mounted at
 that includes one directory per USB serial port, named
 .BI eiaU N.
 In this directory there are two files,
-.BI eiaU N,
+.BI eiau N,
 similar to
 .BI eia N
 in
 .IR eia (3),
 and
-.BI eiaU N /ctl .
+.BI eiau N /ctl .
 .I Ctl
 admits writes in the same format as
 .BI eia N ctl

+ 20 - 0
sys/man/8/screenlock

@@ -0,0 +1,20 @@
+.TH SCREENLOCK 8
+.SH NAME
+screenlock \- disable access to a terminal
+.SH SYNOPSIS
+.B screenlock
+.SH DESCRIPTION
+.I Screenlock
+grabs the screen, keyboard, and mouse devices
+to disable access to the Plan 9 terminal on which it is run.
+The screen can be unlocked by typing the invoking user's Plan 9 password
+and a newline.
+.SH FILES
+.TF /lib/bunny.bit
+.TP
+.B /lib/bunny.bit
+the image displayed while the terminal is locked
+.SH SOURCE
+.B /sys/src/cmd/screenlock.c
+.SH BUGS
+Use of this program on communal terminals is anti-social.

+ 1 - 1
sys/src/9/kw/plug.words

@@ -1,6 +1,6 @@
 marvell or global scale sheevaplug
 
-marvell 88f6281 (feroceon kirkwood) SoC
+marvell 88f6281 (feroceon kirkwood) SoC; ours are revision A0
 arm926ej-s rev 1 [56251311] (armv5tejl) 1.2GHz cpu
 i & d caches 16K each, associativity 4, 32-byte lines, 128 sets
 512MB of dram at physical address 0

+ 272 - 0
sys/src/cmd/screenlock.c

@@ -0,0 +1,272 @@
+/* screenlock - lock a terminal */
+#include <u.h>
+#include <libc.h>
+#include <libsec.h>
+#include <draw.h>
+#include <thread.h>
+#include <auth.h>
+
+char pic[] = "/lib/bunny.bit";
+
+int vgactl;
+int debug;
+int doblank;
+int chatty = 0;
+
+char user[256];
+
+void
+blankscreen(int blank)
+{
+	if(vgactl < 0)
+		return;
+	seek(vgactl, 0, 0);
+	if(fprint(vgactl, blank? "blank": "unblank") < 0)
+		fprint(2, "blankscreen: can't blank: %r\n");
+}
+
+void
+error(char *fmt, ...)
+{
+	Fmt f;
+	char buf[64];
+	va_list arg;
+
+	fmtfdinit(&f, 1, buf, sizeof buf);
+	fmtprint(&f, "screenlock: ");
+	va_start(arg, fmt);
+	fmtvprint(&f, fmt, arg);
+	va_end(arg);
+	fmtprint(&f, "\n");
+	fmtfdflush(&f);
+	threadexitsall("fatal error");
+}
+
+void
+usage(void)
+{
+	fprint(2, "usage: %s\n", argv0);
+	exits("usage");
+}
+
+
+void
+readfile(char *name, char *buf, int nbuf, int addnul)
+{
+	int fd;
+
+	fd = open(name, OREAD);
+	if(fd == -1)
+		error("%s - can't open: %r", name);
+	nbuf = read(fd, buf, nbuf-addnul);
+	close(fd);
+	if(nbuf == -1)
+		error("%s - can't can't read: %r", name);
+	if(addnul)
+		buf[nbuf] = '\0';
+}
+
+void
+readline(char *buf, int nbuf)
+{
+	char c;
+	int i;
+
+	i = 0;
+	while(i < nbuf-1)
+		if(read(0, &c, 1) != 1 || c == '\04' || c == '\177'){
+			i = 0;
+			break;
+		} else if(c == '\n')
+			break;
+		else if(c == '\b' && i > 0)
+			--i;
+		else if(c == ('u' & 037))
+			i = 0;
+		else
+			buf[i++] = c;
+	buf[i] = '\0';
+}
+
+void
+checkpassword(void)
+{
+	int fd, consctl, must;
+	char buf[256];
+	AuthInfo *ai;
+	static int opened;
+
+	must = 1;
+	if(!opened){
+		fd = open("/dev/cons", OREAD);
+		if(fd == -1)
+			error("can't open cons: %r");
+		dup(fd, 0);
+		close(fd);
+		fd = open("/dev/cons", OWRITE);
+		if(fd == -1)
+			error("can't open cons: %r");
+		dup(fd, 1);
+		dup(1, 2);
+		close(fd);
+		consctl = open("/dev/consctl", OWRITE);
+		if(consctl == -1)
+			error("can't open consctl: %r");
+		if(write(consctl, "rawon", 5) != 5)
+			error("can't turn off echo\n");
+		opened = 1;
+	}
+
+	for(;;){
+		if(chatty || !must)
+			fprint(2, "%s's screenlock password: ", user);
+		memset(buf, 0, sizeof buf);
+		readline(buf, sizeof buf);
+		blankscreen(0);
+		if(chatty || !must)
+			fprint(2, "\n");
+		if(buf[0] == '\0' || buf[0] == '\04'){
+			if(must)
+				continue;
+			error("no password typed");
+		}
+
+		/* authenticate */
+		ai = auth_userpasswd(user, buf);
+		if(ai != nil && ai->cap != nil)
+			break;
+		auth_freeAI(ai);
+
+		if(chatty || !must)
+			fprint(2, "password mismatch\n");
+		doblank = 1;
+	}
+	memset(buf, 0, sizeof buf);
+	blankscreen(0);
+}
+
+void
+blanker(void *)
+{
+	int tics;
+
+	tics = 0;
+	for(;;){
+		if(doblank > 0){
+			doblank = 0;
+			tics = 10;
+		}
+		if(tics > 0 && --tics == 0)
+			blankscreen(1);
+		sleep(1000);
+	}
+}
+
+void
+grabmouse(void*)
+{
+	int fd, x, y;
+	char ibuf[256], obuf[256];
+
+	if(debug)
+		return;
+	fd = open("/dev/mouse", ORDWR);
+	if(fd < 0)
+		error("can't open /dev/mouse: %r");
+
+	snprint(obuf, sizeof obuf, "m %d %d",
+		screen->r.min.x + Dx(screen->r)/2,
+		screen->r.min.y + Dy(screen->r)/2);
+	while(read(fd, ibuf, sizeof ibuf) > 0){
+		ibuf[12] = 0;
+		ibuf[24] = 0;
+		x = atoi(ibuf+1);
+		y = atoi(ibuf+13);
+		if(x != screen->r.min.x + Dx(screen->r)/2 ||
+		   y != screen->r.min.y + Dy(screen->r)/2){
+			fprint(fd, "%s", obuf);
+			doblank = 1;
+		}
+	}
+}
+
+void
+lockscreen(void)
+{
+	enum { Nfld = 5, Fldlen = 12, Cursorlen = 2*4 + 2*2*16, };
+	char buf[Nfld*Fldlen], *flds[Nfld], newcmd[128], cbuf[Cursorlen];
+	int fd, dx, dy;
+	Image *i;
+	Rectangle r;
+
+	fd = open("/dev/screen", OREAD);
+	if(fd < 0)
+		error("can't open /dev/screen: %r");
+	if(read(fd, buf, Nfld*Fldlen) != Nfld*Fldlen)
+		error("can't read /dev/screen: %r");
+	close(fd);
+	buf[sizeof buf-1] = 0;
+	if(tokenize(buf, flds, Nfld) != Nfld)
+		error("can't tokenize /dev/screen header");
+	snprint(newcmd, sizeof newcmd, "-r %s %s %d %d",
+		flds[1], flds[2], atoi(flds[3]) - 1, atoi(flds[4]) - 1);
+	newwindow(newcmd);
+	initdraw(nil, nil, "screenlock");
+
+	if(display == nil)
+		error("no display");
+
+	/* screen is now open and covered.  grab mouse and hold on tight */
+	procrfork(grabmouse, nil, 4096, RFFDG);
+	procrfork(blanker, nil, 4096, RFFDG);
+	fd = open(pic, OREAD);
+	if(fd > 0){
+		i = readimage(display, fd, 0);
+		if(i){
+ 			r = screen->r;
+			dx = (Dx(screen->r) - Dx(i->r)) / 2;
+			r.min.x += dx;
+			r.max.x -= dx;
+			dy = (Dy(screen->r) - Dy(i->r)) / 2;
+			r.min.y += dy;
+			r.max.y -= dy;
+			draw(screen, screen->r, display->black, nil, ZP);
+			draw(screen, r, i, nil, i->r.min);
+			flushimage(display, 1);
+		}
+		close(fd);
+	}
+
+	/* clear the cursor */
+	fd = open("/dev/cursor", OWRITE);
+	if(fd > 0){
+		memset(cbuf, 0, sizeof cbuf);
+		write(fd, cbuf, sizeof cbuf);
+		/* leave it open */
+	}
+}
+
+void
+threadmain(int argc, char *argv[])
+{
+	readfile("#c/user", user, sizeof user, 1);
+
+	if((vgactl = open("/dev/vgactl", OWRITE)) < 0)
+		vgactl = open("#v/vgactl", OWRITE);
+
+	ARGBEGIN{
+	case 'd':
+		debug++;
+		break;
+	default:
+		usage();
+	}ARGEND
+
+	if(argc != 0)
+		usage();
+
+	doblank = 1;
+	lockscreen();
+	checkpassword();
+	threadexitsall(nil);
+}

+ 7 - 0
sys/src/cmd/usb/serial/serial.c

@@ -746,6 +746,13 @@ serialmain(Dev *dev, int argc, char* argv[])
 		return -1;
 	}
 
+	dirtab[Qdata].name = smprint("eiau%d", dev->id);
+	dirtab[Qctl].name  = smprint("eiau%dctl", dev->id);
+	/*
+	 * it would nice to get rid of this extra level of directory,
+	 * thus reducing /dev/eiaU6/eiau6* to /dev/eiau6*
+	 * for easier binding into /dev with `bind -a /dev/eiaU* /dev'.
+	 */
 	snprint(ser->fs.name, sizeof ser->fs.name, "eiaU%d", dev->id);
 	fprint(2, "%s\n", ser->fs.name);
 	ser->fs.dev = dev;