update lucida
diff --git a/src/cmd/draw/img.c b/src/cmd/draw/img.c
index 01caa3c..1e96192 100644
--- a/src/cmd/draw/img.c
+++ b/src/cmd/draw/img.c
@@ -50,6 +50,7 @@
 
 	if((image=readimage(display, fd, 0)) == nil)
 		sysfatal("readimage: %r");
+	sleep(1000);
 
 	drawresizewindow(Rect(0,0,Dx(image->r),Dy(image->r)));
 
@@ -60,6 +61,7 @@
 		case Ekeyboard:
 			if(e.kbdc == 'q' || e.kbdc == 0x7F)
 				exits(nil);
+			eresized(0);
 			break;
 		case Emouse:
 			break;
diff --git a/src/cmd/page/filter.c b/src/cmd/page/filter.c
index 07c3df2..319cfb6 100644
--- a/src/cmd/page/filter.c
+++ b/src/cmd/page/filter.c
@@ -1,6 +1,7 @@
 #include <u.h>
 #include <libc.h>
 #include <draw.h>
+#include <cursor.h>
 #include <event.h>
 #include <bio.h>
 #include "page.h"
diff --git a/src/cmd/page/gfx.c b/src/cmd/page/gfx.c
index 72254de..6a94703 100644
--- a/src/cmd/page/gfx.c
+++ b/src/cmd/page/gfx.c
@@ -5,6 +5,7 @@
 #include <u.h>
 #include <libc.h>
 #include <draw.h>
+#include <cursor.h>
 #include <event.h>
 #include <bio.h>
 #include "page.h"
@@ -71,6 +72,8 @@
 static Image*	gfxdrawpage(Document *d, int page);
 static char*	gfxpagename(Document*, int);
 static int	spawnrc(char*, uchar*, int);
+static void	waitrc(void);
+static int	spawnpost(int);
 static int	addpage(Document*, char*);
 static int	rmpage(Document*, int);
 static int	genaddpage(Document*, char*, uchar*, int);
@@ -97,6 +100,7 @@
 	int i;
 
 	USED(b);
+
 	doc = emalloc(sizeof(*doc));
 	gfx = emalloc(sizeof(*gfx));
 	gfx->g = nil;
diff --git a/src/cmd/page/gs.c b/src/cmd/page/gs.c
index 524701e..2093af5 100644
--- a/src/cmd/page/gs.c
+++ b/src/cmd/page/gs.c
@@ -7,6 +7,7 @@
 #include <u.h>
 #include <libc.h>
 #include <draw.h>
+#include <cursor.h>
 #include <event.h>
 #include <bio.h>
 #include "page.h"
@@ -134,7 +135,7 @@
 }
 
 int 
