Browse Source

Plan 9 from Bell Labs 2006-04-05

David du Colombier 15 years ago
parent
commit
b0b726a6ec

+ 49 - 45
dist/replica/_plan9.db

@@ -44,7 +44,7 @@
 386/bin/astro - 775 sys sys 1143741928 138855
 386/bin/auth - 20000000775 sys sys 1016920815 0
 386/bin/auth/aescbc - 775 sys sys 1143777740 140813
-386/bin/auth/asn12rsa - 775 sys sys 1143777740 120801
+386/bin/auth/asn12rsa - 775 sys sys 1144169660 120818
 386/bin/auth/authsrv - 775 sys sys 1143777741 165862
 386/bin/auth/changeuser - 775 sys sys 1143777742 97377
 386/bin/auth/convkeys - 775 sys sys 1143777742 87820
@@ -53,7 +53,7 @@
 386/bin/auth/debug - 775 sys sys 1143777742 101425
 386/bin/auth/disable - 775 sys sys 1020319057 146
 386/bin/auth/enable - 775 sys sys 1020319057 134
-386/bin/auth/factotum - 775 sys sys 1143777743 321841
+386/bin/auth/factotum - 775 sys sys 1144169660 321860
 386/bin/auth/fgui - 775 sys sys 1143777744 218963
 386/bin/auth/guard.srv - 775 sys sys 1143777744 143088
 386/bin/auth/iam - 775 sys sys 1085076981 50791
@@ -64,16 +64,16 @@
 386/bin/auth/pemdecode - 775 sys sys 1143777746 61810
 386/bin/auth/pemencode - 775 sys sys 1143777746 60208
 386/bin/auth/printnetkey - 775 sys sys 1140285592 40436
-386/bin/auth/rsa2csr - 775 sys sys 1143777746 180956
-386/bin/auth/rsa2pub - 775 sys sys 1143777747 143983
-386/bin/auth/rsa2ssh - 775 sys sys 1143777748 139300
-386/bin/auth/rsa2x509 - 775 sys sys 1143777748 184717
-386/bin/auth/rsafill - 775 sys sys 1143777749 144051
-386/bin/auth/rsagen - 775 sys sys 1143777750 153609
+386/bin/auth/rsa2csr - 775 sys sys 1144169661 180973
+386/bin/auth/rsa2pub - 775 sys sys 1144169662 144000
+386/bin/auth/rsa2ssh - 775 sys sys 1144169663 139317
+386/bin/auth/rsa2x509 - 775 sys sys 1144169665 184736
+386/bin/auth/rsafill - 775 sys sys 1144169666 144068
+386/bin/auth/rsagen - 775 sys sys 1144169667 153628
 386/bin/auth/secretpem - 775 sys sys 1045537944 118526
-386/bin/auth/secstore - 775 sys sys 1143777750 195927
-386/bin/auth/secstored - 775 sys sys 1143777751 197368
-386/bin/auth/secuser - 775 sys sys 1143777752 153298
+386/bin/auth/secstore - 775 sys sys 1144169668 195944
+386/bin/auth/secstored - 775 sys sys 1144169670 197387
+386/bin/auth/secuser - 775 sys sys 1144169671 153317
 386/bin/auth/status - 775 sys sys 1020319060 738
 386/bin/auth/uniq - 775 sys sys 1143777752 63409
 386/bin/auth/warning - 775 sys sys 1143777752 101376
@@ -144,7 +144,7 @@
 386/bin/aux/stub - 775 sys sys 1143777766 141237
 386/bin/aux/tcpostio - 775 sys sys 1094040084 200808
 386/bin/aux/text2post - 775 sys sys 1104121986 78336
-386/bin/aux/timesync - 775 sys sys 1143777767 128723
+386/bin/aux/timesync - 775 sys sys 1144169672 128740
 386/bin/aux/tr2post - 775 sys sys 1104121987 176578
 386/bin/aux/trampoline - 775 sys sys 1143777767 83990
 386/bin/aux/typepasswd - 775 sys sys 1143777767 69833
@@ -246,7 +246,7 @@
 386/bin/fs/v10fs - 775 sys sys 1134389867 94594
 386/bin/fs/v6fs - 775 sys sys 1134389867 94512
 386/bin/fs/zipfs - 775 sys sys 1134389867 109110
-386/bin/ftpfs - 775 sys sys 1143777794 273185
+386/bin/ftpfs - 775 sys sys 1144169673 273204
 386/bin/games - 20000000775 sys sys 1096298711 0
 386/bin/games/4s - 775 sys sys 1132506854 178226
 386/bin/games/5s - 775 sys sys 1132506855 180514
@@ -269,7 +269,7 @@
 386/bin/gview - 775 sys sys 1143777796 238956
 386/bin/gzip - 775 sys sys 1143777796 85079
 386/bin/hayes - 775 sys sys 1143777796 64888
-386/bin/hget - 775 sys sys 1143777797 233847
+386/bin/hget - 775 sys sys 1144169675 233866
 386/bin/history - 775 sys sys 1143777797 75786
 386/bin/hoc - 775 sys sys 1143777798 100173
 386/bin/html2ms - 775 sys sys 1143777798 66416
@@ -289,7 +289,7 @@
 386/bin/ip/gping - 775 sys sys 1143777803 183464
 386/bin/ip/hogports - 775 sys sys 1143742001 42914
 386/bin/ip/httpd - 20000000775 sys sys 1016920846 0
-386/bin/ip/httpd/httpd - 775 sys sys 1143777804 294953
+386/bin/ip/httpd/httpd - 775 sys sys 1144169676 294972
 386/bin/ip/httpd/imagemap - 775 sys sys 1143777805 117108
 386/bin/ip/httpd/man2html - 775 sys sys 1143777805 125666
 386/bin/ip/httpd/netlib_find - 775 sys sys 1143777805 117961
@@ -297,7 +297,7 @@
 386/bin/ip/httpd/save - 775 sys sys 1143777806 133518
 386/bin/ip/httpd/webls - 775 sys sys 1143777807 133629
 386/bin/ip/httpd/wikipost - 775 sys sys 1143777808 114989
-386/bin/ip/httpfile - 775 sys sys 1143777809 284287
+386/bin/ip/httpfile - 775 sys sys 1144169677 284304
 386/bin/ip/imap4d - 775 sys sys 1143777810 238051
 386/bin/ip/ipconfig - 775 sys sys 1143777810 138177
 386/bin/ip/ping - 775 sys sys 1143777810 76815
@@ -425,8 +425,8 @@
 386/bin/telnet - 775 sys sys 1143777840 80744
 386/bin/test - 775 sys sys 1143777840 70179
 386/bin/time - 775 sys sys 1143777841 61713
-386/bin/tlsclient - 775 sys sys 1143777841 198846
-386/bin/tlssrv - 775 sys sys 1143777842 199106
+386/bin/tlsclient - 775 sys sys 1144169678 198863
+386/bin/tlssrv - 775 sys sys 1144169678 199123
 386/bin/togif - 775 sys sys 1143777842 190226
 386/bin/toico - 775 sys sys 1143777842 124005
 386/bin/topng - 775 sys sys 1143777843 138675
@@ -557,10 +557,10 @@
 386/lib/libhttpd.a - 664 sys sys 1143777863 99458
 386/lib/libip.a - 664 sys sys 1143777863 35576
 386/lib/libl.a - 664 sys sys 1143777863 5372
-386/lib/libmach.a - 664 sys sys 1143863651 782098
+386/lib/libmach.a - 664 sys sys 1144169680 782440
 386/lib/libmemdraw.a - 664 sys sys 1143777866 284092
 386/lib/libmemlayer.a - 664 sys sys 1143777866 47360
-386/lib/libmp.a - 664 sys sys 1143777866 79974
+386/lib/libmp.a - 664 sys sys 1144169680 79980
 386/lib/libndb.a - 664 sys sys 1143777866 60716
 386/lib/libplumb.a - 664 sys sys 1143777866 19408
 386/lib/libregexp.a - 664 sys sys 1143777866 37438
@@ -6017,7 +6017,7 @@ sys/include/memdraw.h - 664 sys sys 1091904419 5645
 sys/include/memlayer.h - 664 sys sys 1051031022 1851
 sys/include/mouse.h - 664 sys sys 1035232010 1003
 sys/include/mp.h - 664 sys sys 1014929065 4610
-sys/include/ndb.h - 664 sys sys 1091904429 4369
+sys/include/ndb.h - 664 sys sys 1144174492 4412
 sys/include/nfs3.h - 664 sys sys 1045589438 15082
 sys/include/plumb.h - 664 sys sys 1014929065 989
 sys/include/pool.h - 664 sys sys 1102093074 1219
@@ -7700,7 +7700,7 @@ sys/man/8/checkarenas - 664 sys sys 1019866709 669
 sys/man/8/cpurc - 664 sys sys 971455510 1275
 sys/man/8/cron - 664 sys sys 1063858596 1867
 sys/man/8/dhcpd - 664 sys sys 1032654987 5237
-sys/man/8/disksim - 664 sys sys 1141009713 1452
+sys/man/8/disksim - 664 sys sys 1144150487 1476
 sys/man/8/drawterm - 664 sys sys 1135901219 1741
 sys/man/8/fossilcons - 664 sys sys 1138466274 18276
 sys/man/8/fs - 664 sys sys 1055701170 15029
@@ -13457,13 +13457,14 @@ sys/src/cmd/unix/9pfreebsd/mount_9fs/Makefile - 664 sys sys 960684604 412
 sys/src/cmd/unix/9pfreebsd/mount_9fs/crypt.c - 664 sys sys 960684604 18042
 sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.8 - 664 sys sys 960684604 10864
 sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.c - 664 sys sys 960684605 25118
-sys/src/cmd/unix/README - 664 sys sys 1128520385 1735
+sys/src/cmd/unix/README - 664 sys sys 1144150393 1380
 sys/src/cmd/unix/drawterm - 20000000775 sys sys 964488190 0
 sys/src/cmd/unix/drawterm/9ball.ico - 664 sys sys 1135900533 9326
 sys/src/cmd/unix/drawterm/9ball.rc - 664 sys sys 1135900533 39
 sys/src/cmd/unix/drawterm/LICENSE - 664 sys sys 1135900534 12184
 sys/src/cmd/unix/drawterm/Make.config - 664 sys sys 1142177508 40
 sys/src/cmd/unix/drawterm/Make.irix - 664 sys sys 1137502401 493
+sys/src/cmd/unix/drawterm/Make.osx - 664 sys sys 1144150883 426
 sys/src/cmd/unix/drawterm/Make.unix - 664 sys sys 1142177512 453
 sys/src/cmd/unix/drawterm/Make.win32 - 664 sys sys 1141662620 826
 sys/src/cmd/unix/drawterm/Makefile - 664 sys sys 1135900534 1112
@@ -13510,7 +13511,7 @@ sys/src/cmd/unix/drawterm/include/draw.h - 664 sys sys 1135900762 16052
 sys/src/cmd/unix/drawterm/include/dtos.h - 664 sys sys 1135900762 358
 sys/src/cmd/unix/drawterm/include/fcall.h - 664 sys sys 1135900762 2676
 sys/src/cmd/unix/drawterm/include/keyboard.h - 664 sys sys 1135900762 920
-sys/src/cmd/unix/drawterm/include/lib.h - 664 sys sys 1137506302 7467
+sys/src/cmd/unix/drawterm/include/lib.h - 664 sys sys 1144150883 7495
 sys/src/cmd/unix/drawterm/include/libc.h - 664 sys sys 1135900763 36
 sys/src/cmd/unix/drawterm/include/libsec.h - 664 sys sys 1135900763 8861
 sys/src/cmd/unix/drawterm/include/memdraw.h - 664 sys sys 1135900763 6306
@@ -13520,14 +13521,14 @@ sys/src/cmd/unix/drawterm/include/u.h - 664 sys sys 1135900763 336
 sys/src/cmd/unix/drawterm/include/unix.h - 664 sys sys 1137506303 349
 sys/src/cmd/unix/drawterm/include/user.h - 664 sys sys 1135900764 2532
 sys/src/cmd/unix/drawterm/kern - 20000000775 sys sys 1135900801 0
-sys/src/cmd/unix/drawterm/kern/Makefile - 664 sys sys 1142177517 608
+sys/src/cmd/unix/drawterm/kern/Makefile - 664 sys sys 1144150884 620
 sys/src/cmd/unix/drawterm/kern/allocb.c - 664 sys sys 1135900764 3172
 sys/src/cmd/unix/drawterm/kern/cache.c - 664 sys sys 1135900764 466
 sys/src/cmd/unix/drawterm/kern/chan.c - 664 sys sys 1135900764 29593
 sys/src/cmd/unix/drawterm/kern/dat.h - 664 sys sys 1135900765 10716
 sys/src/cmd/unix/drawterm/kern/data.c - 664 sys sys 1135900765 423
 sys/src/cmd/unix/drawterm/kern/dev.c - 664 sys sys 1135900765 8523
-sys/src/cmd/unix/drawterm/kern/devaudio-none.c - 664 sys sys 1142177493 471
+sys/src/cmd/unix/drawterm/kern/devaudio-none.c - 664 sys sys 1144150884 628
 sys/src/cmd/unix/drawterm/kern/devaudio-unix.c - 664 sys sys 1142177493 3064
 sys/src/cmd/unix/drawterm/kern/devaudio.c - 664 sys sys 1142177494 6144
 sys/src/cmd/unix/drawterm/kern/devaudio.h - 664 sys sys 1142177494 328
@@ -13545,7 +13546,8 @@ sys/src/cmd/unix/drawterm/kern/devmouse.c - 664 sys sys 1135900767 3799
 sys/src/cmd/unix/drawterm/kern/devpipe.c - 664 sys sys 1135900767 5927
 sys/src/cmd/unix/drawterm/kern/devroot.c - 664 sys sys 1137502216 4755
 sys/src/cmd/unix/drawterm/kern/devssl.c - 664 sys sys 1135900767 26455
-sys/src/cmd/unix/drawterm/kern/devtab.c - 664 sys sys 1142177519 509
+sys/src/cmd/unix/drawterm/kern/devtab.c - 664 sys sys 1144150884 544
+sys/src/cmd/unix/drawterm/kern/devtls.c - 664 sys sys 1144150884 45295
 sys/src/cmd/unix/drawterm/kern/error.c - 664 sys sys 1135900767 2100
 sys/src/cmd/unix/drawterm/kern/error.h - 664 sys sys 1135900768 2583
 sys/src/cmd/unix/drawterm/kern/exportfs.c - 664 sys sys 1135900768 13444
@@ -13602,7 +13604,7 @@ sys/src/cmd/unix/drawterm/libauthsrv/opasstokey.c - 664 sys sys 1135900562 448
 sys/src/cmd/unix/drawterm/libauthsrv/passtokey.c - 664 sys sys 1135900562 517
 sys/src/cmd/unix/drawterm/libauthsrv/readnvram.c - 664 sys sys 1135900562 8446
 sys/src/cmd/unix/drawterm/libc - 20000000775 sys sys 1135900573 0
