Browse Source

Plan 9 from Bell Labs 2004-05-12

David du Colombier 20 years ago
parent
commit
c1b840678e

+ 36 - 37
dist/replica/plan9.db

@@ -50,8 +50,8 @@
 386/bin/ascii - 775 sys sys 1064598029 63016
 386/bin/astro - 775 sys sys 1064598030 139291
 386/bin/auth - 20000000775 sys sys 1016920815 0
-386/bin/auth/aescbc - 775 sys sys 1064598032 121372
-386/bin/auth/asn12rsa - 775 sys sys 1064598033 118015
+386/bin/auth/aescbc - 775 sys sys 1084329144 122190
+386/bin/auth/asn12rsa - 775 sys sys 1084329144 119074
 386/bin/auth/authsrv - 775 sys sys 1081480398 165315
 386/bin/auth/changeuser - 775 sys sys 1064598034 95843
 386/bin/auth/convkeys - 775 sys sys 1064598035 86037
@@ -254,7 +254,7 @@
 386/bin/gview - 775 sys sys 1076385620 235602
 386/bin/gzip - 775 sys sys 1064598211 83770
 386/bin/hayes - 775 sys sys 1064598212 63307
-386/bin/hget - 775 sys sys 1081657628 226993
+386/bin/hget - 775 sys sys 1084329145 226161
 386/bin/history - 775 sys sys 1073851230 73560
 386/bin/hoc - 775 sys sys 1064598215 98708
 386/bin/html2ms - 775 sys sys 1064598215 64484
@@ -277,9 +277,9 @@
 386/bin/ip/httpd/imagemap - 775 sys sys 1064598228 113413
 386/bin/ip/httpd/man2html - 775 sys sys 1064598229 121681
 386/bin/ip/httpd/netlib_find - 775 sys sys 1068385801 114179
-386/bin/ip/httpd/netlib_history - 775 sys sys 1068385801 112809
-386/bin/ip/httpd/save - 775 sys sys 1064598231 130742
-386/bin/ip/httpd/webls - 775 sys sys 1071245336 129484
+386/bin/ip/httpd/netlib_history - 775 sys sys 1084329145 113053
+386/bin/ip/httpd/save - 775 sys sys 1084329145 130950
+386/bin/ip/httpd/webls - 775 sys sys 1084329146 129732
 386/bin/ip/httpd/wikipost - 775 sys sys 1083812550 111306
 386/bin/ip/imap4d - 775 sys sys 1076990354 236967
 386/bin/ip/ipconfig - 775 sys sys 1081480408 136372
@@ -302,11 +302,11 @@
 386/bin/ktrace - 775 sys sys 1068558079 115884
 386/bin/lens - 775 sys sys 1071245338 122873
 386/bin/lex - 775 sys sys 1064598249 97280
-386/bin/lnfs - 775 sys sys 1064598250 100511
+386/bin/lnfs - 775 sys sys 1084329146 100910
 386/bin/look - 775 sys sys 1064598250 64212
 386/bin/ls - 775 sys sys 1073851233 81182
 386/bin/mc - 775 sys sys 1083466779 131530
-386/bin/md5sum - 775 sys sys 1064598252 59465
+386/bin/md5sum - 775 sys sys 1084329146 59857
 386/bin/mk - 775 sys sys 1064598253 143638
 386/bin/mkdir - 775 sys sys 1082603187 59419
 386/bin/mkpaqfs - 775 sys sys 1073851233 94055
@@ -410,8 +410,8 @@
 386/bin/telnet - 775 sys sys 1081480415 80628
 386/bin/test - 775 sys sys 1081480416 68614
 386/bin/time - 775 sys sys 1064598328 59564
-386/bin/tlsclient - 775 sys sys 1064598330 196114
-386/bin/tlssrv - 775 sys sys 1064598331 196448
+386/bin/tlsclient - 775 sys sys 1084329147 197679
+386/bin/tlssrv - 775 sys sys 1084329147 198229
 386/bin/togif - 775 sys sys 1071245356 189681
 386/bin/toico - 775 sys sys 1073851241 122133
 386/bin/topng - 775 sys sys 1068717504 137683
@@ -454,7 +454,7 @@
 386/bin/upas/smtpd - 775 sys sys 1081480422 327368
 386/bin/upas/spam - 775 sys sys 1064598366 36
 386/bin/upas/testscan - 775 sys sys 1064598366 82161
-386/bin/upas/token - 775 sys sys 1064598367 75930
+386/bin/upas/token - 775 sys sys 1084329147 76755
 386/bin/upas/unesc - 775 sys sys 1075097691 133345
 386/bin/upas/unspam - 775 sys sys 1064598367 38
 386/bin/upas/vf - 775 sys sys 1081480422 91835
@@ -489,7 +489,7 @@
 386/bin/vtdump - 775 sys sys 1076385623 161557
 386/bin/wc - 775 sys sys 1064598399 42148
 386/bin/webcookies - 775 sys sys 1068558171 162995
-386/bin/webfs - 775 sys sys 1068558224 352388
+386/bin/webfs - 775 sys sys 1084329148 353886
 386/bin/webfsget - 775 sys sys 1068558178 39356
 386/bin/wikifs - 775 sys sys 1081480423 203546
 386/bin/winwatch - 775 sys sys 1071245372 141560
@@ -527,7 +527,7 @@
 386/lib/libauthsrv.a - 664 sys sys 1077636970 33806
 386/lib/libbin.a - 664 sys sys 1073851265 2556
 386/lib/libbio.a - 664 sys sys 1073851265 28338
-386/lib/libc.a - 664 sys sys 1081564247 504790
+386/lib/libc.a - 664 sys sys 1084329149 504790
 386/lib/libcomplete.a - 664 sys sys 1076817073 6312
 386/lib/libcontrol.a - 664 sys sys 1073851267 242856
 386/lib/libdisk.a - 664 sys sys 1073851267 43536
@@ -536,22 +536,22 @@
 386/lib/libframe.a - 664 sys sys 1073851269 65534
 386/lib/libgeometry.a - 664 sys sys 1073851269 50732
 386/lib/libhtml.a - 664 sys sys 1073851269 220320
-386/lib/libhttpd.a - 664 sys sys 1081564247 99040
+386/lib/libhttpd.a - 664 sys sys 1084329149 99398
 386/lib/libip.a - 664 sys sys 1073851270 34012
 386/lib/libl.a - 664 sys sys 1073851270 5386
 386/lib/libmach.a - 664 sys sys 1073851272 746962
 386/lib/libmemdraw.a - 664 sys sys 1073851273 291288
 386/lib/libmemlayer.a - 664 sys sys 1073851273 47636
-386/lib/libmp.a - 664 sys sys 1084244418 81428
+386/lib/libmp.a - 664 sys sys 1084329149 78536
 386/lib/libndb.a - 664 sys sys 1079451578 61344
 386/lib/libplumb.a - 664 sys sys 1073851274 18876
 386/lib/libregexp.a - 664 sys sys 1073851274 37502
 386/lib/libscribble.a - 664 sys sys 1073851274 107542
-386/lib/libsec.a - 664 sys sys 1081564249 646502
+386/lib/libsec.a - 664 sys sys 1084329150 648380
 386/lib/libstdio.a - 664 sys sys 1073851276 127052
 386/lib/libsunrpc.a - 664 sys sys 1073851277 357030
 386/lib/libthread.a - 664 sys sys 1083553423 71456
-386/lib/libventi.a - 664 sys sys 1081564249 98178
+386/lib/libventi.a - 664 sys sys 1084329151 98178
 386/mbr - 775 sys sys 1022125974 407
 386/mkfile - 664 sys sys 948141303 46
 386/pbs - 775 sys sys 1022125973 494
@@ -3128,7 +3128,7 @@ rc/bin/whois - 775 sys sys 945617210 189
 rc/bin/window - 775 sys sys 1071573331 1781
 rc/bin/wloc - 775 sys sys 969512017 191
 rc/bin/wurl2txt - 755 sys sys 1017431148 296
-rc/bin/yesterday - 775 sys sys 1070288432 2541
+rc/bin/yesterday - 775 sys sys 1084332530 2545
 rc/lib - 20000000775 sys sys 948037639 0
 rc/lib/rcmain - 664 sys sys 984696976 579
 sparc - 20000000775 sys sys 947991046 0
@@ -3426,7 +3426,7 @@ sys/include/httpd.h - 664 sys sys 1079372798 5747
 sys/include/ip.h - 664 sys sys 1050702405 2908
 sys/include/keyboard.h - 664 sys sys 1079577798 815
 sys/include/libc.h - 664 sys sys 1072792615 19430
-sys/include/libsec.h - 664 sys sys 1081199854 9024
+sys/include/libsec.h - 664 sys sys 1084318867 9264
 sys/include/mach.h - 664 sys sys 1068478049 8194
 sys/include/memdraw.h - 664 sys sys 1039752978 5616
 sys/include/memlayer.h - 664 sys sys 1051031022 1851
@@ -3988,7 +3988,7 @@ sys/lib/man/preface4 - 664 sys sys 1020082276 1758
 sys/lib/man/secindex - 775 sys sys 956337727 322
 sys/lib/man/title - 664 sys sys 1019915894 746
 sys/lib/man/trademarks - 664 sys sys 958527089 1838
-sys/lib/mimetype - 664 sys sys 1077376279 5699
+sys/lib/mimetype - 664 sys sys 1084319210 5694
 sys/lib/newuser - 775 sys sys 1018386991 1229
 sys/lib/plumb - 20000000775 sys sys 944957365 0
 sys/lib/plumb/basic - 664 sys sys 1070330856 2930
@@ -5127,8 +5127,8 @@ sys/man/vol1.ps.gz - 664 sys sys 1020374752 2174519
 sys/src - 20000000775 sys sys 1016902537 0
 sys/src/9 - 20000000775 sys sys 1017795023 0
 sys/src/9/alphapc - 20000000775 sys sys 1018721238 0