-spawngs(GSInfo *g)
+spawngs(GSInfo *g, char *safer)
 {
 	char *args[16];
 	char tb[32], gb[32];
@@ -158,7 +159,7 @@
 	nargs = 0;
 	args[nargs++] = "gs";
 	args[nargs++] = "-dNOPAUSE";
-	args[nargs++] = "-dSAFER";
+	args[nargs++] = safer;
 	args[nargs++] = "-sDEVICE=plan9";
 	args[nargs++] = "-sOutputFile=/fd/3";
 	args[nargs++] = "-dQUIET";
@@ -268,14 +269,11 @@
 	if(!Dx(bbox))
 		bbox = Rect(0, 0, 612, 792);	/* 8½×11 */
 
-	switch(landscape){
-	case 0:
-		pbox = bbox;
-		break;
-	case 1:
+	if(landscape)
 		pbox = Rect(bbox.min.y, bbox.min.x, bbox.max.y, bbox.max.x);
-		break;
-	}
+	else
+		pbox = bbox;
+
 	gscmd(gs, "/PageSize [%d %d]\n", Dx(pbox), Dy(pbox));
 	gscmd(gs, "/Margins [%d %d]\n", -pbox.min.x, -pbox.min.y);
 	gscmd(gs, "currentdevice putdeviceprops pop\n");
diff --git a/src/cmd/page/mkfile b/src/cmd/page/mkfile
index e8dbf52..0c4163a 100644
--- a/src/cmd/page/mkfile
+++ b/src/cmd/page/mkfile
@@ -14,7 +14,7 @@
 	util.$O\
 	view.$O\
 
-<$PLAN9/src//mkone
+<$PLAN9/src/mkone
 
 pdfprolog.c: pdfprolog.ps
 	cat pdfprolog.ps | sed 's/.*/"&\\n"/g' >pdfprolog.c
diff --git a/src/cmd/page/nrotate.c b/src/cmd/page/nrotate.c
index 2225ec3..65fe33a 100644
--- a/src/cmd/page/nrotate.c
+++ b/src/cmd/page/nrotate.c
@@ -15,6 +15,7 @@
 #include <libc.h>
 #include <bio.h>
 #include <draw.h>
+#include <cursor.h>
 #include <event.h>
 #include "page.h"
 
diff --git a/src/cmd/page/page.c b/src/cmd/page/page.c
index 3669ebf..4c76e03 100644
--- a/src/cmd/page/page.c
+++ b/src/cmd/page/page.c
@@ -1,6 +1,7 @@
 #include <u.h>
 #include <libc.h>
 #include <draw.h>
+#include <cursor.h>
 #include <event.h>
 #include <bio.h>
 #include "page.h"
@@ -19,43 +20,6 @@
 int stdinfd;
 int truecolor;
 int imagemode;
-int notewatcher;
-int notegp;
-
-int
-watcher(void *v, char *x)
-{
-	USED(v);
-
-	if(strcmp(x, "die") != 0)
-		postnote(PNGROUP, notegp, x);
-	_exits(0);
-	return 0;
-}
-
-int
-bell(void *u, char *x)
-{
-	if(x && strcmp(x, "hangup") == 0)
-		_exits(0);
-
-	if(x && strstr(x, "die") == nil)
-		fprint(2, "postnote %d: %s\n", getpid(), x);
-
-	/* alarms come from the gs monitor */
-	if(x && strstr(x, "alarm")){
-		postnote(PNGROUP, getpid(), "die (gs error)");
-		postnote(PNPROC, notewatcher, "die (gs error)");
-	}
-
-	/* function mentions u so that it's in the stack trace */
-	if((u == nil || u != x) && doabort)
-		abort();
-
-/*	fprint(2, "exiting %d\n", getpid()); */
-	wexits("note");
-	return 0;
-}
 
 static int
 afmt(Fmt *fmt)
@@ -128,23 +92,7 @@
 		usage();
 	}ARGEND;
 
-	notegp = getpid();
-
-	switch(notewatcher = fork()){
-	case -1:
-		sysfatal("fork\n");
-		exits(0);
-	default:
-		break;
-	case 0:
-		atnotify(watcher, 1);
-		for(;;)
-			sleep(1000);
-		_exits(0);
-	}
-
 	rfork(RFNOTEG);