-sys/src/cmd/unix/drawterm/libc/Makefile - 664 sys sys 1137502398 1113
+sys/src/cmd/unix/drawterm/libc/Makefile - 664 sys sys 1144150884 1141
 sys/src/cmd/unix/drawterm/libc/charstod.c - 664 sys sys 1137619294 1203
 sys/src/cmd/unix/drawterm/libc/cleanname.c - 664 sys sys 1135900562 1199
 sys/src/cmd/unix/drawterm/libc/convD2M.c - 664 sys sys 1135900562 1398
@@ -13618,6 +13620,7 @@ sys/src/cmd/unix/drawterm/libc/dirstat.c - 664 sys sys 1135900563 688
 sys/src/cmd/unix/drawterm/libc/dirwstat.c - 664 sys sys 1135900564 246
 sys/src/cmd/unix/drawterm/libc/dofmt.c - 664 sys sys 1137619295 9020
 sys/src/cmd/unix/drawterm/libc/dorfmt.c - 664 sys sys 1137619295 791
+sys/src/cmd/unix/drawterm/libc/encodefmt.c - 664 sys sys 1144150884 1100
 sys/src/cmd/unix/drawterm/libc/errfmt.c - 664 sys sys 1135900564 175
 sys/src/cmd/unix/drawterm/libc/fcallfmt.c - 664 sys sys 1135900564 5740
 sys/src/cmd/unix/drawterm/libc/fltfmt.c - 664 sys sys 1137619295 6302
@@ -13647,6 +13650,7 @@ sys/src/cmd/unix/drawterm/libc/nsec.c - 664 sys sys 1135900567 1196
 sys/src/cmd/unix/drawterm/libc/pow10.c - 664 sys sys 1137619298 1195
 sys/src/cmd/unix/drawterm/libc/print.c - 664 sys sys 1137619298 184
 sys/src/cmd/unix/drawterm/libc/pushssl.c - 664 sys sys 1135900567 905
+sys/src/cmd/unix/drawterm/libc/pushtls.c - 664 sys sys 1144150885 2023
 sys/src/cmd/unix/drawterm/libc/rand.c - 664 sys sys 1135900567 79
 sys/src/cmd/unix/drawterm/libc/read9pmsg.c - 664 sys sys 1135900567 462
 sys/src/cmd/unix/drawterm/libc/readn.c - 664 sys sys 1135900568 234
@@ -15214,7 +15218,7 @@ sys/src/libmach/kobj.c - 664 sys sys 1091732625 2217
 sys/src/libmach/machdata.c - 664 sys sys 1131289377 8799
 sys/src/libmach/map.c - 664 sys sys 1131289376 3056
 sys/src/libmach/mips2ureg.h - 664 sys sys 1143821483 886
-sys/src/libmach/mkfile - 664 sys sys 1131375713 479
+sys/src/libmach/mkfile - 664 sys sys 1144151016 482
 sys/src/libmach/obj.c - 664 sys sys 1131289376 5929
 sys/src/libmach/obj.h - 664 sys sys 1131292890 604
 sys/src/libmach/q.c - 664 sys sys 1131289379 3630
@@ -15231,7 +15235,7 @@ sys/src/libmach/udb.c - 664 sys sys 1136322404 21967
 sys/src/libmach/uobj.c - 664 sys sys 1114459831 2219
 sys/src/libmach/v.c - 664 sys sys 1131289378 3446
 sys/src/libmach/vcodas.c - 664 sys sys 1136329351 10293
-sys/src/libmach/vdb.c - 664 sys sys 1136329351 22299
+sys/src/libmach/vdb.c - 664 sys sys 1144151030 22870
 sys/src/libmach/vobj.c - 664 sys sys 1091732625 2206
 sys/src/libmemdraw - 20000000775 sys sys 985020762 0
 sys/src/libmemdraw/alloc.c - 664 sys sys 1135895512 3334
@@ -15284,7 +15288,7 @@ sys/src/libmp/386/mkfile - 664 sys sys 1032061348 287
 sys/src/libmp/386/mpdigdiv.s - 664 sys sys 944961744 352
 sys/src/libmp/386/mpvecadd.s - 664 sys sys 944961744 906
 sys/src/libmp/386/mpvecdigmuladd.s - 664 sys sys 964712439 1063
-sys/src/libmp/386/mpvecdigmulsub.s - 664 sys sys 953344710 971
+sys/src/libmp/386/mpvecdigmulsub.s - 664 sys sys 1144150976 982
 sys/src/libmp/386/mpvecsub.s - 664 sys sys 944961744 767
 sys/src/libmp/alpha - 20000000775 sys sys 944961745 0
 sys/src/libmp/alpha/mkfile - 664 sys sys 1032061349 180
@@ -15345,27 +15349,27 @@ sys/src/libmp/power/mpvecsub.s - 664 sys sys 950104732 1118
 sys/src/libmp/power/placeholder.c - 664 sys sys 944961747 0
 sys/src/libmp/test.c - 664 sys sys 964798440 12260
 sys/src/libndb - 20000000775 sys sys 1015013466 0
-sys/src/libndb/csgetval.c - 664 sys sys 1078839927 1752
-sys/src/libndb/csipinfo.c - 664 sys sys 1069206439 1175
-sys/src/libndb/dnsquery.c - 664 sys sys 1078618597 2840
+sys/src/libndb/csgetval.c - 664 sys sys 1144174488 1796
+sys/src/libndb/csipinfo.c - 664 sys sys 1144174488 1178
+sys/src/libndb/dnsquery.c - 664 sys sys 1144174488 2883
 sys/src/libndb/ipattr.c - 664 sys sys 953844690 586
 sys/src/libndb/mkfile - 664 sys sys 1078618596 513
-sys/src/libndb/ndbaux.c - 664 sys sys 1078929180 1504
-sys/src/libndb/ndbcache.c - 664 sys sys 1078618597 2164
+sys/src/libndb/ndbaux.c - 664 sys sys 1144174488 1544
+sys/src/libndb/ndbcache.c - 664 sys sys 1144174488 2246
 sys/src/libndb/ndbcat.c - 664 sys sys 950311789 224
-sys/src/libndb/ndbconcatenate.c - 664 sys sys 1078618598 259
-sys/src/libndb/ndbdiscard.c - 664 sys sys 1078618598 436
-sys/src/libndb/ndbfree.c - 664 sys sys 1078618598 952
-sys/src/libndb/ndbgetipaddr.c - 664 sys sys 1078839928 792
-sys/src/libndb/ndbgetval.c - 664 sys sys 1078839928 1309
-sys/src/libndb/ndbhash.c - 664 sys sys 1069206440 4973
+sys/src/libndb/ndbconcatenate.c - 664 sys sys 1144174489 297
+sys/src/libndb/ndbdiscard.c - 664 sys sys 1144174489 474
+sys/src/libndb/ndbfree.c - 664 sys sys 1144174489 1123
+sys/src/libndb/ndbgetipaddr.c - 664 sys sys 1144174489 876
+sys/src/libndb/ndbgetval.c - 664 sys sys 1144174490 1348
+sys/src/libndb/ndbhash.c - 664 sys sys 1144174490 5276
 sys/src/libndb/ndbhf.h - 664 sys sys 1015013485 746
-sys/src/libndb/ndbipinfo.c - 664 sys sys 1078927860 4929
+sys/src/libndb/ndbipinfo.c - 664 sys sys 1144174490 5105
 sys/src/libndb/ndblookval.c - 664 sys sys 1078839929 791
 sys/src/libndb/ndbopen.c - 664 sys sys 1069206441 2716
-sys/src/libndb/ndbparse.c - 664 sys sys 1069206440 1167
+sys/src/libndb/ndbparse.c - 664 sys sys 1144174490 1207
 sys/src/libndb/ndbreorder.c - 664 sys sys 1078618600 966
-sys/src/libndb/ndbsubstitute.c - 664 sys sys 1078618600 692
+sys/src/libndb/ndbsubstitute.c - 664 sys sys 1144174491 867
 sys/src/libplumb - 20000000775 sys sys 1014928082 0
 sys/src/libplumb/event.c - 664 sys sys 947358887 1861
 sys/src/libplumb/mesg.c - 664 sys sys 1133279518 7080

+ 49 - 45
dist/replica/plan9.db

@@ -44,7 +44,7 @@
 386/bin/astro - 775 sys sys 1143741928 138855
 386/bin/auth - 20000000775 sys sys 1016920815 0
 386/bin/auth/aescbc - 775 sys sys 1143777740 140813
-386/bin/auth/asn12rsa - 775 sys sys 1143777740 120801
+386/bin/auth/asn12rsa - 775 sys sys 1144169660 120818
 386/bin/auth/authsrv - 775 sys sys 1143777741 165862
 386/bin/auth/changeuser - 775 sys sys 1143777742 97377
 386/bin/auth/convkeys - 775 sys sys 1143777742 87820
@@ -53,7 +53,7 @@
 386/bin/auth/debug - 775 sys sys 1143777742 101425
 386/bin/auth/disable - 775 sys sys 1020319057 146
 386/bin/auth/enable - 775 sys sys 1020319057 134
-386/bin/auth/factotum - 775 sys sys 1143777743 321841
+386/bin/auth/factotum - 775 sys sys 1144169660 321860
 386/bin/auth/fgui - 775 sys sys 1143777744 218963
 386/bin/auth/guard.srv - 775 sys sys 1143777744 143088
 386/bin/auth/iam - 775 sys sys 1085076981 50791
@@ -64,16 +64,16 @@
 386/bin/auth/pemdecode - 775 sys sys 1143777746 61810
 386/bin/auth/pemencode - 775 sys sys 1143777746 60208
 386/bin/auth/printnetkey - 775 sys sys 1140285592 40436
-386/bin/auth/rsa2csr - 775 sys sys 1143777746 180956
-386/bin/auth/rsa2pub - 775 sys sys 1143777747 143983
-386/bin/auth/rsa2ssh - 775 sys sys 1143777748 139300
-386/bin/auth/rsa2x509 - 775 sys sys 1143777748 184717
-386/bin/auth/rsafill - 775 sys sys 1143777749 144051
-386/bin/auth/rsagen - 775 sys sys 1143777750 153609
+386/bin/auth/rsa2csr - 775 sys sys 1144169661 180973
+386/bin/auth/rsa2pub - 775 sys sys 1144169662 144000
+386/bin/auth/rsa2ssh - 775 sys sys 1144169663 139317
+386/bin/auth/rsa2x509 - 775 sys sys 1144169665 184736
+386/bin/auth/rsafill - 775 sys sys 1144169666 144068
+386/bin/auth/rsagen - 775 sys sys 1144169667 153628
 386/bin/auth/secretpem - 775 sys sys 1045537944 118526
-386/bin/auth/secstore - 775 sys sys 1143777750 195927
-386/bin/auth/secstored - 775 sys sys 1143777751 197368
-386/bin/auth/secuser - 775 sys sys 1143777752 153298
+386/bin/auth/secstore - 775 sys sys 1144169668 195944
+386/bin/auth/secstored - 775 sys sys 1144169670 197387
+386/bin/auth/secuser - 775 sys sys 1144169671 153317
 386/bin/auth/status - 775 sys sys 1020319060 738
 386/bin/auth/uniq - 775 sys sys 1143777752 63409
 386/bin/auth/warning - 775 sys sys 1143777752 101376
@@ -144,7 +144,7 @@
 386/bin/aux/stub - 775 sys sys 1143777766 141237
 386/bin/aux/tcpostio - 775 sys sys 1094040084 200808
 386/bin/aux/text2post - 775 sys sys 1104121986 78336
-386/bin/aux/timesync - 775 sys sys 1143777767 128723
+386/bin/aux/timesync - 775 sys sys 1144169672 128740
 386/bin/aux/tr2post - 775 sys sys 1104121987 176578
 386/bin/aux/trampoline - 775 sys sys 1143777767 83990
 386/bin/aux/typepasswd - 775 sys sys 1143777767 69833
@@ -246,7 +246,7 @@
 386/bin/fs/v10fs - 775 sys sys 1134389867 94594
 386/bin/fs/v6fs - 775 sys sys 1134389867 94512
 386/bin/fs/zipfs - 775 sys sys 1134389867 109110
-386/bin/ftpfs - 775 sys sys 1143777794 273185
+386/bin/ftpfs - 775 sys sys 1144169673 273204
 386/bin/games - 20000000775 sys sys 1096298711 0
 386/bin/games/4s - 775 sys sys 1132506854 178226
 386/bin/games/5s - 775 sys sys 1132506855 180514
@@ -269,7 +269,7 @@
 386/bin/gview - 775 sys sys 1143777796 238956
 386/bin/gzip - 775 sys sys 1143777796 85079
 386/bin/hayes - 775 sys sys 1143777796 64888
-386/bin/hget - 775 sys sys 1143777797 233847
+386/bin/hget - 775 sys sys 1144169675 233866
 386/bin/history - 775 sys sys 1143777797 75786
 386/bin/hoc - 775 sys sys 1143777798 100173
 386/bin/html2ms - 775 sys sys 1143777798 66416
@@ -289,7 +289,7 @@
 386/bin/ip/gping - 775 sys sys 1143777803 183464
 386/bin/ip/hogports - 775 sys sys 1143742001 42914
 386/bin/ip/httpd - 20000000775 sys sys 1016920846 0
-386/bin/ip/httpd/httpd - 775 sys sys 1143777804 294953
+386/bin/ip/httpd/httpd - 775 sys sys 1144169676 294972
 386/bin/ip/httpd/imagemap - 775 sys sys 1143777805 117108
 386/bin/ip/httpd/man2html - 775 sys sys 1143777805 125666
 386/bin/ip/httpd/netlib_find - 775 sys sys 1143777805 117961
@@ -297,7 +297,7 @@
 386/bin/ip/httpd/save - 775 sys sys 1143777806 133518
 386/bin/ip/httpd/webls - 775 sys sys 1143777807 133629
 386/bin/ip/httpd/wikipost - 775 sys sys 1143777808 114989
-386/bin/ip/httpfile - 775 sys sys 1143777809 284287
+386/bin/ip/httpfile - 775 sys sys 1144169677 284304
 386/bin/ip/imap4d - 775 sys sys 1143777810 238051
 386/bin/ip/ipconfig - 775 sys sys 1143777810 138177
 386/bin/ip/ping - 775 sys sys 1143777810 76815
@@ -425,8 +425,8 @@
 386/bin/telnet - 775 sys sys 1143777840 80744
 386/bin/test - 775 sys sys 1143777840 70179
 386/bin/time - 775 sys sys 1143777841 61713
-386/bin/tlsclient - 775 sys sys 1143777841 198846
-386/bin/tlssrv - 775 sys sys 1143777842 199106
+386/bin/tlsclient - 775 sys sys 1144169678 198863
+386/bin/tlssrv - 775 sys sys 1144169678 199123
 386/bin/togif - 775 sys sys 1143777842 190226
 386/bin/toico - 775 sys sys 1143777842 124005
 386/bin/topng - 775 sys sys 1143777843 138675
@@ -557,10 +557,10 @@
 386/lib/libhttpd.a - 664 sys sys 1143777863 99458
 386/lib/libip.a - 664 sys sys 1143777863 35576
 386/lib/libl.a - 664 sys sys 1143777863 5372