-sys/src/9/alphapc/apc - 664 sys sys 1056171197 624
-sys/src/9/alphapc/apccpu - 664 sys sys 1056171198 510
+sys/src/9/alphapc/apc - 664 sys sys 1084331942 629
+sys/src/9/alphapc/apccpu - 664 sys sys 1084331942 531
 sys/src/9/alphapc/arch164.c - 664 sys sys 1015012783 6100
 sys/src/9/alphapc/audio.h - 664 sys sys 1015012783 349
 sys/src/9/alphapc/axp.h - 664 sys sys 1015012783 1090
@@ -5146,7 +5146,7 @@ sys/src/9/alphapc/etherif.h - 664 sys sys 1045063621 1025
 sys/src/9/alphapc/faultalpha.c - 664 sys sys 1015012784 1257
 sys/src/9/alphapc/fdc37c93x.c - 664 sys sys 1015012785 1110
 sys/src/9/alphapc/floppy.h - 664 sys sys 1015012785 3783
-sys/src/9/alphapc/fns.h - 664 sys sys 1067722581 3906
+sys/src/9/alphapc/fns.h - 664 sys sys 1084331942 3901
 sys/src/9/alphapc/fptrap.c - 664 sys sys 1015012785 707
 sys/src/9/alphapc/i8259.c - 664 sys sys 1015012785 3409
 sys/src/9/alphapc/initcode - 664 sys sys 1039753419 779
@@ -5249,7 +5249,7 @@ sys/src/9/boot/testboot.c - 664 sys sys 1039763734 496
 sys/src/9/ip - 20000000775 sys sys 1015278450 0
 sys/src/9/ip/arp.c - 664 sys sys 1078928097 10687
 sys/src/9/ip/chandial.c - 664 sys sys 1022588098 2276
-sys/src/9/ip/devip.c - 664 sys sys 1079538099 24033
+sys/src/9/ip/devip.c - 664 sys sys 1084331653 24164
 sys/src/9/ip/eipconvtest.c - 664 sys sys 1022588098 3135
 sys/src/9/ip/esp.c - 664 sys sys 1047260561 17084
 sys/src/9/ip/ethermedium.c - 664 sys sys 1066514880 15124
@@ -5272,10 +5272,10 @@ sys/src/9/ip/netdevmedium.c - 664 sys sys 1045063517 2675
 sys/src/9/ip/netlog.c - 664 sys sys 1026847568 4003
 sys/src/9/ip/nudp.c - 664 sys sys 1050756592 13069
 sys/src/9/ip/nullmedium.c - 664 sys sys 1022588099 491
-sys/src/9/ip/pktmedium.c - 664 sys sys 1045063516 1355
+sys/src/9/ip/pktmedium.c - 664 sys sys 1084331746 1314
 sys/src/9/ip/ptclbsum.c - 664 sys sys 1022588099 1243
 sys/src/9/ip/rudp.c - 664 sys sys 1055700790 21415
-sys/src/9/ip/tcp.c - 664 sys sys 1076613357 65462
+sys/src/9/ip/tcp.c - 664 sys sys 1084331800 65642
 sys/src/9/ip/tripmedium.c - 664 sys sys 1045063515 7136
 sys/src/9/ip/udp.c - 664 sys sys 1077376216 13146
 sys/src/9/mkfile - 664 sys sys 1063857477 205
@@ -5336,7 +5336,7 @@ sys/src/9/pc/ether2114x.c - 664 sys sys 1081706476 41545
 sys/src/9/pc/ether589.c - 664 sys sys 1015014516 4644
 sys/src/9/pc/ether79c970.c - 664 sys sys 1071245466 14094
 sys/src/9/pc/ether8003.c - 664 sys sys 1015014516 6665
-sys/src/9/pc/ether8139.c - 664 sys sys 1071245462 18026
+sys/src/9/pc/ether8139.c - 664 sys sys 1084331434 18105
 sys/src/9/pc/ether82543gc.c - 664 sys sys 1055689887 32296
 sys/src/9/pc/ether82557.c - 664 sys sys 1081706477 29736
 sys/src/9/pc/ether83815.c - 664 sys sys 1081706477 23479
@@ -5349,7 +5349,7 @@ sys/src/9/pc/etherga620.c - 664 sys sys 1074785126 28754
 sys/src/9/pc/etherga620fw.h - 644 sys sys 1026847642 222295
 sys/src/9/pc/etherif.h - 664 sys sys 1045063564 961
 sys/src/9/pc/etherigbe.c - 664 sys sys 1081706478 42962
-sys/src/9/pc/ethermii.c - 664 sys sys 1039803177 4555
+sys/src/9/pc/ethermii.c - 664 sys sys 1084331434 4612
 sys/src/9/pc/ethermii.h - 664 sys sys 1039895684 3259
 sys/src/9/pc/etherrhine.c - 664 sys sys 1081706478 13799
 sys/src/9/pc/ethersink.c - 664 sys sys 1048644103 1076
@@ -5362,7 +5362,7 @@ sys/src/9/pc/i8253.c - 664 sys sys 1080572900 6240
 sys/src/9/pc/i8259.c - 664 sys sys 1015014519 4423
 sys/src/9/pc/init9.c - 664 sys sys 1040002518 94
 sys/src/9/pc/initcode.s - 664 sys sys 1015014519 282
-sys/src/9/pc/io.h - 664 sys sys 1072972600 8023
+sys/src/9/pc/io.h - 664 sys sys 1084331225 8023
 sys/src/9/pc/kbd.c - 664 sys sys 1079617269 11655
 sys/src/9/pc/l.s - 664 sys sys 1074785126 22699
 sys/src/9/pc/main.c - 664 sys sys 1074785126 14644
@@ -5459,7 +5459,6 @@ sys/src/9/port/devnmouse.c - 664 sys sys 1036812999 3738
 sys/src/9/port/devpipe.c - 664 sys sys 1077055016 5825
 sys/src/9/port/devpnp.c - 664 sys sys 1055688361 13021
 sys/src/9/port/devproc.c - 664 sys sys 1074785145 28636
-sys/src/9/port/devrealtime.c - 664 sys sys 1055688366 16209
 sys/src/9/port/devroot.c - 664 sys sys 1067722764 4254
 sys/src/9/port/devsd.c - 664 sys sys 1071245428 28564
 sys/src/9/port/devsdp.c - 664 sys sys 1057323393 44800
@@ -6935,7 +6934,7 @@ sys/src/cmd/auth/netkey.c - 664 sys sys 1015008431 741
 sys/src/cmd/auth/newns.c - 664 sys sys 1048614962 486
 sys/src/cmd/auth/none.c - 664 sys sys 1071334976 744
 sys/src/cmd/auth/passwd.c - 664 sys sys 1055699009 2761
-sys/src/cmd/auth/pemdecode.c - 664 sys sys 1048614962 942
+sys/src/cmd/auth/pemdecode.c - 664 sys sys 1084330528 947
 sys/src/cmd/auth/pemencode.c - 664 sys sys 1048614963 998
 sys/src/cmd/auth/printnetkey.c - 664 sys sys 1015008430 732
 sys/src/cmd/auth/respond.c - 664 sys sys 1015008432 472
@@ -11961,7 +11960,7 @@ sys/src/libhttpd/httpunesc.c - 664 sys sys 1014930784 888
 sys/src/libhttpd/lower.c - 664 sys sys 1014930784 226
 sys/src/libhttpd/mkfile - 664 sys sys 1035389778 421
 sys/src/libhttpd/okheaders.c - 664 sys sys 1014930784 433
-sys/src/libhttpd/parse.c - 664 sys sys 1014930784 18711
+sys/src/libhttpd/parse.c - 664 sys sys 1084318724 18934
 sys/src/libhttpd/parsereq.c - 664 sys sys 1014930785 5058
 sys/src/libhttpd/query.c - 664 sys sys 1014930785 712
 sys/src/libhttpd/redirected.c - 664 sys sys 1014930785 1555
@@ -12210,7 +12209,7 @@ sys/src/libsec/mkfile - 664 sys sys 1032061454 533
 sys/src/libsec/port - 20000000775 sys sys 1015023365 0
 sys/src/libsec/port/aes.c - 664 sys sys 1016731561 64104
 sys/src/libsec/port/blowfish.c - 664 sys sys 1016466467 19676
-sys/src/libsec/port/decodepem.c - 664 sys sys 1057953187 1383
+sys/src/libsec/port/decodepem.c - 664 sys sys 1084318869 1831
 sys/src/libsec/port/des.c - 664 sys sys 1015013579 17496
 sys/src/libsec/port/des3CBC.c - 664 sys sys 988225292 1135
 sys/src/libsec/port/des3ECB.c - 664 sys sys 988225292 917
@@ -12240,7 +12239,7 @@ sys/src/libsec/port/hmac.c - 664 sys sys 1015013579 1167
 sys/src/libsec/port/hmactest.c - 664 sys sys 984710522 344
 sys/src/libsec/port/md4.c - 664 sys sys 1015013579 4260
 sys/src/libsec/port/md4test.c - 664 sys sys 984710522 537
-sys/src/libsec/port/md5.c - 664 sys sys 985124885 3298
+sys/src/libsec/port/md5.c - 664 sys sys 1084318868 3254
 sys/src/libsec/port/md5block.c - 664 sys sys 985124885 5015
 sys/src/libsec/port/md5pickle.c - 664 sys sys 1081199854 716
 sys/src/libsec/port/mkfile - 664 sys sys 1044931345 879
@@ -12249,13 +12248,13 @@ sys/src/libsec/port/primetest.c - 664 sys sys 984710523 2486
 sys/src/libsec/port/prng.c - 664 sys sys 984710523 187
 sys/src/libsec/port/probably_prime.c - 664 sys sys 984710523 1567
 sys/src/libsec/port/rc4.c - 664 sys sys 1015013580 1415
