Переглянути джерело

Plan 9 from Bell Labs Fourth Edition 2002-05-23

David du Colombier 22 роки тому
батько
коміт
5d459b5a09
100 змінених файлів з 11419 додано та 3510 видалено
  1. 1 1
      acme/mail/src/dat.h
  2. 3 4
      acme/mail/src/mail.c
  3. 114 6
      acme/mail/src/mesg.c
  4. 0 0
      acme/mail/src/name
  5. 5 2
      acme/mail/src/reply.c
  6. 1 0
      acme/mail/src/util.c
  7. 1 0
      acme/mail/src/win.c
  8. 4 2
      dist/replica/network
  9. 187 176
      dist/replica/plan9.db
  10. 353 0
      dist/replica/plan9.log
  11. 1 0
      dist/replica/plan9.proto
  12. 376 346
      lib/areacodes
  13. 2 0
      lib/font/bit/lucm/passwd.9.font
  14. 128 32
      lib/ndb/common
  15. 1 0
      lib/ndb/local
  16. 2 0
      lib/ndb/local.complicated
  17. 2 0
      lib/vgadb
  18. 30 0
      mail/lib/rewrite.direct
  19. 29 0
      mail/lib/rewrite.gateway
  20. 2 0
      rc/bin/9fs
  21. 5 1
      rc/bin/kill
  22. 5 2
      rc/bin/man
  23. 3 0
      rc/bin/pci
  24. 2 0
      rc/bin/reboot
  25. BIN
      sys/doc/-.2669382.gif
  26. 868 0
      sys/doc/8½/8½.html
  27. 1351 0
      sys/doc/acme/acme.html
  28. BIN
      sys/doc/acme/acme.pdf
  29. 440 2018
      sys/doc/auth.html
  30. 100 78
      sys/doc/auth.ms
  31. 688 686
      sys/doc/auth.ps
  32. 837 0
      sys/doc/fs/fs.html
  33. BIN
      sys/doc/fs/fs.pdf
  34. 427 0
      sys/doc/il/il.html
  35. BIN
      sys/doc/il/il.pdf
  36. 36 37
      sys/doc/libmach.html
  37. 1 2
      sys/doc/libmach.ms
  38. 1 1
      sys/doc/mkfile
  39. 1379 0
      sys/doc/net/net.html
  40. BIN
      sys/doc/net/net.pdf
  41. 3291 0
      sys/doc/sam/sam.html
  42. BIN
      sys/doc/sam/sam.pdf
  43. 8 0
      sys/doc/venti/mkfile
  44. 4 0
      sys/doc/venti/venti.pdf
  45. 1 0
      sys/include/fcall.h
  46. 2 1
      sys/include/libc.h
  47. 169 0
      sys/lib/acid/network
  48. 26 9
      sys/lib/dist/mkfile
  49. 1 1
      sys/lib/dist/pc/inst/bootwin9x
  50. 1 1
      sys/lib/dist/pc/proto
  51. 1 1
      sys/lib/dist/pc/sub/boota:
  52. 1 0
      sys/lib/dist/pc/sub/termrc
  53. 1 1
      sys/lib/plumb/basic
  54. 4 1
      sys/lib/tmac/tmac.s
  55. 0 1
      sys/log/dns
  56. 5 1
      sys/man/1/cat
  57. 17 2
      sys/man/1/con
  58. 1 5
      sys/man/1/replica
  59. 1 1
      sys/man/1/secstore
  60. 4 1
      sys/man/1/ssh
  61. 8 0
      sys/man/1/vac
  62. 3 3
      sys/man/2/control
  63. 26 14
      sys/man/2/fcall
  64. 1 1
      sys/man/2/graphics
  65. 3 3
      sys/man/2/thread
  66. 1 1
      sys/man/4/consolefs
  67. 4 1
      sys/man/4/factotum
  68. 4 1
      sys/man/4/vacfs
  69. 5 0
      sys/man/8/boot
  70. 34 11
      sys/man/8/kfscmd
  71. 3 0
      sys/man/8/plan9.ini
  72. 3 3
      sys/man/8/replica
  73. 1 1
      sys/man/preface4.html
  74. 0 0
      sys/man/searchindex
  75. 6 6
      sys/src/9/bitsy/Booting101
  76. 175 0
      sys/src/9/bitsy/paqfiles/cpurc
  77. 6 0
      sys/src/9/bitsy/paqfiles/local
  78. 32 0
      sys/src/9/bitsy/paqfiles/mfs
  79. 53 0
      sys/src/9/bitsy/paqfiles/namespace
  80. 9 0
      sys/src/9/bitsy/paqfiles/startip
  81. 5 0
      sys/src/9/bitsy/paqfiles/unicode.6.font
  82. 5 1
      sys/src/9/port/auth.c
  83. 1 0
      sys/src/boot/pc/boot.c
  84. 4 3
      sys/src/boot/pc/console.c
  85. 23 0
      sys/src/boot/pc/devfloppy.c
  86. 1 0
      sys/src/boot/pc/devsd.c
  87. 3 0
      sys/src/boot/pc/fns.h
  88. 1 0
      sys/src/boot/pc/inflate.c
  89. 1 5
      sys/src/boot/pc/l.s
  90. 3 4
      sys/src/boot/pc/load.c
  91. 3 1
      sys/src/cmd/9660srv/iobuf.c
  92. 2 0
      sys/src/cmd/acme/exec.c
  93. 31 20
      sys/src/cmd/acme/mkfile
  94. 3 0
      sys/src/cmd/auth/factotum/dat.h
  95. 3 1
      sys/src/cmd/auth/factotum/fs.c
  96. 2 4
      sys/src/cmd/auth/factotum/p9sk1.c
  97. 16 0
      sys/src/cmd/auth/factotum/util.c
  98. 1 1
      sys/src/cmd/auth/secstore/password.c
  99. 10 4
      sys/src/cmd/auth/secstore/secstore.c
  100. 1 1
      sys/src/cmd/auth/secstore/util.c

+ 1 - 1
acme/mail/src/dat.h

@@ -116,7 +116,7 @@ extern	void		winsetdump(Window*, char*, char*);
 extern	void		readmbox(Message*, char*, char*);
 extern	void		rewritembox(Window*, Message*);
 
-extern	void		mkreply(Message*, char*, char*);
+extern	void		mkreply(Message*, char*, char*, Plumbattr*);
 extern	void		delreply(Message*);
 
 extern	int		mesgadd(Message*, char*, Dir*, char*);

+ 3 - 4
acme/mail/src/mail.c

@@ -328,8 +328,7 @@ plumbsendthread(void*)
 
 	threadsetname("plumbsendthread");
 	while((m = recvp(cplumbsend)) != nil){
-		mkreply(nil, "Mail", m->data);
-
+		mkreply(nil, "Mail", m->data, m->attr);
 		plumbfree(m);
 	}
 	threadexits(nil);
@@ -348,9 +347,9 @@ mboxcommand(Window *w, char *s)
 		return 0;
 	if(strcmp(args[0], "Mail") == 0){
 		if(nargs == 1)
-			mkreply(nil, "Mail", "");
+			mkreply(nil, "Mail", "", nil);
 		else
-			mkreply(nil, "Mail", args[1]);
+			mkreply(nil, "Mail", args[1], nil);
 		return 1;
 	}
 	if(strcmp(s, "Del") == 0){

+ 114 - 6
acme/mail/src/mesg.c

@@ -609,16 +609,16 @@ mesgcommand(Message *m, char *cmd)
 	}
 	if(strcmp(args[0], "Reply")==0){
 		if(nargs>=2 && strcmp(args[1], "all")==0)
-			mkreply(m, "Replyall", nil);
+			mkreply(m, "Replyall", nil, nil);
 		else
-			mkreply(m, "Reply", nil);
+			mkreply(m, "Reply", nil, nil);
 		goto Return;
 	}
 	if(strcmp(args[0], "Q") == 0){
 		if(nargs>=3 && strcmp(args[1], "Reply")==0 && strcmp(args[2], "all")==0)
-			mkreply(m, "QReplyall", nil);
+			mkreply(m, "QReplyall", nil, nil);
 		else
-			mkreply(m, "QReply", nil);
+			mkreply(m, "QReply", nil, nil);
 		goto Return;
 	}
 	if(strcmp(args[0], "Del") == 0){
@@ -672,6 +672,111 @@ mesgtagpost(Message *m)
 	m->tagposted = 1;
 }
 
+/* need to expand selection more than default word */
+#pragma varargck argpos eval 2
+
+long
+eval(Window *w, char *s, ...)
+{
+	char buf[64];
+	va_list arg;
+
+	va_start(arg, s);
+	vsnprint(buf, sizeof buf, s, arg);
+	va_end(arg);
+
+	if(winsetaddr(w, buf, 1)==0)
+		return -1;
+
+	if(pread(w->addr, buf, 24, 0) != 24)
+		return -1;
+	return strtol(buf, 0, 10);
+}
+
+int
+isemail(char *s)
+{
+	int nat;
+
+	nat = 0;
+	for(; *s; s++)
+		if(*s == '@')
+			nat++;
+		else if(!isalpha(*s) && !isdigit(*s) && !strchr("_.-+/", *s))
+			return 0;
+	return nat==1;
+}
+
+char addrdelim[] =  "/[ \t\\n<>()\\[\\]]/";
+char*
+expandaddr(Window *w, Event *e)
+{
+	char *s;
+	long q0, q1;
+
+	if(e->q0 != e->q1)	/* cannot happen */
+		return nil;
+
+	q0 = eval(w, "#%d-%s", e->q0, addrdelim);
+	if(q0 == -1)	/* bad char not found */
+		q0 = 0;
+	else			/* increment past bad char */
+		q0++;
+
+	q1 = eval(w, "#%d+%s", e->q0, addrdelim);
+	if(q1 < 0){
+		q1 = eval(w, "$");
+		if(q1 < 0)
+			return nil;
+	}
+	if(q0 >= q1)
+		return nil;
+	s = emalloc((q1-q0)*UTFmax+1);
+	winread(w, q0, q1, s);
+	return s;
+}
+
+int
+replytoaddr(Window *w, Message *m, Event *e, char *s)
+{
+	int did;
+	char *buf;
+	Plumbmsg *pm;
+
+	buf = nil;
+	did = 0;
+	if(e->flag & 2){
+		/* autoexpanded; use our own bigger expansion */
+		buf = expandaddr(w, e);
+		if(buf == nil)
+			return 0;
+		s = buf;
+	}
+	if(isemail(s)){
+		did = 1;
+		pm = emalloc(sizeof(Plumbmsg));
+		pm->src = estrdup("Mail");
+		pm->dst = estrdup("sendmail");
+		pm->data = estrdup(s);
+		pm->ndata = -1;
+		if(m->subject && m->subject[0]){
+			pm->attr = emalloc(sizeof(Plumbattr));
+			pm->attr->name = estrdup("Subject");
+			if(tolower(m->subject[0]) != 'r' || tolower(m->subject[1]) != 'e' || m->subject[2] != ':')
+				pm->attr->value = estrstrdup("Re: ", m->subject);
+			else
+				pm->attr->value = estrdup(m->subject);
+			pm->attr->next = nil;
+		}
+		if(plumbsend(plumbsendfd, pm) < 0)
+			fprint(2, "error writing plumb message: %r\n");
+		plumbfree(pm);
+	}
+	free(buf);
+	return did;
+}
+
+
 void
 mesgctl(void *v)
 {
@@ -679,7 +784,7 @@ mesgctl(void *v)
 	Window *w;
 	Event *e, *eq, *e2, *ea;
 	int na, nopen, i, j;
-	char *s, *t, *buf;
+	char *os, *s, *t, *buf;
 
 	m = v;
 	w = m->w;
@@ -745,6 +850,7 @@ mesgctl(void *v)
 					winread(w, eq->q0, eq->q1, buf);
 					s = buf;
 				}
+				os = s;
 				nopen = 0;
 				do{
 					/* skip mail box name if present */
@@ -766,7 +872,9 @@ mesgctl(void *v)
 					while(*s!=0 && *s++!='\n')
 						;
 				}while(*s);
-				if(nopen == 0)	/* send it back */
+				if(nopen == 0)
+					nopen += replytoaddr(w, m, e, os);
+				if(nopen == 0)
 					winwriteevent(w, e);
 				free(buf);
 				break;

+ 0 - 0
acme/mail/src/name


+ 5 - 2
acme/mail/src/reply.c

@@ -61,11 +61,12 @@ quote(Message *m, Biobuf *b, char *dir)
 }
 
 void
-mkreply(Message *m, char *label, char *to)
+mkreply(Message *m, char *label, char *to, Plumbattr *attr)
 {
 	Message *r;
 	char *dir, *t;
 	int quotereply;
+	Plumbattr *a;
 
 	quotereply = (label[0] == 'Q');
 	r = emalloc(sizeof(Message));
@@ -89,10 +90,12 @@ mkreply(Message *m, char *label, char *to)
 	winopenbody(r->w, OWRITE);
 	if(to!=nil && to[0]!='\0')
 		Bprint(r->w->body, "%s\n", to);
+	for(a=attr; a; a=a->next)
+		Bprint(r->w->body, "%s: %s\n", a->name, a->value);
 	dir = nil;
 	if(m != nil){
 		dir = estrstrdup(mbox.name, m->name);
-		if(to == nil){
+		if(to == nil && attr == nil){
 			/* Reply goes to replyto; Reply all goes to From and To and CC */
 			if(strstr(label, "all") == nil)
 				Bprint(r->w->body, "To: %s\n", m->replyto);

+ 1 - 0
acme/mail/src/util.c

@@ -2,6 +2,7 @@
 #include <libc.h>
 #include <bio.h>
 #include <thread.h>
+#include <plumb.h>
 #include "dat.h"
 
 void*

+ 1 - 0
acme/mail/src/win.c

@@ -2,6 +2,7 @@
 #include <libc.h>
 #include <bio.h>
 #include <thread.h>
+#include <plumb.h>
 #include "dat.h"
 
 Window*

+ 4 - 2
dist/replica/network

@@ -4,13 +4,15 @@ s=/n/dist/dist/replica
 serverroot=/n/dist
 serverlog=$s/plan9.log
 serverproto=$s/plan9.proto
-fn servermount { XXX } 
+fn servermount {
+	srv tcp!sources.cs.bell-labs.com sources /n/sources
+	bind /n/sources/plan9 /n/dist
+}
 fn serverupdate { status='' }
 
 fn clientmount { 9fs kfs }
 c=/n/kfs/dist/replica
 clientroot=/n/kfs
-clientproto=$c/plan9.proto
 clientdb=$c/client/plan9.db
 clientexclude=(dist/replica/client)
 clientlog=$c/client/plan9.log

Різницю між файлами не показано, бо вона завелика
+ 187 - 176
dist/replica/plan9.db


+ 353 - 0
dist/replica/plan9.log

@@ -11401,3 +11401,356 @@
 1020377946 11401 a usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 1020377946 11402 a usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 1020377946 11403 a usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0
+1020713931 0 a 386/bin/upas/list - 775 sys sys 1020713734 80905
+1020713931 1 c lib/ndb/common - 664 sys sys 1020400334 4749
+1020713931 2 c sys/lib/dist/pc/inst/bootwin9x - 775 sys sys 1020384273 2525
+1020713931 3 c sys/lib/dist/pc/proto - 664 sys sys 1020384262 3724
+1020713931 10 c sys/doc/mkfile - 664 sys sys 1020485220 4201
+1020713931 12 c sys/doc/libmach.html - 664 sys sys 1020485624 26336
+1020713931 41 c sys/man/preface4.html - 664 sys sys 1020399749 2640
+1020713931 42 a sys/src/cmd/unix/drawterm/README.MACOSX - 664 sys sys 1020578504 57
+1020713931 43 c sys/src/cmd/upas/mkfile - 664 sys sys 1020713795 1705
+1021922494 0 c usr/glenda/lib/profile - 664 glenda glenda 1021580005 847
+1021922494 1 c 386/bin/acme - 775 sys sys 1021915578 413211
+1021922494 2 c 386/bin/venti/buildindex - 775 sys sys 1020319083 222602
+1021922494 3 c 386/bin/venti/checkarenas - 775 sys sys 1020319084 225605
+1021922494 4 c 386/bin/venti/checkindex - 775 sys sys 1020319084 223420
+1021922494 5 c 386/bin/venti/clumpstats - 775 sys sys 1020319084 212619
+1021922494 6 c 386/bin/venti/findscore - 775 sys sys 1020319084 197220
+1021922494 7 c 386/bin/venti/fmtarenas - 775 sys sys 1020319085 198342
+1021922494 8 c 386/bin/venti/fmtindex - 775 sys sys 1020319085 212282
+1021922494 9 c 386/bin/venti/fmtisect - 775 sys sys 1020319085 212882
+1021922494 10 c 386/bin/venti/rdarena - 775 sys sys 1020319086 196951
+1021922494 11 c 386/bin/venti/sync - 775 sys sys 1020319086 236334
+1021922494 12 c 386/bin/venti/venti - 775 sys sys 1020319086 291126
+1021922494 13 c 386/bin/venti/verifyarena - 775 sys sys 1020319086 171707
+1021922494 14 c 386/bin/cpu - 775 sys sys 1020319008 136709
+1021922494 15 c 386/bin/aux/listen - 775 sys sys 1020319064 103622
+1021922494 16 c 386/lib/libauth.a - 664 sys sys 1019878400 52892
+1021922494 17 c 386/lib/lib9p.a - 664 sys sys 1021580210 71900
+1021922494 18 c 386/lib/libc.a - 664 sys sys 1021580201 496528
+1021922494 19 c 386/lib/libip.a - 664 sys sys 1021580199 32574
+1021922494 20 c 386/lib/libhtml.a - 664 sys sys 1021580171 220944
+1021922494 21 c lib/ndb/common - 664 sys sys 1021579967 5168
+1021922494 22 c lib/vgadb - 664 sys sys 1021579967 26829
+1021922494 23 c lib/areacodes - 664 sys sys 1021579968 26202
+1021922494 24 a mnt/news - 20000000775 sys sys 1020896385 0
+1021922494 25 m n/dist - 20000000555 sys sys 1020896384 0
+1021922494 26 c rc/bin/man - 775 sys sys 1021579956 2011
+1021922494 27 c sys/include/fcall.h - 664 sys sys 1021579968 3061
+1021922494 28 c sys/include/libc.h - 664 sys sys 1021579968 18767
+1021922494 29 c sys/lib/tmac/tmac.s - 664 sys sys 1021579968 23029
+1021922494 30 c sys/lib/troff/font/devutf/charlib/☺ - 664 sys sys 1020895801 468
+1021922494 31 c sys/lib/man/lookman/index - 664 sys sys 1021580074 1335770
+1021922494 32 c sys/lib/dist/mkfile - 664 sys sys 1021579973 2296
+1021922494 33 c sys/lib/dist/pc/sub/boota: - 664 sys sys 1021579974 392
+1021922494 34 c sys/doc/8½/fig1.ps - 664 sys sys 1020895859 473747
+1021922494 35 c sys/doc/8½/8½.ms - 664 sys sys 1020895859 31593
+1021922494 36 c sys/doc/8½/8½.ps - 664 sys sys 1020895860 797150
+1021922494 37 c sys/doc/8½/mkfile - 664 sys sys 1020895860 215
+1021922494 38 c sys/doc/8½/8½.pdf - 664 sys sys 1020895860 81874
+1021922494 39 c sys/doc/8½/8½.html - 664 sys sys 1020895860 33484
+1021922494 40 c sys/doc/libmach.ms - 664 sys sys 1021579974 24145
+1021922494 41 c sys/doc/auth.ms - 664 sys sys 1021579975 66803
+1021922494 42 c sys/doc/auth.ps - 664 sys sys 1021579976 451672
+1021922494 43 c sys/doc/auth.html - 444 sys sys 1021580026 68719
+1021922494 44 c sys/doc/auth.pdf - 664 sys sys 1021579977 118559
+1021922494 45 c sys/man/1/vac - 664 sys sys 1021579977 3227
+1021922494 46 c sys/man/1/ssh - 664 sys sys 1021579977 6732
+1021922494 47 c sys/man/1/secstore - 664 sys sys 1021579978 2279
+1021922494 48 c sys/man/8/kfscmd - 664 sys sys 1021579978 4056
+1021922494 49 c sys/man/8/boot - 664 sys sys 1021579978 5708
+1021922494 50 c sys/man/8/plan9.ini - 664 sys sys 1021579978 20464
+1021922494 51 c sys/man/8/replica - 664 sys sys 1021579979 6239
+1021922494 52 c sys/man/searchindex - 664 sys sys 1021579981 646934
+1021922494 53 c sys/man/2/graphics - 664 sys sys 1021579981 12660
+1021922494 54 c sys/man/2/fcall - 664 sys sys 1021579981 7266
+1021922494 55 c sys/man/2/thread - 664 sys sys 1021579982 11663
+1021922494 56 c sys/man/2/control - 664 sys sys 1021579982 42778
+1021922494 57 c sys/man/4/factotum - 664 sys sys 1021579982 13900
+1021922494 58 c sys/src/9/port/auth.c - 664 sys sys 1021641505 2309
+1021922494 59 c sys/src/9/bitsy/devµc.c - 664 sys sys 1020895966 7731
+1021922494 60 c sys/src/boot/pc/boot.c - 664 sys sys 1021579983 3353
+1021922494 61 c sys/src/boot/pc/console.c - 664 sys sys 1021579983 3420
+1021922494 62 c sys/src/boot/pc/devfloppy.c - 664 sys sys 1021579983 15535
+1021922494 63 c sys/src/boot/pc/devsd.c - 664 sys sys 1021579983 10675
+1021922494 64 c sys/src/boot/pc/fns.h - 664 sys sys 1021579984 4012
+1021922494 65 c sys/src/boot/pc/inflate.c - 664 sys sys 1021579984 2802
+1021922494 66 c sys/src/boot/pc/l.s - 664 sys sys 1021579984 12963
+1021922494 67 c sys/src/boot/pc/load.c - 664 sys sys 1021579984 7797
+1021922494 68 c sys/src/cmd/vnc/vncs.c - 664 sys sys 1021579985 20352
+1021922494 69 c sys/src/cmd/auth/secstore/password.c - 664 sys sys 1021579985 2581
+1021922494 70 c sys/src/cmd/auth/secstore/secstore.c - 664 sys sys 1021579985 10671
+1021922494 71 c sys/src/cmd/auth/secstore/util.c - 664 sys sys 1021579985 1498
+1021922494 72 c sys/src/cmd/auth/factotum/dat.h - 664 sys sys 1021579986 4657
+1021922494 73 c sys/src/cmd/auth/factotum/fs.c - 664 sys sys 1021579986 10093
+1021922494 74 c sys/src/cmd/auth/factotum/p9sk1.c - 664 sys sys 1021579986 9413
+1021922494 75 c sys/src/cmd/auth/factotum/util.c - 664 sys sys 1021579987 16560
+1021922494 76 c sys/src/cmd/aux/vga/virge.c - 664 sys sys 1021579987 16527
+1021922494 77 c sys/src/cmd/aux/timesync.c - 664 sys sys 1021579987 23094
+1021922494 78 c sys/src/cmd/disk/kfs/sub.c - 664 sys sys 1021579988 10775
+1021922494 79 c sys/src/cmd/disk/kfs/con.c - 664 sys sys 1021579988 12681
+1021922494 80 c sys/src/cmd/disk/kfs/9p1.c - 664 sys sys 1021579988 24971
+1021922494 81 c sys/src/cmd/disk/kfs/9p1.h - 664 sys sys 1021579989 2261
+1021922494 82 c sys/src/cmd/disk/9660/dump.c - 664 sys sys 1021579989 9572
+1021922494 83 c sys/src/cmd/disk/9660/ichar.c - 664 sys sys 1021579989 4828
+1021922494 84 c sys/src/cmd/disk/9660/path.c - 664 sys sys 1021579989 3643
+1021922494 85 c sys/src/cmd/disk/9660/write.c - 664 sys sys 1021579990 8764
+1021922494 86 c sys/src/cmd/disk/rd9660.c - 664 sys sys 1021579990 7446
+1021922494 87 c sys/src/cmd/ip/ftpfs/ftpfs.c - 664 sys sys 1021579990 13447
+1021922494 88 c sys/src/cmd/ip/ipconfig.c - 664 sys sys 1021579991 27772
+1021922494 89 c sys/src/cmd/paqfs/paqfs.c - 664 sys sys 1021579991 18326
+1021922494 90 c sys/src/cmd/acme/exec.c - 664 sys sys 1021579991 26915
+1021922494 91 c sys/src/cmd/acme/mkfile - 664 sys sys 1021915577 529
+1021922494 92 c sys/src/cmd/ndb/convDNS2M.c - 664 sys sys 1021579991 6525
+1021922494 93 c sys/src/cmd/ndb/convM2DNS.c - 664 sys sys 1021579992 6684
+1021922494 94 c sys/src/cmd/ndb/dblookup.c - 664 sys sys 1021579992 17169
+1021922494 95 c sys/src/cmd/ndb/dn.c - 664 sys sys 1021579993 23706
+1021922494 96 c sys/src/cmd/ndb/dnresolve.c - 664 sys sys 1021579993 14960
+1021922494 97 c sys/src/cmd/ndb/dns.h - 664 sys sys 1021579993 8014
+1021922494 98 c sys/src/cmd/ndb/dnsdebug.c - 664 sys sys 1021579993 8278
+1021922494 99 c sys/src/cmd/ndb/dnserver.c - 664 sys sys 1021579994 3687
+1021922494 100 c sys/src/cmd/bzip2/bunzip2.c - 664 sys sys 1021579994 3456
+1021922494 101 c sys/src/cmd/faces/facedb.c - 664 sys sys 1021579994 8976
+1021922494 102 c sys/src/cmd/ssh/cmsg.c - 664 sys sys 1021579994 8373
+1021922494 103 c sys/src/cmd/ssh/ssh.c - 664 sys sys 1021579995 8726
+1021922494 104 c sys/src/cmd/ssh/ssh.h - 664 sys sys 1021579995 5526
+1021922494 105 c sys/src/cmd/ssh/sshnet.c - 664 sys sys 1021579995 17308
+1021922494 106 c sys/src/cmd/telco/telco.c - 664 sys sys 1021579996 26253
+1021922494 107 c sys/src/cmd/upas/pop3/pop3.c - 664 sys sys 1021579996 14144
+1021922494 108 c sys/src/cmd/upas/fs/fs.c - 664 sys sys 1021579996 27297
+1021922494 109 c sys/src/cmd/upas/fs/mbox.c - 664 sys sys 1021579996 26745
+1021922494 110 c sys/src/cmd/upas/fs/dat.h - 664 sys sys 1021579997 4246
+1021922494 111 c sys/src/cmd/replica/util.c - 664 sys sys 1021579997 1998
+1021922494 112 c sys/src/cmd/vac/dat.h - 664 sys sys 1021579997 4004
+1021922494 113 c sys/src/cmd/vac/vac.c - 664 sys sys 1021579998 23246
+1021922494 114 c sys/src/cmd/vac/vacfs.c - 664 sys sys 1021579998 12494
+1021922494 115 c sys/src/cmd/venti/dat.h - 664 sys sys 1021579998 15232
+1021922494 116 c sys/src/cmd/venti/fmtisect.c - 664 sys sys 1021579998 1290
+1021922494 117 c sys/src/cmd/venti/fns.h - 664 sys sys 1021579999 6757
+1021922494 118 c sys/src/cmd/venti/icache.c - 664 sys sys 1021579999 3943
+1021922494 119 c sys/src/cmd/venti/lump.c - 664 sys sys 1021921840 3810
+1021922494 120 c sys/src/cmd/venti/mkfile - 664 sys sys 1021921834 1066
+1021922494 121 c sys/src/cmd/page/rotate.c - 664 sys sys 1021579999 4709
+1021922494 122 c sys/src/cmd/mkmany - 664 sys sys 1021580000 1156
+1021922494 123 c sys/src/cmd/cpu.c - 664 sys sys 1021580000 20188
+1021922494 124 c sys/src/cmd/cp.c - 664 sys sys 1021580000 2928
+1021922494 125 c sys/src/lib9p/srv.c - 664 sys sys 1021580001 14489
+1021922494 126 c sys/src/lib9p/tpost.c - 664 sys sys 1021580001 1268
+1021922494 127 c sys/src/libauth/newns.c - 664 sys sys 1019058720 5694
+1021922494 128 c sys/src/libc/9sys/convS2M.c - 664 sys sys 1021580001 5014
+1021922494 129 c sys/src/libhtml/build.c - 664 sys sys 1021580002 94822
+1021922494 130 c sys/src/libhtml/impl.h - 664 sys sys 1021580002 4627
+1021922494 131 c sys/src/libhtml/utils.c - 664 sys sys 1021580002 9745
+1021922494 132 c sys/src/libframe/frselect.c - 664 sys sys 1021580002 2623
+1021922494 133 c sys/src/libip/readipifc.c - 664 sys sys 1021580003 4241
+1021922494 134 c sys/src/libip/testreadipifc.c - 664 sys sys 1021580003 400
+1021922494 135 c sys/src/libndb/ndbhash.c - 664 sys sys 1021580003 4848
+1021922494 136 c sys/games/lib/fortunes - 664 sys sys 1021580004 233092
+1021922494 137 d sys/src/libip/nreadipifc.c - 664 sys sys 944961728 0
+1021926277 0 c 386/bin/venti/buildindex - 775 sys sys 1021925200 222616
+1021926277 1 c 386/bin/venti/checkarenas - 775 sys sys 1021925201 225619
+1021926277 2 c 386/bin/venti/checkindex - 775 sys sys 1021925201 223434
+1021926277 3 c 386/bin/venti/clumpstats - 775 sys sys 1021925202 212633
+1021926277 4 c 386/bin/venti/findscore - 775 sys sys 1021925203 197222
+1021926277 5 c 386/bin/venti/fmtarenas - 775 sys sys 1021925199 198344
+1021926277 6 c 386/bin/venti/fmtindex - 775 sys sys 1021925200 212296
+1021926277 7 c 386/bin/venti/fmtisect - 775 sys sys 1021925199 212880
+1021926277 8 c 386/bin/venti/rdarena - 775 sys sys 1021925203 196953
+1021926277 9 c 386/bin/venti/sync - 775 sys sys 1021925204 237251
+1021926277 10 c 386/bin/venti/venti - 775 sys sys 1021925198 292043
+1021926277 11 c 386/bin/venti/verifyarena - 775 sys sys 1021925204 171709
+1021926277 12 c 386/bin/vac - 775 sys sys 1021925070 204103
+1021926277 13 c 386/bin/vacfs - 775 sys sys 1021925069 209119
+1021926277 14 c 386/lib/libmp.a - 664 sys sys 1021925187 76970
+1021926277 15 a n/sources - 20000000555 sys sys 1021926252 0
+1021926277 16 c rc/bin/9fs - 775 sys sys 1021926249 552
+1021926277 17 c sys/src/cmd/vac/file.c - 664 sys sys 1021925054 15835
+1021926277 18 c sys/src/cmd/vac/mkfile - 664 sys sys 1021925054 395
+1021926277 19 c dist/replica/network - 775 sys sys 1021926283 436
+1021926277 20 m dist/replica/network - 775 sys sys 1021926283 436
+1021926564 0 m acme - 20000000775 sys sys 1020896383 0
+1021926564 1 m lib/ndb/dnsdump - 664 sys sys 959260798 76
+1021926872 0 c rc/bin/9fs - 775 sys sys 1021926888 552
+1021928480 0 c lib/ndb/local - 664 sys sys 1021926975 195
+1021928480 1 c lib/ndb/local.complicated - 664 sys sys 1021926987 2764
+1021928480 2 c sys/man/1/replica - 664 sys sys 1021927495 6619
+1021973494 0 c 386/lib/libmach.a - 664 sys sys 1021972031 744220
+1021973494 1 c sys/src/libmach/0.c - 664 sys sys 1021927268 4042
+1021973494 2 c sys/src/libmach/mkfile - 664 sys sys 1021971907 484
+1021973494 3 a sys/src/libmach/DIST0.c - 664 sys sys 1021927268 4042
+1021973494 4 a sys/src/libmach/DISTmkfile - 664 sys sys 1021971834 489
+1022009917 0 c 386/bin/htmlfmt - 775 sys sys 1022009910 158213
+1022009917 1 c 386/bin/bunzip2 - 775 sys sys 1022009744 95618
+1022009917 2 c 386/bin/cp - 775 sys sys 1022009867 62224
+1022009917 3 c 386/bin/cpu - 775 sys sys 1022009856 136658
+1022009917 4 c 386/bin/vncs - 775 sys sys 1022009571 337056
+1022009917 5 c 386/bin/ftpfs - 775 sys sys 1022009691 137870
+1022009917 6 c 386/bin/netkey - 775 sys sys 1022009909 70290
+1022009917 7 c 386/bin/netstat - 775 sys sys 1022009908 79333
+1022009917 8 c 386/bin/page - 775 sys sys 1022009848 208568
+1022009917 9 c 386/bin/passwd - 775 sys sys 1022009909 82186
+1022009917 10 c 386/bin/rio - 775 sys sys 1022009908 299941
+1022009917 11 c 386/bin/ssh - 775 sys sys 1022009755 184333
+1022009917 12 c 386/bin/telco - 775 sys sys 1022009836 104560
+1022009917 13 c 386/bin/paqfs - 775 sys sys 1022009719 107606
+1022009917 14 c 386/bin/sshnet - 775 sys sys 1022009756 278841
+1022009917 15 c 386/bin/auth/factotum - 775 sys sys 1022009659 299069
+1022009917 16 c 386/bin/auth/secstore - 775 sys sys 1022009649 177793
+1022009917 17 c 386/bin/aux/timesync - 775 sys sys 1022009664 124897
+1022009917 18 c 386/bin/aux/vga - 775 sys sys 1022009673 297822
+1022009917 19 c 386/bin/disk/kfs - 775 sys sys 1022008485 246712
+1022009917 20 c 386/bin/disk/dump9660 - 775 sys sys 1022009684 151005
+1022009917 21 c 386/bin/ip/ipconfig - 775 sys sys 1022009733 103374
+1022009917 22 c 386/bin/ndb/cs - 775 sys sys 1022009703 142258
+1022009917 23 c 386/bin/ndb/dns - 775 sys sys 1022009710 207424
+1022009917 24 c 386/bin/upas/biff - 775 sys sys 1022009619 64424
+1022009917 25 c 386/bin/upas/fs - 775 sys sys 1022009619 314079
+1022009917 26 c 386/bin/upas/pop3 - 775 sys sys 1022009618 241321
+1022009917 27 c sys/src/cmd/disk/kfs/9p12.c - 664 sys sys 1022008487 1963
+1022009917 28 c sys/src/cmd/disk/kfs/dat.h - 664 sys sys 1022008485 3591
+1022009917 29 c sys/src/cmd/disk/kfs/sub.c - 664 sys sys 1022008488 10804
+1022009917 30 c sys/src/cmd/disk/kfs/con.c - 664 sys sys 1022008487 12770
+1022009917 31 c sys/src/cmd/disk/kfs/uid.c - 664 sys sys 1022008489 6719
+1022009917 32 c sys/src/cmd/disk/kfs/mkfile - 664 sys sys 1022008484 755
+1022009917 33 c sys/src/cmd/disk/kfs/main.c - 664 sys sys 1022008488 9756
+1022009917 34 c sys/src/cmd/disk/kfs/9p1.c - 664 sys sys 1022008486 25309
+1022009917 35 c sys/src/cmd/disk/kfs/9p2.c - 664 sys sys 1022008487 34555
+1022009917 36 c sys/log/dns - 10000000666 sys sys 1022008449 0
+1022010177 0 d sys/src/libmach/DIST0.c - 664 sys sys 1021927268 0
+1022010177 1 d sys/src/libmach/DISTmkfile - 664 sys sys 1021971834 0
+1022011309 0 c sys/man/8/kfscmd - 664 sys sys 1022010519 4492
+1022046828 0 a sys/src/cmd/unix/drawterm/bin/drawterm-freebsd.gz - 775 sys sys 1022046828 259893
+1022046828 1 a sys/src/cmd/unix/drawterm/bin/drawterm-macosx.gz - 775 sys sys 1022046829 330048
+1022046828 2 d sys/src/cmd/unix/drawterm/bin/drawterm-freebsd - 664 sys sys 1019863737 0
+1022046828 3 d sys/src/cmd/unix/drawterm/bin/drawterm-macosx - 775 sys sys 1019862439 0
+1022047263 0 c sys/src/cmd/unix/drawterm/devip-unix.c - 664 sys sys 1022047027 15038
+1022049064 0 c 386/bin/read - 775 sys sys 1022047664 56079
+1022049064 1 c sys/man/1/cat - 664 sys sys 1022048090 1335
+1022049064 2 c sys/src/cmd/read.c - 664 sys sys 1022047660 1278
+1022050864 0 c 386/bin/con - 775 sys sys 1022049384 76233
+1022050864 1 c 386/bin/hayes - 775 sys sys 1022049385 61147
+1022050864 2 c 386/bin/xmr - 775 sys sys 1022049385 38942
+1022050864 3 c 386/bin/xms - 775 sys sys 1022049385 40695
+1022050864 4 c sys/man/1/con - 664 sys sys 1022049386 4259
+1022050864 5 c sys/src/cmd/con/mkfile - 664 sys sys 1022049384 214
+1022050864 6 c sys/src/cmd/con/xms.c - 664 sys sys 1022049386 3530
+1022050864 7 c sys/src/cmd/con/con.c - 664 sys sys 1022049386 15527
+1022050864 8 c sys/src/cmd/lp/lp.rc - 775 sys sys 1022050028 5357
+1022085180 0 c 386/bin/9660srv - 775 sys sys 1022085196 104702
+1022085180 1 c sys/src/cmd/9660srv/iobuf.c - 664 sys sys 1022085197 3125
+1022112071 0 c sys/src/cmd/mkmany - 664 sys sys 1022112160 1196
+1022112071 1 c sys/src/libhtml/build.c - 664 sys sys 1022112161 94832
+1022112071 2 c sys/src/libstdio/setvbuf.c - 664 sys sys 1022112161 954
+1022112071 3 c sys/src/libstdio/vsnprintf.c - 664 sys sys 1022112161 256
+1022112071 4 c sys/src/libstdio/vsprintf.c - 664 sys sys 1022112162 246
+1022112071 5 c sys/games/lib/fortunes - 664 sys sys 1022112163 233129
+1022113873 0 c acme/mail/src/win.c - 664 sys sys 1022112163 5390
+1022113873 1 c acme/mail/src/mesg.c - 664 sys sys 1022112163 25817
+1022113873 2 c acme/mail/src/dat.h - 664 sys sys 1022112164 3850
+1022113873 3 c acme/mail/src/util.c - 664 sys sys 1022112164 1391
+1022113873 4 c acme/mail/src/mail.c - 664 sys sys 1022112164 10639
+1022113873 5 c acme/mail/src/reply.c - 664 sys sys 1022112164 10544
+1022113873 6 a cron/upas/cron - 664 upas sys 1020896386 146
+1022113873 7 c sys/include/libc.h - 664 sys sys 1022112153 18741
+1022113873 8 c sys/lib/plumb/basic - 664 sys sys 1022112154 2602
+1022113873 9 c sys/lib/dist/mkfile - 664 sys sys 1022112154 2305
+1022113873 10 c sys/lib/dist/pc/sub/termrc - 664 sys sys 1022112154 1543
+1022113873 11 c sys/man/4/consolefs - 664 sys sys 1022112154 3751
+1022113873 12 c sys/man/4/vacfs - 664 sys sys 1022112155 1419
+1022113873 13 c sys/src/cmd/cc/macbody - 664 sys sys 1022112155 10975
+1022113873 14 c sys/src/cmd/disk/kfs/main.c - 664 sys sys 1022112155 9420
+1022113873 15 c sys/src/cmd/disk/kfs/9p1.c - 664 sys sys 1022112156 25316
+1022113873 16 c sys/src/cmd/ip/ftpfs/ftpfs.c - 664 sys sys 1022112156 13473
+1022113873 17 c sys/src/cmd/ndb/dblookup.c - 664 sys sys 1022112156 19650
+1022113873 18 c sys/src/cmd/ndb/dn.c - 664 sys sys 1022112156 23960
+1022113873 19 c sys/src/cmd/ndb/dns.h - 664 sys sys 1022112157 8067
+1022113873 20 c sys/src/cmd/ndb/dnstcp.c - 664 sys sys 1022112157 10411
+1022113873 21 c sys/src/cmd/ndb/dnudpserver.c - 664 sys sys 1022112157 5086
+1022113873 22 c sys/src/cmd/nntpfs.c - 664 sys sys 1022112158 18788
+1022113873 23 c sys/src/cmd/rio/mkfile - 664 sys sys 1022112158 453
+1022113873 24 c sys/src/cmd/ssh/msg.c - 664 sys sys 1022112158 7703
+1022113873 25 c sys/src/cmd/ssh/ssh.c - 664 sys sys 1022112158 8737
+1022113873 26 c sys/src/cmd/upas/fs/fs.c - 664 sys sys 1022112159 27180
+1022113873 27 c sys/src/cmd/vac/vac.c - 664 sys sys 1022112159 23264
+1022113873 28 c sys/src/cmd/mklib - 664 sys sys 1022112159 599
+1022113873 29 c sys/src/cmd/mksyslib - 664 sys sys 1022112160 660
+1022113873 30 c sys/src/cmd/mkone - 664 sys sys 1022112160 792
+1022113873 31 c dist/replica/plan9.proto - 664 sys sys 1022112985 1209
+1022115673 0 a alpha/bin/usb - 20000000775 sys sys 1022114635 0
+1022117906 0 c 386/bin/bunzip2 - 775 sys sys 1022116915 95539
+1022117906 1 c 386/bin/archfs - 775 sys sys 1022116913 138391
+1022117906 2 c 386/bin/bzip2 - 775 sys sys 1022116915 112125
+1022117906 3 c 386/bin/8a - 775 sys sys 1022116911 112351
+1022117906 4 c 386/bin/8c - 775 sys sys 1022116910 298147
+1022117906 5 c 386/bin/8l - 775 sys sys 1022116911 107261
+1022117906 6 c 386/bin/9660srv - 775 sys sys 1022116911 104623
+1022117906 7 c 386/bin/acid - 775 sys sys 1022116912 377430
+1022117906 8 c 386/bin/acme - 775 sys sys 1022116913 413048
+1022117906 9 c 386/bin/ar - 775 sys sys 1022116913 112601
+1022117906 10 c 386/bin/ascii - 775 sys sys 1022116914 62720
+1022117906 11 c 386/bin/astro - 775 sys sys 1022116914 139017
+1022117906 12 c 386/bin/awd - 775 sys sys 1022116914 5033
+1022117906 13 c 386/bin/awk - 775 sys sys 1022116915 316990
+1022117906 14 c 386/bin/basename - 775 sys sys 1022116915 37833
+1022117906 15 c 386/bin/bc - 775 sys sys 1022116914 79847
+1022117906 16 c 386/bin/bind - 775 sys sys 1022116915 57760
+1022117906 17 c 386/bin/cal - 775 sys sys 1022116916 66134
+1022117906 18 c 386/bin/calendar - 775 sys sys 1022116916 77414
+1022117906 19 c 386/bin/aan - 775 sys sys 1022116911 127196
+1022117906 20 c 386/lib/libframe.a - 664 sys sys 1022116427 65832
+1022117906 21 c 386/lib/libndb.a - 664 sys sys 1022116426 51448
+1022117906 22 c 386/lib/libstdio.a - 664 sys sys 1022116426 125458
+1022117906 23 c 386/lib/libhtml.a - 664 sys sys 1022116427 220944
+1022117906 24 c 386/9pcdisk - 775 sys sys 1022116966 1744105
+1022117906 25 c 386/9pcdisk.gz - 664 sys sys 1022116968 619004
+1022117906 26 c 386/9pc - 775 sys sys 1022116953 1524344
+1022117906 27 c 386/9pccpu - 775 sys sys 1022116958 1210661
+1022117906 28 c 386/9pccpu.gz - 664 sys sys 1022116960 424109
+1022117906 29 c 386/9pc.gz - 664 sys sys 1022116955 521199
+1022118343 0 c 386/bin/nntpfs - 775 sys sys 1022118362 158642
+1022118343 1 c 386/bin/scp - 775 sys sys 1022118362 135921
+1022118343 2 c 386/bin/vac - 775 sys sys 1022118363 203961
+1022118343 3 c acme/mail/386/Mail - 775 sys sys 1022118115 168103
+1022118673 0 c 386/bin/replica/applychanges - 775 sys sys 1022118653 98510
+1022118673 1 c 386/bin/replica/applylog - 775 sys sys 1022118653 97836
+1022118673 2 c 386/bin/replica/compactdb - 775 sys sys 1022118654 77320
+1022118673 3 c 386/bin/replica/updatedb - 775 sys sys 1022118654 95474
+1022118673 4 c 386/bin/ndb/dnsdebug - 775 sys sys 1022118654 185222
+1022119274 0 d sys/doc/8½/8½.pdf - 664 sys sys 1020895860 0
+1022119274 1 d sys/doc/9.pdf - 664 sys sys 1020384320 0
+1022119274 2 d sys/doc/acid.pdf - 664 sys sys 1020384320 0
+1022119274 3 d sys/doc/acidpaper.pdf - 664 sys sys 1020384320 0
+1022119274 4 d sys/doc/ape.pdf - 664 sys sys 1020384321 0
+1022119274 5 d sys/doc/asm.pdf - 664 sys sys 1020384321 0
+1022119274 6 d sys/doc/auth.pdf - 664 sys sys 1021579977 0
+1022119274 7 d sys/doc/colophon.pdf - 664 sys sys 1020384321 0
+1022119274 8 d sys/doc/comp.pdf - 664 sys sys 1020384321 0
+1022119274 9 d sys/doc/compiler.pdf - 664 sys sys 1020384322 0
+1022119274 10 d sys/doc/contents.pdf - 664 sys sys 1020384322 0
+1022119274 11 d sys/doc/lexnames.pdf - 664 sys sys 1020384322 0
+1022119274 12 d sys/doc/libmach.pdf - 664 sys sys 1020485624 0
+1022119274 13 d sys/doc/lp.pdf - 664 sys sys 1020384322 0
+1022119274 14 d sys/doc/mk.pdf - 664 sys sys 1020384322 0
+1022119274 15 d sys/doc/mkfiles.pdf - 664 sys sys 1020384323 0
+1022119274 16 d sys/doc/names.pdf - 664 sys sys 1020384323 0
+1022119274 17 d sys/doc/plumb.pdf - 664 sys sys 1020384323 0
+1022119274 18 d sys/doc/port.pdf - 664 sys sys 1020384323 0
+1022119274 19 d sys/doc/prog4.pdf - 664 sys sys 1020384323 0
+1022119274 20 d sys/doc/rc.pdf - 664 sys sys 1020384324 0
+1022119274 21 d sys/doc/release3.pdf - 664 sys sys 1020384324 0
+1022119274 22 d sys/doc/release4.pdf - 664 sys sys 1020384324 0
+1022119274 23 d sys/doc/sleep.pdf - 664 sys sys 1020384324 0
+1022119274 24 d sys/doc/spin.pdf - 664 sys sys 1020384324 0
+1022119274 25 d sys/doc/title.pdf - 664 sys sys 1020384324 0
+1022119274 26 d sys/doc/trademarks.pdf - 664 sys sys 1020384325 0
+1022119274 27 d sys/doc/troff.pdf - 664 sys sys 1020384325 0
+1022119274 28 d sys/doc/utf.pdf - 664 sys sys 1020384325 0
+1022126009 0 c 386/9load - 775 sys sys 1022125972 177320
+1022126009 1 c 386/ld.com - 775 sys sys 1022125973 61564
+1022126009 2 c 386/mbr - 775 sys sys 1022125974 407
+1022126009 3 c 386/pbs - 775 sys sys 1022125973 494
+1022126009 4 c 386/pbslba - 775 sys sys 1022125974 507
+1022126009 5 c 386/9loadlite - 775 sys sys 1022125973 121896
+1022126009 6 c 386/9loaddebug - 775 sys sys 1022125973 254953
+1022126009 7 c 386/9loadlitedebug - 775 sys sys 1022125973 178681

+ 1 - 0
dist/replica/plan9.proto

@@ -51,6 +51,7 @@ acme	- sys sys
 	+	- sys sys
 cron	- sys sys
 	upas	- upas sys
+		+	- upas sys
 fd	- sys sys
 	+	- sys sys
 env	- sys sys

+ 376 - 346
lib/areacodes

@@ -1,346 +1,376 @@
-# area code updated june 2001 from http://www-cse.ucsd.edu/users/bsy/area.html
-201 NJ [-5] N New Jersey: Jersey City, Hackensack (see 973)
-202 DC [-5] Washington, D.C.
-203 CT [-5] Connecticut: Bridgeport, New Haven (see 860)
-204 MB [-6] Canada: Manitoba
-205 AL [-6] Alabama (including Birmingham; excludes only the southeastern corner of Alabama and the deep south; see splits 256 and 334)
-206 WA [-8] W Washington state: Seattle and Bainbridge Island (see splits 253 , 360 , 425 ; overlay 564)
-207 ME [-5] Maine
-208 ID [-7] Idaho
-209 CA [-8] Cent. California: Stockton (see 559)
-210 TX [-6] S Texas: San Antonio (see also splits 830 , 956)
-211 MD [-5] Maryland: Severn (not in use?)
-212 NY [-5] New York City, New York (Manhattan; see 646 , 718)
-213 CA [-8] S California: Los Angeles (see 310 , 323 , 626 , 818)
-214 TX [-6] Mid NE Texas: central Dallas (see split 972 ; overlay 469)
-215 PA [-5] SE Pennsylvania: Philadelphia (see overlays 267 , 445)
-216 OH [-5] Cleveland (see splits 330 , 440)
-217 IL [-6] Cent. Illinois: Springfield
-218 MN [-6] N Minnesota: Duluth
-219 IN [-5] N Indiana: South Bend
-224 IL [-6] Northern NE Illinois: Evanston, Waukegan, Northbrook (see 847 -- POSTPONED -- effective date unknown)
-225 LA [-6] Louisiana: Baton Rouge, New Roads, Donaldsonville, Albany, Gonzales, Greensburg, Palquemine, Vacherie
-228 MS [-6] S Mississippi (coastal areas, Biloxi, Gulfport; split from 601)
-229 GA [-5] SW Georgia: Albany (split from 912 ; see also 478 ; perm 8/1/00)
-231 MI [-5] W Michigan: Northwestern portion of lower Peninsula; Traverse City, Muskegon, Cheboyhan (eff 99/06/05; see 616)
-234 OH [-5] NE Ohio: Canton, Akron (overlaid on 330 ; perm 10/30/00)
-236 VA [-5] Virginia (region unknown) / Unassigned?
-240 MD [-5] W Maryland: Silver Spring, Frederick (overlay, see 301)
-242 -- [-5] Bahamas
-246 -- [-4] Barbados
-248 MI [-5] Michigan: Oakland county (split from 810)
-250 BC [-8] Canada: British Columbia (see 604)
-251 AL [-6] S Alabama: Mobile (incl Auburn/Opelika, Montgomery, Mobile and coastal areas; split from 334 , eff 6/18/01; see also 205, 256)
-252 NC [-5] E North Carolina (Rocky Mount; split from 919)
-253 WA [-8] Washington: South Tier - Tacoma, Federal Way (split from 206 , see also 425 ; overlay 564)
-254 TX [-6] Central Texas (Waco, Stephenville; split, see 817 , 940)
-256 AL [-6] E and N Alabama (Huntsville, Florence, Gadsden; split from 205 ; see also 334)
-262 WI [-6] SE Wisconsin: counties of Kenosha, Ozaukee, Racine, Walworth, Washington, Waukesha (split from 414)
-264 -- [-4] Anguilla (split from 809)
-267 PA [-5] SE Pennsylvania: Philadelphia (see 215)
-268 -- [-4] Antigua and Barbuda (split from 809)
-270 KY [-6] W Kentucky: Bowling Green, Paducah (split from 502)
-278 MI [-5] Michigan (overlaid on 734 , SUSPENDED)
-281 TX [-6] Texas: Houston Metro (split 713 ; overlay 832)
-283 OH [-5] SW Ohio: Cincinnati (overlaid on 513)
-284 -- [-4] British Virgin Islands (split from 809)
-289 ON [-5] S Cent. Ontario: Greater Toronto Area -- Durham, Halton, Hamilton-Wentworth, Niagara, Peel, York, and southern Simcoe County (excluding Toronto -- overlaid on 905 , eff 6/9/01)
-301 MD [-5] W Maryland: Silver Spring, Frederick, Camp Springs, Prince George's County (see 240)
-302 DE [-5] Delaware
-303 CO [-7] Central Colorado: Denver (see 970 , also 720 overlay)
-304 WV [-5] West Virginia
-305 FL [-5] SE Florida: Miami (see 786 , 954)
-306 SK [-6]/[-7] Canada: Saskatchewan
-307 WY [-7] Wyoming
-308 NE [-6] W Nebraska: North Platte
-309 IL [-6] W Cent. Illinois: Peoria
-310 CA [-8] S California: Beverly Hills, West Hollywood, West Los Angeles (see split 562 ; overlay 424 -- approval denied)
-312 IL [-6] Illinois: Chicago (downtown only -- in the loop; see 773 ; overlay 872)
-313 MI [-5] Michigan: Detroit and suburbs (see 734)
-314 MO [-6] SE Missouri: St Louis metro area only (see 573 , 636 , overlay 557)
-315 NY [-5] N Cent. New York: Syracuse
-316 KS [-6] S Kansas: Wichita (see split 620)
-317 IN [-6] Cent. Indiana: Indianapolis (see 765)
-318 LA [-6] N Louisiana: Shreveport, Ruston, Monroe, Alexandria (see split 337)
-319 IA [-6] E Iowa: Cedar Rapids (see split 563)
-320 MN [-6] Cent. Minnesota: Saint Cloud (rural Minn, excl St. Paul/Minneapolis)
-321 FL [-5] Florida: Brevard County, Cape Canaveral area
-323 CA [-8] S California: Los Angeles (outside downtown: Hollywood; split from 213)
-330 OH [-5] NE Ohio: Akron, Canton (see splits 216 , 440 , overlay 234)
-331 IL [-6] W NE Illinois, western suburbs of Chicago (part of what used to be 708 ; overlaid on 630 ; perm NONE, mand t.b.a.)
-334 AL [-6] S Alabama: Mobile (incl Auburn/Opelika, Montgomery, Mobile and coastal areas; part of what used to be 205 ; see also 256 , split 251)
-336 NC [-5] Cent. North Carolina: Greensboro (split from 910)
-337 LA [-6] SW Louisiana: Lake Charles, Lafayette (see split 318)
-339 MA [-5] Massachusetts: Boston surburbs, to the sourth and west (see splits 617 , 508 ; overlaid on 781 , eff 5/2/2001)
-340 -- [-4] US Virgin Islands (see also 809)
-341 CA [-8] (overlay on 510 ; SUSPENDED)
-345 -- [-5] Cayman Islands
-347 NY [-5] New York (overlay for 718 : NYC area, except Manhattan)
-351 MA [-5] Massachusetts: north of Boston to NH, 508 , and 781 (see split 978 -- this is the northern half of old 508 ; overlaid on 978 , eff 4/2/2001)
-352 FL [-5] Florida: Gainesville area, Ocala, Crystal River (split from 904)
-360 WA [-8] W Washington State: Olympia, Bellingham (except Seattle area; part of what used to be 206 ; see overlay 564)
-361 TX [-6] S Texas: Corpus Christi (split from 512 ; eff 2/13/99)
-369 CA [-8] Solano County (perm 12/02/00, mand 06/02/01)
-385 UT [-7] Utah: Salt Lake City Metro (split from 801 , eff 3/30/02; see also 435)
-386 FL [-5] N Florida: Jacksonville (split from 904 , perm 2/15/01, mand 11[-05][-01])
-401 RI [-5] Rhode Island
-402 NE [-6] E Nebraska: Omaha, Lincoln
-403 AB [-7] Canada: Southern Alberta (see 780 , 867)
-404 GA [-5] N Georgia: Atlanta and suburbs (see overlay 678 , split 770)
-405 OK [-6] W Oklahoma: Oklahoma City (see 580)
-406 MT [-7] Montana
-407 FL [-5] Centra Florida: Metro Orlando
-408 CA [-8] Cent. Coastal California: San Jose (see overlay 669)
-409 TX [-6] SE Texas: Galveston, Port Arthur (splits 936 , 979)
-410 MD [-5] E Maryland: Baltimore, Annapolis, Chesapeake Bay area, Ocean City (see 443)
-412 PA [-5] W Pennsylvania: Pittsburgh (see split 724 , overlay 878)
-413 MA [-5] W Massachusetts: Springfield
-414 WI [-6] SE Wisconsin: Milwaukee (see splits 920 , 262)
-415 CA [-8] San Francisco, California (see 650)
-416 ON [-5] Canada: S Cent. Ontario: Toronto (see overlay 647 , eff 3/5/01)
-417 MO [-6] SW Missouri: Springfield
-418 QC [-5]/[-4] Canada: NE Quebec: Quebec
-419 OH [-5] NW Ohio: Toledo (see overlay 567 , perm 1/1/02)
-420 WI [-6] Wisconsin (not sure what area / split)
-423 TN [-5] E Tennessee: Chattanooga (see split 865 ; part of what used to be 615)
-424 CA [-8] S California: Los Angeles (see split 562 ; overlaid on 310 PENDING)
-425 WA [-8] Washington: North Tier - Everett, Bellevue (split from 206 , see also 253 ; overly 564)
-434 VA [-5] E Virginia: Richmond (overlay on 804 , eff 6/1/01; see also 757)
-435 UT [-7] Rural Utah outside Salt Lake City metro (see split 801)
-440 OH [-5] Ohio: Cleveland metro area, excluding Cleveland (split from 216 , see also 330)
-441 -- [-4] Bermuda (part of what used to be 809)
-442 CA [-8] Far north suburbs of San Diego (Oceanside, Escondido, SUSPENDED -- originally perm 10/21/00, mand 04/14/01)
-443 MD [-5] E Maryland: Baltimore, Annapolis, Chesapeake Bay area, Ocean City (overlaid on 410)
-445 PA [-5] SE Pennsylvania: Philadelphia (overlaid on 215 , eff 5/1/01; see also 267)
-450 QC [-5]/[-4] Canada: Southeastern Quebec outside metro Montreal
-464 IL [-6] Illinois: south suburbs of Chicago (see 630 ; overlaid on 708)
-469 TX [-6] Texas: Dallas (overlays 214 / 972)
-473 -- [-4] Grenada ("new" -- split from 809)
-475 CT [-5] Connecticut: Mew Haven, Greenwich, southwestern (perm 01/06/01; mand 03/01/01???)
-478 GA [-5] Central Georgia: Macon (split from 912 ; see also 229 ; perm 08/01/00; mand 08/01/01)
-480 AZ [-7] East Phoenix Arizona (see 520 ; also Phoenix split 602 , 623)
-484 PA [-5] SE Pennsylvania: Allentown, Reading (see 610)
-501 AR [-6] N Arkansas (see 870)
-502 KY [-5] N Central Kentucky: Louisville (see 270)
-503 OR [-8] Oregon (see 541 , 971)
-504 LA [-6] E Louisiana: New Orleans metro area (see split 985)
-505 NM [-7] New Mexico
-506 NB [-4] Canada: New Brunswick
-507 MN [-6] S Minnesota: Rochester
-508 MA [-5] Cent. Massachusetts: Framingham; Cape Cod (see split 978 , overlay 774)
-509 WA [-8] E Washington state: Spokane
-510 CA [-8] California: Oakland, East Bay (see 925)
-512 TX [-6] S Texas: Austin (see split 361 ; overlay 737 , perm 11/10/01)
-513 OH [-5] SW Ohio: Cincinnati (see overlay 283 , split 937)
-514 QC [-5] Canada: SW Quebec: Montreal
-515 IA [-6] Cent. Iowa: Des Moines (see split 641)
-516 NY [-5] New York: Nassau County, Long Island; Hempstead (see split 631)
-517 MI [-5] Cent. Michigan: Lansing (see split 989)
-518 NY [-5] NE New York: Albany
-519 ON [-5] Canada: SW Ontario: Windsor
-520 AZ [-6] SE Arizona: Tucson area, Yuma (split from 602 ; see split 928)
-525 MX [-6] Mexico: Mexico City area
-530 CA [-8] NE California: Chico, Redding, Marysville, Nevada City/Grass Valley (split from 916)
-540 VA [-5] Northern Virginia: Fredericksburg and Roanoke and nearby areas (part of what used to be 703)
-541 OR [-8] Oregon: Eugene, Medford (split from 503 ; 503 retains NW part [Portland/Salem], all else moves to 541)
-557 MO [-6] SE Missouri: St Louis metro area only (overlaid on 314)
-559 CA [-8] Central California: Fresno (see 209)
-561 FL [-5] Florida (S. Central) (West Palm Beach, Boca Raton, Vero Beach)
-562 CA [-8] California: Long Beach, Brea (split from 310 Los Angeles)
-563 IA [-6] E Iowa: Cedar Rapids ? (split from 319 , eff 3/25/01)
-564 WA [-8] W Washington State: Olympia, Bellingham (overlaid on 360 ; perm 02/03/01; see also 206, 253, 425)
-567 OH [-5] NW Ohio: Toledo (overlaid on 419 , perm 1/1/02)
-570 PA [-5] NE and N Central Pennsylvania: Wilkes-Barre, Scranton (see 717)
-571 VA [-5] Northern Virginia: Arlington, McLean, Tysons Corner (to be overlaid on 703 3/1/2000; see earlier split 540)
-573 MO [-6] NE Missouri: excluding St Louis metro area, includes Central/East Central Missouri
-580 OK [-6] W Oklahoma (rural areas outside Oklahoma City; split from 405)
-586 MI [-5] E Michigan: Flint, Pontiac (overlaid on 810 , perm 9/22/01; see also 248)
-601 MS [-6] Mississippi: Jackson area (see splits 228 , 662)
-602 AZ [-7] Phoenix Arizona (see 520 ; also Phoenix split 480 , 623)
-603 NH [-5] New Hampshire
-604 BC [-8] Canada: British Columbia: Greater Vancouver (overlay 778 , perm 11/3/01; see 250)
-605 SD [-6]/[-7] South Dakota
-606 KY [-5]/[-6] E Kentucky: area east of Frankfort: Ashland (see 859)
-607 NY [-5] S Cent. New York: Ithaca, Binghamton
-608 WI [-6] SW Wisconsin: Madison
-609 NJ [-5] S New Jersey: Trenton (see 856)
-610 PA [-5] SE Pennsylvania: Allentown, Reading (see overlays 484 , 835)
-612 MN [-6] Cent. Minnesota: Minneapolis (split from St. Paul, see 651 ; see splits 763 , 952)
-613 ON [-5] Canada: SE Ontario: Ottawa
-614 OH [-5] SE Ohio: Columbus
-615 TN [-6] E Tennessee: Nashville metro area (see 423 , 931)
-616 MI [-5] W Michigan: Grand Rapids, Battle Creek, Kalamazoo (see 231)
-617 MA [-5] Massachusetts: greater Boston (see overlay 857)
-618 IL [-6] S Illinois: Centralia
-619 CA [-8] S California: San Diego (see split 760 ; overlay 858 , 935)
-620 KS [-6] S Kansas: Wichita (split from 316 ; perm 2/3/01)
-623 AZ [-7] West Phoenix Arizona (see 520 ; also Phoenix split 480 , 602)
-626 CA [-8] E S California: Pasadena (split from 818 Los Angeles)
-627 CA [-8] Napa, Sonoma counties (perm 10/13/01, mand 04/13/02)
-628 CA [-8] (Region unknown; perm 10/21/00)
-630 IL [-6] W NE Illinois, western suburbs of Chicago (part of what used to be 708 ; overlay 331)
-631 NY [-5] New York: Suffolk County, Long Island; Huntington, Riverhead (split 516)
-636 MO [-6] Missouri: St. Charles County, Jefferson County area south (between 314 and 573)
-641 IA [-6] Iowa: Mason City, Marshalltown, Creston, Ottumwa (split from 515 ; perm 07/09/00)
-646 NY [-5] New York (overlay 212 / 917) NYC: Manhattan only
-647 ON [-5] Canada: S Cent. Ontario: Toronto (overlaid on 416 ; eff 3/5/01)
-649 -- [-5] Turks &amp; Caicos Islands
-650 CA [-8] California: Peninsula south of San Francisco -- San Mateo county, parts of Santa Clara county (split from 415)
-651 MN [-6] Cent. Minnesota: St. Paul (split from Minneapolis, see 612)
-657 CA [-8] California: North and Central Orange County (overlaid on 714 ; perm 10/7/00)
-660 MO [-6] N Missouri (split from 816)
-661 CA [-8] California: N Los Angeles, Mckittrick, Mojave, Newhall, Oildale, Palmdal, Taft, Tehachapi, Bakersfield, Earlimart, Lancaster (split from 805)
-662 MS [-6] N Mississippi: Tupelo, Grenada, Meridian (split from 601)
-664 -- [-4] Montserrat (split from 809)
-669 CA [-8] Cent. Coastal California: San Jose (rejected was: overlaid on 408)
-670 MP [+10] Commonwealth of the Northern Mariana Islands (CNMI, US Commonwealth)
-671 GU [+10] Guam
-678 GA [-5] N Georgia: Atlanta and suburbs (overlay; see 404 , 770)
-679 MI [-5]/[-6] (Region unknown; perm 2/3/01)
-682 TX [-6] Texas: Fort Worth areas (perm 10/7/00, mand 12/9/00)
-684 -- ? American Samoa
-701 ND [-6] North Dakota
-702 NV [-8] Nevada: Clark County, incl Las Vegas (see 775)
-703 VA [-5] Northern Virginia: Arlington, McLean, Tysons Corner (see split 540 ; overlay 571)
-704 NC [-5] W North Carolina: Charlotte (see split 828 , overlay 980)
-705 ON [-5] NW Ontario: Sault Ste. Marie
-706 GA [-5] N Georgia: Columbus, Augusta
-707 CA [-8] NW California: Santa Rosa
-708 IL [-6] Illinois: south suburbs of Chicago (see 630 ; overlay 464)
-709 NF [-4]/[-3].5 Canada: Newfoundland
-710 -- ? US Government
-712 IA [-6] W Iowa: Council Bluffs
-713 TX [-6] Mid SE Texas: central Houston (split, 281 ; overlay 832)
-714 CA [-8] North and Central Orange County (see split 949 ; overlay 657)
-715 WI [-6] N Wisconsin: Eau Claire
-716 NY [-5] NW New York: Buffalo, Rochester
-717 PA [-5] E Pennsylvania: Harrisburg (see split 570)
-718 NY [-5] New York City Metro Area, New York (Queens, Staten Island, The Bronx, and Brooklyn; see 212 , 347)
-719 CO [-7] SE Colorado: Pueblo, Colorado Springs
-720 CO [-7] Central Colorado: Denver (overlaid on 303)
-724 PA [-5] SW Pennsylvania (areas outside metro Pittsburgh; split from 412)
-727 FL [-5] Florida Tampa Metro: Saint Petersburg, Clearwater (Pinellas and parts of Pasco county; split from 813)
-731 TN [-6] W Tennessee: outside Memphis metro area (split from 901 , perm 2/12/01, mand 9/17/01)
-732 NJ [-5] Cent. New Jersey: Toms River, New Brunswick, Bound Brook (see 908)
-734 MI [-5] SE Michigan: west and south of Detroit -- Ann Arbor, Monroe (split from 313)
-737 TX [-6] S Texas: Austin (overlaid on 512 , perm 11/10/01; see also 361)
-740 OH [-5] SE Ohio (rural areas outside Columbus; split from 614)
-747 CA [-8] (Region unknown)
-752 CA [-8] (Region unknown; perm 2/10/01)
-754 FL [-5] Florida: Broward County area, incl Ft. Lauderdale (overlaid on 954)
-757 VA [-5] E Virginia: Tidewater / Hampton Roads area -- Norfolk, Virginia Beach, Chesapeake, Portsmouth, Hampton, Newport News, Suffolk (part of what used to be 804)
-758 -- [-4] St. Lucia (split from 809)
-760 CA [-8] California: San Diego North County to Sierra Nevada (split from 619)
-763 MN [-6] Cent. Minnesota: Minneapolis (split from 612 ; see also 952)
-764 CA [-8] (overlay on 650 ; SUSPENDED)
-765 IN [-5] Indiana: outside Indianapolis (split from 317)
-767 -- [-4] Dominica (split from 809)
-770 GA [-5] Georgia: Atlanta suburbs: outside of I- 285 ring road (part of what used to be 404 ; see also overlay 678)
-773 IL [-6] Illinois: city of Chicago, outside the loop (see 312 ; overlay 872)
-774 MA [-5] Cent. Massachusetts: Framingham; Cape Cod (see split 978 , overlaid on 508 , eff 4/2/2001)
-775 NV [-8] Nevada: Reno (all of NV except Clark County area; see 702)
-778 BC [-8] Canada: British Columbia: Greater Vancouver (overlaid on 604 , per 11/3/01; see also 250)
-780 AB [-7] Canada: Northern Alberta, north of Lacombe (see 403)
-781 MA [-5] Massachusetts: Boston surburbs, to the sourth and west (see splits 617 , 508 ; overlay 339)
-784 -- [-4] St. Vincent &amp; Grenadines (split from 809)
-785 KS [-6] N &amp; W Kansas: Topeka (split from 913)
-786 FL [-5] SE Florida (Miami; overlaid on 305)
-787 PR [-4] Puerto Rico (see overlay 939 , perm 8/1/01)
-800 -- ? US toll free (see 888 , 877 , 866 , 855 , 844 , 833 , 822)
-801 UT [-7] Utah: Salt Lake City Metro (see split 385 , eff 3/30/02; see also split 435)
-802 VT [-5] Vermont
-803 SC [-5] South Carolina: Columbia, Aiken (see 843 , 864)
-804 VA [-5] E Virginia: Richmond (see split 757 , overlay 434)
-805 CA [-8] S Cent. Coastal California: San Luis Obispo, Thousand Oaks (see 661 split)
-806 TX [-6] Panhandle Texas: Amarillo
-807 ON [-5] Canada: W Ontario: Thunder Bay
-808 HI [-10] Hawaii
-809 -- [-4] Dominican Republic (see splits 264 , 268 , 284 , 340 , 441 , 473 , 664 , 758 , 767 , 784 , 868 , 876)
-810 MI [-5] E Michigan: Flint, Pontiac (see 248 ; overlay 586)
-812 IN [-6] S Indiana: Evansville
-813 FL [-5] SW Florida: Tampa Metro (splits 727 St. Petersburg, Clearwater, and 941 Sarasota)
-814 PA [-5] Cent. Pennsylvania: Erie
-815 IL [-6] NE Illinois: Rockford, Kankakee
-816 MO [-6] N Missouri: Kansas City (see split 660 , overlay 975)
-817 TX [-6] N Cent. Texas: Fort Worth area (see 254 , 940)
-818 CA [-8] S California: Los Angeles (see 213 , 310 , 562 , 626)
-819 QC [-5] NW Quebec: Trois Rivieres (see 867)
-822 -- ? US toll free (proposed, may not be in use yet)
-828 NC [-5] W North Carolina: Asheville (split from 704)
-830 TX [-6] Texas: N and W of San Antonio (split from 210)
-831 CA [-8] California: central coast area from Santa Cruz through Monterey County
-832 TX [-6] Texas: Houston (overlay 713 / 281)
-833 -- ? US toll free (proposed, may not be in use yet)
-835 PA [-5] SE Pennsylvania: Allentown, Reading (overlaid on 610 , eff 5/1/01; see also 484)
-843 SC [-5] South Carolina, coastal area: Charleston, Beaufort, Myrtle Beach (split from 803)
-844 -- ? US toll free (proposed, may not be in use yet)
-845 NY [-5] New York: Poughkeepsie; Nyack, Nanuet, Valley Cottage, New City, Putnam, Dutchess, Rockland, Orange, Ulster and parts of Sullivan counties in New York's lower Hudson Valley (see 914 ; perm 6/5/2000)
-847 IL [-6] Northern NE Illinois: northwestern suburbs of chicago (Evanston, Waukegan, Northbrook; see overlay 224)
-850 FL [-5] Florida panhandle, from east of Tallahassee to Pensacola (split from 904)
-855 -- ? US toll free (proposed, may not be in use yet)
-856 NJ [-5] SW New Jersey: greater Camden area, Mt Laurel (split from 609)
-857 MA [-5] Massachusetts: greater Boston (overlaid on 617 , eff 4/2/2001)
-858 CA [-8] S California: San Diego (see split 760 ; overlay 619 , 935)
-859 KY [-5] N Kentucky: Lexington; suburban counties of Cincinnati; Covington, Newport, Ft. Thomas, Ft. Wright, Florence (split from 606)
-860 CT [-5] Connecticut: Hartford, New London (split from 203 , overlay 959)
-863 FL [-5] Florida: Polk county (split from 941)
-864 SC [-5] South Carolina, upstate area: Greenville, Spartanburg (split from 803)
-865 TN [-5] E Tennessee: Knoxville, Knox and adjacent counties (split from 423 ; part of what used to be 615)
-866 -- ? US toll free
-867 YT [-8]/[-9] Canada: Yukon and Northwest Territories (split from 403 / 819)
-868 -- [-4] Trinidad and Tobago ("new" -- see 809)
-869 -- [-4] St. Kitts &amp; Nevis
-870 AR [-6] S. Arkansas: Jonesboro (split from 501)
-872 IL [-6] Illinois: Chicago (downtown only -- in the loop; see 773 ; overlaid on 312 and 773)
-876 -- [-5] Jamaica (split from 809)
-877 -- ? US toll free
-878 PA [-5] Pittsburgh, New Castle (overlaid on 412 , perm 8/17/01, mand t.b.a.)
-888 -- ? US toll free
-900 -- ? US toll calls -- prices vary with the number called
-901 TN [-6] W Tennessee: Memphis metro area (see 615 , 931 , split 731)
-902 NS [-4] Canada: Nova Scotia, Prince Edward Island
-903 TX [-6] NE Texas: Tyler
-904 FL [-5] N Florida: Jacksonville (see splits 352 , 386 , 850)
-905 ON [-5] S Cent. Ontario: Greater Toronto Area -- Durham, Halton, Hamilton-Wentworth, Niagara, Peel, York, and southern Simcoe County (excluding Toronto -- see overlay 289 [eff 6/9/01], splits 416, 647)
-906 MI [-5] Upper Peninsula Michigan: Sault Ste. Marie, Escanaba, Marquette
-907 AK [-9] Alaska
-908 NJ [-5] Cent. New Jersey: Elizabeth, Basking Ridge, Somerville, Bridgewater (see 732)
-909 CA [-8] California: Inland empire: San Bernandino, Riverside
-910 NC [-5] S Cent. North Carolina: Fayetteville, Wilmington (see 336)
-912 GA [-5] SE Georgia: Savannah (see splits 229 , 478)
-913 KS [-6] Kansas: Kansas City area (see 785)
-914 NY [-5] S New York: Westchester and Collier Counties (see 845)
-915 TX [-6] W Texas: Sweetwater, El Paso, Odessa, Midland
-916 CA [-8] NE California: Sacramento, Walnut Grove, Lincoln, Newcastle and El Dorado Hills (split to 530)
-917 NY [-5] New York: New York City (cellular, see 646)
-918 OK [-6] E Oklahoma: Tulsa (see 580)
-919 NC [-5] E North Carolina: Raleigh (see 252)
-920 WI [-6] NE Wisconsin: Appleton, Green Bay, Sheboygan, Fond du Lac (from Beaver Dam NE to Oshkosh, Appleton, and Door County; part of what used to be 414)
-925 CA [-8] California (Antioch, Concord, Pleasanton, Walnut Creek; split from 510)
-928 AZ [-6] Central and Northern Arizona (split from 520)
-931 TN [-6] Central Tennessee: semi-circular ring around Nashville (split from 615)
-935 CA [-8] S California: San Diego (see split 760 ; overlay 858 , 619 ; on hold)
-936 TX [-6] SE Texas: Galveston, Port Arthur (split from 409 , see also 979)
-937 OH [-5] SW Ohio: Dayton (part of what used to be 513)
-939 PR [-4] Puerto Rico (overlaid on 787 , perm 8/1/01)
-940 TX [-6] N Cent. Texas: Denton, Wichita Falls (split from 254 , 817)
-941 FL [-5] SW Florida: Sarasota and Manatee counties (part of what used to be 813 ; see split 863)
-947 MI [-5]/[-6] (Region unknown; perm 5/5/01)
-949 CA [-8] California: S Coastal Orange County (split from 714)
-951 CA [-8] (Region unknown)
-952 MN [-6] Cent. Minnesota: Minneapolis, Bloomington (split from 612 ; see also 763)
-954 FL [-5] Florida: Broward County area, incl Ft. Lauderdale (part of what used to be 305 , see overlay 754)
-956 TX [-6] Texas: Valley of Texas area; Harlingen, Laredo (split from 210)
-959 CT [-5] Connecticut: Hartford, New London (overlaid on 860 perm 1/6/01; mand 3/1/01???)
-969 MD [-5] Maryland: Severn area (eff ???)
-970 CO [-7] N and W Colorado (part of what used to be 303)
-971 OR [-8] Oregon: Metropolitan Portland (see 503 ; perm 10/1/00)
-972 TX [-6] Texas: Dallas Metro: Dallas and parts of Denton and Collin counties (split from 214 ; see overlay 469)
-973 NJ [-5] N New Jersey: Newark Paterson Morristown (split from 201)
-975 MO [-6] N Missouri: Kansas City (overlaid on 816)
-978 MA [-5] Massachusetts: north of Boston to NH, 508 , and 781 (see split 978 -- this is the northern half of old 508 ; see overlay 351)
-979 TX [-6] SE Texas: Galveston, Port Arthur, Bryan, College Station (split from 409 , see also 936)
-980 NC [-5] North Carolina: (overlay on 704 ; perm 5/1/00, mand 3[-15][-01])
-985 LA [-6] E Louisiana: SE/N shore of Lake Pontchartrain: Hammond, Slidell, Covington, Amite, Kentwood, area SW of New Orleans, Houma, Thibodeaux, Morgan City (split from 504 ; perm 02/12/2001; mand 10/22/01)
-989 MI [-5] Upper central Michigan: Mt Pleasant, Saginaw (split from 517 ; perm 4/7/01)
-
+# area code updated april 2002 from http://www-cse.ucsd.edu/users/bsy/area.html
+201 NJ [-5] N New Jersey: Jersey City, Hackensack (see split 973 , overlay 551 ) 
+202 DC [-5] Washington, D.C. 
+203 CT [-5] Connecticut: Bridgeport, New Haven (see 860 ) 
+204 MB [-6] Canada: Manitoba 
+205 AL [-6] Central Alabama (including Birmingham; excludes the southeastern corner of Alabama and the deep south; see splits 256 and 334 ) 
+206 WA [-8] W Washington state: Seattle and Bainbridge Island (see splits 253 , 360 , 425 ; overlay 564 ) 
+207 ME [-5] Maine 
+208 ID [-7] Idaho 
+209 CA [-8] Cent. California: Stockton (see 559 ) 
+210 TX [-6] S Texas: San Antonio (see also splits 830 , 956 ) 
+211 -- [--] Local community info / referral services 
+212 NY [-5] New York City, New York (Manhattan; see 646 , 718 ) 
+213 CA [-8] S California: Los Angeles (see 310 , 323 , 626 , 818 ) 
+214 TX [-6] Texas: Dallas Metro (overlays 214 / 469 / 972 ) 
+215 PA [-5] SE Pennsylvania: Philadelphia (see overlays 267 , 445 ) 
+216 OH [-5] Cleveland (see splits 330 , 440 ) 
+217 IL [-6] Cent. Illinois: Springfield 
+218 MN [-6] N Minnesota: Duluth 
+219 IN [-5] NW Indiana: Gary (see 260 , split 574 , 260 ) 
+224 IL [-6] Northern NE Illinois: Evanston, Waukegan, Northbrook (overlay on 847 , eff 1/5/2002) 
+225 LA [-6] Louisiana: Baton Rouge, New Roads, Donaldsonville, Albany, Gonzales, Greensburg, Palquemine, Vacherie 
+228 MS [-6] S Mississippi (coastal areas, Biloxi, Gulfport; split from 601 ) 
+229 GA [-5] SW Georgia: Albany (split from 912 ; see also 478 ; perm 8/1/00) 
+231 MI [-5] W Michigan: Northwestern portion of lower Peninsula; Traverse City, Muskegon, Cheboyhan (eff 99/06/05; see 616) 
+234 OH [-5] NE Ohio: Canton, Akron (overlaid on 330 ; perm 10/30/00) 
+236 VA [-5] Virginia (region unknown) / Unassigned? 
+239 FL [-5] Florida (Lee, Collier, and Monroe Counties, excl the Keys; see 305 ; eff ???/mand ???) 
+240 MD [-5] W Maryland: Silver Spring, Frederick (overlay, see 301 ) 
+242 -- [-5] Bahamas 
+246 -- [-4] Barbados 
+248 MI [-5] Michigan: Oakland county (split from 810 ) 
+250 BC [-8] Canada: British Columbia (see 604 ) 
+251 AL [-6] S Alabama: Mobile (incl Auburn/Opelika, Montgomery, Mobile and coastal areas; split from 334 , eff 6/18/01; see also 205, 256) 
+252 NC [-5] E North Carolina (Rocky Mount; split from 919 ) 
+253 WA [-8] Washington: South Tier - Tacoma, Federal Way (split from 206 , see also 425 ; overlay 564 ) 
+254 TX [-6] Central Texas (Waco, Stephenville; split, see 817 , 940 ) 
+256 AL [-6] E and N Alabama (Huntsville, Florence, Gadsden; split from 205 ; see also 334 ) 
+260 IN [-5] NE Indiana: Fort Wayne (see 219 ) 
+262 WI [-6] SE Wisconsin: counties of Kenosha, Ozaukee, Racine, Walworth, Washington, Waukesha (split from 414 ) 
+264 -- [-4] Anguilla (split from 809 ) 
+267 PA [-5] SE Pennsylvania: Philadelphia (see 215 ) 
+268 -- [-4] Antigua and Barbuda (split from 809 ) 
+270 KY [-6] W Kentucky: Bowling Green, Paducah (split from 502 ) 
+276 VA [-5] Northern Virginia: Fredericksburg and Roanoke and nearby areas (see 540 ; split/overlay unknown; perm 9/1/01, mand 3/16/02) 
+278 MI [-5] Michigan (overlaid on 734 , SUSPENDED) 
+281 TX [-6] Texas: Houston Metro (split 713 ; overlay 832 ) 
+283 OH [-5] SW Ohio: Cincinnati (overlaid on 513 ) 
+284 -- [-4] British Virgin Islands (split from 809 ) 
+289 ON [-5] Canada: S Cent. Ontario: Greater Toronto Area -- Durham, Halton, Hamilton-Wentworth, Niagara, Peel, York, and southern Simcoe County (excluding Toronto -- overlaid on 905 , eff 6/9/01) 
+301 MD [-5] W Maryland: Silver Spring, Frederick, Camp Springs, Prince George's County (see 240 ) 
+302 DE [-5] Delaware 
+303 CO [-7] Central Colorado: Denver (see 970 , also 720 overlay) 
+304 WV [-5] West Virginia 
+305 FL [-5] SE Florida: Miami, the Keys (see 786 , 954 ; 239 ) 
+306 SK [-6/-7] Canada: Saskatchewan 
+307 WY [-7] Wyoming 
+308 NE [-6] W Nebraska: North Platte 
+309 IL [-6] W Cent. Illinois: Peoria 
+310 CA [-8] S California: Beverly Hills, West Hollywood, West Los Angeles (see split 562 ; overlay 424 -- approval denied) 
+311 -- [--] Reserved for special applications 
+312 IL [-6] Illinois: Chicago (downtown only -- in the loop; see 773 ; overlay 872 ) 
+313 MI [-5] Michigan: Detroit and suburbs (see 734 ) 
+314 MO [-6] SE Missouri: St Louis metro area only (see 573 , 636 , overlay 557 ) 
+315 NY [-5] N Cent. New York: Syracuse 
+316 KS [-6] S Kansas: Wichita (see split 620 ) 
+317 IN [-6] Cent. Indiana: Indianapolis (see 765 ) 
+318 LA [-6] N Louisiana: Shreveport, Ruston, Monroe, Alexandria (see split 337 ) 
+319 IA [-6] E Iowa: Cedar Rapids (see split 563 ) 
+320 MN [-6] Cent. Minnesota: Saint Cloud (rural Minn, excl St. Paul/Minneapolis) 
+321 FL [-5] Florida: Brevard County, Cape Canaveral area 
+323 CA [-8] S California: Los Angeles (outside downtown: Hollywood; split from 213 ) 
+327 KY [-5] Kentucky: Maceo 
+330 OH [-5] NE Ohio: Akron, Canton (see splits 216 , 440 , overlay 234 ) 
+331 IL [-6] W NE Illinois, western suburbs of Chicago (part of what used to be 708 ; overlaid on 630 ; perm NONE, mand t.b.a.) 
+334 AL [-6] S Alabama: Mobile (incl Auburn/Opelika, Montgomery, Mobile and coastal areas; part of what used to be 205 ; see also 256 , split 251 ) 
+336 NC [-5] Cent. North Carolina: Greensboro (split from 910 ) 
+337 LA [-6] SW Louisiana: Lake Charles, Lafayette (see split 318 ) 
+339 MA [-5] Massachusetts: Boston surburbs, to the south and west (see splits 617 , 508 ; overlaid on 781 , eff 5/2/2001) 
+340 -- [-4] US Virgin Islands (see also 809 ) 
+341 CA [-8] (overlay on 510 ; SUSPENDED) 
+345 -- [-5] Cayman Islands 
+347 NY [-5] New York (overlay for 718 : NYC area, except Manhattan) 
+351 MA [-5] Massachusetts: north of Boston to NH, 508 , and 781 (overlaid on 978 , eff 4/2/2001) 
+352 FL [-5] Florida: Gainesville area, Ocala, Crystal River (split from 904 ) 
+360 WA [-8] W Washington State: Olympia, Bellingham (except Seattle area; part of what used to be 206 ; see overlay 564 ) 
+361 TX [-6] S Texas: Corpus Christi (split from 512 ; eff 2/13/99) 
+369 CA [-8] Solano County (perm 12/02/00, mand 06/02/01) 
+385 UT [-7] Utah: Salt Lake City Metro (split from 801 , eff 3/30/02; see also 435) 
+386 FL [-5] N central Florida: Lake City (split from 904 , perm 2/15/01, mand 11-05-01) 
+401 RI [-5] Rhode Island 
+402 NE [-6] E Nebraska: Omaha, Lincoln 
+403 AB [-7] Canada: Southern Alberta (see 780 , 867 ) 
+404 GA [-5] N Georgia: Atlanta and suburbs (see overlay 678 , split 770 ) 
+405 OK [-6] W Oklahoma: Oklahoma City (see 580 ) 
+406 MT [-7] Montana 
+407 FL [-5] Centra Florida: Metro Orlando 
+408 CA [-8] Cent. Coastal California: San Jose (see overlay 669 ) 
+409 TX [-6] SE Texas: Galveston, Port Arthur (splits 936 , 979 ) 
+410 MD [-5] E Maryland: Baltimore, Annapolis, Chesapeake Bay area, Ocean City (see 443 ) 
+411 -- [--] Reserved for special applications 
+412 PA [-5] W Pennsylvania: Pittsburgh (see split 724 , overlay 878 ) 
+413 MA [-5] W Massachusetts: Springfield 
+414 WI [-6] SE Wisconsin: Milwaukee county (see splits 920 , 262 ) 
+415 CA [-8] San Francisco, California (see 650 ) 
+416 ON [-5] Canada: S Cent. Ontario: Toronto (see overlay 647 , eff 3/5/01) 
+417 MO [-6] SW Missouri: Springfield 
+418 QC [-5/-4] Canada: NE Quebec: Quebec 
+419 OH [-5] NW Ohio: Toledo (see overlay 567 , perm 1/1/02) 
+420 WI [-6] Wisconsin (not sure what area / split) 
+423 TN [-5] E Tennessee: Chattanooga (see split 865 ; part of what used to be 615 ) 
+424 CA [-8] S California: Los Angeles (see split 562 ; overlaid on 310 PENDING) 
+425 WA [-8] Washington: North Tier - Everett, Bellevue (split from 206 , see also 253 ; overly 564 ) 
+434 VA [-5] E Virginia: Charlottesville, Lynchburg, Danville, South Boston, and Emporia (split from 804 , eff 6/1/01; see also 757) 
+435 UT [-7] Rural Utah outside Salt Lake City metro (see split 801 ) 
+440 OH [-5] Ohio: Cleveland metro area, excluding Cleveland (split from 216 , see also 330 ) 
+441 -- [-4] Bermuda (part of what used to be 809 ) 
+442 CA [-8] Far north suburbs of San Diego (Oceanside, Escondido, SUSPENDED -- originally perm 10/21/00, mand 04/14/01) 
+443 MD [-5] E Maryland: Baltimore, Annapolis, Chesapeake Bay area, Ocean City (overlaid on 410 ) 
+445 PA [-5] SE Pennsylvania: Philadelphia (overlaid on 215 , eff 5/1/01; see also 267) 
+450 QC [-5/-4] Canada: Southeastern Quebec outside metro Montreal 
+456 -- [--] Inbound International 
+464 IL [-6] Illinois: south suburbs of Chicago (see 630 ; overlaid on 708 ) 
+469 TX [-6] Texas: Dallas Metro (overlays 214 / 469 / 972 ) 
+470 GA [-5] Georgia: Greater Atlanta Metropolitan Area (overlaid on 404 / 770 / 678 ; mand 9/2/01) 
+473 -- [-4] Grenada ("new" -- split from 809 ) 
+475 CT [-5] Connecticut: New Haven, Greenwich, southwestern (perm 01/06/01; mand 03/01/01???) 
+478 GA [-5] Central Georgia: Macon (split from 912 ; see also 229 ; perm 08/01/00; mand 08/01/01) 
+479 AR [-6] NW Arkansas: Fayetteville, Springdale, Bentonville (split from 501 , perm 01/19/02, mand 07/20/02) 
+480 AZ [-7] East Phoenix Arizona (see 520 ; also Phoenix split 602 , 623 ) 
+484 PA [-5] SE Pennsylvania: Allentown, Reading (see 610 ) 
+500 -- [--] Personal Communication Service 
+501 AR [-6] N Arkansas (see split 479 ) 
+502 KY [-5] N Central Kentucky: Louisville (see 270 ) 
+503 OR [-8] Oregon (see 541 , 971 ) 
+504 LA [-6] E Louisiana: New Orleans metro area (see split 985 ) 
+505 NM [-7] New Mexico 
+506 NB [-4] Canada: New Brunswick 
+507 MN [-6] S Minnesota: Rochester 
+508 MA [-5] Cent. Massachusetts: Framingham; Cape Cod (see split 978 , overlay 774 ) 
+509 WA [-8] E Washington state: Spokane 
+510 CA [-8] California: Oakland, East Bay (see 925 ) 
+511 -- [--] Reserved for special applications 
+512 TX [-6] S Texas: Austin (see split 361 ; overlay 737 , perm 11/10/01) 
+513 OH [-5] SW Ohio: Cincinnati (see overlay 283 , split 937 ) 
+514 QC [-5] Canada: SW Quebec: Montreal 
+515 IA [-6] Cent. Iowa: Des Moines (see split 641 ) 
+516 NY [-5] New York: Nassau County, Long Island; Hempstead (see split 631 ) 
+517 MI [-5] Cent. Michigan: Lansing (see split 989 ) 
+518 NY [-5] NE New York: Albany 
+519 ON [-5] Canada: SW Ontario: Windsor 
+520 AZ [-7] SE Arizona: Tucson area, Yuma (split from 602 ; see split 928 ) 
+530 CA [-8] NE California: Chico, Redding, Marysville, Nevada City/Grass Valley (split from 916 ) 
+540 VA [-5] Northern Virginia: Fredericksburg and Roanoke and nearby areas (see 276 ; split/overlay unknown) 
+541 OR [-8] Oregon: Eugene, Medford (split from 503 ; 503 retains NW part [Portland/Salem], all else moves to 541 ) 
+546 MI [-5] E Michigan: Flint, Pontiac (overlaid on 810 , perm 9/22/01; see also 248) 
+551 NJ [-5] N New Jersey: Jersey City, Hackensack (overlaid on 201 ) 
+557 MO [-6] SE Missouri: St Louis metro area only (overlaid on 314 ) 
+559 CA [-8] Central California: Fresno (see 209 ) 
+561 FL [-5] S. Central Florida: Palm Beach County (West Palm Beach, Boca Raton, Vero Beach; see split 772 , eff 2/11/02; mand 11/11/02) 
+562 CA [-8] California: Long Beach, Brea (split from 310 Los Angeles) 
+563 IA [-6] E Iowa: Davenport, Dubuque (split from 319 , eff 3/25/01) 
+564 WA [-8] W Washington State: Olympia, Bellingham (overlaid on 360 ; perm 02/03/01; see also 206, 253, 425) 
+567 OH [-5] NW Ohio: Toledo (overlaid on 419 , perm 1/1/02) 
+570 PA [-5] NE and N Central Pennsylvania: Wilkes-Barre, Scranton (see 717 ) 
+571 VA [-5] Northern Virginia: Arlington, McLean, Tysons Corner (to be overlaid on 703 3/1/2000; see earlier split 540) 
+573 MO [-6] SE Missouri: excluding St Louis metro area, includes Central/East Missouri 
+574 IN [-5] N Indiana (split from 219 ) 
+580 OK [-6] W Oklahoma (rural areas outside Oklahoma City; split from 405 ) 
+585 NY [-5] NW New York: Rochester (split from 716 ) 
+586 MI [-5] Michigan: Macomb County (split from 810 ; perm 9/22/01, mand 3/23/02) 
+590 -- [-4] French West Indies Carribean Islands: St. Barthelemy (French), St. martin (Dutch &amp; French) (time zones?) 
+600 -- [--] Canadian Services 
+601 MS [-6] Mississippi: Jackson area (see splits 228 , 662 ) 
+602 AZ [-7] Phoenix Arizona (see 520 ; also Phoenix split 480 , 623 ) 
+603 NH [-5] New Hampshire 
+604 BC [-8] Canada: British Columbia: Greater Vancouver (overlay 778 , perm 11/3/01; see 250) 
+605 SD [-6/-7] South Dakota 
+606 KY [-5/-6] E Kentucky: area east of Frankfort: Ashland (see 859 ) 
+607 NY [-5] S Cent. New York: Ithaca, Binghamton 
+608 WI [-6] SW Wisconsin: Madison 
+609 NJ [-5] S New Jersey: Trenton (see 856 ) 
+610 PA [-5] SE Pennsylvania: Allentown, Reading (see overlays 484 , 835 ) 
+611 -- [--] Reserved for special applications 
+612 MN [-6] Cent. Minnesota: Minneapolis (split from St. Paul, see 651 ; see splits 763 , 952 ) 
+613 ON [-5] Canada: SE Ontario: Ottawa 
+614 OH [-5] SE Ohio: Columbus 
+615 TN [-6] E Tennessee: Nashville metro area (see 423 , 931 ) 
+616 MI [-5] W Michigan: Grand Rapids, Battle Creek, Kalamazoo (see 231 ) 
+617 MA [-5] Massachusetts: greater Boston (see overlay 857 ) 
+618 IL [-6] S Illinois: Centralia 
+619 CA [-8] S California: San Diego (see split 760 ; overlay 858 , 935 ) 
+620 KS [-6] S Kansas: Wichita (split from 316 ; perm 2/3/01) 
+623 AZ [-7] West Phoenix Arizona (see 520 ; also Phoenix split 480 , 602 ) 
+626 CA [-8] E S California: Pasadena (split from 818 Los Angeles) 
+627 CA [-8] Napa, Sonoma counties (perm 10/13/01, mand 04/13/02) 
+628 CA [-8] (Region unknown; perm 10/21/00) 
+630 IL [-6] W NE Illinois, western suburbs of Chicago (part of what used to be 708 ; overlay 331 ) 
+631 NY [-5] New York: Suffolk County, Long Island; Huntington, Riverhead (split 516 ) 
+636 MO [-6] Missouri: St. Charles County, Jefferson County area south (between 314 and 573 ) 
+641 IA [-6] Iowa: Mason City, Marshalltown, Creston, Ottumwa (split from 515 ; perm 07/09/00) 
+646 NY [-5] New York (overlay 212 / 917 ) NYC: Manhattan only 
+647 ON [-5] Canada: S Cent. Ontario: Toronto (overlaid on 416 ; eff 3/5/01) 
+649 -- [-5] Turks &amp; Caicos Islands 
+650 CA [-8] California: Peninsula south of San Francisco -- San Mateo county, parts of Santa Clara county (split from 415 ) 
+651 MN [-6] Cent. Minnesota: St. Paul (split from Minneapolis, see 612 ) 
+657 CA [-8] California: North and Central Orange County (overlaid on 714 ; perm 10/7/00) 
+660 MO [-6] N Missouri (split from 816 ) 
+661 CA [-8] California: N Los Angeles, Mckittrick, Mojave, Newhall, Oildale, Palmdal, Taft, Tehachapi, Bakersfield, Earlimart, Lancaster (split from 805 ) 
+662 MS [-6] N Mississippi: Tupelo, Grenada, Meridian (split from 601 ) 
+664 -- [-4] Montserrat (split from 809 ) 
+669 CA [-8] Cent. Coastal California: San Jose (rejected was: overlaid on 408 ) 
+670 MP [+10] Commonwealth of the Northern Mariana Islands (CNMI, US Commonwealth) 
+671 GU [+10] Guam 
+678 GA [-5] N Georgia: Atlanta and suburbs (overlay; see 404 , 770 ) 
+679 MI [-5/-6] (Region unknown; perm 2/3/01) 
+682 TX [-6] Texas: Fort Worth areas (perm 10/7/00, mand 12/9/00) 
+684 -- [-11] American Samoa 
+700 -- [--] Interexchange Carrier Services 
+701 ND [-6] North Dakota 
+702 NV [-8] Nevada: Clark County, incl Las Vegas (see 775 ) 
+703 VA [-5] Northern Virginia: Arlington, McLean, Tysons Corner (see split 540 ; overlay 571 ) 
+704 NC [-5] W North Carolina: Charlotte (see split 828 , overlay 980 ) 
+705 ON [-5] Canada: NW Ontario: Sault Ste. Marie/N Ontario: N Bay, Sudbury, Thunder Bay 
+706 GA [-5] N Georgia: Columbus, Augusta 
+707 CA [-8] NW California: Santa Rosa 
+708 IL [-6] Illinois: south suburbs of Chicago (see 630 ; overlay 464 ) 
+709 NF [-4/-3.5] Canada: Newfoundland 
+710 -- [?] US Government 
+711 -- [--] Reserved for special applications 
+712 IA [-6] W Iowa: Council Bluffs 
+713 TX [-6] Mid SE Texas: central Houston (split, 281 ; overlay 832 ) 
+714 CA [-8] North and Central Orange County (see split 949 ; overlay 657 ) 
+715 WI [-6] N Wisconsin: Eau Claire 
+716 NY [-5] NW New York: Buffalo (see split 585 ) 
+717 PA [-5] E Pennsylvania: Harrisburg (see split 570 ) 
+718 NY [-5] New York City Metro Area, New York (Queens, Staten Island, The Bronx, and Brooklyn; see 212 , 347 ) 
+719 CO [-7] SE Colorado: Pueblo, Colorado Springs 
+720 CO [-7] Central Colorado: Denver (overlaid on 303 ) 
+724 PA [-5] SW Pennsylvania (areas outside metro Pittsburgh; split from 412 ) 
+727 FL [-5] Florida Tampa Metro: Saint Petersburg, Clearwater (Pinellas and parts of Pasco county; split from 813 ) 
+731 TN [-6] W Tennessee: outside Memphis metro area (split from 901 , perm 2/12/01, mand 9/17/01) 
+732 NJ [-5] Cent. New Jersey: Toms River, New Brunswick, Bound Brook (see overlay 848 ) 
+734 MI [-5] SE Michigan: west and south of Detroit -- Ann Arbor, Monroe (split from 313 ) 
+737 TX [-6] S Texas: Austin (overlaid on 512 , perm 11/10/01; see also 361) 
+740 OH [-5] SE Ohio (rural areas outside Columbus; split from 614 ) 
+747 CA [-8] (Region unknown) 
+752 CA [-8] California: Ontario, Ponoma, Chino, San Bernandino (perm 2/10/01) 
+754 FL [-5] Florida: Broward County area, incl Ft. Lauderdale (overlaid on 954 ; perm 8/1/01, mand 9/1/01) 
+757 VA [-5] E Virginia: Tidewater / Hampton Roads area -- Norfolk, Virginia Beach, Chesapeake, Portsmouth, Hampton, Newport News, Suffolk (part of what used to be 804 ) 
+758 -- [-4] St. Lucia (split from 809 ) 
+760 CA [-8] California: San Diego North County to Sierra Nevada (split from 619 ) 
+763 MN [-6] Cent. Minnesota: Minneapolis (split from 612 ; see also 952 ) 
+764 CA [-8] (overlay on 650 ; SUSPENDED) 
+765 IN [-5] Indiana: outside Indianapolis (split from 317 ) 
+767 -- [-4] Dominica (split from 809 ) 
+770 GA [-5] Georgia: Atlanta suburbs: outside of I- 285 ring road (part of what used to be 404 ; see also overlay 678 ) 
+772 FL [-5] S. Central Florida: St. Lucie, Martin, and Indian River counties (split from 561 ; eff 2/11/02; mand 11/11/02) 
+773 IL [-6] Illinois: city of Chicago, outside the loop (see 312 ; overlay 872 ) 
+774 MA [-5] Cent. Massachusetts: Framingham; Cape Cod (see split 978 , overlaid on 508 , eff 4/2/2001) 
+775 NV [-8] Nevada: Reno (all of NV except Clark County area; see 702 ) 
+778 BC [-8] Canada: British Columbia: Greater Vancouver (overlaid on 604 , per 11/3/01; see also 250) 
+780 AB [-7] Canada: Northern Alberta, north of Lacombe (see 403 ) 
+781 MA [-5] Massachusetts: Boston surburbs, to the north and west (see splits 617 , 508 ; overlay 339 ) 
+784 -- [-4] St. Vincent &amp; Grenadines (split from 809 ) 
+785 KS [-6] N &amp; W Kansas: Topeka (split from 913 ) 
+786 FL [-5] SE Florida, Monroe county (Miami; overlaid on 305 ) 
+787 PR [-4] Puerto Rico (see overlay 939 , perm 8/1/01) 
+800 -- [?] US toll free (see 888 , 877 , 866 , 855 , 844 , 833 , 822 ) 
+801 UT [-7] Utah: Salt Lake City Metro (see split 385 , eff 3/30/02; see also split 435) 
+802 VT [-5] Vermont 
+803 SC [-5] South Carolina: Columbia, Aiken (see 843 , 864 ) 
+804 VA [-5] E Virginia: Richmond (see splits 757 , 434 ) 
+805 CA [-8] S Cent. Coastal California (Ventura County): San Luis Obispo, Thousand Oaks (see 661 split) 
+806 TX [-6] Panhandle Texas: Amarillo 
+807 ON [-5/-6] Canada: W Ontario: Thunder Bay 
+808 HI [-10] Hawaii 
+809 -- [-4] Dominican Republic (see splits 264 , 268 , 284 , 340 , 441 , 473 , 664 , 758 , 767 , 784 , 868 , 876 ) 
+810 MI [-5] E Michigan: Flint, Pontiac (see 248 ; overlay 546 , split 586 ) 
+811 -- [--] Reserved for special applications 
+812 IN [-6] S Indiana: Evansville 
+813 FL [-5] SW Florida: Tampa Metro (splits 727 St. Petersburg, Clearwater, and 941 Sarasota) 
+814 PA [-5] Cent. Pennsylvania: Erie 
+815 IL [-6] NE Illinois: Rockford, Kankakee 
+816 MO [-6] N Missouri: Kansas City (see split 660 , overlay 975 ) 
+817 TX [-6] N Cent. Texas: Fort Worth area (see 254 , 940 ) 
+818 CA [-8] S California (Woodland Hills): Los Angeles (see 213 , 310 , 562 , 626 ) 
+819 QC [-5] NW Quebec: Trois Rivieres (see 867 ) 
+822 -- [?] US toll free (proposed, may not be in use yet) 
+828 NC [-5] W North Carolina: Asheville (split from 704 ) 
+830 TX [-6] Texas: N and W of San Antonio (split from 210 ) 
+831 CA [-8] California: central coast area from Santa Cruz through Monterey County 
+832 TX [-6] Texas: Houston (overlay 713 / 281 ) 
+833 -- [?] US toll free (proposed, may not be in use yet) 
+835 PA [-5] SE Pennsylvania: Allentown, Reading (overlaid on 610 , eff 5/1/01; see also 484) 
+836 FL [-5] Florida (region unknown) 
+843 SC [-5] South Carolina, coastal area: Charleston, Beaufort, Myrtle Beach (split from 803 ) 
+844 -- [?] US toll free (proposed, may not be in use yet) 
+845 NY [-5] New York: Poughkeepsie; Nyack, Nanuet, Valley Cottage, New City, Putnam, Dutchess, Rockland, Orange, Ulster and parts of Sullivan counties in New York's lower Hudson Valley (see 914 ; perm 6/5/2000) 
+847 IL [-6] Northern NE Illinois: northwestern suburbs of chicago (Evanston, Waukegan, Northbrook; see overlay 224 ) 
+848 NJ [-5] Cent. New Jersey: Toms River, New Brunswick, Bound Brook (see overlay 732 ) 
+850 FL [-5] Florida panhandle, from east of Tallahassee to Pensacola (split from 904 ) 
+855 -- [?] US toll free (proposed, may not be in use yet) 
+856 NJ [-5] SW New Jersey: greater Camden area, Mt Laurel (split from 609 ) 
+857 MA [-5] Massachusetts: greater Boston (overlaid on 617 , eff 4/2/2001) 
+858 CA [-8] S California: San Diego (see split 760 ; overlay 619 , 935 ) 
+859 KY [-5] N and Central Kentucky: Lexington; suburban KY counties of Cincinnati OH metro area; Covington, Newport, Ft. Thomas, Ft. Wright, Florence (split from 606 ) 
+860 CT [-5] Connecticut: Hartford, New London (split from 203 , overlay 959 ) 
+862 NJ [-5] N New Jersey: Newark Paterson Morristown (overlaid on 973 ) 
+863 FL [-5] Florida: Polk county (split from 941 ) 
+864 SC [-5] South Carolina, upstate area: Greenville, Spartanburg (split from 803 ) 
+865 TN [-5] E Tennessee: Knoxville, Knox and adjacent counties (split from 423 ; part of what used to be 615 ) 
+866 -- [?] US toll free 
+867 YT [-8/-9] Canada: Yukon and Northwest Territories (split from 403 / 819 ) 
+868 -- [-4] Trinidad and Tobago ("new" -- see 809 ) 
+869 -- [-4] St. Kitts &amp; Nevis 
+870 AR [-6] S. Arkansas: Jonesboro 
+872 IL [-6] Illinois: Chicago (downtown only -- in the loop; see 773 ; overlaid on 312 and 773 ) 
+876 -- [-5] Jamaica (split from 809 ) 
+877 -- [?] US toll free 
+878 PA [-5] Pittsburgh, New Castle (overlaid on 412 , perm 8/17/01, mand t.b.a.) 
+880 -- [--] Paid Toll-Free Service 
+881 -- [--] Paid Toll-Free Service 
+882 -- [--] Paid Toll-Free Service 
+888 -- [?] US toll free 
+900 -- [?] US toll calls -- prices vary with the number called 
+901 TN [-6] W Tennessee: Memphis metro area (see 615 , 931 , split 731 ) 
+902 NS [-4] Canada: Nova Scotia, Prince Edward Island 
+903 TX [-6] NE Texas: Tyler 
+904 FL [-5] N Florida: Jacksonville (see splits 352 , 386 , 850 ) 
+905 ON [-5] Canada: S Cent. Ontario: Greater Toronto Area -- Durham, Halton, Hamilton-Wentworth, Niagara, Peel, York, and southern Simcoe County (excluding Toronto -- see overlay 289 [eff 6/9/01], splits 416, 647) 
+906 MI [-5] Upper Peninsula Michigan: Sault Ste. Marie, Escanaba, Marquette 
+907 AK [-9] Alaska 
+908 NJ [-5] Cent. New Jersey: Elizabeth, Basking Ridge, Somerville, Bridgewater 
+909 CA [-8] California: Inland empire: San Bernandino (? see 752 ), Riverside 
+910 NC [-5] S Cent. North Carolina: Fayetteville, Wilmington (see 336 ) 
+911 -- [--] Emergency 
+912 GA [-5] SE Georgia: Savannah (see splits 229 , 478 ) 
+913 KS [-6] Kansas: Kansas City area (see 785 ) 
+914 NY [-5] S New York: Westchester County (see 845 ) 
+915 TX [-7/-6] W Texas: Sweetwater, El Paso, Odessa, Midland 
+916 CA [-8] NE California: Sacramento, Walnut Grove, Lincoln, Newcastle and El Dorado Hills (split to 530 ) 
+917 NY [-5] New York: New York City (cellular, see 646 ) 
+918 OK [-6] E Oklahoma: Tulsa (see 580 ) 
+919 NC [-5] E North Carolina: Raleigh (see split 252 , overlay 984 ) 
+920 WI [-6] NE Wisconsin: Appleton, Green Bay, Sheboygan, Fond du Lac (from Beaver Dam NE to Oshkosh, Appleton, and Door County; part of what used to be 414 ) 
+925 CA [-8] California (Antioch, Concord, Pleasanton, Walnut Creek; split from 510 ) 
+928 AZ [-7] Central and Northern Arizona (split from 520 ) 
+931 TN [-6] Central Tennessee: semi-circular ring around Nashville (split from 615 ) 
+935 CA [-8] S California: San Diego (see split 760 ; overlay 858 , 619 ; on hold) 
+936 TX [-6] SE Texas: Conroe, Lufkin, Nacogdoches, Crockett (split from 409 , see also 979 ) 
+937 OH [-5] SW Ohio: Dayton (part of what used to be 513 ) 
+939 PR [-4] Puerto Rico (overlaid on 787 , perm 8/1/01) 
+940 TX [-6] N Cent. Texas: Denton, Wichita Falls (split from 254 , 817 ) 
+941 FL [-5] SW Florida: Sarasota and Manatee counties (part of what used to be 813 ; see split 863 ) 
+947 MI [-5/-6] (Region unknown; perm 5/5/01) 
+949 CA [-8] California: S Coastal Orange County (split from 714 ) 
+951 CA [-8] (Region unknown) 
+952 MN [-6] Cent. Minnesota: Minneapolis, Bloomington (split from 612 ; see also 763 ) 
+954 FL [-5] Florida: Broward County area, incl Ft. Lauderdale (part of what used to be 305 , see overlay 754 ) 
+956 TX [-6] Texas: Valley of Texas area; Harlingen, Laredo (split from 210 ) 
+957 NM [-7] New Mexico (pending; region unknown) 
+959 CT [-5] Connecticut: Hartford, New London (overlaid on 860 perm 1/6/01; mand 3/1/01???) 
+969 MD [-5] Maryland: Severn area (eff ???) 
+970 CO [-7] N and W Colorado (part of what used to be 303 ) 
+971 OR [-8] Oregon: Metropolitan Portland (see 503 ; perm 10/1/00) 
+972 TX [-6] Texas: Dallas Metro (overlays 214 / 469 / 972 ) 
+973 NJ [-5] N New Jersey: Newark Paterson Morristown (see overlay 862 ; split from 201 ) 
+975 MO [-6] N Missouri: Kansas City (overlaid on 816 ) 
+978 MA [-5] Massachusetts: north of Boston to NH (see split 978 -- this is the northern half of old 508 ; see overlay 351 ) 
+979 TX [-6] SE Texas: Galveston, Port Arthur, Bryan, College Station (split from 409 , see also 936 ) 
+980 NC [-5] North Carolina: (overlay on 704 ; perm 5/1/00, mand 3-15-01) 
+984 NC [-5] E North Carolina: Raleigh (overlaid on 919 , perm 8/1/01, mand 2/5/02) 
+985 LA [-6] E Louisiana: SE/N shore of Lake Pontchartrain: Hammond, Slidell, Covington, Amite, Kentwood, area SW of New Orleans, Houma, Thibodaux, Morgan City (split from 504 ; perm 02/12/2001; mand 10/22/01) 
+989 MI [-5] Upper central Michigan: Mt Pleasant, Saginaw (split from 517 ; perm 4/7/01) 
+52555 MX [-6] Mexico: Mexico City area (country code + city code) 

+ 2 - 0
lib/font/bit/lucm/passwd.9.font

@@ -0,0 +1,2 @@
+17	14
+0x0000	0x0000	latin1.9

+ 128 - 32
lib/ndb/common

@@ -1,3 +1,107 @@
+#
+#	The master for this file is /n/emelie/lib/ndb/common
+#
+
+#
+#  ip protocol numbers
+#
+protocol=reserved	ipv4proto=0
+protocol=icmp		ipv4proto=1
+protocol=igmp		ipv4proto=2
+protocol=ggp		ipv4proto=3
+protocol=ip		ipv4proto=4
+protocol=st		ipv4proto=5
+protocol=tcp		ipv4proto=6
+protocol=ucl		ipv4proto=7
+protocol=egp		ipv4proto=8
+protocol=igp		ipv4proto=9
+protocol=bbn-rcc-mon	ipv4proto=10
+protocol=nvp-ii		ipv4proto=11
+protocol=pup		ipv4proto=12
+protocol=argus		ipv4proto=13
+protocol=emcon		ipv4proto=14
+protocol=xnet		ipv4proto=15
+protocol=chaos		ipv4proto=16
+protocol=udp		ipv4proto=17
+protocol=mux		ipv4proto=18
+protocol=dcn-meas	ipv4proto=19
+protocol=hmp		ipv4proto=20
+protocol=prm		ipv4proto=21
+protocol=xns-idp	ipv4proto=22
+protocol=trunk-1	ipv4proto=23
+protocol=trunk-2	ipv4proto=24
+protocol=leaf-1		ipv4proto=25
+protocol=leaf-2		ipv4proto=26
+protocol=rdp		ipv4proto=27
+protocol=irtp		ipv4proto=28
+protocol=iso-tp4	ipv4proto=29
+protocol=netblt		ipv4proto=30
+protocol=mfe-nsp	ipv4proto=31
+protocol=merit-inp	ipv4proto=32
+protocol=sep		ipv4proto=33
+protocol=3pc		ipv4proto=34
+protocol=idpr		ipv4proto=35
+protocol=xtp		ipv4proto=36
+protocol=ddp		ipv4proto=37
+protocol=idpr-cmtp	ipv4proto=38
+protocol=tp++		ipv4proto=39
+protocol=il		ipv4proto=40
+protocol=sip		ipv4proto=41
+protocol=sdrp		ipv4proto=42
+protocol=sip-sr		ipv4proto=43
+protocol=sip-frag	ipv4proto=44
+protocol=idrp		ipv4proto=45
+protocol=rsvp		ipv4proto=46
+protocol=gre		ipv4proto=47
+protocol=mhrp		ipv4proto=48
+protocol=bna		ipv4proto=49
+protocol=sipp-esp	ipv4proto=50
+protocol=sipp-ah	ipv4proto=51
+protocol=i-nlsp		ipv4proto=52
+protocol=swipe		ipv4proto=53
+protocol=nhrp		ipv4proto=54
+protocol=any		ipv4proto=61
+protocol=cftp		ipv4proto=62
+protocol=any		ipv4proto=63
+protocol=sat-expak	ipv4proto=64
+protocol=kryptolan	ipv4proto=65
+protocol=rvd		ipv4proto=66
+protocol=ippc		ipv4proto=67
+protocol=any		ipv4proto=68
+protocol=sat-mon	ipv4proto=69
+protocol=visa		ipv4proto=70
+protocol=ipcv		ipv4proto=71
+protocol=cpnx		ipv4proto=72
+protocol=cphb		ipv4proto=73
+protocol=wsn		ipv4proto=74
+protocol=pvp		ipv4proto=75
+protocol=br-sat-mon	ipv4proto=76
+protocol=sun-nd		ipv4proto=77
+protocol=wb-mon		ipv4proto=78
+protocol=wb-expak	ipv4proto=79
+protocol=iso-ip		ipv4proto=80
+protocol=vmtp		ipv4proto=81
+protocol=secure-vmtp	ipv4proto=82
+protocol=vines		ipv4proto=83
+protocol=ttp		ipv4proto=84
+protocol=nsfnet-igp	ipv4proto=85
+protocol=dgp		ipv4proto=86
+protocol=tcf		ipv4proto=87
+protocol=igrp		ipv4proto=88
+protocol=ospfigp	ipv4proto=89	protocol=ospf
+protocol=sprite-rpc	ipv4proto=90
+protocol=larp		ipv4proto=91
+protocol=mtp		ipv4proto=92
+protocol=ax.25		ipv4proto=93
+protocol=ipip		ipv4proto=94
+protocol=micp		ipv4proto=95
+protocol=scc-sp		ipv4proto=96
+protocol=etherip	ipv4proto=97
+protocol=encap		ipv4proto=98
+protocol=any		ipv4proto=99
+protocol=gmtp		ipv4proto=100
+protocol=rudp		ipv4proto=254	# unofficial
+
 #
 #  services
 #
@@ -15,6 +119,7 @@ tcp=telnet port=23
 tcp=smtp port=25
 tcp=time port=37
 tcp=whois port=43
+tcp=dns port=53
 tcp=domain port=53
 tcp=uucp port=64
 tcp=gopher port=70
@@ -34,6 +139,7 @@ tcp=sunrpc port=111
 tcp=uucp-path port=117
 tcp=nntp port=119
 tcp=netbios port=139
+tcp=imap4 port=143
 tcp=NeWS port=144
 tcp=print-srv port=170
 tcp=z39.50 port=210
@@ -43,7 +149,6 @@ tcp=proxy port=402
 tcp=proxyd port=404
 tcp=https port=443
 tcp=ssmtp port=465
-tcp=snntp port=563
 tcp=rexec port=512 restricted=
 tcp=login port=513 restricted=
 tcp=shell port=514 restricted=
@@ -51,14 +156,20 @@ tcp=printer port=515
 tcp=courier port=530
 tcp=cscan port=531
 tcp=uucp port=540
+tcp=snntp port=563
 tcp=9fs port=564
 tcp=whoami port=565
 tcp=guard port=566
 tcp=ticket port=567
+tcp=dlsftp port=666
 tcp=fmclient port=729
+tcp=imaps port=993
+tcp=pop3s port=995
 tcp=ingreslock port=1524
+tcp=pptp port=1723
 tcp=webster port=2627
 tcp=weather port=3000
+tcp=secstore port=5356
 tcp=Xdisplay port=6000
 tcp=styx port=6666
 tcp=mpeg port=6667
@@ -69,57 +180,42 @@ tcp=infcsigner port=6672
 tcp=inflogin port=6673
 tcp=bandt port=7330
 tcp=face port=32000
-tcp=ocpu port=17005
-tcp=ocpunote port=17006
 tcp=exportfs port=17007
 tcp=rexexec port=17009
 tcp=ncpu port=17010
-tcp=ncpunote port=17011
 tcp=cpu port=17013
-tcp=video port=17028
-tcp=vgen port=17029
-tcp=alefnslook port=17030
-tcp=411 port=17031
+tcp=glenglenda1 port=17020
+tcp=glenglenda2 port=17021
+tcp=glenglenda3 port=17022
+tcp=glenglenda4 port=17023
+tcp=glenglenda5 port=17024
+tcp=glenglenda6 port=17025
+tcp=glenglenda7 port=17026
+tcp=glenglenda8 port=17027
+tcp=glenglenda9 port=17028
+tcp=glenglenda10 port=17029
 tcp=flyboy port=17032
+tcp=dlsftp port=17033
 tcp=venti port=17034
 tcp=wiki port=17035
+tcp=vica port=17036
 
-il=echo port=7
-il=discard port=9
-il=chargen port=19
-il=whoami port=565
-il=ticket port=566
-il=challbox port=567
-il=ocpu port=17005
-il=ocpunote port=17006
-il=exportfs port=17007
 il=9fs port=17008
-il=rexexec port=17009
-il=ncpu port=17010
-il=ncpunote port=17011
-il=tcpu port=17012
-il=cpu port=17013
-il=fsauth port=17020
-il=rexauth port=17021
-il=changekey port=17022
-il=chal port=17023
-il=check port=17024
-il=juke port=17026
-il=video port=17028
-il=vgen port=17029
-il=alefnslook port=17030
-il=ramfs port=17031
 
 udp=echo port=7
 udp=tacacs port=49
 udp=tftp port=69
 udp=bootpc port=68
 udp=bootp port=67
+udp=domain port=53
 udp=dns port=53
 udp=ntp port=123
+udp=snmp port=161
 udp=rip port=520
 udp=bfs port=2201
 udp=virgil port=2202
 udp=bandt2 port=7331
+udp=oradius port=1645
+udp=chord-dhash port=11865
 
 gre=ppp port=34827

+ 1 - 0
lib/ndb/local

@@ -6,3 +6,4 @@ database=
 	file=/lib/ndb/local
 	file=/lib/ndb/common
 
+auth=sources.cs.bell-labs.com authdom=outside.plan9.bell-labs.com

+ 2 - 0
lib/ndb/local.complicated

@@ -103,3 +103,5 @@ ip=10.0.1.12 ether=0010dc724076 sys=term
 	dom=myterminal.myuniversity.edu
 	bootf=/386/9pc
 	proto=il
+
+auth=sources.cs.bell-labs.com authdom=outside.plan9.bell-labs.com

+ 2 - 0
lib/vgadb

@@ -268,6 +268,7 @@ ctlr
 ctlr
 	0xE0090="Chips 65540"				# Globalyst 250
 	0xC008D="Chips 65540"				# Midwest Micro Elite
+	0xE0090="TOSHIBA Video BIOS V1.40"
 	link=vga
 	ctlr=ct65540 linear=1
 	hwgc=ct65545hwgc
@@ -277,6 +278,7 @@ ctlr
 	0xC7800-0xC7B00="TVGA BIOS WEN 6.1"		# NEC Versa SX
 	0xC0078="Trident CYBER 8620"			# Acer TravelMate 350
 	0xC0093="Trident TGUI96xx"
+	0xC0044="GL A6.00E"
 	link=vga
 	ctlr=cyber938x linear=1
 	hwgc=cyber938xhwgc

+ 30 - 0
mail/lib/rewrite.direct

@@ -0,0 +1,30 @@
+#
+#	sample rewrite file for systems that send and receive mail directly.
+#
+#	by default, the return address points to this system; if you have multiple systems
+#	and don't want them all to be mail recipients, set $site to a generic
+#	name (e.g., plan9) or system name in /rc/bin/termrc and /rc/bin/cpurc
+#	and put an MX DNS record in /lib/ndb to point to that system.
+#
+#	replace YOURDOMAIN.DOM in the following rules with your domain name.
+
+# translate local aliases from /mail/lib/namefiles
+[^!@.]+			translate	"/bin/upas/aliasmail '&'"
+
+# deliver mail without a domain locally
+local!(.*)		>>		/mail/box/\1/mbox
+
+# your local names
+\l!(.*)					alias		\1
+\l\.YOURDOMAIN\.DOM!(.*)		alias		\1
+
+# convert source domain address to a chain a@b@c@d...
+@([^@!,]*):([^!@]*)@([^!]*)		alias	\2@\3@\1
+@([^@!]*),@([^!@,]*):([^!@]*)@([^!]*)	alias	@\1:\3@\4@\2
+
+# convert a chain a@b@c@d... to ...d!c!b!a
+([^@]+)@([^@]+)@(.+)	alias		\2!\1@\3
+([^@]+)@([^@]+)		alias		\2!\1
+
+# queue all mail for delivery
+([^!]*)!(.*) 		| 		"/mail/lib/qmail '\s' 'net!\1'" "'\2'"

+ 29 - 0
mail/lib/rewrite.gateway

@@ -0,0 +1,29 @@
+#
+#	sample rewrite file for systems that send mail to a mail server or gateway
+#	for delivery.  we assume the mail server handles incoming messages.
+#
+#	by default the return address points to this system; set $site
+#	to the name of the mail server that receives your mail in 
+#	/rc/bin/termrc and /rc/bin/cpurc.
+#
+#	replace YOURDOMAIN.DOM with the name of your domain.
+#
+#	in the last rule, $smtp is the name of the mail server.  set it
+#	in the DNS database in /lib/ndb (see ndb(6)).
+
+# translate local aliases from /mail/lib/namefiles
+[^!@.]+			translate	"/bin/upas/aliasmail '&'"
+
+# append the local domain to addresses without a domain
+local!(.*)		alias		\1@YOURDOMAIN.DOM
+
+# convert source domain address to a chain a@b@c@d...
+@([^@!,]*):([^!@]*)@([^!]*)		alias	\2@\3@\1
+@([^@!]*),@([^!@,]*):([^!@]*)@([^!]*)	alias	@\1:\3@\4@\2
+
+# convert a chain a@b@c@d... to ...d!c!b!a
+([^@]+)@([^@]+)@(.+)	alias		\2!\1@\3
+([^@]+)@([^@]+)		alias		\2!\1
+
+# send all mail to the gateway or mail server, $smtp,  for delivery
+([^!]*)!(.*) 		| 		"/mail/lib/qmail '\s' 'net!$smtp'" "'\2@\1'"

+ 2 - 0
rc/bin/9fs

@@ -15,6 +15,8 @@ case other
 	mount -C /srv/boot /n/other other
 case juke
 	srv -q il!jukefs && mount /srv/il!jukefs /n/njuke && bind -c /n/njuke/juke /n/juke
+case sources
+	srv -m tcp!sources.cs.bell-labs.com sources /n/sources
 case *
 	switch($#*){
 	case 1

+ 5 - 1
rc/bin/kill

@@ -1,4 +1,8 @@
 #!/bin/rc
+rfork e
+U=`{cat /dev/user}
 for(i){
-	ps | sed -n '/ '^$i^'$/s%^[^ ]* *([^ ]*).*%chmod 666 /proc/\1/ctl;echo kill > /proc/\1/ctl%p'
+	ps | sed -n '/^'$U' .* '$i'$/s%[^ ]*  *%~>/proc/%
+	s%  *.*%/note%
+	s%~%echo kill%p'
 }

+ 5 - 2
rc/bin/man

@@ -45,8 +45,11 @@ while(~ $d 0) {
 		echo 'Usage: man [-ntp] [-s sec] [0-9] [0-9] ... name1 name2 ...' >[1=2]
 		exit
 	}
-	switch($1) {
-		case [0-9] ; sec=($sec $1) ; shift
+	if(test -d $S/$1){
+		sec=($sec $1)
+		shift
+	}
+	if not switch($1) {
 		case -t ; cmd=t ; shift
 		case -n ; cmd=n ; shift
 		case -p ; cmd=p ; shift

+ 3 - 0
rc/bin/pci

@@ -0,0 +1,3 @@
+#!/bin/rc
+
+cd '#$/pci' && grep . *ctl | sed 's/ctl:/:	/'

+ 2 - 0
rc/bin/reboot

@@ -0,0 +1,2 @@
+#!/bin/rc
+echo reboot > /dev/reboot

BIN
sys/doc/-.2669382.gif


+ 868 - 0
sys/doc/8½/8½.html

@@ -0,0 +1,868 @@
+<html>
+<title>
+data
+</title>
+<body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#330088" ALINK="#FF0044">
+<H1>8&#189;, the Plan 9 Window System
+</H1>
+<DL><DD><I>Rob Pike<br>
+rob@plan9.bell-labs.com<br>
+</I></DL>
+<DL><DD><H4>ABSTRACT</H4>
+<DL>
+<DT><DT>&#32;<DD>
+NOTE:<I> Originally appeared, in a slightly different form, in
+Proc. of the Summer 1991 USENIX Conf.,
+pp. 257-265,
+Nashville.
+Note that
+<TT>8&#189;</TT>
+has been replaced by
+<TT>rio</TT>
+(see
+<A href="/magic/man2html/1/rio"><I>rio</I>(1)).
+</A></I><DT>&#32;<DD></dl>
+<br>
+The Plan 9 window system, 8&#189;, is a modest-sized program of novel design.
+It provides textual I/O and bitmap graphic services to both
+local and remote client programs by offering a multiplexed file service to those clients.
+It serves traditional UNIX files like
+<TT>/dev/tty</TT>
+as well as more unusual ones that provide access to the mouse
+and the raw screen.
+Bitmap graphics operations are provided by serving a file called
+<TT>/dev/bitblt</TT>
+that interprets client messages to perform raster operations.
+The file service that 8&#189; offers its clients is identical to that it uses for
+its own implementation, so it is fundamentally no more than
+a multiplexer.
+This architecture has some rewarding symmetries and can be implemented
+compactly.
+</DL>
+<H4>Introduction
+</H4>
+<P>
+In 1989 I constructed a toy window system from only a few hundred
+lines of source code using a custom language and an unusual architecture
+involving concurrent processes [Pike89].
+Although that system was rudimentary at best, it demonstrated that
+window systems are not inherently complicated.
+The following year, for the new Plan 9 distributed system [Pike92], I applied some of
+the lessons from that toy project to write, in C,
+a production-quality window system
+called 8&#189;.
+8&#189; provides, on black-and-white, grey-scale, or color displays,
+the services required of a modern window system, including
+programmability and support for remote graphics.
+The entire system, including the default program that runs in the 
+window &#173; the equivalent of
+<TT>xterm</TT>
+[Far89] with `cutting and pasting' between windows &#173;
+is well under 90 kilobytes of text on a Motorola 68020 processor, about
+half the size of the
+operating system
+kernel that supports it and a tenth the size of the X server
+[Sche86]
+<I>without</I>
+<TT>xterm</TT>.
+</P>
+<P>
+What makes 8&#189; so compact?  Much of the saving comes from overall simplicity:
+8&#189; has little graphical fanciness, a concise programming interface, and
+a simple, fixed user interface.
+8&#189; also makes some decisions by fiat
+&#173; three-button mouse, overlapping windows, built-in terminal program and
+window manager, etc. &#173;
+rather than trying to appeal to all tastes.
+Although compact, 8&#189; is not ascetic.
+It provides the fundamentals and
+enough extras to make them comfortable to use.
+The most important contributor to its small size, though, is its
+overall design as a file server.
+This structure may be applicable to window systems
+on traditional UNIX-like operating systems.
+</P>
+<P>
+The small size of 8&#189; does not reflect reduced functionality:
+8&#189; provides service roughly equivalent to the X window system.
+8&#189;'s clients may of course be as complex as they choose,
+although the tendency to mimic 8&#189;'s design
+and the clean programming interface means they
+are not nearly as bloated as X applications.
+</P>
+<H4>User's Model
+</H4>
+<P>
+8&#189; turns the single screen, mouse, and keyboard of the terminal
+(in Plan 9 terminology) or workstation (in commercial terminology) into an array
+of independent virtual terminals that may be textual terminals supporting a shell and
+the usual suite of tools
+or graphical applications using the full power of the bitmap screen and mouse.
+Text is represented in UTF, an encoding of the Unicode Standard [Pike93].
+The entire programming interface is provided through
+reading and writing files in
+<TT>/dev</TT>.
+</P>
+<P>
+Primarily for reasons of history and familiarity,
+the general model and appearance of 8&#189; are similar to those of
+<TT>mux</TT>
+[Pike88].
+The right button has a short menu for controlling window creation, destruction,
+and placement.
+When a window is created, it runs the default shell,
+<TT>rc</TT>
+[Duff90], with standard input
+and output directed to the window and accessible through the file
+<TT>/dev/cons</TT>
+(`console'),
+analogous to the
+<TT>/dev/tty</TT>
+of UNIX.
+The name change represents a break with the past: Plan 9 does not provide a
+Teletype-style model of terminals.  8&#189; provides the only way
+most users ever access Plan 9.
+</P>
+<P>
+Graphical applications,
+like ordinary programs,
+may be run by typing their names
+to the shell running in a window.
+This runs the application in the same window;
+to run the application in a new window one may use an external program,
+<TT>window</TT>,
+described below.
+For graphical applications, the virtual terminal model
+is extended somewhat to allow programs to perform graphical operations,
+access the
+mouse, and perform related functions by reading and writing files with
+suggestive names such as
+<TT>/dev/mouse</TT>
+and
+<TT>/dev/window</TT>
+multiplexed per-window
+much like
+<TT>/dev/cons</TT>.
+The implementation and semantics of these files,
+described below, is central to the structure of 8&#189;.
+</P>
+<P>
+The default program that runs in a window is familiar to users of Blit terminals [Pike83].
+It is very similar to that of
+<TT>mux</TT>
+[Pike88], providing mouse-based editing of input and output text,
+the ability to scroll back to see earlier output, and so on.
+It also has a new feature, toggled by typing ESC,
+that enables the user to control when
+typed characters may be read by the shell or application,
+instead of (for example) after each newline.
+This feature makes the window program directly useful for many text-editing
+tasks such as composing mail messages before sending them.
+</P>
+<H4>Plan 9 and 8&#189;
+</H4>
+<P>
+Plan 9 is a distributed system that provides support for UNIX-like applications
+in an environment built from distinct CPU servers, file servers, and terminals
+connected by a variety of networks [Pike90].
+The terminals are comparable to modest workstations that, once connected to a file
+server over a medium-bandwidth network such as Ethernet, are self-sufficient computers
+running a full operating system.
+Unlike workstations, however, their role is just to
+provide an affordable multiplexed user interface to the rest of the system:
+they run the window system and support simple interactive
+tasks such as text editing.
+Thus they lie somewhere between workstations and X terminals in design,
+cost, performance, and function.
+(The terminals can be used
+for general computing, but in practice Plan 9 users do their
+computing on the CPU servers.)
+The Plan 9 terminal software, including 8&#189;,
+was developed on a 68020-based
+machine called a Gnot
+and has been ported to
+the NeXTstation,
+the MIPS Magnum 3000,
+SGI Indigos,
+and Sun SPARCstations&#173;all small workstations that we use as terminals&#173;as
+well as PCs.
+</P>
+<P>
+Heavy computations such as compilation, text processing,
+or scientific calculation are done on the CPU servers, which are connected
+to the file servers by high-bandwidth networks.
+For interactive work,
+these computations can access the terminal that instantiated them.
+The terminal and CPU server being used by a particular user are connected to the
+same file server, although over different networks; Plan 9 provides a view of the
+file server that is independent of location in the network.
+</P>
+<P>
+The components of Plan 9 are connected by a common protocol based on the sharing of files.
+All resources in the network are implemented as file servers; programs that wish to
+access them connect to them over the network and communicate using ordinary file
+operations.
+An unusual aspect of Plan 9 is that the
+name space
+of a process, the set of files that can be accessed by name
+(for example by an
+<TT>open</TT>
+system call) is not global to all processes on a machine; distinct processes
+may have distinct name spaces.  The system provides methods by which processes
+may change their name spaces, such as the ability to
+<I>mount</I>
+a service upon an existing directory, making the files of the service
+visible in the directory.
+(This is a different operation from its
+UNIX
+namesake.)
+Multiple services may be mounted upon the same directory,
+allowing the files from multiple services to be accessed in the same directory.
+Options to the
+<TT>mount</TT>
+system call control the order of searching for files in such a
+union directory.
+</P>
+<P>
+The most obvious example of a network resource is a file server, where permanent
+files reside.  There are a number of unusual services, however, whose design in
+a different environment would likely not be file-based.  Many are described
+elsewhere [Pike92]; some examples are the representation
+of processes for debugging,
+much like Killian's process files for the 8th edition [Kill84],
+and the implementation of the name/value pairs of the
+UNIX
+<TT>exec</TT>
+environment as files.
+User processes may also implement a file service and make it available to clients
+in the network, much like the `mounted streams' in the 9th Edition
+[Pres90].
+A typical example is a program that interprets an externally-defined file system
+such as that on a CD-ROM or a standard
+UNIX
+system and makes the contents available to Plan 9 programs.
+This design is used by all distributed applications in Plan 9, including 8&#189;.
+</P>
+<P>
+8&#189; serves a set of files in the conventional directory
+<TT>/dev</TT>
+with names like
+<TT>cons</TT>,
+<TT>mouse</TT>,
+and
+<TT>screen</TT>.
+Clients of 8&#189; communicate with the window system by reading and writing
+these files.
+For example, a client program, such as a shell,
+can print text by writing its standard output, which is automatically
+connected to
+<TT>/dev/cons</TT>,
+or it may open and write that file explicitly.
+Unlike files served by a traditional file server, however, the instance of
+<TT>/dev/cons</TT>
+served in each window by 8&#189; is a distinct file;
+the per-process name spaces of Plan 9 allow 8&#189; to provide a unique
+<TT>/dev/cons</TT>
+to each client.
+This mechanism is best illustrated by the creation of a new 8&#189; client.
+</P>
+<P>
+When 8&#189; starts, it creates a full-duplex pipe to be the communication
+medium for the messages that implement the file service it will provide.
+One end will be shared by all the clients; the other end is held by
+8&#189; to accept requests for I/O.
+When a user makes a new window using the mouse,
+8&#189; allocates the window data structures and forks a child process.
+The child's name space,
+initially shared with the parent,
+is then duplicated
+so that changes the child makes to its name space will not affect the parent.
+The child then attaches its end of the communication pipe,
+<TT>cfd</TT>,
+to the directory
+<TT>/dev</TT>
+by doing a
+<TT>mount</TT>
+system call:
+<DL><DT><DD><TT><PRE>
+mount(cfd, "/dev", MBEFORE, buf)
+</PRE></TT></DL>
+This call attaches the service associated with the file descriptor
+<TT>cfd</TT>
+&#173; the client end of the pipe &#173; to the beginning of
+<TT>/dev</TT>
+so that the files in the new service take priority over existing files
+in the directory.
+This makes the new files
+<TT>cons</TT>,
+<TT>mouse</TT>,
+and so on,
+available in
+<TT>/dev</TT>
+in a way that hides any files with the same names already in place.
+The argument
+<TT>buf</TT>
+is a character string (null in this case),
+described below.
+</P>
+<P>
+The client process then closes file descriptors 0, 1, and 2 and opens
+<TT>/dev/cons</TT>
+repeatedly to connect the standard
+input, output, and error files to the window's
+<TT>/dev/cons</TT>.
+It then does an
+<TT>exec</TT>
+system call to begin executing the shell in the window.
+This entire sequence, complete with error handling, is 33 lines of C.
+</P>
+<P>
+The view of these events from 8&#189;'s end of the pipe is a sequence
+of file protocol messages from the new client generated by the
+intervening operating
+system in response to the
+<TT>mount</TT>
+and
+<TT>open</TT>
+system calls executed by the client.
+The message generated by the
+<TT>mount</TT>
+informs 8&#189; that a new client has attached to the file service it provides;
+8&#189;'s response is a unique identifier kept by the operating system and
+passed in all messages generated by I/O on the files derived from that
+<TT>mount</TT>.
+This identifier is used by 8&#189; to distinguish the various clients so
+each sees a unique
+<TT>/dev/cons</TT>;
+most servers do not need to make this distinction.
+</P>
+<P>
+A process unrelated to 8&#189; may create windows by a variant of this mechanism.
+When 8&#189; begins, it uses a Plan 9 service to `post' the client end of the
+communication pipe in a public place.
+A process may open that pipe and
+<TT>mount</TT>
+it to attach to the window system,
+much in the way an X client may connect to a
+UNIX
+domain socket to the server bound to the file system.
+The final argument to
+<TT>mount</TT>
+is passed through uninterpreted by the operating
+system.
+It provides a way for the client and server to
+exchange information at the time of the
+<TT>mount</TT>.
+8&#189; interprets it as the dimensions of the window to be
+created for the new client.  (In the case above, the window has been
+created by the time the mount occurs, and
+<TT>buf</TT>
+carries no information.)
+When the
+<TT>mount</TT>
+returns, the process can open the files of the new window and begin I/O to
+use it.
+</P>
+<P>
+Because 8&#189;'s interface is based on files,
+standard system utilities can be used to control its services.
+For example,
+its method of creating windows externally is packaged in a
+16-line shell script, called
+<TT>window</TT>,
+the core of which is just a
+<TT>mount</TT>
+operation that prefixes 8&#189;'s directory to
+<TT>/dev</TT>
+and runs a command passed on the argument line:
+<DL><DT><DD><TT><PRE>
+mount -b $'8&#189;serv' /dev
+$* &#60; /dev/cons &#62; /dev/cons &#62;[2] /dev/cons &amp;
+</PRE></TT></DL>
+The
+<TT>window</TT>
+program is typically employed by users to create their
+initial working environment when they boot the system, although
+it has more general possibilities.
+</P>
+<P>
+Other basic features of the system fall out naturally from the
+file-based model.
+When the user deletes a window, 8&#189; sends the equivalent of a
+UNIX
+signal to the process group &#173; the clients &#173; in the window,
+removes the window from the screen, and poisons the incoming connections
+to the files that drive it.  If a client ignores the signal and
+continues to write to the window, it will get I/O errors.
+If, on the other hand, all the processes in a window exit spontaneously,
+they will automatically close all connections to the window.
+8&#189; counts references to the window's files; when none are left,
+it shuts down the window and removes it from the screen.
+As a different example, when the user hits the DEL key to generate an
+interrupt,
+8&#189; writes a message to a special file, provided by Plan 9's
+process control interface, that interrupts all the processes
+in the window.
+In all these examples, the implementation works seamlessly
+across a network.
+</P>
+<P>
+There are two valuable side effects of implementing
+a window system by multiplexing
+<TT>/dev/cons</TT>
+and other such files.
+First, the problem of giving a meaningful
+interpretation to the file
+<TT>/dev/cons</TT>
+(<TT>/dev/tty</TT>)
+in each window is solved automatically.
+To provide
+<TT>/dev/cons</TT>
+is the fundamental job of the window system, rather than just an awkward burden;
+other systems must often make special and otherwise irrelevant arrangements for
+<TT>/dev/tty</TT>
+to behave as expected in a window.
+Second, any program that can access the server, including a
+process on a remote machine, can access the files using standard
+read and write system calls to communicate with the window system,
+and standard open and close calls to connect to it.
+Again, no special arrangements need to be made for remote processes to
+use all the graphics facilities of 8&#189;.
+</P>
+<H4>Graphical input
+</H4>
+<P>
+Of course 8&#189; offers more than ASCII I/O to its clients.
+The state of the mouse may be discovered by reading the file
+<TT>/dev/mouse</TT>,
+which returns a ten-byte message encoding the state
+of the buttons and the position of the cursor.
+If the mouse has not moved since the last read of
+<TT>/dev/mouse</TT>,
+or if the window associated with the instance of
+<TT>/dev/mouse</TT>
+is not the `input focus', the read blocks.
+</P>
+<P>
+The format of the message is:
+<DL><DT><DD><TT><PRE>
+<TT>'m'</TT>
+1 byte of button state
+4 bytes of x, low byte first
+4 bytes of y, low byte first
+</PRE></TT></DL>
+As in all shared data structures in Plan 9,
+the order of every byte in the message is defined 
+so all clients can execute the same code to unpack the message
+into a local data structure.
+</P>
+<P>
+For keyboard input, clients can read
+<TT>/dev/cons</TT>
+or, if they need character-at-a-time input,
+<TT>/dev/rcons</TT>
+(`raw console').
+There is no explicit event mechanism to help clients that need to read
+from multiple sources.
+Instead, a small (365 line) external
+support library can be used.
+It attaches a process
+to the various blocking input sources &#173; mouse, keyboard, and perhaps
+a third user-provided file descriptor &#173;
+and funnels their input into a single pipe from which may be read
+the various types of
+events in the traditional style.
+This package is a compromise.  As discussed in a previous paper
+[Pike89] I prefer
+to free applications from event-based programming.  Unfortunately, though, I see
+no easy way to achieve this in single-threaded C programs, and am unwilling
+to require all programmers to master concurrent programming.
+It should be noted, though, that even this compromise results in a small
+and easily understood interface.  An example program that uses it is
+given near the end of the paper.
+</P>
+<H4>Graphical output
+</H4>
+<P>
+The file
+<TT>/dev/screen</TT>
+may be read by any client to recover the contents of the entire screen,
+such as for printing (see Figure 1).
+Similarly,
+<TT>/dev/window</TT>
+holds the contents of the current window.
+These are read-only files.
+</P>
+<P>
+To perform graphics operations in their windows, client programs access
+<TT>/dev/bitblt</TT>.
+It implements a protocol that encodes bitmap graphics operations.
+Most of the messages in the protocol (there are 23 messages in all, about
+half to manage the multi-level fonts necessary for efficient handling
+of Unicode characters)
+are transmissions (via a write)
+from the client to the window system to perform a graphical
+operation such as a
+<TT>bitblt</TT>
+[PLR85] or character-drawing operation; a few include return information
+(recovered via a read) to the client.
+As with
+<TT>/dev/mouse</TT>,
+the
+<TT>/dev/bitblt</TT>
+protocol is in a defined byte order.
+Here, for example, is the layout of the
+<TT>bitblt</TT>
+message:
+<DL><DT><DD><TT><PRE>
+<TT>'b'</TT>
+2 bytes of destination id
+2x4 bytes of destination point
+2 bytes of source id
+4x4 bytes of source rectangle
+2 bytes of boolean function code
+</PRE></TT></DL>
+</P>
+<DL>
+<DT><DT>&#32;<DD>
+Figure 1.
+A representative 8&#189; screen, running on a NeXTstation under Plan 9
+(with no NeXT software).  In the upper right, a program announces the
+arrival of mail.  In the top and left are a broswer for astronomical
+databases and an image of a galaxy produced by the browser.
+In the lower left there is a screen editor,
+<TT>sam</TT>
+[Pike87],
+editing Japanese text encoded in UTF,
+and in the lower right an 8&#189; running recursively and, inside that instantiation,
+a previewer for
+<TT>troff</TT>
+output.
+Underneath the faces is a small window running the command that
+prints the screen by passing
+<TT>/dev/screen</TT>
+to the bitmap printing utility.
+<br>&#32;<br>
+</dl>
+<P>
+The message is trivially constructed from the
+<TT>bitblt</TT>
+subroutine in the library, defined as
+<DL><DT><DD><TT><PRE>
+void bitblt(Bitmap *dst, Point dp,
+            Bitmap *src, Rectangle sr, Fcode c).
+</PRE></TT></DL>
+</P>
+<P>
+The `id'
+fields in the message indicate another property of 8&#189;:
+the clients do not store the actual data for any of their bitmaps locally.
+Instead, the protocol provides a message to allocate a bitmap, to be
+stored in the server, and returns to the client an integer identifier,
+much like a
+UNIX
+file descriptor, to be used in operations on that bitmap.
+Bitmap number 0 is conventionally the client's window,
+analogous to standard input for file I/O.
+In fact, no bitmap graphics operations are executed in the client at all;
+they are all performed on its behalf by the server.
+Again, using the standard remote file operations in Plan 9,
+this permits remote machines having no graphics capability, such
+as the CPU server,
+to run graphics applications.
+Analogous features of the original Andrew window system [Gos86]
+and of X [Sche86] require more complex mechanisms.
+</P>
+<P>
+Nor does 8&#189; itself operate directly on bitmaps.
+Instead, it calls another server to do its graphics operations for it,
+using an identical protocol.
+The operating system for the Plan 9 terminals contains an internal
+server that implements that protocol, exactly as does 8&#189;, but for a single
+client.  That server stores the actual bytes for the bitmaps
+and implements the fundamental bitmap graphics operations.
+Thus the environment in which 8&#189; runs
+has exactly the structure it provides for its clients;
+8&#189; reproduces the environment for its clients,
+multiplexing the interface to keep the clients separate.
+</P>
+<P>
+This idea of multiplexing by simulation is applicable to more
+than window systems, of course, and has some side effects.
+Since 8&#189; simulates its own environment for its clients, it may run
+in one of its own windows (see Figure 1).
+A useful and common application of this
+technique is to connect a window to a remote machine, such as a CPU
+server, and run the window system there so that each subwindow is automatically
+on the remote machine.
+It is also a handy way to debug a new version of the window system
+or to create an environment with, for example, a different default font.
+</P>
+<H4>Implementation
+</H4>
+<P>
+To provide graphics to its clients, 8&#189; mostly just multiplexes and passes
+through to its own server the clients' requests, occasionally rearranging
+the messages to maintain the fiction that the clients have unique screens
+(windows).
+To manage the overlapping windows it uses the layers model,
+which is handled by a separate library [Pike83a].
+Thus it has little work to do and is a fairly simple program;
+it is dominated by a couple of switch statements to interpret
+the bitmap and file server protocols.
+The built-in window program and its associated menus and text-management
+support are responsible for most of the code.
+</P>
+<P>
+The operating system's server is also compact:
+the version for the 68020 processor, excluding the implementation
+of a half dozen bitmap graphics operations, is 2295 lines of C
+(again, about half dealing with fonts);
+the graphics operations are another 2214 lines.
+</P>
+<P>
+8&#189; is structured as a set of communicating coroutines,
+much as discussed in a 1989 paper [Pike89].
+One coroutine manages the mouse, another the keyboard, and another
+is instantiated to manage the state of each window and associated client.
+When no coroutine wishes to run, 8&#189; reads the next file I/O request from
+its clients, which arrive serially on the full-duplex communication pipe.
+Thus 8&#189; is entirely synchronous.
+</P>
+<P>
+The program source is small and compiles in about 10 seconds
+in our Plan 9 environment.  There are ten source files and
+one
+<TT>makefile</TT>
+totaling 5100 lines.
+This includes the source for the window management process,
+the cut-and-paste terminal program,
+the window/file server itself,
+and a small coroutine library
+(<TT>proc.c</TT>).
+It does not include the layer library
+(another 1031 lines)
+or the library to handle the cutting and pasting of text
+displayed in a window (960 lines),
+or the general graphics support library that manages all the
+non-drawing aspects of graphics &#173; arithmetic on points and rectangles,
+memory management, error handling, clipping, &#173; plus fonts,
+events, and non-primitive drawing operations such as circles and ellipses
+(a final 3051 lines).
+Not all the pieces of these libraries are used by 8&#189; itself;
+a large part of the graphics library in particular is used only by clients.
+Thus it is somewhat unfair to 8&#189; just to sum these numbers, including
+the 4509 lines of support in the kernel, and arrive
+at a total implementation size of 14651 lines of source to implement
+all of 8&#189; from the lowest levels to the highest.
+But that number gives a fair measure of the complexity of the overall system.
+</P>
+<P>
+The implementation is also efficient.
+8&#189;'s performance is competitive to X windows'.
+Compared using Dunwoody's and Linton's
+<TT>gbench</TT>
+benchmarks on the 68020,
+distributed with the ``X Test Suite'',
+circles and arcs are drawn about half as fast in 8&#189; as in
+X11 release 4 compiled with
+<TT>gcc</TT>
+for equivalent hardware,
+probably because they are currently implemented in a user library
+by calls to the
+<TT>point</TT>
+primitive.
+Line drawing speed is about equal between the two systems.
+Unicode text is drawn about the same speed by 8&#189; as ASCII text by
+X, and
+the
+<TT>bitblt</TT>
+test is runs four times faster for 8&#189;.
+These numbers vary enough to caution against drawing sweeping
+conclusions, but they
+suggest that 8&#189;'s architecture does not penalize its performance.
+Finally, 8&#189; boots in under a second and creates a new window
+apparently instantaneously.
+</P>
+<H4>An example
+</H4>
+<P>
+Here is a complete program that runs under 8&#189;.
+It prints the string
+<TT>"hello world"</TT>
+wherever the left mouse button is depressed, and exits when the
+right mouse button is depressed.
+It also prints the string in the center of its window, and maintains
+that string when the window is resized.
+<DL><DT><DD><TT><PRE>
+#include &#60;u.h&#62;
+#include &#60;libc.h&#62;
+#include &#60;libg.h&#62;
+
+void
+ereshaped(Rectangle r)
+{
+    Point p;
+
+    screen.r = r;
+    bitblt(&amp;screen, screen.r.min, &amp;screen, r, Zero); /* clear */
+    p.x = screen.r.min.x + Dx(screen.r)/2;
+    p.y = screen.r.min.y + Dy(screen.r)/2;
+    p = sub(p, div(strsize(font, "hello world"), 2));
+    string(&amp;screen, p, font, "hello world", S);
+}
+
+main(void)
+{
+    Mouse m;
+
+    binit(0, 0, 0);	/* initialize graphics library */
+    einit(Emouse);	/* initialize event library */
+    ereshaped(screen.r);
+    for(;;){
+        m = emouse();
+        if(m.buttons &amp; RIGHTB)
+            break;
+        if(m.buttons &amp; LEFTB){
+            string(&amp;screen, m.xy, font, "hello world", S);
+            /* wait for release of button */
+            do; while(emouse().buttons &amp; LEFTB);
+        }
+    }
+}
+</PRE></TT></DL>
+The complete loaded binary is a little over 26K bytes on a 68020.
+This program should be compared to the similar ones in the excellent paper
+by Rosenthal [Rose88].
+(The current program does more: it also employs the mouse.)
+The clumsiest part is
+<TT>ereshaped</TT>,
+a function with a known name that is called from the event library
+whenever the window is
+reshaped or moved, as is discovered inelegantly but adequately
+by a special case of a mouse message.
+(Simple so-called expose events are not events
+at all in 8&#189;; the layer library takes care of them transparently.)
+The lesson of this program, with deference to Rosenthal, is that if
+the window system is cleanly designed a toolkit should be unnecessary
+for simple tasks.
+</P>
+<H4>Status
+</H4>
+<P>
+As of 1992, 8&#189; is in regular daily use by almost all the 60 people in our
+research center.  Some of those people use it to access Plan 9 itself; others
+use it as a front end to remote
+UNIX
+systems, much as one would use an X terminal.
+</P>
+<P>
+Some things about 8&#189; may change.
+It would be nice if its capabilities were more easily accessible
+from the shell.
+A companion to this paper [Pike91] proposes one way to do this,
+but that does not include any graphics functionality.
+Perhaps a textual version of the
+<TT>/dev/bitblt</TT>
+file is a way to proceed; that would allow, for example,
+<TT>awk</TT>
+programs to draw graphs directly.
+</P>
+<P>
+Can this style of window system be built on other operating systems?
+A major part of the design of 8&#189; depends on its structure as a file server.
+In principle this could be done for any system that supports user processes
+that serve files, such as any system running NFS or AFS [Sun89, Kaza87].
+One requirement, however, is 8&#189;'s need
+to respond to its clients' requests out of order:
+if one client reads
+<TT>/dev/cons</TT>
+in a window with no characters to be read,
+other clients should be able to perform I/O in their windows, or even
+the same window.
+Another constraint is that the 8&#189; files are like devices,
+and must not be cached by the client.
+NFS cannot honor these requirements; AFS may be able to.
+Of course, other interprocess communication mechanisms such as sockets
+could be used as a basis for a window system.  One may even argue that
+X's model fits into this overall scheme.  It may prove easy and worthwhile
+to write a small 8&#189;-like system for commercial
+UNIX
+systems to demonstrate that its merits can be won in systems other than
+Plan 9.
+</P>
+<H4>Conclusion
+</H4>
+<P>
+In conclusion, 8&#189; uses an unusual architecture in
+concert with the file-oriented interprocess communication of Plan 9
+to provide network-based interactive graphics to client programs.
+It demonstrates that even production-quality window systems are not
+inherently large or complicated
+and may be simple to use and to program.
+</P>
+<H4>Acknowledgements
+</H4>
+<P>
+Helpful comments on early drafts of this paper were made by
+Doug Blewett,
+Stu Feldman,
+Chris Fraser,
+Brian Kernighan,
+Dennis Ritchie,
+and Phil Winterbottom.
+8&#189;'s support for color was added by Howard Trickey.
+Many of the ideas leading to 8&#189; were tried out in earlier, sometimes less
+successful, programs.  I would like to thank those users who suffered
+through some of my previous 7&#189; window systems.
+</P>
+<H4>References
+</H4>
+<br>&#32;<br>
+[Duff90] Tom Duff, ``Rc - A Shell for Plan 9 and UNIX systems'', Proc. of the Summer 1990 UKUUG Conf., London, July, 1990, pp. 21-33, reprinted, in a different form, in this volume.
+<br>&#32;<br>
+[Far89] Far too many people, XTERM(1), Massachusetts Institute of Technology, 1989.
+<br>&#32;<br>
+[Gos86] James Gosling and David Rosenthal,
+``A window manager for bitmapped displays and UNIX'', in Methodology of Window Management, edited by F.R.A. Hopgood et al., Springer, 1986.
+<br>&#32;<br>
+[Kaza87] Mike Kazar, ``Synchronization and Caching issues in the Andrew File System'', Tech. Rept. CMU-ITC-058, Information Technology Center, Carnegie Mellon University, June, 1987.
+<br>&#32;<br>
+[Kill84] Tom Killian, ``Processes as Files'', USENIX Summer Conf. Proc., Salt Lake City June, 1984.
+<br>&#32;<br>
+[Pike83] Rob Pike, ``The Blit: A Multiplexed Graphics Terminal'', Bell Labs Tech. J., V63, #8, part 2, pp. 1607-1631.
+<br>&#32;<br>
+[Pike83a] Rob Pike, ``Graphics in Overlapping Bitmap Layers'', Trans. on Graph., Vol 2, #2, 135-160, reprinted in Proc. SIGGRAPH '83, pp. 331-356.
+<br>&#32;<br>
+[Pike87] Rob Pike, ``The Text Editor <TT>sam</TT>'', Softw. - Prac. and Exp., Nov 1987, Vol 17 #11, pp. 813-845, reprinted in this volume.
+<br>&#32;<br>
+[Pike88] Rob Pike, ``Window Systems Should Be Transparent'', Comp. Sys., Summer 1988, Vol 1 #3, pp. 279-296.
+<br>&#32;<br>
+[Pike89] Rob Pike, ``A Concurrent Window System'', Comp. Sys., Spring 1989, Vol 2 #2, pp. 133-153.
+<br>&#32;<br>
+[Pike91] Rob Pike, ``A Minimalist Global User Interface'', USENIX Summer Conf. Proc., Nashville, June, 1991.
+<br>&#32;<br>
+[Pike92]  Rob Pike, Dave Presotto, Ken Thompson, Howard Trickey, and Phil Winterbottom,
+Operating Systems Review
+Vol 27, #2, Apr 1993, pp. 72-76
+(reprinted from Proceedings of the 5th ACM SIGOPS European Workshop, Mont Saint-Michel, 1992, Paper n&#186; 34, and reprinted in this volume).
+<br>&#32;<br>
+[Pike94] Rob Pike and Ken Thompson, ``Hello World or &#191;ALPHA&#191;&#191;MU&#191;&#191;ALPHA &#191;&#191;&#191;MUEPSILON or &#191;&#191;&#191;&#191;&#191; &#191;&#191;'', USENIX Winter Conf. Proc., San Diego, Jan, 1993, reprinted in this volume.
+<br>&#32;<br>
+[PLR85] Rob Pike, Bart Locanthi and John Reiser, ``Hardware/Software Tradeoffs for Bitmap Graphics on the Blit'', Softw. - Prac. and Exp., Feb 1985, Vol 15 #2, pp. 131-152.
+<br>&#32;<br>
+[Pres90] David L. Presotto and Dennis M. Ritchie, ``Interprocess Communication in the Ninth Edition Unix System'', Softw. - Prac. and Exp., June 1990, Vol 20 #S1, pp. S1/3-S1/17.
+<br>&#32;<br>
+[Rose88] David Rosenthal, ``A Simple X11 Client Program -or- How hard can it really be to write ``Hello, World''?'', USENIX Winter Conf. Proc., Dallas, Jan, 1988, pp. 229-242.
+<br>&#32;<br>
+[Sche86] Robert W. Scheifler and Jim Gettys,
+``The X Window System'',
+ACM Trans. on Graph., Vol 5 #2, pp. 79-109.
+<br>&#32;<br>
+[Sun89] Sun Microsystems, NFS: Network file system protocol specification,
+RFC 1094, Network Information Center, SRI International, March, 1989.
+<br>
+<br>&#32;<br>
+<A href=http://www.lucent.com/copyright.html>
+Copyright</A> &#169; 2000 Lucent Technologies Inc.  All rights reserved.
+</body></html>

+ 1351 - 0
sys/doc/acme/acme.html

@@ -0,0 +1,1351 @@
+<html>
+<title>
+data
+</title>
+<body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#330088" ALINK="#FF0044">
+<H1>Acme: A User Interface for Programmers
+</H1>
+<DL><DD><I><I>Rob Pike</I>
+<I>rob@plan9.bell-labs.com</I>
+</I></DL>
+<DL><DD><H4>ABSTRACT</H4>
+<DL>
+<DT><DT>&#32;<DD>
+NOTE:<I> <HR>
+<br>
+Originally appeared in
+Proc. of the Winter 1994 USENIX Conf.,
+pp. 223-234,
+San Francisco, CA
+</I><DT>&#32;<DD></dl>
+<br>
+A hybrid of window system, shell, and editor, Acme gives text-oriented
+applications a clean, expressive, and consistent style of interaction.
+Traditional window systems support interactive client programs and offer libraries of
+pre-defined operations such as pop-up menus
+and buttons to promote a consistent
+user interface among the clients.
+Acme instead provides its clients with a fixed user interface and
+simple conventions to encourage its uniform use.
+Clients access the facilities of Acme through a file system interface;
+Acme is in part a file server that exports device-like files that may be
+manipulated to access and control the contents of its windows.
+Written in a concurrent programming language,
+Acme is structured as a set of communicating processes that neatly subdivide
+the various aspects of its tasks: display management, input, file server, and so on.
+<P>
+Acme attaches distinct functions to the three mouse buttons:
+the left selects text;
+the middle executes textual commands;
+and the right combines context search and file opening
+functions to integrate the various applications and files in
+the system.
+</P>
+<P>
+Acme works well enough to have developed
+a community that uses it exclusively.
+Although Acme discourages the traditional style of interaction
+based on typescript windows&#173;teletypes&#173;its
+users find Acme's other services render
+typescripts obsolete. 
+</DL>
+</P>
+<H4>History and motivation
+</H4>
+<P>
+The usual typescript style of interaction with
+Unix and its relatives is an old one.
+The typescript&#173;an intermingling of textual commands and their
+output&#173;originates with the scrolls of paper on teletypes.
+The advent of windowed terminals has given each user what
+amounts to an array of teletypes, a limited and unimaginative
+use of the powers of bitmap displays and mice.
+Systems like the Macintosh
+that do involve the mouse as an integral part of the interaction
+are geared towards general users, not experts, and certainly
+not programmers.
+Software developers, at least on time-sharing systems, have been left behind.
+<br><img src="acme.fig1.14050.gif"><br>
+<br>&#32;<br>
+
+Figure 1.  A small Acme screen&#173;normally it runs on a larger display&#173;demonstrating
+some of the details discussed in the text.
+The right column contains some guide files,
+a mailbox presented by Acme's mail program,
+the columnated display of files in Acme's own source directory,
+a couple of windows from the OED browser,
+a debugger window,
+and an error window showing diagnostics from a compilation.
+The left column holds a couple of source files
+(<TT>dat.h</TT>
+and
+<TT>acme.l</TT>),
+another debugger window displaying a stack trace,
+and a third source file
+(<TT>time.l</TT>).
+<TT>Time.l</TT>
+was opened from the debugger by clicking the right mouse button
+on a line in the stack window;
+the mouse cursor landed on the offending line of
+<TT>acme.l</TT>
+after a click on the compiler message.
+<br>
+<HR>
+</P>
+<P>
+Some programs have mouse-based editing of
+text files and typescripts;
+ones I have built include
+the window systems
+<TT>mux</TT>
+[Pike88]
+and
+<TT>8&#189;</TT>
+[Pike91]
+and the text editor
+Sam [Pike87].
+These have put the programmer's mouse to some productive work,
+but not wholeheartedly.  Even experienced users of these programs
+often retype text that could be grabbed with the mouse,
+partly because the menu-driven interface is imperfect
+and partly because the various pieces are not well enough integrated.
+</P>
+<P>
+Other programs&#173;EMACS [Stal93] is the prime example&#173;offer a high
+degree of integration but with a user interface built around the
+ideas of cursor-addressed terminals that date from the 1970's.
+They are still keyboard-intensive and
+dauntingly complex.
+</P>
+<P>
+The most ambitious attempt to face these issues was the Cedar
+system, developed at Xerox [Swei86].
+It combined a new programming language, compilers,
+window system, even microcode&#173;a complete system&#173;to
+construct a productive, highly
+integrated and interactive environment
+for experienced users of compiled languages.
+Although successful internally, the system was so large
+and so tied to specific hardware that it never fledged.
+</P>
+<P>
+Cedar was, however, the major inspiration for Oberon [Wirt89],
+a system of similar scope but much smaller scale.
+Through careful selection of Cedar's ideas, Oberon shows
+that its lessons can be applied to a small, coherent system
+that can run efficiently on modest hardware.
+In fact, Oberon probably
+errs too far towards simplicity: a single-process system
+with weak networking, it seems an architectural throwback.
+</P>
+<P>
+Acme is a new program,
+a combined window system, editor, and shell,
+that applies
+some of the ideas distilled by Oberon.
+Where Oberon uses objects and modules within a programming language (also called Oberon),
+Acme uses files and commands within an existing operating system (Plan 9).
+Unlike Oberon, Acme does not yet have support for graphical output, just text.
+At least for now, the work on Acme has concentrated on
+producing the smoothest user interface possible for a programmer
+at work.
+</P>
+<P>
+The rest of this paper describes Acme's interface,
+explains how programs can access it,
+compares it to existing systems,
+and finally presents some unusual aspects of its implementation.
+</P>
+<H4>User interface
+</H4>
+<P>
+<br><img src="acme.fig2.14051.gif"><br>
+<br>&#32;<br>
+
+Figure 2.  An Acme window showing a section of code.
+The upper line of text is the tag containing the file name,
+relevant commands, and a scratch area (right of the vertical bar);
+the lower portion of the window is the
+body, or contents, of the file.
+Here the scratch area contains a command for the middle button
+(<TT>mk</TT>)
+and a word to search for with the right button
+(<TT>cxfidalloc</TT>).
+The user has just
+clicked the right button on
+<TT>cxfidalloc</TT>
+and Acme has searched for the word, highlighted it,
+and moved the mouse cursor there.  The file has been modified:
+the center of the layout box is black and the command
+<TT>Put</TT>
+appears in the tag.
+<br>
+<HR>
+Acme windows are arrayed in columns (Figure 1) and are used more
+dynamically than in an environment like X Windows or
+<TT>8&#189;</TT>
+[Sche86, Pike91].
+The system frequently creates them automatically and the user
+can order a new one with a single mouse button click.
+The initial placement of a new window is determined
+automatically, but the user may move an existing window anywhere
+by clicking or dragging a
+<I>layout box</I>
+in the upper left corner of
+the window.
+</P>
+<P>
+Acme windows have two parts: a
+<I>tag</I>
+holding a single line of text,
+above a
+<I>body</I>
+holding zero or more lines (Figure 2).
+The body typically contains an image of a file being edited
+or the editable output of a
+program, analogous to an
+EMACS shell
+window.  The tag contains
+the name of the window
+(usually the name of the associated
+file or directory), some built-in commands, and a scratch area to hold arbitrary text.
+If a window represents a directory, the name in the tag ends with
+a slash and the body contains a list of the names of the files
+in the directory.
+Finally, each non-empty body holds a scroll bar at the left of the text.
+</P>
+<P>
+Each column of windows also has a layout box and a tag.
+The tag has no special meaning, although Acme pre-loads it with a few
+built-in commands.
+There is also a tag across the whole display, also loaded with
+helpful commands and a list of active processes started
+by Acme.
+</P>
+<P>
+Typing with the keyboard and selecting with the left button are as in
+many other systems, including the Macintosh,
+<TT>8&#189;</TT>,
+and Sam.
+The middle and right buttons are used, somewhat like the left button,
+to `sweep' text, but the indicated text is treated in a way
+that depends on the text's location&#173;<I>context</I>&#173;as well as its content.
+This context, based on the directory of the file containing the text,
+is a central component of Acme's style of interaction.
+</P>
+<P>
+Acme has no single notion of `current directory'.
+Instead, every command, file name,
+action, and so on is interpreted or executed in the directory named by the
+tag of the window containing the command.  For example, the string
+<TT>mammals</TT>
+in a window labeled
+<TT>/lib/</TT>
+or
+<TT>/lib/insects</TT>
+will be interpreted as the file name
+<TT>/lib/mammals</TT>
+if such a file exists.
+</P>
+<P>
+Throughout Acme, the middle mouse button is used to execute commands
+and the right mouse button is used to locate and select files and text.
+Even when there are no true files on which to operate&#173;for example
+when editing mail messages&#173;Acme and its applications use
+consistent extensions of these basic functions.
+This idea is as vital to Acme as icons are to the Macintosh.
+</P>
+<P>
+The middle button executes commands: text swept with the button
+pressed is underlined; when the button is released, the underline is
+removed and the indicated text is executed.
+A modest number of commands are recognized as built-ins: words like
+<TT>Cut</TT>,
+<TT>Paste</TT>,
+and
+<TT>New</TT>
+name
+functions performed directly by Acme.
+These words often appear in tags to make them always available,
+but the tags are not menus: any text anywhere in Acme may be a command.
+For example, in the tag or body of any window one may type
+<TT>Cut</TT>,
+select it with the left button, use the middle button to execute it,
+and watch it disappear again.
+</P>
+<P>
+If the middle button indicates a command that is not recognized as a built-in,
+it is executed in the directory
+named by the tag of the window holding the text.
+Also, the file to be executed is searched for first in that directory.
+Standard input is connected to
+<TT>/dev/null</TT>,
+but standard and error outputs are connected to an Acme window,
+created if needed, called
+<I>dir</I><TT>/+Errors</TT> where
+<I>dir</I>
+is the directory of the window.
+(Programs that need interactive input use a different interface, described below.)
+A typical use of this is to type
+<TT>mk</TT>
+(Plan 9's
+<TT>make</TT>)
+in the scratch area in the tag of a C source window, say
+<TT>/sys/src/cmd/sam/regexp.c</TT>,
+and execute it.
+Output, including compiler errors, appears in the window labeled
+<TT>/sys/src/cmd/sam/+Errors</TT>,
+so file names in the output are associated with the windows and directory
+holding the source.
+The
+<TT>mk</TT>
+command remains in the tag, serving as a sort of menu item for the associated
+window.
+</P>
+<P>
+Like the middle button, the right button is used to indicate text by sweeping it out.
+The indicated text is not a command, however, but the argument of a generalized
+search operator.
+If the text, perhaps after appending it to the directory of the window containing it,
+is the name of an existing file, Acme creates a new window to hold the file
+and reads it in.  It then moves the mouse cursor to that window.  If the file is
+already loaded into Acme, the mouse motion happens but no new window is made.
+For example, indicating the string
+<TT>sam.h</TT>
+in
+<DL><DT><DD><TT><PRE>
+#include "sam.h"
+</PRE></TT></DL>
+in a window on the file
+<TT>/sys/src/cmd/sam/regexp.c</TT>
+will open the file
+<TT>/sys/src/cmd/sam/sam.h</TT>.
+</P>
+<P>
+If the file name is followed immediately by a colon and a legal address in
+Sam notation (for example a line number or a regular expression delimited in
+slashes or a comma-separated compound of such addresses), Acme highlights
+the target of that address in the file and places the mouse there.  One may jump to
+line 27 of
+<TT>dat.h</TT>
+by indicating with the right button the text
+<TT>dat.h:27</TT>.
+If the file is not already open, Acme loads it.
+If the file name is null, for example if the indicated string is
+<TT>:/^main/</TT>,
+the file is assumed to be that of the window containing the string.
+Such strings, when typed and evaluated in the tag of a window, amount to
+context searches.
+</P>
+<P>
+If the indicated text is not the name of an existing file, it is taken to be literal
+text and is searched for in the body of the window containing the text, highlighting
+the result as if it were the result of a context search.
+</P>
+<P>
+For the rare occasion when a file name
+<I>is</I>
+just text to search for, it can be selected with the left button and used as the
+argument to a built-in
+<TT>Look</TT>
+command that always searches for literal text.
+</P>
+<H4>Nuances and heuristics
+</H4>
+<P>
+A user interface should not only provide the necessary functions, it should also
+<I>feel</I>
+right.
+In fact, it should almost not be felt at all; when one notices a
+user interface, one is distracted from the job at hand [Pike88].
+To approach this invisibility, some of Acme's properties and features
+are there just to make the others easy to use.
+Many are based on a fundamental principle of good design:
+let the machine do the work.
+</P>
+<P>
+Acme tries to avoid needless clicking and typing.
+There is no `click-to-type', eliminating a button click.
+There are no pop-up or pull-down menus, eliminating the mouse action needed to
+make a menu appear.
+The overall design is intended to make text on the screen useful without
+copying or retyping; the ways in which this happens involve
+the combination of many aspects of the interface.
+</P>
+<P>
+Acme tiles its windows and places them automatically
+to avoid asking the user to place and arrange them.
+For this policy to succeed, the automatic placement must behave well enough
+that the user is usually content with the location of a new window.
+The system will never get it right all the time, but in practice most
+windows are used at least for a while where Acme first places them.
+There have been several complete rewrites of the
+heuristics for placing a new window,
+and with each rewrite the system became
+noticeably more comfortable.  The rules are as follows, although
+they are still subject to improvement.
+The window appears in the `active' column, that most recently used for typing or
+selecting.
+Executing and searching do not affect the choice of active column,
+so windows of commands and such do not draw new windows towards them,
+but rather let them form near the targets of their actions.
+Output (error) windows always appear towards the right, away from
+edited text, which is typically kept towards the left.
+Within the column, several competing desires are balanced to decide where
+and how large the window should be:
+large blank spaces should be consumed;
+existing text should remain visible;
+existing large windows should be divided before small ones;
+and the window should appear near the one containing the action that caused
+its creation.
+</P>
+<P>
+Acme binds some actions to chords of mouse buttons.
+These include
+<TT>Cut</TT>
+and
+<TT>Paste</TT>
+so these common operations can be done without
+moving the mouse.
+Another is a way to apply a command in one window to text (often a file name)
+in another, avoiding the actions needed to assemble the command textually.
+</P>
+<P>
+Another way Acme avoids the need to move the mouse is instead to move the cursor
+to where it is likely to be used next.  When a new window is made, Acme
+moves the cursor to the new window; in fact, to the selected text in that window.
+When the user deletes a newly made window, the cursor is
+returned to the point it was before the window was made,
+reducing the irritation of windows that pop up to report annoying errors.
+</P>
+<P>
+When a window is moved, Acme moves the cursor to the layout box in
+its new place, to permit further adjustment without moving the mouse.
+For example, when a click of the left mouse button on the layout box grows
+the window, the cursor moves to the new location of the box so repeated clicks,
+without moving the mouse, continue to grow it.
+</P>
+<P>
+Another form of assistance the system can offer is to supply precision in
+pointing the mouse.  The best-known form of this is `double-clicking' to
+select a word rather than carefully sweeping out the entire word.
+Acme provides this feature, using context to decide whether to select
+a word, line, quoted string, parenthesized expression, and so on.
+But Acme takes the idea much further by applying it to execution
+and searching.
+A
+<I>single</I>
+click, that is, a null selection, with either the middle or right buttons,
+is expanded automatically to indicate the appropriate text containing
+the click.  What is appropriate depends on the context.
+</P>
+<P>
+For example, to execute a single-word command
+such as
+<TT>Cut</TT>,
+it is not necessary to sweep the entire word; just clicking the button once with
+the mouse pointing at the word is sufficient.  `Word'
+means the largest string of likely file name characters surrounding the location
+of the click: click on a file name, run that program.
+On the right button, the rules are more complicated because
+the target of the click might be a file name, file name with address,
+or just plain text.  Acme examines the text near the click to find
+a likely file name;
+if it finds one, it checks that it names an existing file (in the directory named in the tag, if the name is relative)
+and if so, takes that as the result, after extending it with any address
+that may be present.  If there is no file with that name, Acme
+just takes the largest alphanumeric string under the click.
+The effect is a natural overloading of the button to refer to plain text as
+well as file names.
+</P>
+<P>
+First, though, if the click occurs over the left-button-selected text in the window,
+that text is taken to be what is selected.
+This makes it easy to skip through the occurrences of a string in a file: just click
+the right button
+on some occurrence of the text in the window (perhaps after typing it in the tag)
+and click once for each subsequent occurrence.  It isn't even necessary to move
+the mouse between clicks; Acme does that.
+To turn a complicated command into a sort of menu item, select it:
+thereafter, clicking the middle button on it will execute the full command.
+</P>
+<P>
+As an extra feature, Acme recognizes file names in angle brackets
+<TT><></TT>
+as names of files in standard directories of include files,
+making it possible for instance to look at
+<TT><stdio.h></TT>
+with a single click.
+</P>
+<P>
+Here's an example to demonstrate how the actions and defaults work together.
+Assume
+<TT>/sys/src/cmd/sam/regexp.c</TT>
+is
+open and has been edited.  We write it (execute
+<TT>Put</TT>
+in the tag; once the file is written, Acme removes the word from the tag)
+and type
+<TT>mk</TT>
+in the tag.  We execute
+<TT>mk</TT>
+and get some errors, which appear in a new window labeled
+<TT>/sys/src/cmd/sam/+Errors</TT>.
+The cursor moves automatically to that window.
+Say the error is
+<DL><DT><DD><TT><PRE>
+main.c:112: incompatible types on assignment to `pattern'
+</PRE></TT></DL>
+We move the mouse slightly and click the right button
+at the left of the error message; Acme
+makes a new window, reads
+<TT>/sys/src/cmd/main.c</TT>
+into it, selects line 112
+and places the mouse there, right on the offending line.
+</P>
+<H4>Coupling to existing programs
+</H4>
+<P>
+Acme's syntax for file names and addresses makes it easy for other programs
+to connect automatically to Acme's capabilities.  For example, the output of
+<DL><DT><DD><TT><PRE>
+grep -n variable *.[ch]
+</PRE></TT></DL>
+can be used to help Acme step through the occurrences of a variable in a program;
+every line of output is potentially a command to open a file.
+The file names need not be absolute, either: the output
+appears in a window labeled with the directory in which
+<TT>grep</TT>
+was run, from which Acme can derive the full path names.
+</P>
+<P>
+When necessary, we have changed the output of some programs,
+such as compiler error messages, to match
+Acme's syntax.
+Some might argue that it shouldn't be necessary to change old programs,
+but sometimes programs need to be updated when systems change,
+and consistent output benefits people as well as programs.
+A historical example is the retrofitting of standard error output to the
+early Unix programs when pipes were invented.
+</P>
+<P>
+Another change was to record full path names in
+the symbol table of executables, so line numbers reported by the debugger
+are absolute names that may be used directly by Acme; it's not necessary
+to run the debugger in the source directory.  (This aids debugging
+even without Acme.)
+</P>
+<P>
+A related change was to add lines of the form
+<DL><DT><DD><TT><PRE>
+#pragma src "/sys/src/libregexp"
+</PRE></TT></DL>
+to header files; coupled with Acme's ability to locate a header file,
+this provides a fast, keyboardless way to get the source associated with a library.
+</P>
+<P>
+Finally, Acme directs the standard output of programs it runs to
+windows labeled by the directory in which the program is run.
+Acme's splitting of the
+output into directory-labeled windows is a small feature that has a major effect:
+local file names printed by programs can be interpreted directly by Acme.
+By indirectly coupling the output of programs to the input,
+it also simplifies the management of software that occupies multiple
+directories.
+</P>
+<H4>Coupling to new programs
+</H4>
+<P>
+Like many Plan 9 programs,
+Acme offers a programmable interface to
+other programs by acting as a file server.
+The best example of such a file server is the window system
+<TT>8&#189;</TT>
+[Pike91],
+which exports files with names such as
+<TT>screen</TT>,
+<TT>cons</TT>,
+and
+<TT>mouse</TT>
+through which applications may access the I/O capabilities of the windows.
+<TT>8&#189;</TT>
+provides a
+<I>distinct</I>
+set of files for each window and builds a private file name space
+for the clients running `in' each window;
+clients in separate windows see distinct files with the same names
+(for example
+<TT>/dev/mouse</TT>).
+Acme, like the process file system [PPTTW93], instead associates each
+window with a directory of files; the files of each window are visible
+to any application.
+This difference reflects a difference in how the systems are used:
+<TT>8&#189;</TT>
+tells a client what keyboard and mouse activity has happened in its window;
+Acme tells a client what changes that activity wrought on any window it asks about.
+Putting it another way,
+<TT>8&#189;</TT>
+enables the construction of interactive applications;
+Acme provides the interaction for applications.
+</P>
+<P>
+The root of
+Acme's file system is mounted using Plan 9 operations on the directory
+<TT>/mnt/acme</TT>.
+In
+that root directory appears a directory for each window, numbered with the window's identifier,
+analogous to a process identifier, for example
+<TT>/mnt/acme/27</TT>.
+The window's directory
+contains 6 files:
+<TT>/mnt/acme/27/addr</TT>,
+<TT>body</TT>,
+<TT>ctl</TT>,
+<TT>data</TT>,
+<TT>event</TT>,
+and
+<TT>tag</TT>.
+The
+<TT>body</TT>
+and
+<TT>tag</TT>
+files contain the text of the respective parts of the window; they may be
+read to recover the contents.  Data written to these files is appended to the text;
+<TT>seeks</TT>
+are ignored.
+The
+<TT>addr</TT>
+and
+<TT>data</TT>
+files provide random access to the contents of the body.
+The
+<TT>addr</TT>
+file is written to set a character position within the body; the
+<TT>data</TT>
+file may then be read to recover the contents at that position,
+or written to change them.
+(The tag is assumed
+small and special-purpose enough not to need special treatment.
+Also,
+<TT>addr</TT>
+indexes by character position, which is not the same as byte offset
+in Plan 9's multi-byte character set [Pike93]).
+The format accepted by the
+<TT>addr</TT>
+file is exactly the syntax of addresses within the user interface,
+permitting regular expressions, line numbers, and compound addresses
+to be specified.  For example, to replace the contents of lines 3 through 7,
+write the text
+<DL><DT><DD><TT><PRE>
+3,7
+</PRE></TT></DL>
+to the
+<TT>addr</TT>
+file, then write the replacement text to the
+<TT>data</TT>
+file.  A zero-length write deletes the addressed text; further writes extend the replacement.
+</P>
+<P>
+The control file,
+<TT>ctl</TT>,
+may be written with commands to effect actions on the window; for example
+the command
+<DL><DT><DD><TT><PRE>
+name /adm/users
+</PRE></TT></DL>
+sets the name in the tag of the window to
+<TT>/adm/users</TT>.
+Other commands allow deleting the window, writing it to a file, and so on.
+Reading the
+<TT>ctl</TT>
+file recovers a fixed-format string containing 5 textual numbers&#173;the window
+identifier, the number of characters in the tag, the number in the body,
+and some status information&#173;followed by the text of the tag, up to a newline.
+</P>
+<P>
+The last file,
+<TT>event</TT>,
+is the most unusual.
+A program reading a window's
+<TT>event</TT>
+file is notified of all changes to the text of the window, and
+is asked to interpret all middle- and right-button actions.
+The data passed to the program is fixed-format and reports
+the source of the action (keyboard, mouse, external program, etc.),
+its location (what was pointed at or modified), and its nature (change,
+search, execution, etc.).
+This message, for example,
+<DL><DT><DD><TT><PRE>
+MI15 19 0 4 time
+</PRE></TT></DL>
+reports that actions of the mouse
+(<TT>M</TT>)
+inserted in the body (capital
+<TT>I</TT>)
+the 4 characters of
+<TT>time</TT>
+at character positions 15 through 19; the zero is a flag word.
+Programs may apply their own interpretations of searching and
+execution, or may simply reflect the events back to Acme,
+by writing them back to the
+<TT>event</TT>
+file, to have the default interpretation applied.
+Some examples of these ideas in action are presented below.
+</P>
+<P>
+Notice that changes to the window are reported
+after the fact; the program is told about them but is not required to act
+on them.  Compare this to a more traditional interface in which a program
+is told, for example, that a character has been typed on the keyboard and
+must then display and interpret it.
+Acme's style stems from the basic model of the system, in which any
+number of agents&#173;the keyboard, mouse, external programs
+writing to
+<TT>data</TT>
+or
+<TT>body</TT>,
+and so on&#173;may
+change the contents of a window.
+The style is efficient: many programs are content
+to have Acme do most of the work and act only when the editing is completed.
+An example is the Acme mail program, which can ignore the changes
+made to a message being composed
+and just read its body when asked to send it.
+A disadvantage is that some traditional ways of working are impossible.
+For example, there is no way `to turn off echo': characters appear on the
+screen and are read from there; no agent or buffer stands between
+the keyboard and the display.
+</P>
+<P>
+There are a couple of other files made available by Acme in its root directory
+rather than in the directory of each window.
+The text file
+<TT>/mnt/acme/index</TT>
+holds a list of all window names and numerical identifiers,
+somewhat analogous to the output of the
+<TT>ps</TT>
+command for processes.
+The most important, though, is
+<TT>/mnt/acme/new</TT>,
+a directory that makes new windows, similar to the
+<TT>clone</TT>
+directory in the Plan 9 network devices [Pres93].
+The act of opening any file in
+<TT>new</TT>
+creates a new Acme window; thus the shell command
+<DL><DT><DD><TT><PRE>
+grep -n var *.c &#62; /mnt/acme/new/body
+</PRE></TT></DL>
+places its output in the body of a fresh window.
+More sophisticated applications may open
+<TT>new/ctl</TT>,
+read it to discover the new window's identifier, and then
+open the window's other files in the numbered directory.
+</P>
+<H4>Acme-specific programs
+</H4>
+<P>
+Although Acme is in part an attempt to move beyond typescripts,
+they will probably always have utility.
+The first program written for Acme was therefore one
+to run a shell or other traditional interactive application
+in a window, the Acme analog of
+<TT>xterm</TT>.
+This program,
+<TT>win</TT>,
+has a simple structure:
+it acts as a two-way intermediary between Acme and the shell,
+cross-connecting the standard input and output of the shell to the
+text of the window.
+The style of interaction is modeled after
+<TT>mux</TT>
+[Pike88]: standard output is added to the window at the
+<I>output point;</I>
+text typed after the output point
+is made available on standard input when a newline is typed.
+After either of these actions, the output point is advanced.
+This is different from the working of a regular terminal,
+permitting cut-and-paste editing of an input line until the newline is typed.
+Arbitrary editing may be done to any text in the window.
+The implementation of
+<TT>win</TT>,
+using the
+<TT>event</TT>,
+<TT>addr</TT>,
+and
+<TT>data</TT>
+files, is straightforward.
+<TT>Win</TT>
+needs no code for handling the keyboard and mouse; it just monitors the
+contents of the window.  Nonetheless, it allows Acme's full editing to be
+applied to shell commands.
+The division of labor between
+<TT>win</TT>
+and
+<TT>Acme</TT>
+contrasted with
+<TT>xterm</TT>
+and the X server demonstrates how much work Acme handles automatically.
+<TT>Win</TT>
+is implemented by a single source file 560 lines long and has no graphics code.
+</P>
+<P>
+<TT>Win</TT>
+uses the middle and right buttons to connect itself in a consistent way
+with the rest of Acme.
+The middle button still executes commands, but in a style more suited
+to typescripts.  Text selected with the middle button is treated as if
+it had been typed after the output point, much as a similar feature in
+<TT>xterm</TT>
+or
+<TT>8&#189;</TT>,
+and therefore causes it to be `executed' by the application running in the window.
+Right button actions are reflected back to Acme but refer to the appropriate
+files because
+<TT>win</TT>
+places the name of the current directory in the tag of the window.
+If the shell is running, a simple shell function replacing the
+<TT>cd</TT>
+command can maintain the tag as the shell navigates the file system.
+This means, for example, that a right button click on a file mentioned in an
+<TT>ls</TT>
+listing opens the file within Acme.
+</P>
+<P>
+Another Acme-specific program is a mail reader that begins by presenting,
+in a window, a listing of the messages in the user's mailbox, one per line.
+Here the middle and right button actions are modified to refer to
+mail commands
+and messages, but the change feels natural.
+Clicking the right button on a line creates a new window and displays the
+message there, or, if it's already displayed, moves the mouse to that window.
+The metaphor is that the mailbox is a directory whose constituent files are messages.
+The mail program also places some relevant commands in the tag lines of
+the windows; for example, executing the word
+<TT>Reply</TT>
+in a message's tag creates a new window
+in which to compose a message to the sender of the original;
+<TT>Post</TT>
+then dispatches it.
+In such windows, the addressee is just a list of names
+on the first line of the body, which may be edited to add or change recipients.
+The program also monitors the mailbox, updating the `directory' as new messages
+arrive.
+</P>
+<P>
+The mail program is as simple as it sounds; all the work of interaction,
+editing, and management of the display is done by Acme.
+The only
+difficult sections of the 1200
+lines of code concern honoring the external protocols for managing
+the mailbox and connecting to
+<TT>sendmail</TT>.
+</P>
+<P>
+One of the things Acme does not provide directly is a facility like
+Sam's command language to enable actions such as global substitution;
+within Acme, all editing is done manually.
+It is easy, though, to write external programs for such tasks.
+In this, Acme comes closer to the original intent of Oberon:
+a directory,
+<TT>/acme/edit</TT>,
+contains a set of tools for repetitive editing and a template
+or `guide' file that gives examples
+of its use.  
+Acme's editing guide,
+<TT>/acme/edit/guide</TT>,
+looks like this:
+<DL><DT><DD><TT><PRE>
+e file | x '/regexp/' | c 'replacement'
+e file:'0,$' | x '/.*word.*\n/' | p -n
+e file | pipe command args ...
+</PRE></TT></DL>
+The syntax is reminiscent of Sam's command language, but here the individual
+one-letter commands are all stand-alone programs connected by pipes.
+Passed along the pipes are addresses, analogous to structural expressions
+in Sam terminology.
+The
+<TT>e</TT>
+command, unlike that of Sam, starts the process by generating the address
+(default dot, the highlighted selection) in the named files.
+The other commands are as in Sam:
+<TT>p</TT>
+prints the addressed text on standard output (the
+<TT>-n</TT>
+option is analogous to that of
+<TT>grep</TT>,
+useful in combination with the right mouse button);
+<TT>x</TT>
+matches a regular expression to the addressed (incoming) text,
+subdividing the text;
+<TT>c</TT>
+replaces the text; and so on.  Thus, global substitution throughout a file,
+which would be expressed in Sam as
+<DL><DT><DD><TT><PRE>
+0,$ x/regexp/ c/replacement/
+</PRE></TT></DL>
+in Acme's editor becomes
+<DL><DT><DD><TT><PRE>
+e 'file:0,$' | x '/regexp/' | c 'replacement'
+</PRE></TT></DL>
+</P>
+<P>
+To use the Acme editing commands, open
+<TT>/acme/edit/guide</TT>,
+use the mouse and keyboard to edit one of the commands to the right form,
+and execute it with the middle button.
+Acme's context rules find the appropriate binaries in
+<TT>/acme/edit</TT>
+rather than
+<TT>/bin</TT>;
+the effect is to turn
+<TT>/acme/edit</TT>
+into a toolbox containing tools and instructions (the guide file) for their use.
+In fact, the source for these tools is also there, in the directory
+<TT>/acme/edit/src</TT>.
+This setup allows some control of the file name space for binary programs;
+not only does it group related programs, it permits the use of common
+names for uncommon jobs.  For example, the single-letter names would
+be unwise in a directory in everyone's search path; here they are only
+visible when running editing commands.
+</P>
+<P>
+In Oberon,
+such a collection would be called a
+<I>tool</I>
+and would consist
+of a set of entry points in a module and a menu-like piece of text containing
+representative commands that may be edited to suit and executed.
+There is, in fact, a tool called
+<TT>Edit</TT>
+in Oberon.
+To provide related functionality,
+Acme exploits the directory and file structure of the underlying
+system, rather than the module structure of the language;
+this fits well with Plan 9's
+file-oriented philosophy.
+Such tools are central to the working of Oberon but they are
+less used in Acme, at least so far.
+The main reason is probably that Acme's program interface permits
+an external program to remain executing in the background, providing
+its own commands as needed (for example, the
+<TT>Reply</TT>
+command in the mail program); Oberon uses tools to
+implement such services because its must invoke
+a fresh program for each command.
+Also,
+Acme's better integration allows more
+basic functions to be handled internally; the right mouse button
+covers a lot of the basic utility of the editing tools in Oberon.
+Nonetheless, as more applications are written for Acme,
+many are sure to take this Oberon tool-like form.
+</P>
+<H4>Comparison with other systems
+</H4>
+<P>
+Acme's immediate ancestor is Help [Pike92], an experimental system written
+a few years ago as a first try at exploring some of Oberon's ideas
+in an existing operating system.
+Besides much better engineering, Acme's advances over Help
+include the actions of the right button (Help had nothing comparable),
+the ability to connect long-running programs to the user interface
+(Help had no analog of the
+<TT>event</TT>
+file),
+and the small but important change to split command output into
+windows labeled with the directory in which the commands run.
+</P>
+<P>
+Most of Acme's style, however, derives from the user interface and window
+system of Oberon [Wirt89, Reis91].
+Oberon includes a programming language and operating system,
+which Acme instead borrows from an existing system, Plan 9.
+When I first saw Oberon, in 1988, I was struck by the
+simplicity of its user interface, particularly its lack of menus
+and its elegant use of multiple mouse buttons.
+The system seemed restrictive, though&#173;single process,
+single language, no networking, event-driven programming&#173;and
+failed to follow through on some of its own ideas.
+For example, the middle mouse button had to be pointed accurately and
+the right button was essentially unused.
+Acme does follow through:
+to the basic idea planted by Oberon, it adds
+the ability to run on different operating systems and hardware,
+connection to existing applications including
+interactive ones such as shells and debuggers,
+support for multiple processes,
+the right mouse button's features,
+the default actions and context-dependent properties
+of execution and searching,
+and a host of little touches such as moving the mouse cursor that make the system 
+more pleasant.
+At the moment, though, Oberon does have one distinct advantage: it incorporates
+graphical programs well into its model, an issue Acme has not yet faced.
+</P>
+<P>
+Acme shares with the Macintosh a desire to use the mouse well and it is
+worth comparing the results.
+The mouse on the Macintosh has a single button, so menus are essential
+and the mouse must frequently move a long way
+to reach the appropriate function.
+An indication that this style has trouble is that applications provide
+keyboard sequences to invoke menu selections and users often prefer them.
+A deeper comparison is that the Macintosh uses pictures where Acme uses text.
+In contrast to pictures, text can be edited quickly, created on demand,
+and fine-tuned to the job at hand; consider adding an option to a command.
+It is also self-referential; Acme doesn't need menus because any text can be
+in effect a menu item.
+The result is that, although a Macintosh screen is certainly prettier and probably
+more attractive, especially to beginners, an Acme screen is more dynamic
+and expressive, at least for programmers and experienced users.
+</P>
+<P>
+For its role in the overall system,
+Acme most resembles EMACS [Stal93].
+It is tricky to compare Acme to EMACS, though, because there are
+many versions of EMACS and, since it is fully programmable, EMACS
+can in principle do anything Acme does.
+Also, Acme is much younger and therefore has not
+had the time to acquire as many features.
+The issue therefore is less what the systems can be programmed to do than
+how they are used.
+The EMACS versions that come closest to Acme's style are those that
+have been extended to provide a programming environment, usually
+for a language such as LISP [Alle92, Lucid92].
+For richness of the existing interface, these EMACS versions are certainly superior to Acme.
+On the other hand, Acme's interface works equally well already for a variety
+of languages; for example, one of its most enthusiastic users works almost
+exclusively in Standard ML, a language nothing like C.
+</P>
+<P>
+Where Acme excels is in the smoothness of its interface.
+Until recently, EMACS did not support the mouse especially well,
+and even with the latest version providing features such as `extents'
+that can be programmed to behave much like Acme commands,
+many users don't bother to upgrade.
+Moreover, in the versions that provide extents, 
+most EMACS packages don't take advantage of them.
+</P>
+<P>
+The most important distinction is just that
+EMACS is fundamentally keyboard-based, while
+Acme is mouse-based.
+</P>
+<P>
+People who try Acme find it hard to go back to their previous environment.
+Acme automates so much that to return to a traditional interface
+is to draw attention to the extra work it requires.
+</P>
+<H4>Concurrency in the implementation
+</H4>
+<P>
+Acme is about 8,000 lines of code in Alef, a concurrent object-oriented language syntactically similar to C [Alef].
+Acme's structure is a set of communicating
+processes in a single address space.
+One subset of the processes drives the display and user interface,
+maintaining the windows; other processes forward mouse and keyboard
+activity and implement the file server interface for external programs.
+The language and design worked out well;
+as explained elsewhere [Pike89, Gans93, Reppy93],
+user interfaces built with concurrent systems
+can avoid the clumsy
+top-level event loop typical of traditional interactive systems.
+</P>
+<P>
+An example of the benefits of the multi-process style
+is the management of the state of open
+files held by clients of the file system interface.
+The problem is that some I/O requests,
+such as reading the
+<TT>event</TT>
+file, may block if no data is available, and the server must
+maintain the state of (possibly many) requests until data appears.
+For example,
+in
+<TT>8&#189;</TT>,
+a single-process window system written in C, pending requests were queued in
+a data structure associated with each window.
+After activity in the window that might complete pending I/O,
+the data structure was scanned for requests that could now finish.
+This structure did not fit well with the rest of the program and, worse,
+required meticulous effort
+to guarantee correct behavior under all conditions
+(consider raw mode, reads of partial lines, deleting a window,
+multibyte characters, etc.).
+</P>
+<P>
+Acme instead creates a new dedicated process
+for each I/O request.
+This process coordinates with the rest of the system
+using Alef's synchronous communication;
+its state implicitly encodes the state of
+the I/O request and obviates the need for queuing.
+The passage of the request through Acme proceeds as follows.
+</P>
+<P>
+Acme contains a file server process, F, that executes a
+<TT>read</TT>
+system call to receive a Plan 9 file protocol (9P) message from the client [AT&amp;T92].
+The client blocks until Acme answers the request.
+F communicates with an allocation process, M,
+to acquire an object of type
+<TT>Xfid</TT>
+(`executing fid'; fid is a 9P term)
+to hold the request.
+M sits in a loop (reproduced in Figure 2) waiting for either a request for
+a new
+<TT>Xfid</TT>
+or notification that an existing one has finished its task.
+When an
+<TT>Xfid</TT>
+is created, an associated process, X,
+is also made.
+M queues idle
+<TT>Xfids</TT>,
+allocating new ones only when the list is empty.
+Thus, there is always a pool of
+<TT>Xfids</TT>,
+some executing, some idle.
+</P>
+<P>
+The
+<TT>Xfid</TT>
+object contains a channel,
+<TT>Xfid.c</TT>,
+for communication with its process;
+the unpacked message; and some associated functions,
+mostly corresponding to 9P messages such as
+<TT>Xfid.write</TT>
+to handle a 9P write request.
+</P>
+<P>
+The file server process F parses the message to see its nature&#173;open,
+close, read, write, etc.  Many messages, such as directory
+lookups, can be handled immediately; these are responded to directly
+and efficiently
+by F without invoking the
+<TT>Xfid</TT>,
+which is therefore maintained until the next message.
+When a message, such as a write to the display, requires the attention
+of the main display process and interlocked access to its data structures,
+F enables X
+by sending a function pointer on
+<TT>Xfid.c</TT>.
+For example, if the message is a write, F executes
+<DL><DT><DD><TT><PRE>
+x-&#62;c &#60;-= Xfid.write;
+</PRE></TT></DL>
+which sends
+the address of
+<TT>Xfid.write</TT>
+on
+<TT>Xfid.c</TT>,
+waking up X.
+</P>
+<P>
+The
+<TT>Xfid</TT>
+process, X, executes a simple loop:
+<DL><DT><DD><TT><PRE>
+void
+Xfid.ctl(Xfid *x)
+{
+    for(;;){
+        (*&#60;-x-&#62;c)(x);      /* receive and execute message */
+        bflush();          /* synchronize bitmap display */
+        cxfidfree &#60;-= x;   /* return to free list */
+    }
+}
+</PRE></TT></DL>
+Thus X
+will wake up with the address of a function to call (here
+<TT>Xfid.write</TT>)
+and execute it; once that completes, it returns itself to the pool of
+free processes by sending its address back to the allocator.
+</P>
+<P>
+Although this sequence may seem complicated, it is just a few lines
+of code and is in fact far simpler
+than the management of the I/O queues in
+<TT>8&#189;</TT>.
+The hard work of synchronization is done by the Alef run time system.
+Moreover, the code worked the first time, which cannot be said for the code in
+<TT>8&#189;</TT>.
+</P>
+<H4>Undo
+</H4>
+<P>
+Acme provides a general undo facility like that of Sam, permitting
+textual changes to be unwound arbitrarily.
+The implementation is superior to Sam's, though,
+with much higher performance and the ability to `redo' changes.
+</P>
+<P>
+Sam uses
+a multi-pass algorithm that builds
+a transcript of changes to be made simultaneously
+and then executes them atomically.
+This was thought necessary because the elements of a repetitive
+command such as a global substitution should all be applied to the same
+initial file and implemented simultaneously; forming the complete
+transcript before executing any of the changes avoids the
+cumbersome management of addresses in a changing file.
+Acme, however, doesn't have this problem; global substitution
+is controlled externally and may be made incrementally by exploiting
+an observation: if the changes are sorted in address order and
+executed in reverse, changes will not invalidate the addresses of
+pending changes.
+</P>
+<P>
+Acme therefore avoids the initial transcript.  Instead, changes are applied
+directly to the file, with an undo transcript recorded in a separate list.
+For example, when text is added to a window, it is added directly and a record
+of what to delete to restore the state is appended to the undo list.
+Each undo action and the file are marked with a sequence number;
+actions with the same sequence number are considered a unit
+to be undone together.
+The invariant state of the structure
+is that the last action in the undo list applies to the current state of the file,
+even if that action is one of a related set from, for example, a global substitute.
+(In Sam, a related set of actions needed to be undone simultaneously.)
+To undo an action, pop the last item on the undo list, apply it to the file,
+revert it, and append it to a second, redo list.
+To redo an action, do the identical operation with the lists interchanged.
+The expensive operations occur
+only when actually undoing; in normal editing the overhead is minor.
+For example, Acme reads files about seven times faster than Sam, partly
+because of this improvement and partly because of a cleaner implementation.
+</P>
+<P>
+Acme uses a temporary file to hold the text, keeping in memory only the
+visible portion, and therefore can edit large files comfortably
+even on small-memory machines such as laptops.
+</P>
+<H4>Future
+</H4>
+<P>
+Acme is still under development.
+Some things are simply missing.
+For example, Acme should support non-textual graphics, but this is being
+deferred until it can be done using a new graphics model being developed
+for Plan 9.  Also, it is undecided how Acme's style of interaction should best be
+extended to graphical applications.
+On a smaller scale, although the system feels smooth and comfortable,
+work continues to tune the heuristics and
+try new ideas for the user interface.
+</P>
+<P>
+There need to be more programs that use Acme.  Browsers for
+Usenet and AP News articles, the Oxford English Dictionary, and other
+such text sources exist, but more imaginative applications will
+be necessary to prove that Acme's approach is viable.
+One that has recently been started is an interface to the debugger Acid [Wint94],
+although it is still
+unclear what form it will ultimately take.
+</P>
+<P>
+Acme shows that it is possible to make a user interface a stand-alone component
+of an interactive environment.  By absorbing more of the interactive
+functionality than a simple window system, Acme off-loads much of the
+computation from its applications, which helps keep them small and
+consistent in their interface.  Acme can afford to dedicate
+considerable effort to making that interface as good as possible; the result
+will benefit the entire system.
+</P>
+<P>
+Acme is complete and useful enough to attract users.
+Its comfortable user interface,
+the ease with which it handles multiple tasks and
+programs in multiple directories,
+and its high level of integration
+make it addictive.
+Perhaps most telling,
+Acme shows that typescripts may not be the most
+productive interface to a time-sharing system.
+</P>
+<H4>Acknowledgements
+</H4>
+<P>
+Howard Trickey, Acme's first user, suffered buggy versions gracefully and made
+many helpful suggestions.  Chris Fraser provided the necessary insight for the Acme editing
+commands.
+</P>
+<H4>References
+</H4>
+<br>&#32;<br>
+[Alef] P. Winterbottom,
+``Alef Language Reference Manual'',
+Plan 9 Programmer's Manual,
+AT&amp;T Bell Laboratories,
+Murray Hill, NJ,
+1992;
+revised in this volume.
+<br>
+[Alle92]
+Allegro Common Lisp user Guide, Vol 2, 
+Chapter 14, "The Emacs-Lisp Interface". 
+March 1992.
+<br>
+[AT&amp;T92] Plan 9 Programmer's manual, Murray Hill, New Jersey, 1992.
+<br>
+[Far89] Far too many people, XTERM(1), Massachusetts Institute of Technology, 1989.
+<br>
+[Gans93] Emden R. Gansner and John H. Reppy,  ``A Multi-threaded Higher-order User Interface Toolkit'', in
+Software Trends, Volume 1,
+User Interface Software,
+Bass and Dewan (Eds.),
+John Wiley &amp; Sons 1993,
+pp. 61-80.
+<br>
+[Lucid92] Richard Stallman and Lucid, Inc.,
+Lucid GNU EMACS Manual,
+March 1992.
+<br>
+[Pike87] Rob Pike, ``The Text Editor <TT>sam</TT>'', Softw. - Pract. and Exp., Nov 1987, Vol 17 #11, pp. 813-845; reprinted in this volume.
+<br>
+[Pike88] Rob Pike, ``Window Systems Should Be Transparent'', Comp. Sys., Summer 1988, Vol 1 #3, pp. 279-296.
+<br>
+[Pike89] Rob Pike, ``A Concurrent Window System'', Comp. Sys., Spring 1989, Vol 2 #2, pp. 133-153.
+<br>
+[PPTTW93] Rob Pike, Dave Presotto, Ken Thompson, Howard Trickey, and Phil Winterbottom, ``The Use of Name Spaces in Plan 9'',
+Op. Sys. Rev.,  Vol. 27, No. 2, April 1993, pp. 72-76,
+reprinted in this volume.
+<br>
+[Pike91] Rob Pike, ``8&#189;, the Plan 9 Window System'', USENIX Summer Conf. Proc., Nashville, June, 1991, pp. 257-265,
+reprinted in this volume.
+<br>
+[Pike92] Rob Pike, ``A Minimalist Global User Interface'', Graphics Interface '92 Proc., Vancouver, 1992, pp. 282-293.  An earlier version appeared under the same title in USENIX Summer Conf. Proc., Nashville, June, 1991, pp. 267-279.
+<br>
+[Pike93] Rob Pike and Ken Thompson, ``Hello World or &#191;ALPHA&#191;&#191;MU&#191;&#191;ALPHA &#191;&#191;&#191;MUEPSILON or
+&#191;&#191;&#191;&#191;&#191; &#191;&#191;'', USENIX Winter Conf. Proc., San Diego, 1993, pp. 43-50,
+reprinted in this volume.
+<br>
+[Pres93] Dave Presotto and Phil Winterbottom, ``The Organization of Networks in Plan 9'', Proc. Usenix Winter 1993, pp. 271-287, San Diego, CA,
+reprinted in this volume.
+<br>
+[Reis91] Martin Reiser, <I>The Oberon System,</I> Addison Wesley, New York, 1991.
+<br>
+[Reppy93] John H. Reppy,
+``CML: A higher-order concurrent language'', Proc. SIGPLAN'91 Conf. on Programming, Lang. Design and Impl., June, 1991, pp. 293-305.
+<br>
+[Sche86] Robert W. Scheifler and Jim Gettys,
+``The X Window System'',
+ACM Trans. on Graph., Vol 5 #2, pp. 79-109.
+<br>
+[Stal93] Richard Stallman,
+Gnu Emacs Manual, 9th edition, Emacs version 19.19,
+MIT.
+<br>
+[Swei86] Daniel Sweinhart, Polle Zellweger, Richard Beach, and Robert Hagmann,
+``A Structural View of the Cedar Programming Environment'',
+ACM Trans. Prog. Lang. and Sys., Vol. 8, No. 4, pp. 419-490, Oct. 1986.
+<br>
+[Wint94], Philip Winterbottom, ``Acid: A Debugger based on a Language'', USENIX Winter Conf. Proc., San Francisco, CA, 1993,
+reprinted in this volume.
+<br>
+[Wirt89] N. Wirth and J. Gutknecht, ``The Oberon System'', Softw. - Prac. and Exp., Sep 1989, Vol 19 #9, pp 857-894.
+
+<br>&#32;<br>
+<A href=http://www.lucent.com/copyright.html>
+Copyright</A> &#169; 2000 Lucent Technologies Inc.  All rights reserved.
+</body></html>

BIN
sys/doc/acme/acme.pdf


+ 440 - 2018
sys/doc/auth.html

@@ -1,162 +1,39 @@
-<html>
-<title>
--
-</title>
-<body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#330088" ALINK="#FF0044">
-<H1>Security in Plan 9
-</H1>
-<DL><DD><I>Russ Cox, MIT LCS<br>
-<br>
+<HEAD>
+<TITLE>Security in Plan 9</TITLE>
+<META content="text/html; charset=utf-8" http-equiv=Content-Type>
+</HEAD>
+<BODY BGCOLOR=WHITE>
+<h1>Security in Plan 9</h1>
+<EM>Russ Cox, MIT LCS<br>
 Eric Grosse, Bell Labs<br>
-<br>
 Rob Pike, Bell Labs<br>
-<br>
 Dave Presotto, Avaya Labs and Bell Labs<br>
-<br>
 Sean Quinlan, Bell Labs<br>
-<br>
-<TT>{rsc,ehg,rob,presotto,seanq}@plan9.bell-labs.com</TT>
-</I></DL>
-<DL><DD><H4>ABSTRACT</H4>
-Abstract
-<DL>
-<DT><DT>&#32;<DD>
-NOTE:<I> To appear, in a slightly different form, in
-Proc. of the 2002 Usenix Security Symposium,
-San Francisco.
-</I><DT>&#32;<DD></dl>
-<br>
-The security architecture of the Plan 9(tm)
-operating system has recently been redesigned
-to address some technical shortcomings.
-This redesign provided an opportunity also to make the system more
-convenient to use securely.
-Plan 9 has thus improved in two ways not usually seen together:
-it has become more secure
-<I>and</I>
-easier to use.
-<br>&#32;<br>
-The central component of the new architecture is a per-user
-self-contained agent called
-<TT>factotum</TT>.
-<TT>Factotum</TT>
-securely holds a
-copy of the user's keys and negotiates authentication protocols, on
-behalf of the user, with secure services around the network.
-Concentrating security code in a single program offers several
-advantages including: ease of update or repair to broken security
-software and protocols; the ability to run secure services at a lower
-privilege level; uniform management of keys for all services; and an
-opportunity to provide single sign on, even to unchanged legacy
-applications.
-<TT>Factotum</TT>
-has an unusual architecture: it is implemented
-as a Plan 9 file server.
-</DL>
-<H4>1 Introduction
+</EM><TT>{rsc,ehg,rob,presotto,seanq}@plan9.bell-labs.com<br>
+</TT><h4>ABSTRACT</h4>
+The security architecture of the Plan 9(tm) operating system has recently been redesigned to address some technical shortcomings. This redesign provided an opportunity also to make the system more convenient to use securely. Plan 9 has thus improved in two ways not usually seen together: it has become more secure <EM>and </EM>easier to use.
+  <P>
+The central component of the new architecture is a per-user self-contained agent called <TT>factotum</TT>. <TT>Factotum</TT> securely holds a copy of the user's keys and negotiates authentication protocols, on behalf of the user, with secure services around the network. Concentrating security code in a single program offers several advantages including: ease of update or repair to broken security software and protocols; the ability to run secure services at a lower privilege level; uniform management of keys for all services; and an opportunity to provide single sign on, even to unchanged legacy applications. <TT>Factotum</TT> has an unusual architecture: it is implemented as a Plan 9 file server. [[ To appear, in a slightly different form, in <EM>Proc. of the 2002 Usenix Security Symposium, </EM>San Francisco. ]]
+<H4>1. Introduction
 </H4>
-<br>&#32;<br>
-Secure computing systems face two challenges:
-first, they must employ sophisticated technology that is difficult to design
-and prove correct; and second,
-they must be easy for regular people to use.
-The question of ease of use is sometimes neglected, but it is essential:
-weak but easy-to-use security can be more effective than strong but
-difficult-to-use security if it is more likely to be used.
-People lock their front doors when they leave the house, knowing
-full well that a burglar is capable of picking the lock (or avoiding
-the door altogether); yet few would accept the cost and
-awkwardness of a bank vault door on the
-house even though that might reduce the probability of a robbery.
-A related point is that users need a clear model of how the security
-operates (if not how it actually provides security) in order to use it
-well; for example, the clarity of a lock icon on a web browser
-is offset by the confusing and typically insecure
-steps for installing X.509 certificates.
-<br>&#32;<br>
-The security architecture of the Plan 9
-operating system [Pike95]
-has recently been redesigned to make it both more secure
-and easier to use.
-By
-<I>security</I>
-we mean three things:
-first, the business of authenticating users and services;
-second, the safe handling, deployment, and use of keys
-and other secret information; and
-third, the use of encryption and integrity checks
-to safeguard communications
-from prying eyes.
-<br>&#32;<br>
-The old security architecture of Plan 9
-had several engineering problems in common with other operating systems.
-First, it had an inadequate notion of security domain.
-Once a user provided a password to connect to a local file store,
-the system required that the same password be used to access all the other file
-stores.
-That is, the system treated all network services as
-belonging to the same security domain. 
-<br>&#32;<br>
-Second, the algorithms and protocols used in authentication,
-by nature tricky and difficult to get right, were compiled into the
-various applications, kernel modules, and file servers.
-Changes and fixes to a security protocol
-required that all components using that protocol needed to be recompiled,
-or at least relinked, and restarted.
-<br>&#32;<br>
-Third, the file transport protocol, 9P [Pike93],
-that forms the core of
-the Plan 9 system, had its authentication protocol embedded in its design.
-This meant that fixing or changing the authentication used by 9P
-required deep changes to the system.
-If someone were to find a way to break the protocol, the system would
-be wide open and very hard to fix.
-<br>&#32;<br>
-These and a number of lesser problems, combined with a desire
-for more widespread use of encryption in the system, spurred us to
-rethink the entire security architecture of Plan 9.
-<br>&#32;<br>
-The centerpiece of the new architecture is an agent,
-called
-<TT>factotum</TT>,
-that handles the user's keys and negotiates all security
-interactions with system services and applications.
-Like a trusted houseboy with a copy of the owner's keys,
-<TT>factotum</TT>
-does all the negotiation for security and authentication.
-Programs no longer need to be compiled with cryptographic
-code; instead they communicate with
-<TT>factotum</TT>
-agents
-that represent distinct entities in the cryptographic exchange,
-such as a user and server of a secure service.
-If a security protocol needs to be added, deleted, or modified,
-only
-<TT>factotum</TT>
-needs to be updated for all system services
-to be kept secure.
-<br>&#32;<br>
-Building on
-<TT>factotum</TT>,
-we modified
-secure services in the system to move
-user authentication code into
-<TT>factotum</TT>;
-made authentication a separable component of the file server protocol;
-deployed new security protocols;
-designed a secure file store,
-called
-<TT>secstore</TT>,
-to protect our keys but make them easy to get when they are needed;
-designed a new kernel module to support transparent use of 
-Transport Layer Security (TLS)
-[RFC2246];
-and began using encryption for all communications within the system.
-The overall architecture is illustrated in Figure 1a.
-<DL><DT><DD><TT><PRE>
+Secure computing systems face two challenges: first, they must employ sophisticated technology that is difficult to design and prove correct; and second, they must be easy for regular people to use. The question of ease of use is sometimes neglected, but it is essential: weak but easy-to-use security can be more effective than strong but difficult-to-use security if it is more likely to be used. People lock their front doors when they leave the house, knowing full well that a burglar is capable of picking the lock (or avoiding the door altogether); yet few would accept the cost and awkwardness of a bank vault door on the house even though that might reduce the probability of a robbery. A related point is that users need a clear model of how the security operates (if not how it actually provides security) in order to use it well; for example, the clarity of a lock icon on a web browser is offset by the confusing and typically insecure steps for installing X.509 certificates.
+  <P>
+The security architecture of the Plan 9 operating system [Pike95] has recently been redesigned to make it both more secure and easier to use. By <EM>security </EM>we mean three things: first, the business of authenticating users and services; second, the safe handling, deployment, and use of keys and other secret information; and third, the use of encryption and integrity checks to safeguard communications from prying eyes.
+  <P>
+The old security architecture of Plan 9 had several engineering problems in common with other operating systems. First, it had an inadequate notion of security domain. Once a user provided a password to connect to a local file store, the system required that the same password be used to access all the other file stores. That is, the system treated all network services as belonging to the same security domain.
+  <P>
+Second, the algorithms and protocols used in authentication, by nature tricky and difficult to get right, were compiled into the various applications, kernel modules, and file servers. Changes and fixes to a security protocol required that all components using that protocol needed to be recompiled, or at least relinked, and restarted.
+  <P>
+Third, the file transport protocol, 9P [Pike93], that forms the core of the Plan 9 system, had its authentication protocol embedded in its design. This meant that fixing or changing the authentication used by 9P required deep changes to the system. If someone were to find a way to break the protocol, the system would be wide open and very hard to fix.
+  <P>
+These and a number of lesser problems, combined with a desire for more widespread use of encryption in the system, spurred us to rethink the entire security architecture of Plan 9.<br>
+  <P>
+The centerpiece of the new architecture is an agent, called <TT>factotum</TT>, that handles the user's keys and negotiates all security interactions with system services and applications. Like a trusted assistant with a copy of the owner's keys, <TT>factotum</TT> does all the negotiation for security and authentication. Programs no longer need to be compiled with cryptographic code; instead they communicate with <TT>factotum</TT> agents that represent distinct entities in the cryptographic exchange, such as a user and server of a secure service. If a security protocol needs to be added, deleted, or modified, only <TT>factotum</TT> needs to be updated for all system services to be kept secure.
+  <P>
+Building on <TT>factotum</TT>, we modified secure services in the system to move user authentication code into <TT>factotum</TT>; made authentication a separable component of the file server protocol; deployed new security protocols; designed a secure file store, called <TT>secstore</TT>, to protect our keys but make them easy to get when they are needed; designed a new kernel module to support transparent use of Transport Layer Security (TLS) [RFC2246]; and began using encryption for all communications within the system. The overall architecture is illustrated in Figure 1a.
+<DL><DT><DD>
 <br><img src="-.2669382.gif"><br>
-</PRE></TT></DL>
-<br>&#32;<br>
+</DL>
 Figure 1a.  Components of the security architecture.
 Each box is a (typically) separate machine; each ellipse a process.
 The ellipses labeled <I>F</I><I>X</I>
@@ -173,1888 +50,433 @@ processes consult as required.
 is a shared resource for storing private information such as keys;
 <TT>factotum</TT>
 consults it for the user during bootstrap.
-<br>&#32;<br>
-<br>&#32;<br>
-Secure protocols and algorithms are well understood
-and are usually not the weakest link in a system's security.
-In practice, most security problems arise from buggy servers,
-confusing software, or administrative oversights.
-It is these practical problems that we are addressing.
-Although this paper describes the algorithms and protocols we are using,
-they are included mainly for concreteness.
-Instead, our focus is to present a simple security architecture built
-upon a small trusted code base that is easy to verify (whether by manual or
-automatic means), easy to understand, and easy to use.
-<br>&#32;<br>
-Although it is a subjective assessment,
-we believe we have achieved our goal of ease of use.
-That we have achieved
-our goal of improved security is supported by our plan to
-move our currently private computing environment onto the Internet
-outside the corporate firewall.
-The rest of this paper explains the architecture and how it is used,
-to explain why a system that is easy to use securely is also safe
-enough to run in the open network.
-<H4>2 An Agent for Security
+<P>
+Secure protocols and algorithms are well understood and are usually not the weakest link in a system's security. In practice, most security problems arise from buggy servers, confusing software, or administrative oversights. It is these practical problems that we are addressing. Although this paper describes the algorithms and protocols we are using, they are included mainly for concreteness. Our main intent is to present a simple security architecture built upon a small trusted code base that is easy to verify (whether by manual or automatic means), easy to understand, and easy to use.
+  <P>
+Although it is a subjective assessment, we believe we have achieved our goal of ease of use. That we have achieved our goal of improved security is supported by our plan to move our currently private computing environment onto the Internet outside the corporate firewall. The rest of this paper explains the architecture and how it is used, to explain why a system that is easy to use securely is also safe enough to run in the open network.
+<H4>2. An Agent for Security
+</H4>  <P>
+One of the primary reasons for the redesign of the Plan 9 security infrastructure was to remove the authentication method both from the applications and from the kernel. Cryptographic code is large and intricate, so it should be packaged as a separate component that can be repaired or modified without altering or even relinking applications and services that depend on it. If a security protocol is broken, it should be trivial to repair, disable, or replace it on the fly. Similarly, it should be possible for multiple programs to use a common security protocol without embedding it in each program.
+  <P>
+Some systems use dynamically linked libraries (DLLs) to address these configuration issues. The problem with this approach is that it leaves security code in the same address space as the program using it. The interactions between the program and the DLL can therefore accidentally or deliberately violate the interface, weakening security. Also, a program using a library to implement secure services must run at a privilege level necessary to provide the service; separating the security to a different program makes it possible to run the services at a weaker privilege level, isolating the privileged code to a single, more trustworthy component.
+  <P>
+Following the lead of the SSH agent [Ylon96], we give each user an agent process responsible for holding and using the user's keys. The agent program is called <TT>factotum</TT> because of its similarity to the proverbial servant with the power to act on behalf of his master because he holds the keys to all the master's possessions. It is essential that <TT>factotum</TT> keep the keys secret and use them only in the owner's interest. Later we'll discuss some changes to the kernel to reduce the possibility of <TT>factotum</TT> leaking information inadvertently.
+  <P>
+<TT>Factotum</TT> is implemented, like most Plan 9 services, as a file server. It is conventionally mounted upon the directory <TT>/mnt/factotum</TT>, and the files it serves there are analogous to virtual devices that provide access to, and control of, the services of the <TT>factotum</TT>. The next few sections describe the design of <TT>factotum</TT> and how it operates with the other pieces of Plan 9 to provide security services.
+<H4>2.1. Logging in
 </H4>
-<br>&#32;<br>
-One of the primary reasons for the redesign of the Plan 9
-security infrastructure was to remove the authentication
-method both from the applications and from the kernel.
-Cryptographic code
-is large and intricate, so it should
-be packaged as a separate component that can be repaired or
-modified without altering or even relinking applications
-and services that depend on it.
-If a security protocol is broken, it should be trivial to repair,
-disable, or replace it on the fly.
-Similarly, it should be possible for multiple programs to use
-a common security protocol without embedding it in each program.
-<br>&#32;<br>
-Some systems use dynamically linked libraries (DLLs) to address these configuration issues.
-The problem with this approach is that it leaves
-security code in the same address space as the program using it.
-The interactions between the program and the DLL
-can therefore accidentally or deliberately violate the interface,
-weakening security.
-Also, a program using a library to implement secure services
-must run at a privilege level necessary to provide the service;
-separating the security to a different program makes it possible
-to run the services at a weaker privilege level, isolating the
-privileged code to a single, more trustworthy component.
-<br>&#32;<br>
-Following the lead of the SSH agent
-[Ylon96],
-we give each user
-an agent process responsible
-for holding and using the user's keys.
-The agent program is called
-<TT>factotum</TT>
-because of its similarity to the proverbial servant with the
-power to act on behalf of his master because he holds the
-keys to all the master's possessions.  It is essential that
-<TT>factotum</TT>
-keep the keys secret and use them only in the owner's interest.
-Later we'll discuss some changes to the kernel to reduce the possibility of
-<TT>factotum</TT>
-leaking information inadvertently.
-<br>&#32;<br>
-<TT>Factotum</TT>
-is implemented, like most Plan 9 services, as a file server.
-It is conventionally mounted upon the directory
-<TT>/mnt/factotum</TT>
-and the files it serves there are analogous to virtual devices that provide access to,
-and control of, the services of the
-<TT>factotum</TT>.
-The next few sections describe the design of
-<TT>factotum</TT>
-and how it operates with the other pieces of Plan 9 to provide
-security services.
-<H4>2.1 Logging in
+To make the discussions that follow more concrete, we begin with a couple of examples showing how the Plan 9 security architecture appears to the user. These examples both involve a user <TT>gre</TT> logging in after booting a local machine. The user may or may not have a secure store in which all his keys are kept. If he does, <TT>factotum</TT> will prompt him for the password to the secure store and obtain keys from it, prompting only when a key isn't found in the store. Otherwise, <TT>factotum</TT> must prompt for each key.
+  <P>
+In the typescripts, <TT>\n</TT> represents a literal newline character typed to force a default response. User input is in italics, and long lines are folded and indented to fit.<br>
+  <P>
+This first example shows a user logging in without help from the secure store. First, <TT>factotum</TT> prompts for a user name that the local kernel will use:
+<pre>
+    user[none]: <em>gre</em>
+</pre>
+(Default responses appear in square brackets.) The kernel then starts accessing local resources and requests, through <TT>factotum</TT>, a user/password pair to do so:
+<pre>
+    !Adding key: dom=cs.bell-labs.com proto=p9sk1
+    user[gre]: <em>\n</em>
+    password: ****
+</pre>
+Now the user is logged in to the local system, and the mail client starts up:
+<pre>
+    !Adding key: proto=apop server=plan9.bell-labs.com
+    user[gre]: <em>\n</em>
+    password: <em>****</em>
+</pre>
+<TT>Factotum</TT> is doing all the prompting and the applications being started are not even touching the keys. Note that it's always clear which key is being requested.<br>
+  <P>
+Now consider the same login sequence, but in the case where <TT>gre</TT> has a secure store account:
+<pre>
+    user[none]: gre
+    secstore password: <em>*********</em>
+    STA PIN+SecurID: <em>*********</em>
+</pre>
+That's the last <TT>gre </TT>will hear from <TT>factotum </TT>unless an attempt is made to contact a system for which no key is kept in the secure store.<br>
+<H4>2.2. The factotum
 </H4>
-<br>&#32;<br>
-To make the discussions that follow more concrete,
-we begin with a couple of examples showing how the
-Plan 9 security architecture appears to the user.
-These examples both involve a user
-<TT>gre</TT>
-logging in after booting a local machine.
-The user may or may not have a secure store in which
-all his keys are kept.
-If he does,
-<TT>factotum</TT>
-will prompt him for the password to the secure store
-and obtain keys from it, prompting only when a key
-isn't found in the store.
-If not,
-<TT>factotum</TT>
-must prompt for each key.
-<br>&#32;<br>
-In the typescripts,
-<TT>0</TT>
-epresents a literal newline
-character typed to force a default response.
-User input is in italics, and
-long lines are folded and indented to fit.
-<br>&#32;<br>
-This first example shows a user logging in without
-help from the secure store.
-First,
-<TT>factotum</TT>
-prompts for a user name that the local kernel
-will use:
-<DL><DT><DD><TT><PRE>
-user[none]: gre
-</PRE></TT></DL>
-(Default responses appear in square brackets.)
-The kernel then starts accessing local resources
-and requests, through
-<TT>factotum</TT>,
-a user/password pair to do so:
-<DL><DT><DD><TT><PRE>
-!Adding key: dom=cs.bell-labs.com
-    proto=p9sk1
-user[gre]: \n
-password: ****
-</PRE></TT></DL>
-Now the user is logged in to the local system, and
-the mail client starts up:
-<DL><DT><DD><TT><PRE>
-!Adding key: proto=apop
-    server=plan9.bell-labs.com
-user[gre]: \n
-password: ****
-</PRE></TT></DL>
-<TT>Factotum</TT>
-is doing all the prompting and the applications
-being started are not even touching the keys.
-Note that it's always clear what key is being requested.
-<br>&#32;<br>
-Now consider the same login sequence, but in the case where
-<TT>gre</TT>
-has a secure store account:
-<DL><DT><DD><TT><PRE>
-user[none]: gre
-secstore password: ******
-STA PIN+SecurID: ******
-</PRE></TT></DL>
-That's the last
-<TT>gre</TT>
-will hear from
-<TT>factotum</TT>
-unless an attempt is made to contact
-a system for which no key is kept in the secure store.
-<H4>2.2 The factotum
+Each computer running Plan 9 has one user id that owns all the resources on that system -- the scheduler, local disks, network interfaces, etc. That user, the <EM>host owner</EM>, is the closest analogue in Plan 9 to a Unix <TT>root</TT> account (although it is far weaker; rather than having special powers, as its name implies the host owner is just a regular user that happens to own the resources of the local machine). On a single-user system, which we call a terminal, the host owner is the id of the terminal's user. Shared servers such as CPU servers normally have a pseudo-user that initially owns all resources. At boot time, the Plan 9 kernel starts a <TT>factotum</TT> executing as, and therefore with the privileges of, the host owner.
+  <P>
+New processes run as the same user as the process which created them. When a process must take on the identity of a new user, such as to provide a login shell on a shared CPU server, it does so by proving to the host owner's <TT>factotum</TT> that it is authorized to do so. This is done by running an authentication protocol with <TT>factotum</TT> to prove that the process has access to secret information which only the new user should possess. For example, consider the setup in Figure 1a. If a user on the terminal wants to log in to the CPU server using the Plan 9 <TT>cpu</TT> service [Pike93], then <EM>PT </EM>might be the <TT>cpu</TT> client program and <EM>PC </EM>the <TT>cpu</TT> server. Neither <EM>PC </EM>nor <EM>PT </EM>knows the details of the authentication. They do need to be able to shuttle messages back and forth between the two <TT>factotums</TT>, but this is a generic function easily performed without knowing, or being able to extract, secrets in the messages. <EM>PT </EM>will make a network connection to <EM>PC</EM>. <EM>PT </EM>and <EM>PC </EM>will then relay messages between the <TT>factotum</TT> owned by the user, <EM>FT</EM>, and the one owned by the CPU server, <EM>FC</EM>, until mutual authentication has been established. Later sections describe the RPC between <TT>factotum</TT> and applications and the library functions to support proxy operations.
+  <P>
+The kernel always uses a single local instance of <TT>factotum</TT>, running as the host owner, for its authentication purposes, but a regular user may start other <TT>factotum</TT> agents. In fact, the <TT>factotum</TT> representing the user need not be running on the same machine as its client. For instance, it is easy for a user on a CPU server, through standard Plan 9 operations, to replace the <TT>/mnt/factotum</TT> in the user's private file name space on the server with a connection to the <TT>factotum</TT> running on the terminal. (The usual file system permissions prevent interlopers from doing so maliciously.) This permits secure operations on the CPU server to be transparently validated by the user's own <TT>factotum</TT>, so secrets need never leave the user's terminal. The SSH agent [Ylon96] does much the same with special SSH protocol messages, but an advantage to making our agent a file system is that we need no new mechanism to access our remote agent; remote file access is sufficient.
+  <P>
+Within <TT>factotum</TT>, each protocol is implemented as a state machine with a generic interface, so protocols are in essence pluggable modules, easy to add, modify, or drop. Writing a message to and reading a message from <TT>factotum</TT> each require a separate RPC and result in a single state transition. Therefore <TT>factotum</TT> always runs to completion on every RPC and never blocks waiting for input during any authentication. Moreover, the number of simultaneous authentications is limited only by the amount of memory we're willing to dedicate to representing the state machines.
+  <P>
+Authentication protocols are implemented only within <TT>factotum</TT>, but adding and removing protocols does require relinking the binary, so <TT>factotum</TT> processes (but no others) need to be restarted in order to take advantage of new or repaired protocols.<br>
+  <P>
+At the time of writing, <TT>factotum</TT> contains authentication modules for the Plan 9 shared key protocol (p9sk1), SSH's RSA authentication, passwords in the clear, APOP, CRAM, PPP's CHAP, Microsoft PPP's MSCHAP, and VNC's challenge/response.<br>
+<H4>2.3. Local capabilities
 </H4>
-<br>&#32;<br>
-Each computer running Plan 9 has one user id that owns all the
-resources on that system &#173; the scheduler, local disks,
-network interfaces, etc.
-That user, the
-<I>host owner</I>,
-is the closest analogue in Plan 9 to a Unix
-<TT>root</TT>
-account (although it is far weaker;
-rather than having special powers, as its name implies the host owner
-is just a regular user that happens to own the
-resources of the local machine).
-On a single-user system, which we call a terminal,
-the host owner is the id of the terminal's user.
-Shared servers such as CPU servers normally have a pseudo-user
-that initially owns all resources.
-By default,
-<TT>factotum</TT>
-executes as, and therefore has the privileges of,
-the host owner.
-<br>&#32;<br>
-New processes run as
-the same user as the process which created them.
-When a process must take on the identity of a new user,
-such as to provide a login shell
-on a shared CPU server,
-it does so by proving to the host owner's
-<TT>factotum</TT>
-that it is
-authorized to do so.
-This is done by running an
-authentication protocol with
-<TT>factotum</TT>
-to
-prove that the process has access to secret information
-which only the new user should possess.
-For example, consider the setup in Figure 1a.
-If a user on the terminal
-wants to log on to the CPU server using the
-Plan 9
-<TT>cpu</TT>
-service [Pike93],
-then
-<I>P</I><I>T</I>
-might be the
-<TT>cpu</TT>
-client program and
-<I>P</I><I>C</I>
-the
-<TT>cpu</TT>
-server.
-Neither <I>P</I><I>C</I> nor <I>P</I><I>T</I>
-knows the details of the authentication.
-They
-do need to be able to shuttle messages back and
-forth between the two
-<TT>factotums</TT>,
-but this is
-a generic function easily performed without
-knowing, or being able to extract, secrets in
-the messages.
-<I>P</I><I>T</I>
-will make a network connection to <I>P</I><I>C</I>.
-<I>P</I><I>T</I>
-and
-<I>P</I><I>C</I>
-will then relay messages between
-the
-<TT>factotum</TT>
-owned by the user, <I>F</I><I>T</I>,
-and the one owned by the CPU server, <I>F</I><I>C</I>,
-until mutual authentication has been established.
-Later
-sections describe the RPC between
-<TT>factotum</TT>
-and
-applications and the library functions to support proxy operations.
-<br>&#32;<br>
-The kernel always uses a single local instance of
-<TT>factotum</TT>,
-running as the
-host owner, for
-its authentication purposes, but
-a regular user may start multiple
-<TT>factotum</TT>
-agents.
-In fact, the
-<TT>factotum</TT>
-representing the user need not be
-running on the same machine as its client.
-For instance, it is easy for a user on a CPU server,
-through standard Plan 9 operations,
-to replace the
-<TT>/mnt/factotum</TT>
-in the user's private file name space on the server
-with a connection to the
-<TT>factotum</TT>
-running on the terminal.
-(The usual file system permissions prevent interlopers
-from doing so maliciously.)
-This permits secure operations on the CPU server to be
-transparently validated by the user's own
-<TT>factotum</TT>,
-so
-secrets need never leave the user's terminal.
-SSH agent
-[Ylon96]
-does much the
-same with special SSH protocol messages, but
-an advantage to making our agent a file system
-is that we need no new mechanism to access our remote
-agent; remote file access is sufficient.
-<br>&#32;<br>
-Within
-<TT>factotum</TT>,
-each protocol is implemented as a state
-machine with a generic interface, so protocols are in
-essence pluggable modules, easy to add, modify, or drop.
-Writing a message to and reading a message from
-<TT>factotum</TT>
-each require a separate RPC and result in
-a single state transition.
-Therefore
-<TT>factotum</TT>
-always runs to completion on every RPC and never blocks
-waiting for input during any authentication.
-Moreover, the number of simultaneous
-authentications is limited only by the amount of memory we're
-willing to dedicate to representing the state machines.
-<br>&#32;<br>
-Authentication protocols are implemented only
-within
-<TT>factotum</TT>,
-but adding and removing
-protocols does require relinking the binary, so
-<TT>factotum</TT>
-processes (but no others)
-need to be restarted in order to take advantage of
-new or repaired protocols.
-<br>&#32;<br>
-At the time of writing, 
-<TT>factotum</TT>
-contains authentication
-modules for the Plan 9 shared key protocol (p9sk1), for
-SSH's RSA authentication, passwords in the clear, APOP, CRAM, PPP's CHAP,
-Microsoft PPP's MSCHAP, and VNC's challenge/response.  We're
-in the process of adding support for TLS handshakes.
-<H4>2.3 Local capabilities
+A capability system, managed by the kernel, is used to empower <TT>factotum</TT> to grant permission to another process to change its user id. A kernel device driver implements two files, <TT>/dev/caphash</TT> and <TT>/dev/capuse</TT>. The write-only file <TT>/dev/caphash</TT> can be opened only by the host owner, and only once. <TT>Factotum</TT> opens this file immediately after booting.
+  <P>
+To use the files, <TT>factotum</TT> creates a string of the form <EM>userid1</EM><TT>@</TT><EM>userid2</EM><TT>@</TT><EM>random-string</EM>, uses SHA1 HMAC to hash <EM>userid1</EM><TT>@</TT><EM>userid2 </EM>with key <EM>random-string</EM>, and writes that hash to <TT>/dev/caphash</TT>. <TT>Factotum</TT> then passes the original string to another process on the same machine, running as user <EM>userid1</EM>, which writes the string to <TT>/dev/capuse</TT>. The kernel hashes the string and looks for a matching hash in its list. If it finds one, the writing process's user id changes from <EM>userid1 </EM>to <EM>userid2</EM>. Once used, or if a timeout expires, the capability is discarded by the kernel.
+  <P>
+The capabilities are local to the machine on which they are created. Hence a <TT>factotum</TT> running on one machine cannot pass capabilities to processes on another and expect them to work.<br>
+<H4>2.4. Keys
 </H4>
-<br>&#32;<br>
-A capability system, managed by the kernel, is used to empower
-<TT>factotum</TT>
-to grant permission to another process to change its user id.
-A
-kernel device driver
-implements two files,
-<TT>/dev/caphash</TT>
-and
-<TT>/dev/capuse</TT>.
-The write-only file
-<TT>/dev/caphash</TT>
-can be opened only by the host owner, and only once.
-<TT>Factotum</TT>
-opens this file immediately after booting.
-<br>&#32;<br>
-To use the files,
-<TT>factotum</TT>
-creates a string of the form
-<I>userid1&lt;TT&gt;@&lt;/TT&gt;userid2&lt;TT&gt;@&lt;/TT&gt;random-string</I>,
-uses SHA1 HMAC to hash
-<I>userid1&lt;TT&gt;@&lt;/TT&gt;userid2</I>
-with key
-<I>random-string</I>,
-and writes that hash to
-<TT>/dev/caphash</TT>.
-<TT>Factotum</TT>
-then passes the original string to another
-process on the same machine, running
-as user
-<I>userid1</I>,
-which
-writes the string to
-<TT>/dev/capuse</TT>.
-The kernel hashes the string and looks for
-a matching hash in its list.
-If it finds one,
-the writing process's user id changes from
-<I>userid1</I>
-to
-<I>userid2</I>.
-Once used, or if a timeout expires,
-the capability is discarded by the kernel.
-<br>&#32;<br>
-The capabilities are hashed to keep them secret if
-someone is spying on kernel memory.
-Also, they are local to the machine on which they are created.
-Hence a
-<TT>factotum</TT>
-running on one system cannot pass capabilities
-to processes on another and expect them to work.
-<H4>2.4 Keys
-</H4>
-<br>&#32;<br>
-We define the word
-<I>key</I>
-to mean not only a secret, but also a description of the
-context in which that secret is to be used: the protocol,
-server, user, etc. to which it applies.
-That is,
-a key is a combination of secret and descriptive information
-used to authenticate the identities of parties
-transmitting or receiving information.
-The set of keys used
-in any authentication depends both on the protocol and on
-parameters passed by the program requesting the authentication.
-<br>&#32;<br>
-Taking a tip from SDSI
-[RiLa],
-which represents security information as textual S-expressions,
-keys in Plan 9 are represented as plain UTF-8 text.
-Text is easily
-understood and manipulated by users.
-By contrast,
-a binary or other cryptic format
-can actually reduce overall security.
-Binary formats are difficult for users to examine and can only be
-cracked by special tools, themselves poorly understood by most users.
-For example, very few people know or understand what's inside
-their X.509 certificates.
-Most don't even know where in the system to
-find them.
-Therefore, they have no idea what they are trusting, and why, and
-are powerless to change their trust relationships.
-Textual, centrally stored and managed keys are easier to use and safer.
-<br>&#32;<br>
-Plan 9 has historically represented databases as attribute/value pairs,
-since they are a good foundation for selection and projection operations.
-<TT>Factotum</TT>
-therefore represents
-the keys in the format
-<I>attribute&lt;TT&gt;=&lt;/TT&gt;value</I>,
-where
-<I>attribute</I>
-is an identifier, possibly with a single-character prefix, and
-<I>value</I>
-is an arbitrary quoted string.
-The pairs themselves are separated by white space.
-For example, a Plan 9 key and an APOP key
-might be represented like this:
-<DL><DT><DD><TT><PRE>
-dom=bell-labs.com proto=p9sk1 user=gre
-	!password='don''t tell'
-proto=apop server=x.y.com user=gre
-	!password='bite me'
-</PRE></TT></DL>
-If a value is empty or contains white space or single quotes, it must be quoted;
-quotes are represented by doubled single quotes.
-Attributes that begin with an exclamation mark
-(<TT>!</TT>)
-are considered
-<I>secret</I>.
-<TT>Factotum</TT>
-will never let a secret value escape its address space
-and will suppress keyboard echo when asking the user to type one.
-<br>&#32;<br>
-A program requesting authentication selects a key
-by providing a
-<I>query</I>,
-a list of elements to be matched by the key.
-Each element in the list is either an
-<I>attribute&lt;TT&gt;=&lt;/TT&gt;value</I>
-pair, which is satisfied by keys with
-exactly that pair;
-or an attribute followed by a question mark,
-</TT><I>attribute&lt;TT&gt;?</I><TT>,
-which is satisfied by keys with some pair specifying
-the attribute.
-A key matches a query if every element in the list
-is satisfied.
-For instance, to select the APOP key in the previous example,
-an APOP client process might specify the query
-<DL><DT><DD><TT><PRE>
-server=x.y.com proto=apop
-</PRE></TT></DL>
-Internally,
-</TT><TT>factotum</TT><TT>'s
-APOP module would add the requirements of
-having
-</TT><TT>user</TT><TT>
-and
-</TT><TT>!password</TT><TT>
-attributes, forming the query
-<DL><DT><DD><TT><PRE>
-server=x.y.com proto=apop user? !password?
-</PRE></TT></DL>
-when searching for an appropriate key.
-</TT><br>&#32;<br>
-<TT>Factotum</TT>
-modules expect keys to have some well-known attributes.
-For instance, the
-<TT>proto</TT>
-attribute specifies the protocol module
-responsible for using a particular key,
-and protocol modules may expect other well-known attributes
-(many expect keys to have
-<TT>!password</TT>
-attributes, for example).
-Additional attributes can be used as comments or for
-further discrimination without intervention by 
-<TT>factotum</TT>;
-for example, the APOP and IMAP mail clients conventionally
-include a
-<TT>server</TT>
-attribute to select an appropriate key for authentication.
-<br>&#32;<br>
-Unlike in SDSI,
-keys in Plan 9 have no nested structure.  This design
-keeps the representation simple and straightforward.
-If necessary, we could add a nested attribute
-or, in the manner of relational databases, an attribute that
-selects another tuple, but so far the simple design has been sufficient.
-<br>&#32;<br>
-A simple common structure for all keys makes them easy for users
-to administer,
-but the set of attributes and their interpretation is still
-protocol-specific and can be subtle.
-Users may still
-need to consult a manual to understand all details.
-Many attributes
-(<TT>proto</TT>,
-<TT>user</TT>,
-<TT>password</TT>,
-<TT>server</TT>)
-are self-explanatory and our short experience
-has not uncovered any particular difficulty in handling keys.
-Things
-will likely get messier, however,
-when we grapple with public
-keys and their myriad components.
-<H4>2.5 Protecting keys
+We define the word <EM>key </EM>to mean not only a secret, but also a description of the context in which that secret is to be used: the protocol, server, user, etc. to which it applies. That is, a key is a combination of secret and descriptive information used to authenticate the identities of parties transmitting or receiving information. The set of keys used in any authentication depends both on the protocol and on parameters passed by the program requesting the authentication.
+  <P>
+Taking a tip from SDSI [RiLa], which represents security information as textual S-expressions, keys in Plan 9 are represented as plain UTF-8 text. Text is easily understood and manipulated by users. By contrast, a binary or other cryptic format can actually reduce overall security. Binary formats are difficult for users to examine and can only be cracked by special tools, themselves poorly understood by most users. For example, very few people know or understand what's inside their X.509 certificates. Most don't even know where in the system to find them. Therefore, they have no idea what they are trusting, and why, and are powerless to change their trust relationships. Textual, centrally stored and managed keys are easier to use and safer.
+  <P>
+Plan 9 has historically represented databases as attribute/value pairs, since they are a good foundation for selection and projection operations. <TT>Factotum</TT> therefore represents the keys in the format <EM>attribute</EM><TT>=</TT><EM>value</EM>, where <EM>attribute </EM>is an identifier, possibly with a single-character prefix, and <EM>value </EM>is an arbitrary quoted string. The pairs themselves are separated by white space. For example, a Plan 9 key and an APOP key might be represented like this:
+<pre>
+    dom=bell-labs.com proto=p9sk1 user=gre !password='don''t tell'
+    proto=apop server=x.y.com user=gre !password='open sesame'
+</pre>
+If a value is empty or contains white space or single quotes, it must be quoted; quotes are represented by doubled single quotes. Attributes that begin with an exclamation mark (<TT>!</TT>) are considered <EM>secret</EM>. <TT>Factotum</TT> will never let a secret value escape its address space and will suppress keyboard echo when asking the user to type one.
+  <P>
+A program requesting authentication selects a key by providing a <EM>query</EM>, a list of elements to be matched by the key. Each element in the list is either an <EM>attribute</EM><TT>=</TT><EM>value </EM>pair, which is satisfied by keys with exactly that pair; or an attribute followed by a question mark, <EM>attribute</EM><TT>?</TT>, which is satisfied by keys with some pair specifying the attribute. A key matches a query if every element in the list is satisfied. For instance, to select the APOP key in the previous example, an APOP client process might specify the query
+<DL><DT><DD><TT>server=x.y.com proto=apop<br>
+</TT></DL>Internally, <TT>factotum</TT>'s APOP module would add the requirements of having <TT>user </TT>and <TT>!password </TT>attributes, forming the query<br>
+<DL><DT><DD><TT>server=x.y.com proto=apop user? !password?<br>
+</TT></DL>when searching for an appropriate key.<br>
+  <P>
+<TT>Factotum</TT> modules expect keys to have some well-known attributes. For instance, the <TT>proto</TT> attribute specifies the protocol module responsible for using a particular key, and protocol modules may expect other well-known attributes (many expect keys to have <TT>!password</TT> attributes, for example). Additional attributes can be used as comments or for further discrimination without intervention by <TT>factotum</TT>; for example, the APOP and IMAP mail clients conventionally include a <TT>server</TT> attribute to select an appropriate key for authentication.
+  <P>
+Unlike in SDSI, keys in Plan 9 have no nested structure. This design keeps the representation simple and straightforward. If necessary, we could add a nested attribute or, in the manner of relational databases, an attribute that selects another tuple, but so far the simple design has been sufficient.
+  <P>
+A simple common structure for all keys makes them easy for users to administer, but the set of attributes and their interpretation is still protocol-specific and can be subtle. Users may still need to consult a manual to understand all details. Many attributes (<TT>proto</TT>, <TT>user</TT>, <TT>password</TT>, <TT>server</TT>) are self-explanatory and our short experience has not uncovered any particular difficulty in handling keys. Things will likely get messier, however, when we grapple with public keys and their myriad components.
+<H4>2.5. Protecting keys
 </H4>
-<br>&#32;<br>
-Secrets must be prevented from escaping
-<TT>factotum</TT>.
-There are a number of ways they could leak:
-another process might be able to debug the agent process, the
-agent might swap out to disk, or the process might willingly
-disclose the key.
-The last is the easiest to avoid:
-secret information in a key is marked
-as such, and
-whenever
-<TT>factotum</TT>
-prints keys or queries for new
-ones, it is careful to avoid displaying secret information.
-(The only exception to this is the
-``plaintext password'' protocol, which consists
-of sending the values of the
-<TT>user</TT>
-and
-<TT>!password</TT>
-attributes.
-Only keys tagged with
-<TT>proto=pass</TT>
-can have their passwords disclosed by this mechanism.)
-<br>&#32;<br>
-Preventing the first two forms of leakage
-requires help from the kernel.
-In Plan 9, every process is
-represented by a directory in the
-<TT>/proc</TT>
-file system.
-Using the files in this directory,
-other processes could (with appropriate access permission) examine
-<TT>factotum</TT>'s
-memory and registers.
-<TT>Factotum</TT>
-is protected from processes of other users
-by the default access bits of its
-<TT>/proc</TT>
-directory.
-However, we'd also like to protect the
-agent from other processes owned by the same user,
-both to avoid honest mistakes and to prevent
-an unattended terminal being
-exploited to discover secret passwords.
-To do this, we added a control message to
-<TT>/proc</TT>
-called
-<TT>private</TT>.
-Once the
-<TT>factotum</TT>
-process has written
-<TT>private</TT>
-to its
-<TT>/proc/<I>pid</I>/ctl</TT>
-file, no process can access
-<TT>factotum</TT>'s
-memory
-through
-<TT>/proc</TT>.
-(Plan 9 has no other mechanism, such as
-<TT>/dev/kmem</TT>,
-for accessing a process's memory.)
-<br>&#32;<br>
-Similarly, the agent's address space should not be
-swapped out, to prevent discovering unencrypted
-keys on the swapping media.
-The
-<TT>noswap</TT>
-control message in
-<TT>/proc</TT>
-prevents this scenario.
-Neither
-<TT>private</TT>
-nor
-<TT>noswap</TT>
-is specific to
-<TT>factotum</TT>;
-any process can use
-them.
-Both are useful, for instance, to protect any user-level program
-providing critical file services for the kernel.
-<br>&#32;<br>
-Despite our precautions, attackers might still
-find a way to gain access to a process running as the host
-owner on a machine.
-Although they could not directly
-access the keys, attackers could use the local
-<TT>factotum</TT>
-to perform authentications for them.
-In the case
-of some keys, for example those locking bank
-accounts, we want a way to disable or at least
-detect such access.
-That is the role of the
-<TT>confirm</TT>
-attribute in a key.
-Whenever a key with a
-<TT>confirm</TT>
-attribute is accessed, the local user must
-confirm use of the key via a local GUI.
-The next section describes the actual mechanism.
-<br>&#32;<br>
-We have not addressed leaks possible as a result of
-someone rebooting or resetting a machine running
-<TT>factotum</TT>.
-For example, someone could reset a machine
-and reboot it with a debugger instead of a kernel,
-allowing them to examine the contents of memory
-and find keys.  We have not found a satisfactory
-solution to this problem.
-<H4>2.6 Factotum transactions
+Secrets must be prevented from escaping <TT>factotum</TT>. There are a number of ways they could leak: another process might be able to debug the agent process, the agent might swap out to disk, or the process might willingly disclose the key. The last is the easiest to avoid: secret information in a key is marked as such, and whenever <TT>factotum</TT> prints keys or queries for new ones, it is careful to avoid displaying secret information. (The only exception to this is the ``plaintext password'' protocol, which consists of sending the values of the <TT>user</TT> and <TT>!password</TT> attributes. Only keys tagged with <TT>proto=pass</TT> can have their passwords disclosed by this mechanism.)
+  <P>
+Preventing the first two forms of leakage requires help from the kernel. In Plan 9, every process is represented by a directory in the <TT>/proc</TT> file system. Using the files in this directory, other processes could (with appropriate access permission) examine <TT>factotum</TT>'s memory and registers. <TT>Factotum</TT> is protected from processes of other users by the default access bits of its <TT>/proc</TT> directory. However, we'd also like to protect the agent from other processes owned by the same user, both to avoid honest mistakes and to prevent an unattended terminal being exploited to discover secret passwords. To do this, we added a control message to <TT>/proc</TT> called <TT>private</TT>. Once the <TT>factotum</TT> process has written <TT>private</TT> to its <TT>/proc/</TT><EM>pid</EM><TT>/ctl</TT> file, no process can access <TT>factotum</TT>'s memory through <TT>/proc</TT>. (Plan 9 has no other mechanism, such as <TT>/dev/kmem</TT>, for accessing a process's memory.)
+  <P>
+Similarly, the agent's address space should not be swapped out, to prevent discovering unencrypted keys on the swapping media. The <TT>noswap</TT> control message in <TT>/proc</TT> prevents this scenario. Neither <TT>private</TT> nor <TT>noswap</TT> is specific to <TT>factotum</TT>. User-level file servers such as <TT>dossrv</TT>, which interprets FAT file systems,
+could use <TT>noswap</TT>
+to keep their buffer caches from being
+swapped to disk.
+  <P>
+Despite our precautions, attackers might still find a way to gain access to a process running as the host owner on a machine. Although they could not directly access the keys, attackers could use the local <TT>factotum</TT> to perform authentications for them. In the case of some keys, for example those locking bank accounts, we want a way to disable or at least detect such access. That is the role of the <TT>confirm</TT> attribute in a key. Whenever a key with a <TT>confirm</TT> attribute is accessed, the local user must confirm use of the key via a local GUI. The next section describes the actual mechanism.
+  <P>
+We have not addressed leaks possible as a result of someone rebooting or resetting a machine running <TT>factotum</TT>. For example, someone could reset a machine and reboot it with a debugger instead of a kernel, allowing them to examine the contents of memory and find keys. We have not found a satisfactory solution to this problem.
+<H4>2.6. Factotum transactions
 </H4>
-<br>&#32;<br>
-External programs manage
-<TT>factotum</TT>'s
-internal key state
-through its file interface,
-writing textual
-<TT>key</TT>
-and
-<TT>delkey</TT>
-commands to the
-<TT>/mnt/factotum/ctl</TT>
-file.
-Both commands take a list of attributes as an argument.
-<TT>Key</TT>
-creates a key with the given attributes, replacing any
-extant key with an identical set of public attributes.
-<TT>Delkey</TT>
-deletes all keys that match the given set of attributes.
-Reading the 
-<TT>ctl</TT>
-file returns a list of keys, one per line, displaying only public attributes.
-The following example illustrates these interactions.
-<DL><DT><DD><TT><PRE>
-% cd /mnt/factotum
-% ls -l
--lrw------- gre gre 0 Jan 30 22:17 confirm
---rw------- gre gre 0 Jan 30 22:17 ctl
--lr-------- gre gre 0 Jan 30 22:17 log
--lrw------- gre gre 0 Jan 30 22:17 needkey
---r--r--r-- gre gre 0 Jan 30 22:17 proto
---rw-rw-rw- gre gre 0 Jan 30 22:17 rpc
-% cat &gt;ctl
-key dom=bell-labs.com proto=p9sk1 user=gre
-    !password='don''t tell'
-key proto=apop server=x.y.com user=gre
-    !password='bite me'
-^D
-% cat ctl
-key dom=bell-labs.com proto=p9sk1 user=gre
-key proto=apop server=x.y.com user=gre
-% echo 'delkey proto=apop' &gt;ctl
-% cat ctl
-key dom=bell-labs.com proto=p9sk1 user=gre
-% 
-</PRE></TT></DL>
-(A file with the
-<TT>l</TT>
-bit set can be opened by only one process at a time.)
-<br>&#32;<br>
-The heart of the interface is the
-<TT>rpc</TT>
-file.
-Programs authenticate with
-<TT>factotum</TT>
-by writing a request to the
-<TT>rpc</TT>
-file
-and reading back the reply; this sequence is called an RPC
-<I>transaction</I>.
-Requests and replies have the same format:
-a textual verb possibly followed by arguments,
-which may be textual or binary.
-The most common reply verb is
-<TT>ok</TT>,
-indicating success.
-An RPC session begins with a
-<TT>start</TT>
-transaction; the argument is a key query as described
-earlier.
-Once started, an RPC conversation usually consists of 
-a sequence of
-<TT>read</TT>
-and
-<TT>write</TT>
-transactions.
-If the conversation is successful, an
-<TT>authinfo</TT>
-transaction will return information about
-the identities learned during the transaction.
-The
-<TT>attr</TT>
-transaction returns a list of attributes for the current
-conversation; the list includes any attributes given in
-the 
-<TT>start</TT>
-query as well as any public attributes from keys being used.
-<br>&#32;<br>
-As an example of the RPC file in action, consider a mail client
-connecting to a mail server and authenticating using
-the POP3 protocol's APOP challenge-response command.
-There are four programs involved: the mail client <I>P</I><I>C</I>, the client
-<TT>factotum</TT>
-<I>F</I><I>C</I>, the mail server <I>P</I><I>S</I>, and the server
-<TT>factotum</TT>
-<I>F</I><I>S</I>.
-All authentication computations are handled by the
-<TT>factotum</TT>
-processes.
-The mail programs' role is just to relay messages.
-<br>&#32;<br>
-At startup, the mail server at
-<TT>x.y.com</TT>
-begins an APOP conversation
-with its
-<TT>factotum</TT>
-to obtain the banner greeting, which
-includes a challenge:
-<DL><DT><DD><TT><PRE>
-<I>P</I><I>S</I>-&gt;<I>F</I><I>S</I>: start proto=apop role=server
-<I>F</I><I>S</I>-&gt;<I>P</I><I>S</I>: ok
-<I>P</I><I>S</I>-&gt;<I>F</I><I>S</I>: read
-<I>F</I><I>S</I>-&gt;<I>P</I><I>S</I>: ok +OK POP3 <I>challenge</I>
-</PRE></TT></DL>
-Having obtained the challenge, the server greets the client:
-<DL><DT><DD><TT><PRE>
-<I>P</I><I>S</I>-&gt;<I>P</I><I>C</I>: +OK POP3 <I>challenge</I>
-</PRE></TT></DL>
-The client then uses an APOP conversation with its
-<TT>factotum</TT>
-to obtain a response:
-<DL><DT><DD><TT><PRE>
-<I>P</I><I>C</I>-&gt;<I>F</I><I>C</I>: start proto=apop role=client
-            server=x.y.com
-<I>F</I><I>C</I>-&gt;<I>P</I><I>C</I>: ok
-<I>P</I><I>C</I>-&gt;<I>F</I><I>C</I>: write +OK POP3 <I>challenge</I>
-<I>F</I><I>C</I>-&gt;<I>P</I><I>C</I>: ok
-<I>P</I><I>C</I>-&gt;<I>F</I><I>C</I>: read
-<I>F</I><I>C</I>-&gt;<I>P</I><I>C</I>: ok APOP gre <I>response</I>
-</PRE></TT></DL>
-<TT>Factotum</TT>
-requires that
-<TT>start</TT>
-requests include a 
-<TT>proto</TT>
-attribute, and the APOP module requires an additional
-<TT>role</TT>
-attribute, but the other attributes are optional and only
-restrict the key space.
-Before responding to the
-<TT>start</TT>
-transaction, the client
-<TT>factotum</TT>
-looks for a key to
-use for the rest of the conversation.
-Because of the arguments in the
-<TT>start</TT>
-request, the key must have public attributes
-<TT>proto=apop</TT>
-and
-<TT>server=x.y.com</TT>;
-as mentioned earlier,
-the APOP module additionally requires that the key have
-<TT>user</TT>
-and
-<TT>!password</TT>
-attributes.
-Now that the client has obtained a response
-from its
-<TT>factotum</TT>,
-it echoes that response to the server:
-<DL><DT><DD><TT><PRE>
-<I>P</I><I>C</I>-&gt;<I>P</I><I>S</I>: APOP gre <I>response</I>
-</PRE></TT></DL>
-Similarly, the server passes this message to
-its
-<TT>factotum</TT>
-and obtains another to send back.
-<DL><DT><DD><TT><PRE>
-<I>P</I><I>S</I>-&gt;<I>F</I><I>S</I>: write APOP gre <I>response</I>
-<I>F</I><I>S</I>-&gt;<I>P</I><I>S</I>: ok
-<I>P</I><I>S</I>-&gt;<I>F</I><I>S</I>: read
-<I>F</I><I>S</I>-&gt;<I>P</I><I>S</I>: ok +OK welcome
-
-<I>P</I><I>S</I>-&gt;<I>P</I><I>C</I>: +OK welcome
-</PRE></TT></DL>
-Now the authentication protocol is done, and
-the server can retrieve information
-about what the protocol established.
-<DL><DT><DD><TT><PRE>
-<I>P</I><I>S</I>-&gt;<I>F</I><I>S</I>: authinfo
-<I>F</I><I>S</I>-&gt;<I>P</I><I>S</I>: ok client=gre
-            capability=<I>capability</I>
-</PRE></TT></DL>
-The
-<TT>authinfo</TT>
-data is a list of
-<I>attr&lt;TT&gt;=&lt;/TT&gt;value</I>
-pairs, here a client user name and a capability.
-(Protocols that establish shared secrets or provide
-mutual authentication indicate this by adding
-appropriate
-<I>attr&lt;TT&gt;=&lt;/TT&gt;value</I>
-pairs.)
-The capability can be used by the server to change its
-identity to that of the client, as described earlier.
-Once it has changed its identity, the server can access and serve
-the client's mailbox.
-<br>&#32;<br>
-Two more files provide hooks for a graphical
-<TT>factotum</TT>
-control interface.
-The first, 
-<TT>confirm</TT>,
-allows the user detailed control over the use of certain keys.
-If a key has a
-<TT>confirm=</TT>
-attribute, then the user must approve each use of the key.
-A separate program with a graphical interface reads from the
-<TT>confirm</TT>
-file to see when a confirmation is necessary.
-The read blocks until a key usage needs to be approved, whereupon
-it will return a line of the form
-<DL><DT><DD><TT><PRE>
-confirm tag=1 <I>attributes</I>
-</PRE></TT></DL>
-requesting permission to use the key with those public attributes.
-The graphical interface then prompts the user for approval
-and writes back
-<DL><DT><DD><TT><PRE>
-tag=1 answer=yes
-</PRE></TT></DL>
-(or
-<TT>answer=no</TT>).
-<br>&#32;<br>
-The second file,
-<TT>needkey</TT>,
-diverts key requests.
-In the APOP example, if a suitable key had not been found
-during the
-<TT>start</TT>
-transaction,
-<TT>factotum</TT>
-would have indicated failure by
-returning a response indicating
-what key was needed:
-<DL><DT><DD><TT><PRE>
-<I>F</I><I>C</I>-&gt;<I>P</I><I>C</I>: needkey proto=apop
-    server=x.y.com user? !password?
-</PRE></TT></DL>
-A typical client would then prompt the user for the desired
-key information, create a new key via the
-<TT>ctl</TT>
-file, and then reissue the 
-<TT>start</TT>
-request.
-If the
-<TT>needkey</TT>
-file is open,
-then instead of failing, the transaction
-will block, and the next read from the
-<TT>/mnt/factotum/needkey</TT>
-file will return a line of the form
-<DL><DT><DD><TT><PRE>
-needkey tag=1 <I>attributes</I><I>
-</PRE></TT></DL>
-The graphical interface then prompts the user for the needed
-key information, creates the key via the
-</I><TT>ctl</TT><I>
-file, and writes back
-</I><TT>tag=1</TT><I>
-to resume the transaction.
-</I><br>&#32;<br>
-The remaining files are informational and used for debugging.
-The
-<TT>proto</TT>
-file contains a list of supported protocols (to see what protocols the
-system supports,
-<TT>cat</TT>
-<TT>/mnt/factotum/proto</TT>),
-and the
-<TT>log</TT>
-file contains a log of operations and debugging output
-enabled by a
-<TT>debug</TT>
-control message.
-<br>&#32;<br>
-The next few sections explain how
-<TT>factotum</TT>
-is used by system services.
-<H4>3 Authentication in 9P
+External programs manage <TT>factotum</TT>'s internal key state through its file interface, writing textual <TT>key</TT> and <TT>delkey</TT> commands to the <TT>/mnt/factotum/ctl</TT> file. Both commands take a list of attributes as an argument. <TT>Key</TT> creates a key with the given attributes, replacing any extant key with an identical set of public attributes. <TT>Delkey</TT> deletes all keys that match the given set of attributes. Reading the <TT>ctl</TT> file returns a list of keys, one per line, displaying only public attributes. The following example illustrates these interactions.
+<pre>
+    % cd /mnt/factotum
+    % ls -l
+    -lrw------- gre gre 0 Jan 30 22:17 confirm
+    --rw------- gre gre 0 Jan 30 22:17 ctl
+    -lr-------- gre gre 0 Jan 30 22:17 log
+    -lrw------- gre gre 0 Jan 30 22:17 needkey
+    --r--r--r-- gre gre 0 Jan 30 22:17 proto
+    --rw-rw-rw- gre gre 0 Jan 30 22:17 rpc
+    % cat &gt;ctl
+    key dom=bell-labs.com proto=p9sk1 user=gre !password='don''t tell'
+    key proto=apop server=x.y.com user=gre !password='bite me'
+    ^D
+    % cat ctl
+    key dom=bell-labs.com proto=p9sk1 user=gre
+    key proto=apop server=x.y.com user=gre
+    % echo 'delkey proto=apop' &gt;ctl
+    % cat ctl
+    key dom=bell-labs.com proto=p9sk1 user=gre
+    % 
+</pre>(A file with the <TT>l</TT> bit set can be opened by only one process at a time.)<br>
+  <P>
+The heart of the interface is the <TT>rpc</TT> file. Programs authenticate with <TT>factotum</TT> by writing a request to the <TT>rpc</TT> file and reading back the reply; this sequence is called an RPC <EM>transaction</EM>. Requests and replies have the same format: a textual verb possibly followed by arguments, which may be textual or binary. The most common reply verb is <TT>ok</TT>, indicating success. An RPC session begins with a <TT>start</TT> transaction; the argument is a key query as described earlier. Once started, an RPC conversation usually consists of a sequence of <TT>read</TT> and <TT>write</TT> transactions. If the conversation is successful, an <TT>authinfo</TT> transaction will return information about the identities learned during the transaction. The <TT>attr</TT> transaction returns a list of attributes for the current conversation; the list includes any attributes given in the <TT>start</TT> query as well as any public attributes from keys being used.
+  <P>
+As an example of the <TT>rpc</TT> file in action, consider a mail client connecting to a mail server and authenticating using the POP3 protocol's APOP challenge-response command. There are four programs involved: the mail client <EM>PC</EM>, the client <TT>factotum</TT> <EM>FC</EM>, the mail server <EM>PS</EM>, and the server <TT>factotum</TT> <EM>FS</EM>. All authentication computations are handled by the <TT>factotum</TT> processes. The mail programs' role is just to relay messages.
+  <P>
+At startup, the mail server at <TT>x.y.com</TT> begins an APOP conversation with its <TT>factotum</TT> to obtain the banner greeting, which includes a challenge:<br>
+<DL><DT><DD><EM>PS->FS</EM><TT>: start proto=apop role=server<br>
+</TT><EM>FS->PS</EM><TT>: ok<br>
+</TT><EM>PS->FS</EM><TT>: read<br>
+</TT><EM>FS->PS</EM><TT>: ok +OK POP3 </TT><EM>challenge<br>
+</EM></DL>Having obtained the challenge, the server greets the client:<br>
+<DL><DT><DD><EM>PS->PC</EM><TT>: +OK POP3 </TT><EM>challenge<br>
+</EM></DL>The client then uses an APOP conversation with its <TT>factotum</TT> to obtain a response:<br>
+<DL><DT><DD><EM>PC->FC</EM><TT>: start proto=apop role=client server=x.y.com<br>
+ </TT><DT><DD><DT><DD><DL><DT><DD></DL><EM>FC->PC</EM><TT>: ok<br>
+</TT><EM>PC->FC</EM><TT>: write +OK POP3 </TT><EM>challenge<br>
+FC->PC</EM><TT>: ok<br>
+</TT><EM>PC->FC</EM><TT>: read<br>
+</TT><EM>FC->PC</EM><TT>: ok APOP gre </TT><EM>response<br>
+</EM></DL><TT>Factotum</TT> requires that <TT>start</TT> requests include a <TT>proto</TT> attribute, and the APOP module requires an additional <TT>role</TT> attribute, but the other attributes are optional and only restrict the key space. Before responding to the <TT>start</TT> transaction, the client <TT>factotum</TT> looks for a key to use for the rest of the conversation. Because of the arguments in the <TT>start</TT> request, the key must have public attributes <TT>proto=apop</TT> and <TT>server=x.y.com</TT>; as mentioned earlier, the APOP module additionally requires that the key have <TT>user</TT> and <TT>!password</TT> attributes. Now that the client has obtained a response from its <TT>factotum</TT>, it echoes that response to the server:
+<DL><DT><DD><EM>PC->PS</EM><TT>: APOP gre </TT><EM>response<br>
+</EM></DL>Similarly, the server passes this message to its <TT>factotum </TT>and obtains another to send back.<br>
+<DL><DT><DD><EM>PS->FS</EM><TT>: write APOP gre </TT><EM>response<br>
+FS->PS</EM><TT>: ok<br>
+</TT><EM>PS->FS</EM><TT>: read<br>
+</TT><EM>FS->PS</EM><TT>: ok +OK welcome<br>
+</TT><EM>PS->PC</EM><TT>: +OK welcome<br>
+</TT></DL>Now the authentication protocol is done, and the server can retrieve information about what the protocol established.<br>
+<DL><DT><DD><EM>PS->FS</EM><TT>: authinfo<br>
+</TT><EM>FS->PS</EM><TT>: ok client=gre <TT>capability=</TT><EM>capability
+</EM><br>
+</TT></DL>The <TT>authinfo</TT> data is a list of <EM>attr</EM><TT>=</TT><EM>value </EM>pairs, here a client user name and a capability. (Protocols that establish shared secrets or provide mutual authentication indicate this by adding appropriate <EM>attr</EM><TT>=</TT><EM>value </EM>pairs.) The capability can be used by the server to change its identity to that of the client, as described earlier. Once it has changed its identity, the server can access and serve the client's mailbox.
+  <P>
+Two more files provide hooks for a graphical <TT>factotum</TT> control interface. The first, <TT>confirm</TT>, allows the user detailed control over the use of certain keys. If a key has a <TT>confirm=</TT> attribute, then the user must approve each use of the key. A separate program with a graphical interface reads from the <TT>confirm</TT> file to see when a confirmation is necessary. The read blocks until a key usage needs to be approved, whereupon it will return a line of the form
+<DL><DT><DD><TT>confirm tag=1</TT> <EM>attributes<br>
+</EM></DL>requesting permission to use the key with those public attributes. The graphical interface then prompts the user for approval and writes back<br>
+<DL><DT><DD><TT>tag=1 answer=yes<br>
+</TT></DL>(or <TT>answer=no</TT>).<br>
+  <P>
+The second file, <TT>needkey</TT>, diverts key requests. In the APOP example, if a suitable key had not been found during the <TT>start</TT> transaction, <TT>factotum</TT> would have indicated failure by returning a response indicating what key was needed:
+<pre>
+    <EM>FC->PC</EM>: needkey proto=apop server=x.y.com user? !password?
+</pre>
+A typical client would then prompt the user for the desired key information, create a new key via the <TT>ctl</TT> file, and then reissue the <TT>start</TT> request. If the <TT>needkey</TT> file is open, then instead of failing, the transaction will block, and the next read from the <TT>/mnt/factotum/needkey</TT> file will return a line of the form
+<DL><DT><DD><TT>needkey tag=1</TT> <EM>attributes<br>
+</EM></DL>The graphical interface then prompts the user for the needed key information, creates the key via the <TT>ctl</TT> file, and writes back <TT>tag=1</TT> to resume the transaction.<br>
+  <P>
+The remaining files are informational and used for debugging. The <TT>proto</TT> file contains a list of supported protocols (to see what protocols the system supports, <TT>cat /mnt/factotum/proto</TT>), and the <TT>log</TT> file contains a log of operations and debugging output enabled by a <TT>debug</TT> control message.
+  <P>
+The next few sections explain how <TT>factotum</TT> is used by system services.<br>
+<H4>3. Authentication in 9P
 </H4>
-<br>&#32;<br>
-Plan 9 uses a remote file access protocol, 9P [Pike93],
-to connect to resources such as the
-file server and remote processes.
-The original design for 9P included special messages at the start of a conversation
-to authenticate the user.
-Multiple users can share a single connection, such as when a CPU server
-runs processes for many users connected to a single file server,
-but each must authenticate separately.
-The authentication protocol, similar to that of Kerberos [Stei88],
-used a sequence of messages passed between client, file server, and authentication
-server to verify the identities of the user, calling machine, and serving machine.
-One major drawback to the design was that the authentication method was defined by 9P
-itself and could not be changed.  
-Moreover, there was no mechanism to relegate
-authentication to an external (trusted) agent,
-so a process implementing 9P needed, besides support for file service,
-a substantial body of cryptographic code to implement a handful of early messages
-in the protocol.
-<br>&#32;<br>
-A recent redesign of 9P
-addressed a number of file service issues outside the scope of this paper.
-On issues of authentication, there were two goals:
-first, to remove details about authentication from the
-protocol itself; second, to allow an external program to execute the authentication
-part of the protocol.
-In particular, we wanted a way to quickly incorporate
-ideas found in other systems such as SFS
-[Mazi99].
-<br>&#32;<br>
-Since 9P is a file service protocol, the solution involved creating a new type of file
-to be served: an
-<I>authentication</I>
-<I>file</I>.
-When a new user connects to a 9P service, the connection has the
-permissions of
-`<TT>none</TT>',
-a state that
-allows no general file access but permits the user to open an authentication file
-by sending a special message, generated by the new
-<TT>fauth</TT>
-system call:
-<DL><DT><DD><TT><PRE>
-afd = fauth(int fd, char *servicename);
-</PRE></TT></DL>
-Here
-<TT>fd</TT>
-is the user's file descriptor for the established network connection to the 9P server
-and
-<TT>servicename</TT>
-is the name of the desired service offered on that server, for example the file subsystem
-to be accessed.
-The returned file descriptor,
-<TT>afd</TT>,
-is a unique handle representing the authentication file
-created for this connection to authenticate to
-this service; it is analogous to a capability.
-The authentication file represented by
-<TT>afd</TT>
-is not otherwise addressable on the server, such as through
-the file name hierarchy.
-Otherwise, it behaves like a regular file;
-most important, it accepts standard read and write operations.
-<br>&#32;<br>
-To prove its identity, the user process (via
-<TT>factotum</TT>)
-executes the authentication protocol,
-described in the next section of this paper,
-over the
-<TT>afd</TT>
-file descriptor with ordinary reads and writes.
-When client and server have successfully negotiated, the authentication file
-changes state so it can be used as evidence of authority in
-<TT>mount</TT>.
-<br>&#32;<br>
-Once identity is established, the process presents the (now verified)
-<TT>afd</TT>
-as proof of identity to the
-<TT>mount</TT>
-system call:
-<DL><DT><DD><TT><PRE>
-mount(int fd, int afd, char *mountpoint,
-      int flag, char *servicename)
-</PRE></TT></DL>
-If the
-<TT>mount</TT>
-succeeds, the user now
-has appropriate permissions for the file hierarchy made
-visible at the mount point.
-<br>&#32;<br>
-This sequence of events has several advantages.
-First, the actual authentication protocol is implemented using regular reads and writes,
-not special 9P messages, so
-they can be processed, forwarded, proxied, and so on by
-any 9P agent without special arrangement.
-Second, the business of negotiating the authentication by reading and writing the
-authentication file can be delegated to an outside agent, in particular
-<TT>factotum</TT>;
-the programs that implement the client and server ends of a 9P conversation need
-no authentication or cryptographic code.
-Third,
-since the authentication protocol is not defined by 9P itself, it is easy to change and
-can even be negotiated dynamically.
-Finally, since
-<TT>afd</TT>
-acts like a capability, it can be treated like one:
-handed to another process to give it special permissions;
-kept around for later use when authentication is again required;
-or closed to make sure no other process can use it.
-<br>&#32;<br>
-All these advantages stem from moving the authentication negotiation into
-reads and writes on a separate file.
-As is often the case in Plan 9,
-making a resource (here authentication) accessible with a file-like interface
-reduces
-<I>a</I>
-<I>priori</I>
-the need for special interfaces.
-<br>&#32;<br>
-<H4>3.1 Plan 9 shared key protocol
+Plan 9 uses a remote file access protocol, 9P [Pike93], to connect to resources such as the file server and remote processes. The original design for 9P included special messages at the start of a conversation to authenticate the user. Multiple users can share a single connection, such as when a CPU server runs processes for many users connected to a single file server, but each must authenticate separately. The authentication protocol, similar to that of Kerberos [Stei88], used a sequence of messages passed between client, file server, and authentication server to verify the identities of the user, calling machine, and serving machine. One major drawback to the design was that the authentication method was defined by 9P itself and could not be changed. Moreover, there was no mechanism to relegate authentication to an external (trusted) agent, so a process implementing 9P needed, besides support for file service, a substantial body of cryptographic code to implement a handful of startup messages in the protocol.
+  <P>
+A recent redesign of 9P addressed a number of file service issues outside the scope of this paper. On issues of authentication, there were two goals: first, to remove details about authentication from the protocol itself; second, to allow an external program to execute the authentication part of the protocol. In particular, we wanted a way to quickly incorporate ideas found in other systems such as SFS [Mazi99].
+  <P>
+Since 9P is a file service protocol, the solution involved creating a new type of file to be served: an <EM>authentication file</EM>. Connections to a 9P service begin in a state that
+allows no general file access but permits the client
+to open an authentication file by sending a special message, generated by the new <TT>fauth </TT>system call:
+<DL><DT><DD><TT>afd = fauth(int fd, char *servicename);<br>
+</TT></DL>Here <TT>fd</TT> is the user's file descriptor for the established network connection to the 9P server and <TT>servicename</TT> is the name of the desired service offered on that server, typically the file subsystem to be accessed. The returned file descriptor, <TT>afd</TT>, is a unique handle representing the authentication file created for this connection to authenticate to this service; it is analogous to a capability. The authentication file represented by <TT>afd</TT> is not otherwise addressable on the server, such as through the file name hierarchy. In all other respects, it behaves like a regular file; most important, it accepts standard read and write operations.
+  <P>
+To prove its identity, the user process (via <TT>factotum</TT>) executes the authentication protocol, described in the next section of this paper, over the <TT>afd</TT> file descriptor with ordinary reads and writes. When client and server have successfully negotiated, the authentication file changes state so it can be used as evidence of authority in <TT>mount</TT>.
+  <P>
+Once identity is established, the process presents the (now verified) <TT>afd</TT> as proof of identity to the <TT>mount</TT> system call:
+<pre>
+    mount(int fd, int afd, char *mountpoint,
+        int flag, char *servicename)
+</pre>
+succeeds, the user now has appropriate permissions for the file hierarchy made visible at the mount point.<br>
+  <P>
+This sequence of events has several advantages. First, the actual authentication protocol is implemented using regular reads and writes, not special 9P messages, so they can be processed, forwarded, proxied, and so on by any 9P agent without special arrangement. Second, the business of negotiating the authentication by reading and writing the authentication file can be delegated to an outside agent, in particular <TT>factotum</TT>; the programs that implement the client and server ends of a 9P conversation need no authentication or cryptographic code. Third, since the authentication protocol is not defined by 9P itself, it is easy to change and can even be negotiated dynamically. Finally, since <TT>afd</TT> acts like a capability, it can be treated like one: handed to another process to give it special permissions; kept around for later use when authentication is again required; or closed to make sure no other process can use it.
+  <P>
+All these advantages stem from moving the authentication negotiation into reads and writes on a separate file. As is often the case in Plan 9, making a resource (here authentication) accessible with a file-like interface reduces <EM>a priori </EM>the need for special interfaces.<br>
+  <P>
+<H4>3.1. Plan 9 shared key protocol
 </H4>
-<br>&#32;<br>
-In addition to the various standard protocols supported by
-<TT>factotum</TT>,
-we use a shared key protocol for native
-Plan 9 authentication.
-This protocol provides backward compatibility with
-older versions of the system.  One reason for the new
-architecture is to let us replace such protocols
-in the near future with more cryptographically secure ones.
-<br>&#32;<br>
-<I>P9sk1</I>
-is a shared key protocol that uses tickets much like those
-in the original Kerberos.
-The difference is that we've
-replaced the expiration time in Kerberos tickets with
-a random nonce parameter and a counter.
-We summarize it here:
-<DL><DT><DD><TT><PRE>
-<I>C</I>-&gt;<I>S</I>:  <I>nonce</I><I>C</I>
-<I>S</I>-&gt;<I>C</I>:  <I>nonce</I><I>S</I>,<I>uid</I><I>S</I>,<I>domain</I><I>S</I>
+In addition to the various standard protocols supported by <TT>factotum</TT>, we use a shared key protocol for native Plan 9 authentication. This protocol provides backward compatibility with older versions of the system. One reason for the new architecture is to let us replace such protocols in the near future with more cryptographically secure ones.
+  <P>
+<EM>P9sk1</EM> is a shared key protocol that uses tickets much like those in the original Kerberos. The difference is that we've replaced the expiration time in Kerberos tickets with a random nonce parameter and a counter. We summarize it here:
+<pre>
+    <EM>C->S</EM>:      <EM>nonceC</EM>
+    <EM>S->C</EM>:      <EM>nonceS</EM>,<EM>uidS</EM>,<EM>domainS</EM>
 
-<I>C</I>-&gt;<I>A</I>:  <I>nonce</I><I>S</I>,<I>uid</I><I>S</I>,<I>domain</I><I>S</I>,<I>uid</I><I>C</I>,
-         <I>factotum</I><I>C</I>
-<I>A</I>-&gt;<I>C</I>:  <I>K</I><I>C</I>{<I>nonce</I><I>S</I>,<I>uid</I><I>C</I>,<I>uid</I><I>S</I>,<I>K</I><I>n</I>},
-         <I>K</I><I>S</I>{<I>nonce</I><I>S</I>,<I>uid</I><I>C</I>,<I>uid</I><I>S</I>,<I>K</I><I>n</I>}
+    <EM>C->A</EM>:      <EM>nonceS</EM>,<EM>uidS</EM>,<EM>domainS</EM>,<EM>uidC</EM>,<EM>factotumC</EM>
+    <EM>A->C</EM>:      <EM>KC</EM>{<EM>nonceS</EM>,<EM>uidC</EM>,<EM>uidS</EM>,<EM>Kn</EM>},
+                 <EM>KS</EM>{<EM>nonceS</EM>,<EM>uidC</EM>,<EM>uidS</EM>,<EM>Kn</EM>}
 
-<I>C</I>-&gt;<I>S</I>:  <I>K</I><I>S</I>{<I>nonce</I><I>S</I>,<I>uid</I><I>C</I>,<I>uid</I><I>S</I>,<I>K</I><I>n</I>},
-         <I>K</I><I>n</I>{<I>nonce</I><I>S</I>,<I>counter</I>}
-<I>S</I>-&gt;<I>C</I>:  <I>K</I><I>n</I>{<I>nonce</I><I>C</I>,<I>counter</I>}
-</PRE></TT></DL>
-(Here <I>K</I>{<I>x</I>} indicates <I>x</I> encrypted with
-DES key <I>K</I>.)
-The first two messages exchange nonces and server identification.
-After this initial exchange, the client contacts the authentication
-server to obtain a pair of encrypted tickets, one encrypted with
-the client key and one with the server key.
-The client relays the server ticket to the server.
-The server believes that the ticket is new
-because it contains
-<I>nonce</I><I>S</I>
-and that the ticket is from the authentication
-server because it is encrypted in the server key <I>K</I><I>S</I>.
-The ticket is basically a statement from the authentication
-server that now <I>uid</I><I>C</I> and <I>uid</I><I>S</I> share a
-secret <I>K</I><I>n</I>.
-The authenticator <I>K</I><I>n</I>{<I>nonce</I><I>S</I>,<I>counter</I>}
-convinces the server that the client knows <I>K</I><I>n</I> and thus
-must be <I>uid</I><I>C</I>.
-Similarly, the authenticator <I>K</I><I>n</I>{<I>nonce</I><I>C</I>,<I>counter</I>}
-convinces the client that the server knows <I>K</I><I>n</I> and thus
-must be <I>uid</I><I>S</I>.
-Tickets can be reused, without contacting the authentication
-server again, by incrementing the counter before each
-authenticator is generated.
-<br>&#32;<br>
-In the future we hope to introduce a public key version of
-p9sk1,
-which would allow authentication even
-when the authentication server is not available.
-<H4>3.2 The authentication server
+    <EM>C->S</EM>:      <EM>KS</EM>{<EM>nonceS</EM>,<EM>uidC</EM>,<EM>uidS</EM>,<EM>Kn</EM>},
+                 <EM>Kn</EM>{<EM>nonceS</EM>,<EM>counter</EM>}
+    <EM>S->C</EM>:      <EM>Kn</EM>{<EM>nonceC</EM>,<EM>counter</EM>}
+</pre>
+(Here <EM>K</EM>{<EM>x</EM>} indicates <EM>x </EM>encrypted with DES key <EM>K</EM>.) The first two messages exchange nonces and server identification. After this initial exchange, the client contacts the authentication server to obtain a pair of encrypted tickets, one encrypted with the client key and one with the server key. The client relays the server ticket to the server. The server believes that the ticket is new because it contains <EM>nonceS </EM>and that the ticket is from the authentication server because it is encrypted in the server key <EM>KS</EM>. The ticket is basically a statement from the authentication server that now <EM>uidC </EM>and <EM>uidS </EM>share a secret <EM>Kn</EM>. The authenticator <EM>Kn</EM>{<EM>nonceS</EM>,<EM>counter</EM>} convinces the server that the client knows <EM>Kn </EM>and thus must be <EM>uidC</EM>. Similarly, authenticator <EM>Kn</EM>{<EM>nonceC</EM>,<EM>counter</EM>} convinces the client that the server knows <EM>Kn </EM>and thus must be <EM>uidS</EM>. Tickets can be reused, without contacting the authentication server again, by incrementing the counter before each authenticator is generated.
+  <P>
+In the future we hope to introduce a public key version of p9sk1, which would allow authentication even when the authentication server is not available.<br>
+<H4>3.2. The authentication server
 </H4>
-<br>&#32;<br>
-Each Plan 9 security domain has an authentication server (AS)
-that all users trust to keep the complete set of shared keys.
-It also offers services for users and administrators to manage the
-keys, create and disable accounts, and so on.
-It typically runs on
-a standalone machine with few other services.
-The AS comprises two services,
-<TT>keyfs</TT>
-and
-<TT>authsrv</TT>.
-<br>&#32;<br>
-<TT>Keyfs</TT>
-is a user-level file system that manages an
-encrypted data base of user accounts.
-Each account is represented by a directory containing the
-files
-<TT>key</TT>,
-containing the Plan 9 key for p9sk1;
-<TT>secret</TT>
-for the challenge/response protocols (APOP, VNC, CHAP, MSCHAP,
-CRAM);
-<TT>log</TT>
-for authentication outcomes;
-<TT>expire</TT>
-for an expiration time; and
-<TT>status</TT>.
-If the expiration time passes,
-if the number of successive failed authentications
-exceeds 50, or if
-<TT>disabled</TT>
-is written to the status file,
-any attempt to access the
-<TT>key</TT>
-or
-<TT>secret</TT>
-files will fail.
-<br>&#32;<br>
-<TT>Authsrv</TT>
-is a network service that brokers shared key authentications
-for the protocols p9sk1, APOP, VNC, CHAP, MSCHAP,
-and CRAM.  Remote users can also call
-<TT>authsrv</TT>
-to change their passwords.
-<br>&#32;<br>
-The
-p9sk1
-protocol was described in the previous
-section.
-The challenge/response protocols differ
-in detail but all follow the general structure:
-<DL><DT><DD><TT><PRE>
-<I>C</I>-&gt;<I>S</I>:  <I>uid</I><I>C</I>
-<I>S</I>-&gt;<I>A</I>:  <I>nonce</I><I>S</I>,<I>uid</I><I>S</I>,<I>domain</I><I>S</I>,<I>uid</I><I>C</I>,
-         <I>factotum</I><I>S</I>
-<I>A</I>-&gt;<I>S</I>:  <I>challenge</I>
-<I>S</I>-&gt;<I>C</I>:  <I>challenge</I>
-<I>C</I>-&gt;<I>S</I>:  <I>response</I>
-<I>S</I>-&gt;<I>A</I>:  <I>response</I>
-<I>A</I>-&gt;<I>S</I>:  <I>K</I><I>C</I>{<I>nonce</I><I>S</I>,<I>uid</I><I>C</I>,<I>uid</I><I>S</I>,<I>K</I><I>n</I>},
-         <I>K</I><I>n</I>{<I>nonce</I><I>C</I>}
-</PRE></TT></DL>
+Each Plan 9 security domain has an authentication server (AS) that all users trust to keep the complete set of shared keys. It also offers services for users and administrators to manage the keys, create and disable accounts, and so on. It typically runs on a standalone machine with few other services. The AS comprises two services, <TT>keyfs</TT> and <TT>authsrv</TT>.
+  <P>
+<TT>Keyfs</TT> is a user-level file system that manages an encrypted database of user accounts. Each account is represented by a directory containing the files <TT>key</TT>, containing the Plan 9 key for p9sk1; <TT>secret</TT> for the challenge/response protocols (APOP, VNC, CHAP, MSCHAP, CRAM); <TT>log</TT> for authentication outcomes; <TT>expire</TT> for an expiration time; and <TT>status</TT>. If the expiration time passes, if the number of successive failed authentications exceeds 50, or if <TT>disabled</TT> is written to the status file, any attempt to access the <TT>key</TT> or <TT>secret</TT> files will fail.
+  <P>
+<TT>Authsrv</TT> is a network service that brokers shared key authentications for the protocols p9sk1, APOP, VNC, CHAP, MSCHAP, and CRAM. Remote users can also call <TT>authsrv</TT> to change their passwords.<br>
+  <P>
+The p9sk1 protocol was described in the previous section. The challenge/response protocols differ in detail but all follow the general structure:
+<pre>
+    <EM>C->S</EM>:      <EM>nonceC</EM>
+    <EM>S->C</EM>:      <EM>nonceS</EM>,<EM>uidS</EM>,<EM>domainS</EM>
+    <EM>C->A</EM>:      <EM>nonceS</EM>,<EM>uidS</EM>,<EM>domainS</EM>, <EM>hostidC</EM>,<EM>uidC</EM>
+    <EM>A->C</EM>:      <EM>KC</EM>{<EM>nonceS</EM>,<EM>uidC</EM>,<EM>uidS</EM>,<EM>Kn</EM>},
+                  <EM>KS</EM>{<EM>nonceS</EM>,<EM>uidC</EM>,<EM>uidS</EM>,<EM>Kn</EM>}
+    <EM>C->S</EM>:      <EM>KS</EM>{<EM>nonceS</EM>,<EM>uidC</EM>,<EM>uidS</EM>,<EM>Kn</EM>}, <EM>Kn</EM>{<EM>nonceS</EM>}
+    <EM>S->C</EM>:      <EM>Kn</EM>{<EM>nonceC</EM>}
+</pre>
 The password protocol is:
-<DL><DT><DD><TT><PRE>
-<I>C</I>-&gt;<I>A</I>:  <I>uid</I><I>C</I>
-<I>A</I>-&gt;<I>C</I>:  <I>K</I><I>c</I>{<I>K</I><I>n</I>}
-<I>C</I>-&gt;<I>A</I>:  <I>K</I><I>n</I>{<I>password</I><I>old</I>,<I>password</I><I>new</I>}
-<I>A</I>-&gt;<I>C</I>:  <I>OK</I>
-</PRE></TT></DL>
-To avoid replay attacks, the pre-encryption
-clear text for each of the protocols (as well as for p9sk1) includes
-a tag indicating the encryption's role in the
-protocol.  We elided them in these outlines.
-<H4>3.3 Protocol negotiation
+<pre>
+    <EM>C->A</EM>:      <EM>uidC</EM>
+    <EM>A->C</EM>:      <EM>Kc</EM>{<EM>Kn</EM>}
+    <EM>C->A</EM>:      <EM>Kn</EM>{<EM>passwordold</EM>,<EM>passwordnew</EM>}
+    <EM>A->C</EM>:      <EM>OK</EM>
+</pre>To avoid replay attacks, the pre-encryption clear text for each of the protocols (as well as for p9sk1) includes a tag indicating the encryption's role in the protocol. We elided them in these outlines.<br>
+<H4>3.3. Protocol negotiation
+</H4> 
+Rather than require particular protocols for particular services, we implemented a negotiation metaprotocol, <EM>p9any</EM>, which chooses the actual authentication protocol to use. P9any is used now by all native services on Plan 9.<br>
+  <P>
+The metaprotocol is simple. The callee sends a null-terminated string of the form:<br>
+<DL><DT><DD><TT>v</TT><EM>n proto</EM>1<TT>@</TT><EM>domain</EM>1 <EM>proto</EM>2<TT>@</TT><EM>domain</EM>2 <TT>...<br>
+</TT></DL>where <EM>n </EM>is a decimal version number, <EM>protok </EM>is the name of a protocol for which the <TT>factotum</TT> has a key, and <EM>domaink </EM>is the name of the domain in which the key is valid. The caller then responds<br>
+<DL><DT><DD><EM>proto</EM><TT>@</TT><EM>domain<br>
+</EM></DL>indicating its choice. Finally the callee responds<br>
+<DL><DT><DD><TT>OK<br>
+</TT></DL>Any other string indicates failure. At this point the chosen protocol commences. The final fixed-length reply is used to make it easy to delimit the I/O stream should the chosen protocol require the caller rather than the callee to send the first message.<br>
+  <P>
+With this negotiation metaprotocol, the underlying authentication protocols used for Plan 9 services can be changed under any application just by changing the keys known by the <TT>factotum</TT> agents at each end.<br>
+  <P>
+P9any is vulnerable to man in the middle attacks to the extent that the attacker may constrain the possible choices by changing the stream. However, we believe this is acceptable since the attacker cannot force either side to choose algorithms that it is unwilling to use.
+<H4>4. Library Interface to Factotum
+</H4> 
+Although programs can access <TT>factotum</TT>'s services through its file system interface, it is more common to use a C library that packages the interaction. There are a number of routines in the library, not all of which are relevant here, but a few examples should give their flavor.
+  <P>
+First, consider the problem of mounting a remote file server using 9P. An earlier discussion showed how the <TT>fauth</TT> and <TT>mount</TT> system calls use an authentication file, <TT>afd</TT>, as a capability, but not how <TT>factotum</TT> manages <TT>afd</TT>. The library contains a routine, <TT>amount</TT> (authenticated mount), that is used by most programs in preference to the raw <TT>fauth</TT> and <TT>mount</TT> calls. <TT>Amount</TT> engages <TT>factotum</TT> to validate <TT>afd</TT>; here is the complete code:
+<pre>
+    int
+    amount(int fd, char *mntpt, int flags, char *aname)
+    {
+        int afd, ret;
+        AuthInfo *ai;
+        afd = fauth(fd, aname);
+        if(afd &gt;= 0){
+             ai = auth_proxy(afd, amount_getkey,
+              &quot;proto=p9any role=client&quot;);
+            if(ai != NULL)
+              auth_freeAI(ai);
+        }
+        ret = mount(fd, afd, mntpt,flags, aname);
+        if(afd &gt;= 0)
+            close(afd);
+        return ret;
+    }
+</pre>
+where parameter <TT>fd</TT> is a file descriptor returned by <TT>open</TT> or <TT>dial</TT> for a new connection to a file server. The conversation with <TT>factotum</TT> occurs in the call to <TT>auth_proxy</TT>, which specifies, as a key query, which authentication protocol to use (here the metaprotocol <TT>p9any</TT>) and the role being played (<TT>client</TT>). <TT>Auth_proxy</TT> will read and write the <TT>factotum</TT> files, and the authentication file descriptor <TT>afd</TT>, to validate the user's right to access the service. If the call is successful, any auxiliary data, held in an <TT>AuthInfo</TT> structure, is freed. In any case, the <TT>mount</TT> is then called with the (perhaps validated) <TT>afd.</TT> A 9P server can cause the <TT>fauth</TT> system call to fail, as an indication that authentication is not required to access the service.
+  <P>
+The second argument to <TT>auth_proxy</TT> is a function, here <TT>amount_getkey</TT>, to be called if secret information such as a password or response to a challenge is required as part of the authentication. This function, of course, will provide this data to <TT>factotum</TT> as a <TT>key</TT> message on the <TT>/mnt/factotum/ctl</TT> file.
+  <P>
+Although the final argument to <TT>auth_proxy</TT> in this example is a simple string, in general it can be a formatted-print specifier in the manner of <TT>printf</TT>, to enable the construction of more elaborate key queries.<br>
+  <P>
+As another example, consider the Plan 9 <TT>cpu</TT> service, which exports local devices to a shell process on a remote machine, typically to connect the local screen and keyboard to a more powerful computer. At heart, <TT>cpu</TT> is a superset of a service called <TT>exportfs</TT> [Pike93], which allows one machine to see an arbitrary portion of the file name space of another machine, such as to export the network device to another machine for gatewaying. However, <TT>cpu</TT> is not just <TT>exportfs</TT> because it also delivers signals such as interrupt and negotiates the initial environment for the remote shell.
+  <P>
+To authenticate an instance of <TT>cpu</TT> requires <TT>factotum</TT> processes on both ends: the local, client end running as the user on a terminal and the remote, server end running as the host owner of the server machine. Here is schematic code for the two ends:
+<pre>
+    /* client */
+    int
+    p9auth(int fd)
+    {
+        AuthInfo *ai;
+        ai = auth_proxy(fd, auth_getkey, &quot;proto=p9any role=client&quot;);
+        if(ai == NULL)
+            return -1;
+        /* start cpu protocol here */
+    }
+    /* server */
+    int
+    srvp9auth(int fd, char *user)
+    {
+        AuthInfo *ai;
+        ai = auth_proxy(fd, NULL, &quot;proto=p9any role=server&quot;);
+        if(ai == NULL)
+            return -1;
+        /* set user id for server process */
+        if(auth_chuid(ai, NULL) &lt; 0)
+            return -1;
+        /* start cpu protocol here */
+    }
+</pre>
+Auth_chuid</TT> encapsulates the negotiation to change a user id using the <TT>caphash</TT> and <TT>capuse</TT> files of the (server) kernel. Note that although the client process may ask the user for new keys, using <TT>auth_getkey</TT>, the server machine, presumably a shared machine with a pseudo-user for the host owner, sets the key-getting function to <TT>NULL</TT>.
+<H4>5. Secure Store
 </H4>
-<br>&#32;<br>
-Rather than require particular protocols for particular services,
-we implemented a negotiation metaprotocol,
-<I>p9any</I>,
-which chooses the actual authentication protocol to use.
-P9any
-is used now by all native services on Plan 9.
-<br>&#32;<br>
-The metaprotocol is simple.  The callee sends a
-null-terminated string of the form:
-<DL><DT><DD><TT><PRE>
-v<I></I><I>n</I> <I>proto</I>1@<I>domain</I>1 <I>proto</I>2@<I>domain</I>2 ...
-</PRE></TT></DL>
-where
-<I>n</I>
-is a decimal version number, <I>proto</I><I>k</I>
-is the name of a protocol for which the
-<TT>factotum</TT>
-has a key, and <I>domain</I><I>k</I>
-is the name of the domain in which the key is
-valid.
-The caller then responds
-<DL><DT><DD><TT><PRE>
-<I>proto</I>@<I>domain</I>
-</PRE></TT></DL>
-indicating its choice.
-Finally the callee responds
-<DL><DT><DD><TT><PRE>
-OK
-</PRE></TT></DL>
-Any other string indicates failure.
-At this point the chosen protocol commences.
-The final fixed-length reply is used to make it easy to
-delimit the I/O stream should the chosen protocol
-require the caller rather than the callee to send the first message.
-<br>&#32;<br>
-With this negotiation metaprotocol, the underlying
-authentication protocols used for Plan 9 services
-can be changed under any application just
-by changing the keys known by the
-<TT>factotum</TT>
-agents at each end.
-<br>&#32;<br>
-P9any is vulnerable to man in the middle attacks
-to the extent that the attacker may constrain the
-possible choices by changing the stream.  However,
-we believe this is acceptable since the attacker
-cannot force either side to choose algorithms
-that it is unwilling to use.
-<H4>4 Library Interface to Factotum
+<TT>Factotum</TT> keeps its keys in volatile memory, which must somehow be
+initialized at boot time.
+Therefore,
+<TT>factotum</TT> must be supplemented by a persistent store, perhaps a floppy disk containing a key file of commands to be copied into <TT>/mnt/factotum/ctl</TT> during bootstrap. But removable media are a nuisance to carry and are vulnerable to theft. Keys could be stored encrypted on a shared file system, but only if those keys are not necessary for authenticating to the file system in the first place. Even if the keys are encrypted under a user password, a thief might well succeed with a dictionary attack. Other risks of local storage are loss of the contents through mechanical mishap or dead batteries. Thus for convenience and safety we provide a <TT>secstore</TT> (secure store) server in the network to hold each user's permanent list of keys, a <EM>key file</EM>.
+  <P>
+<TT>Secstore</TT> is a file server for encrypted data, used only during bootstrapping. It must provide strong authentication and resistance to passive and active protocol attacks while assuming nothing more from the client than a password. Once <TT>factotum</TT> has loaded the key file, further encrypted or authenticated file storage can be accomplished by standard mechanisms.
+  <P>
+The cryptographic technology that enables <TT>secstore</TT> is a form of encrypted key exchange called PAK [Boyk00], analogous to EKE [Bell93], SRP [Wu98], or SPEKE [Jabl]. PAK was chosen because it comes with a proof of equivalence in strength to Diffie-Hellman; subtle flaws in some earlier encrypted key exchange protocols and implementations have encouraged us to take special care. In outline, the PAK protocol is:
+<DL><DT><DD><EM>C->S</EM>: <EM>C</EM>,<EM>gxH<br>
+S->C</EM>: <EM>S</EM>,<EM>gy</EM>,<EM>hash</EM>(<EM>gxy</EM>,<EM>C</EM>,<EM>S</EM>)<br>
+<EM>C->S</EM>: <EM>hash</EM>(<EM>gxy</EM>,<EM>S</EM>,<EM>C</EM>)<br>
+</DL>where <EM>H </EM>is a preshared secret between client <EM>C </EM>and server <EM>S</EM>. There are several variants of PAK, all presented in papers mainly concerned with proofs of cryptographic properties. To aid implementers, we have distilled a description of the specific version we use into an Appendix to this paper. The Plan 9 open source license provides for use of Lucent's encrypted key exchange patents in this context.
+  <P>
+As a further layer of defense against password theft, we provide (within the encrypted channel <EM>C->S</EM>) information that is validated at a RADIUS server, such as the digits from a hardware token [RFC2138]. This provides two-factor authentication, which potentially requires tricking two independent administrators in any attack by social engineering.
+  <P>
+The key file stored on the server is encrypted with AES (Rijndael) using CBC with a 10-byte initialization vector and trailing authentication padding. All this is invisible to the user of <TT>secstore</TT>. For that matter, it is invisible to the <TT>secstore</TT> server as well; if the AES Modes of Operation are standardized and a new encryption format designed, it can be implemented by a client without change to the server. The <TT>secstore</TT> is deliberately not backed up; the user is expected to use more than one <TT>secstore</TT> or save the key file on removable media and lock it away. The user's password is hashed to create the <EM>H </EM>used in the PAK protocol; a different hash of the password is used as the file encryption key. Finally, there is a command (inside the authenticated, encrypted channel between client and <TT>secstore</TT>) to change passwords by sending a new <EM>H</EM>; for consistency, the client process must at the same time fetch and re-encrypt all files.
+  <P>
+When <TT>factotum</TT> starts, it dials the local <TT>secstore</TT> and checks whether the user has an account. If so, it prompts for the user's <TT>secstore</TT> password and fetches the key file. The PAK protocol ensures mutual authentication and prevents dictionary attacks on the password by passive wiretappers or active intermediaries. Passwords saved in the key file can be long random strings suitable for simpler challenge/response authentication protocols. Thus the user need only remember a single, weaker password to enable strong, ``single sign on'' authentication to unchanged legacy applications scattered across multiple authentication domains.
+<H4>6. Transport Layer Security
 </H4>
-<br>&#32;<br>
-Although programs can access
-<TT>factotum</TT>'s
-services through its file system interface,
-it is more common to use a C library that
-packages the interaction.
-There are a number of routines in the library,
-not all of which are relevant here, but a few
-examples should give their flavor.
-<br>&#32;<br>
-First, consider the problem of mounting a remote file server using 9P.
-An earlier discussion showed how the
-<TT>fauth</TT>
-and
-<TT>mount</TT>
-system calls use an authentication file,
-<TT>afd</TT>,
-as a capability,
-but not how
-<TT>factotum</TT>
-manages
-<TT>afd</TT>.
-The library contains a routine,
-<TT>amount</TT>
-(authenticated mount), that is used by most programs in preference to
-the raw
-<TT>fauth</TT>
-and
-<TT>mount</TT>
-calls.
-<TT>Amount</TT>
-engages
-<TT>factotum</TT>
-to validate
-<TT>afd</TT>;
-here is the complete code:
-<DL><DT><DD><TT><PRE>
-int
-amount(int fd, char *mntpt,
-	int flags, char *aname)
-{
-	int afd, ret;
-	AuthInfo *ai;
-
-	afd = fauth(fd, aname);
-	if(afd &gt;= 0){
-		ai = auth_proxy(afd, amount_getkey,
-			"proto=p9any role=client");
-		if(ai != NULL)
-			auth_freeAI(ai);
-	}
-	ret = mount(fd, afd, mntpt,
-		flags, aname);
-	if(afd &gt;= 0)
-		close(afd);
-	return ret;
-}
-</PRE></TT></DL>
-The conversation with
-<TT>factotum</TT>
-occurs in the call to
-<TT>auth_proxy</TT>,
-which specifies, as a key query,
-which authentication protocol to use
-(here the metaprotocol
-<TT>p9any</TT>)
-and the role being played
-(<TT>client</TT>).
-<TT>Auth_proxy</TT>
-will read and write the
-<TT>factotum</TT>
-files, and the authentication file descriptor
-<TT>afd</TT>,
-to validate the user's right to access the service.
-If the call is successful, any auxiliary data, held in an
-<TT>AuthInfo</TT>
-structure, is freed.
-In any case, the
-<TT>mount</TT>
-is then called with the (perhaps validated)
-<TT>afd.</TT>
-A 9P server can cause the
-<TT>fauth</TT>
-system call to fail, as an indication that authentication is
-not required to access the service.
-<br>&#32;<br>
-The second argument to
-<TT>auth_proxy</TT>
-is a function, here
-<TT>amount_getkey</TT>,
-to be called if secret information such as a password or
-response to a challenge is required as part of the authentication.
-This function, of course, will provide this data to
-<TT>factotum</TT>
-as a
-<TT>key</TT>
-message on the
-<TT>/mnt/factotum/ctl</TT>
-file.
-<br>&#32;<br>
-Although the final argument to
-<TT>auth_proxy</TT>
-in this example is a simple string, in general
-it can be a formatted-print specifier in the manner of
-<TT>printf</TT>,
-to enable the construction of more elaborate key queries.
-<br>&#32;<br>
-As another example, consider the Plan 9
-<TT>cpu</TT>
-service, which exports local devices to a shell process on
-a remote machine, typically
-to connect the local screen and keyboard to a more powerful computer.
-At heart,
-<TT>cpu</TT>
-is a superset of a service called
-<TT>exportfs</TT>
-[Pike93],
-which allows one machine to see an arbitrary portion of the file name space
-of another machine, such as to
-export the network device to another machine
-for gatewaying.
-However,
-<TT>cpu</TT>
-is not just
-<TT>exportfs</TT>
-because it also delivers signals such as interrupt
-and negotiates the initial environment
-for the remote shell.
-<br>&#32;<br>
-To authenticate an instance of
-<TT>cpu</TT>
-requires
-<TT>factotum</TT>
-processes on both ends: the local, client
-end running as the user on a terminal
-and the remote, server
-end running as the host owner of the server machine.
-Here is schematic code for the two ends:
-<DL><DT><DD><TT><PRE>
-/* client */
-int
-p9auth(int fd)
-{
-	AuthInfo *ai;
-
-	ai = auth_proxy(fd, auth_getkey,
-		"proto=p9any role=client");
-	if(ai == NULL)
-		return -1;
-
-	/* start cpu protocol here */
-}
-
-/* server */
-int
-srvp9auth(int fd, char *user)
-{
-	AuthInfo *ai;
-
-	ai = auth_proxy(fd, NULL,
-		"proto=p9any role=server");
-	if(ai == NULL)
-		return -1;
-	/* set user id for server process */
-	if(auth_chuid(ai, NULL) &lt; 0)
-		return -1;
-
-	/* start cpu protocol here */
-}
-</PRE></TT></DL>
-<TT>Auth_chuid</TT>
-encapsulates the negotiation to change a user id using the
-<TT>caphash</TT>
-and
-<TT>capuse</TT>
-files of the (server) kernel.
-Note that although the client process may ask the user for new keys, using
-<TT>auth_getkey</TT>,
-the server machine, presumably a shared machine with a pseudo-user for
-the host owner, sets the key-getting function to
-<TT>NULL</TT>.
-<H4>5 Secure Store
+Since the Plan 9 operating system is designed for use in network elements that must withstand direct attack, unguarded by firewall or VPN, we seek to ensure that all applications use channels with appropriate mutual authentication and encryption. A principal tool for this is TLS 1.0 [RFC2246]. (TLS 1.0 is nearly the same as SSL 3.0, and our software is designed to interoperate with implementations of either standard.)
+  <P>
+TLS defines a record layer protocol for message integrity and privacy through the use of message digesting and encryption with shared secrets. We implement this service as a kernel device, though it could be performed at slightly higher cost by invoking a separate program. The library interface to the TLS kernel device is:
+<pre>
+    int pushtls(int fd, char *hashalg, char *cryptalg, int isclient,
+         char *secret, char *dir);
+</pre>
+Given a file descriptor, the names of message digest and encryption algorithms, and the shared secret, <TT>pushtls</TT> returns a new file descriptor for the encrypted connection. (The final argument <TT>dir</TT> receives the name of the directory in the TLS device that is associated with the new connection.) The function is named by analogy with the ``push'' operation supported by the stream I/O system of Research Unix and the first two editions of Plan 9. Because adding encryption is as simple as replacing one file descriptor with another, adding encryption to a particular network service is usually trivial.
+  <P>
+The Plan 9 shared key authentication protocols establish a shared 56-bit secret as a side effect. Native Plan 9 network services such as <TT>cpu</TT> and <TT>exportfs</TT> use these protocols for authentication and then invoke <TT>pushtls</TT> with the shared secret.<br>
+  <P>
+Above the record layer, TLS specifies a handshake protocol using public keys to establish the session secret. This protocol is widely used with HTTP and IMAP4 to provide server authentication, though with client certificates it could provide mutual authentication. The library function
+<DL><DT><DD><TT>int tlsClient(int fd, TLSconn *conn)<br>
+</TT></DL>handles the initial handshake and returns the result of <TT>pushtls</TT>. On return, it fills the <TT>conn</TT> structure with the session ID used and the X.509 certificate presented by the server, but makes no effort to verify the certificate. Although the original design intent of X.509 certificates expected that they would be used with a Public Key Infrastructure, reliable deployment has been so long delayed and problematic that we have adopted the simpler policy of just using the X.509 certificate as a representation of the public key, depending on a locally-administered directory of SHA1 thumbprints to allow applications to decide which public keys to trust for which purposes.
+<H4>7. Related Work and Discussion
 </H4>
-<br>&#32;<br>
-<TT>Factotum</TT>
-stores keys in volatile RAM that must be initialized at boot time.
-To store the keys,
-therefore,
-<TT>factotum</TT>
-must be
-supplemented by a persistent store, perhaps
-a floppy disk containing a key file of commands to be copied into
-<TT>/mnt/factotum/ctl</TT>
-during bootstrap.
-But removable media are a nuisance to carry and
-are vulnerable to theft.
-Keys could be stored encrypted on a shared file system, but
-only if those keys are not necessary for authenticating to
-the file system in the first place.
-Even if the keys are encrypted under a user
-password, a thief might well succeed with a dictionary attack.
-Other risks of local storage are loss of the contents
-through mechanical mishap or dead batteries.
-Thus for convenience and
-safety we provide a
-<TT>secstore</TT>
-(secure store) server in the network to hold each user's permanent list of keys, a
-<I>key</I>
-<I>file</I>.
-<br>&#32;<br>
-<TT>Secstore</TT>
-is a file server for encrypted data,
-used only during bootstrapping.
-It must provide strong
-authentication and resistance to passive and active protocol attacks
-while assuming nothing more from the client than a password.
-Once
-<TT>factotum</TT>
-has loaded the key file, further encrypted or authenticated
-file storage can be accomplished by standard mechanisms.
-<br>&#32;<br>
-The cryptographic technology that enables
-<TT>secstore</TT>
-is a form of encrypted
-key exchange
-called PAK
-[Boyk00],
-analogous to
-EKE
-[Bell93],
-SRP
-[Wu98],
-or
-SPEKE
-[Jabl].
-PAK was chosen
-because it comes with a proof of equivalence in strength to
-Diffie-Hellman; subtle flaws in some earlier encrypted key exchange
-protocols and implementations have encouraged us to take special care.
-In outline, the PAK protocol is:
-<DL><DT><DD><TT><PRE>
-<I>C</I>-&gt;<I>S</I>: <I>C</I>,<I>g</I>^<I>x</I><I>H</I>
-<I>S</I>-&gt;<I>C</I>: <I>S</I>,<I>g</I>^<I>y</I>,<I>hash</I>(<I>g</I>^<I>xy</I>,<I>C</I>,<I>S</I>)
-<I>C</I>-&gt;<I>S</I>: <I>hash</I>(<I>g</I>^<I>xy</I>,<I>S</I>,<I>C</I>)
-</PRE></TT></DL>
-where <I>H</I> is a preshared secret between client <I>C</I> and server <I>S</I>.
-There are several variants of PAK, all presented in papers
-mainly concerned with proofs of cryptographic properties.
-To aid implementers, we have distilled a description of the specific
-version we use into an Appendix to this paper.
-<br>&#32;<br>
-As a further layer of defense against password theft,
-we provide (within the encrypted channel <I>C</I>-&gt;<I>S</I>)
-information that is validated at a RADIUS server,
-such as the digits from a hardware token
-[RFC2138].
-This provides two-factor authentication, which potentially
-requires tricking two independent administrators in any attack by
-social engineering.
-<br>&#32;<br>
-The key file stored on the server is encrypted with AES (Rijndael) using CBC
-with a 10-byte initialization vector and trailing authentication padding.
-All this is invisible to the user of
-<TT>secstore</TT>.
-For that matter, it is invisible to the
-<TT>secstore</TT>
-server as well;
-if the AES Modes of Operation are standardized and a new encryption format
-designed, it can be implemented by a client without change to the server.
-The
-<TT>secstore</TT>
-is deliberately not backed up;  the user is expected to
-use more than one
-<TT>secstore</TT>
-or save the key file on removable media
-and lock it away.
-The user's password is hashed to create the <I>H</I> used
-in the PAK protocol;  a different hash of the password is used as
-the file encryption key.
-Finally, there is a command (inside the authenticated,
-encrypted channel between client and
-<TT>secstore</TT>)
-to change passwords by sending
-a new <I>H</I>; 
-for consistency, the client process must at the same time fetch and re-encrypt all files.
-<br>&#32;<br>
-When
-<TT>factotum</TT>
-starts, it dials the local
-<TT>secstore</TT>
-and checks whether the user has an account.
-If so,
-it prompts for the user's
-<TT>secstore</TT>
-password and fetches the key file.
-The PAK protocol
-ensures mutual authentication and prevents dictionary attacks on the password
-by passive wiretappers or active intermediaries.
-Passwords saved in
-the key file can be long random strings suitable for
-simpler challenge/response authentication protocols.
-Thus the user need only remember
-a single, weaker password to enable strong, ``single sign on'' authentication to
-unchanged legacy applications scattered across multiple authentication domains.
-<H4>6 Transport Layer Security
+Kerberos, one of the earliest distributed authentication systems, keeps a set of authentication tickets in a temporary file called a ticket cache. The ticket cache is protected by Unix file permissions. An environment variable containing the file name of the ticket cache allows for different ticket caches in different simultaneous login sessions. A user logs in by typing his or her Kerberos password. The login program uses the Kerberos password to obtain a temporary ticket-granting ticket from the authentication server, initializes the ticket cache with the ticket-granting ticket, and then forgets the password. Other applications can use the ticket-granting ticket to sign tickets for themselves on behalf of the user during the login session. The ticket cache is removed when the user logs out [Stei88]. The ticket cache relieves the user from typing a password every time authentication is needed.
+  <P>
+The secure shell SSH develops this idea further, replacing the temporary file with a named Unix domain socket connected to a user-level program, called an agent. Once the SSH agent is started and initialized with one or more RSA private keys, SSH clients can employ it to perform RSA authentications on their behalf. In the absence of an agent, SSH typically uses RSA keys read from encrypted disk files or uses passphrase-based authentication, both of which would require prompting the user for a passphrase whenever authentication is needed [Ylon96]. The self-certifying file system SFS uses a similar agent [Kami00], not only for moderating the use of client authentication keys but also for verifying server public keys [Mazi99].
+  <P>
+<TT>Factotum</TT> is a logical continuation of this evolution, replacing the program-specific SSH or SFS agents with a general agent capable of serving a wide variety of programs. Having one agent for all programs removes the need to have one agent for each program. It also allows the programs themselves to be protocol-agnostic, so that, for example, one could build an SSH workalike capable of using any protocol supported by <TT>factotum</TT>, without that program knowing anything about the protocols. Traditionally each program needs to implement each authentication protocol for itself, an <EM>O</EM>(<EM>n</EM>2) coding problem that <TT>factotum</TT> reduces to <EM>O</EM>(<EM>n</EM>).
+  <P>
+Previous work on agents has concentrated on their use by clients authenticating to servers. Looking in the other direction, Sun Microsystem's pluggable authentication module (PAM) is one of the earliest attempts to provide a general authentication mechanism for Unix-like operating systems [Sama96]. Without a central authority like PAM, system policy is tied up in the various implementations of network services. For example, on a typical Unix, if a system administrator decides not to allow plaintext passwords for authentication, the configuration files for a half dozen different servers -- <TT>rlogind</TT>, <TT>telnetd</TT>, <TT>ftpd</TT>, <TT>sshd</TT>, and so on -- need to be edited. PAM solves this problem by hiding the details of a given authentication mechanism behind a common library interface. Directed by a system-wide configuration file, an application selects a particular authentication mechanism by dynamically loading the appropriate shared library. PAM is widely used on Sun's Solaris and some Linux distributions.
+  <P>
+<TT>Factotum</TT> achieves the same goals using the agent approach. <TT>Factotum</TT> is the only process that needs to create capabilities, so all the network servers can run as untrusted users (e.g., Plan 9's <TT>none</TT> or Unix's <TT>nobody</TT>), which greatly reduces the harm done if a server is buggy and is compromised. In fact, if <TT>factotum</TT> were implemented on Unix along with an analogue to the Plan 9 capability device, venerable programs like <TT>su</TT> and <TT>login</TT> would no longer need to be installed ``setuid root.''
+  <P>
+Several other systems, such as Password Safe [Schn], store multiple passwords in an encrypted file, so that the user only needs to remember one password. Our <TT>secstore</TT> solution differs from these by placing the storage in a hardened location in the network, so that the encrypted file is less liable to be stolen for offline dictionary attack and so that it is available even when a user has several computers. In contrast, Microsoft's Passport system [Micr] keeps credentials in the network, but centralized at one extremely-high-value target. The important feature of Passport, setting up trust relationships with e-merchants, is outside our scope. The <TT>secstore</TT> architecture is almost identical to Perlman and Kaufman's [Perl99] but with newer EKE technology. Like them, we chose to defend mainly against outside attacks on <TT>secstore</TT>; if additional defense of the files on the server itself is desired, one can use distributed techniques [Ford00].
+  <P>
+We made a conscious choice of placing encryption, message integrity, and key management at the application layer (TLS, just above layer 4) rather than at layer 3, as in IPsec. This leads to a simpler structure for the network stack, easier integration with applications and, most important, easier network administration since we can recognize which applications are misbehaving based on TCP port numbers. TLS does suffer (relative to IPsec) from the possibility of forged TCP Reset, but we feel that this is adequately dealt with by randomized TCP sequence numbers. In contrast with other TLS libraries, Plan 9 does not require the application to change <TT>write</TT> calls to <TT>sslwrite</TT> but simply to add a few lines of code at startup [Resc01].
+<H4>8. Conclusion
 </H4>
-<br>&#32;<br>
-Since the Plan 9 operating system is designed for use in network elements
-that must withstand direct attack, unguarded by firewall or VPN, we seek
-to ensure that all applications use channels with appropriate mutual
-authentication and encryption.
-A principal tool for this is TLS 1.0
-[RFC2246].
-(TLS 1.0 is nearly the same as SSL 3.0,
-and our software is designed to interoperate
-with implementations of either standard.)
-<br>&#32;<br>
-The TLS record layer protocol ensures message integrity and privacy
-through the use of message digesting and encryption with shared secrets.
-We implement this service as a kernel device, though it could
-be performed at slightly higher cost by invoking a separate program.
-The library interface to the TLS kernel device is:
-<DL><DT><DD><TT><PRE>
-int pushtls(int fd, char *hashalg,
-    char *cryptalg, int isclient,
-    char *secret, char *dir);
-</PRE></TT></DL>
-Given a file descriptor, the names of message digest and
-encryption algorithms, and the shared secret,
-<TT>pushtls</TT>
-returns a new file descriptor for the encrypted connection.
-(The final argument
-<TT>dir</TT>
-receives the name of the directory in the TLS device that
-is associated with the new connection.)
-The function is named by analogy with the ``push'' operation
-supported by the stream I/O system of Research Unix and the
-first two editions of Plan 9.
-Because adding encryption is as simple as replacing one
-file descriptor with another, adding encryption to a particular
-network service is usually trivial.
-<br>&#32;<br>
-The Plan 9 shared key authentication protocols establish a shared 56-bit secret
-as a side effect.
-Native Plan 9 network services such as
-<TT>cpu</TT>
-and
-<TT>exportfs</TT>
-use these protocols for authentication and then invoke 
-<TT>pushtls</TT>
-with the shared secret.
-<br>&#32;<br>
-Above the record layer, TLS specifies a handshake protocol using public keys
-to establish the session secret.
-This protocol is widely used with HTTP and IMAP4
-to provide server authentication, though with client certificates it could provide
-mutual authentication.  The library function
-<DL><DT><DD><TT><PRE>
-int tlsClient(int fd, TLSconn *conn)
-</PRE></TT></DL>
-handles the initial handshake and returns the result of
-<TT>pushtls</TT>.
-On return, it fills the
-<TT>conn</TT>
-structure with the session ID used
-and the X.509 certificate presented by the
-server, but makes no effort to verify the certificate.
-Although the original design intent of X.509 certificates expected
-that they would be used with a Public Key Infrastructure,
-reliable deployment has been so long delayed and problematic
-that we have adopted the simpler policy of just using the
-X.509 certificate as a representation of the public key,
-depending on a locally-administered directory of SHA1 thumbprints
-to allow applications to decide which public keys to trust
-for which purposes.
-<H4>7 Related Work and Discussion
+Writing safe code is difficult. Stack attacks, mistakes in logic, and bugs in compilers and operating systems can each make it possible for an attacker to subvert the intended execution sequence of a service. If the server process has the privileges of a powerful user, such as <TT>root</TT> on Unix, then so does the attacker. <TT>Factotum</TT> allows us to constrain the privileged execution to a single process whose core is a few thousand lines of code. Verifying such a process, both through manual and automatic means, is much easier and less error prone than requiring it of all servers.
+  <P>
+An implementation of these ideas is in Plan 9 from Bell Labs, Fourth Edition, freely available from <A href=http://plan9.bell-labs.com/plan9><TT>http://plan9.bell-labs.com/plan9</TT>.</A>
+<H4>Acknowledgments<br>
 </H4>
-<br>&#32;<br>
-Kerberos, one of the earliest distributed authentication
-systems, keeps a set of authentication tickets in a temporary file called
-a ticket cache.  The ticket cache is protected by Unix file permissions.
-An environment variable containing the file name of the ticket cache
-allows for different ticket caches in different simultaneous login sessions.
-A user logs in by typing his or her Kerberos password.
-The login program uses the Kerberos password to obtain a temporary
-ticket-granting ticket from the authentication server, initializes the
-ticket cache with the ticket-granting ticket, and then forgets the password.
-Other applications can use the ticket-granting ticket to sign tickets
-for themselves on behalf of the user during the login session.
-The ticket cache is removed when the user logs out [Stei88]
-The ticket cache relieves the user from typing a password
-every time authentication is needed.
-<br>&#32;<br>
-The secure shell SSH develops this idea further, replacing the
-temporary file with a named Unix domain socket connected to
-a user-level program, called an agent.
-Once the SSH agent is started and initialized with one or
-more RSA private keys, SSH clients can employ it
-to perform RSA authentications on their behalf.
-In the absence of an agent, SSH typically uses RSA keys
-read from encrypted disk files or uses passphrase-based
-authentication, both of which would require prompting the user
-for a passphrase whenever authentication is needed
-[Ylon96].
-The self-certifying file system SFS uses a similar agent
-[Kami00],
-not only for moderating the use of client authentication keys 
-but also for verifying server public keys
-[Mazi99].
-<br>&#32;<br>
-<TT>Factotum</TT>
-is a logical continuation of this evolution,
-replacing the program-specific SSH or SFS agents with
-a general agent capable of serving a wide variety of programs.
-Having one agent for all programs removes the need
-to have one agent for each program.
-It also allows the programs themselves to be protocol-agnostic,
-so that, for example, one could build an SSH workalike
-capable of using any protocol supported by
-<TT>factotum</TT>,
-without that program knowing anything about the protocols.
-Traditionally each program needs to implement each
-authentication protocol for itself, an <I>O</I>(<I>n</I>^2) coding
-problem that reduces to an <I>O</I>(<I>n</I>) coding problem with
-<TT>factotum</TT>.
-<br>&#32;<br>
-Previous work on agents has concentrated on their use by clients
-authenticating to servers.
-Looking in the other direction, Sun Microsystem's 
-system of pluggable authentication modules (PAM) is one
-of the earliest attempts to 
-provide a general authentication mechanism for Unix-like 
-operating systems
-[Sama96].
-Without a central authority like PAM, system policy is tied
-up in the various implementations of network services.
-For example, on a typical Unix, if a system administrator
-decides not to allow plaintext passwords for authentication,
-the configuration files for a half dozen different servers &#173;
-<TT>rlogind</TT>,
-<TT>telnetd</TT>,
-<TT>ftpd</TT>,
-<TT>sshd</TT>,
-and so on &#173;
-need to be edited.
-PAM solves this problem by hiding the details of a given
-authentication mechanism behind a common library interface.
-Directed by a system-wide configuration file,
-an application selects a particular authentication mechanism
-by dynamically loading the appropriate shared library.
-PAM is widely used on Sun's Solaris and some Linux distributions.
-<br>&#32;<br>
-<TT>Factotum</TT>
-achieves the same goals
-using the agent approach.
-<TT>Factotum</TT>
-is the only process that needs to create
-capabilities, so all the network servers can run as 
-untrusted users (e.g.,
-Plan 9's
-<TT>none</TT>
-or Unix's
-<TT>nobody</TT>),
-which greatly reduces the harm done if a server is buggy
-and is compromised.
-In fact, if
-<TT>factotum</TT>
-were implemented on Unix along with
-an analogue to the Plan 9 capability device, venerable
-programs like
-<TT>su</TT>
-and
-<TT>login</TT>
-would no longer need to be installed ``setuid root.''
-<br>&#32;<br>
-Several other systems, such as Password Safe [Schn],
-store multiple passwords in an encrypted file,
-so that the user only needs to remember one password.
-Our
-<TT>secstore</TT>
-solution differs from these by placing the storage in
-a hardened location in the network, so that the encrypted file is
-less liable to be stolen for offline dictionary attack and so that
-it is available even when a user has several computers.
-In contrast, Microsoft's Passport system
-[Micr]
-keeps credentials in
-the network, but centralized at one extremely-high-value target.
-The important feature of Passport, setting up trust relationships
-with e-merchants, is outside our scope.
-The
-<TT>secstore</TT>
-architecture is almost identical to
-Perlman and Kaufman's
-[Perl99]
-but with newer EKE technology.
-Like them, we chose to defend mainly against outside attacks
-on
-<TT>secstore</TT>;
-if additional defense of the files on the server
-itself is desired, one can use distributed techniques
-[Ford00].
-<br>&#32;<br>
-We made a conscious choice of placing encryption, message integrity,
-and key management at the application layer
-(TLS, just above layer 4) rather than at layer 3, as in IPsec.
-This leads to a simpler structure for the network stack, easier
-integration with applications and, most important, easier network
-administration since we can recognize which applications are misbehaving
-based on TCP port numbers.  TLS does suffer (relative to IPsec) from
-the possibility of forged TCP Reset, but we feel that this is adequately
-dealt with by randomized TCP sequence numbers.
-<br>&#32;<br>
-Writing safe code is difficult.
-Stack attacks,
-mistakes in logic, and bugs in compilers and operating systems
-can each make it possible for an attacker
-to subvert the intended execution sequence of a
-service.
-If the server process has the privileges
-of a powerful user, such as
-<TT>root</TT>
-on Unix, then so does the attacker.
-<TT>Factotum</TT>
-allows us
-to constrain the privileged execution to a single
-process whose core is a few thousand lines of code.
-Verifying such a process, both through manual and automatic means,
-is much easier and less error prone
-than requiring it of all servers.
-<H4>Acknowledgments
-</H4>
-<br>&#32;<br>
-William Josephson contributed to the implementation of password changing in
-<TT>secstore</TT>.
-We thank Phil MacKenzie and Mart&iacute;n Abadi for helpful comments on early parts
-of the design.
-Chuck Blake,
-Peter Bosch,
-Frans Kaashoek,
-Sape Mullender,
-and
-Lakshman Y. N.,
-predominantly Dutchmen, gave helpful comments on the paper.
-<H4>References
+William Josephson contributed to the implementation of password changing in <TT>secstore</TT>. We thank Phil MacKenzie and Mart&iacute;n Abadi for helpful comments on early parts of the design. Chuck Blake, Peter Bosch, Frans Kaashoek, Sape Mullender, and Lakshman Y. N., predominantly Dutchmen, gave helpful comments on the paper. Russ Cox is supported by a fellowship from the Fannie and John Hertz Foundation.
+<H4>References<br>
 </H4>
-<br>&#32;<br>
-[Bell93]
-S.M. Bellovin and M. Merritt,
-``Augmented Encrypted Key Exchange,''
-Proceedings of the 1st ACM Conference on Computer and Communications Security (1993) pp. 244 - 250.
-<br>&#32;<br>
-[Boyk00]
-Victor Boyko, Philip MacKenzie, and Sarvar Patel,
-``Provably Secure Password-Authenticated Key Exchange using Diffie-Hellman,''
-Eurocrypt 2000, 156-171.
-<br>&#32;<br>
-[RFC2246]
-T . Dierks and C. Allen,
-``The TLS Protocol, Version 1.0,''
-RFC 2246.
-<br>&#32;<br>
-[Ford00]
-Warwick Ford and Burton S. Kaliski, Jr.,
-``Server-Assisted Generation of a Strong Secret from a Password,''
-IEEE Fifth International Workshop on Enterprise Security,
-National Institute of Standards and Technology (NIST),
-Gaithersburg MD, June 14 - 16, 2000.
-<br>&#32;<br>
-[Jabl]
-David P. Jablon,
-``Strong Password-Only Authenticated Key Exchange,''
-<TT>http://www.integritysciences.com/speke97.html</TT>.
-<br>&#32;<br>
-[Kami00]
-Michael Kaminsky.
-``Flexible Key Management with SFS Agents,''
-Master's Thesis, MIT, May 2000.
-<br>&#32;<br>
-[Mack]
-Philip MacKenzie,
-private communication.
-<br>&#32;<br>
-[Mazi99]
-David Mazi&egrave;res, Michael Kaminsky, M. Frans Kaashoek and Emmett Witchel,
-``Separating key management from file system security,''
-Symposium on Operating Systems Principles, 1999, pp. 124-139.
-<br>&#32;<br>
-[Micr]
-Microsoft Passport,
-<TT>http://www.passport.com/Consumer/PrivacyPolicy.asp</TT>.
-<br>&#32;<br>
-[Perl99]
-Radia Perlman and Charlie Kaufman,
-``Secure Password-Based Protocol for Downloading a Private Key,''
-Proc. 1999 Network and Distributed System Security Symposium,
-Internet Society, January 1999.
-<br>&#32;<br>
-[Pike95]
-Rob Pike, Dave Presotto, Sean Dorward, Bob Flandrena, Ken Thompson, Howard Trickey, and Phil Winterbottom,
-``Plan 9 from Bell Labs,''
-Computing Systems, <B>8</B>, 3, Summer 1995, pp. 221-254.
-<br>&#32;<br>
-[Pike93]
-Rob Pike, Dave Presotto, Ken Thompson, Howard Trickey, Phil Winterbottom,
-``The Use of Name Spaces in Plan 9,''
-Operating Systems Review, <B>27</B>, 2, April 1993, pp. 72-76
-(reprinted from Proceedings of the 5th ACM SIGOPS European Workshop,
-Mont Saint-Michel, 1992, Paper n&#186; 34).
-<br>&#32;<br>
-[RFC2138]
-C. Rigney, A. Rubens, W. Simpson, S. Willens,
-``Remote Authentication Dial In User Service (RADIUS),''
-RFC2138, April 1997.
-<br>&#32;<br>
-[RiLa]
-Ronald L. Rivest and Butler Lampson,
-``SDSI&#173;A Simple Distributed Security Infrastructure,''
-<TT>http://theory.lcs.mit.edu/~rivest/sdsi10.ps</TT>.
-<br>&#32;<br>
-[Schn]
-Bruce Schneier, Password Safe,
-<TT>http://www.counterpane.com/passsafe.html</TT>.
-<br>&#32;<br>
-[Sama96]
-Vipin Samar,
-``Unified Login with Pluggable Authentication Modules (PAM),''
-Proceedings of the Third ACM Conference on Computer Communications and Security,
-March 1996, New Delhi, India.
-<br>&#32;<br>
-[Stei88]
-Jennifer G. Steiner, Clifford Neumann, and Jeffrey I. Schiller,
-``<I>Kerberos</I>: An Authentication Service for Open Network Systems,''
-Proceedings of USENIX Winter Conference, Dallas, Texas, February 1988, p. 191-202.
-<br>&#32;<br>
-[Wu98]
-T. Wu,
-``The Secure Remote Password Protocol,''
-Proceedings of
-the 1998 Internet Society Network and Distributed System Security
-Symposium, San Diego, CA, Mar 1998, pp. 97-111.
-<br>&#32;<br>
-[Ylon96]
-Ylonen, T.,
-``SSH&#173;Secure Login Connections Over the Internet,''
-6th USENIX Security Symposium, pp. 37-42. San Jose, CA, Jul. 1996.
+[Bell93] S.M. Bellovin and M. Merritt, ``Augmented Encrypted Key Exchange,'' Proceedings of the 1st ACM Conference on Computer and Communications Security, 1993, pp. 244 - 250.<br>
+  <P>
+[Boyk00] Victor Boyko, Philip MacKenzie, and Sarvar Patel, ``Provably Secure Password-Authenticated Key Exchange using Diffie-Hellman,'' Eurocrypt 2000, 156&#173;171.<br>
+  <P>
+[RFC2246] T . Dierks and C. Allen, ``The TLS Protocol, Version 1.0,'' RFC 2246.<br>
+  <P>
+[Ford00] Warwick Ford and Burton S. Kaliski, Jr., ``Server-Assisted Generation of a Strong Secret from a Password,'' IEEE Fifth International Workshop on Enterprise Security, National Institute of Standards and Technology (NIST), Gaithersburg MD, June 14 - 16, 2000.<br>
+  <P>
+[Jabl] David P. Jablon, ``Strong Password-Only Authenticated Key Exchange,'' <A href=http://integritysciences.com/speke97.html><TT>http://integritysciences.com/speke97.html</TT></A>.<br>
+  <P>
+[Kami00] Michael Kaminsky. ``Flexible Key Management with SFS Agents,'' Master's Thesis, MIT, May 2000.<br>
+  <P>
+[Mack] Philip MacKenzie, private communication.<br>
+  <P>
+[Mazi99] David Mazi&egrave;res, Michael Kaminsky, M. Frans Kaashoek and Emmett Witchel, ``Separating key management from file system security,'' Symposium on Operating Systems Principles, 1999, pp. 124-139.<br>
+  <P>
+[Micr] Microsoft Passport, <A href=http://www.passport.com/><TT>http://www.passport.com/</TT></A>.<br>
+  <P>
+[Perl99] Radia Perlman and Charlie Kaufman, ``Secure Password-Based Protocol for Downloading a Private Key,'' Proc. 1999 Network and Distributed System Security Symposium, Internet Society, January 1999.<br>
+  <P>
+[Pike95] Rob Pike, Dave Presotto, Sean Dorward, Bob Flandrena, Ken Thompson, Howard Trickey, and Phil Winterbottom, ``Plan 9 from Bell Labs,'' Computing Systems, 8, 3, Summer 1995, pp. 221-254.<br>
+  <P>
+[Pike93] Rob Pike, Dave Presotto, Ken Thompson, Howard Trickey, Phil Winterbottom, ``The Use of Name Spaces in Plan 9,'' Operating Systems Review, 27, 2, April 1993, pp. 72-76 (reprinted from Proceedings of the 5th ACM SIGOPS European Workshop, Mont Saint-Michel, 1992, Paper n&#186; 34).
+  <P>
+[Resc01] Eric Rescorla, ``SSL and TLS: Designing and Building Secure Systems,'' Addison-Wesley, 2001. ISBN 0-201-61598-3, p. 387.<br>
+  <P>
+[RFC2138] C. Rigney, A. Rubens, W. Simpson, S. Willens, ``Remote Authentication Dial In User Service (RADIUS),'' RFC2138, April 1997.<br>
+  <P>
+[RiLa] Ronald L. Rivest and Butler Lampson, ``SDSI--A Simple Distributed Security Infrastructure,'' <A href=http://theory.lcs.mit.edu/~rivest/sdsi10.ps><TT>http://theory.lcs.mit.edu/~rivest/sdsi10.ps</TT></A>.<br>
+  <P>
+[Schn] Bruce Schneier, Password Safe, <A href=http://www.counterpane.com/passsafe.html><TT>http://www.counterpane.com/passsafe.html</TT></A>.<br>
+  <P>
+[Sama96] Vipin Samar, ``Unified Login with Pluggable Authentication Modules (PAM),'' Proceedings of the Third ACM Conference on Computer Communications and Security, March 1996, New Delhi, India.<br>
+  <P>
+[Stei88] Jennifer G. Steiner, Clifford Neumann, and Jeffrey I. Schiller, ``<EM>Kerberos</EM>: An Authentication Service for Open Network Systems,'' Proceedings of USENIX Winter Conference, Dallas, Texas, February 1988, pp. 191&#173;202.<br>
+  <P>
+[Wu98] T. Wu, ``The Secure Remote Password Protocol,'' Proceedings of the 1998 Internet Society Network and Distributed System Security Symposium, San Diego, CA, March 1998, pp. 97-111.<br>
+  <P>
+[Ylon96] Ylonen, T., ``SSH--Secure Login Connections Over the Internet,'' 6th USENIX Security Symposium, pp. 37-42. San Jose, CA, July 1996.<br>
 <H4>Appendix: Summary of the PAK protocol
 </H4>
-<br>&#32;<br>
-Let <I>q&gt;</I>2^160 and <I>p&gt;</I>2^1024 be primes
-such that <I>p=rq+</I> with <I>r</I> not a multiple of <I>q</I>.
-^<I>*</I>h'-0w'<I>*</I>'u+0w'<I>*</I>'u'
-Take <I>h</I><I>&#191;</I><I>Z</I><I>p</I>h'-0w'<I>p</I>'u' such that <I>g</I>==<I>h</I>^<I>r</I> is not 1.
-These parameters may be chosen by the NIST algorithm for DSA,
-and are public, fixed values.
-The client <I>C</I> knows a secret PI
-and computes <I>H</I>==(<I>H</I>1(<I>C</I>, PI)<I></I>)^<I>r</I> and <I>H</I>^<I>-</I>1,
-^<I>*</I>h'-0w'<I>*</I>'u+0w'<I>*</I>'u'
-where <I>H</I>1 is a hash function yielding a random element of <I>Z</I><I>p</I>h'-0w'<I>p</I>'u',
-and <I>H</I>^<I>-</I>1 may be computed by gcd.
-(All arithmetic is modulo <I>p</I>.)
-The client gives <I>H</I>^<I>-</I>1 to the server <I>S</I> ahead of time by a private channel.
-To start a new connection, the client generates a random value <I>x</I>,
-computes <I>m</I>==<I>g</I>^<I>x</I><I>H</I>,
-then calls the server and sends <I>C</I> and <I>m</I>.
-The server checks <I>m</I>!=0 mod <I>p</I>,
-generates random <I>y</I>,
-computes MU==<I>g</I>^<I>y</I>,
-&#191;==(<I>m</I><I>H</I>^<I>-</I>1)^<I>y</I>,
-and sends <I>S</I>, MU, <I>k</I>==<I>sha1</I>("server",<I>C</I>,<I>S</I>,<I>m</I>,MU,&#191;,<I>H</I>^<I>-</I>1).
-Next the client computes &#191;<I>=</I>MU^<I>x</I>,
-verifies <I>k</I>,
-and sends <I>k&#180;</I>==<I>sha1</I>("client",<I>C</I>,<I>S</I>,<I>m</I>,MU,&#191;,<I>H</I>^<I>-</I>1).
-The server then verifies <I>k&#180;</I> and both sides begin
-using session key <I>K</I>==<I>sha1</I>("session",<I>C</I>,<I>S</I>,<I>m</I>,MU,&#191;,<I>H</I>^<I>-</I>1).
-In the published version of PAK, the server name <I>S</I>
-is included in the initial
-hash <I>H</I>, but doing so is inconvenient in our application,
-as the server may be known by various equivalent names.
-<br>&#32;<br>
-MacKenzie has shown
-[Mack]
-that the
-equivalence proof [Boyk00]
-can be adapted to cover our version.
-<br>&#32;<br>
-<A href=http://www.lucent.com/copyright.html>
-Copyright</A> &#169; 2002 Lucent Technologies Inc.  All rights reserved.
-</body></html>
+Let <EM>q&gt;</EM>2^160 and <EM>p&gt;</EM>2^1024 be primes such that <EM>p=rq+</EM>1 with <EM>r </EM>not a multiple of <EM>q</EM>. Take <EM>h∈Zp* </EM>such that <EM>g==h^r </EM>is not 1. These parameters may be chosen by the NIST algorithm for DSA, and are public, fixed values. The client <EM>C </EM>knows a secret π and computes <EM>H==</EM>(<EM>H</EM>1(<EM>C</EM>, π))<EM>r </EM>and <EM>H</EM>^-1, where <EM>H</EM>1 is a hash function yielding a random element of <EM>Zp*</EM>, and <EM>H</EM>^-1 may be computed by gcd. (All arithmetic is modulo <EM>p</EM>.) The client gives <EM>H</EM>^-1 to the server <EM>S </EM>ahead of time by a private channel. To start a new connection, the client generates a random value <EM>x</EM>, computes <EM>m==g^xH</EM>, then calls the server and sends <EM>C </EM>and <EM>m</EM>. The server checks <EM>m!=</EM>0 mod <EM>p</EM>, generates random <EM>y</EM>, computes μ==<EM>g^y</EM>, σ==(<EM>mH</EM>^-1)<EM>y</EM>, and sends <EM>S</EM>, μ, <EM>k==sha1</EM>(&quot;server&quot;,<EM>C</EM>,<EM>S</EM>,<EM>m</EM>,μ,σ,<EM>H-</EM>1). Next the client computes σ=μ<EM>x</EM>, verifies <EM>k</EM>, and sends <EM>k&#180;==sha1</EM>(&quot;client&quot;,<EM>C</EM>,<EM>S</EM>,<EM>m</EM>,μ,σ,<EM>H</EM>^-1). The server then verifies <EM>k&#180; </EM>and both sides begin using session key <EM>K==sha1</EM>(&quot;session&quot;,<EM>C</EM>,<EM>S</EM>,<EM>m</EM>,μ,σ,<EM>H</EM>^-1). In the published version of PAK, the server name <EM>S </EM>is included in the initial hash <EM>H</EM>, but doing so is inconvenient in our application, as the server may be known by various equivalent names.
+  <P>
+MacKenzie has shown [Mack] that the equivalence proof [Boyk00] can be adapted to cover our version.<br>
+
+<BR><FONT size=1><A HREF="http://www.lucent.com/copyright.html">
+Copyright</A> &#169; 2002 Lucent Technologies.  All rights reserved.</FONT>
+
+</BODY></HTML>

+ 100 - 78
sys/doc/auth.ms

@@ -75,7 +75,8 @@ is offset by the confusing and typically insecure
 steps for installing X.509 certificates.
 .LP
 The security architecture of the Plan 9
-operating system [Pike95]
+operating system
+[Pike95]
 has recently been redesigned to make it both more secure
 and easier to use.
 By
@@ -104,7 +105,8 @@ Changes and fixes to a security protocol
 required that all components using that protocol needed to be recompiled,
 or at least relinked, and restarted.
 .LP
-Third, the file transport protocol, 9P [Pike93],
+Third, the file transport protocol, 9P
+[Pike93],
 that forms the core of
 the Plan 9 system, had its authentication protocol embedded in its design.
 This meant that fixing or changing the authentication used by 9P
@@ -121,7 +123,7 @@ called
 .CW factotum ,
 that handles the user's keys and negotiates all security
 interactions with system services and applications.
-Like a trusted houseboy with a copy of the owner's keys,
+Like a trusted assistant with a copy of the owner's keys,
 .CW factotum
 does all the negotiation for security and authentication.
 Programs no longer need to be compiled with cryptographic
@@ -230,7 +232,7 @@ confusing software, or administrative oversights.
 It is these practical problems that we are addressing.
 Although this paper describes the algorithms and protocols we are using,
 they are included mainly for concreteness.
-Instead, our focus is to present a simple security architecture built
+Our main intent is to present a simple security architecture built
 upon a small trusted code base that is easy to verify (whether by manual or
 automatic means), easy to understand, and easy to use.
 .LP
@@ -290,7 +292,7 @@ leaking information inadvertently.
 .CW Factotum
 is implemented, like most Plan 9 services, as a file server.
 It is conventionally mounted upon the directory
-.CW /mnt/factotum
+.CW /mnt/factotum ,
 and the files it serves there are analogous to virtual devices that provide access to,
 and control of, the services of the
 .CW factotum .
@@ -314,12 +316,11 @@ If he does,
 will prompt him for the password to the secure store
 and obtain keys from it, prompting only when a key
 isn't found in the store.
-If not,
+Otherwise,
 .CW factotum
 must prompt for each key.
 .LP
-In the typescripts,
-.CW \en
+In the typescripts, \f6\s9\en\s0\fP
 represents a literal newline
 character typed to force a default response.
 User input is in italics, and
@@ -356,15 +357,15 @@ password: \f6****\fP
 .CW Factotum
 is doing all the prompting and the applications
 being started are not even touching the keys.
-Note that it's always clear what key is being requested.
+Note that it's always clear which key is being requested.
 .LP
 Now consider the same login sequence, but in the case where
 .CW gre
 has a secure store account:
 .P1
 user[none]: \f6\s9gre\s0\fP
-secstore password: \f6******\fP
-STA PIN+SecurID: \f6******\fP
+secstore password: \f6*********\fP
+STA PIN+SecurID: \f6*********\fP
 .P2
 That's the last
 .CW gre
@@ -390,9 +391,9 @@ On a single-user system, which we call a terminal,
 the host owner is the id of the terminal's user.
 Shared servers such as CPU servers normally have a pseudo-user
 that initially owns all resources.
-By default,
+At boot time, the Plan 9 kernel starts a
 .CW factotum
-executes as, and therefore has the privileges of,
+executing as, and therefore with the privileges of,
 the host owner.
 .LP
 New processes run as
@@ -412,10 +413,11 @@ prove that the process has access to secret information
 which only the new user should possess.
 For example, consider the setup in Figure 1a.
 If a user on the terminal
-wants to log on to the CPU server using the
+wants to log in to the CPU server using the
 Plan 9
 .CW cpu
-service [Pike93],
+service
+[Pike93],
 then
 $P sub T#
 might be the
@@ -457,7 +459,7 @@ The kernel always uses a single local instance of
 running as the
 host owner, for
 its authentication purposes, but
-a regular user may start multiple
+a regular user may start other
 .CW factotum
 agents.
 In fact, the
@@ -479,7 +481,7 @@ transparently validated by the user's own
 .CW factotum ,
 so
 secrets need never leave the user's terminal.
-SSH agent
+The SSH agent
 [Ylon96]
 does much the
 same with special SSH protocol messages, but
@@ -517,10 +519,9 @@ new or repaired protocols.
 At the time of writing, 
 .CW factotum
 contains authentication
-modules for the Plan 9 shared key protocol (p9sk1), for
+modules for the Plan 9 shared key protocol (p9sk1),
 SSH's RSA authentication, passwords in the clear, APOP, CRAM, PPP's CHAP,
-Microsoft PPP's MSCHAP, and VNC's challenge/response.  We're
-in the process of adding support for TLS handshakes.
+Microsoft PPP's MSCHAP, and VNC's challenge/response.
 .SS
 Local capabilities
 .LP
@@ -567,12 +568,10 @@ to
 Once used, or if a timeout expires,
 the capability is discarded by the kernel.
 .LP
-The capabilities are hashed to keep them secret if
-someone is spying on kernel memory.
-Also, they are local to the machine on which they are created.
+The capabilities are local to the machine on which they are created.
 Hence a
 .CW factotum
-running on one system cannot pass capabilities
+running on one machine cannot pass capabilities
 to processes on another and expect them to work.
 .SS
 Keys
@@ -627,7 +626,7 @@ might be represented like this:
 dom=bell-labs.com proto=p9sk1 user=gre
 	!password='don''t tell'
 proto=apop server=x.y.com user=gre
-	!password='bite me'
+	!password='open sesame'
 .P2
 If a value is empty or contains white space or single quotes, it must be quoted;
 quotes are represented by doubled single quotes.
@@ -792,11 +791,14 @@ Neither
 nor
 .CW noswap
 is specific to
-.CW factotum ;
-any process can use
-them.
-Both are useful, for instance, to protect any user-level program
-providing critical file services for the kernel.
+.CW factotum .
+User-level file servers such as
+.CW dossrv ,
+which interprets FAT file systems,
+could use
+.CW noswap
+to keep their buffer caches from being
+swapped to disk.
 .LP
 Despite our precautions, attackers might still
 find a way to gain access to a process running as the host
@@ -915,7 +917,9 @@ the
 .CW start
 query as well as any public attributes from keys being used.
 .LP
-As an example of the RPC file in action, consider a mail client
+As an example of the
+.CW rpc
+file in action, consider a mail client
 connecting to a mail server and authenticating using
 the POP3 protocol's APOP challenge-response command.
 There are four programs involved: the mail client $P sub C#, the client
@@ -1110,7 +1114,8 @@ is used by system services.
 .NH 1
 Authentication in 9P
 .LP
-Plan 9 uses a remote file access protocol, 9P [Pike93],
+Plan 9 uses a remote file access protocol, 9P
+[Pike93],
 to connect to resources such as the
 file server and remote processes.
 The original design for 9P included special messages at the start of a conversation
@@ -1118,7 +1123,8 @@ to authenticate the user.
 Multiple users can share a single connection, such as when a CPU server
 runs processes for many users connected to a single file server,
 but each must authenticate separately.
-The authentication protocol, similar to that of Kerberos [Stei88],
+The authentication protocol, similar to that of Kerberos
+[Stei88],
 used a sequence of messages passed between client, file server, and authentication
 server to verify the identities of the user, calling machine, and serving machine.
 One major drawback to the design was that the authentication method was defined by 9P
@@ -1126,7 +1132,7 @@ itself and could not be changed.
 Moreover, there was no mechanism to relegate
 authentication to an external (trusted) agent,
 so a process implementing 9P needed, besides support for file service,
-a substantial body of cryptographic code to implement a handful of early messages
+a substantial body of cryptographic code to implement a handful of startup messages
 in the protocol.
 .LP
 A recent redesign of 9P
@@ -1143,11 +1149,9 @@ Since 9P is a file service protocol, the solution involved creating a new type o
 to be served: an
 .I authentication
 .I file .
-When a new user connects to a 9P service, the connection has the
-permissions of
-.CW none ', `
-a state that
-allows no general file access but permits the user to open an authentication file
+Connections to a 9P service begin in a state that
+allows no general file access but permits the client
+to open an authentication file
 by sending a special message, generated by the new
 .CW fauth
 system call:
@@ -1159,7 +1163,7 @@ Here
 is the user's file descriptor for the established network connection to the 9P server
 and
 .CW servicename
-is the name of the desired service offered on that server, for example the file subsystem
+is the name of the desired service offered on that server, typically the file subsystem
 to be accessed.
 The returned file descriptor,
 .CW afd ,
@@ -1170,7 +1174,7 @@ The authentication file represented by
 .CW afd
 is not otherwise addressable on the server, such as through
 the file name hierarchy.
-Otherwise, it behaves like a regular file;
+In all other respects, it behaves like a regular file;
 most important, it accepts standard read and write operations.
 .LP
 To prove its identity, the user process (via
@@ -1278,7 +1282,7 @@ secret $K sub n#.
 The authenticator $K sub n roman "{" "nonce" sub S , "counter" roman "}"#
 convinces the server that the client knows $K sub n# and thus
 must be $"uid" sub C#.
-Similarly, the authenticator $K sub n roman "{" "nonce" sub C , "counter" roman "}"#
+Similarly, authenticator $K sub n roman "{" "nonce" sub C , "counter" roman "}"#
 convinces the client that the server knows $K sub n# and thus
 must be $"uid" sub S#.
 Tickets can be reused, without contacting the authentication
@@ -1305,7 +1309,7 @@ and
 .LP
 .CW Keyfs
 is a user-level file system that manages an
-encrypted data base of user accounts.
+encrypted database of user accounts.
 Each account is represented by a directory containing the
 files
 .CW key ,
@@ -1343,15 +1347,15 @@ section.
 The challenge/response protocols differ
 in detail but all follow the general structure:
 .P1
-$C -> S: ~~ "uid" sub C#
-$S -> A: ~~ "nonce" sub S , "uid" sub S , "domain" sub S , "uid" sub C ,#
-         $"factotum" sub S#
-$A -> S: ~~ "challenge"#
-$S -> C: ~~ "challenge"#
-$C -> S: ~~ "response"#
-$S -> A: ~~ "response"#
-$A -> S: ~~ K sub C roman "{" "nonce" sub S , "uid" sub C , "uid" sub S, K sub n roman "}",#
-         $K sub n roman "{" "nonce" sub C roman "}"#
+$C -> S: ~~ "nonce" sub C#
+$S -> C: ~~ "nonce" sub S , "uid" sub S ,"domain" sub S#
+$C -> A: ~~ "nonce" sub S , "uid" sub S , "domain" sub S ,#
+         $"hostid" sub C , "uid" sub C#
+$A -> C: ~~ K sub C roman "{" "nonce" sub S , "uid" sub C , "uid" sub S, K sub n roman "}",#
+         $K sub S roman "{" "nonce" sub S , "uid" sub C , "uid" sub S, K sub n roman "}"#
+$C -> S: ~~ K sub S roman "{" "nonce" sub S , "uid" sub C , "uid" sub S, K sub n roman "}",#
+         $K sub n roman "{" "nonce" sub S roman "}"#
+$S -> C: ~~ K sub n roman "{" "nonce" sub C roman "}"#
 .P2
 The password protocol is:
 .P1
@@ -1377,7 +1381,7 @@ is used now by all native services on Plan 9.
 The metaprotocol is simple.  The callee sends a
 null-terminated string of the form:
 .P1
-v$"" sub n# $proto sub 1#@$domain sub 1# $proto sub 2#@$domain sub 2# ...
+v.$n# $proto sub 1#@$domain sub 1# $proto sub 2#@$domain sub 2# ...
 .P2
 where
 .I n
@@ -1476,6 +1480,13 @@ amount(int fd, char *mntpt,
 	return ret;
 }
 .P2
+where parameter
+.CW fd
+is a file descriptor returned by
+.CW open
+or
+.CW dial
+for a new connection to a file server.
 The conversation with
 .CW factotum
 occurs in the call to
@@ -1604,9 +1615,9 @@ the host owner, sets the key-getting function to
 Secure Store
 .LP
 .CW Factotum
-stores keys in volatile RAM that must be initialized at boot time.
-To store the keys,
-therefore,
+keeps its keys in volatile memory, which must somehow be
+initialized at boot time.
+Therefore,
 .CW factotum
 must be
 supplemented by a persistent store, perhaps
@@ -1673,6 +1684,8 @@ There are several variants of PAK, all presented in papers
 mainly concerned with proofs of cryptographic properties.
 To aid implementers, we have distilled a description of the specific
 version we use into an Appendix to this paper.
+The Plan 9 open source license provides for use of Lucent's
+encrypted key exchange patents in this context.
 .LP
 As a further layer of defense against password theft,
 we provide (within the encrypted channel $C -> S#)
@@ -1740,7 +1753,7 @@ A principal tool for this is TLS 1.0
 and our software is designed to interoperate
 with implementations of either standard.)
 .LP
-The TLS record layer protocol ensures message integrity and privacy
+TLS defines a record layer protocol for message integrity and privacy
 through the use of message digesting and encryption with shared secrets.
 We implement this service as a kernel device, though it could
 be performed at slightly higher cost by invoking a separate program.
@@ -1812,7 +1825,8 @@ ticket-granting ticket from the authentication server, initializes the
 ticket cache with the ticket-granting ticket, and then forgets the password.
 Other applications can use the ticket-granting ticket to sign tickets
 for themselves on behalf of the user during the login session.
-The ticket cache is removed when the user logs out [Stei88]
+The ticket cache is removed when the user logs out
+[Stei88].
 The ticket cache relieves the user from typing a password
 every time authentication is needed.
 .LP
@@ -1833,12 +1847,6 @@ not only for moderating the use of client authentication keys
 but also for verifying server public keys
 [Mazi99].
 .LP
-... some reviewer is going to claim that the SFS agent is not
-... protocol-specific, which is simply false.  although
-... the method for verifying server public keys is 
-... entirely agent-chosen, the authentication protocol
-... is hard-coded as rabin n^2 authentication.
-... it's not worth going out of our way to avoid.  -rsc
 .CW Factotum
 is a logical continuation of this evolution,
 replacing the program-specific SSH or SFS agents with
@@ -1852,13 +1860,14 @@ capable of using any protocol supported by
 without that program knowing anything about the protocols.
 Traditionally each program needs to implement each
 authentication protocol for itself, an $O(n sup 2 )# coding
-problem that reduces to an $O(n)# coding problem with
-.CW factotum .
+problem that
+.CW factotum
+reduces to $O(n)#.
 .LP
 Previous work on agents has concentrated on their use by clients
 authenticating to servers.
 Looking in the other direction, Sun Microsystem's 
-system of pluggable authentication modules (PAM) is one
+pluggable authentication module (PAM) is one
 of the earliest attempts to 
 provide a general authentication mechanism for Unix-like 
 operating systems
@@ -1931,11 +1940,6 @@ on
 if additional defense of the files on the server
 itself is desired, one can use distributed techniques
 [Ford00].
-... .LP
-... The use of locally shared thumbprint files rather than
-... dependence on a PKI resembles server names in Mazières's 
-... self-certifying file system
-... [Mazi99].
 .LP
 We made a conscious choice of placing encryption, message integrity,
 and key management at the application layer
@@ -1946,6 +1950,15 @@ administration since we can recognize which applications are misbehaving
 based on TCP port numbers.  TLS does suffer (relative to IPsec) from
 the possibility of forged TCP Reset, but we feel that this is adequately
 dealt with by randomized TCP sequence numbers.
+In contrast with other TLS libraries, Plan 9 does not
+require the application to change
+.CW write
+calls to
+.CW sslwrite
+but simply to add a few lines of code at startup
+[Resc01].
+.NH 1
+Conclusion
 .LP
 Writing safe code is difficult.
 Stack attacks,
@@ -1964,6 +1977,9 @@ process whose core is a few thousand lines of code.
 Verifying such a process, both through manual and automatic means,
 is much easier and less error prone
 than requiring it of all servers.
+.LP
+An implementation of these ideas is in Plan 9 from Bell Labs, Fourth Edition,
+freely available from \f(CWhttp://\%plan9.bell-labs.com/\%plan9\fP.
 .SH
 Acknowledgments
 .LP
@@ -1978,13 +1994,14 @@ Sape Mullender,
 and
 Lakshman Y. N.,
 predominantly Dutchmen, gave helpful comments on the paper.
+Russ Cox is supported by a fellowship from the Fannie and John Hertz Foundation.
 .SH
 References
 .LP
 [Bell93]
 S.M. Bellovin and M. Merritt,
 ``Augmented Encrypted Key Exchange,''
-Proceedings of the 1st ACM Conference on Computer and Communications Security (1993) pp. 244 - 250.
+Proceedings of the 1st ACM Conference on Computer and Communications Security, 1993, pp. 244 - 250.
 .LP
 [Boyk00]
 Victor Boyko, Philip MacKenzie, and Sarvar Patel,
@@ -2007,7 +2024,7 @@ Gaithersburg MD, June 14 - 16, 2000.
 [Jabl]
 David P. Jablon,
 ``Strong Password-Only Authenticated Key Exchange,''
-\f(CWhttp://\%www.integritysciences.com/\%speke97.html\fP.
+\f(CWhttp://\%integritysciences.com/\%speke97.html\fP.
 .LP
 [Kami00]
 Michael Kaminsky.
@@ -2025,7 +2042,7 @@ Symposium on Operating Systems Principles, 1999, pp. 124-139.
 .LP
 [Micr]
 Microsoft Passport,
-\f(CWhttp://\%www.passport.com/\%Consumer/\%PrivacyPolicy.asp\fP.
+\f(CWhttp://\%www.passport.com/\fP.
 .LP
 [Perl99]
 Radia Perlman and Charlie Kaufman,
@@ -2045,6 +2062,11 @@ Operating Systems Review, \f3\&27\fP, 2, April 1993, pp. 72-76
 (reprinted from Proceedings of the 5th ACM SIGOPS European Workshop,
 Mont Saint-Michel, 1992, Paper nº 34).
 .LP
+[Resc01]
+Eric Rescorla,
+``SSL and TLS: Designing and Building Secure Systems,''
+Addison-Wesley, 2001. ISBN 0-201-61598-3, p. 387.
+.LP
 [RFC2138]
 C. Rigney, A. Rubens, W. Simpson, S. Willens,
 ``Remote Authentication Dial In User Service (RADIUS),''
@@ -2069,7 +2091,7 @@ March 1996, New Delhi, India.
 [Stei88]
 Jennifer G. Steiner, Clifford Neumann, and Jeffrey I. Schiller,
 ``\fIKerberos\fR: An Authentication Service for Open Network Systems,''
-Proceedings of USENIX Winter Conference, Dallas, Texas, February 1988, p. 191\-202.
+Proceedings of USENIX Winter Conference, Dallas, Texas, February 1988, pp. 191\-202.
 ... ftp://athena-dist.mit.edu/pub/kerberos/doc/usenix.PS
 .LP
 [Wu98]
@@ -2077,12 +2099,12 @@ T. Wu,
 ``The Secure Remote Password Protocol,''
 Proceedings of
 the 1998 Internet Society Network and Distributed System Security
-Symposium, San Diego, CA, Mar 1998, pp. 97-111.
+Symposium, San Diego, CA, March 1998, pp. 97-111.
 .LP
 [Ylon96]
 Ylonen, T.,
 ``SSH\(emSecure Login Connections Over the Internet,''
-6th USENIX Security Symposium, pp. 37-42. San Jose, CA, Jul. 1996.
+6th USENIX Security Symposium, pp. 37-42. San Jose, CA, July 1996.
 .SH
 Appendix: Summary of the PAK protocol
 .LP

Різницю між файлами не показано, бо вона завелика
+ 688 - 686
sys/doc/auth.ps


+ 837 - 0
sys/doc/fs/fs.html

@@ -0,0 +1,837 @@
+<html>
+<title>
+data
+</title>
+<body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#330088" ALINK="#FF0044">
+<H1>The Plan 9 File Server
+</H1>
+<DL><DD><I>Ken Thompson<br>
+ken@plan9.bell-labs.com<br>
+</I></DL>
+<DL><DD><H4>ABSTRACT</H4>
+This paper describes the structure
+and the operation of Plan 9 file servers.
+The specifics apply to
+our main Plan 9 file server
+Emelie,
+but
+the code is also the basis for
+the user level file server
+<TT>kfs</TT>.
+</DL>
+<H4>Introduction
+</H4>
+<P>
+The Plan 9 file server
+Emelie
+is the oldest piece of system software
+still in use on Plan 9.
+It evolved from a user-level program that served
+serial lines on a Sequent multi-processor.
+The current implementation is neither clean nor
+portable,
+but it has slowly come to terms with
+its particular set of cranky computers
+and devices.
+</P>
+<H4>Process Structure
+</H4>
+<P>
+The Plan 9 file system server is made from
+an ancient version of the Plan 9 kernel.
+The kernel contains process control,
+synchronization,
+locks,
+and some memory
+allocation.
+The kernel has no user processes or
+virtual memory.
+</P>
+<P>
+The structure of the file system server
+is a set of kernel processes
+synchronizing mostly through message passing.
+In Emelie there are 26 processes of 10 types:
+<DL><DT><DD><TT><PRE>
+number name  function
+  15       <TT>srv</TT>   Main file system server processes
+   1       <TT>rah</TT>   Block read-ahead processes
+  h'w'0'u'1       <TT>scp</TT>   Sync process
+  h'w'0'u'1       <TT>wcp</TT>   WORM copy process
+  h'w'0'u'1       <TT>con</TT>   Console process
+  h'w'0'u'1       <TT>ilo</TT>   IL protocol process
+  h'w'0'u'1       <TT>ilt</TT>   IL timer process
+  h'w'0'u'2       <TT>ethi</TT>   Ethernet input process
+  h'w'0'u'2       <TT>etho</TT>   Ethernet output process
+  h'w'0'u'1       <TT>flo</TT>   Floppy disk process
+</PRE></TT></DL>
+</P>
+<H4>The server processes
+</H4>
+<P>
+The main file system algorithm is a set
+of identical processes
+named
+<TT>srv</TT>
+that honor the
+9P protocol.
+Each file system process waits on
+a message queue for an incoming request.
+The request contains a 9P message and
+the address of a reply queue.
+A
+<TT>srv</TT>
+process parses the message,
+performs pseudo-disk I/O
+to the corresponding file system block device,
+formulates a response,
+and sends the
+response back to the reply queue.
+</P>
+<P>
+The unit of storage is a
+block of data on a device:
+<DL><DT><DD><TT><PRE>
+    enum
+    {
+        RBUFSIZE = 16*1024
+    };
+
+    typedef
+    struct
+    {
+        short   pad;
+        short	tag;
+        long	path;
+    } Tag;
+
+    enum
+    {
+        BUFSIZE = RBUFSIZE - sizeof(Tag)
+    };
+
+    typedef
+    struct
+    {
+        uchar   data[BUFSIZE];
+        Tag     tag;
+    } Block;
+</PRE></TT></DL>
+All devices are idealized as a perfect disk
+of contiguously numbered blocks each of size
+<TT>RBUFSIZE</TT>.
+Each block has a tag that identifies what type
+of block it is and a unique id of the file or directory
+where this block resides.
+The remaining data in the block depends on
+what type of block it is.
+</P>
+<P>
+The
+<TT>srv</TT>
+process's main data structure is the directory entry.
+This is the equivalent of a UNIX i-node and
+defines the set of block addresses that comprise a file or directory.
+Unlike the i-node,
+the directory entry also has the name of the
+file or directory in it:
+<DL><DT><DD><TT><PRE>
+    enum
+    {
+        NAMELEN = 28,
+        NDBLOCK = 6
+    };
+</PRE></TT></DL>
+<DL><DT><DD><TT><PRE>
+    typedef
+    struct
+    {
+        char    name[NAMELEN];
+        short   uid;
+        short   gid;
+        ushort  mode;
+        short   wuid;
+        Qid     qid;
+        long    size;
+        long    dblock[NDBLOCK];
+        long    iblock;
+        long    diblock;
+        long    atime;
+        long    mtime;
+    } Dentry;
+</PRE></TT></DL>
+Each directory entry holds the file or directory
+name, protection mode, access times, user-id, group-id, and addressing
+information.
+The entry
+<TT>wuid</TT>
+is the user-id of the last writer of the file
+and
+<TT>size</TT>
+is the size of the file in bytes.
+The first 6
+blocks of the file are held in the
+<TT>dblock</TT>
+array.
+If the file is larger than that,
+an indirect block is allocated that holds
+the next
+<TT>BUFSIZE/sizeof(long)</TT>
+blocks of the file.
+The indirect block address is held in the structure member
+<TT>iblock</TT>.
+If the file is larger yet,
+then there is a double indirect block that points
+at indirect blocks.
+The double indirect address is held in
+<TT>diblock</TT>
+and can point at another
+<TT>(BUFSIZE/sizeof(long))<sup>2</sup></TT>
+blocks of data.
+The maximum addressable size of a file is
+therefore 275 Gbytes.
+There is a tighter restriction of
+2<sup>32</sup>
+bytes because the length of a file is maintained in
+a long.
+Even so,
+sloppy use of long arithmetic restricts the length to
+2<sup>31</sup>
+bytes.
+These numbers are based on Emelie
+which has a block size of 16K and
+<TT>sizeof(long)</TT>
+is 4.
+It would be different if the size of a block
+changed.
+</P>
+<P>
+The declarations of the indirect and double indirect blocks
+are as follows.
+<DL><DT><DD><TT><PRE>
+    enum
+    {
+        INDPERBUF = BUFSIZE/sizeof(long),
+    };
+</PRE></TT></DL>
+<DL><DT><DD><TT><PRE>
+    typedef
+    {
+        long    dblock[INDPERBUF];
+        Tag     ibtag;
+    } Iblock;
+</PRE></TT></DL>
+<DL><DT><DD><TT><PRE>
+    typedef
+    {
+        long    iblock[INDPERBUF];
+        Tag     dibtag;
+    } Diblock;
+</PRE></TT></DL>
+</P>
+<P>
+The root of a file system is a single directory entry
+at a known block address.
+A directory is a file that consists of a list of
+directory entries.
+To make access easier,
+a directory entry cannot cross blocks.
+In Emelie there are 233 directory entries per block.
+</P>
+<P>
+The device on which the blocks reside is implicit
+and ultimately comes from the 9P
+<TT>attach</TT>
+message that specifies the name of the
+device containing the root.
+</P>
+<H4>Buffer Cache
+</H4>
+<P>
+When the file server is
+booted,
+all of the unused memory is allocated to
+a block buffer pool.
+There are two major operations on the buffer
+pool.
+<TT>Getbuf</TT>
+will find the buffer associated with a
+particular block on a particular device.
+The returned buffer is locked so that the
+caller has exclusive use.
+If the requested buffer is not in the pool,
+some other buffer will be relabeled and
+the data will be read from the requested device.
+<TT>Putbuf</TT>
+will unlock a buffer and
+if the contents are marked as modified,
+the buffer will be written to the device before
+the buffer is relabeled.
+If there is some special mapping
+or CPU cache flushing
+that must occur in order for the physical I/O
+device to access the buffers,
+this is done between
+<TT>getbuf</TT>
+and
+<TT>putbuf</TT>.
+The contents of a buffer is never touched
+except while it is locked between
+<TT>getbuf</TT>
+and
+<TT>putbuf</TT>
+calls.
+</P>
+<P>
+The
+file system server processes
+prevent deadlock in the buffers by
+always locking parent and child
+directory entries in that order.
+Since the entire directory structure
+is a hierarchy,
+this makes the locking well-ordered,
+preventing deadlock.
+The major problem in the locking strategy is
+that locks are at a block level and there are many
+directory entries in a single block.
+There are unnecessary lock conflicts
+in the directory blocks.
+When one of these directory blocks is tied up
+accessing the very slow WORM,
+then all I/O to dozens of unrelated directories
+is blocked.
+</P>
+<H4>Block Devices
+</H4>
+<P>
+The block device I/O system is like a
+protocol stack of filters.
+There are a set of pseudo-devices that call
+recursively to other pseudo-devices and real devices.
+The protocol stack is compiled from a configuration
+string that specifies the order of pseudo-devices and devices.
+Each pseudo-device and device has a set of entry points
+that corresponds to the operations that the file system
+requires of a device.
+The most notable operations are
+<TT>read</TT>,
+<TT>write</TT>,
+and
+<TT>size</TT>.
+</P>
+<P>
+The device stack can best be described by
+describing the syntax of the configuration string
+that specifies the stack.
+Configuration strings are used
+during the setup of the file system.
+For a description see
+<A href="/magic/man2html/8/fsconfig"><I>fsconfig</I>(8).
+</A>In the following recursive definition,
+<I>D</I>
+represents a
+string that specifies a block device.
+</P>
+<DL COMPACT>
+<DT><I>D</I> = (<I>DD</I>...)<DD>
+<br>
+This is a set of devices that
+are concatenated to form a single device.
+The size of the catenated device is the
+sum of the sizes of each sub-device.
+<DT><I>D</I> = [<I>DD</I>...]<DD>
+<br>
+This is the interleaving of the
+individual devices.
+If there are N devices in the list,
+then the pseudo-device is the N-way block
+interleaving of the sub-devices.
+The size of the interleaved device is
+N times the size of the smallest sub-device.
+<DT><I>D</I> = <TT>p</TT><I>DN1.N2</I><DD>
+<br>
+This is a partition of a sub-device.
+The sub-device is partitioned into 100 equal pieces.
+If the size of the sub-device is not divisible by 100,
+then there will be some slop thrown away at the top.
+The pseudo-device starts at the N1-th piece and
+continues for N2 pieces. Thus
+<TT>p<I>D</I>67.33</TT>
+will be the
+last third of the device
+<I>D</I>.
+<DT><I>D</I> = <TT>f</TT><I>D</I><DD>
+<br>
+This is a fake write-once-read-many device simulated by a
+second read-write device.
+This second device is partitioned
+into a set of block flags and a set of blocks.
+The flags are used to generate errors if a
+block is ever written twice or read without being written first.
+<DT><I>D</I> = <TT>c</TT><I>DD</I><DD>
+<br>
+This is the cache/WORM device made up of a cache (read-write)
+device and a WORM (write-once-read-many) device.
+More on this later.
+<DT><I>D</I> = <TT>o</TT><DD>
+<br>
+This is the dump file system that is the
+two-level hierarchy of all dumps ever taken on a cache/WORM.
+The read-only root of the cache/WORM file system
+(on the dump taken Feb 18, 1995) can
+be referenced as
+<TT>/1995/0218</TT>
+in this pseudo device.
+The second dump taken that day will be
+<TT>/1995/02181</TT>.
+<DT><I>D</I> = <TT>w</TT><I>N1.N2</I><DD>
+<br>
+This is a SCSI disk on controller N1 and target N2.
+<DT><I>D</I> = <TT>l</TT><I>N1.N2</I><DD>
+<br>
+This is the same as
+<TT>w</TT>,
+but one block from the SCSI disk is removed for labeling.
+<DT><I>D</I> = <TT>j(</TT><I>D<sub>1</sub></I><I>D<sub>2</sub></I><TT>*)</TT><I>D<sub>3</sub></I><DD>
+<br>
+<I>D<sub>1</sub></I>
+is the juke box SCSI interface.
+The
+<I>D<sub>2</sub></I>'s
+are the SCSI drives in the juke box
+and  the
+<I>D<sub>3</sub></I>'s
+are the demountable platters in the juke box.
+<I>D<sub>1</sub></I>
+and
+<I>D<sub>2</sub></I>
+must be
+<TT>w</TT>.
+<I>D<sub>3</sub></I>
+must be pseudo devices of
+<TT>w</TT>
+or
+<TT>l</TT>
+devices.
+</dl>
+<P>
+For both
+<TT>w</TT>
+and
+<TT>r</TT>
+devices any of the configuration numbers
+can be replaced by an iterator of the form
+<TT><<I>N1-N2</I>></TT>.
+Thus
+<DL><DT><DD><TT><PRE>
+    [w0.&#60;2-6&#62;]
+</PRE></TT></DL>
+is the interleaved SCSI disks on SCSI targets
+2 through 6 of SCSI controller 0.
+The main file system on
+Emelie
+is defined by the configuration string
+<DL><DT><DD><TT><PRE>
+    c[w1.&#60;0-5&#62;.0]j(w6w5w4w3w2)l(&#60;0-236&#62;l&#60;238-474&#62;)
+</PRE></TT></DL>
+This is a cache/WORM driver.
+The cache is three interleaved disks on SCSI controller 1
+targets 0, 1, 2, 3, 4, and 5.
+The WORM half of the cache/WORM
+is 474 jukebox disks.
+</P>
+<H4>The read-ahead processes
+</H4>
+<P>
+There are a set of file system processes,
+<TT>rah</TT>,
+that wait for messages consisting of a device and block
+address.
+When a message comes in,
+the process reads the specified block from the device.
+This is done by calling
+<TT>getbuf</TT>
+and
+<TT>putbuf</TT>.
+The purpose of this is the hope that these blocks
+will be used later and that they will reside in the
+buffer cache long enough not to be discarded before
+they are used.
+</P>
+<P>
+The messages to the read-ahead processes are
+generated by the server processes.
+The server processes maintain a relative block mark in every
+open file.
+Whenever an open file reads that relative block,
+the next 110 block addresses of the file are sent
+to the read-ahead processes and
+the relative block mark is advanced by 100.
+The initial relative block is set to 1.
+If the file is opened and
+only a few bytes are read,
+then no anticipating reads are performed
+since the relative block mark is set to 1
+and only block offset 0 is read.
+This is to prevent some
+fairly common action such as
+<DL><DT><DD><TT><PRE>
+    file *
+</PRE></TT></DL>
+from swamping the file system with read-ahead
+requests that will never be used.
+</P>
+<H4>Cache/WORM Driver
+</H4>
+<P>
+The cache/WORM (cw) driver is by far the
+largest and most complicated device driver in the file server.
+There are four devices involved in the cw driver.
+It implements a read/write pseudo-device (the cw-device)
+and a read-only pseudo-device (the dump device)
+by performing operations on its two constituent devices
+the read-write c-device and the write-once-read-many
+w-device.
+The block numbers on the four devices are distinct,
+although the cw addresses,
+dump addresses,
+and the w addresses are
+highly correlated.
+</P>
+<P>
+The cw-driver uses the w-device as the
+stable storage of the file system at the time of the
+last dump.
+All newly written and a large number of recently used
+exact copies of blocks of the w-device are kept on the c-device.
+The c-device is much smaller than the w-device and
+so the subset of w-blocks that are kept on the c-device are
+mapped through a hash table kept on a partition of the c-device.
+</P>
+<P>
+The map portion of the c-device consists of blocks of buckets of entries.
+The declarations follow.
+<DL><DT><DD><TT><PRE>
+    enum
+    {
+        BKPERBLK = 10,
+        CEPERBK  = (BUFSIZE - BKPERBLK*sizeof(long)) /
+                   (sizeof(Centry)*BKPERBLK),
+    };
+</PRE></TT></DL>
+<DL><DT><DD><TT><PRE>
+    typedef
+    struct
+    {
+        ushort   age;
+        short    state;
+        long     waddr;
+    } Centry;
+</PRE></TT></DL>
+<DL><DT><DD><TT><PRE>
+    typedef
+    struct
+    {
+        long     agegen;
+        Centry   entry[CEPERBK];
+    } Bucket;
+</PRE></TT></DL>
+<DL><DT><DD><TT><PRE>
+    Bucket   bucket[BKPERBLK];
+</PRE></TT></DL>
+There is exactly one entry structure for each block in the
+data partition of the c-device.
+A bucket contains all of the w-addresses that have
+the same hash code.
+There are as many buckets as will fit
+in a block and enough blocks to have the required
+number of entries.
+The entries in the bucket are maintained
+in FIFO order with an age variable and an incrementing age generator.
+When the age generator is about to overflow,
+all of the ages in the bucket are rescaled
+from zero.
+</P>
+<P>
+The following steps go into converting a w-address into a c-address.
+The bucket is found by
+<DL><DT><DD><TT><PRE>
+    bucket_number = w-address % total_buckets
+    getbuf(c-device, bucket_offset + bucket_number/BKPERBLK);
+</PRE></TT></DL>
+After the desired bucket is found,
+the desired entry is found by a linear search within the bucket for the
+entry with the desired
+<TT>waddr</TT>.
+</P>
+<P>
+The state variable in the entry is
+one of the following.
+<DL><DT><DD><TT><PRE>
+    enum
+    {
+        Cnone    = 0,
+        Cdirty,
+        Cdump,
+        Cread,
+        Cwrite,
+        Cdump1,
+    };
+</PRE></TT></DL>
+Every w-address has a state.
+Blocks that are not in the
+c-device have the implied
+state
+<TT>Cnone</TT>.
+The
+<TT>Cread</TT>
+state is for blocks that have the
+same data as the corresponding block in
+the w-device.
+Since the c-device is much faster than the
+w-device,
+<TT>Cread</TT>
+blocks are kept as long as possible and
+used in preference to reading the w-device.
+<TT>Cread</TT>
+blocks may be discarded from the c-device
+when the space is needed for newer data.
+The
+<TT>Cwrite</TT>
+state is when the c-device contains newer data
+than the corresponding block on the w-device.
+This happens when a
+<TT>Cnone</TT>,
+<TT>Cread</TT>,
+or
+<TT>Cwrite</TT>
+block is written.
+The
+<TT>Cdirty</TT>
+state
+is when the c-device contains
+new data and the corresponding block
+on the w-device has never been written.
+This happens when a new block has been
+allocated from the free space on the w-device.
+</P>
+<P>
+The
+<TT>Cwrite</TT>
+and
+<TT>Cdirty</TT>
+blocks are created and never removed.
+Unless something is done to
+convert these blocks,
+the c-device will gradually
+fill up and stop functioning.
+Once a day,
+or by command,
+a
+<I>dump</I>
+of the cw-device
+is taken.
+The purpose of
+a dump is to queue the writes that
+have been shunted to the c-device
+to be written to the w-device.
+Since the w-device is a WORM,
+blocks cannot be rewritten.
+Blocks that have already been written to the WORM must be
+relocated to the unused portion of the w-device.
+These are precisely the
+blocks with
+<TT>Cwrite</TT>
+state.
+</P>
+<P>
+The dump algorithm is as follows:
+a) The tree on the cw-device is walked
+as long as the blocks visited have been
+modified since the last dump.
+These are the blocks with state
+<TT>Cwrite</TT>
+and
+<TT>Cdirty</TT>.
+It is possible to restrict the search
+to within these blocks
+since the directory containing a modified
+file must have been accessed to modify the
+file and accessing a directory will set its
+modified time thus causing the block containing it
+to be written.
+The directory containing that directory must be
+modified for the same reason.
+The tree walk is thus drastically restrained and the
+tree walk does not take much time.
+b) All
+<TT>Cwrite</TT>
+blocks found in the tree search
+are relocated to new blank blocks on the w-device
+and converted to
+<TT>Cdump</TT>
+state.
+All
+<TT>Cdirty</TT>
+blocks are converted to
+<TT>Cdump</TT>
+state without relocation.
+At this point,
+all modified blocks in the cw-device
+have w-addresses that point to unwritten
+WORM blocks.
+These blocks are marked for later
+writing to the w-device
+with the state
+<TT>Cdump</TT>.
+c) All open files that were pointing to modified
+blocks are reopened to point at the corresponding
+reallocated blocks.
+This causes the directories leading to the
+open files to be modified.
+Thus the invariant discussed in a) is maintained.
+d) The background dumping process will slowly
+go through the map of the c-device and write out
+all blocks with
+<TT>Cdump</TT>
+state.
+</P>
+<P>
+The dump takes a few minutes to walk the tree
+and mark the blocks.
+It can take hours to write the marked blocks
+to the WORM.
+If a marked block is rewritten before the old
+copy has been written to the WORM,
+it must be forced to the WORM before it is rewritten.
+There is no problem if another dump is taken before the first one
+is finished.
+The newly marked blocks are just added to the marked blocks
+left from the first dump.
+</P>
+<P>
+If there is an error writing a marked block
+to the WORM
+then the
+<TT>dump</TT>
+state is converted to
+<TT>Cdump1</TT>
+and manual intervention is needed.
+(See the
+<TT>cwcmd</TT>
+<TT>mvstate</TT>
+command in
+<A href="/magic/man2html/8/fs"><I>fs</I>(8)).
+</A>These blocks can be disposed of by converting
+their state back to
+<TT>Cdump</TT>
+so that they will be written again.
+They can also be converted to
+<TT>Cwrite</TT>
+state so that they will be allocated new
+addresses at the next dump.
+In most other respects,
+a
+<TT>Cdump1</TT>
+block behaves like a
+<TT>Cwrite</TT>
+block.
+</P>
+<H4>Sync Copy and WORM Copy Processes
+</H4>
+<P>
+The
+<TT>scp</TT>
+process
+wakes up every ten seconds and
+issues writes to blocks in the buffer cache
+that have been modified.
+This is done automatically on important
+console commands such as
+<TT>halt</TT>
+and
+<TT>dump</TT>.
+</P>
+<P>
+The
+<TT>wcp</TT>
+process also wakes up every ten seconds
+and tries to copy a
+<TT>dump</TT>
+block from the cache to the WORM.
+As long as there are
+<TT>dump</TT>
+blocks to copy and there is no competition for
+the WORM device,
+the copy will continue at full speed.
+Whenever there is competition for the WORM
+or there are no more blocks to
+copy,
+then the process will sleep ten seconds
+before looking again.
+</P>
+<P>
+The HP WORM jukebox consists of
+238 disks divided into 476 sides
+or platters.
+Platter 0 is the
+<I>A</I>
+side of disk 0.
+Platter 1 is the
+<I>A</I>
+side of the disk 1.
+Platter 238 is the
+<I>B</I>
+side of disk 0.
+On Emelie,
+the main file system is configured
+on both sides of the first 237 disks,
+platters 0-236 and 238-474.
+</P>
+<H4>9P Protocol Drivers
+</H4>
+<P>
+The file server described so far
+waits for 9P protocol messages to
+appear in its input queue.
+It processes each message and
+sends the reply back to the originator.
+There are groups of processes that
+perform protocol I/O on some network or
+device and the resulting messages
+are sent to the file system queue.
+</P>
+<P>
+There are two sets of processes
+<TT>ethi</TT>
+and
+<TT>etho</TT>
+that perform Ethernet input and output on two different networks.
+These processes send Ethernet messages
+to/from two more processes
+<TT>ilo</TT>
+and
+<TT>ilt</TT>
+that do the IL reliable datagram protocol
+on top of IP packets.
+</P>
+<P>
+The last process in Emelie,
+<TT>con</TT>,
+reads the console
+and calls internal subroutines to
+executes commands typed.
+Since there is only one process,
+only one command can be executing at a
+time.
+See
+<A href="/magic/man2html/8/fs"><I>fs</I>(8)
+</A>for a description of the
+commands available at the console.
+
+</P>
+<br>&#32;<br>
+<A href=http://www.lucent.com/copyright.html>
+Copyright</A> &#169; 2000 Lucent Technologies Inc.  All rights reserved.
+</body></html>

BIN
sys/doc/fs/fs.pdf


+ 427 - 0
sys/doc/il/il.html

@@ -0,0 +1,427 @@
+<html>
+<title>
+-
+</title>
+<body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#330088" ALINK="#FF0044">
+<H1>The IL protocol
+</H1>
+<DL><DD><I>Dave Presotto<br>
+Phil Winterbottom<br>
+<br>&#32;<br>
+presotto,philw@plan9.bell-labs.com<br>
+</I></DL>
+<DL><DD><H4>ABSTRACT</H4>
+To transport the remote procedure call messages of the Plan 9 file system
+protocol 9P, we have implemented a new network protocol, called IL.
+It is a connection-based, lightweight transport protocol that carries
+datagrams encapsulated by IP.
+IL provides retransmission of lost messages and in-sequence delivery, but has
+no flow control and no blind retransmission.
+</DL>
+<H4>Introduction
+</H4>
+<P>
+Plan 9 uses a file system protocol, called 9P [PPTTW93], that assumes
+in-sequence guaranteed delivery of delimited messages
+holding remote procedure call
+(RPC) requests and responses.
+None of the standard IP protocols [RFC791] is suitable for transmission of
+9P messages over an Ethernet or the Internet.
+TCP [RFC793] has a high overhead and does not preserve delimiters.
+UDP [RFC768], while cheap and preserving message delimiters, does not provide
+reliable sequenced delivery.
+When we were implementing IP, TCP, and UDP in our system we
+tried to choose a protocol suitable for carrying 9P.
+The properties we desired were:
+</P>
+<DL COMPACT>
+<DT>*<DD>
+Reliable datagram service
+<DT>*<DD>
+In-sequence delivery
+<DT>*<DD>
+Internetworking using IP
+<DT>*<DD>
+Low complexity, high performance
+<DT>*<DD>
+Adaptive timeouts
+</dl>
+<br>&#32;<br>
+No standard protocol met our needs so we designed a new one,
+called IL (Internet Link).
+<P>
+IL is a lightweight protocol encapsulated by IP.
+It is connection-based and
+provides reliable transmission of sequenced messages.
+No provision is made for flow control since the protocol
+is designed to transport RPC
+messages between client and server, a structure with inherent flow limitations.
+A small window for outstanding messages prevents too
+many incoming messages from being buffered;
+messages outside the window are discarded
+and must be retransmitted.
+Connection setup uses a two-way handshake to generate
+initial sequence numbers at each end of the connection;
+subsequent data messages increment the
+sequence numbers to allow
+the receiver to resequence out of order messages. 
+In contrast to other protocols, IL avoids blind retransmission.
+This helps performance in congested networks,
+where blind retransmission could cause further
+congestion.
+Like TCP, IL has adaptive timeouts,
+so the protocol performs well both on the
+Internet and on local Ethernets.
+A round-trip timer is used
+to calculate acknowledge and retransmission times
+that match the network speed.
+</P>
+<H4>Connections
+</H4>
+<P>
+An IL connection carries a stream of data between two end points.
+While the connection persists,
+data entering one side is sent to the other side in the same sequence.
+The functioning of a connection is described by the state machine in Figure 1,
+which shows the states (circles) and transitions between them (arcs).
+Each transition is labeled with the list of events that can cause
+the transition and, separated by a horizontal line,
+the messages sent or received on that transition.
+The remainder of this paper is a discussion of this state machine.
+
+<DL><DT><DD><TT><PRE>
+<br><img src="-.15070.gif"><br>
+
+<DL><DD>
+</PRE></TT></DL>
+</P>
+<DL COMPACT>
+<DT><I>ackok</I><DD>
+any sequence number between id0 and next inclusive
+<DT><I>!x</I><DD>
+any value except x
+<DT>-<DD>
+any value
+</DL>
+<br>&#32;<br>
+<I>Figure 1 - IL State Transitions</I>
+</dl>
+<P>
+The IL state machine has five states:
+<I>Closed</I>,
+<I>Syncer</I>,
+<I>Syncee</I>,
+<I>Established</I>,
+and
+<I>Closing</I>.
+The connection is identified by the IP address and port number used at each end.
+The addresses ride in the IP protocol header, while the ports are part of the
+18-byte IL header.
+The local variables identifying the state of a connection are:
+<DL><DD>
+</P>
+<DL COMPACT>
+<DT>state<DD>
+one of the states
+<DT>laddr<DD>
+32-bit local IP address
+<DT>lport<DD>
+16-bit local IL port
+<DT>raddr<DD>
+32-bit remote IP address
+<DT>rport<DD>
+16-bit remote IL port
+<DT>id0<DD>
+32-bit starting sequence number of the local side
+<DT>rid0<DD>
+32-bit starting sequence number of the remote side
+<DT>next<DD>
+sequence number of the next message to be sent from the local side
+<DT>rcvd<DD>
+the last in-sequence message received from the remote side
+<DT>unacked<DD>
+sequence number of the first unacked message
+</DL>
+</dl>
+<P>
+Unused connections are in the
+<I>Closed</I>
+state with no assigned addresses or ports.
+Two events open a connection: the reception of
+a message whose addresses and ports match no open connection
+or a user explicitly opening a connection.
+In the first case, the message's source address and port become the
+connection's remote address and port and the message's destination address
+and port become the local address and port.
+The connection state is set to
+<I>Syncee</I>
+and the message is processed.
+In the second case, the user specifies both local and remote addresses and ports.
+The connection's state is set to
+<I>Syncer</I>
+and a
+<TT>sync</TT>
+message is sent to the remote side.
+The legal values for the local address are constrained by the IP implementation.
+</P>
+<H4>Sequence Numbers
+</H4>
+<P>
+IL carries data messages.
+Each message corresponds to a single write from
+the operating system and is identified by a 32-bit
+sequence number.
+The starting sequence number for each direction in a
+connection is picked at random and transmitted in the initial
+<TT>sync</TT>
+message.
+The number is incremented for each subsequent data message.
+A retransmitted message contains its original sequence number.
+</P>
+<H4>Transmission/Retransmission
+</H4>
+<P>
+Each message contains two sequence numbers:
+an identifier (ID) and an acknowledgement.
+The acknowledgement is the last in-sequence
+data message received by the transmitter of the message.
+For
+<TT>data</TT>
+and
+<TT>dataquery</TT>
+messages, the ID is its sequence number.
+For the control messages
+<TT>sync</TT>,
+<TT>ack</TT>,
+<TT>query</TT>,
+<TT>state</TT>,
+and
+<TT>close</TT>,
+the ID is one greater than the sequence number of
+the highest sent data message.
+</P>
+<P>
+The sender transmits data messages with type
+<TT>data</TT>.
+Any messages traveling in the opposite direction carry acknowledgements.
+An
+<TT>ack</TT>
+message will be sent within 200 milliseconds of receiving the data message
+unless a returning message has already piggy-backed an
+acknowledgement to the sender.
+</P>
+<P>
+In IP, messages may be delivered out of order or
+may be lost due to congestion or faults.
+To overcome this,
+IL uses a modified ``go back n'' protocol that also attempts
+to avoid aggravating network congestion.
+An average round trip time is maintained by measuring the delay between
+the transmission of a message and the
+receipt of its acknowledgement.
+Until the first acknowledge is received, the average round trip time
+is assumed to be 100ms.
+If an acknowledgement is not received within four round trip times
+of the first unacknowledged message
+(<I>rexmit timeout</I>
+in Figure 1), IL assumes the message or the acknowledgement
+has been lost.
+The sender then resends only the first unacknowledged message,
+setting the type to
+<TT>dataquery</TT>.
+When the receiver receives a
+<TT>dataquery</TT>,
+it responds with a
+<TT>state</TT>
+message acknowledging the highest received in-sequence data message.
+This may be the retransmitted message or, if the receiver has been
+saving up out-of-sequence messages, some higher numbered message.
+Implementations of the receiver are free to choose whether to save out-of-sequence messages.
+Our implementation saves up to 10 packets ahead.
+When the sender receives the
+<TT>state</TT>
+message, it will immediately resend the next unacknowledged message
+with type
+<TT>dataquery</TT>.
+This continues until all messages are acknowledged.
+</P>
+<P>
+If no acknowledgement is received after the first
+<TT>dataquery</TT>,
+the transmitter continues to timeout and resend the
+<TT>dataquery</TT>
+message.
+The intervals between retransmissions increase exponentially.
+After 300 times the round trip time
+(<I>death timeout</I>
+in Figure 1), the sender gives up and
+assumes the connection is dead.
+</P>
+<P>
+Retransmission also occurs in the states
+<I>Syncer</I>,
+<I>Syncee</I>,
+and
+<I>Close</I>.
+The retransmission intervals are the same as for data messages.
+</P>
+<H4>Keep Alive
+</H4>
+<P>
+Connections to dead systems must be discovered and torn down
+lest they consume resources.
+If the surviving system does not need to send any data and
+all data it has sent has been acknowledged, the protocol
+described so far will not discover these connections.
+Therefore, in the
+<I>Established</I>
+state, if no other messages are sent for a 6 second period,
+a
+<TT>query</TT>
+is sent.
+The receiver always replies to a
+<TT>query</TT>
+with a
+<TT>state</TT>
+message.
+If no messages are received for 30 seconds, the
+connection is torn down.
+This is not shown in Figure 1.
+</P>
+<H4>Byte Ordering
+</H4>
+<P>
+All 32- and 16-bit quantities are transmitted high-order byte first, as
+is the custom in IP.
+</P>
+<H4>Formats
+</H4>
+<P>
+The following is a C language description of an IP+IL
+header, assuming no IP options:
+<DL><DT><DD><TT><PRE>
+typedef unsigned char byte;
+struct IPIL
+{
+	byte	vihl;       /* Version and header length */
+	byte	tos;        /* Type of service */
+	byte	length[2];  /* packet length */
+	byte	id[2];      /* Identification */
+	byte	frag[2];    /* Fragment information */
+	byte	ttl;        /* Time to live */
+	byte	proto;      /* Protocol */
+	byte	cksum[2];   /* Header checksum */
+	byte	src[4];     /* Ip source */
+	byte	dst[4];     /* Ip destination */
+	byte	ilsum[2];   /* Checksum including header */
+	byte	illen[2];   /* Packet length */
+	byte	iltype;     /* Packet type */
+	byte	ilspec;     /* Special */
+	byte	ilsrc[2];   /* Src port */
+	byte	ildst[2];   /* Dst port */
+	byte	ilid[4];    /* Sequence id */
+	byte	ilack[4];   /* Acked sequence */
+};
+</PRE></TT></DL>
+</P>
+<br>&#32;<br>
+Data is assumed to immediately follow the header in the message.
+<TT>Ilspec</TT>
+is an extension reserved for future protocol changes.
+<P>
+The checksum is calculated with
+<TT>ilsum</TT>
+and
+<TT>ilspec</TT>
+set to zero.
+It is the standard IP checksum, that is, the 16-bit one's complement of the one's
+complement sum of all 16 bit words in the header and text.  If a
+message contains an odd number of header and text bytes to be
+checksummed, the last byte is padded on the right with zeros to
+form a 16-bit word for the checksum.
+The checksum covers from
+<TT>cksum</TT>
+to  the end of the data.
+</P>
+<P>
+The possible
+<I>iltype</I>
+values are:
+<DL><DT><DD><TT><PRE>
+enum {
+	sync=		0,
+	data=		1,
+	dataquery=	2,
+	ack=		3,
+	query=		4,
+	state=		5,
+	close=		6,
+};
+</PRE></TT></DL>
+</P>
+<br>&#32;<br>
+The
+<TT>illen</TT>
+field is the size in bytes of the IL header (18 bytes) plus the size of the data.
+<H4>Numbers
+</H4>
+<P>
+The IP protocol number for IL is 40.
+</P>
+<P>
+The assigned IL port numbers are:
+<DL><DD>
+</P>
+<DL COMPACT>
+<DT>7<DD>
+echo all input to output
+<DT>9<DD>
+discard input
+<DT>19<DD>
+send a standard pattern to output
+<DT>565<DD>
+send IP addresses of caller and callee to output
+<DT>566<DD>
+Plan 9 authentication protocol
+<DT>17005<DD>
+Plan 9 CPU service, data
+<DT>17006<DD>
+Plan 9 CPU service, notes
+<DT>17007<DD>
+Plan 9 exported file systems
+<DT>17008<DD>
+Plan 9 file service
+<DT>17009<DD>
+Plan 9 remote execution
+<DT>17030<DD>
+Alef Name Server
+</DL>
+</dl>
+<H4>References
+</H4>
+<br>&#32;<br>
+[PPTTW93] Rob Pike, Dave Presotto, Ken Thompson, Howard Trickey, and Phil Winterbottom,
+``The Use of Name Spaces in Plan 9'',
+<I>Op. Sys. Rev.,</I>
+Vol. 27, No. 2, April 1993, pp. 72-76,
+reprinted in this volume.
+<br>
+[RFC791] RFC791,
+<I>Internet Protocol,</I>
+<I>DARPA Internet Program Protocol Specification,</I>
+September 1981.
+<br>
+[RFC793] RFC793,
+<I>Transmission Control Protocol,</I>
+<I>DARPA Internet Program Protocol Specification,</I>
+September 1981.
+<br>
+[RFC768] J. Postel, RFC768,
+<I>User Datagram Protocol,</I>
+<I>DARPA Internet Program Protocol Specification,</I>
+August 1980.
+
+<br>&#32;<br>
+<A href=http://www.lucent.com/copyright.html>
+Copyright</A> &#169; 2000 Lucent Technologies Inc.  All rights reserved.
+</body></html>

BIN
sys/doc/il/il.pdf


+ 36 - 37
sys/doc/libmach.html

@@ -47,39 +47,38 @@ application program support for a new architecture.
 </H4>
 <P>
 Architecture-dependent information for the new processor
-is stored in the directory tree rooted at
-</I><TT>/<I>m</TT><I>
+is stored in the directory tree rooted at <TT>/</TT><I>m</I>
 where
-</I><I>m</I><I>
+<I>m</I>
 is the name of the new architecture (e.g.,
-</I><TT>mips</TT><I>).
+<TT>mips</TT>).
 The new directory should be initialized with several important
 subdirectories, notably
-</I><TT>bin</TT><I>,
-</I><TT>include</TT><I>,
+<TT>bin</TT>,
+<TT>include</TT>,
 and
-</I><TT>lib</TT><I>.
+<TT>lib</TT>.
 The directory tree of an existing architecture
 serves as a good model for the new tree.
 The architecture-dependent
-</I><TT>mkfile</TT><I>
+<TT>mkfile</TT>
 must be stored in the newly created root directory
 for the architecture.  It is easiest to copy the
 mkfile for an existing architecture and modify
 it for the new architecture.  When the mkfile
 is correct, change the
-</I><TT>OS</TT><I>
+<TT>OS</TT>
 and
-</I><TT>CPUS</TT><I>
+<TT>CPUS</TT>
 variables in the
-</I><TT>/sys/src/mkfile.proto</TT><I>
+<TT>/sys/src/mkfile.proto</TT>
 to reflect the addition of the new architecture.
 </P>
-</I><H4>Headers
+<H4>Headers
 </H4>
 <br>&#32;<br>
 Architecture-dependent headers are stored in directory
-<TT>/<I>m</I>/include</TT>
+<TT>/&lt;I&gt;m&lt;/I&gt;/include</TT>
 where
 <I>m</I>
 is the name of the architecture (e.g.,
@@ -403,7 +402,7 @@ A variety of symbol table access functions then support
 queries on the reformatted table.
 <DT>Debugger Support - <DD>
 Files named
-<TT><I>m</I>.c</TT>,
+<TT>&lt;I&gt;m&lt;/I&gt;.c</TT>,
 where
 <I>m</I>
 is the code letter assigned to the architecture,
@@ -416,7 +415,7 @@ an initialized
 <TT>Machdata</TT>
 structure are stored in
 files named
-<TT><I>m</I>db.c</TT>.
+<TT>&lt;I&gt;m&lt;/I&gt;db.c</TT>.
 Files
 <TT>machdata.c</TT>
 and
@@ -448,7 +447,7 @@ and extract references to symbols.  File
 <TT>obj.c</TT>
 contains code common to all architectures;
 file
-<TT><I>m</I>obj.c</TT>
+<TT>&lt;I&gt;m&lt;/I&gt;obj.c</TT>
 contains the architecture-specific source code
 for the machine with code character
 <I>m</I>.
@@ -528,7 +527,7 @@ A symbolic code for the object file.
 <DL COMPACT>
 <DT>2.<DD>
 In a file name
-<TT>/sys/src/libmach/<I>m</I>.c</TT>
+<TT>/sys/src/libmach/&lt;I&gt;m&lt;/I&gt;.c</TT>
 (where
 <I>m</I>
 is the identifier character assigned to the architecture),
@@ -545,7 +544,7 @@ Most of the fields of the
 data structure are obvious
 but a few require further explanation.
 <DL><DD>
-<DT><TT>kbase</TT> - <DD>
+<DT>&lt;TT&gt;kbase&lt;/TT&gt; - <DD>
 This field
 contains the address of the kernel 
 <TT>ublock</TT>.
@@ -555,7 +554,7 @@ assume the first entry of the kernel
 points to the
 <TT>Proc</TT>
 structure for a kernel thread.
-<DT><TT>ktmask</TT> - <DD>
+<DT>&lt;TT&gt;ktmask&lt;/TT&gt; - <DD>
 This field
 is a bit mask used to calculate the kernel text address from
 the kernel 
@@ -566,7 +565,7 @@ kernel text segment is calculated by
 ANDing
 the negation of this mask with
 <TT>kbase</TT>.
-<DT><TT>kspoff</TT> - <DD>
+<DT>&lt;TT&gt;kspoff&lt;/TT&gt; - <DD>
 This field
 contains the byte offset in the
 <TT>Proc</TT>
@@ -577,7 +576,7 @@ is the offset to the
 field of a
 <TT>Proc</TT>
 table entry.
-<DT><TT>kpcoff</TT> - <DD>
+<DT>&lt;TT&gt;kpcoff&lt;/TT&gt; - <DD>
 This field contains the byte offset into the
 <TT>Proc</TT>
 data structure
@@ -587,7 +586,7 @@ This is the offset to
 field
 <TT>sched.pc</TT>
 in that structure.
-<DT><TT>kspdelta</TT> and <TT>kpcdelta</TT> - <DD>
+<DT>&lt;TT&gt;kspdelta&lt;/TT&gt; and &lt;TT&gt;kpcdelta&lt;/TT&gt; - <DD>
 These fields
 contain corrections to be added to
 the stack pointer and program counter, respectively,
@@ -603,7 +602,7 @@ in the
 data structure.
 Most architectures require no bias
 and these fields contain zeros.
-<DT><TT>scalloff</TT> - <DD>
+<DT>&lt;TT&gt;scalloff&lt;/TT&gt; - <DD>
 This field
 contains the byte offset of the
 <TT>scallnr</TT>
@@ -701,7 +700,7 @@ architecture can be adopted with minor modifications.
 <DT>4.<DD>
 Write an object file parser and
 store it in file
-<TT>/sys/src/libmach/<I>m</I>obj.c</TT>
+<TT>/sys/src/libmach/&lt;I&gt;m&lt;/I&gt;obj.c</TT>
 where
 <I>m</I>
 is the identifier character assigned to the architecture.
@@ -726,7 +725,7 @@ initialize the parameters and jump table of the
 data structure for the architecture.
 This code is conventionally stored in
 a file named
-<TT>/sys/src/libmach/<I>m</I>db.c</TT>
+<TT>/sys/src/libmach/&lt;I&gt;m&lt;/I&gt;db.c</TT>
 where
 <I>m</I>
 is the identifier character assigned to the architecture.
@@ -734,11 +733,11 @@ The fields of the
 <TT>Machdata</TT>
 structure are:
 <DL><DD>
-<DT><TT>bpinst</TT> and <TT>bpsize</TT> - <DD>
+<DT>&lt;TT&gt;bpinst&lt;/TT&gt; and &lt;TT&gt;bpsize&lt;/TT&gt; - <DD>
 These fields
 contain the breakpoint instruction and the size
 of the instruction, respectively.
-<DT><TT>swab</TT> - <DD>
+<DT>&lt;TT&gt;swab&lt;/TT&gt; - <DD>
 This field
 contains the address of a function to
 byte-swap a 16-bit value.  Choose
@@ -746,7 +745,7 @@ byte-swap a 16-bit value.  Choose
 or
 <TT>beswab</TT>
 for little-endian or big-endian architectures, respectively.
-<DT><TT>swal</TT> - <DD>
+<DT>&lt;TT&gt;swal&lt;/TT&gt; - <DD>
 This field
 contains the address of a function to
 byte-swap a 32-bit value.  Choose
@@ -754,7 +753,7 @@ byte-swap a 32-bit value.  Choose
 or
 <TT>beswal</TT>
 for little-endian or big-endian architectures, respectively.
-<DT><TT>ctrace</TT> - <DD>
+<DT>&lt;TT&gt;ctrace&lt;/TT&gt; - <DD>
 This field
 contains the address of a function to perform a
 C-language stack trace.  Two general trace functions,
@@ -767,7 +766,7 @@ new architecture conforms to one of
 these models, select the appropriate function.  If the
 stack model is unique,
 supply a custom stack trace function.
-<DT><TT>findframe</TT> - <DD>
+<DT>&lt;TT&gt;findframe&lt;/TT&gt; - <DD>
 This field
 contains the address of a function to locate the stack
 frame associated with a text address.
@@ -777,7 +776,7 @@ and
 <TT>ciscframe</TT>
 process fixed-frame and relative-frame stack
 models.
-<DT><TT>ufixup</TT> - <DD>
+<DT>&lt;TT&gt;ufixup&lt;/TT&gt; - <DD>
 This field
 contains the address of a function to adjust
 the base address of the register save area.
@@ -785,7 +784,7 @@ Currently, only the
 68020 requires this bias
 to offset over the active
 exception frame.
-<DT><TT>excep</TT> - <DD>
+<DT>&lt;TT&gt;excep&lt;/TT&gt; - <DD>
 This field
 contains the address of a function to produce a
 text
@@ -793,11 +792,11 @@ string describing the
 current exception.
 Each architecture stores exception
 information uniquely, so this code must always be supplied.
-<DT><TT>bpfix</TT> - <DD>
+<DT>&lt;TT&gt;bpfix&lt;/TT&gt; - <DD>
 This field
 contains the address of a function to adjust an
 address prior to laying down a breakpoint.
-<DT><TT>sftos</TT> - <DD>
+<DT>&lt;TT&gt;sftos&lt;/TT&gt; - <DD>
 This field
 contains the address of a function to convert a single
 precision floating point value
@@ -807,7 +806,7 @@ for little-endian
 or
 <TT>beieeesftos</TT>
 for big-endian architectures.
-<DT><TT>dftos</TT> - <DD>
+<DT>&lt;TT&gt;dftos&lt;/TT&gt; - <DD>
 This field
 contains the address of a function to convert a double
 precision floating point value
@@ -817,7 +816,7 @@ for little-endian
 or
 <TT>beieeedftos</TT>
 for big-endian architectures.
-<DT><TT>foll</TT>, <TT>das</TT>, <TT>hexinst</TT>, and <TT>instsize</TT> - <DD>
+<DT>&lt;TT&gt;foll&lt;/TT&gt;, &lt;TT&gt;das&lt;/TT&gt;, &lt;TT&gt;hexinst&lt;/TT&gt;, and &lt;TT&gt;instsize&lt;/TT&gt; - <DD>
 These fields point to functions that interpret machine
 instructions.
 They rely on disassembly of the instruction
@@ -907,5 +906,5 @@ and load with
 </dl>
 <br>&#32;<br>
 <A href=http://www.lucent.com/copyright.html>
-Copyright</A> &#169; 2000 Lucent Technologies Inc.  All rights reserved.
+Copyright</A> &#169; 2002 Lucent Technologies Inc.  All rights reserved.
 </body></html>

+ 1 - 2
sys/doc/libmach.ms

@@ -42,8 +42,7 @@ application program support for a new architecture.
 Directory Structure
 .PP
 Architecture-dependent information for the new processor
-is stored in the directory tree rooted at
-.CW /\fIm
+is stored in the directory tree rooted at \f(CW/\fP\fIm\fP
 where
 .I m
 is the name of the new architecture (e.g.,

+ 1 - 1
sys/doc/mkfile

@@ -65,7 +65,7 @@ print:V: \
 	compiler.ps \
 	libmach.ps \
 	fs/fs.ps \
-	vent/venti.ps \
+	venti/venti.ps \
 	il/il.ps \
 	sleep.ps \
 	lexnames.ps \

+ 1379 - 0
sys/doc/net/net.html

@@ -0,0 +1,1379 @@
+<html>
+<title>
+data
+</title>
+<body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#330088" ALINK="#FF0044">
+<H1>The Organization of Networks in Plan 9
+</H1>
+<DL><DD><I>Dave Presotto<br>
+Phil Winterbottom<br>
+<br>&#32;<br>
+presotto,philw@plan9.bell-labs.com<br>
+</I></DL>
+<DL><DD><H4>ABSTRACT</H4>
+<DL>
+<DT><DT>&#32;<DD>
+NOTE:<I> Originally appeared in
+Proc. of the Winter 1993 USENIX Conf.,
+pp. 271-280,
+San Diego, CA
+</I><DT>&#32;<DD></dl>
+<br>
+In a distributed system networks are of paramount importance. This
+paper describes the implementation, design philosophy, and organization
+of network support in Plan 9. Topics include network requirements
+for distributed systems, our kernel implementation, network naming, user interfaces,
+and performance. We also observe that much of this organization is relevant to
+current systems.
+</DL>
+<H4>1 Introduction
+</H4>
+<P>
+Plan 9 [Pike90] is a general-purpose, multi-user, portable distributed system
+implemented on a variety of computers and networks.
+What distinguishes Plan 9 is its organization.
+The goals of this organization were to
+reduce administration
+and to promote resource sharing. One of the keys to its success as a distributed
+system is the organization and management of its networks.
+</P>
+<P>
+A Plan 9 system comprises file servers, CPU servers and terminals.
+The file servers and CPU servers are typically centrally
+located multiprocessor machines with large memories and
+high speed interconnects.
+A variety of workstation-class machines
+serve as terminals
+connected to the central servers using several networks and protocols.
+The architecture of the system demands a hierarchy of network
+speeds matching the needs of the components.
+Connections between file servers and CPU servers are high-bandwidth point-to-point
+fiber links.
+Connections from the servers fan out to local terminals
+using medium speed networks
+such as Ethernet [Met80] and Datakit [Fra80].
+Low speed connections via the Internet and
+the AT&amp;T backbone serve users in Oregon and Illinois.
+Basic Rate ISDN data service and 9600 baud serial lines provide slow
+links to users at home.
+</P>
+<P>
+Since CPU servers and terminals use the same kernel,
+users may choose to run programs locally on
+their terminals or remotely on CPU servers.
+The organization of Plan 9 hides the details of system connectivity
+allowing both users and administrators to configure their environment
+to be as distributed or centralized as they wish.
+Simple commands support the
+construction of a locally represented name space
+spanning many machines and networks.
+At work, users tend to use their terminals like workstations,
+running interactive programs locally and
+reserving the CPU servers for data or compute intensive jobs
+such as compiling and computing chess endgames.
+At home or when connected over
+a slow network, users tend to do most work on the CPU server to minimize
+traffic on the slow links.
+The goal of the network organization is to provide the same
+environment to the user wherever resources are used.
+</P>
+<H4>2 Kernel Network Support
+</H4>
+<P>
+Networks play a central role in any distributed system. This is particularly
+true in Plan 9 where most resources are provided by servers external to the kernel.
+The importance of the networking code within the kernel
+is reflected by its size;
+of 25,000 lines of kernel code, 12,500 are network and protocol related.
+Networks are continually being added and the fraction of code
+devoted to communications
+is growing.
+Moreover, the network code is complex.
+Protocol implementations consist almost entirely of
+synchronization and dynamic memory management, areas demanding 
+subtle error recovery
+strategies.
+The kernel currently supports Datakit, point-to-point fiber links,
+an Internet (IP) protocol suite and ISDN data service.
+The variety of networks and machines
+has raised issues not addressed by other systems running on commercial
+hardware supporting only Ethernet or FDDI.
+</P>
+<H4>2.1 The File System protocol
+</H4>
+<P>
+A central idea in Plan 9 is the representation of a resource as a hierarchical
+file system.
+Each process assembles a view of the system by building a
+<I>name space</I>
+[Needham] connecting its resources.
+File systems need not represent disc files; in fact, most Plan 9 file systems have no
+permanent storage.
+A typical file system dynamically represents
+some resource like a set of network connections or the process table.
+Communication between the kernel, device drivers, and local or remote file servers uses a
+protocol called 9P. The protocol consists of 17 messages
+describing operations on files and directories.
+Kernel resident device and protocol drivers use a procedural version
+of the protocol while external file servers use an RPC form.
+Nearly all traffic between Plan 9 systems consists
+of 9P messages.
+9P relies on several properties of the underlying transport protocol.
+It assumes messages arrive reliably and in sequence and
+that delimiters between messages
+are preserved.
+When a protocol does not meet these
+requirements (for example, TCP does not preserve delimiters)
+we provide mechanisms to marshal messages before handing them
+to the system.
+</P>
+<P>
+A kernel data structure, the
+<I>channel</I>,
+is a handle to a file server.
+Operations on a channel generate the following 9P messages.
+The
+<TT>session</TT>
+and
+<TT>attach</TT>
+messages authenticate a connection, established by means external to 9P,
+and validate its user.
+The result is an authenticated
+channel
+referencing the root of the
+server.
+The
+<TT>clone</TT>
+message makes a new channel identical to an existing channel, much like
+the
+<TT>dup</TT>
+system call.
+A
+channel
+may be moved to a file on the server using a
+<TT>walk</TT>
+message to descend each level in the hierarchy.
+The
+<TT>stat</TT>
+and
+<TT>wstat</TT>
+messages read and write the attributes of the file referenced by a channel.
+The
+<TT>open</TT>
+message prepares a channel for subsequent
+<TT>read</TT>
+and
+<TT>write</TT>
+messages to access the contents of the file.
+<TT>Create</TT>
+and
+<TT>remove</TT>
+perform the actions implied by their names on the file
+referenced by the channel.
+The
+<TT>clunk</TT>
+message discards a channel without affecting the file.
+</P>
+<P>
+A kernel resident file server called the
+<I>mount driver</I>
+converts the procedural version of 9P into RPCs.
+The
+<I>mount</I>
+system call provides a file descriptor, which can be
+a pipe to a user process or a network connection to a remote machine, to
+be associated with the mount point.
+After a mount, operations
+on the file tree below the mount point are sent as messages to the file server.
+The
+mount
+driver manages buffers, packs and unpacks parameters from
+messages, and demultiplexes among processes using the file server.
+</P>
+<H4>2.2 Kernel Organization
+</H4>
+<P>
+The network code in the kernel is divided into three layers: hardware interface,
+protocol processing, and program interface.
+A device driver typically uses streams to connect the two interface layers.
+Additional stream modules may be pushed on
+a device to process protocols.
+Each device driver is a kernel-resident file system.
+Simple device drivers serve a single level
+directory containing just a few files;
+for example, we represent each UART
+by a data and a control file.
+<DL><DT><DD><TT><PRE>
+cpu% cd /dev
+cpu% ls -l eia*
+--rw-rw-rw- t 0 bootes bootes 0 Jul 16 17:28 eia1
+--rw-rw-rw- t 0 bootes bootes 0 Jul 16 17:28 eia1ctl
+--rw-rw-rw- t 0 bootes bootes 0 Jul 16 17:28 eia2
+--rw-rw-rw- t 0 bootes bootes 0 Jul 16 17:28 eia2ctl
+cpu%
+</PRE></TT></DL>
+The control file is used to control the device;
+writing the string
+<TT>b1200</TT>
+to
+<TT>/dev/eia1ctl</TT>
+sets the line to 1200 baud.
+</P>
+<P>
+Multiplexed devices present
+a more complex interface structure.
+For example, the LANCE Ethernet driver
+serves a two level file tree (Figure 1)
+providing
+</P>
+<DL COMPACT>
+<DT>*<DD>
+device control and configuration
+<DT>*<DD>
+user-level protocols like ARP
+<DT>*<DD>
+diagnostic interfaces for snooping software.
+</dl>
+<br>&#32;<br>
+The top directory contains a
+<TT>clone</TT>
+file and a directory for each connection, numbered
+<TT>1</TT>
+to
+<TT>n</TT>.
+Each connection directory corresponds to an Ethernet packet type.
+Opening the
+<TT>clone</TT>
+file finds an unused connection directory
+and opens its
+<TT>ctl</TT>
+file.
+Reading the control file returns the ASCII connection number; the user
+process can use this value to construct the name of the proper 
+connection directory.
+In each connection directory files named
+<TT>ctl</TT>,
+<TT>data</TT>,
+<TT>stats</TT>,
+and 
+<TT>type</TT>
+provide access to the connection.
+Writing the string
+<TT>connect 2048</TT>
+to the
+<TT>ctl</TT>
+file sets the packet type to 2048
+and
+configures the connection to receive
+all IP packets sent to the machine.
+Subsequent reads of the file
+<TT>type</TT>
+yield the string
+<TT>2048</TT>.
+The
+<TT>data</TT>
+file accesses the media;
+reading it
+returns the
+next packet of the selected type.
+Writing the file
+queues a packet for transmission after
+appending a packet header containing the source address and packet type.
+The
+<TT>stats</TT>
+file returns ASCII text containing the interface address,
+packet input/output counts, error statistics, and general information
+about the state of the interface.
+<DL><DT><DD><TT><PRE>
+<br><img src="data.7580.gif"><br>
+</PRE></TT></DL>
+If several connections on an interface
+are configured for a particular packet type, each receives a
+copy of the incoming packets.
+The special packet type
+<TT>-1</TT>
+selects all packets.
+Writing the strings
+<TT>promiscuous</TT>
+and
+<TT>connect</TT>
+<TT>-1</TT>
+to the
+<TT>ctl</TT>
+file
+configures a conversation to receive all packets on the Ethernet.
+<P>
+Although the driver interface may seem elaborate,
+the representation of a device as a set of files using ASCII strings for
+communication has several advantages.
+Any mechanism supporting remote access to files immediately
+allows a remote machine to use our interfaces as gateways.
+Using ASCII strings to control the interface avoids byte order problems and
+ensures a uniform representation for
+devices on the same machine and even allows devices to be accessed remotely.
+Representing dissimilar devices by the same set of files allows common tools
+to serve
+several networks or interfaces.
+Programs like
+<TT>stty</TT>
+are replaced by
+<TT>echo</TT>
+and shell redirection.
+</P>
+<H4>2.3 Protocol devices
+</H4>
+<P>
+Network connections are represented as pseudo-devices called protocol devices.
+Protocol device drivers exist for the Datakit URP protocol and for each of the
+Internet IP protocols TCP, UDP, and IL.
+IL, described below, is a new communication protocol used by Plan 9 for
+transmitting file system RPC's.
+All protocol devices look identical so user programs contain no
+network-specific code.
+</P>
+<P>
+Each protocol device driver serves a directory structure
+similar to that of the Ethernet driver.
+The top directory contains a
+<TT>clone</TT>
+file and a directory for each connection numbered
+<TT>0</TT>
+to
+<TT>n</TT>.
+Each connection directory contains files to control one
+connection and to send and receive information.
+A TCP connection directory looks like this:
+<DL><DT><DD><TT><PRE>
+cpu% cd /net/tcp/2
+cpu% ls -l
+--rw-rw---- I 0 ehg    bootes 0 Jul 13 21:14 ctl
+--rw-rw---- I 0 ehg    bootes 0 Jul 13 21:14 data
+--rw-rw---- I 0 ehg    bootes 0 Jul 13 21:14 listen
+--r--r--r-- I 0 bootes bootes 0 Jul 13 21:14 local
+--r--r--r-- I 0 bootes bootes 0 Jul 13 21:14 remote
+--r--r--r-- I 0 bootes bootes 0 Jul 13 21:14 status
+cpu% cat local remote status
+135.104.9.31 5012
+135.104.53.11 564
+tcp/2 1 Established connect
+cpu%
+</PRE></TT></DL>
+The files
+<TT>local</TT>,
+<TT>remote</TT>,
+and
+<TT>status</TT>
+supply information about the state of the connection.
+The
+<TT>data</TT>
+and
+<TT>ctl</TT>
+files
+provide access to the process end of the stream implementing the protocol.
+The
+<TT>listen</TT>
+file is used to accept incoming calls from the network.
+</P>
+<P>
+The following steps establish a connection.
+</P>
+<DL COMPACT>
+<DT>1)<DD>
+The clone device of the
+appropriate protocol directory is opened to reserve an unused connection.
+<DT>2)<DD>
+The file descriptor returned by the open points to the
+<TT>ctl</TT>
+file of the new connection.
+Reading that file descriptor returns an ASCII string containing
+the connection number.
+<DT>3)<DD>
+A protocol/network specific ASCII address string is written to the
+<TT>ctl</TT>
+file.
+<DT>4)<DD>
+The path of the
+<TT>data</TT>
+file is constructed using the connection number.
+When the
+<TT>data</TT>
+file is opened the connection is established.
+</dl>
+<br>&#32;<br>
+A process can read and write this file descriptor
+to send and receive messages from the network.
+If the process opens the
+<TT>listen</TT>
+file it blocks until an incoming call is received.
+An address string written to the
+<TT>ctl</TT>
+file before the listen selects the
+ports or services the process is prepared to accept.
+When an incoming call is received, the open completes
+and returns a file descriptor
+pointing to the
+<TT>ctl</TT>
+file of the new connection.
+Reading the
+<TT>ctl</TT>
+file yields a connection number used to construct the path of the
+<TT>data</TT>
+file.
+A connection remains established while any of the files in the connection directory
+are referenced or until a close is received from the network.
+<H4>2.4 Streams
+</H4>
+<P>
+A
+<I>stream</I>
+[Rit84a][Presotto] is a bidirectional channel connecting a
+physical or pseudo-device to user processes.
+The user processes insert and remove data at one end of the stream.
+Kernel processes acting on behalf of a device insert data at
+the other end.
+Asynchronous communications channels such as pipes,
+TCP conversations, Datakit conversations, and RS232 lines are implemented using
+streams.
+</P>
+<P>
+A stream comprises a linear list of
+<I>processing modules</I>.
+Each module has both an upstream (toward the process) and
+downstream (toward the device)
+<I>put routine</I>.
+Calling the put routine of the module on either end of the stream
+inserts data into the stream.
+Each module calls the succeeding one to send data up or down the stream.
+</P>
+<P>
+An instance of a processing module is represented by a pair of
+<I>queues</I>,
+one for each direction.
+The queues point to the put procedures and can be used
+to queue information traveling along the stream.
+Some put routines queue data locally and send it along the stream at some
+later time, either due to a subsequent call or an asynchronous
+event such as a retransmission timer or a device interrupt.
+Processing modules create helper kernel processes to
+provide a context for handling asynchronous events.
+For example, a helper kernel process awakens periodically
+to perform any necessary TCP retransmissions.
+The use of kernel processes instead of serialized run-to-completion service routines
+differs from the implementation of Unix streams.
+Unix service routines cannot
+use any blocking kernel resource and they lack a local long-lived state.
+Helper kernel processes solve these problems and simplify the stream code.
+</P>
+<P>
+There is no implicit synchronization in our streams.
+Each processing module must ensure that concurrent processes using the stream
+are synchronized.
+This maximizes concurrency but introduces the
+possibility of deadlock.
+However, deadlocks are easily avoided by careful programming; to
+date they have not caused us problems.
+</P>
+<P>
+Information is represented by linked lists of kernel structures called
+<I>blocks</I>.
+Each block contains a type, some state flags, and pointers to
+an optional buffer.
+Block buffers can hold either data or control information, i.e., directives
+to the processing modules.
+Blocks and block buffers are dynamically allocated from kernel memory.
+</P>
+<H4>2.4.1 User Interface
+</H4>
+<P>
+A stream is represented at user level as two files, 
+<TT>ctl</TT>
+and
+<TT>data</TT>.
+The actual names can be changed by the device driver using the stream,
+as we saw earlier in the example of the UART driver.
+The first process to open either file creates the stream automatically.
+The last close destroys it.
+Writing to the
+<TT>data</TT>
+file copies the data into kernel blocks
+and passes them to the downstream put routine of the first processing module.
+A write of less than 32K is guaranteed to be contained by a single block.
+Concurrent writes to the same stream are not synchronized, although the
+32K block size assures atomic writes for most protocols.
+The last block written is flagged with a delimiter
+to alert downstream modules that care about write boundaries.
+In most cases the first put routine calls the second, the second
+calls the third, and so on until the data is output.
+As a consequence, most data is output without context switching.
+</P>
+<P>
+Reading from the
+<TT>data</TT>
+file returns data queued at the top of the stream.
+The read terminates when the read count is reached
+or when the end of a delimited block is encountered.
+A per stream read lock ensures only one process
+can read from a stream at a time and guarantees
+that the bytes read were contiguous bytes from the
+stream.
+</P>
+<P>
+Like UNIX streams [Rit84a],
+Plan 9 streams can be dynamically configured.
+The stream system intercepts and interprets
+the following control blocks:
+</P>
+<DL COMPACT>
+<DT><TT>push</TT> <I>name</I><DD>
+adds an instance of the processing module 
+<I>name</I>
+to the top of the stream.
+<DT><TT>pop</TT><DD>
+removes the top module of the stream.
+<DT><TT>hangup</TT><DD>
+sends a hangup message
+up the stream from the device end.
+</dl>
+<br>&#32;<br>
+Other control blocks are module-specific and are interpreted by each
+processing module
+as they pass.
+<P>
+The convoluted syntax and semantics of the UNIX
+<TT>ioctl</TT>
+system call convinced us to leave it out of Plan 9.
+Instead,
+<TT>ioctl</TT>
+is replaced by the
+<TT>ctl</TT>
+file.
+Writing to the
+<TT>ctl</TT>
+file
+is identical to writing to a
+<TT>data</TT>
+file except the blocks are of type
+<I>control</I>.
+A processing module parses each control block it sees.
+Commands in control blocks are ASCII strings, so
+byte ordering is not an issue when one system
+controls streams in a name space implemented on another processor.
+The time to parse control blocks is not important, since control
+operations are rare.
+</P>
+<H4>2.4.2 Device Interface
+</H4>
+<P>
+The module at the downstream end of the stream is part of a device interface.
+The particulars of the interface vary with the device.
+Most device interfaces consist of an interrupt routine, an output
+put routine, and a kernel process.
+The output put routine stages data for the
+device and starts the device if it is stopped.
+The interrupt routine wakes up the kernel process whenever
+the device has input to be processed or needs more output staged.
+The kernel process puts information up the stream or stages more data for output.
+The division of labor among the different pieces varies depending on
+how much must be done at interrupt level.
+However, the interrupt routine may not allocate blocks or call
+a put routine since both actions require a process context.
+</P>
+<H4>2.4.3 Multiplexing
+</H4>
+<P>
+The conversations using a protocol device must be
+multiplexed onto a single physical wire.
+We push a multiplexer processing module
+onto the physical device stream to group the conversations.
+The device end modules on the conversations add the necessary header
+onto downstream messages and then put them to the module downstream
+of the multiplexer.
+The multiplexing module looks at each message moving up its stream and
+puts it to the correct conversation stream after stripping
+the header controlling the demultiplexing.
+</P>
+<P>
+This is similar to the Unix implementation of multiplexer streams.
+The major difference is that we have no general structure that
+corresponds to a multiplexer.
+Each attempt to produce a generalized multiplexer created a more complicated
+structure and underlined the basic difficulty of generalizing this mechanism.
+We now code each multiplexer from scratch and favor simplicity over
+generality.
+</P>
+<H4>2.4.4 Reflections
+</H4>
+<P>
+Despite five year's experience and the efforts of many programmers,
+we remain dissatisfied with the stream mechanism.
+Performance is not an issue;
+the time to process protocols and drive
+device interfaces continues to dwarf the
+time spent allocating, freeing, and moving blocks
+of data.
+However the mechanism remains inordinately
+complex.
+Much of the complexity results from our efforts
+to make streams dynamically configurable, to
+reuse processing modules on different devices
+and to provide kernel synchronization
+to ensure data structures
+don't disappear under foot.
+This is particularly irritating since we seldom use these properties.
+</P>
+<P>
+Streams remain in our kernel because we are unable to
+devise a better alternative.
+Larry Peterson's X-kernel [Pet89a]
+is the closest contender but
+doesn't offer enough advantage to switch.
+If we were to rewrite the streams code, we would probably statically
+allocate resources for a large fixed number of conversations and burn
+memory in favor of less complexity.
+</P>
+<H4>3 The IL Protocol
+</H4>
+<P>
+None of the standard IP protocols is suitable for transmission of
+9P messages over an Ethernet or the Internet.
+TCP has a high overhead and does not preserve delimiters.
+UDP, while cheap, does not provide reliable sequenced delivery.
+Early versions of the system used a custom protocol that was
+efficient but unsatisfactory for internetwork transmission.
+When we implemented IP, TCP, and UDP we looked around for a suitable
+replacement with the following properties:
+</P>
+<DL COMPACT>
+<DT>*<DD>
+Reliable datagram service with sequenced delivery
+<DT>*<DD>
+Runs over IP
+<DT>*<DD>
+Low complexity, high performance
+<DT>*<DD>
+Adaptive timeouts
+</dl>
+<br>&#32;<br>
+None met our needs so a new protocol was designed.
+IL is a lightweight protocol designed to be encapsulated by IP.
+It is a connection-based protocol
+providing reliable transmission of sequenced messages between machines.
+No provision is made for flow control since the protocol is designed to transport RPC
+messages between client and server.
+A small outstanding message window prevents too
+many incoming messages from being buffered;
+messages outside the window are discarded
+and must be retransmitted.
+Connection setup uses a two way handshake to generate
+initial sequence numbers at each end of the connection;
+subsequent data messages increment the
+sequence numbers allowing
+the receiver to resequence out of order messages. 
+In contrast to other protocols, IL does not do blind retransmission.
+If a message is lost and a timeout occurs, a query message is sent.
+The query message is a small control message containing the current
+sequence numbers as seen by the sender.
+The receiver responds to a query by retransmitting missing messages.
+This allows the protocol to behave well in congested networks,
+where blind retransmission would cause further
+congestion.
+Like TCP, IL has adaptive timeouts.
+A round-trip timer is used
+to calculate acknowledge and retransmission times in terms of the network speed.
+This allows the protocol to perform well on both the Internet and on local Ethernets.
+<P>
+In keeping with the minimalist design of the rest of the kernel, IL is small.
+The entire protocol is 847 lines of code, compared to 2200 lines for TCP.
+IL is our protocol of choice.
+</P>
+<H4>4 Network Addressing
+</H4>
+<P>
+A uniform interface to protocols and devices is not sufficient to
+support the transparency we require.
+Since each network uses a different
+addressing scheme,
+the ASCII strings written to a control file have no common format.
+As a result, every tool must know the specifics of the networks it
+is capable of addressing.
+Moreover, since each machine supplies a subset
+of the available networks, each user must be aware of the networks supported
+by every terminal and server machine.
+This is obviously unacceptable.
+</P>
+<P>
+Several possible solutions were considered and rejected; one deserves
+more discussion.
+We could have used a user-level file server
+to represent the network name space as a Plan 9 file tree. 
+This global naming scheme has been implemented in other distributed systems.
+The file hierarchy provides paths to
+directories representing network domains.
+Each directory contains
+files representing the names of the machines in that domain;
+an example might be the path
+<TT>/net/name/usa/edu/mit/ai</TT>.
+Each machine file contains information like the IP address of the machine.
+We rejected this representation for several reasons.
+First, it is hard to devise a hierarchy encompassing all representations
+of the various network addressing schemes in a uniform manner.
+Datakit and Ethernet address strings have nothing in common.
+Second, the address of a machine is
+often only a small part of the information required to connect to a service on
+the machine.
+For example, the IP protocols require symbolic service names to be mapped into
+numeric port numbers, some of which are privileged and hence special.
+Information of this sort is hard to represent in terms of file operations.
+Finally, the size and number of the networks being represented burdens users with
+an unacceptably large amount of information about the organization of the network
+and its connectivity.
+In this case the Plan 9 representation of a
+resource as a file is not appropriate.
+</P>
+<P>
+If tools are to be network independent, a third-party server must resolve
+network names.
+A server on each machine, with local knowledge, can select the best network
+for any particular destination machine or service.
+Since the network devices present a common interface,
+the only operation which differs between networks is name resolution.
+A symbolic name must be translated to
+the path of the clone file of a protocol
+device and an ASCII address string to write to the
+<TT>ctl</TT>
+file.
+A connection server (CS) provides this service.
+</P>
+<H4>4.1 Network Database
+</H4>
+<P>
+On most systems several
+files such as
+<TT>/etc/hosts</TT>,
+<TT>/etc/networks</TT>,
+<TT>/etc/services</TT>,
+<TT>/etc/hosts.equiv</TT>,
+<TT>/etc/bootptab</TT>,
+and
+<TT>/etc/named.d</TT>
+hold network information.
+Much time and effort is spent
+administering these files and keeping
+them mutually consistent.
+Tools attempt to
+automatically derive one or more of the files from
+information in other files but maintenance continues to be
+difficult and error prone.
+</P>
+<P>
+Since we were writing an entirely new system, we were free to
+try a simpler approach.
+One database on a shared server contains all the information
+needed for network administration.
+Two ASCII files comprise the main database:
+<TT>/lib/ndb/local</TT>
+contains locally administered information and
+<TT>/lib/ndb/global</TT>
+contains information imported from elsewhere.
+The files contain sets of attribute/value pairs of the form
+<I>attr<TT>=</TT>value</I>,
+where
+<I>attr</I>
+and
+<I>value</I>
+are alphanumeric strings.
+Systems are described by multi-line entries;
+a header line at the left margin begins each entry followed by zero or more
+indented attribute/value pairs specifying
+names, addresses, properties, etc.
+For example, the entry for our CPU server
+specifies a domain name, an IP address, an Ethernet address,
+a Datakit address, a boot file, and supported protocols.
+<DL><DT><DD><TT><PRE>
+sys = helix
+	dom=helix.research.bell-labs.com
+	bootf=/mips/9power
+	ip=135.104.9.31 ether=0800690222f0
+	dk=nj/astro/helix
+	proto=il flavor=9cpu
+</PRE></TT></DL>
+If several systems share entries such as
+network mask and gateway, we specify that information
+with the network or subnetwork instead of the system.
+The following entries define a Class B IP network and 
+a few subnets derived from it.
+The entry for the network specifies the IP mask,
+file system, and authentication server for all systems
+on the network.
+Each subnetwork specifies its default IP gateway.
+<DL><DT><DD><TT><PRE>
+ipnet=mh-astro-net ip=135.104.0.0 ipmask=255.255.255.0
+	fs=bootes.research.bell-labs.com
+	auth=1127auth
+ipnet=unix-room ip=135.104.117.0
+	ipgw=135.104.117.1
+ipnet=third-floor ip=135.104.51.0
+	ipgw=135.104.51.1
+ipnet=fourth-floor ip=135.104.52.0
+	ipgw=135.104.52.1
+</PRE></TT></DL>
+Database entries also define the mapping of service names
+to port numbers for TCP, UDP, and IL.
+<DL><DT><DD><TT><PRE>
+tcp=echo	port=7
+tcp=discard	port=9
+tcp=systat	port=11
+tcp=daytime	port=13
+</PRE></TT></DL>
+</P>
+<P>
+All programs read the database directly so
+consistency problems are rare.
+However the database files can become large.
+Our global file, containing all information about
+both Datakit and Internet systems in AT&amp;T, has 43,000
+lines.
+To speed searches, we build hash table files for each
+attribute we expect to search often.
+The hash file entries point to entries
+in the master files.
+Every hash file contains the modification time of its master
+file so we can avoid using an out-of-date hash table.
+Searches for attributes that aren't hashed or whose hash table
+is out-of-date still work, they just take longer.
+</P>
+<H4>4.2 Connection Server
+</H4>
+<P>
+On each system a user level connection server process, CS, translates
+symbolic names to addresses.
+CS uses information about available networks, the network database, and
+other servers (such as DNS) to translate names.
+CS is a file server serving a single file,
+<TT>/net/cs</TT>.
+A client writes a symbolic name to
+<TT>/net/cs</TT>
+then reads one line for each matching destination reachable
+from this system.
+The lines are of the form
+<I>filename message</I>,
+where
+<I>filename</I>
+is the path of the clone file to open for a new connection and
+<I>message</I>
+is the string to write to it to make the connection.
+The following example illustrates this.
+<TT>Ndb/csquery</TT>
+is a program that prompts for strings to write to
+<TT>/net/cs</TT>
+and prints the replies.
+<DL><DT><DD><TT><PRE>
+% ndb/csquery
+&#62; net!helix!9fs
+/net/il/clone 135.104.9.31!17008
+/net/dk/clone nj/astro/helix!9fs
+</PRE></TT></DL>
+</P>
+<P>
+CS provides meta-name translation to perform complicated
+searches.
+The special network name
+<TT>net</TT>
+selects any network in common between source and
+destination supporting the specified service.
+A host name of the form <TT>$</TT><I>attr</I>
+is the name of an attribute in the network database.
+The database search returns the value
+of the matching attribute/value pair
+most closely associated with the source host.
+Most closely associated is defined on a per network basis.
+For example, the symbolic name
+<TT>tcp!$auth!rexauth</TT>
+causes CS to search for the
+<TT>auth</TT>
+attribute in the database entry for the source system, then its
+subnetwork (if there is one) and then its network.
+<DL><DT><DD><TT><PRE>
+% ndb/csquery
+&#62; net!$auth!rexauth
+/net/il/clone 135.104.9.34!17021
+/net/dk/clone nj/astro/p9auth!rexauth
+/net/il/clone 135.104.9.6!17021
+/net/dk/clone nj/astro/musca!rexauth
+</PRE></TT></DL>
+</P>
+<P>
+Normally CS derives naming information from its database files.
+For domain names however, CS first consults another user level
+process, the domain name server (DNS).
+If no DNS is reachable, CS relies on its own tables.
+</P>
+<P>
+Like CS, the domain name server is a user level process providing
+one file,
+<TT>/net/dns</TT>.
+A client writes a request of the form
+<I>domain-name type</I>,
+where
+<I>type</I>
+is a domain name service resource record type.
+DNS performs a recursive query through the
+Internet domain name system producing one line
+per resource record found.  The client reads
+<TT>/net/dns</TT>
+to retrieve the records.
+Like other domain name servers, DNS caches information
+learned from the network.
+DNS is implemented as a multi-process shared memory application
+with separate processes listening for network and local requests.
+</P>
+<H4>5 Library routines
+</H4>
+<P>
+The section on protocol devices described the details
+of making and receiving connections across a network.
+The dance is straightforward but tedious.
+Library routines are provided to relieve
+the programmer of the details.
+</P>
+<H4>5.1 Connecting
+</H4>
+<P>
+The
+<TT>dial</TT>
+library call establishes a connection to a remote destination.
+It
+returns an open file descriptor for the
+<TT>data</TT>
+file in the connection directory.
+<DL><DT><DD><TT><PRE>
+int  dial(char *dest, char *local, char *dir, int *cfdp)
+</PRE></TT></DL>
+</P>
+<DL COMPACT>
+<DT><TT>dest</TT><DD>
+is the symbolic name/address of the destination.
+<DT><TT>local</TT><DD>
+is the local address.
+Since most networks do not support this, it is
+usually zero.
+<DT><TT>dir</TT><DD>
+is a pointer to a buffer to hold the path name of the protocol directory
+representing this connection.
+<TT>Dial</TT>
+fills this buffer if the pointer is non-zero.
+<DT><TT>cfdp</TT><DD>
+is a pointer to a file descriptor for the
+<TT>ctl</TT>
+file of the connection.
+If the pointer is non-zero,
+<TT>dial</TT>
+opens the control file and tucks the file descriptor here.
+</dl>
+<br>&#32;<br>
+Most programs call
+<TT>dial</TT>
+with a destination name and all other arguments zero.
+<TT>Dial</TT>
+uses CS to
+translate the symbolic name to all possible destination addresses
+and attempts to connect to each in turn until one works.
+Specifying the special name
+<TT>net</TT>
+in the network portion of the destination
+allows CS to pick a network/protocol in common
+with the destination for which the requested service is valid.
+For example, assume the system
+<TT>research.bell-labs.com</TT>
+has the Datakit address
+<TT>nj/astro/research</TT>
+and IP addresses
+<TT>135.104.117.5</TT>
+and
+<TT>129.11.4.1</TT>.
+The call
+<DL><DT><DD><TT><PRE>
+fd = dial("net!research.bell-labs.com!login", 0, 0, 0, 0);
+</PRE></TT></DL>
+tries in succession to connect to
+<TT>nj/astro/research!login</TT>
+on the Datakit and both
+<TT>135.104.117.5!513</TT>
+and
+<TT>129.11.4.1!513</TT>
+across the Internet.
+<P>
+<TT>Dial</TT>
+accepts addresses instead of symbolic names.
+For example, the destinations
+<TT>tcp!135.104.117.5!513</TT>
+and
+<TT>tcp!research.bell-labs.com!login</TT>
+are equivalent
+references to the same machine.
+</P>
+<H4>5.2 Listening
+</H4>
+<P>
+A program uses
+four routines to listen for incoming connections.
+It first
+<TT>announce()</TT>s
+its intention to receive connections,
+then
+<TT>listen()</TT>s
+for calls and finally
+<TT>accept()</TT>s
+or
+<TT>reject()</TT>s
+them.
+<TT>Announce</TT>
+returns an open file descriptor for the
+<TT>ctl</TT>
+file of a connection and fills
+<TT>dir</TT>
+with the
+path of the protocol directory
+for the announcement.
+<DL><DT><DD><TT><PRE>
+int  announce(char *addr, char *dir)
+</PRE></TT></DL>
+<TT>Addr</TT>
+is the symbolic name/address announced;
+if it does not contain a service, the announcement is for
+all services not explicitly announced.
+Thus, one can easily write the equivalent of the
+<TT>inetd</TT>
+program without
+having to announce each separate service.
+An announcement remains in force until the control file is
+closed.
+</P>
+<br>&#32;<br>
+<TT>Listen</TT>
+returns an open file descriptor for the
+<TT>ctl</TT>
+file and fills
+<TT>ldir</TT>
+with the path
+of the protocol directory
+for the received connection.
+It is passed
+<TT>dir</TT>
+from the announcement.
+<DL><DT><DD><TT><PRE>
+int  listen(char *dir, char *ldir)
+</PRE></TT></DL>
+<br>&#32;<br>
+<TT>Accept</TT>
+and
+<TT>reject</TT>
+are called with the control file descriptor and
+<TT>ldir</TT>
+returned by
+<TT>listen.</TT>
+Some networks such as Datakit accept a reason for a rejection;
+networks such as IP ignore the third argument.
+<DL><DT><DD><TT><PRE>
+int  accept(int ctl, char *ldir)
+int  reject(int ctl, char *ldir, char *reason)
+</PRE></TT></DL>
+<P>
+The following code implements a typical TCP listener.
+It announces itself, listens for connections, and forks a new
+process for each.
+The new process echoes data on the connection until the
+remote end closes it.
+The "*" in the symbolic name means the announcement is valid for
+any addresses bound to the machine the program is run on.
+<DL><DT><DD><TT><PRE>
+int
+echo_server(void)
+{
+	int dfd, lcfd;
+	char adir[40], ldir[40];
+	int n;
+	char buf[256];
+
+	afd = announce("tcp!*!echo", adir);
+	if(afd &#60; 0)
+		return -1;
+
+	for(;;){
+		/* listen for a call */
+		lcfd = listen(adir, ldir);
+		if(lcfd &#60; 0)
+			return -1;
+
+		/* fork a process to echo */
+		switch(fork()){
+		case 0:
+			/* accept the call and open the data file */
+			dfd = accept(lcfd, ldir);
+			if(dfd &#60; 0)
+				return -1;
+
+			/* echo until EOF */
+			while((n = read(dfd, buf, sizeof(buf))) &#62; 0)
+				write(dfd, buf, n);
+			exits(0);
+		case -1:
+			perror("forking");
+		default:
+			close(lcfd);
+			break;
+		}
+
+	}
+}
+</PRE></TT></DL>
+</P>
+<H4>6 User Level
+</H4>
+<P>
+Communication between Plan 9 machines is done almost exclusively in
+terms of 9P messages. Only the two services
+<TT>cpu</TT>
+and
+<TT>exportfs</TT>
+are used.
+The
+<TT>cpu</TT>
+service is analogous to
+<TT>rlogin</TT>.
+However, rather than emulating a terminal session
+across the network,
+<TT>cpu</TT>
+creates a process on the remote machine whose name space is an analogue of the window
+in which it was invoked.
+<TT>Exportfs</TT>
+is a user level file server which allows a piece of name space to be
+exported from machine to machine across a network. It is used by the
+<TT>cpu</TT>
+command to serve the files in the terminal's name space when they are
+accessed from the
+cpu server.
+</P>
+<P>
+By convention, the protocol and device driver file systems are mounted in a
+directory called
+<TT>/net</TT>.
+Although the per-process name space allows users to configure an
+arbitrary view of the system, in practice their profiles build
+a conventional name space.
+</P>
+<H4>6.1 Exportfs
+</H4>
+<P>
+<TT>Exportfs</TT>
+is invoked by an incoming network call.
+The
+<I>listener</I>
+(the Plan 9 equivalent of
+<TT>inetd</TT>)
+runs the profile of the user
+requesting the service to construct a name space before starting
+<TT>exportfs</TT>.
+After an initial protocol
+establishes the root of the file tree being
+exported,
+the remote process mounts the connection,
+allowing
+<TT>exportfs</TT>
+to act as a relay file server. Operations in the imported file tree
+are executed on the remote server and the results returned.
+As a result
+the name space of the remote machine appears to be exported into a
+local file tree.
+</P>
+<P>
+The
+<TT>import</TT>
+command calls
+<TT>exportfs</TT>
+on a remote machine, mounts the result in the local name space,
+and
+exits.
+No local process is required to serve mounts;
+9P messages are generated by the kernel's mount driver and sent
+directly over the network.
+</P>
+<P>
+<TT>Exportfs</TT>
+must be multithreaded since the system calls
+<TT>open,</TT>
+<TT>read</TT>
+and
+<TT>write</TT>
+may block.
+Plan 9 does not implement the 
+<TT>select</TT>
+system call but does allow processes to share file descriptors,
+memory and other resources.
+<TT>Exportfs</TT>
+and the configurable name space
+provide a means of sharing resources between machines.
+It is a building block for constructing complex name spaces
+served from many machines.
+</P>
+<P>
+The simplicity of the interfaces encourages naive users to exploit the potential
+of a richly connected environment.
+Using these tools it is easy to gateway between networks.
+For example a terminal with only a Datakit connection can import from the server
+<TT>helix</TT>:
+<DL><DT><DD><TT><PRE>
+import -a helix /net
+telnet ai.mit.edu
+</PRE></TT></DL>
+The
+<TT>import</TT>
+command makes a Datakit connection to the machine
+<TT>helix</TT>
+where
+it starts an instance
+<TT>exportfs</TT>
+to serve
+<TT>/net</TT>.
+The
+<TT>import</TT>
+command mounts the remote
+<TT>/net</TT>
+directory after (the
+<TT>-a</TT>
+option to
+<TT>import</TT>)
+the existing contents
+of the local
+<TT>/net</TT>
+directory.
+The directory contains the union of the local and remote contents of
+<TT>/net</TT>.
+Local entries supersede remote ones of the same name so
+networks on the local machine are chosen in preference
+to those supplied remotely.
+However, unique entries in the remote directory are now visible in the local
+<TT>/net</TT>
+directory.
+All the networks connected to
+<TT>helix</TT>,
+not just Datakit,
+are now available in the terminal. The effect on the name space is shown by the following
+example:
+<DL><DT><DD><TT><PRE>
+philw-gnot% ls /net
+/net/cs
+/net/dk
+philw-gnot% import -a musca /net
+philw-gnot% ls /net
+/net/cs
+/net/cs
+/net/dk
+/net/dk
+/net/dns
+/net/ether
+/net/il
+/net/tcp
+/net/udp
+</PRE></TT></DL>
+</P>
+<H4>6.2 Ftpfs
+</H4>
+<P>
+We decided to make our interface to FTP
+a file system rather than the traditional command.
+Our command,
+<I>ftpfs,</I>
+dials the FTP port of a remote system, prompts for login and password, sets image mode,
+and mounts the remote file system onto
+<TT>/n/ftp</TT>.
+Files and directories are cached to reduce traffic.
+The cache is updated whenever a file is created.
+Ftpfs works with TOPS-20, VMS, and various Unix flavors
+as the remote system.
+</P>
+<H4>7 Cyclone Fiber Links
+</H4>
+<P>
+The file servers and CPU servers are connected by
+high-bandwidth
+point-to-point links.
+A link consists of two VME cards connected by a pair of optical
+fibers.
+The VME cards use 33MHz Intel 960 processors and AMD's TAXI
+fiber transmitter/receivers to drive the lines at 125 Mbit/sec.
+Software in the VME card reduces latency by copying messages from system memory
+to fiber without intermediate buffering.
+</P>
+<H4>8 Performance
+</H4>
+<P>
+We measured both latency and throughput
+of reading and writing bytes between two processes
+for a number of different paths.
+Measurements were made on two- and four-CPU SGI Power Series processors.
+The CPUs are 25 MHz MIPS 3000s.
+The latency is measured as the round trip time
+for a byte sent from one process to another and
+back again.
+Throughput is measured using 16k writes from
+one process to another.
+<DL><DT><DD><TT><PRE>
+<br><img src="data.7581.gif"><br>
+</PRE></TT></DL>
+</P>
+<H4>9 Conclusion
+</H4>
+<P>
+The representation of all resources as file systems
+coupled with an ASCII interface has proved more powerful
+than we had originally imagined.
+Resources can be used by any computer in our networks
+independent of byte ordering or CPU type.
+The connection server provides an elegant means
+of decoupling tools from the networks they use.
+Users successfully use Plan 9 without knowing the
+topology of the system or the networks they use.
+More information about 9P can be found in the Section 5 of the Plan 9 Programmer's
+Manual, Volume I.
+</P>
+<H4>10 References
+</H4>
+<br>&#32;<br>
+[Pike90] R. Pike, D. Presotto, K. Thompson, H. Trickey,
+``Plan 9 from Bell Labs'',
+UKUUG Proc. of the Summer 1990 Conf. ,
+London, England,
+1990.
+<br>&#32;<br>
+[Needham] R. Needham, ``Names'', in
+Distributed systems,
+S. Mullender, ed.,
+Addison Wesley, 1989.
+<br>&#32;<br>
+[Presotto] D. Presotto, ``Multiprocessor Streams for Plan 9'',
+UKUUG Proc. of the Summer 1990 Conf. ,
+London, England, 1990.
+<br>&#32;<br>
+[Met80] R. Metcalfe, D. Boggs, C. Crane, E. Taf and J. Hupp, ``The
+Ethernet Local Network: Three reports'',
+CSL-80-2,
+XEROX Palo Alto Research Center, February 1980.
+<br>&#32;<br>
+[Fra80] A. G. Fraser, ``Datakit - A Modular Network for Synchronous
+and Asynchronous Traffic'', 
+Proc. Int'l Conf. on Communication,
+Boston, June 1980.
+<br>&#32;<br>
+[Pet89a] L. Peterson, ``RPC in the X-Kernel: Evaluating new Design Techniques'',
+Proc. Twelfth Symp. on Op. Sys. Princ.,
+Litchfield Park, AZ, December 1990.
+<br>&#32;<br>
+[Rit84a] D. M. Ritchie, ``A Stream Input-Output System'',
+AT&amp;T Bell Laboratories Technical Journal, 68(8),
+October 1984.
+
+<br>&#32;<br>
+<A href=http://www.lucent.com/copyright.html>
+Copyright</A> &#169; 2000 Lucent Technologies Inc.  All rights reserved.
+</body></html>

BIN
sys/doc/net/net.pdf


+ 3291 - 0
sys/doc/sam/sam.html

@@ -0,0 +1,3291 @@
+<html>
+<title>
+-
+</title>
+<body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#330088" ALINK="#FF0044">
+<H1>The Text Editor <TT>sam</TT>
+</H1>
+<DL><DD><I>Rob Pike<br>
+rob@plan9.bell-labs.com<br>
+</I></DL>
+<DL><DD><H4>ABSTRACT</H4>
+<br>&#32;<br>
+<TT>Sam</TT>
+is an interactive multi-file text editor intended for
+bitmap displays.
+A textual command language
+supplements the mouse-driven, cut-and-paste interface
+to make complex or
+repetitive editing tasks easy to specify.
+The language is characterized by the composition of regular expressions
+to describe the structure of the text being modified.
+The treatment of files as a database, with changes logged
+as atomic transactions, guides the implementation and
+makes a general `undo' mechanism straightforward.
+<P>
+<TT>Sam</TT>
+is implemented as two processes connected by a low-bandwidth stream,
+one process handling the display and the other the editing
+algorithms.  Therefore it can run with the display process
+in a bitmap terminal and the editor on a local host,
+with both processes on a bitmap-equipped host, or with
+the display process in the terminal and the editor in a
+remote host.
+By suppressing the display process,
+it can even run without a bitmap terminal.
+</P>
+<P>
+This paper is reprinted from Software&#173;Practice and Experience,
+Vol 17, number 11, pp. 813-845, November 1987.
+The paper has not been updated for the Plan 9 manuals.  Although
+<TT>Sam</TT>
+has not changed much since the paper was written, the system around it certainly has.
+Nonetheless, the description here still stands as the best introduction to the editor.
+</DL>
+</P>
+<H4>Introduction
+</H4>
+<br>&#32;<br>
+<TT>Sam</TT>
+is an interactive text editor that combines cut-and-paste interactive editing with
+an unusual command language based on the composition of regular expressions.
+It is written as two programs: one, the `host part,' runs on a UNIX system
+and implements the command language and provides file access; the other, the
+`terminal part,' runs asynchronously
+on a machine with a mouse and bitmap display
+and supports the display and interactive editing.
+The host part may be even run in isolation on an ordinary terminal
+to edit text using the command
+language, much like a traditional line editor,
+without assistance from a mouse or display.
+Most often,
+the terminal part runs on a Blit<sup>1</sup> terminal
+(actually on a Teletype DMD 5620, the production version of the Blit), whose
+host connection is an ordinary 9600 bps RS232 link;
+on the SUN computer the host and display processes run on a single machine,
+connected by a pipe.
+<P>
+<TT>Sam</TT>
+edits uninterpreted
+ASCII text.
+It has no facilities for multiple fonts, graphics or tables,
+unlike MacWrite,<sup>2</sup> Bravo,<sup>3</sup> Tioga<sup>4</sup>
+or Lara.<sup>5</sup>
+Also unlike them, it has a rich command language.
+(Throughout this paper, the phrase
+command language
+refers to
+textual commands; commands activated from the mouse form the
+<I>mouse</I>
+<I>language.</I>)
+<TT>Sam</TT>
+developed as an editor for use by programmers, and tries to join
+the styles of the UNIX text editor
+<TT>ed</TT><sup>6,7</sup>
+with that of interactive cut-and-paste editors by
+providing a comfortable mouse-driven interface
+to a program with a solid command language driven by regular expressions.
+The command language developed more than the mouse language, and
+acquired a notation for describing the structure of files
+more richly than as a sequence of lines,
+using a dataflow-like syntax for specifying changes.
+</P>
+<P>
+The interactive style was influenced by
+<TT>jim</TT>,<sup>1</sup>
+an early cut-and-paste editor for the Blit, and by
+<TT>mux</TT>,<sup>8</sup>
+the Blit window system.
+<TT>Mux</TT>
+merges the original Blit window system,
+<TT>mpx</TT>,<sup>1</sup>
+with cut-and-paste editing, forming something like a
+multiplexed version of
+<TT>jim</TT>
+that edits the output of (and input to) command sessions rather than files.
+</P>
+<P>
+The first part of this paper describes the command language, then the mouse
+language, and explains how they interact.
+That is followed by a description of the implementation,
+first of the host part, then of the terminal part.
+A principle that influenced the design of
+<TT>sam</TT>
+is that it should have no explicit limits, such as upper limits on
+file size or line length.
+A secondary consideration is that it be efficient.
+To honor these two goals together requires a method for efficiently
+manipulating
+huge strings (files) without breaking them into lines,
+perhaps while making thousands of changes
+under control of the command language.
+<TT>Sam</TT>'s
+method is to
+treat the file as a transaction database, implementing changes as atomic
+updates.  These updates may be unwound easily to `undo' changes.
+Efficiency is achieved through a collection of caches that minimizes
+disc traffic and data motion, both within the two parts of the program
+and between them.
+</P>
+<P>
+The terminal part of
+<TT>sam</TT>
+is fairly straightforward.
+More interesting is how the two halves of the editor stay
+synchronized when either half may initiate a change.
+This is achieved through a data structure that organizes the
+communications and is maintained in parallel by both halves.
+</P>
+<P>
+The last part of the paper chronicles the writing of
+<TT>sam</TT>
+and discusses the lessons that were learned through its development and use.
+</P>
+<P>
+The paper is long, but is composed largely of two papers of reasonable length:
+a description of the user interface of
+<TT>sam</TT>
+and a discussion of its implementation.
+They are combined because the implementation is strongly influenced by
+the user interface, and vice versa.
+</P>
+<H4>The Interface
+</H4>
+<br>&#32;<br>
+<TT>Sam</TT>
+is a text editor for multiple files.
+File names may be provided when it is invoked:
+<DL><DT><DD><TT><PRE>
+sam file1 file2 ...
+</PRE></TT></DL>
+and there are commands
+to add new files and discard unneeded ones.
+Files are not read until necessary
+to complete some command.
+Editing operations apply to an internal copy
+made when the file is read; the UNIX file associated with the copy
+is changed only by an explicit command.
+To simplify the discussion, the internal copy is here called a
+<I>file</I>,
+while the disc-resident original is called a
+disc file.
+<P>
+<TT>Sam</TT>
+is usually connected to a bitmap display that presents a cut-and-paste
+editor driven by the mouse.
+In this mode, the command language is still available:
+text typed in a special window, called the
+<TT>sam</TT>
+<I>window,</I>
+is interpreted
+as commands to be executed in the current file.
+Cut-and-paste editing may be used in any window &#173; even in the
+<TT>sam</TT>
+window to construct commands.
+The other mode of operation, invoked by starting
+<TT>sam</TT>
+with the option
+<TT>-d</TT>
+(for `no download'),
+does not use the mouse or bitmap display, but still permits
+editing using the textual command language, even on an ordinary terminal,
+interactively or from a script.
+</P>
+<P>
+The following sections describe first the command language (under
+<TT>sam -d</TT>
+and in the
+<TT>sam</TT>
+window), and then the mouse interface.
+These two languages are nearly independent, but connect through the
+<I>current</I>
+<I>text,</I>
+described below.
+</P>
+<H4>The Command Language
+</H4>
+<br>&#32;<br>
+A file consists of its contents, which are an array of characters
+(that is, a string); the
+<I>name</I>
+of the associated disc file; the
+modified bit
+that states whether the contents match those of
+the disc file;
+and a substring of the contents, called the
+current text
+or
+<I>dot</I>
+(see Figures 1 and 2).
+If the current text is a null string, dot falls between characters.
+The
+<I>value</I>
+of dot is the location of the current text; the
+<I>contents</I>
+of dot are the characters it contains.
+<TT>Sam</TT>
+imparts to the text no two-dimensional interpretation such as columns
+or fields; text is always one-dimensional.
+Even the idea of a `line' of text as understood by most UNIX programs
+&#173; a sequence of characters terminated by a newline character &#173;
+is only weakly supported.
+<P>
+The
+current file
+is the file to which editing commands refer.
+The current text is therefore dot in the current file.
+If a command doesn't explicitly name a particular file or piece of text,
+the command is assumed to apply to the current text.
+For the moment, ignore the presence of multiple files and consider
+editing a single file.
+<br><img src="fig1.ps.11760.gif"><br>
+<br>
+<I>Figure 1. A typical
+</I><TT>sam</TT><I>
+screen, with the editing menu presented.
+The
+</I><TT>sam</TT><I>
+(command language) window is in the middle, with file windows above and below.
+(The user interface makes it easy to create these abutting windows.)
+The partially obscured window is a third file window.
+The uppermost window is that to which typing and mouse operations apply,
+as indicated by its heavy border.
+Each window has its current text highlighted in reverse video.
+The
+</I><TT>sam</TT><I>
+window's current text is the null string on the last visible line,
+indicated by a vertical bar.
+See also Figure 2.
+<br>
+<DL><DT><DD><TT><PRE>
+</I><br>&#32;<br>
+</PRE></TT></DL>
+</P>
+<P>
+Commands have one-letter names.
+Except for non-editing commands such as writing
+the file to disc, most commands make some change
+to the text in dot and leave dot set to the text resulting from the change.
+For example, the delete command,
+<TT>d</TT>,
+deletes the text in dot, replacing it by the null string and setting dot
+to the result.
+The change command,
+<TT>c</TT>,
+replaces dot by text delimited by an arbitrary punctuation character,
+conventionally
+a slash.  Thus,
+<DL><DT><DD><TT><PRE>
+c/Peter/
+</PRE></TT></DL>
+replaces the text in dot by the string
+<TT>Peter</TT>.
+Similarly,
+<DL><DT><DD><TT><PRE>
+a/Peter/
+</PRE></TT></DL>
+(append) adds the string after dot, and
+<DL><DT><DD><TT><PRE>
+i/Peter/
+</PRE></TT></DL>
+(insert) inserts before dot.
+All three leave dot set to the new text,
+<TT>Peter</TT>.
+</P>
+<P>
+Newlines are part of the syntax of commands:
+the newline character lexically terminates a command.
+Within the inserted text, however, newlines are never implicit.
+But since it is often convenient to insert multiple lines of text,
+<TT>sam</TT>
+has a special
+syntax for that case:
+<DL><DT><DD><TT><PRE>
+a
+some lines of text
+to be inserted in the file,
+terminated by a period
+on a line by itself
+.
+</PRE></TT></DL>
+In the one-line syntax, a newline character may be specified by a C-like
+escape, so
+<DL><DT><DD><TT><PRE>
+c/\n/
+</PRE></TT></DL>
+replaces dot by a single newline character.
+</P>
+<P>
+<TT>Sam</TT>
+also has a substitute command,
+<TT>s</TT>:
+<DL><DT><DD><TT><PRE>
+s/<I>expression</I>/<I>replacement</I>/
+</PRE></TT></DL>
+substitutes the replacement text for the first match, in dot,
+of the regular expression.
+Thus, if dot is the string
+<TT>Peter</TT>,
+the command
+<DL><DT><DD><TT><PRE>
+s/t/st/
+</PRE></TT></DL>
+changes it to
+<TT>Pester</TT>.
+In general,
+<TT>s</TT>
+is unnecessary, but it was inherited from
+<TT>ed</TT>
+and it has some convenient variations.
+For instance, the replacement text may include the matched text,
+specified by
+<TT>&</TT>:
+<DL><DT><DD><TT><PRE>
+s/Peter/Oh, &amp;, &amp;, &amp;, &amp;!/
+</PRE></TT></DL>
+</P>
+<P>
+There are also three commands that apply programs
+to text:
+<DL><DT><DD><TT><PRE>
+&#60; <I>UNIX program</I>
+</PRE></TT></DL>
+replaces dot by the output of the UNIX program.
+Similarly, the
+<TT>></TT>
+command
+runs the program with dot as its standard input, and
+<TT>|</TT>
+does both.  For example,
+<DL><DT><DD><TT><PRE>
+| sort
+</PRE></TT></DL>
+replaces dot by the result of applying the standard sorting utility to it.
+Again, newlines have no special significance for these
+<TT>sam</TT>
+commands.
+The text acted upon and resulting from these commands is not necessarily
+bounded by newlines, although for connection with UNIX programs,
+newlines may be necessary to obey conventions.
+</P>
+<P>
+One more command:
+<TT>p</TT>
+prints the contents of dot.
+Table I summarizes
+<TT>sam</TT>'s
+commands.
+<br><img src="-.11761.gif"><br>
+<br>&#32;<br>
+</P>
+<P>
+The value of dot may be changed by
+specifying an
+<I>address</I>
+for the command.
+The simplest address is a line number:
+<DL><DT><DD><TT><PRE>
+3
+</PRE></TT></DL>
+refers to the third line of the file, so
+<DL><DT><DD><TT><PRE>
+3d
+</PRE></TT></DL>
+deletes the third line of the file, and implicitly renumbers
+the lines so the old line 4 is now numbered 3.
+(This is one of the few places where
+<TT>sam</TT>
+deals with lines directly.)
+Line
+<TT>0</TT>
+is the null string at the beginning of the file.
+If a command consists of only an address, a
+<TT>p</TT>
+command is assumed, so typing an unadorned
+<TT>3</TT>
+prints line 3 on the terminal.
+There are a couple of other basic addresses:
+a period addresses dot itself; and
+a dollar sign
+(<TT>$</TT>)
+addresses the null string at the end of the file.
+</P>
+<P>
+An address is always a single substring of the file.
+Thus, the address
+<TT>3</TT>
+addresses the characters
+after the second newline of
+the file through the third newline of the file.
+A
+compound address
+is constructed by the comma operator
+<DL><DT><DD><TT><PRE>
+<I>address1</I>,<I>address2</I>
+</PRE></TT></DL>
+and addresses the substring of the file from the beginning of
+<I>address1</I>
+to the end of
+<I>address2</I>.
+For example, the command
+<TT>3,5p</TT>
+prints the third through fifth lines of the file and
+<TT>.,$d</TT>
+deletes the text from the beginning of dot to the end of the file.
+</P>
+<P>
+These addresses are all absolute positions in the file, but
+<TT>sam</TT>
+also has relative addresses, indicated by
+<TT>+</TT>
+or
+<TT>-</TT>.
+For example,
+<DL><DT><DD><TT><PRE>
+$-3
+</PRE></TT></DL>
+is the third line before the end of the file and
+<DL><DT><DD><TT><PRE>
+.+1
+</PRE></TT></DL>
+is the line after dot.
+If no address appears to the left of the
+<TT>+</TT>
+or
+<TT>-</TT>,
+dot is assumed;
+if nothing appears to the right,
+<TT>1</TT>
+is assumed.
+Therefore,
+<TT>.+1</TT>
+may be abbreviated to just a plus sign.
+</P>
+<P>
+The
+<TT>+</TT>
+operator acts relative to the end of its first argument, while the
+<TT>-</TT>
+operator acts relative to the beginning.  Thus
+<TT>.+1</TT>
+addresses the first line after dot,
+<TT>.-</TT>
+addresses the first line before dot, and
+<TT>+-</TT>
+refers to the line containing the end of dot.  (Dot may span multiple lines, and
+<TT>+</TT>
+selects the line after the end of dot, then
+<TT>-</TT>
+backs up one line.)
+</P>
+<P>
+The final type of address is a regular expression, which addresses the
+text matched by the expression.  The expression is enclosed in slashes, as in
+<DL><DT><DD><TT><PRE>
+/<I>expression</I>/
+</PRE></TT></DL>
+The expressions are the same as those in the UNIX program
+<TT>egrep</TT>,<sup>6,7</sup>
+and include closures, alternations, and so on.
+They find the
+leftmost longest
+string that matches the expression, that is,
+the first match after the point where the search is started,
+and if more than one match begins at the same spot, the longest such match.
+(I assume familiarity with the syntax for regular expressions in UNIX programs.<sup>9</sup>)
+For example,
+<DL><DT><DD><TT><PRE>
+/x/
+</PRE></TT></DL>
+matches the next
+<TT>x</TT>
+character in the file,
+<DL><DT><DD><TT><PRE>
+/xx*/
+</PRE></TT></DL>
+matches the next run of one or more
+<TT>x</TT>'s,
+and
+<DL><DT><DD><TT><PRE>
+/x|Peter/
+</PRE></TT></DL>
+matches the next
+<TT>x</TT>
+or
+<TT>Peter</TT>.
+For compatibility with other UNIX programs, the `any character' operator,
+a period,
+does not match a newline, so
+<DL><DT><DD><TT><PRE>
+/.*/
+</PRE></TT></DL>
+matches the text from dot to the end of the line, but excludes the newline
+and so will not match across
+the line boundary.
+</P>
+<P>
+Regular expressions are always relative addresses.
+The direction is forwards by default,
+so
+<TT>/Peter/</TT>
+is really an abbreviation for
+<TT>+/Peter/</TT>.
+The search can be reversed with a minus sign, so
+<DL><DT><DD><TT><PRE>
+<TT>-/Peter/</TT>
+</PRE></TT></DL>
+finds the first
+<TT>Peter</TT>
+before dot.
+Regular expressions may be used with other address forms, so
+<TT>0+/Peter/</TT>
+finds the first
+<TT>Peter</TT>
+in the file and
+<TT>$-/Peter/</TT>
+finds the last.
+Table II summarizes
+<TT>sam</TT>'s
+addresses.
+<br><img src="-.11762.gif"><br>
+<br>&#32;<br>
+</P>
+<P>
+The language discussed so far will not seem novel
+to people who use UNIX text editors
+such as
+<TT>ed</TT>
+or
+<TT>vi</TT>.<sup>9</sup>
+Moreover, the kinds of editing operations these commands allow, with the exception
+of regular expressions and line numbers,
+are clearly more conveniently handled by a mouse-based interface.
+Indeed,
+<TT>sam</TT>'s
+mouse language (discussed at length below) is the means by which
+simple changes are usually made.
+For large or repetitive changes, however, a textual language
+outperforms a manual interface.
+</P>
+<P>
+Imagine that, instead of deleting just one occurrence of the string
+<TT>Peter</TT>,
+we wanted to eliminate every
+<TT>Peter</TT>.
+What's needed is an iterator that runs a command for each occurrence of some
+text.
+<TT>Sam</TT>'s
+iterator is called
+<TT>x</TT>,
+for extract:
+<DL><DT><DD><TT><PRE>
+x/<I>expression</I>/ <I>command</I>
+</PRE></TT></DL>
+finds all matches in dot of the specified expression, and for each
+such match, sets dot to the text matched and runs the command.
+So to delete all the
+<TT>Peters:</TT>
+<DL><DT><DD><TT><PRE>
+0,$ x/Peter/ d
+</PRE></TT></DL>
+(Blanks in these examples are to improve readability;
+<TT>sam</TT>
+neither requires nor interprets them.)
+This searches the entire file
+(<TT>0,$</TT>)
+for occurrences of the string
+<TT>Peter</TT>,
+and runs the
+<TT>d</TT>
+command with dot set to each such occurrence.
+(By contrast, the comparable
+<TT>ed</TT>
+command would delete all
+<I>lines</I>
+containing
+<TT>Peter</TT>;
+<TT>sam</TT>
+deletes only the
+<TT>Peters</TT>.)
+The address
+<TT>0,$</TT>
+is commonly used, and may be abbreviated to just a comma.
+As another example,
+<DL><DT><DD><TT><PRE>
+, x/Peter/ p
+</PRE></TT></DL>
+prints a list of
+<TT>Peters,</TT>
+one for each appearance in the file, with no intervening text (not even newlines
+to separate the instances).
+</P>
+<P>
+Of course, the text extracted by
+<TT>x</TT>
+may be selected by a regular expression,
+which complicates deciding what set of matches is chosen &#173;
+matches may overlap.  This is resolved by generating the matches
+starting from the beginning of dot using the leftmost-longest rule,
+and searching for each match starting from the end of the previous one.
+Regular expressions may also match null strings, but a null match
+adjacent to a non-null match is never selected; at least one character
+must intervene.
+For example,
+<DL><DT><DD><TT><PRE>
+, c/AAA/
+x/B*/ c/-/
+, p
+</PRE></TT></DL>
+produces as output
+<DL><DT><DD><TT><PRE>
+-A-A-A-
+</PRE></TT></DL>
+because the pattern
+<TT>B*</TT>
+matches the null strings separating the
+<TT>A</TT>'s.
+</P>
+<P>
+The
+<TT>x</TT>
+command has a complement,
+<TT>y</TT>,
+with similar syntax, that executes the command with dot set to the text
+<I>between</I>
+the matches of the expression.
+For example,
+<DL><DT><DD><TT><PRE>
+, c/AAA/
+y/A/ c/-/
+, p
+</PRE></TT></DL>
+produces the same result as the example above.
+</P>
+<P>
+The
+<TT>x</TT>
+and
+<TT>y</TT>
+commands are looping constructs, and
+<TT>sam</TT>
+has a pair of conditional commands to go with them.
+They have similar syntax:
+<DL><DT><DD><TT><PRE>
+g/<I>expression</I>/ <I>command</I>
+</PRE></TT></DL>
+(guard)
+runs the command exactly once if dot contains a match of the expression.
+This is different from
+<TT>x</TT>,
+which runs the command for
+<I>each</I>
+match:
+<TT>x</TT>
+loops;
+<TT>g</TT>
+merely tests, without changing the value of dot.
+Thus,
+<DL><DT><DD><TT><PRE>
+, x/Peter/ d
+</PRE></TT></DL>
+deletes all occurrences of
+<TT>Peter</TT>,
+but
+<DL><DT><DD><TT><PRE>
+, g/Peter/ d
+</PRE></TT></DL>
+deletes the whole file (reduces it to a null string) if
+<TT>Peter</TT>
+occurs anywhere in the text.
+The complementary conditional is
+<TT>v</TT>,
+which runs the command if there is
+<I>no</I>
+match of the expression.
+</P>
+<P>
+These control-structure-like commands may be composed to construct more
+involved operations.  For example, to print those lines of text that
+contain the string
+<TT>Peter</TT>:
+<DL><DT><DD><TT><PRE>
+, x/.*\n/ g/Peter/ p
+</PRE></TT></DL>
+The
+<TT>x</TT>
+breaks the file into lines, the
+<TT>g</TT>
+selects those lines containing
+<TT>Peter</TT>,
+and the
+<TT>p</TT>
+prints them.
+This command gives an address for the
+<TT>x</TT>
+command (the whole file), but because
+<TT>g</TT>
+does not have an explicit address, it applies to the value of
+dot produced by the
+<TT>x</TT>
+command, that is, to each line.
+All commands in
+<TT>sam</TT>
+except for the command to write a file to disc use dot for the
+default address.
+</P>
+<P>
+Composition may be continued indefinitely.
+<DL><DT><DD><TT><PRE>
+, x/.*\n/ g/Peter/ v/SaltPeter/ p
+</PRE></TT></DL>
+prints those lines containing
+<TT>Peter</TT>
+but
+<I>not</I>
+those containing
+<TT>SaltPeter</TT>.
+</P>
+<H4>Structural Regular Expressions
+</H4>
+<br>&#32;<br>
+Unlike other UNIX text editors,
+including the non-interactive ones such as
+<TT>sed</TT>
+and
+<TT>awk</TT>,<sup>7</sup>
+<TT>sam</TT>
+is good for manipulating files with multi-line `records.'
+An example is an on-line phone book composed of records,
+separated by blank lines, of the form
+<DL><DT><DD><TT><PRE>
+Herbert Tic
+44 Turnip Ave., Endive, NJ
+201-5555642
+
+Norbert Twinge
+16 Potato St., Cabbagetown, NJ
+201-5553145
+
+...
+</PRE></TT></DL>
+The format may be encoded as a regular expression:
+<DL><DT><DD><TT><PRE>
+(.+\n)+
+</PRE></TT></DL>
+that is, a sequence of one or more non-blank lines.
+The command to print Mr. Tic's entire record is then
+<DL><DT><DD><TT><PRE>
+, x/(.+\n)+/ g/^Herbert Tic$/ p
+</PRE></TT></DL>
+and that to extract just the phone number is
+<DL><DT><DD><TT><PRE>
+, x/(.+\n)+/ g/^Herbert Tic$/ x/^[0-9]*-[0-9]*\n/ p
+</PRE></TT></DL>
+The latter command breaks the file into records,
+chooses Mr. Tic's record,
+extracts the phone number from the record,
+and finally prints the number.
+<P>
+A more involved problem is that of
+renaming a particular variable, say
+<TT>n</TT>,
+to
+<TT>num</TT>
+in a C program.
+The obvious first attempt,
+<DL><DT><DD><TT><PRE>
+, x/n/ c/num/
+</PRE></TT></DL>
+is badly flawed: it changes not only the variable
+<TT>n</TT>
+but any letter
+<TT>n</TT>
+that appears.
+We need to extract all the variables, and select those that match
+<TT>n</TT>
+and only
+<TT>n</TT>:
+<DL><DT><DD><TT><PRE>
+, x/[A-Za-z_][A-Za-z_0-9]*/ g/n/ v/../ c/num/
+</PRE></TT></DL>
+The pattern
+<TT>[A-Za-z_][A-Za-z_0-9]*</TT>
+matches C identifiers.
+Next
+<TT>g/n/</TT>
+selects those containing an
+<TT>n</TT>.
+Then
+<TT>v/../</TT>
+rejects those containing two (or more) characters, and finally
+<TT>c/num/</TT>
+changes the remainder (identifiers
+<TT>n</TT>)
+to
+<TT>num</TT>.
+This version clearly works much better, but there may still be problems.
+For example, in C character and string constants, the sequence
+<TT>0fP
+is interpreted as a newline character, and we don't want to change it to
+</TT><TT>0m.</TT><TT>
+This problem can be forestalled with a
+</TT><TT>y</TT><TT>
+command:
+<DL><DT><DD><TT><PRE>
+, y/\\n/ x/[A-Za-z_][A-Za-z_0-9]*/ g/n/ v/../ c/num/
+</PRE></TT></DL>
+(the second
+</TT><TT>\fP
+is necessary because of lexical conventions in regular expressions),
+or we could even reject character constants and strings outright:
+<DL><DT><DD><TT><PRE>
+,y/'[^']*'/ y/"[^"]*"/ x/[A-Za-z_][A-Za-z_0-9]*/ g/n/ v/../ c/num/
+</PRE></TT></DL>
+The
+</TT><TT>y</TT><TT>
+commands in this version exclude from consideration all character constants
+and strings.
+The only remaining problem is to deal with the possible occurrence of
+</TT><TT>'</TT><TT>
+or
+</TT><TT>
+within these sequences, but it's easy to see how to resolve this difficulty.
+</P>
+</TT><P>
+The point of these composed commands is successive refinement.
+A simple version of the command is tried, and if it's not good enough,
+it can be honed by adding a clause or two.
+(Mistakes can be undone; see below.
+Also, the mouse language makes it unnecessary to retype the command each time.)
+The resulting chains of commands are somewhat reminiscent of
+shell pipelines.<sup>7</sup>
+Unlike pipelines, though, which pass along modified
+<I>data</I>,
+<TT>sam</TT>
+commands pass a
+<I>view</I>
+of the data.
+The text at each step of the command is the same, but which pieces
+are selected is refined step by step until the correct piece is
+available to the final step of the command line, which ultimately makes the change.
+</P>
+<P>
+In other UNIX programs, regular expressions are used only for selection,
+as in the
+<TT>sam</TT>
+<TT>g</TT>
+command, never for extraction as in the
+<TT>x</TT>
+or
+<TT>y</TT>
+command.
+For example, patterns in
+<TT>awk</TT><sup>7</sup>
+are used to select lines to be operated on, but cannot be used
+to describe the format of the input text, or to handle newline-free text.
+The use of regular expressions to describe the structure of a piece
+of text rather than its contents, as in the
+<TT>x</TT>
+command, 
+has been given a name:
+structural regular expressions.
+When they are composed, as in the above example,
+they are pleasantly expressive.
+Their use is discussed at greater length elsewhere.<sup>10</sup>
+</P>
+<P>
+</P>
+<H4>Multiple files
+</H4>
+<br>&#32;<br>
+<TT>Sam</TT>
+has a few other commands, mostly relating to input and output.
+<DL><DT><DD><TT><PRE>
+e discfilename
+</PRE></TT></DL>
+replaces the contents and name of the current file with those of the named
+disc file;
+<DL><DT><DD><TT><PRE>
+w discfilename
+</PRE></TT></DL>
+writes the contents to the named disc file; and
+<DL><DT><DD><TT><PRE>
+r discfilename
+</PRE></TT></DL>
+replaces dot with the contents of the named disc file.
+All these commands use the current file's name if none is specified.
+Finally,
+<DL><DT><DD><TT><PRE>
+f discfilename
+</PRE></TT></DL>
+changes the name associated with the file and displays the result:
+<DL><DT><DD><TT><PRE>
+'-. discfilename
+</PRE></TT></DL>
+This output is called the file's
+menu line,
+because it is the contents of the file's line in the button 3 menu (described
+in the
+next section).
+The first three characters are a concise notation for the state of the file.
+The apostrophe signifies that the file is modified.
+The minus sign indicates the number of windows
+open on the file (see the next section):
+<TT>-</TT>
+means none,
+<TT>+</TT>
+means one, and
+<TT>*</TT>
+means more than one.
+Finally, the period indicates that this is the current file.
+These characters are useful for controlling the
+<TT>X</TT>
+command, described shortly.
+<P>
+<TT>Sam</TT>
+may be started with a set of disc files (such as all the source for
+a program) by invoking it with a list of file names as arguments, and
+more may be added or deleted on demand.
+<DL><DT><DD><TT><PRE>
+B discfile1 discfile2 ...
+</PRE></TT></DL>
+adds the named files to
+<TT>sam</TT>'s
+list, and
+<DL><DT><DD><TT><PRE>
+D discfile1 discfile2 ...
+</PRE></TT></DL>
+removes them from
+<TT>sam</TT>'s
+memory (without effect on associated disc files).
+Both these commands have a syntax for using the shell<sup>7</sup>
+(the UNIX command interpreter) to generate the lists:
+<DL><DT><DD><TT><PRE>
+B &#60;echo *.c
+</PRE></TT></DL>
+will add all C source files, and
+<DL><DT><DD><TT><PRE>
+B &#60;grep -l variable *.c
+</PRE></TT></DL>
+will add all C source files referencing a particular variable
+(the UNIX command
+<TT>grep -l</TT>
+lists all files in its arguments that contain matches of
+the specified regular expression).
+Finally,
+<TT>D</TT>
+without arguments deletes the current file.
+</P>
+<P>
+There are two ways to change which file is current:
+<DL><DT><DD><TT><PRE>
+b filename
+</PRE></TT></DL>
+makes the named file current.
+The
+<TT>B</TT>
+command
+does the same, but also adds any new files to
+<TT>sam</TT>'s
+list.
+(In practice, of course, the current file
+is usually chosen by mouse actions, not by textual commands.)
+The other way is to use a form of address that refers to files:
+<DL><DT><DD><TT><PRE>
+"<I>expression</I>" <I>address</I>
+</PRE></TT></DL>
+refers to the address evaluated in the file whose menu line
+matches the expression (there must be exactly one match).
+For example,
+<DL><DT><DD><TT><PRE>
+"peter.c" 3
+</PRE></TT></DL>
+refers to the third line of the file whose name matches
+<TT>peter.c</TT>.
+This is most useful in the move
+(<TT>m</TT>)
+and copy
+(<TT>t</TT>)
+commands:
+<DL><DT><DD><TT><PRE>
+0,$ t "peter.c" 0
+</PRE></TT></DL>
+makes a copy of the current file at the beginning of
+<TT>peter.c</TT>.
+</P>
+<P>
+The
+<TT>X</TT>
+command
+is a looping construct, like
+<TT>x</TT>,
+that refers to files instead of strings:
+<DL><DT><DD><TT><PRE>
+X/<I>expression</I>/ <I>command</I>
+</PRE></TT></DL>
+runs the command in all
+files whose menu lines match the expression.  The best example is
+<DL><DT><DD><TT><PRE>
+X/'/ w
+</PRE></TT></DL>
+which writes to disc all modified files.
+<TT>Y</TT>
+is the complement of
+<TT>X</TT>:
+it runs the command on all files whose menu lines don't match the expression:
+<DL><DT><DD><TT><PRE>
+Y/\.c/ D
+</PRE></TT></DL>
+deletes all files that don't have
+<TT>.c</TT>
+in their names, that is, it keeps all C source files and deletes the rest.
+</P>
+<P>
+Braces allow commands to be grouped, so
+<DL><DT><DD><TT><PRE>
+{
+	<I>command1</I>
+	<I>command2</I>
+}
+</PRE></TT></DL>
+is syntactically a single command that runs two commands.
+Thus,
+<DL><DT><DD><TT><PRE>
+X/\.c/ ,g/variable/ {
+	f
+	, x/.*\n/ g/variable/ p
+}
+</PRE></TT></DL>
+finds all occurrences of
+<TT>variable</TT>
+in C source files, and prints
+out the file names and lines of each match.
+The precise semantics of compound operations is discussed in the implementation
+sections below.
+</P>
+<P>
+Finally,
+the undo command,
+<TT>u</TT>,
+undoes the last command,
+no matter how many files were affected.
+Multiple undo operations move further back in time, so
+<DL><DT><DD><TT><PRE>
+u
+u
+</PRE></TT></DL>
+(which may be abbreviated
+<TT>u2</TT>)
+undoes the last two commands.  An undo may not be undone, however, nor
+may any command that adds or deletes files.
+Everything else is undoable, though, including for example
+<TT>e</TT>
+commands:
+<DL><DT><DD><TT><PRE>
+e filename
+u
+</PRE></TT></DL>
+restores the state of the file completely, including its name, dot,
+and modified bit.  Because of the undo, potentially dangerous commands
+are not guarded by confirmations.  Only
+<TT>D</TT>,
+which destroys the information necessary to restore itself, is protected.
+It will not delete a modified file, but a second
+<TT>D</TT>
+of the same file will succeed regardless.
+The
+<TT>q</TT>
+command, which exits
+<TT>sam</TT>,
+is similarly guarded.
+</P>
+<H4>Mouse Interface
+</H4>
+<br>&#32;<br>
+<TT>Sam</TT>
+is most commonly run
+connected to a bitmap display and mouse for interactive editing.
+The only difference in the command language
+between regular, mouse-driven
+<TT>sam</TT>
+and
+<TT>sam -d</TT>
+is that if an address
+is provided without a command,
+<TT>sam -d</TT>
+will print the text referenced by the address, but
+regular
+<TT>sam</TT>
+will highlight it on the screen &#173; in fact,
+dot is always highlighted (see Figure 2).
+<br><img src="fig3.ps.11763.gif"><br>
+<br>
+<I>Figure 2. A
+</I><TT>sam</TT><I>
+window.  The scroll bar down the left
+represents the file, with the bubble showing the fraction
+visible in the window.
+The scroll bar may be manipulated by the mouse for convenient browsing.
+The current text,
+which is highlighted, need not fit on a line.  Here it consists of one partial
+line, one complete line, and final partial line.
+<br>
+<DL><DT><DD><TT><PRE>
+</I><br>&#32;<br>
+</PRE></TT></DL>
+<P>
+Each file may have zero or more windows open on the display.
+At any time, only one window in all of
+<TT>sam</TT>
+is the
+current window,
+that is, the window to which typing and mouse actions refer;
+this may be the
+<TT>sam</TT>
+window (that in which commands may be typed)
+or one of the file windows.
+When a file has multiple windows, the image of the file in each window
+is always kept up to date.
+The current file is the last file affected by a command,
+so if the
+<TT>sam</TT>
+window is current,
+the current window is not a window on the current file.
+However, each window on a file has its own value of dot,
+and when switching between windows on a single file,
+the file's value of dot is changed to that of the window.
+Thus, flipping between windows behaves in the obvious, convenient way.
+</P>
+<P>
+The mouse on the Blit has three buttons, numbered left to right.
+Button 3 has a list of commands to manipulate windows,
+followed by a list of `menu lines' exactly as printed by the
+<TT>f</TT>
+command, one per file (not one per window).
+These menu lines are sorted by file name.
+If the list is long, the Blit menu software will make it more manageable
+by generating a scrolling menu instead of an unwieldy long list.
+Using the menu to select a file from the list makes that file the current
+file, and the most recently current window in that file the current window.
+But if that file is already current, selecting it in the menu cycles through
+the windows on the file; this simple trick avoids a special menu to
+choose windows on a file.
+If there is no window open on the file,
+<TT>sam</TT>
+changes the mouse cursor to prompt the user to create one.
+</P>
+<P>
+The commands on the button 3 menu are straightforward (see Figure 3), and
+are like the commands to manipulate windows in
+<TT>mux</TT>,<sup>8</sup>
+the Blit's window system.
+<TT>New</TT>
+makes a new file, and gives it one empty window, whose size is determined
+by a rectangle swept by the mouse.
+<TT>Zerox</TT>
+prompts for a window to be selected, and
+makes a clone of that window; this is how multiple windows are created on one file.
+<TT>Reshape</TT>
+changes the size of the indicated window, and
+<TT>close</TT>
+deletes it.  If that is the last window open on the file,
+<TT>close</TT>
+first does a
+<TT>D</TT>
+command on the file.
+<TT>Write</TT>
+is identical to a
+<TT>w</TT>
+command on the file; it is in the menu purely for convenience.
+Finally,
+<TT>~~sam~~</TT>
+is a menu item that appears between the commands and the file names.
+Selecting it makes the
+<TT>sam</TT>
+window the current window,
+causing subsequent typing to be interpreted as commands.
+<br><img src="fig2.ps.11764.gif"><br>
+<br>
+<I>Figure 3. The menu on button 3.
+The black rectangle on the left is a scroll bar; the menu is limited to
+the length shown to prevent its becoming unwieldy.
+Above the
+</I><TT>~~sam~~</TT><I>
+line is a list of commands;
+beneath it is a list of files, presented exactly as with the
+</I><TT>f</TT><I>
+command.
+<br>
+<DL><DT><DD><TT><PRE>
+</I><br>&#32;<br>
+</PRE></TT></DL>
+</P>
+<P>
+When
+<TT>sam</TT>
+requests that a window be swept, in response to
+<TT>new</TT>,
+<TT>zerox</TT>
+or
+<TT>reshape</TT>,
+it changes the mouse cursor from the usual arrow to a box with
+a small arrow.
+In this state, the mouse may be used to indicate an arbitrary rectangle by
+pressing button 3 at one corner and releasing it at the opposite corner.
+More conveniently,
+button 3 may simply be clicked,
+whereupon
+<TT>sam</TT>
+creates the maximal rectangle that contains the cursor
+and abuts the
+<TT>sam</TT>
+window.
+By placing the
+<TT>sam</TT>
+window in the middle of the screen, the user can define two regions (one above,
+one below) in which stacked fully-overlapping
+windows can be created with minimal fuss (see Figure 1).
+This simple user interface trick makes window creation noticeably easier.
+</P>
+<P>
+The cut-and-paste editor is essentially the same as that in Smalltalk-80.<sup>11</sup>
+The text in dot is always highlighted on the screen.
+When a character is typed it replaces dot, and sets dot to the null
+string after the character.  Thus, ordinary typing inserts text.
+Button 1 is used for selection:
+pressing the button, moving the mouse, and lifting the button
+selects (sets dot to) the text between the points where the
+button was pressed and released.
+Pressing and releasing at the same point selects a null string; this
+is called clicking.  Clicking twice quickly, or
+double clicking,
+selects larger objects;
+for example, double clicking in a word selects the word,
+double clicking just inside an opening bracket selects the text
+contained in the brackets (handling nested brackets correctly),
+and similarly for
+parentheses, quotes, and so on.
+The double-clicking rules reflect a bias toward
+programmers.
+If
+<TT>sam</TT>
+were intended more for word processing, double-clicks would probably
+select linguistic structures such as sentences.
+</P>
+<P>
+If button 1 is pressed outside the current window, it makes the indicated
+window current.
+This is the easiest way to switch between windows and files.
+</P>
+<P>
+Pressing button 2 brings up a menu of editing functions (see Figure 4).
+These mostly apply to the selected text:
+<TT>cut</TT>
+deletes the selected text, and remembers it in a hidden buffer called the
+snarf buffer,
+<TT>paste</TT>
+replaces the selected text by the contents of the snarf buffer,
+<TT>snarf</TT>
+just copies the selected text to the snarf buffer,
+<TT>look</TT>
+searches forward for the next literal occurrence of the selected text, and
+<TT><mux></TT>
+exchanges snarf buffers with the window system in which
+<TT>sam</TT>
+is running.
+Finally, the last regular expression used appears as a menu entry
+to search
+forward for the next occurrence of a match for the expression.
+<br><img src="fig4.ps.11765.gif"><br>
+<br>
+<I>Figure 4. The menu on button 2.
+The bottom entry tracks the most recently used regular expression, which may
+be literal text.
+<br>
+<DL><DT><DD><TT><PRE>
+</I><br>&#32;<br>
+</PRE></TT></DL>
+</P>
+<P>
+The relationship between the command language and the mouse language is
+entirely due to the equality of dot and the selected text chosen
+with button 1 on the mouse.
+For example, to make a set of changes in a C subroutine, dot can be
+set by double clicking on the left brace that begins the subroutine,
+which sets dot for the command language.
+An address-free command then typed in the
+<TT>sam</TT>
+window will apply only to the text between the opening and closing
+braces of the function.
+The idea is to select what you want, and then say what you want
+to do with it, whether invoked by a menu selection or by a typed command.
+And of course, the value of dot is highlighted on
+the display after the command completes.
+This relationship between mouse interface and command language
+is clumsy to explain, but comfortable, even natural, in practice.
+</P>
+<H4>The Implementation
+</H4>
+<br>&#32;<br>
+The next few sections describe how
+<TT>sam</TT>
+is put together, first the host part,
+then the inter-component communication,
+then the terminal part.
+After explaining how the command language is implemented,
+the discussion follows (roughly) the path of a character
+from the temporary file on disc to the screen.
+The presentation centers on the data structures,
+because that is how the program was designed and because
+the algorithms are easy to provide, given the right data
+structures.
+<H4>Parsing and execution
+</H4>
+<br>&#32;<br>
+The command language is interpreted by parsing each command with a
+table-driven recursive
+descent parser, and when a complete command is assembled, invoking a top-down
+executor.
+Most editors instead employ a simple character-at-a-time
+lexical scanner.
+Use of a parser makes it
+easy and unambiguous to detect when a command is complete,
+which has two advantages.
+First, escape conventions such as backslashes to quote
+multiple-line commands are unnecessary;  if the command isn't finished,
+the parser keeps reading.  For example, a multiple-line append driven by an
+<TT>x</TT>
+command is straightforward:
+<DL><DT><DD><TT><PRE>
+x/.*\n/ g/Peter/ a
+one line about Peter
+another line about Peter
+.
+</PRE></TT></DL>
+Other UNIX editors would require a backslash after all but the last line.
+<P>
+The other advantage is specific to the two-process structure of
+<TT>sam</TT>.
+The host process must decide when a command is completed so the
+command interpreter can be called.  This problem is easily resolved
+by having the lexical analyzer read the single stream of events from the
+terminal, directly executing all typing and mouse commands,
+but passing to the parser characters typed to the
+<TT>sam</TT>
+command window.
+This scheme is slightly complicated by the availability of cut-and-paste
+editing in the
+<TT>sam</TT>
+window, but that difficulty is resolved by applying the rules
+used in
+<TT>mux</TT>:
+when a newline is typed to the
+<TT>sam</TT>
+window, all text between the newline and the previously typed newline
+is made available to the parser.
+This permits arbitrary editing to be done to a command before
+typing newline and thereby requesting execution.
+</P>
+<P>
+The parser is driven by a table because the syntax of addresses
+and commands is regular enough
+to be encoded compactly.  There are few special cases, such as the
+replacement text in a substitution, so the syntax of almost all commands
+can be encoded with a few flags.
+These include whether the command allows an address (for example,
+<TT>e</TT>
+does not), whether it takes a regular expression (as in
+<TT>x</TT>
+and
+<TT>s</TT>),
+whether it takes replacement text (as in
+<TT>c</TT>
+or
+<TT>i</TT>),
+which may be multi-line, and so on.
+The internal syntax of regular expressions is handled by a separate
+parser; a regular expression is a leaf of the command parse tree.
+Regular expressions are discussed fully in the next section.
+</P>
+<P>
+The parser table also has information about defaults, so the interpreter
+is always called with a complete tree.  For example, the parser fills in
+the implicit
+<TT>0</TT>
+and
+<TT>$</TT>
+in the abbreviated address
+<TT>,</TT>
+(comma),
+inserts a
+<TT>+</TT>
+to the left of an unadorned regular expression in an address,
+and provides the usual default address
+<TT>.</TT>
+(dot) for commands that expect an address but are not given one.
+</P>
+<P>
+Once a complete command is parsed, the evaluation is easy.
+The address is evaluated left-to-right starting from the value of dot,
+with a mostly ordinary expression evaluator.
+Addresses, like many of the data structures in
+<TT>sam</TT>,
+are held in a C structure and passed around by value:
+<DL><DT><DD><TT><PRE>
+typedef long Posn;    /* Position in a file */
+typedef struct Range{
+        Posn    p1, p2;
+}Range;
+typedef struct Address{
+        Range   r;
+        File    *f;
+}Address;
+</PRE></TT></DL>
+An address is encoded as a substring (character positions
+<TT>p1</TT>
+to
+<TT>p2</TT>)
+in a file
+<TT>f</TT>.
+(The data type
+<TT>File</TT>
+is described in detail below.)
+</P>
+<P>
+The address interpreter is an
+<TT>Address</TT>-valued
+function that traverses the parse tree describing an address (the
+parse tree for the address has type
+<TT>Addrtree</TT>):
+<DL><DT><DD><TT><PRE>
+Address
+address(ap, a, sign)
+	Addrtree *ap;
+	Address a;
+	int sign;
+{
+	Address a2;
+	do
+		switch(ap-&#62;type){
+		case '.':
+			a=a.f-&#62;dot;
+			break;
+		case '$':
+			a.r.p1=a.r.p2=a.f-&#62;nbytes;
+			break;
+		case '"':	
+			a=matchfile(a, ap-&#62;aregexp)-&#62;dot; 
+			break;
+		case ',':
+			a2=address(ap-&#62;right, a, 0);
+			a=address(ap-&#62;left, a, 0);
+			if(a.f!=a2.f || a2.r.p2&#60;a.r.p1)
+				error(Eorder);
+			a.r.p2=a2.r.p2;
+			return a;
+		/* and so on */
+		}
+	while((ap=ap-&#62;right)!=0);
+	return a;
+}
+</PRE></TT></DL>
+</P>
+<P>
+Throughout, errors are handled by a non-local
+<TT>goto</TT>
+(a
+<TT>setjmp/longjmp</TT>
+in C terminology)
+hidden in a routine called
+<TT>error</TT>
+that immediately aborts the execution, retracts any
+partially made changes (see the section below on `undoing'), and
+returns to the top level of the parser.
+The argument to
+<TT>error</TT>
+is an enumeration type that
+is translated to a terse but possibly helpful
+message such as `?addresses out of order.'
+Very common messages are kept short; for example the message for
+a failed regular expression search is `?search.'
+</P>
+<P>
+Character addresses such as
+<TT>#3</TT>
+are trivial to implement, as the
+<TT>File</TT>
+data structure is accessible by character number.
+However,
+<TT>sam</TT>
+keeps no information about the position of newlines &#173; it is too
+expensive to track dynamically &#173; so line addresses are computed by reading
+the file, counting newlines.  Except in very large files, this has proven
+acceptable: file access is fast enough to make the technique practical,
+and lines are not central to the structure of the command language.
+</P>
+<P>
+The command interpreter, called
+<TT>cmdexec</TT>,
+is also straightforward.  The parse table includes a
+function to call to interpret a particular command.  That function
+receives as arguments
+the calculated address
+for the command
+and the command tree (of type
+<TT>Cmdtree</TT>),
+which may contain information such as the subtree for compound commands.
+Here, for example, is the function for the
+<TT>g</TT>
+and
+<TT>v</TT>
+commands:
+<DL><DT><DD><TT><PRE>
+int
+g_cmd(a, cp)
+	Address a;
+	Cmdtree *cp;
+{
+	compile(cp-&#62;regexp);
+	if(execute(a.f, a.r.p1, a.r.p2)!=(cp-&#62;cmdchar=='v')){
+		a.f-&#62;dot=a;
+		return cmdexec(a, cp-&#62;subcmd);
+	}
+	return TRUE;	/* cause execution to continue */
+}
+</PRE></TT></DL>
+(<TT>Compile</TT>
+and
+<TT>execute</TT>
+are part of the regular expression code, described in the next section.)
+Because the parser and the
+<TT>File</TT>
+data structure do most of the work, most commands
+are similarly brief.
+</P>
+<H4>Regular expressions
+</H4>
+<br>&#32;<br>
+The regular expression code in
+<TT>sam</TT>
+is an interpreted, rather than compiled on-the-fly, implementation of Thompson's
+non-deterministic finite automaton algorithm.<sup>12</sup>
+The syntax and semantics of the expressions are as in the UNIX program
+<TT>egrep</TT>,
+including alternation, closures, character classes, and so on.
+The only changes in the notation are two additions:
+<TT>0fP
+is translated to, and matches, a newline character, and
+</TT><TT>@</TT><TT>
+matches any character.  In
+</TT><TT>egrep</TT><TT>,
+the character
+</TT><TT>.</TT><TT>
+matches any character except newline, and in
+</TT><TT>sam</TT><TT>
+the same rule seemed safest, to prevent idioms like
+</TT><TT>.*</TT><TT>
+from spanning newlines.
+</TT><TT>Egrep</TT><TT>
+expressions are arguably too complicated for an interactive editor &#173;
+certainly it would make sense if all the special characters were two-character
+sequences, so that most of the punctuation characters wouldn't have
+peculiar meanings &#173; but for an interesting command language, full
+regular expressions are necessary, and
+</TT><TT>egrep</TT><TT>
+defines the full regular expression syntax for UNIX programs.
+Also, it seemed superfluous to define a new syntax, since various UNIX programs
+(</TT><TT>ed</TT><TT>,
+</TT><TT>egrep</TT><TT>
+and
+</TT><TT>vi</TT><TT>)
+define too many already.
+</TT><P>
+The expressions are compiled by a routine,
+<TT>compile</TT>,
+that generates the description of the non-deterministic finite state machine.
+A second routine,
+<TT>execute</TT>,
+interprets the machine to generate the leftmost-longest match of the
+expression in a substring of the file.
+The algorithm is described elsewhere.<sup>12,13</sup>
+<TT>Execute</TT>
+reports
+whether a match was found, and sets a global variable,
+of type
+<TT>Range</TT>,
+to the substring matched.
+</P>
+<P>
+A trick is required to evaluate the expression in reverse, such as when
+searching backwards for an expression.
+For example,
+<DL><DT><DD><TT><PRE>
+-/P.*r/
+</PRE></TT></DL>
+looks backwards through the file for a match of the expression.
+The expression, however, is defined for a forward search.
+The solution is to construct a machine identical to the machine
+for a forward search except for a reversal of all the concatenation
+operators (the other operators are symmetric under direction reversal),
+to exchange the meaning of the operators
+<TT>^</TT>
+and
+<TT>$</TT>,
+and then to read the file backwards, looking for the
+usual earliest longest match.
+</P>
+<P>
+<TT>Execute</TT>
+generates only one match each time it is called.
+To interpret looping constructs such as the
+<TT>x</TT>
+command,
+<TT>sam</TT>
+must therefore synchronize between
+calls of
+<TT>execute</TT>
+to avoid
+problems with null matches.
+For example, even given the leftmost-longest rule,
+the expression
+<TT>a*</TT>
+matches three times in the string
+<TT>ab</TT>
+(the character
+<TT>a</TT>,
+the null string between the
+<TT>a</TT>
+and
+<TT>b</TT>,
+and the final null string).
+After returning a match for the
+<TT>a</TT>,
+<TT>sam</TT>
+must not match the null string before the
+<TT>b</TT>.
+The algorithm starts
+<TT>execute</TT>
+at the end of its previous match, and
+if the match it returns
+is null and abuts the previous match, rejects the match and advances
+the initial position one character.
+</P>
+<H4>Memory allocation
+</H4>
+<br>&#32;<br>
+The C language has no memory allocation primitives, although a standard
+library routine,
+<TT>malloc</TT>,
+provides adequate service for simple programs.
+For specific uses, however,
+it can be better to write a custom allocator.
+The allocator (or rather, pair of allocators) described here
+work in both the terminal and host parts of
+<TT>sam</TT>.
+They are designed for efficient manipulation of strings,
+which are allocated and freed frequently and vary in length from essentially
+zero to 32 Kbytes (very large strings are written to disc).
+More important, strings may be large and change size often,
+so to minimize memory usage it is helpful to reclaim and to coalesce the
+unused portions of strings when they are truncated.
+<P>
+Objects to be allocated in
+<TT>sam</TT>
+are of two flavors:
+the first is C
+<TT>structs</TT>,
+which are small and often addressed by pointer variables;
+the second is variable-sized arrays of characters
+or integers whose
+base pointer is always used to access them.
+The memory allocator in
+<TT>sam</TT>
+is therefore in two parts:
+first, a traditional first-fit allocator that provides fixed storage for
+<TT>structs</TT>;
+and second, a garbage-compacting allocator that reduces storage
+overhead for variable-sized objects, at the cost of some bookkeeping.
+The two types of objects are allocated from adjoining arenas, with
+the garbage-compacting allocator controlling the arena with higher addresses.
+Separating into two arenas simplifies compaction and prevents fragmentation due
+to immovable objects.
+The access rules for garbage-compactable objects
+(discussed in the next paragraph) allow them to be relocated, so when
+the first-fit arena needs space, it moves the garbage-compacted arena
+to higher addresses to make room.  Storage is therefore created only
+at successively higher addresses, either when more garbage-compacted
+space is needed or when the first-fit arena pushes up the other arena.
+</P>
+<P>
+Objects that may be compacted declare to the
+allocator a cell that is guaranteed to be the sole repository of the
+address of the object whenever a compaction can occur.
+The compactor can then update the address when the object is moved.
+For example, the implementation of type
+<TT>List</TT>
+(really a variable-length array)
+is:
+<DL><DT><DD><TT><PRE>
+typedef struct List{
+        int     nused;
+        long    *ptr;
+}List;
+</PRE></TT></DL>
+The
+<TT>ptr</TT>
+cell must always be used directly, and never copied.  When a
+<TT>List</TT>
+is to be created the
+<TT>List</TT>
+structure is allocated in the ordinary first-fit arena
+and its
+<TT>ptr</TT>
+is allocated in the garbage-compacted arena.
+A similar data type for strings, called
+<TT>String</TT>,
+stores variable-length character arrays of up to 32767 elements.
+</P>
+<P>
+A related matter of programming style:
+<TT>sam</TT>
+frequently passes structures by value, which
+simplifies the code.
+Traditionally, C programs have
+passed structures by reference, but implicit allocation on
+the stack is easier to use.
+Structure passing is a relatively new feature of C
+(it is not in the 
+standard reference manual for C<sup>14</sup>), and is poorly supported in most
+commercial C compilers.
+It's convenient and expressive, though,
+and simplifies memory management by
+avoiding the allocator altogether
+and eliminating pointer aliases.
+</P>
+<H4>Data structures for manipulating files
+</H4>
+<br>&#32;<br>
+Experience with
+<TT>jim</TT>
+showed that the requirements
+of the file data structure were few, but strict.
+First, files need to be read and written quickly;
+adding a fresh file must be painless.
+Second, the implementation must place no arbitrary upper limit on
+the number or sizes of files.  (It should be practical to edit many files,
+and files up to megabytes in length should be handled gracefully.)
+This implies that files be stored on disc, not in main memory.
+(Aficionados of virtual memory may argue otherwise, but the
+implementation of virtual
+memory in our system is not something to depend on
+for good performance.)
+Third, changes to files need be made by only two primitives:
+deletion and insertion.
+These are inverses of each other,
+which simplifies the implementation of the undo operation.
+Finally,
+it must be easy and efficient to access the file, either
+forwards or backwards, a byte at a time.
+<P>
+The
+<TT>File</TT>
+data type is constructed from three simpler data structures that hold arrays
+of characters.
+Each of these types has an insertion and deletion operator, and the
+insertion and deletion operators of the
+<TT>File</TT>
+type itself are constructed from them.
+</P>
+<P>
+The simplest type is the
+<TT>String</TT>,
+which is used to hold strings in main memory.
+The code that manages
+<TT>Strings</TT>
+guarantees that they will never be longer
+than some moderate size, and in practice they are rarely larger than 8 Kbytes.
+<TT>Strings</TT>
+have two purposes: they hold short strings like file names with little overhead,
+and because they are deliberately small, they are efficient to modify.
+They are therefore used as the data structure for in-memory caches.
+</P>
+<P>
+The disc copy of the file is managed by a data structure called a
+<TT>Disc</TT>,
+which corresponds to a temporary file.  A
+<TT>Disc</TT>
+has no storage in main memory other than bookkeeping information;
+the actual data being held is all on the disc.
+To reduce the number of open files needed,
+<TT>sam</TT>
+opens a dozen temporary UNIX files and multiplexes the
+<TT>Discs</TT>
+upon them.
+This permits many files to
+be edited; the entire
+<TT>sam</TT>
+source (48 files) may be edited comfortably with a single
+instance of
+<TT>sam</TT>.
+Allocating one temporary file per
+<TT>Disc</TT>
+would strain the operating system's limit on the number of open files.
+Also, spreading the traffic among temporary files keeps the files shorter,
+and shorter files are more efficiently implemented by the UNIX
+I/O subsystem.
+</P>
+<P>
+A
+<TT>Disc</TT>
+is an array of fixed-length blocks, each of which contains
+between 1 and 4096 characters of active data.
+(The block size of our UNIX file system is 4096 bytes.)
+The block addresses within the temporary file and the length of each
+block are stored in a
+<TT>List</TT>.
+When changes are made the live part of blocks may change size.
+Blocks are created and coalesced when necessary to try to keep the sizes
+between 2048 and 4096 bytes.
+An actively changing part of the
+<TT>Disc</TT>
+therefore typically has about a kilobyte of slop that can be
+inserted or deleted
+without changing more than one block or affecting the block order.
+When an insertion would overflow a block, the block is split, a new one
+is allocated to receive the overflow, and the memory-resident list of blocks
+is rearranged to reflect the insertion of the new block.
+</P>
+<P>
+Obviously, going to the disc for every modification to the file is
+prohibitively expensive.
+The data type
+<TT>Buffer</TT>
+consists of a
+<TT>Disc</TT>
+to hold the data and a
+<TT>String</TT>
+that acts as a cache.
+This is the first of a series of caches throughout the data structures in
+<TT>sam.</TT>
+The caches not only improve performance, they provide a way to organize
+the flow of data, particularly in the communication between the host
+and terminal.
+This idea is developed below, in the section on communications.
+</P>
+<P>
+To reduce disc traffic, changes to a
+<TT>Buffer</TT>
+are mediated by a variable-length string, in memory, that acts as a cache.
+When an insertion or deletion is made to a
+<TT>Buffer</TT>,
+if the change can be accommodated by the cache, it is done there.
+If the cache becomes bigger than a block because of an insertion,
+some of it is written to the
+<TT>Disc</TT>
+and deleted from the cache.
+If the change does not intersect the cache, the cache is flushed.
+The cache is only loaded at the new position if the change is smaller than a block;
+otherwise, it is sent directly to the
+<TT>Disc</TT>.
+This is because
+large changes are typically sequential,
+whereupon the next change is unlikely to overlap the current one.
+</P>
+<P>
+A
+<TT>File</TT>
+comprises a
+<TT>String</TT>
+to hold the file name and some ancillary data such as dot and the modified bit.
+The most important components, though, are a pair of
+<TT>Buffers</TT>,
+one called the transcript and the other the contents.
+Their use is described in the next section.
+</P>
+<P>
+The overall structure is shown in Figure 5.
+Although it may seem that the data is touched many times on its
+way from the
+<TT>Disc</TT>,
+it is read (by one UNIX system call) directly into the cache of the
+associated
+<TT>Buffer</TT>;
+no extra copy is done.
+Similarly, when flushing the cache, the text is written
+directly from the cache to disc.
+Most operations act directly on the text in the cache.
+A principle applied throughout
+<TT>sam</TT>
+is that the fewer times the data is copied, the faster the program will run
+(see also the paper by Waite<sup>15</sup>).
+<DL><DT><DD><TT><PRE>
+<br><img src="-.11766.gif"><br>
+<br>
+</PRE></TT></DL>
+<I>Figure 5. File data structures.
+The temporary files are stored in the standard repository for such files
+on the host system.
+<br>
+<DL><DT><DD><TT><PRE>
+</I><br>&#32;<br>
+</PRE></TT></DL>
+</P>
+<P>
+The contents of a
+<TT>File</TT>
+are accessed by a routine that
+copies to a buffer a substring of a file starting at a specified offset.
+To read a byte at a time, a
+per-<TT>File</TT>
+array is loaded starting from a specified initial position,
+and bytes may then be read from the array.
+The implementation is done by a macro similar to the C standard I/O
+<TT>getc</TT>
+macro.<sup>14</sup>
+Because the reading may be done at any address, a minor change to the
+macro allows the file to be read backwards.
+This array is read-only; there is no
+<TT>putc</TT>.
+</P>
+<H4>Doing and undoing
+</H4>
+<br>&#32;<br>
+<TT>Sam</TT>
+has an unusual method for managing changes to files.
+The command language makes it easy to specify multiple variable-length changes
+to a file millions of bytes long, and such changes
+must be made efficiently if the editor is to be practical.
+The usual techniques for inserting and deleting strings
+are inadequate under these conditions.
+The
+<TT>Buffer</TT>
+and
+<TT>Disc</TT>
+data structures are designed for efficient random access to long strings,
+but care must be taken to avoid super-linear behavior when making
+many changes simultaneously.
+<P>
+<TT>Sam</TT>
+uses a two-pass algorithm for making changes, and treats each file as a database
+against which transactions are registered.
+Changes are not made directly to the contents.
+Instead, when a command is started, a `mark' containing
+a sequence number is placed in the transcript
+<TT>Buffer</TT>,
+and each change made to the file, either an insertion or deletion
+or a change to the file name,
+is appended to the end of the transcript.
+When the command is complete, the transcript is rewound to the
+mark and applied to the contents.
+</P>
+<P>
+One reason for separating evaluation from
+application in this way is to simplify tracking the addresses of changes
+made in the middle of a long sequence.
+The two-pass algorithm also allows all changes to apply to the
+<I>original</I>
+data: no change can affect another change made in the same command.
+This is particularly important when evaluating an
+<TT>x</TT>
+command because it prevents regular expression matches
+from stumbling over changes made earlier in the execution.
+Also, the two-pass
+algorithm is cleaner than the way other UNIX editors allow changes to
+affect each other;
+for example,
+<TT>ed</TT>'s
+idioms to do things like delete every other line
+depend critically on the implementation.
+Instead,
+<TT>sam</TT>'s
+simple model, in which all changes in a command occur effectively
+simultaneously, is easy to explain and to understand.
+</P>
+<P>
+The records in the transcript are of the form ``delete substring from
+locations
+123 to 456'' and ``insert 11 characters `hello there' at location 789.''
+(It is an error if the changes are not at monotonically greater
+positions through the file.)
+While the update is occurring, these numbers must be
+offset by earlier changes, but that is straightforward and
+local to the update routine;
+moreover, all the numbers have been computed
+before the first is examined.
+</P>
+<P>
+Treating the file as a transaction system has another advantage:
+undo is trivial.
+All it takes is to invert the transcript after it has been
+implemented, converting insertions
+into deletions and vice versa, and saving them in a holding
+<TT>Buffer</TT>.
+The `do' transcript can then be deleted from
+the transcript
+<TT>Buffer</TT>
+and replaced by the `undo' transcript.
+If an undo is requested, the transcript is rewound and the undo transcript
+executed.
+Because the transcript
+<TT>Buffer</TT>
+is not truncated after each command, it accumulates
+successive changes.
+A sequence of undo commands
+can therefore back up the file arbitrarily,
+which is more helpful than the more commonly implemented self-inverse form of undo.
+(<TT>Sam</TT>
+provides no way to undo an undo, but if it were desired,
+it would be easy to provide by re-interpreting the `do' transcript.)
+Each mark in the transcript contains a sequence number and the offset into
+the transcript of the previous mark, to aid in unwinding the transcript.
+Marks also contain the value of dot and the modified bit so these can be
+restored easily.
+Undoing multiple files is easy; it merely demands undoing all files whose
+latest change has the same sequence number as the current file.
+</P>
+<P>
+Another benefit of having a transcript is that errors encountered in the middle
+of a complicated command need not leave the files in an intermediate state.
+By rewinding the transcript to the mark beginning the command,
+the partial command can be trivially undone.
+</P>
+<P>
+When the update algorithm was first implemented, it was unacceptably slow,
+so a cache was added to coalesce nearby changes,
+replacing multiple small changes by a single larger one.
+This reduced the number
+of insertions into the transaction
+<TT>Buffer</TT>,
+and made a dramatic improvement in performance,
+but made it impossible
+to handle changes in non-monotonic order in the file; the caching method
+only works if changes don't overlap.
+Before the cache was added, the transaction could in principle be sorted
+if the changes were out of order, although
+this was never done.
+The current status is therefore acceptable performance with a minor
+restriction on global changes, which is sometimes, but rarely, an annoyance.
+</P>
+<P>
+The update algorithm obviously paws the data more than simpler
+algorithms, but it is not prohibitively expensive;
+the caches help.
+(The principle of avoiding copying the data is still honored here,
+although not as piously:
+the data is moved from contents' cache to
+the transcript's all at once and through only one internal buffer.)
+Performance figures confirm the efficiency.
+To read from a dead start a hundred kilobyte file on a VAX-11/750
+takes 1.4 seconds of user time, 2.5 seconds of system time,
+and 5 seconds of real time.
+Reading the same file in
+<TT>ed</TT>
+takes 6.0 seconds of user time, 1.7 seconds of system time,
+and 8 seconds of real time.
+<TT>Sam</TT>
+uses about half the CPU time.
+A more interesting example is the one stated above:
+inserting a character between every pair of characters in the file.
+The
+<TT>sam</TT>
+command is
+<DL><DT><DD><TT><PRE>
+,y/@/ a/x/
+</PRE></TT></DL>
+and takes 3 CPU seconds per kilobyte of input file, of which
+about a third is spent in the regular expression code.
+This translates to about 500 changes per second.
+<TT>Ed</TT>
+takes 1.5 seconds per kilobyte to make a similar change (ignoring newlines),
+but cannot undo it.
+The same example in
+<TT>ex</TT>,<sup>9</sup>
+a variant of
+<TT>ed</TT>
+done at the University of California at Berkeley,
+which allows one level of undoing, again takes 3 seconds.
+In summary,
+<TT>sam</TT>'s
+performance is comparable to that of other UNIX editors, although it solves
+a harder problem.
+</P>
+<H4>Communications
+</H4>
+<br>&#32;<br>
+The discussion so far has described the implementation of the host part of
+<TT>sam</TT>;
+the next few sections explain how a machine with mouse and bitmap display
+can be engaged to improve interaction.
+<TT>Sam</TT>
+is not the first editor to be written as two processes,<sup>16</sup>
+but its implementation
+has some unusual aspects.
+<P>
+There are several ways
+<TT>sam</TT>'s
+host and terminal parts may be connected.
+The first and simplest is to forgo the terminal part and use the host
+part's command language to edit text on an ordinary terminal.
+This mode is invoked by starting
+<TT>sam</TT>
+with the
+<TT>-d</TT>
+option.
+With no options,
+<TT>sam</TT>
+runs separate host and terminal programs,
+communicating with a message protocol over the physical
+connection that joins them.
+Typically, the connection is an RS-232 link between a Blit
+(the prototypical display for
+<TT>sam</TT>)
+and a host running
+the Ninth Edition of the UNIX operating system.<sup>8</sup>
+(This is the version of the system used in the Computing Sciences Research
+Center at AT&amp;T Bell Laboratories [now Lucent Technologies, Bell Labs], where I work.  Its relevant
+aspects are discussed in the Blit paper.<sup>1</sup>)
+The implementation of
+<TT>sam</TT>
+for the SUN computer runs both processes on the same machine and
+connects them by a pipe.
+</P>
+<P>
+The low bandwidth of an RS-232 link
+necessitated the split between
+the two programs.
+The division is a mixed blessing:
+a program in two parts is much harder to write and to debug
+than a self-contained one,
+but the split makes several unusual configurations possible.
+The terminal may be physically separated from the host, allowing the conveniences
+of a mouse and bitmap display to be taken home while leaving the files at work.
+It is also possible to run the host part on a remote machine:
+<DL><DT><DD><TT><PRE>
+sam -r host
+</PRE></TT></DL>
+connects to the terminal in the usual way, and then makes a call
+across the network to establish the host part of
+<TT>sam</TT>
+on the named machine.
+Finally, it cross-connects the I/O to join the two parts.
+This allows
+<TT>sam</TT>
+to be run on machines that do not support bitmap displays;
+for example,
+<TT>sam</TT>
+is the editor of choice on our Cray X-MP/24.
+<TT>Sam</TT>
+<TT>-r</TT>
+involves
+<I>three</I>
+machines: the remote host, the terminal, and the local host.
+The local host's job is simple but vital: it passes the data
+between the remote host and terminal.
+</P>
+<P>
+The host and terminal exchange messages asynchronously
+(rather than, say, as remote procedure calls) but there is no
+error detection or correction
+because, whatever the configuration, the connection is reliable.
+Because the terminal handles mundane interaction tasks such as
+popping up menus and interpreting the responses, the messages are about
+data, not actions.
+For example, the host knows nothing about what is displayed on the screen,
+and when the user types a character, the message sent to the host says
+``insert a one-byte string at location 123 in file 7,'' not ``a character
+was typed at the current position in the current file.''
+In other words, the messages look very much like the transaction records
+in the transcripts.
+</P>
+<P>
+Either the host or terminal part of
+<TT>sam</TT>
+may initiate a change to a file.
+The command language operates on the host, while typing and some
+mouse operations are executed directly in the terminal to optimize response.
+Changes initiated by the host program must be transmitted to the terminal,
+and
+vice versa.
+(A token is exchanged to determine which end is in control,
+which means that characters typed while a time-consuming command runs
+must be buffered and do not appear until the command is complete.)
+To maintain consistent information,
+the host and terminal track changes through a per-file
+data structure that records what portions of the file
+the terminal has received.
+The data structure, called a
+<TT>Rasp</TT>
+(a weak pun: it's a file with holes)
+is held and updated by both the host and terminal.
+A
+<TT>Rasp</TT>
+is a list of
+<TT>Strings</TT>
+holding those parts of the file known to the terminal,
+separated by counts of the number of bytes in the interstices.
+Of course, the host doesn't keep a separate copy of the data (it only needs
+the lengths of the various pieces),
+but the structure is the same on both ends.
+</P>
+<P>
+The
+<TT>Rasp</TT>
+in the terminal doubles as a cache.
+Since the terminal keeps the text for portions of the file it has displayed,
+it need not request data from the host when revisiting old parts of the file
+or redrawing obscured windows, which speeds things up considerably
+over low-speed links.
+</P>
+<P>
+It's trivial for the terminal to maintain its
+<TT>Rasp</TT>,
+because all changes made on the terminal apply to parts of the file
+already loaded there.
+Changes made by the host are compared against the
+<TT>Rasp</TT>
+during the update sequence after each command.
+Small changes to pieces of the file loaded in the terminal
+are sent in their entirety.
+Larger changes, and changes that fall entirely in the holes,
+are transmitted as messages without literal data:
+only the lengths of the deleted and inserted strings are transmitted.
+When a command is completed, the terminal examines its visible
+windows to see if any holes in their
+<TT>Rasps</TT>
+intersect the visible portion of the file.
+It then requests the missing data from the host,
+along with up to 512 bytes of surrounding data, to minimize
+the number of messages when visiting a new portion of the file.
+This technique provides a kind of two-level lazy evaluation for the terminal.
+The first level sends a minimum of information about
+parts of the file not being edited interactively;
+the second level waits until a change is displayed before
+transmitting the new data.
+Of course,
+performance is also helped by having the terminal respond immediately to typing
+and simple mouse requests.
+Except for small changes to active pieces of the file, which are
+transmitted to the terminal without negotiation,
+the terminal is wholly responsible for deciding what is displayed;
+the host uses the
+<TT>Rasp</TT>
+only to tell the terminal what might be relevant.
+</P>
+<P>
+When a change is initiated by the host,
+the messages to the terminal describing the change
+are generated by the routine that applies the transcript of the changes
+to the contents of the
+<TT>File</TT>.
+Since changes are undone by the same update routine,
+undoing requires
+no extra code in the communications;
+the usual messages describing changes to the file are sufficient
+to back up the screen image.
+</P>
+<P>
+The
+<TT>Rasp</TT>
+is a particularly good example of the way caches are used in
+<TT>sam</TT>.
+First, it facilitates access to the active portion of the text by placing
+the busy text in main memory.
+In so doing, it provides efficient access
+to a large data structure that does not fit in memory.
+Since the form of data is to be imposed by the user, not by the program,
+and because characters will frequently be scanned sequentially,
+files are stored as flat objects.
+Caches help keep performance good and linear when working with such
+data.
+</P>
+<P>
+Second, the
+<TT>Rasp</TT>
+and several of the other caches have some
+<I>read-ahead;</I>
+that is, the cache is loaded with more information than is needed for
+the job immediately at hand.
+When manipulating linear structures, the accesses are usually sequential,
+and read-ahead can significantly reduce the average time to access the
+next element of the object.
+Sequential access is a common mode for people as well as programs;
+consider scrolling through a document while looking for something.
+</P>
+<P>
+Finally, like any good data structure,
+the cache guides the algorithm, or at least the implementation.
+The
+<TT>Rasp</TT>
+was actually invented to control the communications between the host and
+terminal parts, but I realized very early that it was also a form of
+cache.  Other caches were more explicitly intended to serve a double
+purpose: for example, the caches in
+<TT>Files</TT>
+that coalesce updates not only reduce traffic to the
+transcript and contents
+<TT>Buffers</TT>,
+they also clump screen updates so that complicated changes to the
+screen are achieved in
+just a few messages to the terminal.
+This saved me considerable work: I did not need to write special
+code to optimize the message traffic to the
+terminal.
+Caches pay off in surprising ways.
+Also, they tend to be independent, so their performance improvements
+are multiplicative.
+</P>
+<H4>Data structures in the terminal
+</H4>
+<br>&#32;<br>
+The terminal's job is to display and to maintain a consistent image of
+pieces of the files being edited.
+Because the text is always in memory, the data structures are
+considerably simpler than those in the host part.
+<P>
+<TT>Sam</TT>
+typically has far more windows than does
+<TT>mux</TT>,
+the window system within which its Blit implementation runs.
+<TT>Mux</TT>
+has a fairly small number of asynchronously updated windows;
+<TT>sam</TT>
+needs a large number of synchronously updated windows that are
+usually static and often fully obscured.
+The different tradeoffs guided
+<TT>sam</TT>
+away from the memory-intensive implementation of windows, called
+<TT>Layers</TT>,<sup>17</sup>
+used in
+<TT>mux.</TT>
+Rather than depending on a complete bitmap image of the display for each window,
+<TT>sam</TT>
+regenerates the image from its in-memory text
+(stored in the
+<TT>Rasp</TT>)
+when necessary, although it will use such an image if it is available.
+Like
+<TT>Layers</TT>,
+though,
+<TT>sam</TT>
+uses the screen bitmap as active storage in which to update the image using
+<TT>bitblt</TT>.<sup>18,19</sup>
+The resulting organization, pictured in Figure 6,
+has a global array of windows, called
+<TT>Flayers</TT>,
+each of which holds an image of a piece of text held in a data structure
+called a
+<TT>Frame</TT>,
+which in turn represents
+a rectangular window full of text displayed in some
+<TT>Bitmap</TT>.
+Each
+<TT>Flayer</TT>
+appears in a global list that orders them all front-to-back
+on the display, and simultaneously as an element of a per-file array
+that holds all the open windows for that file.
+The complement in the terminal of the
+<TT>File</TT>
+on the host is called a
+<TT>Text</TT>;
+each connects its
+<TT>Flayers</TT>
+to the associated
+<TT>Rasp</TT>.
+<DL><DT><DD><TT><PRE>
+<br><img src="-.11767.gif"><br>
+<br>
+</PRE></TT></DL>
+<I>Figure 6. Data structures in the terminal.
+</I><TT>Flayers</TT><I>
+are also linked together into a front-to-back list.
+</I><TT>Boxes</TT><I>
+are discussed in the next section.
+<br>
+<DL><DT><DD><TT><PRE>
+</I><br>&#32;<br>
+</PRE></TT></DL>
+</P>
+<P>
+The
+<TT>Bitmap</TT>
+for a
+<TT>Frame</TT>
+contains the image of the text.
+For a fully visible window, the
+<TT>Bitmap</TT>
+will be the screen (or at least the
+<TT>Layer</TT>
+in which
+<TT>sam</TT>
+is being run),
+while for partially obscured windows the
+<TT>Bitmap</TT>
+will be off-screen.
+If the window is fully obscured, the
+<TT>Bitmap</TT>
+will be null.
+</P>
+<P>
+The
+<TT>Bitmap</TT>
+is a kind of cache.
+When making changes to the display, most of the original image will
+look the same in the final image, and the update algorithms exploit this.
+The
+<TT>Frame</TT>
+software updates the image in the
+<TT>Bitmap</TT>
+incrementally; the
+<TT>Bitmap</TT>
+is not just an image, it is a data structure.<sup>18,19</sup>
+The job of the software that updates the display is therefore
+to use as much as possible of the existing image (converting the
+text from ASCII characters to pixels is expensive) in a sort of two-dimensional
+string insertion algorithm.
+The details of this process are described in the next section.
+</P>
+<P>
+The
+<TT>Frame</TT>
+software has no code to support overlapping windows;
+its job is to keep a single
+<TT>Bitmap</TT>
+up to date.
+It falls to the
+<TT>Flayer</TT>
+software to multiplex the various
+<TT>Bitmaps</TT>
+onto the screen.
+The problem of maintaining overlapping
+<TT>Flayers</TT>
+is easier than for
+<TT>Layers</TT><sup>17</sup>
+because changes are made synchronously and because the contents of the window
+can be reconstructed from the data stored in the
+<TT>Frame</TT>;
+the
+<TT>Layers</TT>
+software
+makes no such assumptions.
+In
+<TT>sam</TT>,
+the window being changed is almost always fully visible, because the current
+window is always fully visible, by construction.
+However, when multi-file changes are being made, or when
+more than one window is open on a file,
+it may be necessary to update partially obscured windows.
+</P>
+<P>
+There are three cases: the window is 
+fully visible, invisible (fully obscured), or partially visible.
+If fully visible, the
+<TT>Bitmap</TT>
+is part of the screen, so when the
+<TT>Flayer</TT>
+update routine calls the
+<TT>Frame</TT>
+update routine, the screen will be updated directly.
+If the window is invisible,
+there is no associated
+<TT>Bitmap</TT>,
+and all that is necessary is to update the
+<TT>Frame</TT>
+data structure, not the image.
+If the window is partially visible, the
+<TT>Frame</TT>
+routine is called to update the image in the off-screen
+<TT>Bitmap</TT>,
+which may require regenerating it from the text of the window.
+The
+<TT>Flayer</TT>
+code then clips this
+<TT>Bitmap</TT>
+against the
+<TT>Bitmaps</TT>
+of all
+<TT>Frames</TT>
+in front of the
+<TT>Frame</TT>
+being modified, and the remainder is copied to the display.
+</P>
+<P>
+This is much faster than recreating the image off-screen
+for every change, or clipping all the changes made to the image
+during its update.
+Unfortunately, these caches can also consume prohibitive amounts of
+memory, so they are freed fairly liberally &#173; after every change to the
+front-to-back order of the
+<TT>Flayers</TT>.
+The result is that
+the off-screen
+<TT>Bitmaps</TT>
+exist only while multi-window changes are occurring,
+which is the only time the performance improvement they provide is needed.
+Also, the user interface causes fully-obscured windows to be the
+easiest to make &#173;
+creating a canonically sized and placed window requires only a button click
+&#173; which reduces the need for caching still further.
+</P>
+<P>
+</P>
+<H4>Screen update
+</H4>
+<br>&#32;<br>
+Only two low-level primitives are needed for incremental update:
+<TT>bitblt</TT>,
+which copies rectangles of pixels, and
+<TT>string</TT>
+(which in turn calls
+<TT>bitblt</TT>),
+which draws a null-terminated character string in a
+<TT>Bitmap</TT>.
+A
+<TT>Frame</TT>
+contains a list of
+<TT>Boxes</TT>,
+each of which defines a horizontal strip of text in the window
+(see Figure 7).
+A
+<TT>Box</TT>
+has a character string
+<TT>str</TT>,
+and a
+<TT>Rectangle</TT>
+<TT>rect</TT>
+that defines the location of the strip in the window.
+(The text in
+<TT>str</TT>
+is stored in the
+<TT>Box</TT>
+separately from the
+<TT>Rasp</TT>
+associated with the window's file, so
+<TT>Boxes</TT>
+are self-contained.)
+The invariant is that
+the image of the
+<TT>Box</TT>
+can be reproduced by calling
+<TT>string</TT>
+with argument
+<TT>str</TT>
+to draw the string in
+<TT>rect</TT>,
+and the resulting picture fits perfectly within
+<TT>rect</TT>.
+In other words, the
+<TT>Boxes</TT>
+define the tiling of the window.
+The tiling may be complicated by long lines of text, which
+are folded onto the next line.
+Some editors use horizontal scrolling to avoid this complication,
+but to be comfortable this technique requires that lines not be
+<I>too</I>
+long;
+<TT>sam</TT>
+has no such restriction.
+Also, and perhaps more importantly, UNIX programs and terminals traditionally fold
+long lines to make their contents fully visible.
+<P>
+Two special kinds of
+<TT>Boxes</TT>
+contain a single
+character: either a newline or a tab.
+Newlines and tabs are white space.
+A newline
+<TT>Box</TT>
+always extends to the right edge of the window,
+forcing the following
+<TT>Box</TT>
+to the next line.
+The width of a tab depends on where it is located:
+it forces the next
+<TT>Box</TT>
+to begin at a tab location.
+Tabs also
+have a minimum width equivalent to a blank (blanks are
+drawn by
+<TT>string</TT>
+and are not treated specially); newlines have a minimum width of zero.
+<DL><DT><DD><TT><PRE>
+<br><img src="-.11768.gif"><br>
+<br>&#32;<br>
+<br>
+</PRE></TT></DL>
+<I>Figure 7. A line of text showing its
+</I><TT>Boxes</TT><I>.
+The first two blank
+</I><TT>Boxes</TT><I>
+contain tabs; the last contains a newline.
+Spaces are handled as ordinary characters.
+<br>
+<DL><DT><DD><TT><PRE>
+</I><br>&#32;<br>
+</PRE></TT></DL>
+</P>
+<P>
+The update algorithms always use the
+<TT>Bitmap</TT>
+image of the text (either the display or cache
+<TT>Bitmap</TT>);
+they never examine the characters within a
+<TT>Box</TT>
+except when the
+<TT>Box</TT>
+needs to be split in two.
+Before a change, the window consists of a tiling of
+<TT>Boxes</TT>;
+after the change the window is tiled differently.
+The update algorithms rearrange the tiles in place, without
+backup storage.
+The algorithms are not strictly optimal &#173; for example, they can
+clear a pixel that is later going to be written upon &#173;
+but they never move a tile that doesn't need to be moved,
+and they move each tile at most once.
+<TT>Frinsert</TT>
+on a Blit can absorb over a thousand characters a second if the strings
+being inserted are a few tens of characters long.
+</P>
+<P>
+Consider
+<TT>frdelete</TT>.
+Its job is to delete a substring from a
+<TT>Frame</TT>
+and restore the image of the
+<TT>Frame</TT>.
+The image of a substring has a peculiar shape (see Figure 2) comprising
+possibly a partial line,
+zero or more full lines,
+and possibly a final partial line.
+For reference, call this the
+Z-shape.
+<TT>Frdelete</TT>
+begins by splitting, if necessary, the
+<TT>Boxes</TT>
+containing the ends of
+the substring so the substring begins and ends on
+<TT>Box</TT>
+boundaries.
+Because the substring is being deleted, its image is not needed,
+so the Z-shape is then cleared.
+Then, tiles (that is, the images of
+<TT>Boxes</TT>)
+are copied, using
+<TT>bitblt</TT>,
+from immediately after the Z-shape to
+the beginning of the Z-shape,
+resulting in a new Z-shape.
+(<TT>Boxes</TT>
+whose contents would span two lines in the new position must first be split.)
+</P>
+<P>
+Copying the remainder of the
+<TT>Frame</TT>
+tile by tile
+this way will clearly accomplish the deletion but eventually,
+typically when the copying algorithm encounters a tab or newline,
+the old and new
+<TT>x</TT>
+coordinates of the tile
+to be copied are the same.
+This correspondence implies
+that the Z-shape has its beginning and ending edges aligned
+vertically, and a sequence of at most two
+<TT>bitblts</TT>
+can be used to copy the remaining tiles.
+The last step is to clear out the resulting empty space at the bottom
+of the window;
+the number of lines to be cleared is the number of complete lines in the
+Z-shape closed by the final
+<TT>bitblts.</TT>
+The final step is to merge horizontally adjacent
+<TT>Boxes</TT>
+of plain text.
+The complete source to
+<TT>frdelete</TT>
+is less than 100 lines of C.
+</P>
+<P>
+<TT>frinsert</TT>
+is more complicated because it must do four passes:
+one to construct the
+<TT>Box</TT>
+list for the inserted string,
+one to reconnoitre,
+one to copy (in opposite order to
+<TT>frdelete</TT>)
+the
+<TT>Boxes</TT>
+to make the hole for the new text,
+and finally one to copy the new text into place.
+Overall, though,
+<TT>frinsert</TT>
+has a similar flavor to
+<TT>frdelete</TT>,
+and needn't be described further.
+<TT>Frinsert</TT>
+and its subsidiary routines comprise 211 lines of C.
+</P>
+<P>
+The terminal source code is 3024 lines of C,
+and the host source is 5797 lines.
+</P>
+<H4>Discussion
+</H4>
+<H4>History
+</H4>
+<br>&#32;<br>
+The immediate ancestor of
+<TT>sam</TT>
+was the original text editor for the Blit, called
+<TT>jim</TT>.
+<TT>Sam</TT>
+inherited
+<TT>jim</TT>'s
+two-process structure and mouse language almost unchanged, but
+<TT>jim</TT>
+suffered from several drawbacks that were addressed in the design of
+<TT>sam</TT>.
+The most important of these was the lack of a command language.
+Although
+<TT>jim</TT>
+was easy to use for simple editing, it provided no direct help with
+large or repetitive editing tasks.  Instead, it provided a command to pass
+selected text through a shell pipeline,
+but this was no more satisfactory than could be expected of a stopgap measure.
+<P>
+<TT>Jim</TT>
+was written primarily as a vehicle for experimenting with a mouse-based
+interface to text, and the experiment was successful.
+<TT>Jim</TT>
+had some spin-offs:
+<TT>mux</TT>,
+the second window system for the Blit, is essentially a multiplexed
+version of the terminal part of
+<TT>jim</TT>;
+and the debugger
+<TT>pi</TT>'s
+user interface<sup>20</sup> was closely modeled on
+<TT>jim</TT>'s.
+But after a couple of years,
+<TT>jim</TT>
+had become difficult to maintain and limiting to use,
+and its replacement was overdue.
+</P>
+<P>
+I began the design of
+<TT>sam</TT>
+by asking
+<TT>jim</TT>
+customers what they wanted.
+This was probably a mistake; the answers were essentially a list of features
+to be found in other editors, which did not provide any of the
+guiding principles I was seeking.
+For instance, one common request was for a ``global substitute,''
+but no one suggested how to provide it within a cut-and-paste editor.
+I was looking for a scheme that would
+support such specialized features comfortably in the context of some
+general command language.
+Ideas were not forthcoming, though, particularly given my insistence
+on removing all limits on file sizes, line lengths and so on.
+Even worse, I recognized that, since the mouse could easily
+indicate a region of the screen that was not an integral number of lines,
+the command language would best forget about newlines altogether,
+and that meant the command language had to treat the file as a single
+string, not an array of lines.
+</P>
+<P>
+Eventually, I decided that thinking was not getting me very far and it was
+time to try building.
+I knew that the terminal part could be built easily &#173;
+that part of
+<TT>jim</TT>
+behaved acceptably well &#173; and that most of the hard work was going
+to be in the host part: the file interface, command interpreter and so on.
+Moreover, I had some ideas about how the architecture of
+<TT>jim</TT>
+could be improved without destroying its basic structure, which I liked
+in principle but which hadn't worked out as well as I had hoped.
+So I began by designing the file data structure,
+starting with the way
+<TT>jim</TT>
+worked &#173; comparable to a single structure merging
+<TT>Disc</TT>
+and
+<TT>Buffer</TT>,
+which I split to make the cache more general
+&#173; and thinking about how global substitute could be implemented.
+The answer was clearly that it had to be done in two passes,
+and the transcript-oriented implementation fell out naturally.
+</P>
+<P>
+<TT>Sam</TT>
+was written bottom-up,
+starting from the data structures and algorithms for manipulating text,
+through the command language and up to the code for maintaining
+the display.
+In retrospect, it turned out well, but this implementation method is
+not recommended in general.
+There were several times when I had a large body of interesting code
+assembled and no clue how to proceed with it.
+The command language, in particular, took almost a year to figure out,
+but can be implemented (given what was there at the beginning of that year)
+in a day or two.  Similarly, inventing the
+<TT>Rasp</TT>
+data structure delayed the
+connection of the host and terminal pieces by another few months.
+<TT>Sam</TT>
+took about two years to write, although only about four months were
+spent actually working on it.
+</P>
+<P>
+Part of the design process was unusual:
+the subset of the protocol that maintains the
+<TT>Rasp</TT>
+was simulated, debugged
+and verified by an automatic protocol analyzer,<sup>21</sup> and was bug-free
+from the start.
+The rest of the protocol, concerned mostly
+with keeping menus up to date,
+was unfortunately too unwieldy for such analysis,
+and was debugged by more traditional methods, primarily
+by logging in a file all messages in and out of the host.
+</P>
+<H4>Reflections
+</H4>
+<br>&#32;<br>
+<TT>Sam</TT>
+is essentially the only interactive editor used by the sixty or so members of
+the computing science research center in which I work.
+The same could not be said of
+<TT>jim</TT>;
+the lack of a command language kept some people from adopting it.
+The union of a user interface as comfortable as
+<TT>jim</TT>'s
+with a command language as powerful as
+<TT>ed</TT>'s&#191;
+<DL>
+<DT><DT>&#32;<DD>
+NOTE:<I> &#191;The people who criticize
+<TT>ed</TT>
+as an interactive program often forget that it and its close relative
+<TT>sed</TT><sup>7</sup>
+still thrive as programmable editors.  The strength of these programs is
+independent of their convenience for interactive editing.
+<br>
+</I><DT>&#32;<DD></dl>
+<br>
+is essential to
+<TT>sam</TT>'s
+success.
+When
+<TT>sam</TT>
+was first made available to the
+<TT>jim</TT>
+community,
+almost everyone switched to it within two or three days.
+In the months that followed, even people who had never adopted
+<TT>jim</TT>
+started using
+<TT>sam</TT>
+exclusively.
+<P>
+To be honest,
+<TT>ed</TT>
+still gets occasional use, but usually when
+something quick needs to be done and the overhead of
+downloading the terminal part of
+<TT>sam</TT>
+isn't worth the trouble.
+Also, as a `line' editor,
+<TT>sam</TT>
+<TT>-d</TT>
+is a bit odd;
+when using a good old ASCII terminal, it's comforting to have
+a true line editor.
+But it is fair to say that
+<TT>sam</TT>'s
+command language has displaced
+<TT>ed</TT>'s
+for most of the complicated editing that has kept line editors
+(that is, command-driven editors) with us.
+</P>
+<P>
+<TT>Sam</TT>'s
+command language is even fancier than
+<TT>ed</TT>'s,
+and most
+<TT>sam</TT>
+customers don't come near to using all its capabilities.
+Does it need to be so sophisticated?
+I think the answer is yes, for two reasons.
+</P>
+<P>
+First, the
+<I>model</I>
+for
+<TT>sam</TT>'s
+command language is really relatively simple, and certainly simpler than that of
+<TT>ed</TT>.
+For instance, there is only one kind of textual loop in
+<TT>sam</TT>
+&#173; the
+<TT>x</TT>
+command &#173;
+while
+<TT>ed</TT>
+has three (the
+<TT>g</TT>
+command, the global flag on substitutions, and the implicit loop over
+lines in multi-line substitutions).
+Also,
+<TT>ed</TT>'s
+substitute command is necessary to make changes within lines, but in
+<TT>sam</TT>
+the
+<TT>s</TT>
+command is more of a familiar convenience than a necessity;
+<TT>c</TT>
+and
+<TT>t</TT>
+can do all the work.
+</P>
+<P>
+Second,
+given a community that expects an editor to be about as powerful as
+<TT>ed</TT>,
+it's hard to see how
+<TT>sam</TT>
+could really be much simpler and still satisfy that expectation.
+People want to do ``global substitutes,'' and most are content
+to have the recipe for that and a few other fancy changes.
+The sophistication of the command language is really just a veneer
+over a design that makes it possible to do global substitutes
+in a screen editor.
+Some people will always want something more, however, and it's gratifying to
+be able to provide it.
+The real power of
+<TT>sam</TT>'s
+command language comes from composability of the operators, which is by
+nature orthogonal to the underlying model.
+In other words,
+<TT>sam</TT>
+is not itself complex, but it makes complex things possible.
+If you don't want to do anything complex, you can ignore the
+complexity altogether, and many people do so.
+</P>
+<P>
+Sometimes I am asked the opposite question: why didn't I just make
+<TT>sam</TT>
+a real programmable editor, with macros and variables and so on?
+The main reason is a matter of taste: I like the editor
+to be the same every time I use it.
+There is one technical reason, though:
+programmability in editors is largely a workaround for insufficient
+interactivity.
+Programmable editors are used to make particular, usually short-term,
+things easy to do, such as by providing shorthands for common actions.
+If things are generally easy to do in the first place,
+shorthands are not as helpful.
+<TT>Sam</TT>
+makes common editing operations very easy, and the solutions to
+complex editing problems seem commensurate with the problems themselves.
+Also, the ability to edit the
+<TT>sam</TT>
+window makes it easy to repeat commands &#173; it only takes a mouse button click
+to execute a command again.
+</P>
+<H4>Pros and cons
+</H4>
+<br>&#32;<br>
+<TT>Sam</TT>
+has several other good points,
+and its share of problems.
+Among the good things is the idea of
+structural regular expressions,
+whose usefulness has only begun to be explored.
+They were arrived at serendipitously when I attempted to distill the essence of
+<TT>ed</TT>'s
+way of doing global substitution and recognized that the looping command in
+<TT>ed</TT>
+was implicitly imposing a structure (an array of lines) on the file.
+<P>
+Another of
+<TT>sam</TT>'s
+good things is its undo capability.
+I had never before used an editor with a true undo,
+but I would never go back now.
+Undo
+<I>must</I>
+be done well, but if it is, it can be relied on.
+For example,
+it's safe to experiment if you're not sure how to write some intricate command,
+because if you make a mistake, it can be fixed simply and reliably.
+I learned two things about undo from writing
+<TT>sam</TT>:
+first, it's easy to provide if you design it in from the beginning, and
+second, it's necessary, particularly if the system has some subtle
+properties that may be unfamiliar or error-prone for users.
+</P>
+<P>
+<TT>Sam</TT>'s
+lack of internal limits and sizes is a virtue.
+Because it avoids all fixed-size tables and data structures,
+<TT>sam</TT>
+is able to make global changes to files that some of our other
+tools cannot even read.
+Moreover, the design keeps the performance linear when doing such
+operations, although I must admit
+<TT>sam</TT>
+does get slow when editing a huge file.
+</P>
+<P>
+Now, the problems.
+Externally, the most obvious is that it is poorly integrated into the
+surrounding window system.
+By design, the user interface in
+<TT>sam</TT>
+feels almost identical to that of
+<TT>mux</TT>,
+but a thick wall separates text in
+<TT>sam</TT>
+from the programs running in
+<TT>mux</TT>.
+For instance, the `snarf buffer' in
+<TT>sam</TT>
+must be maintained separately from that in
+<TT>mux</TT>.
+This is regrettable, but probably necessary given the unusual configuration
+of the system, with a programmable terminal on the far end of an RS-232 link.
+</P>
+<P>
+<TT>Sam</TT>
+is reliable; otherwise, people wouldn't use it.
+But it was written over such a long time, and has so many new (to me)
+ideas in it, that I would like to see it done over again to clean
+up the code and remove many of the lingering problems in the implementation.
+The worst part is in the interconnection of the host and terminal parts,
+which might even be able to go away in a redesign for a more
+conventional window system.
+The program must be split in two to use the terminal effectively,
+but the low bandwidth of the connection forces the separation to
+occur in an inconvenient part of the design if performance is to be acceptable.
+A simple remote procedure call
+protocol driven by the host, emitting only graphics
+commands, would be easy to write but wouldn't have nearly the
+necessary responsiveness.  On the other hand, if the terminal were in control
+and requested much simpler file services from the host, regular expression
+searches would require that the terminal read the entire file over its RS-232
+link, which would be unreasonably slow.
+A compromise in which either end can take control is necessary.
+In retrospect, the communications protocol should have been
+designed and verified formally, although I do not know of any tool
+that can adequately relate the protocol to
+its implementation.
+</P>
+<P>
+Not all of
+<TT>sam</TT>'s
+users are comfortable with its command language, and few are adept.
+Some (venerable) people use a sort of
+<TT>ed</TT>
+``
+subset'' of
+<TT>sam</TT>'s
+command language,
+and even ask why
+<TT>sam</TT>'s
+command language is not exactly
+<TT>ed</TT>'s.
+(The reason, of course, is that
+<TT>sam</TT>'s
+model for text does not include newlines, which are central to
+<TT>ed</TT>.
+Making the text an array of newlines to the command language would
+be too much of a break from the seamless model provided by the mouse.
+Some editors, such as
+<TT>vi</TT>,
+are willing to make this break, though.)
+The difficulty is that
+<TT>sam</TT>'s
+syntax is so close to
+<TT>ed</TT>'s
+that people believe it
+<I>should</I>
+be the same.
+I thought, with some justification in hindsight,
+that making
+<TT>sam</TT>
+similar to
+<TT>ed</TT>
+would make it easier to learn and to accept.
+But I may have overstepped and raised the users'
+expectations too much.
+It's hard to decide which way to resolve this problem.
+</P>
+<P>
+Finally, there is a tradeoff in
+<TT>sam</TT>
+that was decided by the environment in which it runs:
+<TT>sam</TT>
+is a multi-file editor, although in a different system there might instead be
+multiple single-file editors.
+The decision was made primarily because starting a new program in a Blit is
+time-consuming.
+If the choice could be made freely, however, I would
+still choose the multi-file architecture, because it allows
+groups of files to be handled as a unit;
+the usefulness of the multi-file commands is incontrovertible.
+It is delightful to have the source to an entire program
+available at your fingertips.
+</P>
+<H4>Acknowledgements
+</H4>
+<br>&#32;<br>
+Tom Cargill suggested the idea behind the
+<TT>Rasp</TT>
+data structure.
+Norman Wilson and Ken Thompson influenced the command language.
+This paper was improved by comments from
+Al Aho,
+Jon Bentley,
+Chris Fraser,
+Gerard Holzmann,
+Brian Kernighan,
+Ted Kowalski,
+Doug McIlroy
+and
+Dennis Ritchie.
+<H4>REFERENCES
+</H4>
+<P>
+</P>
+<DL COMPACT>
+<DT> 1.<DD>
+R. Pike,
+`The Blit: a multiplexed graphics terminal,'
+AT&amp;T Bell Labs. Tech. J.,
+<B>63</B>,
+(8),
+1607-1631 (1984).
+<DT> 2.<DD>
+L. Johnson,
+<I>MacWrite,</I>
+Apple Computer Inc., Cupertino, Calif. 1983.
+<DT> 3.<DD>
+B. Lampson,
+`Bravo Manual,'
+in
+Alto User's Handbook,
+pp. 31-62,
+Xerox Palo Alto Research Center,
+Palo Alto, Calif.
+1979.
+<DT> 4.<DD>
+W. Teitelman,
+`A tour through Cedar,'
+IEEE Software,
+<B>1</B>
+(2), 44-73 (1984).
+<DT> 5.<DD>
+J. Gutknecht,
+`Concepts of the text editor Lara,'
+Comm. ACM,
+<B>28</B>,
+(9),
+942-960 (1985).
+<DT> 6.<DD>
+Bell Telephone Laboratories,
+UNIX Programmer's Manual,
+Holt, Rinehart and Winston, New York 1983.
+<DT> 7.<DD>
+B. W. Kernighan and R. Pike,
+The Unix Programming Environment,
+Prentice-Hall, Englewood Cliffs, New Jersey 1984.
+<DT> 8.<DD>
+Unix Time-Sharing System Programmer's Manual, Research Version, Ninth Edition,
+Volume 1,
+AT&amp;T Bell Laboratories, Murray Hill, New Jersey 1986.
+<DT> 9.<DD>
+Unix Time-Sharing System Programmer's Manual, 4.1 Berkeley Software Distribution,
+Volumes 1 and 2C,
+University of California, Berkeley, Calif. 1981.
+<DT>10.<DD>
+R. Pike,
+`Structural Regular Expressions,'
+Proc. EUUG Spring Conf., Helsinki 1987,
+Eur. Unix User's Group, Buntingford, Herts, UK 1987.
+<DT>11.<DD>
+A. Goldberg,
+Smalltalk-80 &#191; The Interactive Programming Environment,
+Addison-Wesley, Reading, Mass. 1984.
+<DT>12.<DD>
+K. Thompson,
+`Regular expression search algorithm,'
+Comm. ACM,
+<B>11</B>,
+(6),
+419-422 (1968).
+<DT>13.<DD>
+A. V. Aho, J. E. Hopcroft and J. D. Ullman,
+The Design and Analysis of Computer Algorithms,
+Addison-Wesley, Reading, Mass. 1974.
+<DT>14.<DD>
+B. W. Kernighan and D. M. Ritchie,
+The C Programming Language,
+Prentice-Hall, Englewood Cliffs, New Jersey 1978.
+<DT>15.<DD>
+W. M. Waite,
+`The cost of lexical analysis,'
+Softw. Pract. Exp.,
+<B>16</B>,
+(5),
+473-488 (1986).
+<DT>16.<DD>
+C. W. Fraser,
+`A generalized text editor,'
+Comm. ACM,
+<B>23</B>,
+(3),
+154-158 (1980).
+<DT>17.<DD>
+R. Pike,
+`Graphics in overlapping bitmap layers,'
+ACM Trans. on Graph.,
+<B>2</B>,
+(2)
+135-160 (1983).
+<DT>18.<DD>
+L. J. Guibas and J. Stolfi,
+`A language for bitmap manipulation,'
+ACM Trans. on Graph.,
+<B>1</B>,
+(3),
+191-214 (1982).
+<DT>19.<DD>
+R. Pike, B. Locanthi and J. Reiser,
+`Hardware/software trade-offs for bitmap graphics on the Blit,'
+Softw. Pract. Exp.,
+<B>15</B>,
+(2),
+131-151 (1985).
+<DT>20.<DD>
+T. A. Cargill,
+`The feel of Pi,'
+Winter USENIX Conference Proceedings,
+Denver 1986,
+62-71,
+USENIX Assoc., El Cerrito, CA.
+<DT>21.<DD>
+G. J. Holzmann,
+`Tracing protocols,'
+AT&amp;T Tech. J.,
+<B>64</B>,
+(10),
+2413-2434 (1985).
+
+</dl>
+<br>&#32;<br>
+<A href=http://www.lucent.com/copyright.html>
+Copyright</A> &#169; 2000 Lucent Technologies Inc.  All rights reserved.
+</body></html>

BIN
sys/doc/sam/sam.pdf


+ 8 - 0
sys/doc/venti/mkfile

@@ -0,0 +1,8 @@
+</sys/doc/fonts
+
+venti.ps:V:
+	echo up to date
+
+venti.html:V:
+	echo up to date
+

+ 4 - 0
sys/doc/venti/venti.pdf

@@ -3824,3 +3824,7 @@ The path to enlightenment requires no software.
 Notegroups! They kill you!
 Question: Did you ever have an important idea that you wanted to jot down, but... your portable, fold-up keyboard is all folded up in your pocket, and there isn't any flat place around to set it up on anyway?
 Let's take Stallman's opinions and agree with them, even though we're not sure what he's talking about.   -- someone on slashdot
+They call themselves flower children but all I see is a lot of weed.
+One in three criminals have cats.
+"I instructed people on the team to follow the document retention policy, which I knew would result in the destruction of documents." -David B. Duncan
+REMINDER! You're About to Get SMART!

+ 1 - 0
sys/include/fcall.h

@@ -122,6 +122,7 @@ enum
 
 uint	convM2S(uchar*, uint, Fcall*);
 uint	convS2M(Fcall*, uchar*, uint);
+uint	sizeS2M(Fcall*);
 
 int	statcheck(uchar *abuf, uint nbuf);
 uint	convM2D(uchar*, uint, Dir*, char*);

+ 2 - 1
sys/include/libc.h

@@ -351,7 +351,6 @@ extern	int	gettokens(char *, char **, int, char *);
 extern	char*	getuser(void);
 extern	char*	getwd(char*, int);
 extern	int	iounit(int);
-extern	int	kiounit(void);
 extern	long	labs(long);
 extern	double	ldexp(double, int);
 extern	void	longjmp(jmp_buf, int);
@@ -426,8 +425,10 @@ struct RWLock
 
 extern	void	rlock(RWLock*);
 extern	void	runlock(RWLock*);
+extern	int		canrlock(RWLock*);
 extern	void	wlock(RWLock*);
 extern	void	wunlock(RWLock*);
+extern	int		canwlock(RWLock*);
 
 extern	void**	privalloc(void);
 extern	void	privfree(void**);

+ 169 - 0
sys/lib/acid/network

@@ -0,0 +1,169 @@
+_ni=0;	// network indent level
+
+defn
+_ni() {
+	loop 1,_ni do {
+		print("\t");
+	}
+}
+
+defn
+ipdev(n) {
+	_ipfs(*(ipfs+4*n));
+}
+
+// the funny _foo/foo pairs exist so that if we get
+// interrupted in the middle of one of these, _ni will 
+// get reset to 0 next time an external call happens.
+
+defn
+_ipfs(fs) {
+	complex Fs fs;
+	local i;
+
+	print("ipfs(", fs\X, ")  #I", fs.dev\D, "\n");
+	i=0;
+	_ni = _ni+1;
+	while i < fs.np do {
+		_proto(*(fs.p+i*4));
+		i = i + 1;
+	}
+	_ni = _ni-1;
+}
+
+defn
+ipfs(fs) {
+	_ni = 0;
+	_ipfs(fs);
+}
+
+defn
+_proto(p) {
+	local c;
+	complex Proto p;
+	_ni();
+	print("proto(", p\X, ") ", *(p.name\s), "\n");
+	_ni = _ni+1;
+	local i;
+	i = 0;
+	while i < p.nc do {
+		c = *(p.conv+i*4);
+		complex Conv c;
+		if c != 0 && c.inuse then 
+			_conv(*(p.conv+i*4));
+		i = i + 1;
+	}
+	_ni = _ni - 1;
+}
+
+defn
+proto(p) {
+	_ni = 0;
+	_proto(p);
+}
+
+defn
+_conv(c) {
+	complex Conv c;
+	_ni();
+	local p;
+	p = c.p;
+	complex Proto p;
+	print("conv(", c\X, ") ", *(p.name\s), "/", c.x\D, " ", 
+		iptostr(*(c.laddr+12)), "!", c.lport\D, " ", iptostr(*(c.raddr+12)), 
+		"!", c.rport\D, " rq ", qtostr(c.rq), " wq ", qtostr(c.wq), 
+		" eq ", qtostr(c.eq), "\n");
+}
+
+defn
+conv(c) {
+	_ni = 0;
+	_conv(c);
+}
+
+defn
+iptostr(a)
+{
+	// BUG: little endian
+	return itoa(a&0xFF)+"."+itoa((a>>8)&0xFF)+"."+itoa((a>>16)&0xFF)+"."+itoa((a>>24)&0xFF);
+}
+
+defn
+qtostr(q)
+{
+	complex Queue q;
+
+	return "queue("+itoa(q, "%lux")+") ["+itoa(q.len, "%d")+","+itoa(q.dlen, "%d")+","+itoa(qblocks(q), "%d")+"]";
+}
+
+defn
+qblocks(q)
+{
+	complex Queue q;
+	local b, n;
+
+	b = q.bfirst;
+	n = 0;
+	while b != 0 do { 
+		n = n + 1;
+		complex Block b;
+		b = b.next;
+	}
+	return n;
+}
+
+defn
+_queue(q)
+{
+	complex Queue q;
+	local b;
+
+	print("queue(", q\X, ") len ", q.len\D, " dlen ", q.dlen\D, " limit ", q.limit\D, " nblocks ", qblocks(q)\D);
+	if q.state & Qstarve then 
+		print(" starve");
+	if q.state & Qmsg then
+		print(" msg");
+	if q.state & Qclosed then
+		print(" closed");
+	if q.state & Qflow then
+		print(" flow");
+	if q.state & Qcoalesce then
+		print(" coalesce");
+	print("\n");
+
+	b = q.bfirst;
+	_ni = _ni+1;
+	while b != 0 do {
+		_block(b);
+		complex Block b;
+		b = b.next;
+	}
+	_ni = _ni - 1;
+}
+
+defn
+queue(q)
+{
+	_ni = 0;
+	_queue(q);
+}
+
+defn
+_block(b)
+{
+	complex Block b;
+
+	_ni();
+	print("block(", b\X, ") base ", b.base\X, " rp ", b.rp\X, "/", b.rp-b.base\D, " wp ", b.wp\X, "/", b.wp-b.base\D, " lim ", b.lim\X, "/", b.lim-b.base\D, "\n");
+}
+
+defn
+block(b)
+{
+	_ni = 0;
+	block(b);
+}
+
+print("/sys/lib/acid/network");
+needacid("tcp");
+needacid("qio");

+ 26 - 9
sys/lib/dist/mkfile

@@ -1,18 +1,23 @@
-d=/n/emelieother/plan9
-x=`{mount /srv/emelie /n/emelieother other}
+d=/n/sources/plan9
+x=`{9fs sources; 9fs emelieother}
 
 cd:V: /n/emelieother/rsc/plan9.iso
 
 /n/emelieother/rsc/plan9.iso:DV:
+	t=/tmp/pdf.$pid
+	mkdir $t
+	mv $d/sys/doc/*.pdf $t
 	@{cd pc; mk cddisk; cd ..}
 	rm -f $target
 	bind pc/cddisk cdstub/bootdisk.img
 	bind -a cdstub $d
-	disk/mk9660 -9cj -v 'Plan 9 from Bell Labs 4th Edition' -s $d \
+	disk/mk9660 -9cj -v 'Plan 9 4th Edition' -s $d \
 		-b bootdisk.img $target
+	mv $t/*.pdf $d/sys/doc
+	rm $t
 
 scan:V:
-	replica/scan /sys/lib/dist/emelieother.replica
+	replica/scan /sys/lib/dist/sources.replica <scan.lock
 
 compresslog:V:
 	awk -f logcompress.awk $d/dist/replica/plan9.log | awk -f logtime.awk -v 't='^`{date -n} >/tmp/plan9.log
@@ -32,7 +37,7 @@ odump:V:
 		-p /sys/lib/sysconfig/proto/allproto /n/emelieother/rsc/distdump.iso
 
 cd.install:V:
-	if(~ $sysname achille){ echo 'run this on a real machine, like olive.'; exit bad }
+	if(~ $sysname achille){ echo; echo; echo '*** run this on a real machine, like olive.'; exit bad }
 	bzip2 -9 < /n/emelieother/rsc/plan9.iso >web.protect/nplan9.iso.bz2
 
 D.install:V:
@@ -43,8 +48,9 @@ D.install:V:
 
 
 reallyinstall:V:
+	if(! ~ $sysname achille){ echo; echo; echo '*** this needs to run on achille.'; exit bad }
 	cd web.protect
-	for (i in plan9.iso.bz2 disk 9loaddebug){
+	for (i in plan9.iso.bz2 disk 9loaddebug vmware.tar.bz2){
 		if(test -f n$i){
 			mv $i _$i && { mv n$i $i || mv _$i $i }
 		}
@@ -54,9 +60,20 @@ reallyinstall:V:
 
 dump:V:
 	rm -f /srv/9660.xxx
-	9660srv xxx
+	9660srv 9660.xxx
 	mount /srv/9660.xxx /n/kremvax /n/emelieother/rsc/plan9.iso
-	now=`{/usr/rsc/bin/$cputype/mtime /n/emelieother/rsc/plan9.iso | awk '{print $2}'}
+	now=`{/usr/rsc/bin/$cputype/mtime /sys/lib/dist/web.protect/plan9.iso.bz2 | awk '{print $2}'}
 	ls -l /rls/plan9/4e.iso
-	disk/dump9660 -s /n/kremvax -n $now /rls/plan9/4e.iso
+	disk/dump9660 -9cj -s /n/kremvax -n $now /rls/plan9/4e.iso
 	ls -l /rls/plan9/4e.iso
+	rm /srv/9660.xxx
+
+reencode:V:
+	rm -f /n/emelieother/rsc/nplan9.iso
+	rm -f /srv/9660.xxx
+	9660srv 9660.xxx
+	mount /srv/9660.xxx /n/kremvax /n/emelieother/rsc/plan9.iso
+	disk/mk9660 -9cj -v 'Plan 9 4th Edition' -s /n/kremvax \
+		-b bootdisk.img /n/emelieother/rsc/nplan9.iso
+	rm /srv/9660.xxx
+

+ 1 - 1
sys/lib/dist/pc/inst/bootwin9x

@@ -23,7 +23,7 @@ if(! test -d /n/c:/plan9 && ! mkdir /n/c:/plan9) {
 	exit bad
 }
 
-if(! cp /386/^(9load ld.com) /tmp/plan9ini.bak /n/kfs/386/9pcdisk /n/c:/plan9) {
+if(! cp /n/kfs/386/^(9load ld.com 9pcdisk) /tmp/plan9ini.bak /n/c:/plan9) {
 	echo 'Could not copy Plan 9 boot files into /n/c:/plan9.'
 	exit bad
 }

+ 1 - 1
sys/lib/dist/pc/proto

@@ -130,7 +130,7 @@ rc	d555 sys sys
 		kill	555 sys sys
 		lc	555 sys sys
 		mkdir	555 sys sys /sys/lib/dist/pc/sub/mkdir
-		pci	555 sys sys /sys/lib/dist/pc/sub/pci
+		pci	555 sys sys
 		pwd	555 sys sys /sys/lib/dist/pc/sub/pwd
 		ramfs	555 sys sys /sys/lib/dist/pc/sub/ramfs
 		replica	d555 sys sys

+ 1 - 1
sys/lib/dist/pc/sub/boota:

@@ -7,7 +7,7 @@ unmount /n/a:>[2]/dev/null
 
 switch($bootfile) {
 case sd*
-	adisk=`{echo $bootfile | sed 's#(sd..).*#/dev/\1/data#'}
+	adisk=`{echo $bootfile | sed 's#(sd..).*#/dev/\1/dos#'}
 case fd*
 	adisk=`{echo $bootfile | sed 's#(fd.).*#/dev/\1disk#'}
 case *

+ 1 - 0
sys/lib/dist/pc/sub/termrc

@@ -32,6 +32,7 @@ bind -a '#l' /net >/dev/null >[2=1]
 
 dossrv
 boota:
+boota:	# again, just in case a timeout made the earlier one fail
 cp /n/a:/plan9.ini /tmp/plan9.orig
 
 # restore a partial install

+ 1 - 1
sys/lib/plumb/basic

@@ -23,7 +23,7 @@ plumb start wdoc2txt $file
 
 # email addresses get a new mail window
 type is text
-data matches '[a-zA-Z0-9_.\-]+@[a-zA-Z0-9_.\-]*'
+data matches '[a-zA-Z0-9_+.\-]+@[a-zA-Z0-9_+.\-]*'
 plumb to sendmail
 plumb start window rc -c '''echo % mail '''$0'; mail '$0
 

+ 4 - 1
sys/lib/tmac/tmac.s

@@ -1128,7 +1128,7 @@ Piscataway, New Jersey 08854
 .if n .ul 1000
 ..
 .	\"NH - numbered heading
-.de NH
+.de N{
 .RT
 .ie \\n(1T .sp 1
 .el .BG
@@ -1151,6 +1151,9 @@ Piscataway, New Jersey 08854
 .if \\n(NS-2 .as SN \\n(H3.
 .if \\n(NS-3 .as SN \\n(H4.
 .if \\n(NS-4 .as SN \\n(H5.
+..
+.de NH
+.N{ \\$1
 \\*(SN
 ..
 .	\"BG - begin, execute at first PP

+ 0 - 1
sys/log/dns

@@ -1 +0,0 @@
-sum-06 Dec 31 19:00:14 starting dns on 135.104.9.43

+ 5 - 1
sys/man/1/cat

@@ -72,7 +72,11 @@ It never reads any more data from the input than it prints to the output.
 .I Read
 exits with status
 .B eof
-on end of file.
+on end of file or, in the
+.B -n
+case, if it doesn't read
+.I nlines
+lines.
 .SH BUGS
 Beware of
 .L "cat a b >a"

+ 17 - 2
sys/man/1/con

@@ -4,7 +4,7 @@ con, telnet, rx, xms, xmr \- remote login, execution, and XMODEM file transfer
 .SH SYNOPSIS
 .B con
 [
-.B -CdnrRvs
+.B -CdnrRvsT
 ]
 [
 .B -b
@@ -45,6 +45,9 @@ con, telnet, rx, xms, xmr \- remote login, execution, and XMODEM file transfer
 ]
 .PP
 .B xms
+[
+.B -1p
+]
 .I file
 .PP
 .B xmr
@@ -100,7 +103,10 @@ Plan 9.
 .TP
 .B -R
 translates newlines to carriage returns and
-.IR vice versa .
+.IR "vice versa" .
+.TP
+.B -T
+translates incoming carriage returns to newlines.
 .TP
 .B -s
 strips received characters to 7 bits to forestall
@@ -193,6 +199,15 @@ XMODEM protocol.
 They use standard input and standard output for communication
 and are intended for use with
 .IR con .
+The
+.B -1
+option to
+.I xms
+causes it to use kilobyte packet size of 1024 bytes.
+The
+.B -p
+option causes it to print a progress
+message every ten kilobytes.
 .SH EXAMPLES
 .TP
 .L

+ 1 - 5
sys/man/1/replica

@@ -248,7 +248,7 @@ These paths are relative to the root of the replicated file system.
 .PP
 As an example, the Plan 9 distribution replica configuration looks like:
 .EX
-    fn servermount { 9fs outside; bind /n/outside/plan9 /n/dist }
+    fn servermount { 9fs sources; bind /n/sources/plan9 /n/dist }
     fn serverupdate { status='' }
     serverroot=/n/dist
     s=/n/dist/dist/replica
@@ -285,10 +285,6 @@ to the internet and run
     replica/pull /dist/replica/network
     disk/kfscmd disallow
 .EE
-(We have not yet set up the outside file server at Bell Labs
-to make this work; once we do, we will announce instructions
-on the Plan 9 web page and in the Usenet group
-.BR comp.os.plan9 ).
 .PP
 To see a list of changes made to the local file system
 since installation, run

+ 1 - 1
sys/man/1/secstore

@@ -77,7 +77,7 @@ at startup, open a new window and
   % ramfs -p; cd /tmp
   % auth/secstore -g factotum
   secstore password:
-  % echo 'proto=apop dom=x.com user=ehg !password=y~1' >> factotum
+  % echo 'key proto=apop dom=x.com user=ehg !password=y~1' >> factotum
   % auth/secstore -p factotum
   secstore password:
   % read -m factotum > /mnt/factotum/ctl

+ 4 - 1
sys/man/1/ssh

@@ -4,7 +4,7 @@ ssh, sshnet, scp, sshserve, ssh_genkey \- secure login and file copy from/to Uni
 .SH SYNOPSIS
 .B ssh
 [
-.B -CiImPprvw
+.B -CiImPpRrvw
 ]
 [
 .B -A
@@ -116,6 +116,9 @@ force no pseudoterminal request.
 .B -r
 strip carriage returns.
 .TP
+.B -R
+put the allocated pseudoterminal, if any, in raw mode.
+.TP
 .B -v
 enable verbose feedback during the connection and authentication process. 
 .TP

+ 8 - 0
sys/man/1/vac

@@ -18,6 +18,9 @@ vac \- create a vac archive on Venti
 .B -f
 .I vacfile
 ] [
+.B -i
+.I name
+] [
 .B -h
 .I host
 ]
@@ -81,6 +84,11 @@ are place in
 .IR vacfile ,
 or the standard output if no file is given.
 .TP
+.BI -i " name
+Include standard input as one of the input files, storing it in the archive
+with the specified
+.IR name .
+.TP
 .BI -h " host
 The network address of the Venti server.
 The default is taken from the environment variable

+ 3 - 3
sys/man/2/control

@@ -1729,8 +1729,8 @@ resizecontrolset(Controlset*)
 	r1.max.y = r1.min.y+1+font->height+1;
 	r2.min.y = r1.max.y+10;
 	r2.max.y = r2.min.y+1+font->height+1;
-	chanprint(cs->ctl, "top rect %R\enshow", r1);
-	chanprint(cs->ctl, "bot rect %R\enshow", r2);
+	chanprint(cs->ctl, "top rect %R\entop show", r1);
+	chanprint(cs->ctl, "bot rect %R\enbot show", r2);
 }
 
 void
@@ -1738,7 +1738,7 @@ threadmain(int argc, char *argv[])
 {
 	char *s, *args[3];
 	Channel *c;
-	Contro *top, *bot;
+	Control *top, *bot;
 	int n;
 
 	initdraw(0, 0, "example");

+ 26 - 14
sys/man/2/fcall

@@ -1,6 +1,6 @@
 .TH FCALL 2
 .SH NAME
-Fcall, convS2M, convD2M, convM2S, convM2D, fcallfmt, dirfmt, dirmodefmt, read9pmsg, statcheck, sizeD2M \- interface to Plan 9 File protocol
+Fcall, convS2M, convD2M, convM2S, convM2D, fcallfmt, dirfmt, dirmodefmt, read9pmsg, statcheck, sizeS2M, sizeD2M \- interface to Plan 9 File protocol
 .SH SYNOPSIS
 .B #include <u.h>
 .br
@@ -31,10 +31,13 @@ int fcallfmt(Fmt*)
 int dirmodefmt(Fmt*)
 .PP
 .B
-int read9pmsg(int fd, uchar *buf, uint nbuf);
+int read9pmsg(int fd, uchar *buf, uint nbuf)
 .PP
 .B
-int statcheck(uchar *buf, uint nbuf);
+int statcheck(uchar *buf, uint nbuf)
+.PP
+.B
+uint sizeS2M(Fcall *f)
 .PP
 .B
 uint sizeD2M(Dir *d)
@@ -214,6 +217,17 @@ will be no more than the buffer size negotiated in the
 exchange, minus
 .BR IOHDRSZ .
 .PP
+The routine
+.I sizeS2M
+returns the number of bytes required to store the machine-independent representation of the
+.B Fcall
+structure
+.IR f ,
+including its initial 32-bit size field.
+In other words, it reports the number of bytes produced
+by a successful call to
+.IR convS2M .
+.PP
 Another structure is
 .BR Dir ,
 used by the routines described in
@@ -265,6 +279,15 @@ With the exception of handling short buffers in
 .IR convD2M ,
 these macros are not usually needed except by internal routines.
 .PP
+Analogous to
+.IR sizeS2M ,
+.I sizeD2M
+returns the number of bytes required to store the machine-independent representation of the
+.B Dir
+structure
+.IR d ,
+including its initial 16-bit size field.
+.PP
 The routine
 .B statcheck
 checks whether the
@@ -299,17 +322,6 @@ for a valid entry and
 .B -1
 for an incorrectly formatted entry.
 .PP
-The routine
-.I sizeD2M
-returns the number of bytes required to store the machine-independent representation of the
-.B Dir
-structure
-.IR d ,
-including its initial 16-bit size field.
-In other words, it reports the number of bytes produced
-by a successful call to
-.IR convD2M .
-.PP
 .IR Dirfmt ,
 .IR fcallfmt ,
 and

+ 1 - 1
sys/man/2/graphics

@@ -586,7 +586,7 @@ if(fd < 0)
 	sysfatal("can't open $wsys: %r");
 
 /* mount creates window; see \f2rio\fP(4) */
-if(mount(fd, "/tmp", MREPL, "new -dx 300-dy 200") < 0)
+if(mount(fd, -1, "/tmp", MREPL, "new -dx 300-dy 200") < 0)
 	sysfatal("can't mount new window: %r");
 if(gengetwindow(display, "/tmp/winname",
    &screen2, &_screen2, Refnone) < 0)

+ 3 - 3
sys/man/2/thread

@@ -119,8 +119,8 @@ int	nbsendp(Channel *c, void *v)
 int	nbsendul(Channel *c, ulong v)
 int	chanprint(Channel *c, char *fmt, ...)
 .XX
-void	procexecl(Channel *cpid, char *file, ...)
-void	procexec(Channel *cpid, char *file, char *args[])
+int	procexecl(Channel *cpid, char *file, ...)
+int	procexec(Channel *cpid, char *file, char *args[])
 Channel*	threadwaitchan(void)
 .XX
 int	threadnotify(int (*f)(void*, char*), int in)
@@ -321,7 +321,7 @@ and
 .IR exec (2));
 on success,
 they replace the calling thread (which must be the only thread in its proc)
-and invoke the external program.
+and invoke the external program, never returning.
 On error, they return \-1.
 If
 .I cpid

+ 1 - 1
sys/man/4/consolefs

@@ -207,7 +207,7 @@ Default user database.
 .SH BUGS
 .PP
 Changing the gid's or uid's while
-.I consoelfs
+.I consolefs
 is running
 is detected by
 .IR consolefs .

+ 4 - 1
sys/man/4/factotum

@@ -62,7 +62,10 @@ allows external programs to control the addition of new keys
 a log of actions
 .TP
 .B ctl
-for maintaining keys; when read, it returns a list of keys (without the secret data)
+for maintaining keys; when read, it returns a list of keys.
+For secret attributes, only the attribute name follow by a
+.L ?
+is returned.
 .PD
 .PP
 In any authentication, the caller typically acts as a client

+ 4 - 1
sys/man/4/vacfs

@@ -4,7 +4,7 @@ vacfs \- a Venti-based file system
 .SH SYNOPSIS
 .B vacfs
 [
-.B -dis
+.B -dips
 ]
 [
 .B -c
@@ -61,6 +61,9 @@ Use file descriptors 0 and 1 as the 9P communication channel rather than create
 The location to mount the file system. The default is
 .BR /n/vac .
 .TP
+.BI -p
+Disables permission checking.
+.TP
 .B -s
 Post the 9P channel on #s/vacfs rather than
 mounting it on

+ 5 - 0
sys/man/8/boot

@@ -176,6 +176,11 @@ If the
 .B -m
 option is given it is also passed as an option to
 .IR init .
+If the environment variable
+.B init
+is set (via
+.IR plan9.ini (8)),
+it is used as a command line to exec instead.
 .PP
 If the kernel has been built with the cache file system,
 .IR cfs (4),

+ 34 - 11
sys/man/8/kfscmd

@@ -113,39 +113,62 @@ Report statistics about the performance of the file system.
 Re-initialize authentication information by reading
 .BR /adm/users .
 .TP
+.B nowritegroup
+Each time
+.I kfs
+rereads
+.BR /adm/users ,
+it looks for a group named
+.BR write .
+If such a group exists, then the entire file system
+will appear read-only to users not in the group.
+If a write group exists but no one is in it,
+it will be impossible to edit
+.B /adm/users
+to correct the problem.
+To resolve this, the
+.B nowritegroup
+command turns off write group checking until the next
+time
+.B /adm/users
+is reread.
+.TP
 .BI cfs " filsys
 Change the `console' to the named file system (default is the main system).
 .TP
 .B chat
 Toggle tracing of 9P messages.
 .TP
-.B check [PRdfprtw]
-Check the file system.
+.B check [cdfpPqrtw]
+Check the file system and print summary information.
 The options are
 .PD 0
 .RS
 .TP
+.B c
+fix bad tags and clear the contents of the block.
+.TP
+.B d
+delete redundant references to a block.
+.TP
+.B f
+rebuild the list of free blocks.
+.TP
 .B p
 print the names of directories as they are checked.
 .TP
 .B P
 print the names of all files as they are checked.
 .TP
+.B q
+quiet mode: report errors, but suppress summary information
+.TP
 .B r
 read all of the data blocks and check the tags.
 .TP
-.B f
-rebuild the list of free blocks.
-.TP
-.B d
-delete redundant references to a block.
-.TP
 .B t
 fix bad tags.
 .TP
-.B c
-fix bad tags and clear the contents of the block.
-.TP
 .B w
 write all of the blocks that are touched.
 .RE

+ 3 - 0
sys/man/8/plan9.ini

@@ -580,6 +580,9 @@ below are rarely used and only on troublesome or suspect hardware.
 .SS \fL*pcimaxdno=value\fP
 This puts a limit on the maximum device number probed
 on a PCI bus (default 31).
+.SS \fL*nopcirouting=\fP
+Disable pci routing during boot.  May solve interrupt routing
+problems on certain machines.
 .\" .SS \fL*nobios=\fP
 .\" what does this do?  something with pci
 .SS \fLioexclude=value\fP

+ 3 - 3
sys/man/8/replica

@@ -201,7 +201,7 @@ to the file system rooted at
 copying files when necessary from the file system rooted at
 .IR serverroot .
 By default,
-.I replapplylog
+.I applylog
 does not attempt to set the uid on files; the
 .B -u
 flag enables this.
@@ -212,14 +212,14 @@ the conflict and takes no action.
 If the
 .B -c
 flag is given, 
-.I replapplylog
+.I applylog
 still takes no action, but does so silently and will not
 report the conflicts in the future.
 (The conflict is resolved in favor of the client.)
 If the
 .B -s
 flag is given,
-.I replapplylog
+.I applylog
 overwrites the local changes.
 (The conflict is resolved in favor of the server.)
 .PP

+ 1 - 1
sys/man/preface4.html

@@ -28,7 +28,7 @@ Many aspects of system security have been improved.
 The new security agent
 <A href="/magic/man2html/4/factotum"><I>factotum</I>(4)
 </A>maintains user passwords, while
-<A href="/magic/man2html/4/secstore"><I>secstore</I>(4)
+<A href="/magic/man2html/8/secstore"><I>secstore</I>(8)
 </A>keeps them safe and enables single sign-on to multiple domains and machines
 using a variety of secure protocols and services.
 <br>&#32;<br>

Різницю між файлами не показано, бо вона завелика
+ 0 - 0
sys/man/searchindex


+ 6 - 6
sys/src/9/bitsy/Booting101

@@ -115,20 +115,20 @@ being corrupted, because we haven't yet initialized it.
 sequence of commands.
 
 	# aux/mkflashfs /dev/flash/fs
-	
+
 	# aux/flashfs
 
 aux/flashfs created a Plan 9 server in /srv/brzr, which we can use to set up
 default directories. 
-	
+
 	# mount -c /srv/brzr /n/brzr
-	
+
 	# cd /n/brzr
-	
+
 	# mkdir n usr
-	
+
 	# mkdir n/fs n/emelie n/choline n/nslocum
-	
+
 	# mkdir usr/yourname usr/yourfriend
 
 

+ 175 - 0
sys/src/9/bitsy/paqfiles/cpurc

@@ -0,0 +1,175 @@
+#!/bin/rc
+
+debug=0
+
+#set service to terminal (necessary for factotum, handy for everything else)
+service=terminal 
+
+echo -n terminal > /env/service
+echo -n plan9 > /env/site
+echo -n astro > /env/facedom
+echo -n emelie > /env/fs
+
+bind -a '#y' /dev
+bind -a '#F' /dev
+bind -a '#I' /net
+bind -a '#D' /net
+
+# parallelism for mk
+NPROC=1
+
+sysname=`{cat /dev/sysname}
+if (~ $sysname ''){
+	sysname=bitsy
+	echo $sysname>/dev/sysname
+}
+prompt=($sysname^'# ' '	')
+
+# flavor
+fileserver=emelie
+cpu=olive
+
+# user defined flash partitions
+echo -n add fs		0x0800000 0x1000000 > /dev/flash/flashctl
+
+# so we can see things
+light 0
+
+# set variables
+if(~ $debug 1) echo ramfs
+ramfs
+if(~ $debug 1) echo pencal
+params -f
+if(! grep -s '^calibrate=' /tmp/tmpparams)
+	pencal >>/tmp/tmpparams
+if not {
+	eval `{grep '^calibrate=' /tmp/tmpparams}
+	echo calibrate $calibrate > '#m/mousectl'
+}
+prompter /tmp/tmpparams
+params
+if(~ $debug 1) {
+	echo tmpparams:
+	cat /tmp/tmpparams
+}
+. /tmp/tmpparams
+
+if(~ $debug 1) echo set user
+# set userid
+if(test -e /env/user){
+	echo -n $user > /dev/hostowner
+}
+
+if(~ $debug 1) echo start flashfs
+# bind in read/write file system
+if (aux/flashfs) {
+	if (~ $debug 1) echo flashfs started
+	mount /srv/brzr /n/tmp
+	bind -a /n /n/tmp/n
+	bind -a /sys/lib /n/tmp/sys/lib
+	bind -a /sys /n/tmp/sys
+	bind -a /arm/bin/auth /n/tmp/arm/bin/auth
+	bind -a /arm/bin/ndb /n/tmp/arm/bin/ndb
+	bind -a /arm/bin/ip /n/tmp/arm/bin/ip
+	bind -a /arm/bin/aux /n/tmp/arm/bin/aux
+	bind -a /arm/bin /n/tmp/arm/bin
+	bind -a /arm /n/tmp/arm
+	bind -a /lib/ndb /n/tmp/lib/ndb
+	bind -a /lib/font /n/tmp/lib/font
+	bind -a /lib /n/tmp/lib
+	bind -a / /n/tmp
+	bind /n/tmp /
+	unmount /n/tmp
+} >[2] /dev/null
+
+# start network
+if(grep -s WaveLAN/IEEE /dev/pcm0ctl){
+	if (~ $debug 1) echo 'configure #l0 wavelan'
+	echo -n 'configure #l0 wavelan'>/dev/pcm0ctl
+	bind -a '#l0' /net
+	switch($wvkey1){
+	case ''
+		;
+	case *
+		echo -n 'key1 '^$wvkey1 >/net/ether0/clone
+	}
+	switch($wvkey2){
+	case ''
+		;
+	case *
+		echo -n 'key2 '^$wvkey2 >/net/ether0/clone
+	}
+	switch($wvkey3){
+	case ''
+		;
+	case *
+		echo -n 'key3 '^$wvkey3 >/net/ether0/clone
+	}
+	switch($wvtxkey){
+	case ''
+		;
+	case *
+		echo -n 'txkey '^$wvtxkey >/net/ether0/clone
+	}
+	switch($wvmode){
+	case ''
+		;
+	case *
+		echo -n 'mode '^$wvmode >/net/ether0/clone
+	}
+	switch($wvibss){
+	case ''
+		;
+	case *
+		echo -n 'ibss '^$wvibss >/net/ether0/clone
+	}
+	switch($wvessid){
+	case ''
+		;
+	case *
+		echo -n 'essid '^$wvessid >/net/ether0/clone
+	}
+	switch($wvcrypt){
+	case ''
+		;
+	case *
+		echo -n 'crypt '^$wvcrypt >/net/ether0/clone
+	}
+	if (~ $debug 1) echo ip/ipconfig ether /net/ether0 $ipaddr $ipmask
+	ip/ipconfig ether /net/ether0 $ipaddr $ipmask
+	if(test -e /env/auth)
+		echo '	auth='^$auth >>/net/ndb
+	if(test -e /env/dns)
+		echo '	dns='^$dns >>/net/ndb
+	if(test -e /env/dnsdomain)
+		echo '	dnsdomain='^$dnsdomain >>/net/ndb
+	if(test -e /env/authdom)
+		echo '	authdom='^$authdom >>/net/ndb
+
+	if (~ $debug 1) echo ndb/cs
+	ndb/cs
+	ndb/dns -r
+}
+
+auth/factotum -n -s factotum -a $auth
+
+if(! test -e /env/font)
+	font=/lib/font/bit/lucidasans/unicode.6.font
+if(! test -e /env/tabstop)
+	tabstop=2
+
+if (test -d /usr/$user) {
+	home=/usr/$user
+	cd $home
+	if (test -r lib/profile) {
+		. lib/profile
+		exec /bin/rc
+	}
+	if (test -r lib/windows) {
+		if (~ $debug 1) echo 'exec rio -sk ''/bin/keyboard -l'' -i '$home'/lib/windows'
+		exec rio -sk '/bin/keyboard -l -w' -i $home/lib/windows
+	}
+}
+# bind in read/write file system
+if (~ $debug 1) echo 'exec rio -sk ''/bin/keyboard -l'''
+exec rio -sk '/bin/keyboard -l -w'

+ 6 - 0
sys/src/9/bitsy/paqfiles/local

@@ -0,0 +1,6 @@
+#
+#   files comprising the database
+#
+database=
+	file=/lib/ndb/local
+	file=/lib/ndb/common

+ 32 - 0
sys/src/9/bitsy/paqfiles/mfs

@@ -0,0 +1,32 @@
+#!/bin/rc
+switch($fs){
+case ''
+	echo you must set the environment variable fs
+	exit 0
+}
+if (! test -e /mnt/factotum) {
+	if (test -e /srv/factotum) {
+		mount -b /srv/factotum /mnt
+	}
+	if not {
+		auth/factotum -u
+	}
+}
+srv -m $fs $fs /n/fs
+bind -b /n/fs/arm/bin /bin
+bind -b /n/fs/rc/bin /bin
+bind -a /n/fs/lib /lib
+bind -b /n/fs/sys /sys
+bind -a /n/fs/usr /usr
+bind -c /n/fs/mail /mail
+bind -c /n/fs/acme /acme
+user=`{cat /dev/user}
+home=/usr/$user
+bind -a /n/fs/usr/$user /usr/$user
+bind -cb /usr/$user/tmp /tmp
+bind -b /usr/$user/bin/rc /bin
+bind -b /usr/$user/bin/arm /bin
+bind -a /n/fs/lib/font/bit/lucidasans /lib/font/bit/lucidasans 
+bind -a /n/fs/lib/font/bit/lucida /lib/font/bit/lucida
+bind -a /n/fs/lib/font/bit/misc /lib/font/bit/misc
+#service=cpu aux/listen -t /bin/service

+ 53 - 0
sys/src/9/bitsy/paqfiles/namespace

@@ -0,0 +1,53 @@
+# root
+mount #s/boot /root
+bind -a /root /
+bind -c /root/mnt /mnt
+
+# kernel devices
+bind #c /dev
+bind #d /fd
+bind -c #e /env
+bind #p /proc
+bind -c #s /srv
+bind -a #t /dev
+bind -a #r /dev
+bind -a #m /dev
+bind -a #y /dev
+bind -a #I /net
+bind -a #A /dev
+bind -a #F /dev
+bind -a #¤ /dev
+
+# servers
+mount -a /srv/cs /net
+mount -a /srv/dns /net
+mount -a /srv/factotum /mnt
+
+# read/write file system
+mount /srv/brzr /n/brzr
+mount /srv/brzr /n/tmp
+bind -a /n /n/tmp/n
+bind -a /sys/lib /n/tmp/sys/lib
+bind -a /sys /n/tmp/sys
+bind -a /arm/bin/auth /n/tmp/arm/bin/auth
+bind -a /arm/bin/ndb /n/tmp/arm/bin/ndb
+bind -a /arm/bin/ip /n/tmp/arm/bin/ip
+bind -a /arm/bin/aux /n/tmp/arm/bin/aux
+bind -a /arm/bin /n/tmp/arm/bin
+bind -a /arm /n/tmp/arm
+bind -a /lib/ndb /n/tmp/lib/ndb
+bind -a /lib/font /n/tmp/lib/font
+bind -a /lib /n/tmp/lib
+bind -a / /n/tmp
+bind /n/tmp /
+unmount /n/tmp
+
+# standard bin
+bind /arm/bin /bin
+bind -a /rc/bin /bin
+bind -a /arm/bin/bitsy /bin
+
+# user defines
+bind -cb /usr/$user/tmp /tmp
+bind -b /usr/$user/bin/rc /bin
+bind -b /usr/$user/bin/arm /bin

+ 9 - 0
sys/src/9/bitsy/paqfiles/startip

@@ -0,0 +1,9 @@
+#!/bin/rc
+if(grep -s WaveLAN/IEEE /dev/pcm0ctl){
+	echo -n 'configure #l0 WaveLAN/IEEE'>/dev/pcm0ctl
+	bind -a '#l0' /net
+	echo -n 'key moon1'>/net/ether0/clone
+	ip/ipconfig ether /net/ether0
+	ndb/cs
+	ndb/dns -r
+}

+ 5 - 0
sys/src/9/bitsy/paqfiles/unicode.6.font

@@ -0,0 +1,5 @@
+11	9
+0x0000	0x00FF	lsr.10
+0x0100	0x01f0	../lucida/EuroLatin.5.0
+0x2000	0x20aa	../lucida/GenPunct.5.0
+0x2200	0x22f1	../lucida/MathOps1.5.0

+ 5 - 1
sys/src/9/port/auth.c

@@ -75,6 +75,11 @@ sysfauth(ulong *arg)
 	}
 
 	ac = mntauth(c, aname);
+
+	/* at this point ac is responsible for keeping c alive */
+	cclose(c);
+	poperror();	/* c */
+
 	if(waserror()){
 		cclose(ac);
 		nexterror();
@@ -84,7 +89,6 @@ sysfauth(ulong *arg)
 	if(fd < 0)
 		error(Enofd);
 	poperror();	/* ac */
-	poperror();	/* c */
 
 	/* always mark it close on exec */
 	ac->flag |= CCEXEC;

+ 1 - 0
sys/src/boot/pc/boot.c

@@ -134,6 +134,7 @@ Endofinput:
 			print("badly compressed kernel\n");
 			return FAIL;
 		}
+
 		entry = GLLONG(ep->entry);
 		text = GLLONG(ep->text);
 		data = GLLONG(ep->data);

+ 4 - 3
sys/src/boot/pc/console.c

@@ -5,8 +5,8 @@
 #include "fns.h"
 #include "io.h"
 
-static IOQ consiq;
-static IOQ consoq;
+IOQ consiq;
+IOQ consoq;
 
 static int useuart;
 
@@ -207,7 +207,8 @@ panic(char *fmt, ...)
 	consputs(buf, n);
 	consputs("\n", 1);
 
-splhi(); for(;;);
+//floppymemwrite();
+//splhi(); for(;;);
 	if(etherdetach)
 		etherdetach();
 	if(sddetach)

+ 23 - 0
sys/src/boot/pc/devfloppy.c

@@ -810,6 +810,29 @@ floppyxfer(FDrive *dp, int cmd, void *a, long off, long n)
 	return -1;
 }
 
+/*
+void
+floppymemwrite(void)
+{
+	int i;
+	int n;
+	uchar *a;
+	FDrive *dp;
+
+	dp = &fl.d[0];
+	a = (uchar*)0x80000000;
+	n = 0;
+	while(n < 1440*1024){
+		i = floppyxfer(dp, Fwrite, a+n, n, 1440*1024-n);
+		if(i <= 0)
+			break;
+		n += i;
+	}
+	print("floppymemwrite wrote %d bytes\n", n);
+splhi(); for(;;);
+}
+*/
+
 static void
 floppyintr(Ureg *ur)
 {

+ 1 - 0
sys/src/boot/pc/devsd.c

@@ -283,6 +283,7 @@ sdinit(void)
 			m |= (1<<i);
 	}
 
+//notesdinfo();
 	return m;
 }
 

+ 3 - 0
sys/src/boot/pc/fns.h

@@ -7,6 +7,7 @@ void	apminit(void);
 int	bootp(int, char*, Boot*);
 int	bootpass(Boot*, void*, int);
 void	cancel(Alarm*);
+void	check(char*);
 void	cgascreenputs(char*, int);
 int	cistrcmp(char*, char*);
 int	cistrncmp(char*, char*, int);
@@ -82,12 +83,14 @@ int	pcmcistuple(int, int, void*, int);
 int	pcmspecial(char*, ISAConf*);
 void	pcmspecialclose(int);
 void	pcmunmap(int, PCMmap*);
+void	ptcheck(char*);
 void	putcr3(ulong);
 void	putidt(Segdesc*, int);
 void	qinit(IOQ*);
 void	readlsconf(void);
 void	sdaddconf(int);
 int	sdboot(int, char*, Boot*);
+void	sdcheck(char*);
 void*	sdgetdospart(int, char*, int);
 int	sdinit(void);
 void	sdinitdev(int, char*);

+ 1 - 0
sys/src/boot/pc/inflate.c

@@ -37,6 +37,7 @@ enum {
 static ulong	*crctab;
 static ulong	crc;
 
+extern void diff(char*);	//XXX
 int
 gunzip(uchar *out, int outn, uchar *in, int inn)
 {

+ 1 - 5
sys/src/boot/pc/l.s

@@ -198,14 +198,10 @@ noapm:
 	 BYTE	$0x16
 	 WORD	$tgdtptr(SB)
 
-	MOVL	$1,AX
+	LWI(1, rAX)
 	/* MOV AX,MSW */
 	BYTE $0x0F; BYTE $0x01; BYTE $0xF0
 
-/*	MOVL	CR0,AX
-	ORL	$1,AX
-	MOVL	AX,CR0
-*/
 /*
  *	clear prefetch queue (weird code to avoid optimizations)
  */

+ 3 - 4
sys/src/boot/pc/load.c

@@ -260,7 +260,6 @@ main(void)
 
 	if((p = getconf("console")) != nil)
 		consinit(p, getconf("baud"));
-
 	devpccardlink();
 	devi82365link();
 
@@ -391,11 +390,12 @@ cistrncmp(char *a, char *b, int n)
 	return 0;
 }
 
+extern void diff(char*);
+
+ulong palloc;
 void*
 ialloc(ulong n, int align)
 {
-
-	static ulong palloc;
 	ulong p;
 	int a;
 
@@ -411,7 +411,6 @@ ialloc(ulong n, int align)
 		p += align - a;
 
 	palloc = p+n;
-
 	return memset((void*)(p|KZERO), 0, n);
 }
 

+ 3 - 1
sys/src/cmd/9660srv/iobuf.c

@@ -76,8 +76,10 @@ purgebuf(Xdata *dev)
 	Ioclust *p;
 
 	for(p=iohead; p!=nil; p=p->next)
-		if(p->dev == dev)
+		if(p->dev == dev){
+			p->addr = -1;
 			p->busy = 0;
+		}
 }
 
 static Ioclust*

+ 2 - 0
sys/src/cmd/acme/exec.c

@@ -1285,6 +1285,8 @@ runwaittask(void *v)
 	if(c->pid != 0)	/* successful exec */
 		sendp(ccommand, c);
 	else{
+		if(c->iseditcmd)
+			sendul(cedit, 0);
 		free(c->name);
 		free(c->text);
 		free(c);

+ 31 - 20
sys/src/cmd/acme/mkfile

@@ -2,30 +2,41 @@
 BIN=/$objtype/bin
 
 TARG=acme
-OFILES=acme.$O\
-	addr.$O\
-	buff.$O\
-	cols.$O\
-	disk.$O\
-	ecmd.$O\
-	edit.$O\
-	elog.$O\
-	exec.$O\
-	file.$O\
-	fsys.$O\
-	look.$O\
-	regx.$O\
-	rows.$O\
-	scrl.$O\
-	text.$O\
-	time.$O\
-	util.$O\
-	wind.$O\
-	xfid.$O\
+
+FILES=acme\
+	addr\
+	buff\
+	cols\
+	disk\
+	ecmd\
+	edit\
+	elog\
+	exec\
+	file\
+	fsys\
+	look\
+	regx\
+	rows\
+	scrl\
+	text\
+	time\
+	util\
+	wind\
+	xfid\
 
 HFILES=dat.h\
+	edit.h\
 	fns.h\
 
+CFILES=${FILES:%=%.c}
+
+OFILES=${FILES:%=%.$O}
+
+UPDATE=mkfile\
+	/386/bin/$TARG\
+	$HFILES\
+	$CFILES\
+
 </sys/src/cmd/mkone
 
 $O.out:	/$objtype/lib/libframe.a /$objtype/lib/libdraw.a /$objtype/lib/libthread.a

+ 3 - 0
sys/src/cmd/auth/factotum/dat.h

@@ -9,6 +9,8 @@
 #include <fcall.h>
 #include <9p.h>
 
+#pragma varargck type "N" Attr*
+
 enum
 {
 	Maxname = 128,
@@ -182,6 +184,7 @@ int secstorefetch(char*);
 
 int		_authdial(char*, char*);
 void		askuser(char*);
+int		attrnamefmt(Fmt *fmt);
 int		canusekey(Fsstate*, Key*);
 void		closekey(Key*);
 uchar	*convAI2M(AuthInfo*, uchar*, int);

+ 3 - 1
sys/src/cmd/auth/factotum/fs.c

@@ -99,6 +99,7 @@ main(int argc, char **argv)
 
 	quotefmtinstall();
 	fmtinstall('A', _attrfmt);
+	fmtinstall('N', attrnamefmt);
 	fmtinstall('H', encodefmt);
 
 	ring = emalloc(sizeof(*ring));
@@ -146,6 +147,7 @@ main(int argc, char **argv)
 				if(strcmp(err, "cancel") == 0)
 					break;
 				fprint(2, "secstorefetch: %r\n");
+				fprint(2, "Enter an empty password to quit.\n");
 				secstorepw = nil; /* just try nvram pw once */
 			}
 		}else{
@@ -435,7 +437,7 @@ keylist(int i, char *a, uint n)
 		return 0;
 	k = ring->key[i];
 	k->attr = sortattr(k->attr);
-	snprint(buf, sizeof buf, "key %A\n", k->attr);
+	snprint(buf, sizeof buf, "key %A %N\n", k->attr, k->privattr);
 	strcpy(buf+sizeof buf-2, "\n");	/* if line is really long, just truncate */
 	if(strlen(buf) > n)
 		return 0;

+ 2 - 4
sys/src/cmd/auth/factotum/p9sk1.c

@@ -419,7 +419,7 @@ mkserverticket(State *s, char *tbuf)
 	Ticketreq *tr = &s->tr;
 	Ticket t;
 
-	if(strcmp(tr->authid, tr->hostid) != 0 || strcmp(tr->authid, tr->uid) != 0)
+	if(strcmp(tr->authid, tr->hostid) != 0)
 		return -1;
 	memset(&t, 0, sizeof(t));
 	memmove(t.chal, tr->chal, CHALLEN);
@@ -442,9 +442,7 @@ gettickets(State *s, char *trbuf, char *tbuf)
 */
 	if(getastickets(s, trbuf, tbuf) >= 0)
 		return 0;
-	if(sflag)
-		return mkserverticket(s, tbuf);
-	return -1;
+	return mkserverticket(s, tbuf);
 }
 
 Proto p9sk1 = {

+ 16 - 0
sys/src/cmd/auth/factotum/util.c

@@ -889,3 +889,19 @@ writehostowner(char *owner)
 	}
 }
 
+int
+attrnamefmt(Fmt *fmt)
+{
+	char *b, buf[1024], *ebuf;
+	Attr *a;
+
+	ebuf = buf+sizeof buf;
+	b = buf;
+	strcpy(buf, " ");
+	for(a=va_arg(fmt->args, Attr*); a; a=a->next){
+		if(a->name == nil)
+			continue;
+		b = seprint(b, ebuf, " %q?", s_to_c(a->name));
+	}
+	return fmtstrcpy(fmt, buf+1);
+}

+ 1 - 1
sys/src/cmd/auth/secstore/password.c

@@ -84,7 +84,7 @@ getPW(char *id)
 	if(pw->failed < 10)
 		return pw;  // success
 	if(now < mtimePW(id)+300){
-		werrstr("too many failed logins");
+		werrstr("too many failures; try again in five minutes");
 		freePW(pw);
 		return nil;
 	}

+ 10 - 4
sys/src/cmd/auth/secstore/secstore.c

@@ -235,7 +235,7 @@ login(char *id, char *dest, int chpass, char **gf, int *Gflag, char **pf, char *
 {
 	char pass[64];
 	ulong len;
-	int rv = -1, fd, passlen, newpasslen = 0;
+	int rv = -1, fd, passlen, newpasslen = 0, ntry = 0;
 	uchar *memfile, *memcur, *memnext;
 	char *S, *list, *cur, *next, *newpass = nil, *hexHi;
 	char *f[8], s[Maxmsg+1], prompt[128], buf[Maxmsg];
@@ -253,6 +253,7 @@ login(char *id, char *dest, int chpass, char **gf, int *Gflag, char **pf, char *
 		}
 		if((conn = newSConn(fd)) == nil)
 			return -1;
+		ntry++;
 		getpasswd("secstore password: ", pass, sizeof pass);
 		if(pass[0]==0){
 			fprint(2, "null password, skipping secstore login\n");
@@ -263,6 +264,8 @@ login(char *id, char *dest, int chpass, char **gf, int *Gflag, char **pf, char *
 			break;
 		conn->free(conn);
 		// and let user try retyping the password
+		if(ntry==3)
+			fprint(2, "Enter an empty password to quit.\n");
 	}
 	passlen = strlen(pass);
 	fprint(2, "%s\n", S);
@@ -412,21 +415,21 @@ main(int argc, char **argv)
 			exits("too many gfiles");
 		gfile[ngfile++] = ARGF();
 		if(gfile[ngfile-1] == nil)
-			exits("usage");
+			usage();
 		break;
 	case 'p':
 		if(npfile >= MAXFILES)
 			exits("too many pfiles");
 		pfile[npfile++] = ARGF();
 		if(pfile[npfile-1] == nil)
-			exits("usage");
+			usage();
 		break;
 	case 'r':
 		if(nrfile >= MAXFILES)
 			exits("too many rfiles");
 		rfile[nrfile++] = ARGF();
 		if(rfile[nrfile-1] == nil)
-			exits("usage");
+			usage();
 		break;
 	case 's':
 		serve = EARGF(usage());
@@ -437,6 +440,9 @@ main(int argc, char **argv)
 	case 'v':
 		verbose++;
 		break;
+	default:
+		usage();
+		break;
 	}ARGEND;
 	gfile[ngfile] = nil;
 	pfile[npfile] = nil;

+ 1 - 1
sys/src/cmd/auth/secstore/util.c

@@ -58,7 +58,7 @@ getpasswd(char *prompt, char *line, int len)
 			fprint(cons, "\n");
 			return -1;
 		}
-		if(n == 0 || *p == '\n' || *p == '\r'){
+		if(n == 0 || *p == '\n' || *p == '\r' || *p == 0x7f){
 			*p = '\0';
 			fprint(consctl, "rawoff");
 			fprint(cons, "\n");

Деякі файли не було показано, через те що забагато файлів було змінено