-386/lib/libmach.a - 664 sys sys 1143863651 782098
+386/lib/libmach.a - 664 sys sys 1144169680 782440
 386/lib/libmemdraw.a - 664 sys sys 1143777866 284092
 386/lib/libmemlayer.a - 664 sys sys 1143777866 47360
-386/lib/libmp.a - 664 sys sys 1143777866 79974
+386/lib/libmp.a - 664 sys sys 1144169680 79980
 386/lib/libndb.a - 664 sys sys 1143777866 60716
 386/lib/libplumb.a - 664 sys sys 1143777866 19408
 386/lib/libregexp.a - 664 sys sys 1143777866 37438
@@ -6017,7 +6017,7 @@ sys/include/memdraw.h - 664 sys sys 1091904419 5645
 sys/include/memlayer.h - 664 sys sys 1051031022 1851
 sys/include/mouse.h - 664 sys sys 1035232010 1003
 sys/include/mp.h - 664 sys sys 1014929065 4610
-sys/include/ndb.h - 664 sys sys 1091904429 4369
+sys/include/ndb.h - 664 sys sys 1144174492 4412
 sys/include/nfs3.h - 664 sys sys 1045589438 15082
 sys/include/plumb.h - 664 sys sys 1014929065 989
 sys/include/pool.h - 664 sys sys 1102093074 1219
@@ -7700,7 +7700,7 @@ sys/man/8/checkarenas - 664 sys sys 1019866709 669
 sys/man/8/cpurc - 664 sys sys 971455510 1275
 sys/man/8/cron - 664 sys sys 1063858596 1867
 sys/man/8/dhcpd - 664 sys sys 1032654987 5237
-sys/man/8/disksim - 664 sys sys 1141009713 1452
+sys/man/8/disksim - 664 sys sys 1144150487 1476
 sys/man/8/drawterm - 664 sys sys 1135901219 1741
 sys/man/8/fossilcons - 664 sys sys 1138466274 18276
 sys/man/8/fs - 664 sys sys 1055701170 15029
@@ -13457,13 +13457,14 @@ sys/src/cmd/unix/9pfreebsd/mount_9fs/Makefile - 664 sys sys 960684604 412
 sys/src/cmd/unix/9pfreebsd/mount_9fs/crypt.c - 664 sys sys 960684604 18042
 sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.8 - 664 sys sys 960684604 10864
 sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.c - 664 sys sys 960684605 25118
-sys/src/cmd/unix/README - 664 sys sys 1128520385 1735
+sys/src/cmd/unix/README - 664 sys sys 1144150393 1380
 sys/src/cmd/unix/drawterm - 20000000775 sys sys 964488190 0
 sys/src/cmd/unix/drawterm/9ball.ico - 664 sys sys 1135900533 9326
 sys/src/cmd/unix/drawterm/9ball.rc - 664 sys sys 1135900533 39
 sys/src/cmd/unix/drawterm/LICENSE - 664 sys sys 1135900534 12184
 sys/src/cmd/unix/drawterm/Make.config - 664 sys sys 1142177508 40
 sys/src/cmd/unix/drawterm/Make.irix - 664 sys sys 1137502401 493
+sys/src/cmd/unix/drawterm/Make.osx - 664 sys sys 1144150883 426
 sys/src/cmd/unix/drawterm/Make.unix - 664 sys sys 1142177512 453
 sys/src/cmd/unix/drawterm/Make.win32 - 664 sys sys 1141662620 826
 sys/src/cmd/unix/drawterm/Makefile - 664 sys sys 1135900534 1112
@@ -13510,7 +13511,7 @@ sys/src/cmd/unix/drawterm/include/draw.h - 664 sys sys 1135900762 16052
 sys/src/cmd/unix/drawterm/include/dtos.h - 664 sys sys 1135900762 358
 sys/src/cmd/unix/drawterm/include/fcall.h - 664 sys sys 1135900762 2676
 sys/src/cmd/unix/drawterm/include/keyboard.h - 664 sys sys 1135900762 920
-sys/src/cmd/unix/drawterm/include/lib.h - 664 sys sys 1137506302 7467
+sys/src/cmd/unix/drawterm/include/lib.h - 664 sys sys 1144150883 7495
 sys/src/cmd/unix/drawterm/include/libc.h - 664 sys sys 1135900763 36
 sys/src/cmd/unix/drawterm/include/libsec.h - 664 sys sys 1135900763 8861
 sys/src/cmd/unix/drawterm/include/memdraw.h - 664 sys sys 1135900763 6306
@@ -13520,14 +13521,14 @@ sys/src/cmd/unix/drawterm/include/u.h - 664 sys sys 1135900763 336
 sys/src/cmd/unix/drawterm/include/unix.h - 664 sys sys 1137506303 349
 sys/src/cmd/unix/drawterm/include/user.h - 664 sys sys 1135900764 2532
 sys/src/cmd/unix/drawterm/kern - 20000000775 sys sys 1135900801 0
-sys/src/cmd/unix/drawterm/kern/Makefile - 664 sys sys 1142177517 608
+sys/src/cmd/unix/drawterm/kern/Makefile - 664 sys sys 1144150884 620
 sys/src/cmd/unix/drawterm/kern/allocb.c - 664 sys sys 1135900764 3172
 sys/src/cmd/unix/drawterm/kern/cache.c - 664 sys sys 1135900764 466
 sys/src/cmd/unix/drawterm/kern/chan.c - 664 sys sys 1135900764 29593
 sys/src/cmd/unix/drawterm/kern/dat.h - 664 sys sys 1135900765 10716
 sys/src/cmd/unix/drawterm/kern/data.c - 664 sys sys 1135900765 423
 sys/src/cmd/unix/drawterm/kern/dev.c - 664 sys sys 1135900765 8523
-sys/src/cmd/unix/drawterm/kern/devaudio-none.c - 664 sys sys 1142177493 471
+sys/src/cmd/unix/drawterm/kern/devaudio-none.c - 664 sys sys 1144150884 628
 sys/src/cmd/unix/drawterm/kern/devaudio-unix.c - 664 sys sys 1142177493 3064
 sys/src/cmd/unix/drawterm/kern/devaudio.c - 664 sys sys 1142177494 6144
 sys/src/cmd/unix/drawterm/kern/devaudio.h - 664 sys sys 1142177494 328
@@ -13545,7 +13546,8 @@ sys/src/cmd/unix/drawterm/kern/devmouse.c - 664 sys sys 1135900767 3799
 sys/src/cmd/unix/drawterm/kern/devpipe.c - 664 sys sys 1135900767 5927
 sys/src/cmd/unix/drawterm/kern/devroot.c - 664 sys sys 1137502216 4755
 sys/src/cmd/unix/drawterm/kern/devssl.c - 664 sys sys 1135900767 26455
-sys/src/cmd/unix/drawterm/kern/devtab.c - 664 sys sys 1142177519 509
+sys/src/cmd/unix/drawterm/kern/devtab.c - 664 sys sys 1144150884 544
+sys/src/cmd/unix/drawterm/kern/devtls.c - 664 sys sys 1144150884 45295
 sys/src/cmd/unix/drawterm/kern/error.c - 664 sys sys 1135900767 2100
 sys/src/cmd/unix/drawterm/kern/error.h - 664 sys sys 1135900768 2583
 sys/src/cmd/unix/drawterm/kern/exportfs.c - 664 sys sys 1135900768 13444
@@ -13602,7 +13604,7 @@ sys/src/cmd/unix/drawterm/libauthsrv/opasstokey.c - 664 sys sys 1135900562 448
 sys/src/cmd/unix/drawterm/libauthsrv/passtokey.c - 664 sys sys 1135900562 517
 sys/src/cmd/unix/drawterm/libauthsrv/readnvram.c - 664 sys sys 1135900562 8446
 sys/src/cmd/unix/drawterm/libc - 20000000775 sys sys 1135900573 0
-sys/src/cmd/unix/drawterm/libc/Makefile - 664 sys sys 1137502398 1113
+sys/src/cmd/unix/drawterm/libc/Makefile - 664 sys sys 1144150884 1141
 sys/src/cmd/unix/drawterm/libc/charstod.c - 664 sys sys 1137619294 1203
 sys/src/cmd/unix/drawterm/libc/cleanname.c - 664 sys sys 1135900562 1199
 sys/src/cmd/unix/drawterm/libc/convD2M.c - 664 sys sys 1135900562 1398
@@ -13618,6 +13620,7 @@ sys/src/cmd/unix/drawterm/libc/dirstat.c - 664 sys sys 1135900563 688
 sys/src/cmd/unix/drawterm/libc/dirwstat.c - 664 sys sys 1135900564 246
 sys/src/cmd/unix/drawterm/libc/dofmt.c - 664 sys sys 1137619295 9020
 sys/src/cmd/unix/drawterm/libc/dorfmt.c - 664 sys sys 1137619295 791
+sys/src/cmd/unix/drawterm/libc/encodefmt.c - 664 sys sys 1144150884 1100
 sys/src/cmd/unix/drawterm/libc/errfmt.c - 664 sys sys 1135900564 175
 sys/src/cmd/unix/drawterm/libc/fcallfmt.c - 664 sys sys 1135900564 5740
 sys/src/cmd/unix/drawterm/libc/fltfmt.c - 664 sys sys 1137619295 6302
@@ -13647,6 +13650,7 @@ sys/src/cmd/unix/drawterm/libc/nsec.c - 664 sys sys 1135900567 1196
 sys/src/cmd/unix/drawterm/libc/pow10.c - 664 sys sys 1137619298 1195
 sys/src/cmd/unix/drawterm/libc/print.c - 664 sys sys 1137619298 184
 sys/src/cmd/unix/drawterm/libc/pushssl.c - 664 sys sys 1135900567 905
+sys/src/cmd/unix/drawterm/libc/pushtls.c - 664 sys sys 1144150885 2023
 sys/src/cmd/unix/drawterm/libc/rand.c - 664 sys sys 1135900567 79
 sys/src/cmd/unix/drawterm/libc/read9pmsg.c - 664 sys sys 1135900567 462
 sys/src/cmd/unix/drawterm/libc/readn.c - 664 sys sys 1135900568 234
@@ -15214,7 +15218,7 @@ sys/src/libmach/kobj.c - 664 sys sys 1091732625 2217
 sys/src/libmach/machdata.c - 664 sys sys 1131289377 8799
 sys/src/libmach/map.c - 664 sys sys 1131289376 3056
 sys/src/libmach/mips2ureg.h - 664 sys sys 1143821483 886
-sys/src/libmach/mkfile - 664 sys sys 1131375713 479
+sys/src/libmach/mkfile - 664 sys sys 1144151016 482
 sys/src/libmach/obj.c - 664 sys sys 1131289376 5929
 sys/src/libmach/obj.h - 664 sys sys 1131292890 604
 sys/src/libmach/q.c - 664 sys sys 1131289379 3630
@@ -15231,7 +15235,7 @@ sys/src/libmach/udb.c - 664 sys sys 1136322404 21967
 sys/src/libmach/uobj.c - 664 sys sys 1114459831 2219
 sys/src/libmach/v.c - 664 sys sys 1131289378 3446
 sys/src/libmach/vcodas.c - 664 sys sys 1136329351 10293
-sys/src/libmach/vdb.c - 664 sys sys 1136329351 22299
+sys/src/libmach/vdb.c - 664 sys sys 1144151030 22870
 sys/src/libmach/vobj.c - 664 sys sys 1091732625 2206
 sys/src/libmemdraw - 20000000775 sys sys 985020762 0
 sys/src/libmemdraw/alloc.c - 664 sys sys 1135895512 3334
@@ -15284,7 +15288,7 @@ sys/src/libmp/386/mkfile - 664 sys sys 1032061348 287
 sys/src/libmp/386/mpdigdiv.s - 664 sys sys 944961744 352
 sys/src/libmp/386/mpvecadd.s - 664 sys sys 944961744 906
 sys/src/libmp/386/mpvecdigmuladd.s - 664 sys sys 964712439 1063
-sys/src/libmp/386/mpvecdigmulsub.s - 664 sys sys 953344710 971
+sys/src/libmp/386/mpvecdigmulsub.s - 664 sys sys 1144150976 982
 sys/src/libmp/386/mpvecsub.s - 664 sys sys 944961744 767
 sys/src/libmp/alpha - 20000000775 sys sys 944961745 0
 sys/src/libmp/alpha/mkfile - 664 sys sys 1032061349 180
@@ -15345,27 +15349,27 @@ sys/src/libmp/power/mpvecsub.s - 664 sys sys 950104732 1118
 sys/src/libmp/power/placeholder.c - 664 sys sys 944961747 0
 sys/src/libmp/test.c - 664 sys sys 964798440 12260
 sys/src/libndb - 20000000775 sys sys 1015013466 0
-sys/src/libndb/csgetval.c - 664 sys sys 1078839927 1752
-sys/src/libndb/csipinfo.c - 664 sys sys 1069206439 1175
-sys/src/libndb/dnsquery.c - 664 sys sys 1078618597 2840
+sys/src/libndb/csgetval.c - 664 sys sys 1144174488 1796
+sys/src/libndb/csipinfo.c - 664 sys sys 1144174488 1178
+sys/src/libndb/dnsquery.c - 664 sys sys 1144174488 2883
 sys/src/libndb/ipattr.c - 664 sys sys 953844690 586
 sys/src/libndb/mkfile - 664 sys sys 1078618596 513
-sys/src/libndb/ndbaux.c - 664 sys sys 1078929180 1504
-sys/src/libndb/ndbcache.c - 664 sys sys 1078618597 2164
+sys/src/libndb/ndbaux.c - 664 sys sys 1144174488 1544
+sys/src/libndb/ndbcache.c - 664 sys sys 1144174488 2246
 sys/src/libndb/ndbcat.c - 664 sys sys 950311789 224
-sys/src/libndb/ndbconcatenate.c - 664 sys sys 1078618598 259
-sys/src/libndb/ndbdiscard.c - 664 sys sys 1078618598 436
-sys/src/libndb/ndbfree.c - 664 sys sys 1078618598 952
-sys/src/libndb/ndbgetipaddr.c - 664 sys sys 1078839928 792
-sys/src/libndb/ndbgetval.c - 664 sys sys 1078839928 1309
-sys/src/libndb/ndbhash.c - 664 sys sys 1069206440 4973
+sys/src/libndb/ndbconcatenate.c - 664 sys sys 1144174489 297
+sys/src/libndb/ndbdiscard.c - 664 sys sys 1144174489 474
+sys/src/libndb/ndbfree.c - 664 sys sys 1144174489 1123
+sys/src/libndb/ndbgetipaddr.c - 664 sys sys 1144174489 876
+sys/src/libndb/ndbgetval.c - 664 sys sys 1144174490 1348
+sys/src/libndb/ndbhash.c - 664 sys sys 1144174490 5276
 sys/src/libndb/ndbhf.h - 664 sys sys 1015013485 746
-sys/src/libndb/ndbipinfo.c - 664 sys sys 1078927860 4929
+sys/src/libndb/ndbipinfo.c - 664 sys sys 1144174490 5105
 sys/src/libndb/ndblookval.c - 664 sys sys 1078839929 791
 sys/src/libndb/ndbopen.c - 664 sys sys 1069206441 2716