-sys/src/libsec/port/readcert.c - 664 sys sys 1015013580 777
+sys/src/libsec/port/readcert.c - 664 sys sys 1084318870 1026
 sys/src/libsec/port/reduce - 664 sys sys 984710524 306
 sys/src/libsec/port/rsaalloc.c - 664 sys sys 984710524 657
 sys/src/libsec/port/rsadecrypt.c - 664 sys sys 984710524 749
 sys/src/libsec/port/rsaencrypt.c - 664 sys sys 984710524 192
 sys/src/libsec/port/rsafill.c - 664 sys sys 1045502171 1104
-sys/src/libsec/port/rsagen.c - 664 sys sys 1063853596 1164
+sys/src/libsec/port/rsagen.c - 664 sys sys 1084318869 1462
 sys/src/libsec/port/rsaprivtopub.c - 664 sys sys 984710525 237
 sys/src/libsec/port/rsatest.c - 664 sys sys 984710525 1095
 sys/src/libsec/port/sha1.c - 664 sys sys 985124885 2279
@@ -12264,7 +12263,7 @@ sys/src/libsec/port/sha1pickle.c - 664 sys sys 988225292 717
 sys/src/libsec/port/smallprimes.c - 664 sys sys 984710525 6851
 sys/src/libsec/port/smallprimetest.c - 664 sys sys 984710525 70640
 sys/src/libsec/port/thumb.c - 664 sys sys 1019832052 1891
-sys/src/libsec/port/tlshand.c - 664 sys sys 1048777088 53926
+sys/src/libsec/port/tlshand.c - 664 sys sys 1084318870 54247
 sys/src/libsec/port/x509.c - 664 sys sys 1063853597 50342
 sys/src/libsec/power - 20000000775 sys sys 984710502 0
 sys/src/libsec/power/mkfile - 664 sys sys 1032061453 139

+ 38 - 0
dist/replica/plan9.log

@@ -14979,3 +14979,41 @@
 1083985228 0 c 386/lib/libmp.a - 664 sys sys 1083985019 81428
 1084071649 0 c 386/lib/libmp.a - 664 sys sys 1084071517 77700
 1084244476 0 c 386/lib/libmp.a - 664 sys sys 1084244418 81428
+1084320015 0 c 386/lib/libhttpd.a - 664 sys sys 1084318725 99392
+1084320015 1 c sys/include/libsec.h - 664 sys sys 1084318867 9264
+1084320015 2 c sys/lib/mimetype - 664 sys sys 1084319210 5694
+1084320015 3 c sys/src/libhttpd/parse.c - 664 sys sys 1084318724 18934
+1084320015 4 c sys/src/libsec/port/decodepem.c - 664 sys sys 1084318869 1831
+1084320015 5 c sys/src/libsec/port/md5.c - 664 sys sys 1084318868 3254
+1084320015 6 c sys/src/libsec/port/readcert.c - 664 sys sys 1084318870 1026
+1084320015 7 c sys/src/libsec/port/rsagen.c - 664 sys sys 1084318869 1462
+1084320015 8 c sys/src/libsec/port/tlshand.c - 664 sys sys 1084318870 54247
+1084330818 0 c 386/bin/hget - 775 sys sys 1084329145 226161
+1084330818 1 c 386/bin/lnfs - 775 sys sys 1084329146 100910
+1084330818 2 c 386/bin/md5sum - 775 sys sys 1084329146 59857
+1084330818 3 c 386/bin/webfs - 775 sys sys 1084329148 353886
+1084330818 4 c 386/bin/auth/aescbc - 775 sys sys 1084329144 122190
+1084330818 5 c 386/bin/auth/asn12rsa - 775 sys sys 1084329144 119074
+1084330818 6 c 386/bin/ip/httpd/netlib_history - 775 sys sys 1084329145 113053
+1084330818 7 c 386/bin/ip/httpd/save - 775 sys sys 1084329145 130950
+1084330818 8 c 386/bin/ip/httpd/webls - 775 sys sys 1084329146 129732
+1084330818 9 c 386/bin/tlsclient - 775 sys sys 1084329147 197679
+1084330818 10 c 386/bin/tlssrv - 775 sys sys 1084329147 198229
+1084330818 11 c 386/bin/upas/token - 775 sys sys 1084329147 76755
+1084330818 12 c 386/lib/libc.a - 664 sys sys 1084329149 504790
+1084330818 13 c 386/lib/libhttpd.a - 664 sys sys 1084329149 99398
+1084330818 14 c 386/lib/libmp.a - 664 sys sys 1084329149 78536
+1084330818 15 c 386/lib/libsec.a - 664 sys sys 1084329150 648380
+1084330818 16 c 386/lib/libventi.a - 664 sys sys 1084329151 98178
+1084330818 17 c sys/src/cmd/auth/pemdecode.c - 664 sys sys 1084330528 947
+1084332617 0 c rc/bin/yesterday - 775 sys sys 1084332530 2545
+1084332617 1 c sys/src/9/alphapc/apc - 664 sys sys 1084331942 629
+1084332617 2 c sys/src/9/alphapc/apccpu - 664 sys sys 1084331942 531
+1084332617 3 c sys/src/9/alphapc/fns.h - 664 sys sys 1084331942 3901
+1084332617 4 c sys/src/9/ip/devip.c - 664 sys sys 1084331653 24164
+1084332617 5 c sys/src/9/ip/pktmedium.c - 664 sys sys 1084331746 1314
+1084332617 6 c sys/src/9/ip/tcp.c - 664 sys sys 1084331800 65642
+1084332617 7 c sys/src/9/pc/ether8139.c - 664 sys sys 1084331434 18105
+1084332617 8 c sys/src/9/pc/io.h - 664 sys sys 1084331225 8023
+1084332617 9 c sys/src/9/pc/ethermii.c - 664 sys sys 1084331434 4612
+1084332617 10 d sys/src/9/port/devrealtime.c - 664 sys sys 1055688366 0

+ 1 - 0
rc/bin/src