-	atnotify(bell, 1);
 
 	readstdin = 0;
 	if(imagemode == 0 && argc == 0){
@@ -159,6 +107,8 @@
 
 	fmtinstall('R', Rfmt);
 	fmtinstall('P', Pfmt);
+	if(mknewwindow)
+		newwin();
 
 	if(readstdin){
 		b = nil;
@@ -229,8 +179,5 @@
 void
 wexits(char *s)
 {
-	if(s && *s && strcmp(s, "note") != 0 && mknewwindow)
-		sleep(10*1000);
-	postnote(PNPROC, notewatcher, "die");
 	exits(s);
 }
diff --git a/src/cmd/page/page.h b/src/cmd/page/page.h
index aa19ff7..be54e38 100644
--- a/src/cmd/page/page.h
+++ b/src/cmd/page/page.h
@@ -1,5 +1,3 @@
-#include <cursor.h>
-
 typedef struct Document Document;
 
 struct Document {
@@ -44,6 +42,7 @@
 
 void rot180(Image*);
 Image *rot90(Image*);
+Image *rot270(Image*);
 Image *resample(Image*, Image*);
 
 /* ghostscript interface shared by ps, pdf */
@@ -57,7 +56,7 @@
 };
 void	waitgs(GSInfo*);
 int	gscmd(GSInfo*, char*, ...);
-int	spawngs(GSInfo*);
+int	spawngs(GSInfo*, char*);
 void	setdim(GSInfo*, Rectangle, int, int);
 int	spawnwriter(GSInfo*, Biobuf*);
 Rectangle	screenrect(void);
diff --git a/src/cmd/page/pdf.c b/src/cmd/page/pdf.c
index 44615a2..d723ad8 100644
--- a/src/cmd/page/pdf.c
+++ b/src/cmd/page/pdf.c
@@ -7,6 +7,7 @@
 #include <u.h>
 #include <libc.h>
 #include <draw.h>
+#include <cursor.h>
 #include <event.h>
 #include <bio.h>
 #include "page.h"
@@ -97,14 +98,14 @@
 	d->pagename = pdfpagename;
 	d->fwdonly = 0;
 
-	if(spawngs(&pdf->gs) < 0)
+	if(spawngs(&pdf->gs, "-dDELAYSAFER") < 0)
 		return nil;
 
 	gscmd(&pdf->gs, "%s", pdfprolog);
 	waitgs(&pdf->gs);
 
 	setdim(&pdf->gs, Rect(0,0,0,0), ppi, 0);
-	gscmd(&pdf->gs, "(%s) (r) file pdfopen begin\n", fn);
+	gscmd(&pdf->gs, "(%s) (r) file { DELAYSAFER { .setsafe } if } stopped pop pdfopen begin\n", fn);
 	gscmd(&pdf->gs, "pdfpagecount PAGE==\n");
 	p = Brdline(&pdf->gs.gsrd, '\n');
 	npage = atoi(p);
@@ -121,11 +122,10 @@
 	pdf->pagebbox = emalloc(sizeof(Rectangle)*npage);
 	for(i=0; i<npage; i++) {
 		gscmd(&pdf->gs, "%d pdfgetpage\n", i+1);
-		pdf->pagebbox[i] = pdfbbox(&pdf->gs);
+		pdf->pagebbox[i] = pdfbbox(pdf);
 		if(Dx(pdf->pagebbox[i]) <= 0)
 			pdf->pagebbox[i] = bbox;
 	}
-
 	return d;
 }
 
@@ -149,6 +149,7 @@
 pdfpagename(Document *d, int page)
 {
 	static char str[15];
+	
 	USED(d);
 	sprint(str, "p %d", page+1);
 	return str;
diff --git a/src/cmd/page/ps.c b/src/cmd/page/ps.c
index 46ad5cd..cc6f3c5 100644
--- a/src/cmd/page/ps.c
+++ b/src/cmd/page/ps.c
@@ -7,6 +7,7 @@
 #include <u.h>
 #include <libc.h>
 #include <draw.h>
+#include <cursor.h>
 #include <event.h>
 #include <bio.h>
 #include <ctype.h>
@@ -348,7 +349,7 @@
 	d->fwdonly = ps->clueless = dumb;
 	d->docname = argv[0];
 
-	if(spawngs(&ps->gs) < 0)
+	if(spawngs(&ps->gs, "-dSAFER") < 0)
 		return nil;
 
 	if(!cantranslate)
diff --git a/src/cmd/page/rotate.c b/src/cmd/page/rotate.c
index b295263..9e1c20d 100644
--- a/src/cmd/page/rotate.c
+++ b/src/cmd/page/rotate.c
@@ -15,6 +15,7 @@
 #include <libc.h>
 #include <bio.h>
 #include <draw.h>
+#include <cursor.h>
 #include <event.h>
 #include "page.h"
 
@@ -54,6 +55,7 @@
 	drawop(tmp, tmp->r, im, nil, im->r.min, S);
 
 	switch(axis){
+	default:
 	case Xaxis:
 		range = Rect(a, im->r.min.y,  c, im->r.max.y);
 		dr0 = range;
@@ -88,6 +90,7 @@
 	r0 = im->r;
 	r1 = im->r;
 	switch(axis) {
+	default:
 	case Xaxis:
 		r0.max.x = n;
 		r1.min.x = n;
@@ -245,6 +248,31 @@
 	return(tmp);
 }
 
+/* rotates an image 270 degrees clockwise */
+Image *
+rot270(Image *im)
+{
+	Image *tmp;
+	int i, j, dx, dy;
+
+	dx = Dx(im->r);
+	dy = Dy(im->r);
+	tmp = xallocimage(display, Rect(0, 0, dy, dx), im->chan, 0, DCyan);
+	if(tmp == nil) {
+		fprint(2, "out of memory during rot270: %r\n");
+		wexits("memory");
+	}
+
+	for(i = 0; i < dy; i++) {
+		for(j = 0; j < dx; j++) {
+			drawop(tmp, Rect(i, j, i+1, j+1), im, nil, Pt(dx-(j+1), i), S);
+		}
+	}
+	freeimage(im);
+
+	return(tmp);
+}
+
 /* from resample.c -- resize from → to using interpolation */
 
 
@@ -288,6 +316,7 @@
 	return i0(alpha*sqrt(1-(x*x/(tau*tau))))/i0(alpha);
 }
 
+
 void
 resamplex(uchar *in, int off, int d, int inx, uchar *out, int outx)
 {
diff --git a/src/cmd/page/util.c b/src/cmd/page/util.c
index 22832ba..2669df8 100644
--- a/src/cmd/page/util.c
+++ b/src/cmd/page/util.c
@@ -1,6 +1,7 @@
 #include <u.h>
 #include <libc.h>
 #include <draw.h>
+#include <cursor.h>
 #include <event.h>
 #include <bio.h>
 #include "page.h"
diff --git a/src/cmd/page/view.c b/src/cmd/page/view.c
index 92aedeb..4321f82 100644
--- a/src/cmd/page/view.c
+++ b/src/cmd/page/view.c
@@ -6,6 +6,7 @@
 #include <libc.h>
 #include <draw.h>
 #include <cursor.h>
+#include <cursor.h>
 #include <event.h>
 #include <bio.h>
 #include <plumb.h>
@@ -16,7 +17,7 @@
 Document *doc;
 Image *im;
 int page;
-int upside = 0;
+int angle = 0;
 int showbottom = 0;		/* on the next showpage, move the image so the bottom is visible. */
 
 Rectangle ulrange;	/* the upper left corner of the image must be in this rectangle */
@@ -156,8 +157,17 @@
 		im = tmp;
 	}
 
-	if(upside)
+	switch(angle){
+	case 90:
+		im = rot90(im);
+		break;
+	case 180:
 		rot180(im);
+		break;
+	case 270:
+		im = rot270(im);
+		break;
+	}
 
 	esetcursor(nil);
 	if(showbottom){
@@ -390,7 +400,7 @@
 				esetcursor(&reading);
 				rot180(im);
 				esetcursor(nil);
-				upside = !upside;
+				angle = (angle+180) % 360;
 				redraw(screen);
 				flushimage(display, 1);
 				break;
@@ -589,6 +599,7 @@
 					esetcursor(&reading);
 					im = rot90(im);
 					esetcursor(nil);
+					angle = (angle+90) % 360;
 					redraw(screen);
 					flushimage(display, 1);
 					break;
@@ -598,7 +609,7 @@
 					esetcursor(&reading);
 					rot180(im);
 					esetcursor(nil);
-					upside = !upside;
+					angle = (angle+180) % 360;
 					redraw(screen);
 					flushimage(display, 1);
 					break;
@@ -978,6 +989,67 @@
 	return v;
 }
 
+void
+newwin(void)
+{
+	char *srv, *mntsrv;
+	char spec[100];
+	int srvfd, cons, pid;
+
+	switch(rfork(RFFDG|RFPROC|RFNAMEG|RFENVG|RFNOTEG|RFNOWAIT)){
+	case -1:
+		fprint(2, "page: can't fork: %r\n");
+		wexits("no fork");
+	case 0:
+		break;
+	default:
+		wexits(0);
+	}
+
+	srv = rdenv("/env/wsys");
+	if(srv == 0){
+		mntsrv = rdenv("/mnt/term/env/wsys");
+		if(mntsrv == 0){
+			fprint(2, "page: can't find $wsys\n");
+			wexits("srv");
+		}
+		srv = malloc(strlen(mntsrv)+10);
+		sprint(srv, "/mnt/term%s", mntsrv);
+		free(mntsrv);
+		pid  = 0;			/* can't send notes to remote processes! */
+	}else
+		pid = getpid();
+	srvfd = open(srv, ORDWR);
+	free(srv);
+	if(srvfd == -1){
+		fprint(2, "page: can't open %s: %r\n", srv);
+		wexits("no srv");
+	}
+	sprint(spec, "new -pid %d", pid);
+	if(mount(srvfd, -1, "/mnt/wsys", 0, spec) == -1){
+		fprint(2, "page: can't mount /mnt/wsys: %r (spec=%s)\n", spec);
+		wexits("no mount");
+	}
+	close(srvfd);
+	unmount("/mnt/acme", "/dev");
+	bind("/mnt/wsys", "/dev", MBEFORE);
+	cons = open("/dev/cons", OREAD);
+	if(cons==-1){
+	NoCons:
+		fprint(2, "page: can't open /dev/cons: %r");
+		wexits("no cons");
+	}
+	dup(cons, 0);
+	close(cons);
+	cons = open("/dev/cons", OWRITE);
+	if(cons==-1)
+		goto NoCons;
+	dup(cons, 1);
+	dup(cons, 2);
+	close(cons);
+//	wctlfd = open("/dev/wctl", OWRITE);
+}
+
 Rectangle
 screenrect(void)
 {
@@ -1011,7 +1083,7 @@
 		case 0: 
 			dup(pfd[1], 0);
 			close(pfd[0]);
-			execl("/bin/page", "page", "-w", 0);
+			execl("/bin/page", "page", "-w", nil);
 			wexits("cannot exec in zerox: %r\n");
 		default:
 			close(pfd[1]);
diff --git a/src/cmd/rc/lex.c b/src/cmd/rc/lex.c
index 798ffe8..b0e27eb 100644
--- a/src/cmd/rc/lex.c
+++ b/src/cmd/rc/lex.c
@@ -113,7 +113,7 @@
 }
 char *addtok(char *p, int val){
 	if(p==0) return 0;
-	if(p==&tok[NTOK]){
+	if(p==&tok[NTOK-1]){
 		*p=0;
 		yyerror("token buffer too short");
 		return 0;
diff --git a/src/cmd/sam/io.c b/src/cmd/sam/io.c
index 95c2e0c..8b6f281 100644
--- a/src/cmd/sam/io.c
+++ b/src/cmd/sam/io.c
@@ -226,7 +226,7 @@
 	// count args
 	for(av = argv; *av; av++)
 		;
-	av = malloc(sizeof(char*)*((av-argv) + 5));
+	av = malloc(sizeof(char*)*((av-argv) + 10));
 	if(av == nil){
 		dprint("out of memory\n");
 		exits("fork/exec");
@@ -234,6 +234,8 @@
 	ac = 0;
 	av[ac++] = RX;
 	av[ac++] = machine;
+	if(rxopt)
+		av[ac++] = rxopt;
 	av[ac++] = rsamname;
 	av[ac++] = "-R";
 	while(*argv)
diff --git a/src/cmd/sam/sam.c b/src/cmd/sam/sam.c
index 0ade9c2..01893cb 100644
--- a/src/cmd/sam/sam.c
+++ b/src/cmd/sam/sam.c
@@ -30,6 +30,7 @@
 long	seq;
 
 char *winsize;
+char *rxopt;
 
 Rune	baddir[] = { '<', 'b', 'a', 'd', 'd', 'i', 'r', '>', '\n'};
 
@@ -56,6 +57,9 @@
 	case 'R':
 		Rflag++;
 		break;
+	case 'O':
+		rxopt = EARGF(usage());
+		break;
 	case 't':
 		samterm = EARGF(usage());
 		break;
@@ -118,7 +122,7 @@
 void
 usage(void)
 {
-	dprint("usage: sam [-d] [-t samterm] [-s sam name] -r machine\n");
+	dprint("usage: sam [-d] [-t samterm] [-s sam name] [-r machine] [file ...]\n");
 	exits("usage");
 }
 
diff --git a/src/cmd/sam/sam.h b/src/cmd/sam/sam.h
index eefb4b3..bb88c33 100644
--- a/src/cmd/sam/sam.h
+++ b/src/cmd/sam/sam.h
@@ -348,6 +348,7 @@
 extern char	SHPATH[];
 extern char	RX[];
 extern char	RXPATH[];
+extern char	*rxopt;
 
 /*
  * acme globals
diff --git a/src/cmd/upas/smtp/smtp.c b/src/cmd/upas/smtp/smtp.c
index 0661f4c..d3297df 100644
--- a/src/cmd/upas/smtp/smtp.c
+++ b/src/cmd/upas/smtp/smtp.c
@@ -754,6 +754,8 @@
 	reply = s_reset(reply);
 	for(;;){
 		line = getcrnl(reply);
+		if(debug)
+			Bflush(&berr);
 		if(line == 0)
 			return -1;
 		if(!isdigit(line[0]) || !isdigit(line[1]) || !isdigit(line[2]))
@@ -761,8 +763,6 @@
 		if(line[3] != '-')
 			break;
 	}
-	if(debug)
-		Bflush(&berr);
 	rv = atoi(line)/100;
 	return rv;
 }
@@ -999,6 +999,7 @@
 		case '\r':
 			c = Bgetc(&bin);
 			if(c == '\n'){
+		case '\n':
 				s_putc(s, c);
 				if(debug)
 					Bputc(&berr, c);