-sys/src/libndb/ndbparse.c - 664 sys sys 1069206440 1167
+sys/src/libndb/ndbparse.c - 664 sys sys 1144174490 1207
 sys/src/libndb/ndbreorder.c - 664 sys sys 1078618600 966
-sys/src/libndb/ndbsubstitute.c - 664 sys sys 1078618600 692
+sys/src/libndb/ndbsubstitute.c - 664 sys sys 1144174491 867
 sys/src/libplumb - 20000000775 sys sys 1014928082 0
 sys/src/libplumb/event.c - 664 sys sys 947358887 1861
 sys/src/libplumb/mesg.c - 664 sys sys 1133279518 7080

+ 49 - 0
dist/replica/plan9.log

@@ -29233,3 +29233,52 @@
 1143948659 0 a sys/src/cmd/upas/fs/rfc2047-test - 664 sys sys 1143946985 1146
 1143950460 0 c 386/bin/aux/vga - 775 sys sys 1143950134 334335
 1143981068 0 c rc/bin/iwhois - 775 sys sys 1143979502 1637
+1144152012 0 c sys/man/8/disksim - 664 sys sys 1144150487 1476
+1144152012 1 c sys/src/cmd/unix/README - 664 sys sys 1144150393 1380
+1144152012 2 a sys/src/cmd/unix/drawterm/Make.osx - 664 sys sys 1144150883 426
+1144152012 3 c sys/src/cmd/unix/drawterm/include/lib.h - 664 sys sys 1144150883 7495
+1144152012 4 c sys/src/cmd/unix/drawterm/kern/Makefile - 664 sys sys 1144150884 620
+1144152012 5 c sys/src/cmd/unix/drawterm/kern/devaudio-none.c - 664 sys sys 1144150884 628
+1144152012 6 c sys/src/cmd/unix/drawterm/kern/devtab.c - 664 sys sys 1144150884 544
+1144152012 7 a sys/src/cmd/unix/drawterm/kern/devtls.c - 664 sys sys 1144150884 45295
+1144152012 8 c sys/src/cmd/unix/drawterm/libc/Makefile - 664 sys sys 1144150884 1141
+1144152012 9 a sys/src/cmd/unix/drawterm/libc/encodefmt.c - 664 sys sys 1144150884 1100
+1144152012 10 a sys/src/cmd/unix/drawterm/libc/pushtls.c - 664 sys sys 1144150885 2023
+1144152012 11 c sys/src/libmach/mkfile - 664 sys sys 1144151016 482
+1144152012 12 c sys/src/libmach/vdb.c - 664 sys sys 1144151030 22870
+1144152012 13 c sys/src/libmp/386/mpvecdigmulsub.s - 664 sys sys 1144150976 982
+1144170021 0 c 386/bin/hget - 775 sys sys 1144169675 233866
+1144170021 1 c 386/bin/ftpfs - 775 sys sys 1144169673 273204
+1144170021 2 c 386/bin/auth/asn12rsa - 775 sys sys 1144169660 120818
+1144170021 3 c 386/bin/auth/factotum - 775 sys sys 1144169660 321860
+1144170021 4 c 386/bin/auth/rsa2csr - 775 sys sys 1144169661 180973
+1144170021 5 c 386/bin/auth/rsa2pub - 775 sys sys 1144169662 144000
+1144170021 6 c 386/bin/auth/rsa2ssh - 775 sys sys 1144169663 139317
+1144170021 7 c 386/bin/auth/rsa2x509 - 775 sys sys 1144169665 184736
+1144170021 8 c 386/bin/auth/rsafill - 775 sys sys 1144169666 144068
+1144170021 9 c 386/bin/auth/rsagen - 775 sys sys 1144169667 153628
+1144170021 10 c 386/bin/auth/secstore - 775 sys sys 1144169668 195944
+1144170021 11 c 386/bin/auth/secstored - 775 sys sys 1144169670 197387
+1144170021 12 c 386/bin/auth/secuser - 775 sys sys 1144169671 153317
+1144170021 13 c 386/bin/aux/timesync - 775 sys sys 1144169672 128740
+1144170021 14 c 386/bin/ip/httpd/httpd - 775 sys sys 1144169676 294972
+1144170021 15 c 386/bin/ip/httpfile - 775 sys sys 1144169677 284304
+1144170021 16 c 386/bin/tlsclient - 775 sys sys 1144169678 198863
+1144170021 17 c 386/bin/tlssrv - 775 sys sys 1144169678 199123
+1144170021 18 c 386/lib/libmach.a - 664 sys sys 1144169680 782440
+1144170021 19 c 386/lib/libmp.a - 664 sys sys 1144169680 79980
+1144175424 0 c sys/include/ndb.h - 664 sys sys 1144174492 4412
+1144175424 1 c sys/src/libndb/csgetval.c - 664 sys sys 1144174488 1796
+1144175424 2 c sys/src/libndb/csipinfo.c - 664 sys sys 1144174488 1178
+1144175424 3 c sys/src/libndb/dnsquery.c - 664 sys sys 1144174488 2883
+1144175424 4 c sys/src/libndb/ndbaux.c - 664 sys sys 1144174488 1544
+1144175424 5 c sys/src/libndb/ndbcache.c - 664 sys sys 1144174488 2246
+1144175424 6 c sys/src/libndb/ndbconcatenate.c - 664 sys sys 1144174489 297
+1144175424 7 c sys/src/libndb/ndbdiscard.c - 664 sys sys 1144174489 474
+1144175424 8 c sys/src/libndb/ndbfree.c - 664 sys sys 1144174489 1123
+1144175424 9 c sys/src/libndb/ndbgetipaddr.c - 664 sys sys 1144174489 876
+1144175424 10 c sys/src/libndb/ndbgetval.c - 664 sys sys 1144174490 1348
+1144175424 11 c sys/src/libndb/ndbhash.c - 664 sys sys 1144174490 5276
+1144175424 12 c sys/src/libndb/ndbipinfo.c - 664 sys sys 1144174490 5105
+1144175424 13 c sys/src/libndb/ndbparse.c - 664 sys sys 1144174490 1207
+1144175424 14 c sys/src/libndb/ndbsubstitute.c - 664 sys sys 1144174491 867

+ 1 - 0
sys/include/ndb.h

@@ -152,3 +152,4 @@ long		ndbseek(Ndb*, long);
 void		ndbsetval(Ndbtuple*, char*, int);
 Ndbtuple*	ndbsnext(Ndbs*, char*, char*);
 Ndbtuple*	ndbsubstitute(Ndbtuple*, Ndbtuple*, Ndbtuple*);
+void		ndbsetmalloctag(Ndbtuple*, uintptr);

+ 1 - 0
sys/man/8/disksim

@@ -64,6 +64,7 @@ disks:
 .EX
 aux/disksim
 echo geometry 40000 512 0 0 0 >/dev/sdXX/ctl # 20MB
+disk/mbr /dev/sdXX/data
 disk/fdisk -baw /dev/sdXX/data
 disk/prep /dev/sdXX/plan9
 .EE

+ 2 - 10
sys/src/cmd/unix/README

@@ -9,16 +9,8 @@ help Plan 9 co-exist with the non-Plan 9 world.
 	drawterm/
 		Drawterm is a Unix and Windows program that simulates
 		a Plan 9 terminal to connect to a Plan 9 cpu server.
-		The version in this directory speaks the pre-9P2000 
-		protocols.  
-
-		A new 9P2000 version is in progress but still crashes
-		with some regularity on Unix.  It can be found at
-		  http://cvs.pdos.csail.mit.edu/cvs/drawterm/
-		or use
-		  cvs -d :pserver:anoncvs@cvs.pdos.csail.mit.edu:/cvs co drawterm
-		For more information about CVS, see
-		  http://swtch.com/plan9port/man/man1/cvs.html
+
+		See drawterm/README for details.
 
 	u9fs/
 		U9fs is a simple 9P server that runs on Unix.

+ 21 - 0
sys/src/cmd/unix/drawterm/Make.osx

@@ -0,0 +1,21 @@
+# Mac OS X
+PTHREAD=	# for Mac
+AR=ar
+AS=as
+RANLIB=ranlib
+X11=/usr/X11R6
+CC=gcc
+CFLAGS=-Wall -Wno-missing-braces -ggdb -I$(ROOT) -I$(ROOT)/include -I$(ROOT)/kern -c -I$(X11)/include -D_THREAD_SAFE $(PTHREAD) -O2
+O=o
+OS=posix
+GUI=x11
+LDADD=-L$(X11)/lib -lX11 -ggdb
+LDFLAGS=$(PTHREAD)
+TARG=drawterm
+AUDIO=none
+
+all: default
+
+libmachdep.a:
+	arch=`uname -m|sed 's/i.86/386/;s/Power Macintosh/power/'`; \
+	(cd posix-$$arch &&  make)

+ 1 - 0
sys/src/cmd/unix/drawterm/include/lib.h

@@ -230,6 +230,7 @@ extern	int	fmtinstall(int, int (*)(Fmt*));
 extern	char*	fmtstrflush(Fmt*);
 extern	int	runefmtstrinit(Fmt*);
 extern	Rune*	runefmtstrflush(Fmt*);
+extern	int	encodefmt(Fmt*);
 extern	int	fmtstrcpy(Fmt*, char*);
 extern	int	fmtprint(Fmt*, char*, ...);
 extern	int	fmtvprint(Fmt*, char*, va_list);

+ 1 - 0
sys/src/cmd/unix/drawterm/kern/Makefile

@@ -21,6 +21,7 @@ OFILES=\
 	devpipe.$O\
 	devroot.$O\
 	devssl.$O\
+	devtls.$O\
 	devtab.$O\
 	error.$O\
 	parse.$O\

+ 14 - 0
sys/src/cmd/unix/drawterm/kern/devaudio-none.c

@@ -21,6 +21,20 @@ audiodevclose(void)
 	error("no audio support");
 }
 