@@ -50,5 +50,6 @@ for(i){
 	if(test -f $i) go $i
 	if not if(test -f /bin/$i) go /bin/$i
 	if not if(test -f /bin/*/$i) go /bin/*/$i
+	if not if(test -f /bin/*/*/$i) go /bin/*/*/$i
 	if not echo 'src: can''t find '$i
 }

+ 2 - 2
rc/bin/yesterday

@@ -141,10 +141,10 @@ for(i){
 		9fs $xdump
 
 	if(~ $#last 0){
-		xlast=`{ls -t /n/$xdump/$year|sed 1q}
+		xlast=`{ls /n/$xdump/$year|sed -n '$p'}
 		switch($defdump){
 		case snap
-			xlast=`{ls -t $xlast|sed 1q}
+			xlast=`{ls $xlast|sed -n '$p'}
 		}
 	}
 	if not

+ 1 - 0
sys/games/lib/fortunes

@@ -4007,3 +4007,4 @@ httpd_server* httpd_initialize(char* hostname, httpd_sockaddr* sa4P, httpd_socka
 it's easier to post to 9fans than to think. - boyd
 We assume familiarity with Rubik's Cube, the delights of which cannot be presented adequately in a textual description!  - an algorithms textbook
 If you are idle for more than 1000 hours, the system will log you out.  Please save reviews frequently.
+We lead by following standards. - sape

+ 18 - 7
sys/include/libsec.h

@@ -194,6 +194,7 @@ void	rc4back(RC4state*, int);
 /////////////////////////////////////////////////////////
 typedef struct RSApub RSApub;
 typedef struct RSApriv RSApriv;
+typedef struct PEMChain PEMChain;
 
 // public/encryption key
 struct RSApub
@@ -217,6 +218,12 @@ struct RSApriv
 	mpint	*c2;	// (inv p) mod q
 };
 
+struct PEMChain{
+	PEMChain *next;
+	uchar *pem;
+	int pemlen;
+};
+
 RSApriv*	rsagen(int nlen, int elen, int rounds);
 RSApriv*	rsafill(mpint *n, mpint *e, mpint *d, mpint *p, mpint *q);
 mpint*		rsaencrypt(RSApub *k, mpint *in, mpint *out);
@@ -229,11 +236,13 @@ RSApub*		rsaprivtopub(RSApriv*);
 RSApub*		X509toRSApub(uchar*, int, char*, int);
 RSApriv*	asn1toRSApriv(uchar*, int);
 void		asn1dump(uchar *der, int len);
-uchar*		decodepem(char *s, char *type, int *len);
+uchar*		decodePEM(char *s, char *type, int *len, char **new_s);
+PEMChain*	decodepemchain(char *s, char *type);
 uchar*		X509gen(RSApriv *priv, char *subj, ulong valid[2], int *certlen);
 uchar*		X509req(RSApriv *priv, char *subj, int *certlen);
 char*		X509verify(uchar *cert, int ncert, RSApub *pk);
 void		X509dump(uchar *cert, int ncert);
+
 /////////////////////////////////////////////////////////
 // elgamal
 /////////////////////////////////////////////////////////
@@ -329,16 +338,18 @@ typedef struct TLSconn{
 	uchar *sessionID;
 	int certlen, sessionIDlen;
 	int (*trace)(char*fmt, ...);
+	PEMChain *chain; // optional extra certificate evidence for servers to present
 } TLSconn;
 
 // tlshand.c
-extern int tlsClient(int fd, TLSconn *c);
-extern int tlsServer(int fd, TLSconn *c);
+int tlsClient(int fd, TLSconn *c);
+int tlsServer(int fd, TLSconn *c);
 
 // thumb.c
-extern Thumbprint* initThumbprints(char *ok, char *crl);
-extern void freeThumbprints(Thumbprint *ok);
-extern int okThumbprint(uchar *sha1, Thumbprint *ok);
+Thumbprint* initThumbprints(char *ok, char *crl);
+void	freeThumbprints(Thumbprint *ok);
+int		okThumbprint(uchar *sha1, Thumbprint *ok);
 
 // readcert.c
-extern uchar *readcert(char *filename, int *pcertlen);
+uchar	*readcert(char *filename, int *pcertlen);
+PEMChain *readcertchain(char *filename);

+ 1 - 1
sys/lib/mimetype

@@ -66,7 +66,7 @@
 .ltx		application	x-latex		-		y
 .man		application	x-troff-man	-		y
 .me		application	x-troff-me	-		y
-.mid		application	midi		-		y # MIDI music
+.mid		audio		midi		-		y # MIDI music
 .mime		message		rfc822		-		y
 .mod		text		plain		-		y # AMPL et al.
 .mov		video		quicktime	-		y

+ 10 - 6
sys/man/2/rsa

@@ -57,7 +57,7 @@ RSApriv*	asn1toRSApriv(uchar *priv, int npriv)
 void		asn1dump(uchar *der, int len)
 .PP
 .B
-uchar*	decodepem(char *s, char *type, int *len)
+uchar*	decodePEM(char *s, char *type, int *len, char **new_s)
 .PP
 .B
 uchar*	X509gen(RSApriv *priv, char *subj, ulong valid[2], int *certlen);
@@ -172,7 +172,7 @@ structure.
 .I Asn1dump
 prints an ASN1 object to standard output.
 .PP
-.I Decodepem
+.I DecodePEM
 takes a zero terminated string,
 .IR s ,
 and decodes the PEM (privacy-enhanced mail) formatted section for
@@ -180,10 +180,14 @@ and decodes the PEM (privacy-enhanced mail) formatted section for
 within it.
 If successful, it returns the decoded section and sets
 .BI * len
-to its decoded length.
-If not, it returns
-.BR nil ,
-and
+to its decoded length.  If not nil,
+.I new_s
+is set to the first character beyond the
+.I type
+section.
+Otherwise
+.B nil
+is returned and
 .BI * len
 is undefined.
 .SH SOURCE

+ 14 - 1
sys/man/4/vacfs

@@ -18,6 +18,10 @@ vacfs \- a Venti-based file system
 .B -m
 .I mtpt
 ]
+[
+.B -S
+.I srvname
+]
 .I vacfile
 .SH DESCRIPTION
 .I Vacfs
@@ -65,7 +69,16 @@ The location to mount the file system. The default is
 Disables permission checking.
 .TP
 .B -s
-Post the 9P channel on #s/vacfs rather than
+Post the 9P channel in
+.B /srv/vacfs
+rather than
+mounting it on
+.IR mtpt .
+.TP
+.BI -S " srvname
+Post the 9P channel in
+.BI /srv/ srvname
+rather than
 mounting it on
 .IR mtpt .
 .SH SOURCE

+ 1 - 0
sys/src/9/alphapc/apc

@@ -57,6 +57,7 @@ port
 	int cpuserver = 0;
 
 boot
+	tcp
 	il
 
 bootdir

+ 3 - 1
sys/src/9/alphapc/apccpu

@@ -16,7 +16,7 @@ dev
 #	loopback
 
 	ether		netif
-	ip		arp chandial inferno ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum
+	ip		arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum inferno
 
 	sd
 	floppy		dma
@@ -27,6 +27,7 @@ dev
 link
 	ether2114x	pci
 	ethermedium
+	loopbackmedium
 
 misc
 	arch164
@@ -50,6 +51,7 @@ port
 	int cpuserver = 1;
 
 boot cpu
+	tcp
 	il
 
 bootdir

+ 81 - 79
sys/src/9/alphapc/fns.h

@@ -1,78 +1,80 @@
 #include "../port/portfns.h"
 
 Dirtab*	addarchfile(char*, int, long(*)(Chan*,void*,long,vlong), long(*)(Chan*,void*,long,vlong));
-void		archinit(void);
-void		arginit(void);
-void		arith(void);
-void		clearmmucache(void);
-void		clock(Ureg*);
-void		clockinit(void);
-void		clockintrsched(void);
-#define 	coherence 	mb
-int		cistrcmp(char*, char*);
-int		cistrncmp(char*, char*, int);
-void		cpuidprint(void);
-void		cserve(ulong, ulong);
+void	archinit(void);
+void	arginit(void);
+void	arith(void);
+void	clearmmucache(void);
+void	clock(Ureg*);
+void	clockinit(void);
+void	clockintrsched(void);
+#define coherence 	mb
+int	cistrcmp(char*, char*);
+int	cistrncmp(char*, char*, int);
+void	cpuidprint(void);
+void	cserve(ulong, ulong);
 #define cycles(x)
-void		timeradd(Timer *);
-void		timerdel(Timer *);
+void	timeradd(Timer *);
+void	timerdel(Timer *);
 int	dmacount(int);
 int	dmadone(int);
 void	dmaend(int);
 int	dmainit(int, int);
 long	dmasetup(int, void*, long, int);
-void _dumpstack(Ureg *);
-void		evenaddr(ulong);
-void		fataltrap(Ureg *, char *);
-void		fault0(void);
-void		faultalpha(Ureg*);
+void	_dumpstack(Ureg *);
+void	evenaddr(ulong);
+void	fataltrap(Ureg *, char *);
+void	fault0(void);
+void	faultalpha(Ureg*);
 ulong	fcr31(void);
-void		firmware(void);
+void	firmware(void);
 #define	flushpage(s)	icflush()
-void		fpenab(int);
-void		fptrap(Ureg*);
-int		getcfields(char*, char**, int, char*);
-char		*getconf(char*);
+void	fpenab(int);
+void	fptrap(Ureg*);
+int	getcfields(char*, char**, int, char*);
+char	*getconf(char*);
 ulong	getfcr(void);
 ulong	getstatus(void);
-void		gotopc(ulong);
-int		havetimer(void);
-int		i8042auxcmd(int);
-void		i8042auxenable(void (*)(int, int));
-void		i8042reset(void);
+void	gotopc(ulong);
+int	havetimer(void);
+int	i8042auxcmd(int);
+void	i8042auxenable(void (*)(int, int));
+void	i8042reset(void);
 void	i8250console(void);
 void	i8250mouse(char*, int(*)(Queue*,int), int);
-void		i8259init(void);
-int		i8259enable(int, int, Vctl*);
-#define	idlehands()			/* nothing to do in the runproc */
-void		icflush(void);
-void		illegal0(void);
-void		intr0(void);
-void		intrenable(int, void (*)(Ureg*, void*), void*, int, char*);
-int		intrdisable(int, void (*)(Ureg *, void *), void*, int, char*);
-int		ioalloc(int, int, int, char*);
-void		iofree(int);
-void		ioinit(void);
-int		iounused(int, int);
-int		irqallocread(char*, long, vlong);
-int		isaconfig(char*, int, ISAConf*);
-void		kbdinit(void);
+void	i8250setmouseputc(char*, int (*)(Queue*, int));
+void	i8259init(void);
+int	i8259enable(int, int, Vctl*);
+#define	idlehands()		/* nothing to do in the runproc */
+void	icflush(void);
+void	illegal0(void);
+void	intr0(void);
+void	intrenable(int, void (*)(Ureg*, void*), void*, int, char*);
+int	intrdisable(int, void (*)(Ureg *, void *), void*, int, char*);
+int	ioalloc(int, int, int, char*);
+void	iofree(int);
+void	ioinit(void);
+int	iounused(int, int);
+int	irqallocread(char*, long, vlong);
+int	isaconfig(char*, int, ISAConf*);
+void	kbdinit(void);
+#define kexit(a)
 #define	kmapinval()
-void		*kmapv(uvlong, int);
-int		kprint(char*, ...);
-void		launchinit(void);
-void		launch(int);
-void		links(void);
-void		mb(void);
-void 		memholes(void);
+void	*kmapv(uvlong, int);
+int	kprint(char*, ...);
+void	launchinit(void);
+void	launch(int);
+void	links(void);
+void	mb(void);
+void 	memholes(void);
 ulong 	meminit(void);
-void		mmudump(void);
-void		mmuinit(void);
+void	mmudump(void);
+void	mmuinit(void);
 #define	mmunewpage(x)
-void		mmupark(void);
-void		mntdump(void);
-void		ns16552install(void);
-void		ns16552special(int, int, Queue**, Queue**, int (*)(Queue*, int));
+void	mmupark(void);
+void	mntdump(void);
+void	ns16552install(void);
+void	ns16552special(int, int, Queue**, Queue**, int (*)(Queue*, int));
 ulong	pcibarsize(Pcidev*, int);
 int	pcicfgr8(Pcidev*, int);
 int	pcicfgr16(Pcidev*, int);
@@ -80,38 +82,38 @@ int	pcicfgr32(Pcidev*, int);
 void	pcicfgw8(Pcidev*, int, int);
 void	pcicfgw16(Pcidev*, int, int);
 void	pcicfgw32(Pcidev*, int, int);
-void pciclrbme(Pcidev*);
+void	pciclrbme(Pcidev*);
 void	pcihinv(Pcidev*);
 Pcidev* pcimatch(Pcidev*, int, int);
 Pcidev* pcimatchtbdf(int);
 void	pcireset(void);
 void	pcisetbme(Pcidev*);
 int	pcmspecial(char*, ISAConf*);
-int (*_pcmspecial)(char *, ISAConf *);
+int	(*_pcmspecial)(char *, ISAConf *);
 void	pcmspecialclose(int);
-void (*_pcmspecialclose)(int);
-void		prflush(void);
-void		printinit(void);
+void	(*_pcmspecialclose)(int);
+void	prflush(void);
+void	printinit(void);
 #define	procrestore(p)
 void	procsave(Proc*);
 void	procsetup(Proc*);
-void		restfpregs(FPsave*);
-uvlong		rpcc(uvlong*);
-void		screeninit(void);
-void		(*screenputs)(char*, int);
-void 		setpcb(PCB *);
-PCB		*swpctx(PCB *);
-void		syscall0(void);
-int		tas(ulong*);
-void		tlbflush(int, ulong);
-void		touser(void*);
-void		trapinit(void);
-void		unaligned(void);
+void	restfpregs(FPsave*);
+uvlong	rpcc(uvlong*);
+void	screeninit(void);
+void	(*screenputs)(char*, int);
+void 	setpcb(PCB *);
+PCB	*swpctx(PCB *);
+void	syscall0(void);
+int	tas(ulong*);
+void	tlbflush(int, ulong);
+void	touser(void*);
+void	trapinit(void);
+void	unaligned(void);
 ulong	upamalloc(ulong, int, int);
 void	upafree(ulong, int);
-#define		userureg(ur) ((ur)->status & UMODE)
-void		wrent(int, void*);
-void		wrvptptr(uvlong);
+#define	userureg(ur) ((ur)->status & UMODE)
+void	wrent(int, void*);
+void	wrvptptr(uvlong);
 
 #define	waserror()	(up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
 #define	kmapperm(x)	kmap(x)
@@ -126,8 +128,8 @@ void		wrvptptr(uvlong);
 #define	outl(p, x)	(arch->_outl)((p), (x))
 
 #define	insb(p, buf, len)	(arch->_insb)((p), (buf), (len))
-#define	inss(p, buf, len)		(arch->_inss)((p), (buf), (len))
-#define	insl(p, buf, len)		(arch->_insl)((p), (buf), (len))
+#define	inss(p, buf, len)	(arch->_inss)((p), (buf), (len))
+#define	insl(p, buf, len)	(arch->_insl)((p), (buf), (len))
 #define	outsb(p, buf, len)	(arch->_outsb)((p), (buf), (len))
 #define	outss(p, buf, len)	(arch->_outss)((p), (buf), (len))
 #define	outsl(p, buf, len)	(arch->_outsl)((p), (buf), (len))

+ 10 - 0
sys/src/9/ip/devip.c

@@ -456,6 +456,14 @@ ipopen(Chan* c, int omode)
 		if(cv->state != Announced)
 			error("not announced");
 
+		if(waserror()){
+			closeconv(cv);
+			nexterror();
+		}
+		qlock(cv);
+		cv->inuse++;
+		qunlock(cv);
+
 		nc = nil;
 		while(nc == nil) {
 			/* give up if we got a hangup */
@@ -483,6 +491,8 @@ ipopen(Chan* c, int omode)
 			qunlock(&cv->listenq);
 			poperror();
 		}
+		closeconv(cv);
+		poperror();
 		break;
 	}
 	c->mode = openmode(omode);

+ 6 - 6
sys/src/9/ip/pktmedium.c

@@ -8,17 +8,17 @@
 #include "ip.h"
 
 
-static void	pktbind(Ipifc *ifc, int argc, char **argv);
-static void	pktunbind(Ipifc *ifc);
-static void	pktbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip);
-static void	pktin(Fs*, Ipifc *ifc, Block *bp);
+static void	pktbind(Ipifc*, int, char**);
+static void	pktunbind(Ipifc*);
+static void	pktbwrite(Ipifc*, Block*, int, uchar*);
+static void	pktin(Fs*, Ipifc*, Block*);
 
 Medium pktmedium =
 {
 .name=		"pkt",
 .hsize=		14,
-.mintu=	40,
-.maxtu=	4*1024,
+.mintu=		40,
+.maxtu=		4*1024,
 .maclen=	6,
 .bind=		pktbind,
 .unbind=	pktunbind,

+ 4 - 1
sys/src/9/ip/tcp.c

@@ -2182,8 +2182,11 @@ reset:
 	 */
 	for(;;) {
 		if(seg.flags & RST) {
-			if(tcb->state == Established)
+			if(tcb->state == Established) {
 				tpriv->stats[EstabResets]++;
+				if(tcb->rcv.nxt != seg.seq)
+					print("out of order RST rcvd: %I.%d -> %I.%d, rcv.nxt %lux seq %lux\n", s->raddr, s->rport, s->laddr, s->lport, tcb->rcv.nxt, seg.seq);
+			}
 			localclose(s, Econrefused);
 			goto raise;
 		}

+ 8 - 3
sys/src/9/pc/ether8139.c

@@ -278,14 +278,19 @@ rtl8139ifstat(Ether* edev, void* a, long n, ulong offset)
 static int
 rtl8139reset(Ctlr* ctlr)
 {
+	int timeo;
+
 	/*
 	 * Soft reset the controller.
 	 */
 	csr8w(ctlr, Cr, Rst);
-	while(csr8r(ctlr, Cr) & Rst)
-		;
+	for(timeo = 0; timeo < 1000; timeo++){
+		if(!(csr8r(ctlr, Cr) & Rst))
+			return 0;
+		delay(1);
+	}
 
-	return 0;
+	return -1;
 }
 
 static void

+ 9 - 5
sys/src/9/pc/ethermii.c

@@ -14,7 +14,7 @@ int
 mii(Mii* mii, int mask)
 {
 	MiiPhy *miiphy;
-	int bit, phyno, r, rmask;
+	int bit, oui, phyno, r, rmask;
 
 	/*
 	 * Probe through mii for PHYs in mask;
@@ -33,14 +33,18 @@ mii(Mii* mii, int mask)
 		}
 		if(mii->mir(mii, phyno, Bmsr) == -1)
 			continue;
+		r = mii->mir(mii, phyno, Phyidr1);
+		oui = (r & 0x3FFF)<<6;
+		r = mii->mir(mii, phyno, Phyidr2);
+		oui |= r>>10;
+		if(oui == 0xFFFFF || oui == 0)
+			continue;
+
 		if((miiphy = malloc(sizeof(MiiPhy))) == nil)
 			continue;
 
 		miiphy->mii = mii;
-		r = mii->mir(mii, phyno, Phyidr1);
-		miiphy->oui = (r & 0x3FFF)<<6;
-		r = mii->mir(mii, phyno, Phyidr2);
-		miiphy->oui |= r>>10;
+		miiphy->oui = oui;
 		miiphy->phyno = phyno;
 
 		miiphy->anar = ~0;

+ 1 - 1
sys/src/9/pc/io.h

@@ -10,7 +10,7 @@ enum {
 	Vector2F	= 8,		/* double fault */
 	VectorCSO	= 9,		/* coprocessor segment overrun */
 	VectorPF	= 14,		/* page fault */
-	Vector15 = 15,		/* reserved */
+	Vector15	= 15,		/* reserved */
 	VectorCERR	= 16,		/* coprocessor error */
 
 	VectorPIC	= 32,		/* external i8259 interrupts */

+ 0 - 768
sys/src/9/port/devrealtime.c

@@ -1,768 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "error.h"
-#include "realtime.h"
-#include "edf.h"
-
-#pragma	varargck	type	"T"		vlong
-
-/* debugging */
-extern int			edfprint;
-extern Edfinterface	realedf, *edf;
-
-static Schedevent *events;
-static int nevents, revent, wevent;
-static Rendez eventr;
-static QLock elock;
-static Ref logopens;
-static Ref debugopens;
-static uvlong fasthz;	
-
-enum {
-	Qistask = 0x10000,
-	Qdir = 0,
-	Qrealtime,
-	Qclone,
-	Qdebug,
-	Qdump,
-	Qlog,
-	Qnblog,
-	Qresrc,
-	Qtask,
-	Qtime,
-
-	Nevents = 10000,
-	Clockshift = 17,		// Good to about 10GHz clock and max. 5(s)
-};
-
-Dirtab schedrootdir[]={
-	".",			{Qdir, 0, QTDIR},		0,	DMDIR|0555,
-	"realtime",	{Qrealtime, 0, QTDIR},	0,	DMDIR|0555,
-};
-
-Dirtab scheddir[]={
-	".",			{Qrealtime, 0, QTDIR},	0,	DMDIR|0555,
-	"clone",		{Qclone},				0,	0666,
-	"debug",		{Qdebug},				0,	0444,
-	"dump",		{Qdump},				0,	0444,
-	"log",		{Qlog},				0,	0444,	/* one open only */
-	"nblog",		{Qnblog},				0,	0444,	/* nonblocking version of log */
-	"resources",	{Qresrc},				0,	0444,
-	"task",		{Qtask, 0, QTDIR},		0,	DMDIR|0555,
-	"time",		{Qtime},				0,	0444,
-};
-
-static char *schedstatename[] = {
-	[SRelease] =	"Release",
-	[SRun] =		"Run",
-	[SPreempt] =	"Preempt",
-	[SBlock] =		"Block",
-	[SResume] =	"Resume",
-	[SDeadline] =	"Deadline",
-	[SYield] =		"Yield",
-	[SSlice] =		"Slice",
-	[SExpel] =		"Expel",
-};
-
-static int taskno;
-
-static Task *
-taskinit(void)
-{
-	Dirtab *d;
-	Task *t;
-
-	t = malloc(sizeof(Task));
-	if (t == nil)
-		error("taskinit: malloc");
-	d = &t->dir;
-	if (up->user)
-		kstrdup(&t->user, up->user);
-	else
-		kstrdup(&t->user, eve);
-	t->state = EdfExpelled;
-	t->taskno = ++taskno;
-	snprint(d->name, sizeof d->name, "%d", t->taskno);
-	mkqid(&d->qid, Qistask | t->taskno, 0, QTFILE);
-	d->length = 0;
-	d->perm = 0600;
-	enlist(&tasks, t);
-	incref(t);
-	return t;
-}
-
-void
-taskfree(Task *t)
-{
-	if (decref(t))
-		return;
-	assert(t->procs.n == 0);
-	assert(t->csns.n == 0);
-	free(t->user);
-	free(t);
-}
-
-/*
- * the zeroth element of the table MUST be the directory itself for ..
-*/
-int
-schedgen(Chan *c, char*, Dirtab *, int, int i, Dir *dp)
-{
-	Dirtab *tab;
-	int ntab;
-	char *owner;
-	ulong taskindex;
-	Qid qid;
-	Task *t;
-	List *l;
-
-	if((ulong)c->qid.path & Qistask){
-		qlock(&edfschedlock);
-		taskindex = (ulong)c->qid.path & (Qistask-1);
-		if ((t = findtask(taskindex)) == nil){
-			qunlock(&edfschedlock);
-			return -1;
-		}
-	}else if((ulong)c->qid.path == Qtask){
-		qlock(&edfschedlock);
-
-		taskindex = i;
-		SET(t);
-		for (l = tasks.next; l; l = l->next)
-			if ((t = l->i) && taskindex-- == 0)
-				break;
-		if (l == nil){
-			qunlock(&edfschedlock);
-			return -1;
-		}
-	}else {
-		if((ulong)c->qid.path == Qdir){
-			tab = schedrootdir;
-			ntab = nelem(schedrootdir);
-		}else{
-			tab = scheddir;
-			ntab = nelem(scheddir);
-		}
-		if(i != DEVDOTDOT){
-			/* skip over the first element, that for . itself */
-			i++;
-			if(i >= ntab)
-				return -1;
-			tab += i;
-		}
-		devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
-		return 1;
-	}
-	if(i == DEVDOTDOT){
-		mkqid(&qid, Qtask, 0, QTDIR);
-		devdir(c, qid, ".", 0, eve, 0555, dp);
-	}else{
-		owner = t->user;
-		if (owner == nil)
-			owner = eve;
-		tab = &t->dir;
-		devdir(c, tab->qid, tab->name, tab->length, owner, tab->perm, dp);
-	}
-	qunlock(&edfschedlock);
-	return 1;
-}
-
-static void
-_devrt(Task *t, Ticks t1, SEvent etype)
-{
-	if (logopens.ref == 0 || nevents == Nevents)
-		return;
-
-	if(edfprint)iprint("state %s\n", schedstatename[etype]);
-	events[wevent].tid = t->taskno;
-	events[wevent].ts = 0;
-	if (t1)
-		events[wevent].ts = ticks2time(t1);
-	else
-		events[wevent].ts = 0;
-	events[wevent].etype = etype;
-
-	if (!canqlock(&elock)) 
-		return;
-
-	wevent = (wevent + 1) % Nevents;
-	if (nevents < Nevents)
-		nevents++;
-	else
-		revent = (revent + 1) % Nevents;
-
-	if(edfprint)iprint("wakesched\n");
-	/* To avoid circular wakeup when used in combination with 
-	 * EDF scheduling.
-	 */
-	if (eventr.p && eventr.p->state == Wakeme)
-		wakeup(&eventr);
-
-	qunlock(&elock);
-}
-
-static void
-devrtinit(void)
-{
-	fmtinstall('T', timeconv);
-	fmtinstall('U', timeconv);
-	fastticks(&fasthz);
-	devrt = _devrt;
-	events = (Schedevent *)malloc(sizeof(Schedevent) * Nevents);
-	assert(events);
-	nevents = revent = wevent = 0;
-	edf = &realedf;
-}
-
-static Chan *
-devrtattach(char *param)
-{
-	return devattach('R', param);
-}
-
-static Walkqid *
-devrtwalk(Chan *c, Chan *nc, char **name, int nname)
-{
-	return devwalk(c, nc, name, nname, nil, 0, schedgen);
-}
-
-static int
-devrtstat(Chan *c, uchar *db, int n)
-{
-	return devstat(c, db, n, nil, 0, schedgen);
-}
-
-static Chan *
-devrtopen(Chan *c, int mode)
-{
-	Task *t;
-
-	switch ((ulong)c->qid.path){
-	case Qlog:
-	case Qnblog:
-		if (mode != OREAD) 
-			error(Eperm);
-		incref(&logopens);
-		if (logopens.ref > 1){
-			decref(&logopens);
-			error("already open");
-		}
-		break;
-	case Qdebug:
-		if (mode != OREAD) 
-			error(Eperm);
-		incref(&debugopens);
-		if (debugopens.ref > 1){
-			decref(&debugopens);
-			error("already open");
-		}
-		break;
-	case Qdump:
-		if (mode != OREAD) 
-			error(Eperm);
-		break;
-	case Qclone:
-		if (mode == OREAD) 
-			error(Eperm);
-		edf->edfinit();
-		qlock(&edfschedlock);
-		/* open a new task */
-		t = taskinit();
-		c->qid.vers = t->taskno;
-		qunlock(&edfschedlock);
-		break;
-	}
-//	print("open %lux, mode %o\n", (ulong)c->qid.path, mode);
-	return devopen(c, mode, nil, 0, schedgen);
-}
-
-static void
-devrtclose(Chan *c)
-{
-	switch ((ulong)c->qid.path){
-	case Qlog:
-	case Qnblog:
-		nevents = revent = wevent = 0;
-		decref(&logopens);
-		break;
-	case Qdebug:
-		nevents = revent = wevent = 0;
-		decref(&debugopens);
-		break;
-	}
-}
-
-static int
-eventsavailable(void *)
-{
-	return nevents > 0;
-}
-
-static long
-devrtread(Chan *c, void *v, long n, vlong offs)
-{
-	char *p, *e;
-	char buf[1024];
-	long n0;
-	int navail;
-	Task *t;
-	int s, i;
-	Ticks now;
-	Time tim;
-	List *l;
-
-	n0 = n;
-//	print("schedread 0x%lux\n", (ulong)c->qid.path);
-	buf[0] = '\0';
-	switch((ulong)c->qid.path){
-	case Qdir:
-		return devdirread(c, v, n, schedrootdir, nelem(schedrootdir), devgen);
-
-	case Qrealtime:
-		return devdirread(c, v, n, scheddir, nelem(scheddir), devgen);
-
-	case Qtask:
-		return devdirread(c, v, n, nil, 0, schedgen);
-
-	case Qtime:
-		if (n < sizeof(Time))
-			error(Ebadarg);
-		now = fastticks(nil);
-		tim = ticks2time(now);
- 		memmove(v, &tim, sizeof(Time));
-		n -= sizeof(Ticks);
-		if (n >= sizeof(Ticks)){
-			memmove((char*)v + sizeof(Time), &now, sizeof(Ticks));
-			n -= sizeof(Ticks);
-		}
-		if (n >= sizeof(Ticks)){
-			memmove((char*)v + sizeof(Time) + sizeof(Ticks), &fasthz, sizeof(Ticks));
-			n -= sizeof(Ticks);
-		}
-		break;
-
-	case Qnblog:
-		if (eventsavailable(nil))
-			goto getevnt;
-		break;
-
-	case Qlog:
-
-		while (!eventsavailable(nil))
-			sleep(&eventr, eventsavailable, nil);
-	getevnt:
-
-		p = (char *)v;
-
-		navail = nevents;
-		if (navail > n / sizeof(Schedevent))
-			navail = n / sizeof(Schedevent);
-		n -= navail * sizeof(Schedevent);
-
-		qlock(&elock);
-		while (navail > 0) {
-			int ncopy;
-
-			ncopy = (revent + navail > Nevents)? Nevents - revent: navail;
-			memmove(p, &events[revent], ncopy * sizeof(Schedevent));
-			revent = (revent+ ncopy) % Nevents;
-			p += ncopy * sizeof(Schedevent);
-			navail -= ncopy;
-			nevents -= ncopy;
-		}
-		qunlock(&elock);
-		break;
-	case Qresrc:
-		qlock(&edfschedlock);
-		if(waserror()){
-			qunlock(&edfschedlock);
-			nexterror();
-		}
-		seprintresources(buf, buf + sizeof(buf));
-		qunlock(&edfschedlock);
-		poperror();
-		return readstr(offs, v, n, buf);
-		break;
-	case Qdump:
-		p = buf;
-		e = p + sizeof(buf);
-		qlock(&edfschedlock);
-		qunlock(&edfschedlock);
-		seprint(p, e, "\n");
-		return readstr(offs, v, n, buf);
-	case Qdebug:
-		p = buf;
-		e = p + sizeof(buf);
-		ilock(&edflock);
-		now = fastticks(nil);
-		for (i = 0; i < conf.nmach; i++){
-			p = seprint(p, e, "edfstack[%d]\n", i);
-			p = dumpq(p, e, edfstack + i, now);
-		}
-		p = seprint(p, e, "qreleased\n");
-		p = dumpq(p, e, &qreleased, now);
-		p = seprint(p, e, "qwaitrelease\n");
-		p = dumpq(p, e, &qwaitrelease, now);
-		p = seprint(p, e, "qextratime\n");
-		dumpq(p, e, &qextratime, now);
-		iunlock(&edflock);
-		return readstr(offs, v, n, buf);
-	case Qclone:
-		s = c->qid.vers;
-		goto common;
-	default:
-		if ((c->qid.path & Qistask) == 0)
-			error(Enonexist);
-		s = (ulong)c->qid.path & (Qistask - 1);
-	common:
-		qlock(&edfschedlock);
-		t = findtask(s);
-		if (t == nil){
-			qunlock(&edfschedlock);
-			error(Enonexist);
-		}
-		p = buf;
-		e = p + sizeof(buf);
-		p = seprint(p, e, "task=%d", s);
-		p = seprint(p, e, " state=%s", edfstatename[t->state]);
-		if (t->T)
-			p = seprint(p, e, " T=%T", ticks2time(t->T));
-		if (t->D)
-			p = seprint(p, e, " D=%T", ticks2time(t->D));
-		if (t->C)
-			p = seprint(p, e, " C=%T", ticks2time(t->C));
-		if (t->Delta)
-			p = seprint(p, e, " Δ=%T", ticks2time(t->Delta));
-		else if (t->testDelta)
-			p = seprint(p, e, " testΔ=%T", ticks2time(t->testDelta));
-		p = seprint(p, e, " yieldonblock=%d", (t->flags & Verbose) != 0);
-		if (t->csns.n){
-			p = seprint(p, e, " resources='");
-			p = seprintcsn(p, e, &t->csns);
-			p = seprint(p, e, "'");
-		}
-		if (t->procs.n){
-			p = seprint(p, e, " procs='");
-			for (l = t->procs.next; l; l = l->next){
-				Proc *pr = l->i;
-				assert(pr);
-				if (l != t->procs.next)
-					p = seprint(p, e, " ");
-				p = seprint(p, e, "%lud", pr->pid);
-			}
-			p = seprint(p, e, "'");
-		}
-		if (t->periods)
-			p = seprint(p, e, " n=%lud", t->periods);
-		if (t->missed)
-			p = seprint(p, e, " m=%lud", t->missed);
-		if (t->preemptions)
-			p = seprint(p, e, " p=%lud", t->preemptions);
-		if (t->total)
-			p = seprint(p, e, " t=%T", ticks2time(t->total));
-		if (t->aged)
-			p = seprint(p, e, " c=%T", ticks2time(t->aged));
-		seprint(p, e, "\n");
-		qunlock(&edfschedlock);
-		return readstr(offs, v, n, buf);
-	}
-	return n0 - n;
-}
-
-static long
-devrtwrite(Chan *c, void *va, long n, vlong)
-{
-	char *a, *v, *e, *args[16], *rargs[16], buf[512];
-	int i, j, s, nargs, nrargs, add;
-	Resource *r;
-	Task *t;
-	Ticks ticks;
-	Time time;
-	long pid;
-	Proc *p;
-	CSN *l;
-
-	a = va;
-	if (c->mode == OREAD)
-		error(Eperm);
-	switch((ulong)c->qid.path){
-	case Qclone:
-		s = c->qid.vers;
-		goto common;
-	default:
-		if ((c->qid.path & Qistask) == 0)
-			error(Enonexist);
-		s = (ulong)c->qid.path & (Qistask - 1);
-	common:
-		qlock(&edfschedlock);
-		if (waserror()){
-			qunlock(&edfschedlock);
-			nexterror();
-		}
-		t = findtask(s);
-		if (t == nil)
-			error(Enonexist);
-		if(n >= sizeof(buf))
-			n = sizeof(buf)-1;
-		strncpy(buf, a, n);
-		buf[n] = 0;
-		nargs = tokenize(buf, args, nelem(args));
-		for (i = 0; i < nargs; i++){
-			a = args[i];
-			add  = 0;
-			if (v = strchr(a, '=')){
-				*v = '\0';
-				if (v != a && v[-1] == '+'){
-					add = 1;
-					v[-1] = '\0';
-				} else if (v != a && v[-1] == '-'){
-					add = -1;
-					v[-1] = '\0';
-				}
-				v++;
-			}
-			if (strcmp(a, "T") == 0){
-				if (e=parsetime(&time, v))
-					error(e);
-				ticks = time2ticks(time);
-				edf->edfexpel(t);
-				switch(add){
-				case -1:
-					if (ticks > t->T)
-						t->T = 0;
-					else
-						t->T -= ticks;
-					break;
-				case 0:
-					t->T = ticks;
-					break;
-				case 1:
-					t->T += ticks;
-					break;
-				}
-				if (t->T < time2ticks(10000000/HZ))
-					error("period too short");
-				DEBUG("Task %d, T=%T\n", t->taskno, ticks2time(t->T));
-			}else if (strcmp(a, "D") == 0){
-				if (e=parsetime(&time, v))
-					error(e);
-				ticks = time2ticks(time);
-				edf->edfexpel(t);
-				switch(add){
-				case -1:
-					if (ticks > t->D)
-						t->D = 0;
-					else
-						t->D -= ticks;
-					break;
-				case 0:
-					t->D = ticks;
-					break;
-				case 1:
-					t->D += ticks;
-					break;
-				}
-				DEBUG("Task %d, D=%T\n", t->taskno, ticks2time(t->D));
-			}else if (strcmp(a, "C") == 0){
-				if (e=parsetime(&time, v))
-					error(e);
-				ticks = time2ticks(time);
-				edf->edfexpel(t);
-				switch(add){
-				case -1:
-					if (ticks > t->C)
-						t->C = 0;
-					else
-						t->C -= ticks;
-					break;
-				case 0:
-					t->C = ticks;
-					break;
-				case 1:
-					t->C += ticks;
-					break;
-				}
-				if (t->C < time2ticks(10000000/HZ))
-					error("cost too small");
-				DEBUG("Task %d, C=%T\n", t->taskno, ticks2time(t->C));
-			}else if (strcmp(a, "resources") == 0){
-				if (v == nil)
-					error("resources: value missing");
-				edf->edfexpel(t);
-				if (add < 0)
-					error("can't remove resources yet");
-				if (add == 0){
-					List *l;
-	
-					while (l = t->csns.next) {
-						r = l->i;
-						assert(r);
-						if (delist(&r->tasks, t))
-							taskfree(t);
-						if (delist(&t->csns, r))
-							resourcefree(r);
-					}
-					assert(t->csns.n == 0);
-					add = 1;
-					USED(add);
-				}
-				v = parseresource(&t->csns, nil, v);
-				if (v && *v)
-					error("resources: parse error");
-			}else if (strcmp(a, "acquire") == 0){
-				if (v == nil)
-					error("acquire: value missing");
-				if (up->task != t)
-					error("acquire: not for another task");
-				if ((r = resource(v, 0)) == nil)
-					error("acquire: no such resource");
-				for (l = (CSN*)t->csns.next; l; l = (CSN*)l->next){
-					if (l->i == r){
-DEBUG("l->p (0x%p) == t->curcsn (0x%p) && l->S (%T) != 0\n", l->p, t->curcsn, ticks2time(l->S));
-						if(l->p == t->curcsn && l->S != 0)
-						break;
-					}
-				}
-				if (l == nil)
-					error("acquire: no access or resource exhausted");
-				edf->resacquire(t, l);
-			}else if (strcmp(a, "release") == 0){
-				if (v == nil)
-					error("release: value missing");
-				if (up->task != t)
-					error("release: not for another task");
-				if ((r = resource(v, 0)) == nil)
-					error("release: no such resource");
-				if (t->curcsn->i != r)
-					error("release: release not held or illegal release order");
-				edf->resrelease(t);
-			}else if (strcmp(a, "procs") == 0){
-				if (v == nil)
-					error("procs: value missing");
-				if (add <= 0){
-					edf->edfexpel(t);
-				}
-				if (add == 0){
-					List *l;
-
-					while (l = t->procs.next){
-						p = l->i;
-						assert(p->task == t);
-						delist(&t->procs, p);
-						p->task = nil;
-					}
-					add = 1;
-				}
-				nrargs = tokenize(v, rargs, nelem(rargs));
-				for (j = 0; j < nrargs; j++){
-					if (strcmp("self", rargs[j]) == 0){
-						p = up;
-					}else{
-						pid = atoi(rargs[j]);
-						if (pid <= 0)
-							error("bad process number");
-						s = procindex(pid);
-						if(s < 0)
-							error("no such process");
-						p = proctab(s);
-					}
-					if(p->task && p->task != t)
-						error("proc belongs to another task");
-					if (add > 0){
-						enlist(&t->procs, p);
-						p->task = t;
-					}else{
-						delist(&t->procs, p);
-						p->task = nil;
-					}
-				}
-			}else if (strcmp(a, "admit") == 0){
-				if (e = edf->edfadmit(t))
-					error(e);
-			}else if (strcmp(a, "besteffort") == 0){
-				t->T = Infinity;
-				t->D = Infinity;
-				t->C = 0;
-				t->flags |= BestEffort;
-				if (e = edf->edfadmit(t))
-					error(e);
-			}else if (strcmp(a, "expel") == 0){
-				edf->edfexpel(t);
-			}else if (strcmp(a, "remove") == 0){
-				removetask(t);
-				poperror();
-				qunlock(&edfschedlock);
-				return n;	/* Ignore any subsequent commands */
-			}else if (strcmp(a, "verbose") == 0){
-				if (t->flags & Verbose)
-					t->flags &= ~Verbose;
-				else
-					t->flags |= Verbose;
-			}else if (strcmp(a, "yieldonblock") == 0){
-				if (v == nil)
-					error("yieldonblock: value missing");
-				if (add != 0)
-					error("yieldonblock: cannot increment/decrement");
-				if (atoi(v) == 0)
-					t->flags &= ~Useblocking;
-				else
-					t->flags |= Useblocking;
-			}else if (strcmp(a, "yield") == 0){
-				if (edf->isedf(up) && up->task == t){
-					edf->edfdeadline(up);	/* schedule next release */
-					qunlock(&edfschedlock);
-					sched();
-					qlock(&edfschedlock);
-				}else
-					error("yield outside task");
-			}else
-				error("unrecognized command");
-		}
-		poperror();
-		qunlock(&edfschedlock);
-	}
-	return n;
-}
-
-static void
-devrtremove(Chan *c)
-{
-	int s;
-	Task *t;
-
-	if ((c->qid.path & Qistask) == 0)
-		error(Eperm);
-	s = (ulong)c->qid.path & (Qistask - 1);
-	t = findtask(s);
-	if (t == nil)
-		error(Enonexist);
-	qlock(&edfschedlock);
-	removetask(t);
-	qunlock(&edfschedlock);
-}
-
-Dev realtimedevtab = {
-	'R',
-	"scheduler",
-
-	devreset,
-	devrtinit,
-	devshutdown,
-	devrtattach,
-	devrtwalk,
-	devrtstat,
-	devrtopen,
-	devcreate,
-	devrtclose,
-	devrtread,
-	devbread,
-	devrtwrite,
-	devbwrite,
-	devrtremove,
-	devwstat,
-};

+ 1 - 1
sys/src/cmd/auth/pemdecode.c

@@ -50,7 +50,7 @@ main(int argc, char **argv)
 		tot += n;
 	}
 	buf[tot] = 0;
-	bin = decodepem(buf, tag, &len);
+	bin = decodePEM(buf, tag, &len, nil);
 	if(bin == nil)
 		sysfatal("cannot extract section '%s' from pem", tag);
 	if((n=write(1, bin, len)) != len)

+ 1 - 0
sys/src/cmd/aux/mkfile

@@ -43,6 +43,7 @@ UPDATE=\
 </sys/src/cmd/mkmany
 
 DIRS=mnihongo\
+	bandt2\
 	flashfs\
 	na\
 	vga

+ 1 - 1
sys/src/cmd/fossil/conf.rc

@@ -5,7 +5,7 @@
 
 rfork e
 fn usage {
-	echo 'usage: fossil/conf [-w] /dev/sdC0/fossil' >[1=2]
+	echo 'usage: fossil/conf [-w] /dev/sdC0/fossil [config]' >[1=2]
 	exit usage
 }
 

+ 20 - 7
sys/src/cmd/vac/vacfs.c

@@ -126,7 +126,7 @@ notifyf(void *a, char *s)
 void
 main(int argc, char *argv[])
 {
-	char *defmnt;
+	char *defmnt, *defsrv, *srv;
 	int p[2];
 	char buf[12];
 	int fd;
@@ -136,6 +136,7 @@ main(int argc, char *argv[])
 	int readOnly = 1;
 
 	defmnt = "/n/vac";
+	defsrv = "vacfs";
 	ARGBEGIN{
 	case 'd':
 		fmtinstall('F', fcallfmt);
@@ -145,7 +146,7 @@ main(int argc, char *argv[])
 		ncache = atoi(ARGF());
 		break;
 	case 'i':
-		defmnt = 0;
+		defmnt = nil;
 		stdio = 1;
 		mfd[0] = 0;
 		mfd[1] = 1;
@@ -153,8 +154,11 @@ main(int argc, char *argv[])
 	case 'h':
 		host = ARGF();
 		break;
+	case 'S':
+		defsrv = ARGF();
+		/*FALLTHROUGH*/
 	case 's':
-		defmnt = 0;
+		defmnt = nil;
 		break;
 	case 'p':
 		noperm = 1;
@@ -179,12 +183,14 @@ main(int argc, char *argv[])
 		mfd[0] = p[0];
 		mfd[1] = p[0];
 		if(defmnt == 0){
-			fd = create("#s/vacfs", OWRITE, 0666);
+			srv = smprint("/srv/%s", defsrv);
+			fd = create(srv, OWRITE, 0666);
 			if(fd < 0)
-				sysfatal("create of /srv/vacfs failed: %r");
+				sysfatal("create of %s failed: %r", srv);
 			sprint(buf, "%d", p[1]);
 			if(write(fd, buf, strlen(buf)) < 0)
-				sysfatal("writing /srv/vacfs: %r");
+				sysfatal("writing %s: %r", srv);
+			free(srv);
 		}
 	}
 
@@ -209,7 +215,14 @@ main(int argc, char *argv[])
 void
 usage(void)
 {
-	fprint(2, "usage: %s [-sd] [-h host] [-c ncache] [-m mountpoint] vacfile\n", argv0);
+	fprint(2, "usage: %s"
+		" [-sd]"
+		" [-h host]"
+		" [-c ncache]"
+		" [-m mountpoint]"
+		" [-S srvname]"
+		" vacfile"
+		"\n", argv0);
 	exits("usage");
 }
 

+ 6 - 0
sys/src/libhttpd/parse.c

@@ -338,6 +338,12 @@ mimeok(Hlex *h, char *name, int multipart, HContent *head)
 					head->q = v;
 				else if(strcmp(s, "mxb") == 0)
 					head->mxb = v;
+				else{
+					/* cope with accept: application/xhtml+xml; profile=http://www.wapforum.org/xhtml, */
+					while(lex(h) == Word || (h->tok != ',' && h->eol == 0) )
+						;
+					return mimeok(h, name, multipart, head);
+				}
 			}
 			break;
 		case ',':

+ 29 - 1
sys/src/libsec/port/decodepem.c

@@ -6,7 +6,7 @@
 #define STRLEN(s)	(sizeof(s)-1)
 
 uchar*
-decodepem(char *s, char *type, int *len)
+decodePEM(char *s, char *type, int *len, char **new_s)
 {
 	uchar *d;
 	char *t, *e, *tt;
@@ -44,6 +44,8 @@ decodepem(char *s, char *type, int *len)
 		return nil;
 	}
 
+	if(new_s)
+		*new_s = tt+1;
 	n = ((tt - t) * 6 + 7) / 8;
 	d = malloc(n);
 	if(d == nil){
@@ -59,3 +61,29 @@ decodepem(char *s, char *type, int *len)
 	*len = n;
 	return d;
 }
+
+PEMChain*
+decodepemchain(char *s, char *type)
+{
+	PEMChain *first = nil, *last = nil, *chp;
+	uchar *d;
+	char *e;
+	int n;
+
+	e = strchr(s, '\0');
+	while (s < e) {
+		d = decodePEM(s, type, &n, &s);
+		if(d == nil)
+			break;
+		chp = malloc(sizeof(PEMChain));
+		chp->next = nil;
+		chp->pem = d;
+		chp->pemlen = n;
+		if (first == nil)
+			first = chp;
+		else
+			last->next = chp;
+		last = chp;
+	}
+	return first;
+}

+ 0 - 1
sys/src/libsec/port/md5.c

@@ -28,7 +28,6 @@
  */
 
 static void encode(uchar*, u32int*, ulong);
-static void decode(u32int*, uchar*, ulong);
 
 extern void _md5block(uchar*, ulong, u32int*);
 

+ 16 - 1
sys/src/libsec/port/readcert.c

@@ -40,7 +40,7 @@ readcert(char *filename, int *pcertlen)
 		werrstr("can't read %s", filename);
 		return nil;
 	}
-	binary = decodepem(pem, "CERTIFICATE", pcertlen);
+	binary = decodePEM(pem, "CERTIFICATE", pcertlen, nil);
 	free(pem);
 	if(binary == nil){
 		werrstr("can't parse %s", filename);
@@ -49,3 +49,18 @@ readcert(char *filename, int *pcertlen)
 	return binary;
 }
 
+PEMChain *
+readcertchain(char *filename)
+{
+	char *chfile;
+	PEMChain *chp;
+
+	chfile = readfile(filename);
+	if (chfile == nil) {
+		werrstr("can't read %s", filename);
+		return nil;
+	}
+	chp = decodepemchain(chfile, "CERTIFICATE");
+	return chp;
+}
+

+ 8 - 2
sys/src/libsec/port/rsagen.c

@@ -16,8 +16,8 @@ rsagen(int nlen, int elen, int rounds)
 	phi = mpnew(nlen);
 
 	// create the prime factors and euclid's function
-	genstrongprime(p, nlen/2, rounds);
-	genstrongprime(q, nlen - mpsignif(p) + 1, rounds);
+	genprime(p, nlen/2, rounds);
+	genprime(q, nlen - mpsignif(p) + 1, rounds);
 	mpmul(p, q, n);
 	mpsub(p, mpone, e);
 	mpsub(q, mpone, d);
@@ -27,6 +27,12 @@ rsagen(int nlen, int elen, int rounds)
 	t1 = mpnew(0);
 	t2 = mpnew(0);
 	mprand(elen, genrandom, e);
+	if(mpcmp(e,mptwo) <= 0)
+		itomp(3, e);
+	// See Menezes et al. p.291 "8.8 Note (selecting primes)" for discussion
+	// of the merits of various choices of primes and exponents.  e=3 is a
+	// common and recommended exponent, but doesn't necessarily work here
+	// because we chose strong rather than safe primes.
 	for(;;){
 		mpextendedgcd(e, phi, t1, d, t2);
 		if(mpcmp(t1, mpone) == 0)

+ 20 - 5
sys/src/libsec/port/tlshand.c

@@ -248,7 +248,7 @@ static uchar compressors[] = {
 	CompressionNull,
 };
 
-static TlsConnection *tlsServer2(int ctl, int hand, uchar *cert, int ncert, int (*trace)(char*fmt, ...));
+static TlsConnection *tlsServer2(int ctl, int hand, uchar *cert, int ncert, int (*trace)(char*fmt, ...), PEMChain *chain);
 static TlsConnection *tlsClient2(int ctl, int hand, uchar *csid, int ncsid, int (*trace)(char*fmt, ...));
 
 static void	msgClear(Msg *m);
@@ -337,7 +337,7 @@ tlsServer(int fd, TLSconn *conn)
 		return -1;
 	}
 	fprint(ctl, "fd %d 0x%x", fd, ProtocolVersion);
-	tls = tlsServer2(ctl, hand, conn->cert, conn->certlen, conn->trace);
+	tls = tlsServer2(ctl, hand, conn->cert, conn->certlen, conn->trace, conn->chain);
 	sprint(dname, "#a/tls/%s/data", buf);
 	data = open(dname, ORDWR);
 	close(fd);
@@ -412,15 +412,27 @@ tlsClient(int fd, TLSconn *conn)
 	return data;
 }
 