+int
+audiodevread(void *a, int n)
+{
+	error("no audio support");
+	return -1;
+}
+
+int
+audiodevwrite(void *a, int n)
+{
+	error("no audio support");
+	return -1;
+}
+
 void
 audiodevsetvol(int what, int left, int right)
 {

+ 2 - 0
sys/src/cmd/unix/drawterm/kern/devtab.c

@@ -8,6 +8,7 @@ extern Dev consdevtab;
 extern Dev rootdevtab;
 extern Dev pipedevtab;
 extern Dev ssldevtab;
+extern Dev tlsdevtab;
 extern Dev mousedevtab;
 extern Dev drawdevtab;
 extern Dev ipdevtab;
@@ -21,6 +22,7 @@ Dev *devtab[] = {
 	&consdevtab,
 	&pipedevtab,
 	&ssldevtab,
+	&tlsdevtab,
 	&mousedevtab,
 	&drawdevtab,
 	&ipdevtab,

+ 2179 - 0
sys/src/cmd/unix/drawterm/kern/devtls.c

@@ -0,0 +1,2179 @@
+/*
+ *  devtls - record layer for transport layer security 1.0 and secure sockets layer 3.0
+ */
+#include	"u.h"
+#include	"lib.h"
+#include	"dat.h"
+#include	"fns.h"
+#include	"error.h"
+
+#include	"libsec.h"
+
+typedef struct OneWay	OneWay;
+typedef struct Secret		Secret;
+typedef struct TlsRec	TlsRec;
+typedef struct TlsErrs	TlsErrs;
+
+enum {
+	Statlen=	1024,		/* max. length of status or stats message */
+	/* buffer limits */
+	MaxRecLen		= 1<<14,	/* max payload length of a record layer message */
+	MaxCipherRecLen	= MaxRecLen + 2048,
+	RecHdrLen		= 5,
+	MaxMacLen		= SHA1dlen,
+
+	/* protocol versions we can accept */
+	TLSVersion		= 0x0301,
+	SSL3Version		= 0x0300,
+	ProtocolVersion	= 0x0301,	/* maximum version we speak */
+	MinProtoVersion	= 0x0300,	/* limits on version we accept */
+	MaxProtoVersion	= 0x03ff,
+
+	/* connection states */
+	SHandshake	= 1 << 0,	/* doing handshake */
+	SOpen		= 1 << 1,	/* application data can be sent */
+	SRClose		= 1 << 2,	/* remote side has closed down */
+	SLClose		= 1 << 3,	/* sent a close notify alert */
+	SAlert		= 1 << 5,	/* sending or sent a fatal alert */
+	SError		= 1 << 6,	/* some sort of error has occured */
+	SClosed		= 1 << 7,	/* it is all over */
+
+	/* record types */
+	RChangeCipherSpec = 20,
+	RAlert,
+	RHandshake,
+	RApplication,
+
+	SSL2ClientHello = 1,
+	HSSL2ClientHello = 9,  /* local convention;  see tlshand.c */
+
+	/* alerts */
+	ECloseNotify 			= 0,
+	EUnexpectedMessage 	= 10,
+	EBadRecordMac 		= 20,
+	EDecryptionFailed 		= 21,
+	ERecordOverflow 		= 22,
+	EDecompressionFailure 	= 30,
+	EHandshakeFailure 		= 40,
+	ENoCertificate 			= 41,
+	EBadCertificate 		= 42,
+	EUnsupportedCertificate 	= 43,
+	ECertificateRevoked 		= 44,
+	ECertificateExpired 		= 45,
+	ECertificateUnknown 	= 46,
+	EIllegalParameter 		= 47,
+	EUnknownCa 			= 48,
+	EAccessDenied 		= 49,
+	EDecodeError 			= 50,
+	EDecryptError 			= 51,
+	EExportRestriction 		= 60,
+	EProtocolVersion 		= 70,
+	EInsufficientSecurity 	= 71,
+	EInternalError 			= 80,
+	EUserCanceled 			= 90,
+	ENoRenegotiation 		= 100,
+
+	EMAX = 256
+};
+
+struct Secret
+{
+	char		*encalg;	/* name of encryption alg */
+	char		*hashalg;	/* name of hash alg */
+	int		(*enc)(Secret*, uchar*, int);
+	int		(*dec)(Secret*, uchar*, int);
+	int		(*unpad)(uchar*, int, int);
+	DigestState	*(*mac)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
+	int		block;		/* encryption block len, 0 if none */
+	int		maclen;
+	void		*enckey;
+	uchar	mackey[MaxMacLen];
+};
+
+struct OneWay
+{
+	QLock		io;		/* locks io access */
+	QLock		seclock;	/* locks secret paramaters */
+	ulong		seq;
+	Secret		*sec;		/* cipher in use */
+	Secret		*new;		/* cipher waiting for enable */
+};
+
+struct TlsRec
+{
+	Chan	*c;				/* io channel */
+	int		ref;				/* serialized by tdlock for atomic destroy */
+	int		version;			/* version of the protocol we are speaking */
+	char		verset;			/* version has been set */
+	char		opened;			/* opened command every issued? */
+	char		err[ERRMAX];		/* error message to return to handshake requests */
+	vlong	handin;			/* bytes communicated by the record layer */
+	vlong	handout;
+	vlong	datain;
+	vlong	dataout;
+
+	Lock		statelk;
+	int		state;
+	int		debug;
+
+	/* record layer mac functions for different protocol versions */
+	void		(*packMac)(Secret*, uchar*, uchar*, uchar*, uchar*, int, uchar*);
+
+	/* input side -- protected by in.io */
+	OneWay		in;
+	Block		*processed;	/* next bunch of application data */
+	Block		*unprocessed;	/* data read from c but not parsed into records */
+
+	/* handshake queue */
+	Lock		hqlock;			/* protects hqref, alloc & free of handq, hprocessed */
+	int		hqref;
+	Queue		*handq;		/* queue of handshake messages */
+	Block		*hprocessed;	/* remainder of last block read from handq */
+	QLock		hqread;		/* protects reads for hprocessed, handq */
+
+	/* output side */
+	OneWay		out;
+
+	/* protections */
+	char		*user;
+	int		perm;
+};
+
+struct TlsErrs{
+	int	err;
+	int	sslerr;
+	int	tlserr;
+	int	fatal;
+	char	*msg;
+};
+
+static TlsErrs tlserrs[] = {
+	{ECloseNotify,			ECloseNotify,			ECloseNotify,			0, 	"close notify"},
+	{EUnexpectedMessage,	EUnexpectedMessage,	EUnexpectedMessage, 	1, "unexpected message"},
+	{EBadRecordMac,		EBadRecordMac,		EBadRecordMac, 		1, "bad record mac"},
+	{EDecryptionFailed,		EIllegalParameter,		EDecryptionFailed,		1, "decryption failed"},
+	{ERecordOverflow,		EIllegalParameter,		ERecordOverflow,		1, "record too long"},
+	{EDecompressionFailure,	EDecompressionFailure,	EDecompressionFailure,	1, "decompression failed"},
+	{EHandshakeFailure,		EHandshakeFailure,		EHandshakeFailure,		1, "could not negotiate acceptable security parameters"},
+	{ENoCertificate,		ENoCertificate,			ECertificateUnknown,	1, "no appropriate certificate available"},
+	{EBadCertificate,		EBadCertificate,		EBadCertificate,		1, "corrupted or invalid certificate"},
+	{EUnsupportedCertificate,	EUnsupportedCertificate,	EUnsupportedCertificate,	1, "unsupported certificate type"},
+	{ECertificateRevoked,	ECertificateRevoked,		ECertificateRevoked,		1, "revoked certificate"},
+	{ECertificateExpired,		ECertificateExpired,		ECertificateExpired,		1, "expired certificate"},
+	{ECertificateUnknown,	ECertificateUnknown,	ECertificateUnknown,	1, "unacceptable certificate"},
+	{EIllegalParameter,		EIllegalParameter,		EIllegalParameter,		1, "illegal parameter"},
+	{EUnknownCa,			EHandshakeFailure,		EUnknownCa,			1, "unknown certificate authority"},
+	{EAccessDenied,		EHandshakeFailure,		EAccessDenied,		1, "access denied"},
+	{EDecodeError,			EIllegalParameter,		EDecodeError,			1, "error decoding message"},
+	{EDecryptError,			EIllegalParameter,		EDecryptError,			1, "error decrypting message"},
+	{EExportRestriction,		EHandshakeFailure,		EExportRestriction,		1, "export restriction violated"},
+	{EProtocolVersion,		EIllegalParameter,		EProtocolVersion,		1, "protocol version not supported"},
+	{EInsufficientSecurity,	EHandshakeFailure,		EInsufficientSecurity,	1, "stronger security routines required"},
+	{EInternalError,			EHandshakeFailure,		EInternalError,			1, "internal error"},
+	{EUserCanceled,		ECloseNotify,			EUserCanceled,			0, "handshake canceled by user"},
+	{ENoRenegotiation,		EUnexpectedMessage,	ENoRenegotiation,		0, "no renegotiation"},
+};
+
+enum
+{
+	/* max. open tls connections */
+	MaxTlsDevs	= 1024
+};
+
+static	Lock	tdlock;
+static	int	tdhiwat;
+static	int	maxtlsdevs = 128;
+static	TlsRec	**tlsdevs;
+static	char	**trnames;
+static	char	*encalgs;
+static	char	*hashalgs;
+
+enum{
+	Qtopdir		= 1,	/* top level directory */
+	Qprotodir,
+	Qclonus,
+	Qencalgs,
+	Qhashalgs,
+	Qconvdir,		/* directory for a conversation */
+	Qdata,
+	Qctl,
+	Qhand,
+	Qstatus,
+	Qstats,
+};
+
+#define TYPE(x) 	((x).path & 0xf)
+#define CONV(x) 	(((x).path >> 5)&(MaxTlsDevs-1))
+#define QID(c, y) 	(((c)<<5) | (y))
+
+static void	checkstate(TlsRec *, int, int);
+static void	ensure(TlsRec*, Block**, int);
+static void	consume(Block**, uchar*, int);
+static Chan*	buftochan(char*);
+static void	tlshangup(TlsRec*);
+static void	tlsError(TlsRec*, char *);
+static void	alertHand(TlsRec*, char *);
+static TlsRec	*newtls(Chan *c);
+static TlsRec	*mktlsrec(void);
+static DigestState*sslmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
+static DigestState*sslmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
+static DigestState*nomac(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
+static void	sslPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac);
+static void	tlsPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac);
+static void	put64(uchar *p, vlong x);
+static void	put32(uchar *p, u32int);
+static void	put24(uchar *p, int);
+static void	put16(uchar *p, int);
+static u32int	get32(uchar *p);
+static int	get16(uchar *p);
+static void	tlsSetState(TlsRec *tr, int new, int old);
+static void	rcvAlert(TlsRec *tr, int err);
+static void	sendAlert(TlsRec *tr, int err);
+static void	rcvError(TlsRec *tr, int err, char *msg, ...);
+static int	rc4enc(Secret *sec, uchar *buf, int n);
+static int	des3enc(Secret *sec, uchar *buf, int n);
+static int	des3dec(Secret *sec, uchar *buf, int n);
+static int	noenc(Secret *sec, uchar *buf, int n);
+static int	sslunpad(uchar *buf, int n, int block);
+static int	tlsunpad(uchar *buf, int n, int block);
+static void	freeSec(Secret *sec);
+static char	*tlsstate(int s);
+static void	pdump(int, void*, char*);
+
+static char *tlsnames[] = {
+[Qclonus]		"clone",
+[Qencalgs]	"encalgs",
+[Qhashalgs]	"hashalgs",
+[Qdata]		"data",
+[Qctl]		"ctl",
+[Qhand]		"hand",
+[Qstatus]		"status",
+[Qstats]		"stats",
+};
+
+static int convdir[] = { Qctl, Qdata, Qhand, Qstatus, Qstats };
+
+static int
+tlsgen(Chan *c, char*unused1, Dirtab *unused2, int unused3, int s, Dir *dp)
+{
+	Qid q;
+	TlsRec *tr;
+	char *name, *nm;
+	int perm, t;
+
+	q.vers = 0;
+	q.type = QTFILE;
+
+	t = TYPE(c->qid);
+	switch(t) {
+	case Qtopdir:
+		if(s == DEVDOTDOT){
+			q.path = QID(0, Qtopdir);
+			q.type = QTDIR;
+			devdir(c, q, "#a", 0, eve, 0555, dp);
+			return 1;
+		}
+		if(s > 0)
+			return -1;
+		q.path = QID(0, Qprotodir);
+		q.type = QTDIR;
+		devdir(c, q, "tls", 0, eve, 0555, dp);
+		return 1;
+	case Qprotodir:
+		if(s == DEVDOTDOT){
+			q.path = QID(0, Qtopdir);
+			q.type = QTDIR;
+			devdir(c, q, ".", 0, eve, 0555, dp);
+			return 1;
+		}
+		if(s < 3){
+			switch(s) {
+			default:
+				return -1;
+			case 0:
+				q.path = QID(0, Qclonus);
+				break;
+			case 1:
+				q.path = QID(0, Qencalgs);
+				break;
+			case 2:
+				q.path = QID(0, Qhashalgs);
+				break;
+			}
+			perm = 0444;
+			if(TYPE(q) == Qclonus)
+				perm = 0555;
+			devdir(c, q, tlsnames[TYPE(q)], 0, eve, perm, dp);
+			return 1;
+		}
+		s -= 3;
+		if(s >= tdhiwat)
+			return -1;
+		q.path = QID(s, Qconvdir);
+		q.type = QTDIR;
+		lock(&tdlock);
+		tr = tlsdevs[s];
+		if(tr != nil)
+			nm = tr->user;
+		else
+			nm = eve;
+		if((name = trnames[s]) == nil){
+			name = trnames[s] = smalloc(16);
+			sprint(name, "%d", s);
+		}
+		devdir(c, q, name, 0, nm, 0555, dp);
+		unlock(&tdlock);
+		return 1;
+	case Qconvdir:
+		if(s == DEVDOTDOT){
+			q.path = QID(0, Qprotodir);
+			q.type = QTDIR;
+			devdir(c, q, "tls", 0, eve, 0555, dp);
+			return 1;
+		}
+		if(s < 0 || s >= nelem(convdir))
+			return -1;
+		lock(&tdlock);
+		tr = tlsdevs[CONV(c->qid)];
+		if(tr != nil){
+			nm = tr->user;
+			perm = tr->perm;
+		}else{
+			perm = 0;
+			nm = eve;
+		}
+		t = convdir[s];
+		if(t == Qstatus || t == Qstats)
+			perm &= 0444;
+		q.path = QID(CONV(c->qid), t);
+		devdir(c, q, tlsnames[t], 0, nm, perm, dp);
+		unlock(&tdlock);
+		return 1;
+	case Qclonus:
+	case Qencalgs:
+	case Qhashalgs:
+		perm = 0444;
+		if(t == Qclonus)
+			perm = 0555;
+		devdir(c, c->qid, tlsnames[t], 0, eve, perm, dp);
+		return 1;
+	default:
+		lock(&tdlock);
+		tr = tlsdevs[CONV(c->qid)];
+		if(tr != nil){
+			nm = tr->user;
+			perm = tr->perm;
+		}else{
+			perm = 0;
+			nm = eve;
+		}
+		if(t == Qstatus || t == Qstats)
+			perm &= 0444;
+		devdir(c, c->qid, tlsnames[t], 0, nm, perm, dp);
+		unlock(&tdlock);
+		return 1;
+	}
+	return -1;
+}
+
+static Chan*
+tlsattach(char *spec)
+{
+	Chan *c;
+
+	c = devattach('a', spec);
+	c->qid.path = QID(0, Qtopdir);
+	c->qid.type = QTDIR;
+	c->qid.vers = 0;
+	return c;
+}
+
+static Walkqid*
+tlswalk(Chan *c, Chan *nc, char **name, int nname)
+{
+	return devwalk(c, nc, name, nname, nil, 0, tlsgen);
+}
+
+static int
+tlsstat(Chan *c, uchar *db, int n)
+{
+	return devstat(c, db, n, nil, 0, tlsgen);
+}
+
+static Chan*
+tlsopen(Chan *c, int omode)
+{
+	TlsRec *tr, **pp;
+	int t, perm;
+
+	perm = 0;
+	omode &= 3;
+	switch(omode) {
+	case OREAD:
+		perm = 4;
+		break;
+	case OWRITE:
+		perm = 2;
+		break;
+	case ORDWR:
+		perm = 6;
+		break;
+	}
+
+	t = TYPE(c->qid);
+	switch(t) {
+	default:
+		panic("tlsopen");
+	case Qtopdir:
+	case Qprotodir:
+	case Qconvdir:
+		if(omode != OREAD)
+			error(Eperm);
+		break;
+	case Qclonus:
+		tr = newtls(c);
+		if(tr == nil)
+			error(Enodev);
+		break;
+	case Qctl:
+	case Qdata:
+	case Qhand:
+	case Qstatus:
+	case Qstats:
+		if((t == Qstatus || t == Qstats) && omode != OREAD)
+			error(Eperm);
+		if(waserror()) {
+			unlock(&tdlock);
+			nexterror();
+		}
+		lock(&tdlock);
+		pp = &tlsdevs[CONV(c->qid)];
+		tr = *pp;
+		if(tr == nil)
+			error("must open connection using clone");
+		if((perm & (tr->perm>>6)) != perm
+		&& (strcmp(up->user, tr->user) != 0
+		    || (perm & tr->perm) != perm))
+			error(Eperm);
+		if(t == Qhand){
+			if(waserror()){
+				unlock(&tr->hqlock);
+				nexterror();
+			}
+			lock(&tr->hqlock);
+			if(tr->handq != nil)
+				error(Einuse);
+			tr->handq = qopen(2 * MaxCipherRecLen, 0, nil, nil);
+			if(tr->handq == nil)
+				error("cannot allocate handshake queue");
+			tr->hqref = 1;
+			unlock(&tr->hqlock);
+			poperror();
+		}
+		tr->ref++;
+		unlock(&tdlock);
+		poperror();
+		break;
+	case Qencalgs:
+	case Qhashalgs:
+		if(omode != OREAD)
+			error(Eperm);
+		break;
+	}
+	c->mode = openmode(omode);
+	c->flag |= COPEN;
+	c->offset = 0;
+	c->iounit = qiomaxatomic;
+	return c;
+}
+
+static int
+tlswstat(Chan *c, uchar *dp, int n)
+{
+	Dir *d;
+	TlsRec *tr;
+	int rv;
+
+	d = nil;
+	if(waserror()){
+		free(d);
+		unlock(&tdlock);
+		nexterror();
+	}
+
+	lock(&tdlock);
+	tr = tlsdevs[CONV(c->qid)];
+	if(tr == nil)
+		error(Ebadusefd);
+	if(strcmp(tr->user, up->user) != 0)
+		error(Eperm);
+
+	d = smalloc(n + sizeof *d);
+	rv = convM2D(dp, n, &d[0], (char*) &d[1]);
+	if(rv == 0)
+		error(Eshortstat);
+	if(!emptystr(d->uid))
+		kstrdup(&tr->user, d->uid);
+	if(d->mode != ~0UL)
+		tr->perm = d->mode;
+
+	free(d);
+	poperror();
+	unlock(&tdlock);
+
+	return rv;
+}
+
+static void
+dechandq(TlsRec *tr)
+{
+	lock(&tr->hqlock);
+	if(--tr->hqref == 0){
+		if(tr->handq != nil){
+			qfree(tr->handq);
+			tr->handq = nil;
+		}
+		if(tr->hprocessed != nil){
+			freeb(tr->hprocessed);
+			tr->hprocessed = nil;
+		}
+	}
+	unlock(&tr->hqlock);
+}
+
+static void
+tlsclose(Chan *c)
+{
+	TlsRec *tr;
+	int t;
+
+	t = TYPE(c->qid);
+	switch(t) {
+	case Qctl:
+	case Qdata:
+	case Qhand:
+	case Qstatus:
+	case Qstats:
+		if((c->flag & COPEN) == 0)
+			break;
+
+		tr = tlsdevs[CONV(c->qid)];
+		if(tr == nil)
+			break;
+
+		if(t == Qhand)
+			dechandq(tr);
+
+		lock(&tdlock);
+		if(--tr->ref > 0) {
+			unlock(&tdlock);
+			return;
+		}
+		tlsdevs[CONV(c->qid)] = nil;
+		unlock(&tdlock);
+
+		if(tr->c != nil && !waserror()){
+			checkstate(tr, 0, SOpen|SHandshake|SRClose);
+			sendAlert(tr, ECloseNotify);
+			poperror();
+		}
+		tlshangup(tr);
+		if(tr->c != nil)
+			cclose(tr->c);
+		freeSec(tr->in.sec);
+		freeSec(tr->in.new);
+		freeSec(tr->out.sec);
+		freeSec(tr->out.new);
+		free(tr->user);
+		free(tr);
+		break;
+	}
+}
+
+/*
+ *  make sure we have at least 'n' bytes in list 'l'
+ */
+static void
+ensure(TlsRec *s, Block **l, int n)
+{
+	int sofar, i;
+	Block *b, *bl;
+
+	sofar = 0;
+	for(b = *l; b; b = b->next){
+		sofar += BLEN(b);
+		if(sofar >= n)
+			return;
+		l = &b->next;
+	}
+
+	while(sofar < n){
+		bl = devtab[s->c->type]->bread(s->c, MaxCipherRecLen + RecHdrLen, 0);
+		if(bl == 0)
+			error(Ehungup);
+		*l = bl;
+		i = 0;
+		for(b = bl; b; b = b->next){
+			i += BLEN(b);
+			l = &b->next;
+		}
+		if(i == 0)
+			error(Ehungup);
+		sofar += i;
+	}
+if(s->debug) pprint("ensure read %d\n", sofar);
+}
+
+/*
+ *  copy 'n' bytes from 'l' into 'p' and free
+ *  the bytes in 'l'
+ */
+static void
+consume(Block **l, uchar *p, int n)
+{
+	Block *b;
+	int i;
+
+	for(; *l && n > 0; n -= i){
+		b = *l;
+		i = BLEN(b);
+		if(i > n)
+			i = n;
+		memmove(p, b->rp, i);
+		b->rp += i;
+		p += i;
+		if(BLEN(b) < 0)
+			panic("consume");
+		if(BLEN(b))
+			break;
+		*l = b->next;
+		freeb(b);
+	}
+}
+
+/*
+ *  give back n bytes
+ */
+static void
+regurgitate(TlsRec *s, uchar *p, int n)
+{
+	Block *b;
+
+	if(n <= 0)
+		return;
+	b = s->unprocessed;
+	if(s->unprocessed == nil || b->rp - b->base < n) {
+		b = allocb(n);
+		memmove(b->wp, p, n);
+		b->wp += n;
+		b->next = s->unprocessed;
+		s->unprocessed = b;
+	} else {
+		b->rp -= n;
+		memmove(b->rp, p, n);
+	}
+}
+
+/*
+ *  remove at most n bytes from the queue
+ */
+static Block*
+qgrab(Block **l, int n)
+{
+	Block *bb, *b;
+	int i;
+
+	b = *l;
+	if(BLEN(b) == n){
+		*l = b->next;
+		b->next = nil;
+		return b;
+	}
+
+	i = 0;
+	for(bb = b; bb != nil && i < n; bb = bb->next)
+		i += BLEN(bb);
+	if(i > n)
+		i = n;
+
+	bb = allocb(i);
+	consume(l, bb->wp, i);
+	bb->wp += i;
+	return bb;
+}
+
+static void
+tlsclosed(TlsRec *tr, int new)
+{
+	lock(&tr->statelk);
+	if(tr->state == SOpen || tr->state == SHandshake)
+		tr->state = new;
+	else if((new | tr->state) == (SRClose|SLClose))
+		tr->state = SClosed;
+	unlock(&tr->statelk);
+	alertHand(tr, "close notify");
+}
+
+/*
+ *  read and process one tls record layer message
+ *  must be called with tr->in.io held
+ *  We can't let Eintrs lose data, since doing so will get
+ *  us out of sync with the sender and break the reliablity
+ *  of the channel.  Eintr only happens during the reads in
+ *  consume.  Therefore we put back any bytes consumed before
+ *  the last call to ensure.
+ */
+static void
+tlsrecread(TlsRec *tr)
+{
+	OneWay *volatile in;
+	Block *volatile b;
+	uchar *p, seq[8], header[RecHdrLen], hmac[MD5dlen];
+	int volatile nconsumed;
+	int len, type, ver, unpad_len;
+
+	nconsumed = 0;
+	if(waserror()){
+		if(strcmp(up->errstr, Eintr) == 0 && !waserror()){
+			regurgitate(tr, header, nconsumed);
+			poperror();
+		}else
+			tlsError(tr, "channel error");
+		nexterror();
+	}
+	ensure(tr, &tr->unprocessed, RecHdrLen);
+	consume(&tr->unprocessed, header, RecHdrLen);
+if(tr->debug)pprint("consumed %d header\n", RecHdrLen);
+	nconsumed = RecHdrLen;
+
+	if((tr->handin == 0) && (header[0] & 0x80)){
+		/* Cope with an SSL3 ClientHello expressed in SSL2 record format.
+			This is sent by some clients that we must interoperate
+			with, such as Java's JSSE and Microsoft's Internet Explorer. */
+		len = (get16(header) & ~0x8000) - 3;
+		type = header[2];
+		ver = get16(header + 3);
+		if(type != SSL2ClientHello || len < 22)
+			rcvError(tr, EProtocolVersion, "invalid initial SSL2-like message");
+	}else{  /* normal SSL3 record format */
+		type = header[0];
+		ver = get16(header+1);
+		len = get16(header+3);
+	}
+	if(ver != tr->version && (tr->verset || ver < MinProtoVersion || ver > MaxProtoVersion))
+		rcvError(tr, EProtocolVersion, "devtls expected ver=%x%s, saw (len=%d) type=%x ver=%x '%.12s'",
+			tr->version, tr->verset?"/set":"", len, type, ver, (char*)header);
+	if(len > MaxCipherRecLen || len < 0)
+		rcvError(tr, ERecordOverflow, "record message too long %d", len);
+	ensure(tr, &tr->unprocessed, len);
+	nconsumed = 0;
+	poperror();
+
+	/*
+	 * If an Eintr happens after this, we'll get out of sync.
+	 * Make sure nothing we call can sleep.
+	 * Errors are ok, as they kill the connection.
+	 * Luckily, allocb won't sleep, it'll just error out.
+	 */
+	b = nil;
+	if(waserror()){
+		if(b != nil)
+			freeb(b);
+		tlsError(tr, "channel error");
+		nexterror();
+	}
+	b = qgrab(&tr->unprocessed, len);
+if(tr->debug) pprint("consumed unprocessed %d\n", len);
+
+	in = &tr->in;
+	if(waserror()){
+		qunlock(&in->seclock);
+		nexterror();
+	}
+	qlock(&in->seclock);
+	p = b->rp;
+	if(in->sec != nil) {
+		/* to avoid Canvel-Hiltgen-Vaudenay-Vuagnoux attack, all errors here
+		        should look alike, including timing of the response. */
+		unpad_len = (*in->sec->dec)(in->sec, p, len);
+		if(unpad_len >= in->sec->maclen)
+			len = unpad_len - in->sec->maclen;
+if(tr->debug) pprint("decrypted %d\n", unpad_len);
+if(tr->debug) pdump(unpad_len, p, "decrypted:");
+
+		/* update length */
+		put16(header+3, len);
+		put64(seq, in->seq);
+		in->seq++;
+		(*tr->packMac)(in->sec, in->sec->mackey, seq, header, p, len, hmac);
+		if(unpad_len < in->sec->maclen)
+			rcvError(tr, EBadRecordMac, "short record mac");
+		if(memcmp(hmac, p+len, in->sec->maclen) != 0)
+			rcvError(tr, EBadRecordMac, "record mac mismatch");
+		b->wp = b->rp + len;
+	}
+	qunlock(&in->seclock);
+	poperror();
+	if(len < 0)
+		rcvError(tr, EDecodeError, "runt record message");
+
+	switch(type) {
+	default:
+		rcvError(tr, EIllegalParameter, "invalid record message 0x%x", type);
+		break;
+	case RChangeCipherSpec:
+		if(len != 1 || p[0] != 1)
+			rcvError(tr, EDecodeError, "invalid change cipher spec");
+		qlock(&in->seclock);
+		if(in->new == nil){
+			qunlock(&in->seclock);
+			rcvError(tr, EUnexpectedMessage, "unexpected change cipher spec");
+		}
+		freeSec(in->sec);
+		in->sec = in->new;
+		in->new = nil;
+		in->seq = 0;
+		qunlock(&in->seclock);
+		break;
+	case RAlert:
+		if(len != 2)
+			rcvError(tr, EDecodeError, "invalid alert");
+		if(p[0] == 2)
+			rcvAlert(tr, p[1]);
+		if(p[0] != 1)
+			rcvError(tr, EIllegalParameter, "invalid alert fatal code");
+
+		/*
+		 * propate non-fatal alerts to handshaker
+		 */
+		if(p[1] == ECloseNotify) {
+			tlsclosed(tr, SRClose);
+			if(tr->opened)
+				error("tls hungup");
+			error("close notify");
+		}
+		if(p[1] == ENoRenegotiation)
+			alertHand(tr, "no renegotiation");
+		else if(p[1] == EUserCanceled)
+			alertHand(tr, "handshake canceled by user");
+		else
+			rcvError(tr, EIllegalParameter, "invalid alert code");
+		break;
+	case RHandshake:
+		/*
+		 * don't worry about dropping the block
+		 * qbwrite always queues even if flow controlled and interrupted.
+		 *
+		 * if there isn't any handshaker, ignore the request,
+		 * but notify the other side we are doing so.
+		 */
+		lock(&tr->hqlock);
+		if(tr->handq != nil){
+			tr->hqref++;
+			unlock(&tr->hqlock);
+			if(waserror()){
+				dechandq(tr);
+				nexterror();
+			}
+			b = padblock(b, 1);
+			*b->rp = RHandshake;
+			qbwrite(tr->handq, b);
+			b = nil;
+			poperror();
+			dechandq(tr);
+		}else{
+			unlock(&tr->hqlock);
+			if(tr->verset && tr->version != SSL3Version && !waserror()){
+				sendAlert(tr, ENoRenegotiation);
+				poperror();
+			}
+		}
+		break;
+	case SSL2ClientHello:
+		lock(&tr->hqlock);
+		if(tr->handq != nil){
+			tr->hqref++;
+			unlock(&tr->hqlock);
+			if(waserror()){
+				dechandq(tr);
+				nexterror();
+			}
+			/* Pass the SSL2 format data, so that the handshake code can compute
+				the correct checksums.  HSSL2ClientHello = HandshakeType 9 is
+				unused in RFC2246. */
+			b = padblock(b, 8);
+			b->rp[0] = RHandshake;
+			b->rp[1] = HSSL2ClientHello;
+			put24(&b->rp[2], len+3);
+			b->rp[5] = SSL2ClientHello;
+			put16(&b->rp[6], ver);
+			qbwrite(tr->handq, b);
+			b = nil;
+			poperror();
+			dechandq(tr);
+		}else{
+			unlock(&tr->hqlock);
+			if(tr->verset && tr->version != SSL3Version && !waserror()){
+				sendAlert(tr, ENoRenegotiation);
+				poperror();
+			}
+		}
+		break;
+	case RApplication:
+		if(!tr->opened)
+			rcvError(tr, EUnexpectedMessage, "application message received before handshake completed");
+		if(BLEN(b) > 0){
+			tr->processed = b;
+			b = nil;
+		}
+		break;
+	}
+	if(b != nil)
+		freeb(b);
+	poperror();
+}
+
+/*
+ * got a fatal alert message
+ */
+static void
+rcvAlert(TlsRec *tr, int err)
+{
+	char *s;
+	int i;
+
+	s = "unknown error";
+	for(i=0; i < nelem(tlserrs); i++){
+		if(tlserrs[i].err == err){
+			s = tlserrs[i].msg;
+			break;
+		}
+	}
+if(tr->debug) pprint("rcvAlert: %s\n", s);
+
+	tlsError(tr, s);
+	if(!tr->opened)
+		error(s);
+	error("tls error");
+}
+
+/*
+ * found an error while decoding the input stream
+ */
+static void
+rcvError(TlsRec *tr, int err, char *fmt, ...)
+{
+	char msg[ERRMAX];
+	va_list arg;
+
+	va_start(arg, fmt);
+	vseprint(msg, msg+sizeof(msg), fmt, arg);
+	va_end(arg);
+if(tr->debug) pprint("rcvError: %s\n", msg);
+
+	sendAlert(tr, err);
+
+	if(!tr->opened)
+		error(msg);
+	error("tls error");
+}
+
+/*
+ * make sure the next hand operation returns with a 'msg' error
+ */
+static void
+alertHand(TlsRec *tr, char *msg)
+{
+	Block *b;
+	int n;
+
+	lock(&tr->hqlock);
+	if(tr->handq == nil){
+		unlock(&tr->hqlock);
+		return;
+	}
+	tr->hqref++;
+	unlock(&tr->hqlock);
+
+	n = strlen(msg);
+	if(waserror()){
+		dechandq(tr);
+		nexterror();
+	}
+	b = allocb(n + 2);
+	*b->wp++ = RAlert;
+	memmove(b->wp, msg, n + 1);
+	b->wp += n + 1;
+
+	qbwrite(tr->handq, b);
+
+	poperror();
+	dechandq(tr);
+}
+
+static void
+checkstate(TlsRec *tr, int ishand, int ok)
+{
+	int state;
+
+	lock(&tr->statelk);
+	state = tr->state;
+	unlock(&tr->statelk);
+	if(state & ok)
+		return;
+	switch(state){
+	case SHandshake:
+	case SOpen:
+		break;
+	case SError:
+	case SAlert:
+		if(ishand)
+			error(tr->err);
+		error("tls error");
+	case SRClose:
+	case SLClose:
+	case SClosed:
+		error("tls hungup");
+	}
+	error("tls improperly configured");
+}
+
+static Block*
+tlsbread(Chan *c, long n, ulong offset)
+{
+	int ty;
+	Block *b;
+	TlsRec *volatile tr;
+
+	ty = TYPE(c->qid);
+	switch(ty) {
+	default:
+		return devbread(c, n, offset);
+	case Qhand:
+	case Qdata:
+		break;
+	}
+
+	tr = tlsdevs[CONV(c->qid)];
+	if(tr == nil)
+		panic("tlsbread");
+
+	if(waserror()){
+		qunlock(&tr->in.io);
+		nexterror();
+	}
+	qlock(&tr->in.io);
+	if(ty == Qdata){
+		checkstate(tr, 0, SOpen);
+		while(tr->processed == nil)
+			tlsrecread(tr);
+
+		/* return at most what was asked for */
+		b = qgrab(&tr->processed, n);
+if(tr->debug) pprint("consumed processed %d\n", BLEN(b));
+if(tr->debug) pdump(BLEN(b), b->rp, "consumed:");
+		qunlock(&tr->in.io);
+		poperror();
+		tr->datain += BLEN(b);
+	}else{
+		checkstate(tr, 1, SOpen|SHandshake|SLClose);
+
+		/*
+		 * it's ok to look at state without the lock
+		 * since it only protects reading records,
+		 * and we have that tr->in.io held.
+		 */
+		while(!tr->opened && tr->hprocessed == nil && !qcanread(tr->handq))
+			tlsrecread(tr);
+
+		qunlock(&tr->in.io);
+		poperror();
+
+		if(waserror()){
+			qunlock(&tr->hqread);
+			nexterror();
+		}
+		qlock(&tr->hqread);
+		if(tr->hprocessed == nil){
+			b = qbread(tr->handq, MaxRecLen + 1);
+			if(*b->rp++ == RAlert){
+				kstrcpy(up->errstr, (char*)b->rp, ERRMAX);
+				freeb(b);
+				nexterror();
+			}
+			tr->hprocessed = b;
+		}
+		b = qgrab(&tr->hprocessed, n);
+		poperror();
+		qunlock(&tr->hqread);
+		tr->handin += BLEN(b);
+	}
+
+	return b;
+}
+
+static long
+tlsread(Chan *c, void *a, long n, vlong off)
+{
+	Block *volatile b;
+	Block *nb;
+	uchar *va;
+	int i, ty;
+	char *buf, *s, *e;
+	ulong offset = off;
+	TlsRec * tr;
+
+	if(c->qid.type & QTDIR)
+		return devdirread(c, a, n, 0, 0, tlsgen);
+
+	tr = tlsdevs[CONV(c->qid)];
+	ty = TYPE(c->qid);
+	switch(ty) {
+	default:
+		error(Ebadusefd);
+	case Qstatus:
+		buf = smalloc(Statlen);
+		qlock(&tr->in.seclock);
+		qlock(&tr->out.seclock);
+		s = buf;
+		e = buf + Statlen;
+		s = seprint(s, e, "State: %s\n", tlsstate(tr->state));
+		s = seprint(s, e, "Version: 0x%x\n", tr->version);
+		if(tr->in.sec != nil)
+			s = seprint(s, e, "EncIn: %s\nHashIn: %s\n", tr->in.sec->encalg, tr->in.sec->hashalg);
+		if(tr->in.new != nil)
+			s = seprint(s, e, "NewEncIn: %s\nNewHashIn: %s\n", tr->in.new->encalg, tr->in.new->hashalg);
+		if(tr->out.sec != nil)
+			s = seprint(s, e, "EncOut: %s\nHashOut: %s\n", tr->out.sec->encalg, tr->out.sec->hashalg);
+		if(tr->out.new != nil)
+			seprint(s, e, "NewEncOut: %s\nNewHashOut: %s\n", tr->out.new->encalg, tr->out.new->hashalg);
+		qunlock(&tr->in.seclock);
+		qunlock(&tr->out.seclock);
+		n = readstr(offset, a, n, buf);
+		free(buf);
+		return n;
+	case Qstats:
+		buf = smalloc(Statlen);
+		s = buf;
+		e = buf + Statlen;
+		s = seprint(s, e, "DataIn: %lld\n", tr->datain);
+		s = seprint(s, e, "DataOut: %lld\n", tr->dataout);
+		s = seprint(s, e, "HandIn: %lld\n", tr->handin);
+		seprint(s, e, "HandOut: %lld\n", tr->handout);
+		n = readstr(offset, a, n, buf);
+		free(buf);
+		return n;
+	case Qctl:
+		buf = smalloc(Statlen);
+		snprint(buf, Statlen, "%llud", CONV(c->qid));
+		n = readstr(offset, a, n, buf);
+		free(buf);
+		return n;
+	case Qdata:
+	case Qhand:
+		b = tlsbread(c, n, offset);
+		break;
+	case Qencalgs:
+		return readstr(offset, a, n, encalgs);
+	case Qhashalgs:
+		return readstr(offset, a, n, hashalgs);
+	}
+
+	if(waserror()){
+		freeblist(b);
+		nexterror();
+	}
+
+	n = 0;
+	va = a;
+	for(nb = b; nb; nb = nb->next){
+		i = BLEN(nb);
+		memmove(va+n, nb->rp, i);
+		n += i;
+	}
+
+	freeblist(b);
+	poperror();
+
+	return n;
+}
+
+/*
+ *  write a block in tls records
+ */
+static void
+tlsrecwrite(TlsRec *tr, int type, Block *b)
+{
+	Block *volatile bb;
+	Block *nb;
+	uchar *p, seq[8];
+	OneWay *volatile out;
+	int n, maclen, pad, ok;
+
+	out = &tr->out;
+	bb = b;
+	if(waserror()){
+		qunlock(&out->io);
+		if(bb != nil)
+			freeb(bb);
+		nexterror();
+	}
+	qlock(&out->io);
+if(tr->debug)pprint("send %d\n", BLEN(b));
+if(tr->debug)pdump(BLEN(b), b->rp, "sent:");
+
+
+	ok = SHandshake|SOpen|SRClose;
+	if(type == RAlert)
+		ok |= SAlert;
+	while(bb != nil){
+		checkstate(tr, type != RApplication, ok);
+
+		/*
+		 * get at most one maximal record's input,
+		 * with padding on the front for header and
+		 * back for mac and maximal block padding.
+		 */
+		if(waserror()){
+			qunlock(&out->seclock);
+			nexterror();
+		}
+		qlock(&out->seclock);
+		maclen = 0;
+		pad = 0;
+		if(out->sec != nil){
+			maclen = out->sec->maclen;
+			pad = maclen + out->sec->block;
+		}
+		n = BLEN(bb);
+		if(n > MaxRecLen){
+			n = MaxRecLen;
+			nb = allocb(n + pad + RecHdrLen);
+			memmove(nb->wp + RecHdrLen, bb->rp, n);
+			bb->rp += n;
+		}else{
+			/*
+			 * carefully reuse bb so it will get freed if we're out of memory
+			 */
+			bb = padblock(bb, RecHdrLen);
+			if(pad)
+				nb = padblock(bb, -pad);
+			else
+				nb = bb;
+			bb = nil;
+		}
+
+		p = nb->rp;
+		p[0] = type;
+		put16(p+1, tr->version);
+		put16(p+3, n);
+
+		if(out->sec != nil){
+			put64(seq, out->seq);
+			out->seq++;
+			(*tr->packMac)(out->sec, out->sec->mackey, seq, p, p + RecHdrLen, n, p + RecHdrLen + n);
+			n += maclen;
+
+			/* encrypt */
+			n = (*out->sec->enc)(out->sec, p + RecHdrLen, n);
+			nb->wp = p + RecHdrLen + n;
+
+			/* update length */
+			put16(p+3, n);
+		}
+		if(type == RChangeCipherSpec){
+			if(out->new == nil)
+				error("change cipher without a new cipher");
+			freeSec(out->sec);
+			out->sec = out->new;
+			out->new = nil;
+			out->seq = 0;
+		}
+		qunlock(&out->seclock);
+		poperror();
+
+		/*
+		 * if bwrite error's, we assume the block is queued.
+		 * if not, we're out of sync with the receiver and will not recover.
+		 */
+		if(waserror()){
+			if(strcmp(up->errstr, "interrupted") != 0)
+				tlsError(tr, "channel error");
+			nexterror();
+		}
+		devtab[tr->c->type]->bwrite(tr->c, nb, 0);
+		poperror();
+	}
+	qunlock(&out->io);
+	poperror();
+}
+
+static long
+tlsbwrite(Chan *c, Block *b, ulong offset)
+{
+	int ty;
+	ulong n;
+	TlsRec *tr;
+
+	n = BLEN(b);
+
+	tr = tlsdevs[CONV(c->qid)];
+	if(tr == nil)
+		panic("tlsbread");
+
+	ty = TYPE(c->qid);
+	switch(ty) {
+	default:
+		return devbwrite(c, b, offset);
+	case Qhand:
+		tlsrecwrite(tr, RHandshake, b);
+		tr->handout += n;
+		break;
+	case Qdata:
+		checkstate(tr, 0, SOpen);
+		tlsrecwrite(tr, RApplication, b);
+		tr->dataout += n;
+		break;
+	}
+
+	return n;
+}
+
+typedef struct Hashalg Hashalg;
+struct Hashalg
+{
+	char	*name;
+	int	maclen;
+	void	(*initkey)(Hashalg *, int, Secret *, uchar*);
+};
+
+static void
+initmd5key(Hashalg *ha, int version, Secret *s, uchar *p)
+{
+	s->maclen = ha->maclen;
+	if(version == SSL3Version)
+		s->mac = sslmac_md5;
+	else
+		s->mac = hmac_md5;
+	memmove(s->mackey, p, ha->maclen);
+}
+
+static void
+initclearmac(Hashalg *unused1, int unused2, Secret *s, uchar *unused3)
+{
+	s->maclen = 0;
+	s->mac = nomac;
+}
+
+static void
+initsha1key(Hashalg *ha, int version, Secret *s, uchar *p)
+{
+	s->maclen = ha->maclen;
+	if(version == SSL3Version)
+		s->mac = sslmac_sha1;
+	else
+		s->mac = hmac_sha1;
+	memmove(s->mackey, p, ha->maclen);
+}
+
+static Hashalg hashtab[] =
+{
+	{ "clear", 0, initclearmac, },
+	{ "md5", MD5dlen, initmd5key, },
+	{ "sha1", SHA1dlen, initsha1key, },
+	{ 0 }
+};
+
+static Hashalg*
+parsehashalg(char *p)
+{
+	Hashalg *ha;
+
+	for(ha = hashtab; ha->name; ha++)
+		if(strcmp(p, ha->name) == 0)
+			return ha;
+	error("unsupported hash algorithm");
+	return nil;
+}
+
+typedef struct Encalg Encalg;
+struct Encalg
+{
+	char	*name;
+	int	keylen;
+	int	ivlen;
+	void	(*initkey)(Encalg *ea, Secret *, uchar*, uchar*);
+};
+
+static void
+initRC4key(Encalg *ea, Secret *s, uchar *p, uchar *unused1)
+{
+	s->enckey = smalloc(sizeof(RC4state));
+	s->enc = rc4enc;
+	s->dec = rc4enc;
+	s->block = 0;
+	setupRC4state(s->enckey, p, ea->keylen);
+}
+
+static void
+initDES3key(Encalg *unused1, Secret *s, uchar *p, uchar *iv)
+{
+	s->enckey = smalloc(sizeof(DES3state));
+	s->enc = des3enc;
+	s->dec = des3dec;
+	s->block = 8;
+	setupDES3state(s->enckey, (uchar(*)[8])p, iv);
+}
+
+static void
+initclearenc(Encalg *unused1, Secret *s, uchar *unused2, uchar *unused3)
+{
+	s->enc = noenc;
+	s->dec = noenc;
+	s->block = 0;
+}
+
+static Encalg encrypttab[] =
+{
+	{ "clear", 0, 0, initclearenc },
+	{ "rc4_128", 128/8, 0, initRC4key },
+	{ "3des_ede_cbc", 3 * 8, 8, initDES3key },
+	{ 0 }
+};
+
+static Encalg*
+parseencalg(char *p)
+{
+	Encalg *ea;
+
+	for(ea = encrypttab; ea->name; ea++)
+		if(strcmp(p, ea->name) == 0)
+			return ea;
+	error("unsupported encryption algorithm");
+	return nil;
+}
+
+static long
+tlswrite(Chan *c, void *a, long n, vlong off)
+{
+	Encalg *ea;
+	Hashalg *ha;
+	TlsRec *volatile tr;
+	Secret *volatile tos, *volatile toc;
+	Block *volatile b;
+	Cmdbuf *volatile cb;
+	int m, ty;
+	char *p, *e;
+	uchar *volatile x;
+	ulong offset = off;
+
+	tr = tlsdevs[CONV(c->qid)];
+	if(tr == nil)
+		panic("tlswrite");
+
+	ty = TYPE(c->qid);
+	switch(ty){
+	case Qdata:
+	case Qhand:
+		p = a;
+		e = p + n;
+		do{
+			m = e - p;
+			if(m > MaxRecLen)
+				m = MaxRecLen;
+
+			b = allocb(m);
+			if(waserror()){
+				freeb(b);
+				nexterror();
+			}
+			memmove(b->wp, p, m);
+			poperror();
+			b->wp += m;
+
+			tlsbwrite(c, b, offset);
+
+			p += m;
+		}while(p < e);
+		return n;
+	case Qctl:
+		break;
+	default:
+		error(Ebadusefd);
+		return -1;
+	}
+
+	cb = parsecmd(a, n);
+	if(waserror()){
+		free(cb);
+		nexterror();
+	}
+	if(cb->nf < 1)
+		error("short control request");
+
+	/* mutex with operations using what we're about to change */
+	if(waserror()){
+		qunlock(&tr->in.seclock);
+		qunlock(&tr->out.seclock);
+		nexterror();
+	}
+	qlock(&tr->in.seclock);
+	qlock(&tr->out.seclock);
+
+	if(strcmp(cb->f[0], "fd") == 0){
+		if(cb->nf != 3)
+			error("usage: fd open-fd version");
+		if(tr->c != nil)
+			error(Einuse);
+		m = strtol(cb->f[2], nil, 0);
+		if(m < MinProtoVersion || m > MaxProtoVersion)
+			error("unsupported version");
+		tr->c = buftochan(cb->f[1]);
+		tr->version = m;
+		tlsSetState(tr, SHandshake, SClosed);
+	}else if(strcmp(cb->f[0], "version") == 0){
+		if(cb->nf != 2)
+			error("usage: version vers");
+		if(tr->c == nil)
+			error("must set fd before version");
+		if(tr->verset)
+			error("version already set");
+		m = strtol(cb->f[1], nil, 0);
+		if(m == SSL3Version)
+			tr->packMac = sslPackMac;
+		else if(m == TLSVersion)
+			tr->packMac = tlsPackMac;
+		else
+			error("unsupported version");
+		tr->verset = 1;
+		tr->version = m;
+	}else if(strcmp(cb->f[0], "secret") == 0){
+		if(cb->nf != 5)
+			error("usage: secret hashalg encalg isclient secretdata");
+		if(tr->c == nil || !tr->verset)
+			error("must set fd and version before secrets");
+
+		if(tr->in.new != nil){
+			freeSec(tr->in.new);
+			tr->in.new = nil;
+		}
+		if(tr->out.new != nil){
+			freeSec(tr->out.new);
+			tr->out.new = nil;
+		}
+
+		ha = parsehashalg(cb->f[1]);
+		ea = parseencalg(cb->f[2]);
+
+		p = cb->f[4];
+		m = (strlen(p)*3)/2;
+		x = smalloc(m);
+		tos = nil;
+		toc = nil;
+		if(waserror()){
+			freeSec(tos);
+			freeSec(toc);
+			free(x);
+			nexterror();
+		}
+		m = dec64(x, m, p, strlen(p));
+		if(m < 2 * ha->maclen + 2 * ea->keylen + 2 * ea->ivlen)
+			error("not enough secret data provided");
+
+		tos = smalloc(sizeof(Secret));
+		toc = smalloc(sizeof(Secret));
+		if(!ha->initkey || !ea->initkey)
+			error("misimplemented secret algorithm");
+		(*ha->initkey)(ha, tr->version, tos, &x[0]);
+		(*ha->initkey)(ha, tr->version, toc, &x[ha->maclen]);
+		(*ea->initkey)(ea, tos, &x[2 * ha->maclen], &x[2 * ha->maclen + 2 * ea->keylen]);
+		(*ea->initkey)(ea, toc, &x[2 * ha->maclen + ea->keylen], &x[2 * ha->maclen + 2 * ea->keylen + ea->ivlen]);
+
+		if(!tos->mac || !tos->enc || !tos->dec
+		|| !toc->mac || !toc->enc || !toc->dec)
+			error("missing algorithm implementations");
+		if(strtol(cb->f[3], nil, 0) == 0){
+			tr->in.new = tos;
+			tr->out.new = toc;
+		}else{
+			tr->in.new = toc;
+			tr->out.new = tos;
+		}
+		if(tr->version == SSL3Version){
+			toc->unpad = sslunpad;
+			tos->unpad = sslunpad;
+		}else{
+			toc->unpad = tlsunpad;
+			tos->unpad = tlsunpad;
+		}
+		toc->encalg = ea->name;
+		toc->hashalg = ha->name;
+		tos->encalg = ea->name;
+		tos->hashalg = ha->name;
+
+		free(x);
+		poperror();
+	}else if(strcmp(cb->f[0], "changecipher") == 0){
+		if(cb->nf != 1)
+			error("usage: changecipher");
+		if(tr->out.new == nil)
+			error("cannot change cipher spec without setting secret");
+
+		qunlock(&tr->in.seclock);
+		qunlock(&tr->out.seclock);
+		poperror();
+		free(cb);
+		poperror();
+
+		/*
+		 * the real work is done as the message is written
+		 * so the stream is encrypted in sync.
+		 */
+		b = allocb(1);
+		*b->wp++ = 1;
+		tlsrecwrite(tr, RChangeCipherSpec, b);
+		return n;
+	}else if(strcmp(cb->f[0], "opened") == 0){
+		if(cb->nf != 1)
+			error("usage: opened");
+		if(tr->in.sec == nil || tr->out.sec == nil)
+			error("cipher must be configured before enabling data messages");
+		lock(&tr->statelk);
+		if(tr->state != SHandshake && tr->state != SOpen){
+			unlock(&tr->statelk);
+			error("cannot enable data messages");
+		}
+		tr->state = SOpen;
+		unlock(&tr->statelk);
+		tr->opened = 1;
+	}else if(strcmp(cb->f[0], "alert") == 0){
+		if(cb->nf != 2)
+			error("usage: alert n");
+		if(tr->c == nil)
+			error("must set fd before sending alerts");
+		m = strtol(cb->f[1], nil, 0);
+
+		qunlock(&tr->in.seclock);
+		qunlock(&tr->out.seclock);
+		poperror();
+		free(cb);
+		poperror();
+
+		sendAlert(tr, m);
+
+		if(m == ECloseNotify)
+			tlsclosed(tr, SLClose);
+
+		return n;
+	} else if(strcmp(cb->f[0], "debug") == 0){
+		if(cb->nf == 2){
+			if(strcmp(cb->f[1], "on") == 0)
+				tr->debug = 1;
+			else
+				tr->debug = 0;
+		} else
+			tr->debug = 1;
+	} else
+		error(Ebadarg);
+
+	qunlock(&tr->in.seclock);
+	qunlock(&tr->out.seclock);
+	poperror();
+	free(cb);
+	poperror();
+
+	return n;
+}
+
+static void
+tlsinit(void)
+{
+	struct Encalg *e;
+	struct Hashalg *h;
+	int n;
+	char *cp;
+	static int already;
+
+	if(!already){
+		fmtinstall('H', encodefmt);
+		already = 1;
+	}
+
+	tlsdevs = smalloc(sizeof(TlsRec*) * maxtlsdevs);
+	trnames = smalloc((sizeof *trnames) * maxtlsdevs);
+
+	n = 1;
+	for(e = encrypttab; e->name != nil; e++)
+		n += strlen(e->name) + 1;
+	cp = encalgs = smalloc(n);
+	for(e = encrypttab;;){
+		strcpy(cp, e->name);
+		cp += strlen(e->name);
+		e++;
+		if(e->name == nil)
+			break;
+		*cp++ = ' ';
+	}
+	*cp = 0;
+
+	n = 1;
+	for(h = hashtab; h->name != nil; h++)
+		n += strlen(h->name) + 1;
+	cp = hashalgs = smalloc(n);
+	for(h = hashtab;;){
+		strcpy(cp, h->name);
+		cp += strlen(h->name);
+		h++;
+		if(h->name == nil)
+			break;
+		*cp++ = ' ';
+	}
+	*cp = 0;
+}
+
+Dev tlsdevtab = {
+	'a',
+	"tls",
+
+	devreset,
+	tlsinit,
+	devshutdown,
+	tlsattach,
+	tlswalk,
+	tlsstat,
+	tlsopen,
+	devcreate,
+	tlsclose,
+	tlsread,
+	tlsbread,
+	tlswrite,
+	tlsbwrite,
+	devremove,
+	tlswstat,
+};
+
+/* get channel associated with an fd */
+static Chan*
+buftochan(char *p)
+{
+	Chan *c;
+	int fd;
+
+	if(p == 0)
+		error(Ebadarg);
+	fd = strtoul(p, 0, 0);
+	if(fd < 0)
+		error(Ebadarg);
+	c = fdtochan(fd, -1, 0, 1);	/* error check and inc ref */
+	return c;
+}
+
+static void
+sendAlert(TlsRec *tr, int err)
+{
+	Block *b;
+	int i, fatal;
+	char *msg;
+
+if(tr->debug)pprint("sendAlert %d\n", err);
+	fatal = 1;
+	msg = "tls unknown alert";
+	for(i=0; i < nelem(tlserrs); i++) {
+		if(tlserrs[i].err == err) {
+			msg = tlserrs[i].msg;
+			if(tr->version == SSL3Version)
+				err = tlserrs[i].sslerr;
+			else
+				err = tlserrs[i].tlserr;
+			fatal = tlserrs[i].fatal;
+			break;
+		}
+	}
+
+	if(!waserror()){
+		b = allocb(2);
+		*b->wp++ = fatal + 1;
+		*b->wp++ = err;
+		if(fatal)
+			tlsSetState(tr, SAlert, SOpen|SHandshake|SRClose);
+		tlsrecwrite(tr, RAlert, b);
+		poperror();
+	}
+	if(fatal)
+		tlsError(tr, msg);
+}
+
+static void
+tlsError(TlsRec *tr, char *msg)
+{
+	int s;
+
+if(tr->debug)pprint("tleError %s\n", msg);
+	lock(&tr->statelk);
+	s = tr->state;
+	tr->state = SError;
+	if(s != SError){
+		strncpy(tr->err, msg, ERRMAX - 1);
+		tr->err[ERRMAX - 1] = '\0';
+	}
+	unlock(&tr->statelk);
+	if(s != SError)
+		alertHand(tr, msg);
+}
+
+static void
+tlsSetState(TlsRec *tr, int new, int old)
+{
+	lock(&tr->statelk);
+	if(tr->state & old)
+		tr->state = new;
+	unlock(&tr->statelk);
+}
+
+/* hand up a digest connection */
+static void
+tlshangup(TlsRec *tr)
+{
+	Block *b;
+
+	qlock(&tr->in.io);
+	for(b = tr->processed; b; b = tr->processed){
+		tr->processed = b->next;
+		freeb(b);
+	}
+	if(tr->unprocessed != nil){
+		freeb(tr->unprocessed);
+		tr->unprocessed = nil;
+	}
+	qunlock(&tr->in.io);
+
+	tlsSetState(tr, SClosed, ~0);
+}
+
+static TlsRec*
+newtls(Chan *ch)
+{
+	TlsRec **pp, **ep, **np;
+	char **nmp;
+	int t, newmax;
+
+	if(waserror()) {
+		unlock(&tdlock);
+		nexterror();
+	}
+	lock(&tdlock);
+	ep = &tlsdevs[maxtlsdevs];
+	for(pp = tlsdevs; pp < ep; pp++)
+		if(*pp == nil)
+			break;
+	if(pp >= ep) {
+		if(maxtlsdevs >= MaxTlsDevs) {
+			unlock(&tdlock);
+			poperror();
+			return nil;
+		}
+		newmax = 2 * maxtlsdevs;
+		if(newmax > MaxTlsDevs)
+			newmax = MaxTlsDevs;
+		np = smalloc(sizeof(TlsRec*) * newmax);
+		memmove(np, tlsdevs, sizeof(TlsRec*) * maxtlsdevs);
+		tlsdevs = np;
+		pp = &tlsdevs[maxtlsdevs];
+		memset(pp, 0, sizeof(TlsRec*)*(newmax - maxtlsdevs));
+
+		nmp = smalloc(sizeof *nmp * newmax);
+		memmove(nmp, trnames, sizeof *nmp * maxtlsdevs);
+		trnames = nmp;
+
+		maxtlsdevs = newmax;
+	}
+	*pp = mktlsrec();
+	if(pp - tlsdevs >= tdhiwat)
+		tdhiwat++;
+	t = TYPE(ch->qid);
+	if(t == Qclonus)
+		t = Qctl;
+	ch->qid.path = QID(pp - tlsdevs, t);
+	ch->qid.vers = 0;
+	unlock(&tdlock);
+	poperror();
+	return *pp;
+}
+
+static TlsRec *
+mktlsrec(void)
+{
+	TlsRec *tr;
+
+	tr = mallocz(sizeof(*tr), 1);
+	if(tr == nil)
+		error(Enomem);
+	tr->state = SClosed;
+	tr->ref = 1;
+	kstrdup(&tr->user, up->user);
+	tr->perm = 0660;
+	return tr;
+}
+
+static char*
+tlsstate(int s)
+{
+	switch(s){
+	case SHandshake:
+		return "Handshaking";
+	case SOpen:
+		return "Established";
+	case SRClose:
+		return "RemoteClosed";
+	case SLClose:
+		return "LocalClosed";
+	case SAlert:
+		return "Alerting";
+	case SError:
+		return "Errored";
+	case SClosed:
+		return "Closed";
+	}
+	return "Unknown";
+}
+
+static void
+freeSec(Secret *s)
+{
+	if(s != nil){
+		free(s->enckey);
+		free(s);
+	}
+}
+
+static int
+noenc(Secret *unused1, uchar *unused2, int n)
+{
+	return n;
+}
+
+static int
+rc4enc(Secret *sec, uchar *buf, int n)
+{
+	rc4(sec->enckey, buf, n);
+	return n;
+}
+
+static int
+tlsunpad(uchar *buf, int n, int block)
+{
+	int pad, nn;
+
+	pad = buf[n - 1];
+	nn = n - 1 - pad;
+	if(nn <= 0 || n % block)
+		return -1;
+	while(--n > nn)
+		if(pad != buf[n - 1])
+			return -1;
+	return nn;
+}
+
+static int
+sslunpad(uchar *buf, int n, int block)
+{
+	int pad, nn;
+
+	pad = buf[n - 1];
+	nn = n - 1 - pad;
+	if(nn <= 0 || n % block)
+		return -1;
+	return nn;
+}
+
+static int
+blockpad(uchar *buf, int n, int block)
+{
+	int pad, nn;
+
+	nn = n + block;
+	nn -= nn % block;
+	pad = nn - (n + 1);
+	while(n < nn)
+		buf[n++] = pad;
+	return nn;
+}
+		
+static int
+des3enc(Secret *sec, uchar *buf, int n)
+{
+	n = blockpad(buf, n, 8);
+	des3CBCencrypt(buf, n, sec->enckey);
+	return n;
+}
+
+static int
+des3dec(Secret *sec, uchar *buf, int n)
+{
+	des3CBCdecrypt(buf, n, sec->enckey);
+	return (*sec->unpad)(buf, n, 8);
+}
+static DigestState*
+nomac(uchar *unused1, ulong unused2, uchar *unused3, ulong unused4,
+	uchar *unused5, DigestState *unused6)
+{
+	return nil;
+}
+
+/*
+ * sslmac: mac calculations for ssl 3.0 only; tls 1.0 uses the standard hmac.
+ */
+static DigestState*
+sslmac_x(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s,
+	DigestState*(*x)(uchar*, ulong, uchar*, DigestState*), int xlen, int padlen)
+{
+	int i;
+	uchar pad[48], innerdigest[20];
+
+	if(xlen > sizeof(innerdigest)
+	|| padlen > sizeof(pad))
+		return nil;
+
+	if(klen>64)
+		return nil;
+
+	/* first time through */
+	if(s == nil){
+		for(i=0; i<padlen; i++)
+			pad[i] = 0x36;
+		s = (*x)(key, klen, nil, nil);
+		s = (*x)(pad, padlen, nil, s);
+		if(s == nil)
+			return nil;
+	}
+
+	s = (*x)(p, len, nil, s);
+	if(digest == nil)
+		return s;
+
+	/* last time through */
+	for(i=0; i<padlen; i++)
+		pad[i] = 0x5c;
+	(*x)(nil, 0, innerdigest, s);
+	s = (*x)(key, klen, nil, nil);
+	s = (*x)(pad, padlen, nil, s);
+	(*x)(innerdigest, xlen, digest, s);
+	return nil;
+}
+
+static DigestState*
+sslmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
+{
+	return sslmac_x(p, len, key, klen, digest, s, sha1, SHA1dlen, 40);
+}
+
+static DigestState*
+sslmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
+{
+	return sslmac_x(p, len, key, klen, digest, s, md5, MD5dlen, 48);
+}
+
+static void
+sslPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac)
+{
+	DigestState *s;
+	uchar buf[11];
+
+	memmove(buf, seq, 8);
+	buf[8] = header[0];
+	buf[9] = header[3];
+	buf[10] = header[4];
+
+	s = (*sec->mac)(buf, 11, mackey, sec->maclen, 0, 0);
+	(*sec->mac)(body, len, mackey, sec->maclen, mac, s);
+}
+
+static void
+tlsPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac)
+{
+	DigestState *s;
+	uchar buf[13];
+
+	memmove(buf, seq, 8);
+	memmove(&buf[8], header, 5);
+
+	s = (*sec->mac)(buf, 13, mackey, sec->maclen, 0, 0);
+	(*sec->mac)(body, len, mackey, sec->maclen, mac, s);
+}
+
+static void
+put32(uchar *p, u32int x)
+{
+	p[0] = x>>24;
+	p[1] = x>>16;
+	p[2] = x>>8;
+	p[3] = x;
+}
+
+static void
+put64(uchar *p, vlong x)
+{
+	put32(p, (u32int)(x >> 32));
+	put32(p+4, (u32int)x);
+}
+
+static void
+put24(uchar *p, int x)
+{
+	p[0] = x>>16;
+	p[1] = x>>8;
+	p[2] = x;
+}
+
+static void
+put16(uchar *p, int x)
+{
+	p[0] = x>>8;
+	p[1] = x;
+}
+
+static u32int
+get32(uchar *p)
+{
+	return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
+}
+