+static int
+countchain(PEMChain *p)
+{
+	int i = 0;
+
+	while (p) {
+		i++;
+		p = p->next;
+	}
+	return i;
+}
+
 static TlsConnection *
-tlsServer2(int ctl, int hand, uchar *cert, int ncert, int (*trace)(char*fmt, ...))
+tlsServer2(int ctl, int hand, uchar *cert, int ncert, int (*trace)(char*fmt, ...), PEMChain *chp)
 {
 	TlsConnection *c;
 	Msg m;
 	Bytes *csid;
 	uchar sid[SidSize], kd[MaxKeyData];
 	char *secrets;
-	int cipher, compressor, nsid, rv;
+	int cipher, compressor, nsid, rv, numcerts, i;
 
 	if(trace)
 		trace("tlsServer2\n");
@@ -498,9 +510,12 @@ tlsServer2(int ctl, int hand, uchar *cert, int ncert, int (*trace)(char*fmt, ...
 	msgClear(&m);
 
 	m.tag = HCertificate;
-	m.u.certificate.ncert = 1;
+	numcerts = countchain(chp);
+	m.u.certificate.ncert = 1 + numcerts;
 	m.u.certificate.certs = emalloc(m.u.certificate.ncert * sizeof(Bytes));
 	m.u.certificate.certs[0] = makebytes(cert, ncert);
+	for (i = 0; i < numcerts && chp; i++, chp = chp->next)
+		m.u.certificate.certs[i+1] = makebytes(chp->pem, chp->pemlen);
 	if(!msgSend(c, &m, AQueue))
 		goto Err;
 	msgClear(&m);