Browse Source

Plan 9 from Bell Labs 2007-03-26

David du Colombier 14 years ago
parent
commit
98584bfd83
75 changed files with 19598 additions and 125 deletions
  1. 81 6
      dist/replica/_plan9.db
  2. 81 6
      dist/replica/plan9.db
  3. 81 0
      dist/replica/plan9.log
  4. 14 0
      rc/bin/diskparts
  5. 8 6
      rc/bin/man
  6. 2 7
      rc/bin/termrc
  7. 153 97
      sys/lib/lp/process/generic
  8. 13 1
      sys/lib/tmac/tmac.an
  9. 75 0
      sys/man/2/lock
  10. 298 0
      sys/man/4/cwfs
  11. 20 0
      sys/src/cmd/cwfs/32bit.h
  12. 22 0
      sys/src/cmd/cwfs/64bit.h
  13. 31 0
      sys/src/cmd/cwfs/9netics32.16k/conf.c
  14. 36 0
      sys/src/cmd/cwfs/9netics32.16k/dat.h
  15. 2 0
      sys/src/cmd/cwfs/9netics32.16k/mkfile
  16. 31 0
      sys/src/cmd/cwfs/9netics64.8k/conf.c
  17. 36 0
      sys/src/cmd/cwfs/9netics64.8k/dat.h
  18. 2 0
      sys/src/cmd/cwfs/9netics64.8k/mkfile
  19. 1636 0
      sys/src/cmd/cwfs/9p1.c
  20. 116 0
      sys/src/cmd/cwfs/9p1.h
  21. 523 0
      sys/src/cmd/cwfs/9p1lib.c
  22. 1856 0
      sys/src/cmd/cwfs/9p2.c
  23. 8 0
      sys/src/cmd/cwfs/README
  24. 112 0
      sys/src/cmd/cwfs/all.h
  25. 326 0
      sys/src/cmd/cwfs/auth.c
  26. 838 0
      sys/src/cmd/cwfs/chk.c
  27. 31 0
      sys/src/cmd/cwfs/choline/conf.c
  28. 36 0
      sys/src/cmd/cwfs/choline/dat.h
  29. 2 0
      sys/src/cmd/cwfs/choline/mkfile
  30. 844 0
      sys/src/cmd/cwfs/con.c
  31. 1037 0
      sys/src/cmd/cwfs/config.c
  32. 309 0
      sys/src/cmd/cwfs/console.c
  33. 2259 0
      sys/src/cmd/cwfs/cw.c
  34. 32 0
      sys/src/cmd/cwfs/cwfs/conf.c
  35. 36 0
      sys/src/cmd/cwfs/cwfs/dat.h
  36. 2 0
      sys/src/cmd/cwfs/cwfs/mkfile
  37. 150 0
      sys/src/cmd/cwfs/data.c
  38. 337 0
      sys/src/cmd/cwfs/dentry.c
  39. 68 0
      sys/src/cmd/cwfs/doc/changes
  40. 181 0
      sys/src/cmd/cwfs/doc/emelie.boot
  41. 29 0
      sys/src/cmd/cwfs/doc/user.mode.boot
  42. 25 0
      sys/src/cmd/cwfs/doc/words
  43. 128 0
      sys/src/cmd/cwfs/doc/worm.fs
  44. 81 0
      sys/src/cmd/cwfs/doc/worm.fs64
  45. 150 0
      sys/src/cmd/cwfs/doc/worms.32-bit
  46. 33 0
      sys/src/cmd/cwfs/emelie/conf.c
  47. 36 0
      sys/src/cmd/cwfs/emelie/dat.h
  48. 1 0
      sys/src/cmd/cwfs/emelie/map.w2-w0
  49. 2 0
      sys/src/cmd/cwfs/emelie/mkfile
  50. 32 0
      sys/src/cmd/cwfs/fs/conf.c
  51. 36 0
      sys/src/cmd/cwfs/fs/dat.h
  52. 2 0
      sys/src/cmd/cwfs/fs/mkfile
  53. 31 0
      sys/src/cmd/cwfs/fs64/conf.c
  54. 36 0
      sys/src/cmd/cwfs/fs64/dat.h
  55. 2 0
      sys/src/cmd/cwfs/fs64/mkfile
  56. 105 0
      sys/src/cmd/cwfs/fworm.c
  57. 38 0
      sys/src/cmd/cwfs/io.h
  58. 289 0
      sys/src/cmd/cwfs/iobuf.c
  59. 1329 0
      sys/src/cmd/cwfs/juke.c
  60. 83 0
      sys/src/cmd/cwfs/lrand.c
  61. 573 0
      sys/src/cmd/cwfs/main.c
  62. 130 0
      sys/src/cmd/cwfs/malloc.c
  63. 8 0
      sys/src/cmd/cwfs/mkfile
  64. 285 0
      sys/src/cmd/cwfs/mworm.c
  65. 454 0
      sys/src/cmd/cwfs/net.c
  66. 92 0
      sys/src/cmd/cwfs/pc.c
  67. 773 0
      sys/src/cmd/cwfs/portdat.h
  68. 246 0
      sys/src/cmd/cwfs/portfns.h
  69. 61 0
      sys/src/cmd/cwfs/portmkfile
  70. 423 0
      sys/src/cmd/cwfs/scsi.c
  71. 1537 0
      sys/src/cmd/cwfs/sub.c
  72. 117 0
      sys/src/cmd/cwfs/time.c
  73. 582 0
      sys/src/cmd/cwfs/uidgid.c
  74. 122 0
      sys/src/cmd/cwfs/wren.c
  75. 2 2
      sys/src/libauthsrv/readnvram.c

+ 81 - 6
dist/replica/_plan9.db

@@ -5444,6 +5444,7 @@ rc/bin/delkey - 775 sys sys 1109429137 643
 rc/bin/dial - 20000000775 sys sys 1059180057 0
 rc/bin/diffy - 775 sys sys 1140694870 277
 rc/bin/dircp - 775 sys sys 1169490692 234
+rc/bin/diskparts - 775 sys sys 1174849973 392
 rc/bin/doc2ps - 775 sys sys 1069793831 244
 rc/bin/doc2txt - 775 sys sys 1025197880 563
 rc/bin/doctype - 775 sys sys 1162921755 1727
@@ -5469,7 +5470,7 @@ rc/bin/leak - 775 sys sys 1172760642 1921
 rc/bin/lookman - 775 sys sys 1017679344 686
 rc/bin/lp - 775 sys sys 1162105982 5201
 rc/bin/mail - 775 sys sys 1045504003 138
-rc/bin/man - 775 sys sys 1173755398 2504
+rc/bin/man - 775 sys sys 1174803269 2639
 rc/bin/map - 775 sys sys 945617207 1576
 rc/bin/mapdemo - 775 sys sys 945617207 4075
 rc/bin/membername - 775 sys sys 945617207 89
@@ -5559,7 +5560,7 @@ rc/bin/start - 775 sys sys 945617209 120
 rc/bin/stock - 775 sys sys 1143126371 292
 rc/bin/stop - 775 sys sys 945617209 110
 rc/bin/tel - 775 sys sys 1161209756 128
-rc/bin/termrc - 775 sys sys 1164658821 2647
+rc/bin/termrc - 775 sys sys 1174850048 2434
 rc/bin/thesaurus - 775 sys sys 1068054167 246
 rc/bin/tlsclienttunnel - 775 sys sys 1024375633 153
 rc/bin/tlssrvtunnel - 775 sys sys 1024375634 175
@@ -6568,7 +6569,7 @@ sys/lib/lp/process - 20000000775 sys sys 1077670465 0
 sys/lib/lp/process/dpost - 775 sys sys 1015012079 2412
 sys/lib/lp/process/dvipost - 775 sys sys 954037459 3123
 sys/lib/lp/process/g3post - 775 sys sys 954037459 2348
-sys/lib/lp/process/generic - 775 sys sys 1077715118 4805
+sys/lib/lp/process/generic - 775 sys sys 1174846328 4108
 sys/lib/lp/process/gifpost - 775 sys sys 1015012079 2317
 sys/lib/lp/process/gspipe - 775 sys sys 1015012079 434
 sys/lib/lp/process/gspipeijs - 775 sys sys 1077670465 949
@@ -7066,7 +7067,7 @@ sys/lib/tmac/mmt - 664 sys sys 964454718 40915
 sys/lib/tmac/name.sed - 664 sys sys 944956202 62
 sys/lib/tmac/sendcover - 775 sys sys 944956202 50
 sys/lib/tmac/strings.mm - 664 sys sys 964455723 2146
-sys/lib/tmac/tmac.an - 664 sys sys 1161484650 8228
+sys/lib/tmac/tmac.an - 664 sys sys 1174803319 8439
 sys/lib/tmac/tmac.anhtml - 664 sys sys 984696197 105
 sys/lib/tmac/tmac.antimes - 664 sys sys 964454718 7809
 sys/lib/tmac/tmac.bits - 664 sys sys 944956202 1089
@@ -7508,7 +7509,7 @@ sys/man/2/iounit - 664 sys sys 1015091523 1001
 sys/man/2/ip - 664 sys sys 1173239323 7249
 sys/man/2/isalpharune - 664 sys sys 1015091523 1059
 sys/man/2/keyboard - 664 sys sys 950892860 2065
-sys/man/2/lock - 664 sys sys 1172959628 4693
+sys/man/2/lock - 664 sys sys 1174844415 5704
 sys/man/2/mach - 664 sys sys 1080179298 7995
 sys/man/2/malloc - 664 sys sys 1102093069 4763
 sys/man/2/matrix - 664 sys sys 950892861 6090
@@ -7618,6 +7619,7 @@ sys/man/4/archfs - 664 sys sys 960000712 533
 sys/man/4/cdfs - 664 sys sys 1026846913 3638
 sys/man/4/cfs - 664 sys sys 1172762903 1813
 sys/man/4/consolefs - 664 sys sys 1144424854 4245
+sys/man/4/cwfs - 664 sys sys 1174799917 6329
 sys/man/4/dossrv - 664 sys sys 1168307403 4334
 sys/man/4/execnet - 664 sys sys 1019866708 1069
 sys/man/4/exportfs - 664 sys sys 1145881912 4655
@@ -9941,6 +9943,79 @@ sys/src/cmd/cpp/test.c - 664 sys sys 944960879 47
 sys/src/cmd/cpp/tokens.c - 664 sys sys 944960879 6755
 sys/src/cmd/cpu.c - 664 sys sys 1164133664 21154
 sys/src/cmd/crop.c - 664 sys sys 1134557476 4137
+sys/src/cmd/cwfs - 20000000775 sys sys 1174799196 0
+sys/src/cmd/cwfs/32bit.h - 664 sys sys 1171162581 594
+sys/src/cmd/cwfs/64bit.h - 664 sys sys 1171162523 634
+sys/src/cmd/cwfs/9netics32.16k - 20000000775 sys sys 1174799194 0
+sys/src/cmd/cwfs/9netics32.16k/conf.c - 664 sys sys 1171171267 503
+sys/src/cmd/cwfs/9netics32.16k/dat.h - 664 sys sys 1171171041 794
+sys/src/cmd/cwfs/9netics32.16k/mkfile - 664 sys sys 1171519744 29
+sys/src/cmd/cwfs/9netics64.8k - 20000000775 sys sys 1174799194 0
+sys/src/cmd/cwfs/9netics64.8k/conf.c - 664 sys sys 1171171458 564
+sys/src/cmd/cwfs/9netics64.8k/dat.h - 664 sys sys 1171171387 791
+sys/src/cmd/cwfs/9netics64.8k/mkfile - 664 sys sys 1171519752 28
+sys/src/cmd/cwfs/9p1.c - 664 sys sys 1174716878 29747
+sys/src/cmd/cwfs/9p1.h - 664 sys sys 1171159776 2128
+sys/src/cmd/cwfs/9p1lib.c - 664 sys sys 1171145882 7894
+sys/src/cmd/cwfs/9p2.c - 664 sys sys 1174716894 35170
+sys/src/cmd/cwfs/README - 664 sys sys 1171520084 344
+sys/src/cmd/cwfs/all.h - 664 sys sys 1174716764 2186
+sys/src/cmd/cwfs/auth.c - 664 sys sys 1174797532 5840
+sys/src/cmd/cwfs/chk.c - 664 sys sys 1174716979 14579
+sys/src/cmd/cwfs/choline - 20000000775 sys sys 1174799194 0
+sys/src/cmd/cwfs/choline/conf.c - 664 sys sys 1171170952 412
+sys/src/cmd/cwfs/choline/dat.h - 664 sys sys 1171170751 791
+sys/src/cmd/cwfs/choline/mkfile - 664 sys sys 1171519759 26
+sys/src/cmd/cwfs/con.c - 664 sys sys 1174717615 15713
+sys/src/cmd/cwfs/config.c - 664 sys sys 1174717895 20243
+sys/src/cmd/cwfs/console.c - 664 sys sys 1174716894 4671
+sys/src/cmd/cwfs/cw.c - 664 sys sys 1174716894 42798
+sys/src/cmd/cwfs/cwfs - 20000000775 sys sys 1174799195 0
+sys/src/cmd/cwfs/cwfs/conf.c - 664 sys sys 1171485877 452
+sys/src/cmd/cwfs/cwfs/dat.h - 664 sys sys 1171485890 796
+sys/src/cmd/cwfs/cwfs/mkfile - 664 sys sys 1174798645 21
+sys/src/cmd/cwfs/data.c - 664 sys sys 1171158553 4515
+sys/src/cmd/cwfs/dentry.c - 664 sys sys 1174716894 6265
+sys/src/cmd/cwfs/doc - 20000000775 sys sys 1174799195 0
+sys/src/cmd/cwfs/doc/changes - 664 sys sys 1146795434 2967
+sys/src/cmd/cwfs/doc/emelie.boot - 664 sys sys 1171304297 8751
+sys/src/cmd/cwfs/doc/user.mode.boot - 664 sys sys 1171326690 747
+sys/src/cmd/cwfs/doc/words - 664 sys sys 1171172525 1096
+sys/src/cmd/cwfs/doc/worm.fs - 664 sys sys 1146795434 4057
+sys/src/cmd/cwfs/doc/worm.fs64 - 664 sys sys 1146795434 1554
+sys/src/cmd/cwfs/doc/worms.32-bit - 664 sys sys 1146795434 2806
+sys/src/cmd/cwfs/emelie - 20000000775 sys sys 1174799195 0
+sys/src/cmd/cwfs/emelie/conf.c - 664 sys sys 1174370534 500
+sys/src/cmd/cwfs/emelie/dat.h - 664 sys sys 1171165543 790
+sys/src/cmd/cwfs/emelie/map.w2-w0 - 664 sys sys 1171864578 6
+sys/src/cmd/cwfs/emelie/mkfile - 664 sys sys 1174799340 26
+sys/src/cmd/cwfs/fs - 20000000775 sys sys 1174799195 0
+sys/src/cmd/cwfs/fs/conf.c - 664 sys sys 1171171939 554
+sys/src/cmd/cwfs/fs/dat.h - 664 sys sys 1171171640 784
+sys/src/cmd/cwfs/fs/mkfile - 664 sys sys 1171519772 21
+sys/src/cmd/cwfs/fs64 - 20000000775 sys sys 1174799195 0
+sys/src/cmd/cwfs/fs64/conf.c - 664 sys sys 1171172030 559
+sys/src/cmd/cwfs/fs64/dat.h - 664 sys sys 1171172076 786
+sys/src/cmd/cwfs/fs64/mkfile - 664 sys sys 1174799404 24
+sys/src/cmd/cwfs/fworm.c - 664 sys sys 1174716894 1814
+sys/src/cmd/cwfs/io.h - 664 sys sys 1174280312 866
+sys/src/cmd/cwfs/iobuf.c - 664 sys sys 1174716894 4713
+sys/src/cmd/cwfs/juke.c - 664 sys sys 1174799503 28859
+sys/src/cmd/cwfs/lrand.c - 664 sys sys 1171160167 1070
+sys/src/cmd/cwfs/main.c - 664 sys sys 1174799729 9976
+sys/src/cmd/cwfs/malloc.c - 664 sys sys 1174281557 2360
+sys/src/cmd/cwfs/mkfile - 664 sys sys 1174799125 170
+sys/src/cmd/cwfs/mworm.c - 664 sys sys 1174370308 4311
+sys/src/cmd/cwfs/net.c - 664 sys sys 1174521421 9939
+sys/src/cmd/cwfs/pc.c - 664 sys sys 1174716747 1718
+sys/src/cmd/cwfs/portdat.h - 664 sys sys 1174716952 15241
+sys/src/cmd/cwfs/portfns.h - 664 sys sys 1174798778 6701
+sys/src/cmd/cwfs/portmkfile - 664 sys sys 1174798711 791
+sys/src/cmd/cwfs/scsi.c - 664 sys sys 1174282908 8865
+sys/src/cmd/cwfs/sub.c - 664 sys sys 1174798849 24353
+sys/src/cmd/cwfs/time.c - 664 sys sys 1171500176 1696
+sys/src/cmd/cwfs/uidgid.c - 664 sys sys 1174717700 9421
+sys/src/cmd/cwfs/wren.c - 664 sys sys 1174458303 2737
 sys/src/cmd/date.c - 664 sys sys 944961351 449
 sys/src/cmd/db - 20000000775 sys sys 1046363143 0
 sys/src/cmd/db/command.c - 664 sys sys 1166823791 4376
@@ -14655,7 +14730,7 @@ sys/src/libauthsrv/mkfile - 664 sys sys 1035389776 409
 sys/src/libauthsrv/nvcsum.c - 664 sys sys 1015091654 192
 sys/src/libauthsrv/opasstokey.c - 664 sys sys 1015091654 448
 sys/src/libauthsrv/passtokey.c - 664 sys sys 1143695654 488
-sys/src/libauthsrv/readnvram.c - 664 sys sys 1171777600 10170
+sys/src/libauthsrv/readnvram.c - 664 sys sys 1174807437 10155
 sys/src/libbin - 20000000775 sys sys 1045502972 0
 sys/src/libbin/bin.c - 664 sys sys 1135487932 1829
 sys/src/libbin/mkfile - 664 sys sys 1035389776 197

+ 81 - 6
dist/replica/plan9.db

@@ -5444,6 +5444,7 @@ rc/bin/delkey - 775 sys sys 1109429137 643
 rc/bin/dial - 20000000775 sys sys 1059180057 0
 rc/bin/diffy - 775 sys sys 1140694870 277
 rc/bin/dircp - 775 sys sys 1169490692 234
+rc/bin/diskparts - 775 sys sys 1174849973 392
 rc/bin/doc2ps - 775 sys sys 1069793831 244
 rc/bin/doc2txt - 775 sys sys 1025197880 563
 rc/bin/doctype - 775 sys sys 1162921755 1727
@@ -5469,7 +5470,7 @@ rc/bin/leak - 775 sys sys 1172760642 1921
 rc/bin/lookman - 775 sys sys 1017679344 686
 rc/bin/lp - 775 sys sys 1162105982 5201
 rc/bin/mail - 775 sys sys 1045504003 138
-rc/bin/man - 775 sys sys 1173755398 2504
+rc/bin/man - 775 sys sys 1174803269 2639
 rc/bin/map - 775 sys sys 945617207 1576
 rc/bin/mapdemo - 775 sys sys 945617207 4075
 rc/bin/membername - 775 sys sys 945617207 89
@@ -5559,7 +5560,7 @@ rc/bin/start - 775 sys sys 945617209 120
 rc/bin/stock - 775 sys sys 1143126371 292
 rc/bin/stop - 775 sys sys 945617209 110
 rc/bin/tel - 775 sys sys 1161209756 128
-rc/bin/termrc - 775 sys sys 1164658821 2647
+rc/bin/termrc - 775 sys sys 1174850048 2434
 rc/bin/thesaurus - 775 sys sys 1068054167 246
 rc/bin/tlsclienttunnel - 775 sys sys 1024375633 153
 rc/bin/tlssrvtunnel - 775 sys sys 1024375634 175
@@ -6568,7 +6569,7 @@ sys/lib/lp/process - 20000000775 sys sys 1077670465 0
 sys/lib/lp/process/dpost - 775 sys sys 1015012079 2412
 sys/lib/lp/process/dvipost - 775 sys sys 954037459 3123
 sys/lib/lp/process/g3post - 775 sys sys 954037459 2348
-sys/lib/lp/process/generic - 775 sys sys 1077715118 4805
+sys/lib/lp/process/generic - 775 sys sys 1174846328 4108
 sys/lib/lp/process/gifpost - 775 sys sys 1015012079 2317
 sys/lib/lp/process/gspipe - 775 sys sys 1015012079 434
 sys/lib/lp/process/gspipeijs - 775 sys sys 1077670465 949
@@ -7066,7 +7067,7 @@ sys/lib/tmac/mmt - 664 sys sys 964454718 40915
 sys/lib/tmac/name.sed - 664 sys sys 944956202 62
 sys/lib/tmac/sendcover - 775 sys sys 944956202 50
 sys/lib/tmac/strings.mm - 664 sys sys 964455723 2146
-sys/lib/tmac/tmac.an - 664 sys sys 1161484650 8228
+sys/lib/tmac/tmac.an - 664 sys sys 1174803319 8439
 sys/lib/tmac/tmac.anhtml - 664 sys sys 984696197 105
 sys/lib/tmac/tmac.antimes - 664 sys sys 964454718 7809
 sys/lib/tmac/tmac.bits - 664 sys sys 944956202 1089
@@ -7508,7 +7509,7 @@ sys/man/2/iounit - 664 sys sys 1015091523 1001
 sys/man/2/ip - 664 sys sys 1173239323 7249
 sys/man/2/isalpharune - 664 sys sys 1015091523 1059
 sys/man/2/keyboard - 664 sys sys 950892860 2065
-sys/man/2/lock - 664 sys sys 1172959628 4693
+sys/man/2/lock - 664 sys sys 1174844415 5704
 sys/man/2/mach - 664 sys sys 1080179298 7995
 sys/man/2/malloc - 664 sys sys 1102093069 4763
 sys/man/2/matrix - 664 sys sys 950892861 6090
@@ -7618,6 +7619,7 @@ sys/man/4/archfs - 664 sys sys 960000712 533
 sys/man/4/cdfs - 664 sys sys 1026846913 3638
 sys/man/4/cfs - 664 sys sys 1172762903 1813
 sys/man/4/consolefs - 664 sys sys 1144424854 4245
+sys/man/4/cwfs - 664 sys sys 1174799917 6329
 sys/man/4/dossrv - 664 sys sys 1168307403 4334
 sys/man/4/execnet - 664 sys sys 1019866708 1069
 sys/man/4/exportfs - 664 sys sys 1145881912 4655
@@ -9941,6 +9943,79 @@ sys/src/cmd/cpp/test.c - 664 sys sys 944960879 47
 sys/src/cmd/cpp/tokens.c - 664 sys sys 944960879 6755
 sys/src/cmd/cpu.c - 664 sys sys 1164133664 21154
 sys/src/cmd/crop.c - 664 sys sys 1134557476 4137
+sys/src/cmd/cwfs - 20000000775 sys sys 1174799196 0
+sys/src/cmd/cwfs/32bit.h - 664 sys sys 1171162581 594
+sys/src/cmd/cwfs/64bit.h - 664 sys sys 1171162523 634
+sys/src/cmd/cwfs/9netics32.16k - 20000000775 sys sys 1174799194 0
+sys/src/cmd/cwfs/9netics32.16k/conf.c - 664 sys sys 1171171267 503
+sys/src/cmd/cwfs/9netics32.16k/dat.h - 664 sys sys 1171171041 794
+sys/src/cmd/cwfs/9netics32.16k/mkfile - 664 sys sys 1171519744 29
+sys/src/cmd/cwfs/9netics64.8k - 20000000775 sys sys 1174799194 0
+sys/src/cmd/cwfs/9netics64.8k/conf.c - 664 sys sys 1171171458 564
+sys/src/cmd/cwfs/9netics64.8k/dat.h - 664 sys sys 1171171387 791
+sys/src/cmd/cwfs/9netics64.8k/mkfile - 664 sys sys 1171519752 28
+sys/src/cmd/cwfs/9p1.c - 664 sys sys 1174716878 29747
+sys/src/cmd/cwfs/9p1.h - 664 sys sys 1171159776 2128
+sys/src/cmd/cwfs/9p1lib.c - 664 sys sys 1171145882 7894
+sys/src/cmd/cwfs/9p2.c - 664 sys sys 1174716894 35170
+sys/src/cmd/cwfs/README - 664 sys sys 1171520084 344
+sys/src/cmd/cwfs/all.h - 664 sys sys 1174716764 2186
+sys/src/cmd/cwfs/auth.c - 664 sys sys 1174797532 5840
+sys/src/cmd/cwfs/chk.c - 664 sys sys 1174716979 14579
+sys/src/cmd/cwfs/choline - 20000000775 sys sys 1174799194 0
+sys/src/cmd/cwfs/choline/conf.c - 664 sys sys 1171170952 412
+sys/src/cmd/cwfs/choline/dat.h - 664 sys sys 1171170751 791
+sys/src/cmd/cwfs/choline/mkfile - 664 sys sys 1171519759 26
+sys/src/cmd/cwfs/con.c - 664 sys sys 1174717615 15713
+sys/src/cmd/cwfs/config.c - 664 sys sys 1174717895 20243
+sys/src/cmd/cwfs/console.c - 664 sys sys 1174716894 4671
+sys/src/cmd/cwfs/cw.c - 664 sys sys 1174716894 42798
+sys/src/cmd/cwfs/cwfs - 20000000775 sys sys 1174799195 0
+sys/src/cmd/cwfs/cwfs/conf.c - 664 sys sys 1171485877 452
+sys/src/cmd/cwfs/cwfs/dat.h - 664 sys sys 1171485890 796
+sys/src/cmd/cwfs/cwfs/mkfile - 664 sys sys 1174798645 21
+sys/src/cmd/cwfs/data.c - 664 sys sys 1171158553 4515
+sys/src/cmd/cwfs/dentry.c - 664 sys sys 1174716894 6265
+sys/src/cmd/cwfs/doc - 20000000775 sys sys 1174799195 0
+sys/src/cmd/cwfs/doc/changes - 664 sys sys 1146795434 2967
+sys/src/cmd/cwfs/doc/emelie.boot - 664 sys sys 1171304297 8751
+sys/src/cmd/cwfs/doc/user.mode.boot - 664 sys sys 1171326690 747
+sys/src/cmd/cwfs/doc/words - 664 sys sys 1171172525 1096
+sys/src/cmd/cwfs/doc/worm.fs - 664 sys sys 1146795434 4057
+sys/src/cmd/cwfs/doc/worm.fs64 - 664 sys sys 1146795434 1554
+sys/src/cmd/cwfs/doc/worms.32-bit - 664 sys sys 1146795434 2806
+sys/src/cmd/cwfs/emelie - 20000000775 sys sys 1174799195 0
+sys/src/cmd/cwfs/emelie/conf.c - 664 sys sys 1174370534 500
+sys/src/cmd/cwfs/emelie/dat.h - 664 sys sys 1171165543 790
+sys/src/cmd/cwfs/emelie/map.w2-w0 - 664 sys sys 1171864578 6
+sys/src/cmd/cwfs/emelie/mkfile - 664 sys sys 1174799340 26
+sys/src/cmd/cwfs/fs - 20000000775 sys sys 1174799195 0
+sys/src/cmd/cwfs/fs/conf.c - 664 sys sys 1171171939 554
+sys/src/cmd/cwfs/fs/dat.h - 664 sys sys 1171171640 784
+sys/src/cmd/cwfs/fs/mkfile - 664 sys sys 1171519772 21
+sys/src/cmd/cwfs/fs64 - 20000000775 sys sys 1174799195 0
+sys/src/cmd/cwfs/fs64/conf.c - 664 sys sys 1171172030 559
+sys/src/cmd/cwfs/fs64/dat.h - 664 sys sys 1171172076 786
+sys/src/cmd/cwfs/fs64/mkfile - 664 sys sys 1174799404 24
+sys/src/cmd/cwfs/fworm.c - 664 sys sys 1174716894 1814
+sys/src/cmd/cwfs/io.h - 664 sys sys 1174280312 866
+sys/src/cmd/cwfs/iobuf.c - 664 sys sys 1174716894 4713
+sys/src/cmd/cwfs/juke.c - 664 sys sys 1174799503 28859
+sys/src/cmd/cwfs/lrand.c - 664 sys sys 1171160167 1070
+sys/src/cmd/cwfs/main.c - 664 sys sys 1174799729 9976
+sys/src/cmd/cwfs/malloc.c - 664 sys sys 1174281557 2360
+sys/src/cmd/cwfs/mkfile - 664 sys sys 1174799125 170
+sys/src/cmd/cwfs/mworm.c - 664 sys sys 1174370308 4311
+sys/src/cmd/cwfs/net.c - 664 sys sys 1174521421 9939
+sys/src/cmd/cwfs/pc.c - 664 sys sys 1174716747 1718
+sys/src/cmd/cwfs/portdat.h - 664 sys sys 1174716952 15241
+sys/src/cmd/cwfs/portfns.h - 664 sys sys 1174798778 6701
+sys/src/cmd/cwfs/portmkfile - 664 sys sys 1174798711 791
+sys/src/cmd/cwfs/scsi.c - 664 sys sys 1174282908 8865
+sys/src/cmd/cwfs/sub.c - 664 sys sys 1174798849 24353
+sys/src/cmd/cwfs/time.c - 664 sys sys 1171500176 1696
+sys/src/cmd/cwfs/uidgid.c - 664 sys sys 1174717700 9421
+sys/src/cmd/cwfs/wren.c - 664 sys sys 1174458303 2737
 sys/src/cmd/date.c - 664 sys sys 944961351 449
 sys/src/cmd/db - 20000000775 sys sys 1046363143 0
 sys/src/cmd/db/command.c - 664 sys sys 1166823791 4376
@@ -14655,7 +14730,7 @@ sys/src/libauthsrv/mkfile - 664 sys sys 1035389776 409
 sys/src/libauthsrv/nvcsum.c - 664 sys sys 1015091654 192
 sys/src/libauthsrv/opasstokey.c - 664 sys sys 1015091654 448
 sys/src/libauthsrv/passtokey.c - 664 sys sys 1143695654 488
-sys/src/libauthsrv/readnvram.c - 664 sys sys 1171777600 10170
+sys/src/libauthsrv/readnvram.c - 664 sys sys 1174807437 10155
 sys/src/libbin - 20000000775 sys sys 1045502972 0
 sys/src/libbin/bin.c - 664 sys sys 1135487932 1829
 sys/src/libbin/mkfile - 664 sys sys 1035389776 197

+ 81 - 0
dist/replica/plan9.log

@@ -47963,3 +47963,84 @@
 1174793406 0 c sys/man/8/cpurc - 664 sys sys 1174792133 1541
 1174793406 1 c sys/man/8/listen - 664 sys sys 1174792129 3826
 1174793406 2 c sys/src/cmd/ndb/dblookup.c - 664 sys sys 1174792290 20940
+1174800606 0 a sys/man/4/cwfs - 664 sys sys 1174799917 6329
+1174800606 1 a sys/src/cmd/cwfs - 20000000775 sys sys 1174799196 0
+1174800606 2 a sys/src/cmd/cwfs/32bit.h - 664 sys sys 1171162581 594
+1174800606 3 a sys/src/cmd/cwfs/64bit.h - 664 sys sys 1171162523 634
+1174800606 4 a sys/src/cmd/cwfs/9netics32.16k - 20000000775 sys sys 1174799194 0
+1174800606 5 a sys/src/cmd/cwfs/9netics32.16k/conf.c - 664 sys sys 1171171267 503
+1174800606 6 a sys/src/cmd/cwfs/9netics32.16k/dat.h - 664 sys sys 1171171041 794
+1174800606 7 a sys/src/cmd/cwfs/9netics32.16k/mkfile - 664 sys sys 1171519744 29
+1174800606 8 a sys/src/cmd/cwfs/9netics64.8k - 20000000775 sys sys 1174799194 0
+1174800606 9 a sys/src/cmd/cwfs/9netics64.8k/conf.c - 664 sys sys 1171171458 564
+1174800606 10 a sys/src/cmd/cwfs/9netics64.8k/dat.h - 664 sys sys 1171171387 791
+1174800606 11 a sys/src/cmd/cwfs/9netics64.8k/mkfile - 664 sys sys 1171519752 28
+1174800606 12 a sys/src/cmd/cwfs/9p1.c - 664 sys sys 1174716878 29747
+1174800606 13 a sys/src/cmd/cwfs/9p1.h - 664 sys sys 1171159776 2128
+1174800606 14 a sys/src/cmd/cwfs/9p1lib.c - 664 sys sys 1171145882 7894
+1174800606 15 a sys/src/cmd/cwfs/9p2.c - 664 sys sys 1174716894 35170
+1174800606 16 a sys/src/cmd/cwfs/README - 664 sys sys 1171520084 344
+1174800606 17 a sys/src/cmd/cwfs/all.h - 664 sys sys 1174716764 2186
+1174800606 18 a sys/src/cmd/cwfs/auth.c - 664 sys sys 1174797532 5840
+1174800606 19 a sys/src/cmd/cwfs/chk.c - 664 sys sys 1174716979 14579
+1174800606 20 a sys/src/cmd/cwfs/choline - 20000000775 sys sys 1174799194 0
+1174800606 21 a sys/src/cmd/cwfs/choline/conf.c - 664 sys sys 1171170952 412
+1174800606 22 a sys/src/cmd/cwfs/choline/dat.h - 664 sys sys 1171170751 791
+1174800606 23 a sys/src/cmd/cwfs/choline/mkfile - 664 sys sys 1171519759 26
+1174800606 24 a sys/src/cmd/cwfs/con.c - 664 sys sys 1174717615 15713
+1174800606 25 a sys/src/cmd/cwfs/config.c - 664 sys sys 1174717895 20243
+1174800606 26 a sys/src/cmd/cwfs/console.c - 664 sys sys 1174716894 4671
+1174800606 27 a sys/src/cmd/cwfs/cw.c - 664 sys sys 1174716894 42798
+1174800606 28 a sys/src/cmd/cwfs/cwfs - 20000000775 sys sys 1174799195 0
+1174800606 29 a sys/src/cmd/cwfs/cwfs/conf.c - 664 sys sys 1171485877 452
+1174800606 30 a sys/src/cmd/cwfs/cwfs/dat.h - 664 sys sys 1171485890 796
+1174800606 31 a sys/src/cmd/cwfs/cwfs/mkfile - 664 sys sys 1174798645 21
+1174800606 32 a sys/src/cmd/cwfs/data.c - 664 sys sys 1171158553 4515
+1174800606 33 a sys/src/cmd/cwfs/dentry.c - 664 sys sys 1174716894 6265
+1174800606 34 a sys/src/cmd/cwfs/doc - 20000000775 sys sys 1174799195 0
+1174800606 35 a sys/src/cmd/cwfs/doc/changes - 664 sys sys 1146795434 2967
+1174800606 36 a sys/src/cmd/cwfs/doc/emelie.boot - 664 sys sys 1171304297 8751
+1174800606 37 a sys/src/cmd/cwfs/doc/user.mode.boot - 664 sys sys 1171326690 747
+1174800606 38 a sys/src/cmd/cwfs/doc/words - 664 sys sys 1171172525 1096
+1174800606 39 a sys/src/cmd/cwfs/doc/worm.fs - 664 sys sys 1146795434 4057
+1174800606 40 a sys/src/cmd/cwfs/doc/worm.fs64 - 664 sys sys 1146795434 1554
+1174800606 41 a sys/src/cmd/cwfs/doc/worms.32-bit - 664 sys sys 1146795434 2806
+1174800606 42 a sys/src/cmd/cwfs/emelie - 20000000775 sys sys 1174799195 0
+1174800606 43 a sys/src/cmd/cwfs/emelie/conf.c - 664 sys sys 1174370534 500
+1174800606 44 a sys/src/cmd/cwfs/emelie/dat.h - 664 sys sys 1171165543 790
+1174800606 45 a sys/src/cmd/cwfs/emelie/map.w2-w0 - 664 sys sys 1171864578 6
+1174800606 46 a sys/src/cmd/cwfs/emelie/mkfile - 664 sys sys 1174799340 26
+1174800606 47 a sys/src/cmd/cwfs/fs - 20000000775 sys sys 1174799195 0
+1174800606 48 a sys/src/cmd/cwfs/fs/conf.c - 664 sys sys 1171171939 554
+1174800606 49 a sys/src/cmd/cwfs/fs/dat.h - 664 sys sys 1171171640 784
+1174800606 50 a sys/src/cmd/cwfs/fs/mkfile - 664 sys sys 1171519772 21
+1174800606 51 a sys/src/cmd/cwfs/fs64 - 20000000775 sys sys 1174799195 0
+1174800606 52 a sys/src/cmd/cwfs/fs64/conf.c - 664 sys sys 1171172030 559
+1174800606 53 a sys/src/cmd/cwfs/fs64/dat.h - 664 sys sys 1171172076 786
+1174800606 54 a sys/src/cmd/cwfs/fs64/mkfile - 664 sys sys 1174799404 24
+1174800606 55 a sys/src/cmd/cwfs/fworm.c - 664 sys sys 1174716894 1814
+1174800606 56 a sys/src/cmd/cwfs/io.h - 664 sys sys 1174280312 866
+1174800606 57 a sys/src/cmd/cwfs/iobuf.c - 664 sys sys 1174716894 4713
+1174800606 58 a sys/src/cmd/cwfs/juke.c - 664 sys sys 1174799503 28859
+1174800606 59 a sys/src/cmd/cwfs/lrand.c - 664 sys sys 1171160167 1070
+1174800606 60 a sys/src/cmd/cwfs/main.c - 664 sys sys 1174799729 9976
+1174800606 61 a sys/src/cmd/cwfs/malloc.c - 664 sys sys 1174281557 2360
+1174800606 62 a sys/src/cmd/cwfs/mkfile - 664 sys sys 1174799125 170
+1174800606 63 a sys/src/cmd/cwfs/mworm.c - 664 sys sys 1174370308 4311
+1174800606 64 a sys/src/cmd/cwfs/net.c - 664 sys sys 1174521421 9939
+1174800606 65 a sys/src/cmd/cwfs/pc.c - 664 sys sys 1174716747 1718
+1174800606 66 a sys/src/cmd/cwfs/portdat.h - 664 sys sys 1174716952 15241
+1174800606 67 a sys/src/cmd/cwfs/portfns.h - 664 sys sys 1174798778 6701
+1174800606 68 a sys/src/cmd/cwfs/portmkfile - 664 sys sys 1174798711 791
+1174800606 69 a sys/src/cmd/cwfs/scsi.c - 664 sys sys 1174282908 8865
+1174800606 70 a sys/src/cmd/cwfs/sub.c - 664 sys sys 1174798849 24353
+1174800606 71 a sys/src/cmd/cwfs/time.c - 664 sys sys 1171500176 1696
+1174800606 72 a sys/src/cmd/cwfs/uidgid.c - 664 sys sys 1174717700 9421
+1174800606 73 a sys/src/cmd/cwfs/wren.c - 664 sys sys 1174458303 2737
+1174804206 0 c rc/bin/man - 775 sys sys 1174803269 2639
+1174804206 1 c sys/lib/tmac/tmac.an - 664 sys sys 1174803319 8439
+1174807805 0 c sys/src/libauthsrv/readnvram.c - 664 sys sys 1174807437 10155
+1174845606 0 c sys/man/2/lock - 664 sys sys 1174844415 5704
+1174847405 0 c sys/lib/lp/process/generic - 775 sys sys 1174846328 4108
+1174851005 0 c rc/bin/termrc - 775 sys sys 1174850048 2434
+1174851005 1 a rc/bin/diskparts - 775 sys sys 1174849973 392

+ 14 - 0
rc/bin/diskparts

@@ -0,0 +1,14 @@
+#!/bin/rc
+# set up any /dev/sd partitions
+rfork e
+for(disk in /dev/sd[0-9A-Zabd-z]*) {
+	if(test -f $disk/data && test -f $disk/ctl)
+		disk/fdisk -p $disk/data >$disk/ctl >[2]/dev/null
+	for(part in $disk/plan9*)
+		if(test -f $part)
+			disk/prep -p $part >$disk/ctl >[2]/dev/null
+}
+
+# set up any fs(3) partitions
+if (test -r	/cfg/$sysname/fsconfig)
+	read -m /cfg/$sysname/fsconfig >/dev/fs/ctl

+ 8 - 6
rc/bin/man

@@ -21,7 +21,9 @@ fn roff {
 		Nflag=-Tutf
 	}
 	if not {
-		Nflag=-N
+		Nflag='-N'
+		Lflag='-rL1000i'
+		# setting L changes page length to infinity (sed script removes empty lines)
 		if (grep -s '^\.2C' $2)
 			postproc=col
 	}
@@ -32,17 +34,17 @@ fn roff {
 	{echo -n $FONTS; cat $2 </dev/null} |
 		switch($#preproc) {
 		case 0
-			troff $Nflag -$MAN 
+			troff $Nflag $Lflag -$MAN 
 		case 1
-			$preproc | troff $Nflag -$MAN
+			$preproc | troff $Nflag $Lflag -$MAN
 		case 2
-			$preproc(1) | $preproc(2) | troff $Nflag -$MAN
+			$preproc(1) | $preproc(2) | troff $Nflag $Lflag -$MAN
 		case 3
 			$preproc(1) | $preproc(2) | $preproc(3) |
-				troff $Nflag -$MAN
+				troff $Nflag $Lflag -$MAN
 		case *
 			$preproc(1) | $preproc(2) | $preproc(3) |
-				$preproc(4) | troff $Nflag -$MAN
+				$preproc(4) | troff $Nflag $Lflag -$MAN
 		} | $postproc
 }
 

+ 2 - 7
rc/bin/termrc

@@ -56,13 +56,8 @@ case *' indigo'*
 case NCR* 'AT&TNSX'* generic* _MP_* 'alpha apc'*
 	for(i in H w f t m v L S P U '$' Σ κ)
 		/bin/bind -a '#'^$i /dev >/dev/null >[2=1]
-	for(disk in /dev/sd??) {
-		if(test -f $disk/data && test -f $disk/ctl)
-			disk/fdisk -p $disk/data >$disk/ctl >[2]/dev/null
-		for(part in $disk/plan9*)
-			if(test -f $part)
-				disk/prep -p $part >$disk/ctl >[2]/dev/null
-	}
+
+	diskparts
 
 	if(! ~ `{cat /dev/user} none)
 		aux/vmware

+ 153 - 97
sys/lib/lp/process/generic

@@ -2,134 +2,190 @@
 # Tries to determine what type of file you are printing and do the correct
 # thing with it.
 # It currently knows about images, troff intermediate, and ascii files.
-TMPFILE=/tmp/lp$pid
-fn sigexit { rm -f $TMPFILE; }
-if (! ~ $DEBUG '') flag x +
-if (~ $LPCLASS *nohead*) NOHEAD=1
-if (~ $LPCLASS *duplex*) DUPLEX=1
-cat >$TMPFILE
-FILETYPE=`{file $TMPFILE}
-switch ($FILETYPE(2)) {
-case troff;
-	switch ($LPCLASS) {
-	case *Latin1* *post* *opost*;	switch ($FILETYPE(5)) {
-					# Latin1 is for compatibility with old research UNIX systems, doesn't work on Plan 9
-					case Latin1 post; tcs -s -f utf -t latin1 < $TMPFILE |$LPLIB/process/dpost
-
-					case UTF; $LPLIB/process/tr2post < $TMPFILE
-					}
+rfork e
+temp=/tmp/lp$pid
+fn sigexit { rm -f $temp }
+proc=$LPLIB/process
 
-	case *gs!* *gsijs!*;	switch ($FILETYPE(5)) {
-					# Latin1 is for compatibility with old research UNIX systems, doesn't work on Plan 9
-					case Latin1 post; tcs -s -f utf -t latin1 < $TMPFILE |$LPLIB/process/dpost |$LPLIB/process/gspipe
+if (! ~ $DEBUG '')
+	flag x +
+if (~ $LPCLASS *nohead*)
+	NOHEAD=1
+if (~ $LPCLASS *duplex*)
+	DUPLEX=1
+cat >$temp
 
-					case UTF; $LPLIB/process/tr2post < $TMPFILE |$LPLIB/process/gspipe
-					}
+type=`{file $temp}
+switch ($type(2)) {
+case troff
+	switch ($LPCLASS) {
+	case *Latin1* *post* *opost*
+		switch ($type(5)) {
+		# Latin1 is for compatibility with old research UNIX systems,
+		# doesn't work on Plan 9
+		case Latin1 post
+			tcs -s -f utf -t latin1 <$temp | $proc/dpost
+		case UTF
+			$proc/tr2post <$temp
+		}
+	case *gs!* *gsijs!*
+		switch ($type(5)) {
+		# Latin1 is for compatibility with old research UNIX systems,
+		# doesn't work on Plan 9
+		case Latin1 post
+			tcs -s -f utf -t latin1 <$temp | $proc/dpost |
+				$proc/gspipe
 
-	case *;		echo $FILETYPE(2) -T$FILETYPE(5) output is improper for $LPDEST >[1=2]
+		case UTF
+			$proc/tr2post <$temp | $proc/gspipe
+		}
+	case *
+		echo $type(2) -T$type(5) output is improper for $LPDEST >[1=2]
 	}
-case special;
-	switch ($FILETYPE(4)) {
-	case '#b';		switch ($LPCLASS) {
-				case *post*;	$LPLIB/process/p9bitpost < $TMPFILE
-				case *gs!*;	$LPLIB/process/p9bitpost < $TMPFILE |$LPLIB/process/gspipe
-				case *gsijs!*;	$LPLIB/process/p9bitpost < $TMPFILE |$LPLIB/process/gspipeijs
-				}
-
-	case *;		echo $FILETYPE file is improper for $LPDEST >[1=2]
+case special
+	switch ($type(4)) {
+	case '#b'
+		switch ($LPCLASS) {
+		case *post*
+			$proc/p9bitpost <$temp
+		case *gs!*
+			$proc/p9bitpost <$temp | $proc/gspipe
+		case *gsijs!*
+			$proc/p9bitpost <$temp | $proc/gspipeijs
+		}
+	case *
+		echo $type file is improper for $LPDEST >[1=2]
 	}
-case Compressed plan old;	# type is really 'Compressed image' or 'plan 9 image' 
-				# or 'old plan 9 image'
+case Compressed plan old
+	# type is really 'Compressed image' or 'plan 9 image' or
+	# 'old plan 9 image'
 	switch ($LPCLASS) {
-	case *post*;	$LPLIB/process/p9bitpost < $TMPFILE
-	case *gs!*;	$LPLIB/process/p9bitpost < $TMPFILE |$LPLIB/process/gspipe
-	case *gsijs!*;	$LPLIB/process/p9bitpost < $TMPFILE |$LPLIB/process/gspipeijs
+	case *post*
+		$proc/p9bitpost <$temp
+	case *gs!*
+		$proc/p9bitpost <$temp | $proc/gspipe
+	case *gsijs!*
+		$proc/p9bitpost <$temp | $proc/gspipeijs
 	}
-case jpeg;
+case jpeg
 	switch ($LPCLASS) {
-	case *post*;	$LPLIB/process/jpgpost < $TMPFILE
-	case *gs!*;	$LPLIB/process/jpgpost < $TMPFILE |$LPLIB/process/gspipe
-	case *gsijs!*;	$LPLIB/process/jpgpost < $TMPFILE |$LPLIB/process/gspipeijs
+	case *post*
+		$proc/jpgpost <$temp
+	case *gs!*
+		$proc/jpgpost <$temp | $proc/gspipe
+	case *gsijs!*
+		$proc/jpgpost <$temp | $proc/gspipeijs
 	}
-
-case GIF;
+case GIF
 	switch ($LPCLASS) {
-	case *post*;	$LPLIB/process/gifpost < $TMPFILE
-	case *gs!*;	$LPLIB/process/gifpost < $TMPFILE |$LPLIB/process/gspipe
-	case *gsijs!*;	$LPLIB/process/gifpost < $TMPFILE |$LPLIB/process/gspipeijs
+	case *post*
+		$proc/gifpost <$temp
+	case *gs!*
+		$proc/gifpost <$temp | $proc/gspipe
+	case *gsijs!*
+		$proc/gifpost <$temp | $proc/gspipeijs
 	}
-
 case ccitt-g31;
 	switch ($LPCLASS) {
-	case *post*;	$LPLIB/process/g3post < $TMPFILE
-	case *gs!*;	$LPLIB/process/g3post < $TMPFILE |$LPLIB/process/gspipe
-	case *gsijs!*;	$LPLIB/process/g3post < $TMPFILE |$LPLIB/process/gspipeijs
+	case *post*
+		$proc/g3post <$temp
+	case *gs!*
+		$proc/g3post <$temp | $proc/gspipe
+	case *gsijs!*
+		$proc/g3post <$temp | $proc/gspipeijs
 	}
-
-# bitmap for research UNIX compatibility, does not work on Plan 9.
-case bitmap;
+case bitmap
+	# bitmap for research UNIX compatibility, does not work on Plan 9.
 	switch ($LPCLASS) {
-	case *post*;	$LPLIB/process/bpost < $TMPFILE
-	case *mhcc*;	$LPLIB/process/bpost < $TMPFILE | $LPLIB/process/mhcc
-	case *;		echo $FILETYPE(2) file is improper for $LPDEST >[1=2]
+	case *post*
+		$proc/bpost <$temp
+	case *mhcc*
+		$proc/bpost <$temp | $proc/mhcc
+	case *
+		echo $type(2) file is improper for $LPDEST >[1=2]
 	}
-case tex;
-	mv $TMPFILE $TMPFILE.dvi
-	TMPFILE=$TMPFILE.dvi
+case tex
+	mv $temp $temp.dvi
+	temp=$temp.dvi
 	switch ($LPCLASS) {
-	case *post*;	$LPLIB/process/dvipost $TMPFILE
-	case *gs!*;	$LPLIB/process/dvipost $TMPFILE |$LPLIB/process/gspipe
-	case *gsijs!*;	$LPLIB/process/dvipost $TMPFILE |$LPLIB/process/gspipeijs
-	case *;		echo $FILETYPE(2) file is improper for $LPDEST >[1=2]
+	case *post*
+		$proc/dvipost $temp
+	case *gs!*
+		$proc/dvipost $temp | $proc/gspipe
+	case *gsijs!*
+		$proc/dvipost $temp | $proc/gspipeijs
+	case *
+		echo $type(2) file is improper for $LPDEST >[1=2]
 	}
-case postscript;
+case postscript
 	switch ($LPCLASS) {
-	case *post*;		$LPLIB/process/post < $TMPFILE
-	case *gs!*;		$LPLIB/process/post < $TMPFILE |$LPLIB/process/gspipe
-	case *gsijs!*;		$LPLIB/process/post < $TMPFILE |$LPLIB/process/gspipeijs
-	case *;			echo $FILETYPE(2) file is improper for $LPDEST >[1=2]
+	case *post*
+		$proc/post <$temp
+	case *gs!*
+		$proc/post <$temp | $proc/gspipe
+	case *gsijs!*
+		$proc/post <$temp | $proc/gspipeijs
+	case *
+		echo $type(2) file is improper for $LPDEST >[1=2]
 	}
-case HPJCL;
+case HPJCL
 	switch ($LPCLASS) {
-	case *HPJCL*;		$LPLIB/process/noproc < $TMPFILE
-	case *;			echo $FILETYPE(2) file is improper for $LPDEST >[1=2]
+	case *HPJCL*
+		$proc/noproc <$temp
+	case *
+		echo $type(2) file is improper for $LPDEST >[1=2]
 	}
-case daisy;
+case daisy
 	switch ($LPDEST) {
-	case *;		echo $FILETYPE(2) file is improper for $LPDEST >[1=2]
+	case *
+		echo $type(2) file is improper for $LPDEST >[1=2]
 	}
-case English short extended alef limbo [Aa]scii assembler c latin rc sh as mail email message/rfc822;
+case tiff
 	switch ($LPCLASS) {
-	case *post*;	$LPLIB/process/ppost < $TMPFILE
-	case *gs!*;	$LPLIB/process/ppost < $TMPFILE |$LPLIB/process/gspipe
-	case *gsijs!*;	$LPLIB/process/ppost < $TMPFILE |$LPLIB/process/gspipeijs
-	case *canon*;	$LPLIB/process/can $* < $TMPFILE
-	case *;		echo Unrecognized class of line printer for $LPDEST >[1=2]
+	case *post*
+		$proc/tiffpost $temp
+	case *gs!*
+		$proc/tiffpost $temp | $proc/gspipe
+	case *gsijs!*
+		$proc/tiffpost $temp | $proc/gspipeijs
+	case *
+		echo Unrecognized class of line printer for $LPDEST >[1=2]
 	}
-
-case tiff;
-	switch ($LPCLASS) {
-	case *post*;	$LPLIB/process/tiffpost $TMPFILE
-	case *gs!*;	$LPLIB/process/tiffpost $TMPFILE |$LPLIB/process/gspipe
-	case *gsijs!*;	$LPLIB/process/tiffpost $TMPFILE |$LPLIB/process/gspipeijs
-	case *;		echo Unrecognized class of line printer for $LPDEST >[1=2]
-	}
-case PDF;
+case PDF
 	switch ($LPCLASS) {
-	case *post*;	$LPLIB/process/pdfpost $TMPFILE
-	case *gs!*;	$LPLIB/process/pdfgs $TMPFILE
-	case *gsijs!*;	$LPLIB/process/pdfgsijs $TMPFILE
-	case *;		echo Unrecognized class of line printer for $LPDEST >[1=2]
+	case *post*
+		$proc/pdfpost $temp
+	case *gs!*
+		$proc/pdfgs $temp
+	case *gsijs!*
+		$proc/pdfgsijs $temp
+	case *
+		echo Unrecognized class of line printer for $LPDEST >[1=2]
 	}
-case empty;
+case empty
 	echo file is empty >[1=2]
-case cannot;
+case cannot
 	echo cannot open file >[1=2]
-case *;
-	echo $FILETYPE(2) file is improper for $LPDEST >[1=2]
+case English short extended alef limbo [Aa]scii assembler c latin rc sh \
+    as mail email message/rfc822 manual
+	switch ($LPCLASS) {
+	case *post*
+		$proc/ppost <$temp
+	case *gs!*
+		$proc/ppost <$temp | $proc/gspipe
+	case *gsijs!*
+		$proc/ppost <$temp | $proc/gspipeijs
+	case *canon*
+		$proc/can $* <$temp
+	case *
+		echo Unrecognized class of line printer for $LPDEST >[1=2]
+	}
+case *
+	echo $type(2) file is improper for $LPDEST >[1=2]
 }
+
 wait
 rv=$status
-rm -f $TMPFILE
-#exit $status
+rm -f $temp
+# exit $rv
 exit

+ 13 - 1
sys/lib/tmac/tmac.an

@@ -447,6 +447,9 @@
 .tlNot for use or disclosure outside the
 .tlBell System except under written agreement. \}
 ..
+.\" end of macros
+.
+.\" choose page dimensions
 .nr)s 0
 .ift .if \ns .nr )s 1
 .nr)t 0
@@ -464,7 +467,12 @@
 .ift \{.ds R ®
 .dsS \s\n()S
 ..\}
-.ifn \{.nr )L 1000i
+.ifn \{.if \nL<=0 .nr )L 11i
+.ie \{
+.nr )L \nLu
+.\" Changed the above from .nr )L 1000i
+.\" (doesn't work for invocation outside of man) [sape]
+.nr V 0\}
 .nrLL 6.5i
 .nr)O .463i
 .if '\*(.T'think' \{.nrLL 80n
@@ -480,6 +488,7 @@
 .nrLL 82n
 .nr)L 84v
 .rmul \}
+.
 .nr)p 0 1
 .ds]I \\\\n(]
 .ds]R \\\\n()
@@ -506,10 +515,13 @@
 .if\n()t \{.ie \nd .ds ]W \*(]m \nd, 20\ny
 .el.ds ]W \*(]m \n(dy, 20\n(yr
 ..\}
+.
+.\" set page dimensions
 .pl\n()Lu
 .ll\n(LLu
 .lt\n(LLu
 .po\n()Ou
+.
 .ift .tr \``\''
 .}f
 .if\n()s .nr :m 3.5v

+ 75 - 0
sys/man/2/lock

@@ -184,6 +184,9 @@ pointer, which should point at the
 .B QLock
 that will guard
 .IR r .
+It is important that this
+.B QLock
+is the same one that protects the rendezvous condition; see the example.
 .PP
 A
 .B Ref
@@ -198,6 +201,78 @@ in one atomic operation.
 atomically decrements the
 .B Ref
 and returns zero if the resulting value is zero, non-zero otherwise.
+.SH EXAMPLE
+Implement a buffered single-element channel using 
+.I rsleep
+and
+.IR rwakeup :
+.IP
+.EX
+.ta +4n +4n +4n
+typedef struct Chan
+{
+	QLock l;
+	Rendez full, empty;
+	int val, haveval;
+} Chan;
+.EE
+.IP
+.EX
+.ta +4n +4n +4n
+Chan*
+mkchan(void)
+{
+	Chan *c;
+
+	c = mallocz(sizeof *c, 1);
+	c->full.l = &c->l;
+	c->empty.l = &c->l;
+	return c;
+}
+.EE
+.IP
+.EX
+.ta +4n +4n +4n
+void
+send(Chan *c, int val)
+{
+	qlock(&c->l);
+	while(c->haveval)
+		rsleep(&c->full);
+	c->haveval = 1;
+	c->val = val;
+	rwakeup(&c->empty);  /* no longer empty */
+	qunlock(&c->l);
+}
+.EE
+.IP
+.EX
+.ta +4n +4n +4n
+int
+recv(Chan *c)
+{
+	int v;
+
+	qlock(&c->l);
+	while(!c->haveval)
+		rsleep(&c->empty);
+	c->haveval = 0;
+	v = c->val;
+	rwakeup(&c->full);  /* no longer full */
+	qunlock(&c->l);
+	return v;
+}
+.EE
+.LP
+Note that the 
+.B QLock
+protecting the
+.B Chan
+is the same
+.B QLock
+used for the 
+.B Rendez ;
+this ensures that wakeups are not missed.
 .SH SOURCE
 .B /sys/src/libc/port/lock.c
 .br

+ 298 - 0
sys/man/4/cwfs

@@ -0,0 +1,298 @@
+.TH CWFS 4
+.SH NAME
+cwfs \- cached-worm file server, dump
+.SH SYNOPSIS
+.B cwfs
+[
+.B -f
+] [
+.B -a
+.I announce-string
+] ... [
+.B -m
+.I device-map
+]
+.I config-device
+.SH DESCRIPTION
+.I Cwfs
+is a cached-worm file server that runs
+as a user-mode program and can
+maintain file systems created by
+.IR fs (4),
+the original Plan 9 file server
+that had its own kernel and operated
+a standalone system with disks and
+optical-disc jukebox attached.
+Unlike
+.IR fs (4),
+which could only accept 9P connections over IL/IPv4 on Ethernets
+(or over Datakit and Cyclones, long ago),
+.I cwfs
+accepts 9P connections over any network medium and protocol
+that it can announce on,
+by default TCP (over IPv4 or IPv6).
+Given suitable 9P clients,
+one could even run 9P over
+.IR aan (8)
+or
+.IR tls (3).
+.PP
+The stock
+.I cwfs
+implements a 16K file system block size
+and 32-bit disk addresses,
+in order to be compatible with some existing file systems, notably
+.IR emelie 's.
+These parameters can be changed by recompilation.
+.PP
+.I Cwfs
+expects to find the configuration block on
+.IR config-device .
+.PP
+Options are:
+.TF -m
+.TP
+.B -a
+announce on
+.I announce-string
+instead of
+.LR tcp!*!9fs .
+.TP
+.B -f
+enter the file server's configuration mode
+before starting normal operation.
+.TP
+.B -m
+the file
+.I device-map
+contains a simple device name
+(e.g.,
+.LR w9 )
+and a replacement per line.
+The device name is in the usual
+.I filsys
+notation of
+.IR fsconfig (8).
+The replacement can be the name of an existing file
+or another such device name.
+For example, the file
+.RS
+.PD
+.IP
+.EX
+w0 /tmp/w0
+h1 w2
+.EE
+.PP
+.PD 0.3v
+would map accesses to device
+.L w0
+to existing file
+.LR /tmp/w0
+and accesses to device
+.L h1
+to device
+.LR w2 ,
+if no file named
+.L w2
+exists.
+.RE
+.PD
+.PP
+The file server normally requires all users except
+.L none
+to provide authentication tickets on each
+.IR attach (5).
+This can be disabled using the
+.B noauth
+configuration command (see
+.IR fsconfig (8)).
+.PP
+The group numbered 9999, normally called
+.BR noworld ,
+is special
+on the file server.  Any user belonging to that group has
+attenuated access privileges.  Specifically, when checking such
+a user's access to files, the file's permission bits are first ANDed
+with 0770 for normal files or 0771 for directories.  The effect is
+to deny world access permissions to
+.B noworld
+users, except
+when walking directories.
+.PP
+The user
+.B none
+is always allowed to attach to
+.B emelie
+without authentication but has minimal permissions.
+.PP
+.B Emelie
+maintains three file systems
+on a combination of disks and
+write-once-read-many (WORM) magneto-optical disks.
+.TP
+.B other
+is a simple disk-based file system similar to
+.IR kfs (4) .
+.TP
+.B main
+is a worm-based file system with a disk-based
+look-aside cache.
+The disk cache holds
+modified worm blocks
+to overcome the write-once property of the worm.
+The cache also holds recently accessed
+non-modified blocks to
+speed up the effective access time of the worm.
+Occasionally
+(usually daily at 5AM) the modified blocks in the
+disk cache are
+.IR dumped .
+At this time,
+traffic to the file system is halted and the
+modified blocks are relabeled to the unwritten
+portion of the worm.
+After the dump,
+the file system traffic is continued and
+the relabeled blocks are copied to the worm by
+a background process.
+.TP
+.B dump
+Each time the main file system is dumped,
+its root is appended to a subdirectory of the dump file system.
+Since the dump file system is not mirrored with a disk
+cache,
+it is read-only.
+The name of the newly added root is created from the date
+of the dump:
+.BI / yyyy / mmdds\f1.
+Here
+.I yyyy
+is the full year,
+.I mm
+is the month number,
+.I dd
+is the day number and
+.I s
+is a sequence number if more than
+one dump is done in a day.
+For the first dump,
+.I s
+is null.
+For the subsequent dumps
+.I s
+is 1, 2, 3, etc.
+.sp
+The root of the main file system
+that is frozen on the first dump
+of March 1, 1992
+will be named
+.B /1992/0301/
+in the dump file system.
+.SS "Changes from fs(4)"
+.IR fs (4)'s
+IP configuration is ignored and the underlying system's is used.
+.PP
+Various other
+.IR fs (4)
+commands have been omitted since they (or equivalents) can now be
+executed directly on the underlying CPU server,
+notably
+.I date
+and
+.I passwd
+(see
+.IR auth/wrkey ).
+.PP
+.IR fs (4)'s
+device names
+.L h
+for IDE disks and
+.L m
+for Marvell SATA disks are not supported; use
+.B -m
+to map wren devices to appropriate names under
+.BR /dev/sd* .
+.PP
+The file server kernel seems to have scanned PCI buses
+in reverse order from the other Plan 9 kernels,
+so systems with multiple SCSI cards may find controller
+numbering reversed.
+.B -m
+can be used to compensate for this if you don't want to change
+.I filsys
+declarations.
+.PP
+The file server kernel's
+.I config
+field in NVRAM was overloaded in recent times to hold a
+.IR secstore (1)
+key for the CPU hostowner.
+Since
+.I cwfs
+runs on a CPU kernel,
+the location of its configuration block must be supplied on the command line.
+.PP
+Disk labels are now implemented for
+.B l
+devices.
+At the first access of a side,
+.I cwfs
+will attempt to read the label and verify that it has the correct side
+number and byte order; if either is wrong, it will issue a warning.
+If the label cannot be read,
+.I cwfs
+will attempt to write a new label.
+.SH EXAMPLES
+Place the root of the
+.B dump
+file system on
+.B /n/dump
+and show the modified times of the MIPS C compiler
+over all dumps in February, 1992:
+.IP
+.EX
+9fs dump
+ls -l /n/dump/1992/02??/mips/bin/vc
+.EE
+.PP
+To get only one line of output for each version of the compiler:
+.IP
+.EX
+ls -lp /n/dump/1992/02??/mips/bin/vc | uniq
+.EE
+.PP
+Make the
+.B other
+file system available in directory
+.BR /n/emelieother :
+.IP
+.EX
+mount -c /srv/boot /n/emelieother other
+.EE
+.SH SOURCE
+.B /sys/src/cmd/cwfs
+.SH SEE ALSO
+.IR yesterday (1),
+.IR fs (3),
+.IR sd (3),
+.IR fs (4),
+.IR srv (4),
+.IR fs (8)
+.br
+Sean Quinlan,
+``A Cached WORM File System'',
+.I
+Software \- Practice and Experience,
+December, 1991
+.br
+Ken Thompson,
+Geoff Collyer,
+``The 64-bit Standalone Plan 9 File Server''
+.SH BUGS
+For the moment,
+the file server serves both the old (9P1) and new (9P2000) versions of 9P,
+deciding which to serve by sniffing the first packet on each connection.
+.PP
+File system block size and disk address size (32- or 64-bit) are fixed
+at compilation time, and this is not easily changed.

+ 20 - 0
sys/src/cmd/cwfs/32bit.h

@@ -0,0 +1,20 @@
+/*
+ * fundamental constants and types of the implementation
+ * changing any of these changes the layout on disk
+ */
+
+/*
+ * compatible on disk with the old 32-bit file server and can also speak 9P1.
+ * this lets people run this file server on their old file systems.
+ * DON'T TOUCH or you'll break compatibility.
+ */
+enum {
+	NAMELEN		= 28,		/* max size of file name components */
+	NDBLOCK		= 6,		/* number of direct blocks in Dentry */
+	NIBLOCK		= 2,		/* max depth of indirect blocks */
+};
+
+typedef long Off;	/* file offsets & sizes, in bytes & blocks */
+
+#define COMPAT32
+#define swaboff swab4

+ 22 - 0
sys/src/cmd/cwfs/64bit.h

@@ -0,0 +1,22 @@
+/*
+ * fundamental constants and types of the implementation
+ * changing any of these changes the layout on disk
+ */
+
+/* the glorious new, incompatible (on disk) 64-bit world */
+
+/* keeping NAMELEN ≤ 50 bytes permits 3 Dentrys per mag disk sector */
+enum {
+	NAMELEN		= 56,		/* max size of file name components */
+	NDBLOCK		= 6,		/* number of direct blocks in Dentry */
+	NIBLOCK		= 4,		/* max depth of indirect blocks */
+};
+
+/*
+ * file offsets & sizes, in bytes & blocks.  typically long or vlong.
+ * vlong is used in the code where would be needed if Off were just long.
+ */
+typedef vlong Off;
+
+#undef COMPAT32
+#define swaboff swab8

+ 31 - 0
sys/src/cmd/cwfs/9netics32.16k/conf.c

@@ -0,0 +1,31 @@
+/* 9net32.16k-specific configuration */
+
+#include "all.h"
+
+#ifndef	DATE
+#define	DATE 1170808167L
+#endif
+
+Timet	fs_mktime = DATE;			/* set by mkfile */
+
+Startsb	startsb[] = {
+	"main",		2,
+	nil,
+};
+
+void
+localconfinit(void)
+{
+	conf.nodump = 0;
+	conf.dumpreread = 0;
+	conf.firstsb = 0;	/* time- & jukebox-dependent optimisation */
+	conf.recovsb = 0;
+	conf.nlgmsg = 1100;	/* @8576 bytes, for packets */
+	conf.nsmmsg = 500;	/* @128 bytes */
+}
+
+int (*fsprotocol[])(Msgbuf*) = {
+	serve9p1,
+	serve9p2,
+	nil,
+};

+ 36 - 0
sys/src/cmd/cwfs/9netics32.16k/dat.h

@@ -0,0 +1,36 @@
+/* 9net32.16k's configuration: 16K blocks, 32-bit sizes */
+
+/*
+ * The most fundamental constant.
+ * The code will not compile with RBUFSIZE made a variable;
+ * for one thing, RBUFSIZE determines FEPERBUF, which determines
+ * the number of elements in a free-list-block array.
+ */
+#ifndef RBUFSIZE
+#define RBUFSIZE	(16*1024)	/* raw buffer size */
+#endif
+#include "32bit.h"
+/*
+ * setting this to zero permits the use of discs of different sizes, but
+ * can make jukeinit() quite slow while the robotics work through each disc
+ * twice (once per side).
+ */
+enum { FIXEDSIZE = 1 };
+
+
+#include "portdat.h"
+
+enum { MAXBANK = 2 };
+
+typedef struct Mbank {
+	ulong	base;
+	ulong	limit;
+} Mbank;
+
+typedef struct Mconf {
+	Lock;
+	Mbank	bank[MAXBANK];
+	int	nbank;
+	ulong	memsize;
+} Mconf;
+extern Mconf mconf;

+ 2 - 0
sys/src/cmd/cwfs/9netics32.16k/mkfile

@@ -0,0 +1,2 @@
+FS=9net32.16k
+<../portmkfile

+ 31 - 0
sys/src/cmd/cwfs/9netics64.8k/conf.c

@@ -0,0 +1,31 @@
+/* 9net64.8k-specific configuration */
+
+#include "all.h"
+
+#ifndef	DATE
+#define	DATE 1170808167L
+#endif
+
+Timet	fs_mktime = DATE;			/* set by mkfile */
+
+Startsb	startsb[] = {
+	"main",		2,
+	nil,
+};
+
+void
+localconfinit(void)
+{
+	conf.nodump = 0;
+	conf.dumpreread = 0;
+	conf.firstsb = 0;	/* time- & jukebox-dependent optimisation */
+	conf.recovsb = 0;
+	conf.nlgmsg = 1100;	/* @8576 bytes, for packets */
+	conf.nsmmsg = 500;	/* @128 bytes */
+}
+
+int (*fsprotocol[])(Msgbuf*) = {
+	/* 64-bit file servers can't serve 9P1 correctly: NAMELEN is too big */
+	serve9p2,
+	nil,
+};

+ 36 - 0
sys/src/cmd/cwfs/9netics64.8k/dat.h

@@ -0,0 +1,36 @@
+/* 9net64.8k's configuration: 8K blocks, 64-bit sizes */
+
+/*
+ * The most fundamental constant.
+ * The code will not compile with RBUFSIZE made a variable;
+ * for one thing, RBUFSIZE determines FEPERBUF, which determines
+ * the number of elements in a free-list-block array.
+ */
+#ifndef RBUFSIZE
+#define RBUFSIZE	(8*1024)	/* raw buffer size */
+#endif
+#include "64bit.h"
+/*
+ * setting this to zero permits the use of discs of different sizes, but
+ * can make jukeinit() quite slow while the robotics work through each disc
+ * twice (once per side).
+ */
+enum { FIXEDSIZE = 1 };
+
+
+#include "portdat.h"
+
+enum { MAXBANK = 2 };
+
+typedef struct Mbank {
+	ulong	base;
+	ulong	limit;
+} Mbank;
+
+typedef struct Mconf {
+	Lock;
+	Mbank	bank[MAXBANK];
+	int	nbank;
+	ulong	memsize;
+} Mconf;
+extern Mconf mconf;

+ 2 - 0
sys/src/cmd/cwfs/9netics64.8k/mkfile

@@ -0,0 +1,2 @@
+FS=9net64.8k
+<../portmkfile

+ 1636 - 0
sys/src/cmd/cwfs/9p1.c

@@ -0,0 +1,1636 @@
+#include "all.h"
+#include "9p1.h"
+
+extern Nvrsafe	nvr;
+
+typedef struct {
+	uchar	chal[CHALLEN];		/* locally generated challenge */
+	uchar	rchal[CHALLEN];		/* remotely generated challenge */
+	Lock	idlock;
+	ulong	idoffset;		/* offset of id vector */
+	ulong	idvec;			/* vector of acceptable id's */
+} Authinfo;
+
+static void
+f_nop(Chan *cp, Fcall*, Fcall*)
+{
+	if(CHAT(cp))
+		print("c_nop %d\n", cp->chan);
+}
+
+static void
+f_flush(Chan *cp, Fcall*, Fcall*)
+{
+	if(CHAT(cp))
+		print("c_flush %d\n", cp->chan);
+	runlock(&cp->reflock);
+	wlock(&cp->reflock);
+	wunlock(&cp->reflock);
+	rlock(&cp->reflock);
+}
+
+/*
+ *  create a challenge for a fid space
+ */
+static void
+mkchallenge(Authinfo *aip)
+{
+	int i;
+
+	srand((ulong)aip + time(nil));
+	for(i = 0; i < CHALLEN; i++)
+		aip->chal[i] = nrand(256);
+
+	aip->idoffset = 0;
+	aip->idvec = 0;
+}
+
+static void
+f_session(Chan *cp, Fcall *in, Fcall *ou)
+{
+	Authinfo *aip;
+
+	aip = (Authinfo*)cp->authinfo;
+
+	if(CHAT(cp))
+		print("c_session %d\n", cp->chan);
+	memmove(aip->rchal, in->chal, sizeof(aip->rchal));
+	mkchallenge(aip);
+	memmove(ou->chal, aip->chal, sizeof(ou->chal));
+	if(noauth || wstatallow)
+		memset(ou->authid, 0, sizeof(ou->authid));
+	else
+		memmove(ou->authid, nvr.authid, sizeof(ou->authid));
+
+	sprint(ou->authdom, "%s.%s", service, nvr.authdom);
+	fileinit(cp);
+}
+
+/*
+ *  match a challenge from an attach
+ */
+static int
+authorize(Chan *cp, Fcall *in, Fcall *ou)
+{
+	Ticket t;
+	Authenticator a;
+	int x;
+	ulong bit;
+	Authinfo *aip;
+
+	if(noauth || wstatallow)	/* set to allow entry during boot */
+		return 1;
+
+	if(strcmp(in->uname, "none") == 0)
+		return 1;
+
+	if(in->type == Toattach)
+		return 0;
+
+	/* decrypt and unpack ticket */
+	convM2T9p1(in->ticket, &t, nvr.machkey);
+	if(t.num != AuthTs){
+		print("9p1: bad AuthTs num\n");
+		return 0;
+	}
+
+	/* decrypt and unpack authenticator */
+	convM2A9p1(in->auth, &a, t.key);
+	if(a.num != AuthAc){
+		print("9p1: bad AuthAc num\n");
+		return 0;
+	}
+
+	/* challenges must match */
+	aip = (Authinfo*)cp->authinfo;
+	if(memcmp(a.chal, aip->chal, sizeof(a.chal)) != 0){
+		print("9p1: bad challenge\n");
+		return 0;
+	}
+
+	/*
+	 *  the id must be in a valid range.  the range is specified by a
+	 *  lower bound (idoffset) and a bit vector (idvec) where a
+	 *  bit set to 1 means unusable
+	 */
+	lock(&aip->idlock);
+	x = a.id - aip->idoffset;
+	bit = 1<<x;
+	if(x < 0 || x > 31 || (bit&aip->idvec)){
+		unlock(&aip->idlock);
+		print("9p1: id out of range: idoff %ld idvec %lux id %ld\n",
+		   aip->idoffset, aip->idvec, a.id);
+		return 0;
+	}
+	aip->idvec |= bit;
+
+	/* normalize the vector */
+	while(aip->idvec&0xffff0001){
+		aip->idvec >>= 1;
+		aip->idoffset++;
+	}
+	unlock(&aip->idlock);
+
+	/* ticket name and attach name must match */
+	if(memcmp(in->uname, t.cuid, sizeof(in->uname)) != 0){
+		print("9p1: names don't match\n");
+		return 0;
+	}
+
+	/* copy translated name into input record */
+	memmove(in->uname, t.suid, sizeof(in->uname));
+
+	/* craft a reply */
+	a.num = AuthAs;
+	memmove(a.chal, aip->rchal, CHALLEN);
+	convA2M9p1(&a, ou->rauth, t.key);
+
+	return 1;
+}
+
+/*
+ * buggery to give false qid for
+ * the top 2 levels of the dump fs
+ */
+void
+mkqid(Qid* qid, Dentry *d, int buggery)
+{
+	int c;
+
+	if(buggery && d->qid.path == (QPDIR|QPROOT)){
+		c = d->name[0];
+		if(isascii(c) && isdigit(c)){
+			qid->path = 3;
+			qid->vers = d->qid.version;
+			qid->type = QTDIR;
+
+			c = (c-'0')*10 + (d->name[1]-'0');
+			if(c >= 1 && c <= 12)
+				qid->path = 4;
+			return;
+		}
+	}
+
+	mkqid9p2(qid, &d->qid, d->mode);
+}
+
+int
+mkqidcmp(Qid* qid, Dentry *d)
+{
+	Qid tmp;
+
+	mkqid(&tmp, d, 1);
+	if(qid->path == tmp.path && qid->type == tmp.type)
+		return 0;
+	return Eqid;
+}
+
+static void
+f_attach(Chan *cp, Fcall *in, Fcall *ou)
+{
+	Iobuf *p;
+	Dentry *d;
+	File *f;
+	int u;
+	Filsys *fs;
+	Off raddr;
+
+	if(CHAT(cp)) {
+		print("c_attach %d\n", cp->chan);
+		print("\tfid = %d\n", in->fid);
+		print("\tuid = %s\n", in->uname);
+		print("\targ = %s\n", in->aname);
+	}
+
+	ou->qid = QID9P1(0,0);
+	ou->fid = in->fid;
+	if(!in->aname[0])	/* default */
+		strncpy(in->aname, "main", sizeof(in->aname));
+	p = 0;
+	f = filep(cp, in->fid, 1);
+	if(!f) {
+		ou->err = Efid;
+		goto out;
+	}
+
+	u = -1;
+	if(cp != cons.chan) {
+		if(noattach && strcmp(in->uname, "none")) {
+			ou->err = Enoattach;
+			goto out;
+		}
+		if(authorize(cp, in, ou) == 0 || strcmp(in->uname, "adm") == 0) {
+			ou->err = Eauth;
+			goto out;
+		}
+		u = strtouid(in->uname);
+		if(u < 0) {
+			ou->err = Ebadu;
+			goto out;
+		}
+	}
+	f->uid = u;
+
+	fs = fsstr(in->aname);
+	if(fs == 0) {
+		ou->err = Ebadspc;
+		goto out;
+	}
+	raddr = getraddr(fs->dev);
+	p = getbuf(fs->dev, raddr, Brd);
+	d = getdir(p, 0);
+	if(!d || checktag(p, Tdir, QPROOT) || !(d->mode & DALLOC)) {
+		ou->err = Ealloc;
+		goto out;
+	}
+	if (iaccess(f, d, DEXEC) ||
+	    f->uid == 0 && fs->dev->type == Devro) {
+		/*
+		 * 'none' not allowed on dump
+		 */
+		ou->err = Eaccess;
+		goto out;
+	}
+	accessdir(p, d, FREAD, f->uid);
+	mkqid(&f->qid, d, 1);
+	f->fs = fs;
+	f->addr = raddr;
+	f->slot = 0;
+	f->open = 0;
+	freewp(f->wpath);
+	f->wpath = 0;
+
+	mkqid9p1(&ou->qid, &f->qid);
+
+	strncpy(cp->whoname, in->uname, sizeof(cp->whoname));
+	cp->whotime = time(nil);
+	if(cons.flags & attachflag)
+		print("9p1: attach %s %T to \"%s\" C%d\n",
+			cp->whoname, cp->whotime, fs->name, cp->chan);
+
+out:
+	if((cons.flags & attachflag) && ou->err)
+		print("9p1: attach %s %T SUCK EGGS --- %s\n",
+			in->uname, time(nil), errstr9p[ou->err]);
+	if(p)
+		putbuf(p);
+	if(f) {
+		qunlock(f);
+		if(ou->err)
+			freefp(f);
+	}
+}
+
+static void
+f_clone(Chan *cp, Fcall *in, Fcall *ou)
+{
+	File *f1, *f2;
+	Wpath *p;
+	int fid, fid1;
+
+	if(CHAT(cp)) {
+		print("c_clone %d\n", cp->chan);
+		print("\told fid = %d\n", in->fid);
+		print("\tnew fid = %d\n", in->newfid);
+	}
+
+	fid = in->fid;
+	fid1 = in->newfid;
+
+	f1 = 0;
+	f2 = 0;
+	if(fid < fid1) {
+		f1 = filep(cp, fid, 0);
+		f2 = filep(cp, fid1, 1);
+	} else
+	if(fid1 < fid) {
+		f2 = filep(cp, fid1, 1);
+		f1 = filep(cp, fid, 0);
+	}
+	if(!f1 || !f2) {
+		ou->err = Efid;
+		goto out;
+	}
+
+
+	f2->fs = f1->fs;
+	f2->addr = f1->addr;
+	f2->open = f1->open & ~FREMOV;
+	f2->uid = f1->uid;
+	f2->slot = f1->slot;
+	f2->qid = f1->qid;
+
+	freewp(f2->wpath);
+	lock(&wpathlock);
+	f2->wpath = f1->wpath;
+	for(p = f2->wpath; p; p = p->up)
+		p->refs++;
+	unlock(&wpathlock);
+
+out:
+	ou->fid = fid;
+	if(f1)
+		qunlock(f1);
+	if(f2) {
+		qunlock(f2);
+		if(ou->err)
+			freefp(f2);
+	}
+}
+
+static void
+f_walk(Chan *cp, Fcall *in, Fcall *ou)
+{
+	Iobuf *p, *p1;
+	Dentry *d, *d1;
+	File *f;
+	Wpath *w;
+	int slot;
+	Off addr, qpath;
+
+	if(CHAT(cp)) {
+		print("c_walk %d\n", cp->chan);
+		print("\tfid = %d\n", in->fid);
+		print("\tname = %s\n", in->name);
+	}
+
+	ou->fid = in->fid;
+	ou->qid = QID9P1(0,0);
+	p = 0;
+	f = filep(cp, in->fid, 0);
+	if(!f) {
+		ou->err = Efid;
+		goto out;
+	}
+	p = getbuf(f->fs->dev, f->addr, Brd);
+	d = getdir(p, f->slot);
+	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
+		ou->err = Ealloc;
+		goto out;
+	}
+	if(!(d->mode & DDIR)) {
+		ou->err = Edir1;
+		goto out;
+	}
+	if(ou->err = mkqidcmp(&f->qid, d))
+		goto out;
+	if(cp != cons.chan && iaccess(f, d, DEXEC)) {
+		ou->err = Eaccess;
+		goto out;
+	}
+	accessdir(p, d, FREAD, f->uid);
+	if(strcmp(in->name, ".") == 0)
+		goto setdot;
+	if(strcmp(in->name, "..") == 0) {
+		if(f->wpath == 0)
+			goto setdot;
+		putbuf(p);
+		p = 0;
+		addr = f->wpath->addr;
+		slot = f->wpath->slot;
+		p1 = getbuf(f->fs->dev, addr, Brd);
+		d1 = getdir(p1, slot);
+		if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
+			if(p1)
+				putbuf(p1);
+			ou->err = Ephase;
+			goto out;
+		}
+		lock(&wpathlock);
+		f->wpath->refs--;
+		f->wpath = f->wpath->up;
+		unlock(&wpathlock);
+		goto found;
+	}
+	for(addr=0;; addr++) {
+		if(p == 0) {
+			p = getbuf(f->fs->dev, f->addr, Brd);
+			d = getdir(p, f->slot);
+			if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
+				ou->err = Ealloc;
+				goto out;
+			}
+		}
+		qpath = d->qid.path;
+		p1 = dnodebuf1(p, d, addr, 0, f->uid);
+		p = 0;
+		if(!p1 || checktag(p1, Tdir, qpath) ) {
+			if(p1)
+				putbuf(p1);
+			ou->err = Eentry;
+			goto out;
+		}
+		for(slot=0; slot<DIRPERBUF; slot++) {
+			d1 = getdir(p1, slot);
+			if(!(d1->mode & DALLOC))
+				continue;
+			if(strncmp(in->name, d1->name, sizeof(in->name)) != 0)
+				continue;
+			/*
+			 * update walk path
+			 */
+			w = newwp();
+			if(!w) {
+				ou->err = Ewalk;
+				putbuf(p1);
+				goto out;
+			}
+			w->addr = f->addr;
+			w->slot = f->slot;
+			w->up = f->wpath;
+			f->wpath = w;
+			slot += DIRPERBUF*addr;
+			goto found;
+		}
+		putbuf(p1);
+	}
+
+found:
+	f->addr = p1->addr;
+	mkqid(&f->qid, d1, 1);
+	putbuf(p1);
+	f->slot = slot;
+
+setdot:
+	mkqid9p1(&ou->qid, &f->qid);
+	f->open = 0;
+
+out:
+	if(p)
+		putbuf(p);
+	if(f)
+		qunlock(f);
+}
+
+static void
+f_open(Chan *cp, Fcall *in, Fcall *ou)
+{
+	Iobuf *p;
+	Dentry *d;
+	File *f;
+	Tlock *t;
+	Qid qid;
+	int ro, fmod, wok;
+
+	if(CHAT(cp)) {
+		print("c_open %d\n", cp->chan);
+		print("\tfid = %d\n", in->fid);
+		print("\tmode = %o\n", in->mode);
+	}
+
+	wok = 0;
+	if(cp == cons.chan || writeallow)
+		wok = 1;
+
+	p = 0;
+	f = filep(cp, in->fid, 0);
+	if(!f) {
+		ou->err = Efid;
+		goto out;
+	}
+
+	/*
+	 * if remove on close, check access here
+	 */
+	ro = f->fs->dev->type == Devro;
+	if(in->mode & ORCLOSE) {
+		if(ro) {
+			ou->err = Eronly;
+			goto out;
+		}
+		/*
+		 * check on parent directory of file to be deleted
+		 */
+		if(f->wpath == 0 || f->wpath->addr == f->addr) {
+			ou->err = Ephase;
+			goto out;
+		}
+		p = getbuf(f->fs->dev, f->wpath->addr, Brd);
+		d = getdir(p, f->wpath->slot);
+		if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
+			ou->err = Ephase;
+			goto out;
+		}
+		if(iaccess(f, d, DWRITE)) {
+			ou->err = Eaccess;
+			goto out;
+		}
+		putbuf(p);
+	}
+	p = getbuf(f->fs->dev, f->addr, Brd);
+	d = getdir(p, f->slot);
+	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
+		ou->err = Ealloc;
+		goto out;
+	}
+	if(ou->err = mkqidcmp(&f->qid, d))
+		goto out;
+	mkqid(&qid, d, 1);
+	switch(in->mode & 7) {
+
+	case OREAD:
+		if(iaccess(f, d, DREAD) && !wok)
+			goto badaccess;
+		fmod = FREAD;
+		break;
+
+	case OWRITE:
+		if((d->mode & DDIR) ||
+		   (iaccess(f, d, DWRITE) && !wok))
+			goto badaccess;
+		if(ro) {
+			ou->err = Eronly;
+			goto out;
+		}
+		fmod = FWRITE;
+		break;
+
+	case ORDWR:
+		if((d->mode & DDIR) ||
+		   (iaccess(f, d, DREAD) && !wok) ||
+		   (iaccess(f, d, DWRITE) && !wok))
+			goto badaccess;
+		if(ro) {
+			ou->err = Eronly;
+			goto out;
+		}
+		fmod = FREAD+FWRITE;
+		break;
+
+	case OEXEC:
+		if((d->mode & DDIR) ||
+		   (iaccess(f, d, DEXEC) && !wok))
+			goto badaccess;
+		fmod = FREAD;
+		break;
+
+	default:
+		ou->err = Emode;
+		goto out;
+	}
+	if(in->mode & OTRUNC) {
+		if((d->mode & DDIR) ||
+		   (iaccess(f, d, DWRITE) && !wok))
+			goto badaccess;
+		if(ro) {
+			ou->err = Eronly;
+			goto out;
+		}
+	}
+	t = 0;
+	if(d->mode & DLOCK) {
+		t = tlocked(p, d);
+		if(t == nil) {
+			ou->err = Elocked;
+			goto out;
+		}
+	}
+	if(in->mode & ORCLOSE)
+		fmod |= FREMOV;
+	f->open = fmod;
+	if(in->mode & OTRUNC)
+		if(!(d->mode & DAPND)) {
+			dtrunc(p, d, f->uid);
+			qid.vers = d->qid.version;
+		}
+	f->tlock = t;
+	if(t)
+		t->file = f;
+	f->lastra = 1;
+	mkqid9p1(&ou->qid, &qid);
+	goto out;
+
+badaccess:
+	ou->err = Eaccess;
+	f->open = 0;
+
+out:
+	if(p)
+		putbuf(p);
+	if(f)
+		qunlock(f);
+	ou->fid = in->fid;
+}
+
+static void
+f_create(Chan *cp, Fcall *in, Fcall *ou)
+{
+	Iobuf *p, *p1;
+	Dentry *d, *d1;
+	File *f;
+	int slot, slot1, fmod, wok;
+	Off addr, addr1, path;
+	Qid qid;
+	Tlock *t;
+	Wpath *w;
+
+	if(CHAT(cp)) {
+		print("c_create %d\n", cp->chan);
+		print("\tfid = %d\n", in->fid);
+		print("\tname = %s\n", in->name);
+		print("\tperm = %lx+%lo\n", (in->perm>>28)&0xf,
+				in->perm&0777);
+		print("\tmode = %o\n", in->mode);
+	}
+
+	wok = 0;
+	if(cp == cons.chan || writeallow)
+		wok = 1;
+
+	p = 0;
+	f = filep(cp, in->fid, 0);
+	if(!f) {
+		ou->err = Efid;
+		goto out;
+	}
+	if(f->fs->dev->type == Devro) {
+		ou->err = Eronly;
+		goto out;
+	}
+
+	p = getbuf(f->fs->dev, f->addr, Brd);
+	d = getdir(p, f->slot);
+	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
+		ou->err = Ealloc;
+		goto out;
+	}
+	if(ou->err = mkqidcmp(&f->qid, d))
+		goto out;
+	if(!(d->mode & DDIR)) {
+		ou->err = Edir2;
+		goto out;
+	}
+	if(iaccess(f, d, DWRITE) && !wok) {
+		ou->err = Eaccess;
+		goto out;
+	}
+	accessdir(p, d, FREAD, f->uid);
+	if(!strncmp(in->name, ".", sizeof(in->name)) ||
+	   !strncmp(in->name, "..", sizeof(in->name))) {
+		ou->err = Edot;
+		goto out;
+	}
+	if(checkname(in->name)) {
+		ou->err = Ename;
+		goto out;
+	}
+	addr1 = 0;
+	slot1 = 0;	/* set */
+	for(addr=0;; addr++) {
+		p1 = dnodebuf(p, d, addr, 0, f->uid);
+		if(!p1) {
+			if(addr1)
+				break;
+			p1 = dnodebuf(p, d, addr, Tdir, f->uid);
+		}
+		if(p1 == 0) {
+			ou->err = Efull;
+			goto out;
+		}
+		if(checktag(p1, Tdir, d->qid.path)) {
+			putbuf(p1);
+			goto phase;
+		}
+		for(slot=0; slot<DIRPERBUF; slot++) {
+			d1 = getdir(p1, slot);
+			if(!(d1->mode & DALLOC)) {
+				if(!addr1) {
+					addr1 = p1->addr;
+					slot1 = slot + addr*DIRPERBUF;
+				}
+				continue;
+			}
+			if(!strncmp(in->name, d1->name, sizeof(in->name))) {
+				putbuf(p1);
+				ou->err = Eexist;
+				goto out;
+			}
+		}
+		putbuf(p1);
+	}
+	switch(in->mode & 7) {
+	case OEXEC:
+	case OREAD:		/* seems only useful to make directories */
+		fmod = FREAD;
+		break;
+
+	case OWRITE:
+		fmod = FWRITE;
+		break;
+
+	case ORDWR:
+		fmod = FREAD+FWRITE;
+		break;
+
+	default:
+		ou->err = Emode;
+		goto out;
+	}
+	if(in->perm & PDIR)
+		if((in->mode & OTRUNC) || (in->perm & PAPND) || (fmod & FWRITE))
+			goto badaccess;
+	/*
+	 * do it
+	 */
+	path = qidpathgen(f->fs->dev);
+	p1 = getbuf(f->fs->dev, addr1, Brd|Bimm|Bmod);
+	d1 = getdir(p1, slot1);
+	if(!d1 || checktag(p1, Tdir, d->qid.path)) {
+		if(p1)
+			putbuf(p1);
+		goto phase;
+	}
+	if(d1->mode & DALLOC) {
+		putbuf(p1);
+		goto phase;
+	}
+
+	strncpy(d1->name, in->name, sizeof(in->name));
+	if(cp == cons.chan) {
+		d1->uid = cons.uid;
+		d1->gid = cons.gid;
+	} else {
+		d1->uid = f->uid;
+		d1->gid = d->gid;
+		in->perm &= d->mode | ~0666;
+		if(in->perm & PDIR)
+			in->perm &= d->mode | ~0777;
+	}
+	d1->qid.path = path;
+	d1->qid.version = 0;
+	d1->mode = DALLOC | (in->perm & 0777);
+	if(in->perm & PDIR) {
+		d1->mode |= DDIR;
+		d1->qid.path |= QPDIR;
+	}
+	if(in->perm & PAPND)
+		d1->mode |= DAPND;
+	t = 0;
+	if(in->perm & PLOCK) {
+		d1->mode |= DLOCK;
+		t = tlocked(p1, d1);
+		/* if nil, out of tlock structures */
+	}
+	accessdir(p1, d1, FWRITE, f->uid);
+	mkqid(&qid, d1, 0);
+	putbuf(p1);
+	accessdir(p, d, FWRITE, f->uid);
+
+	/*
+	 * do a walk to new directory entry
+	 */
+	w = newwp();
+	if(!w) {
+		ou->err = Ewalk;
+		goto out;
+	}
+	w->addr = f->addr;
+	w->slot = f->slot;
+	w->up = f->wpath;
+	f->wpath = w;
+	f->qid = qid;
+	f->tlock = t;
+	if(t)
+		t->file = f;
+	f->lastra = 1;
+	if(in->mode & ORCLOSE)
+		fmod |= FREMOV;
+	f->open = fmod;
+	f->addr = addr1;
+	f->slot = slot1;
+	mkqid9p1(&ou->qid, &qid);
+	goto out;
+
+badaccess:
+	ou->err = Eaccess;
+	goto out;
+
+phase:
+	ou->err = Ephase;
+
+out:
+	if(p)
+		putbuf(p);
+	if(f)
+		qunlock(f);
+	ou->fid = in->fid;
+}
+
+static void
+f_read(Chan *cp, Fcall *in, Fcall *ou)
+{
+	Iobuf *p, *p1;
+	File *f;
+	Dentry *d, *d1;
+	Tlock *t;
+	Off addr, offset;
+	Timet tim;
+	int nread, count, n, o, slot;
+
+	if(CHAT(cp)) {
+		print("c_read %d\n", cp->chan);
+		print("\tfid = %d\n", in->fid);
+		print("\toffset = %lld\n", (Wideoff)in->offset);
+		print("\tcount = %ld\n", in->count);
+	}
+
+	p = 0;
+	count = in->count;
+	offset = in->offset;
+	nread = 0;
+	f = filep(cp, in->fid, 0);
+	if(!f) {
+		ou->err = Efid;
+		goto out;
+	}
+	if(!(f->open & FREAD)) {
+		ou->err = Eopen;
+		goto out;
+	}
+	if(count < 0 || count > MAXDAT) {
+		ou->err = Ecount;
+		goto out;
+	}
+	if(offset < 0) {
+		ou->err = Eoffset;
+		goto out;
+	}
+	p = getbuf(f->fs->dev, f->addr, Brd);
+	d = getdir(p, f->slot);
+	if(!d || !(d->mode & DALLOC)) {
+		ou->err = Ealloc;
+		goto out;
+	}
+	if(ou->err = mkqidcmp(&f->qid, d))
+		goto out;
+	if(t = f->tlock) {
+		tim = toytime();
+		if(t->time < tim || t->file != f) {
+			ou->err = Ebroken;
+			goto out;
+		}
+		/* renew the lock */
+		t->time = tim + TLOCK;
+	}
+	accessdir(p, d, FREAD, f->uid);
+	if(d->mode & DDIR) {
+		addr = 0;
+		goto dread;
+	}
+
+	/* XXXX terrible hack to get at raw data XXXX */
+	if(rawreadok && strncmp(d->name, "--raw--", 7) == 0) {
+		Device *dev;
+		Devsize boff, bsize;
+
+		dev = p->dev;
+		putbuf(p);
+		p = 0;
+
+		boff = number(d->name + 7, 0, 10) * 100000;
+		if(boff < 0)
+			boff = 0;
+		if(boff > devsize(dev))
+			boff = devsize(dev);
+		bsize = devsize(dev) - boff;
+
+		if(offset+count >= 100000*RBUFSIZE)
+			count = 100000*RBUFSIZE - offset;
+
+		if((offset+count)/RBUFSIZE >= bsize)
+			/* will not overflow */
+			count = bsize*RBUFSIZE - offset;
+
+		while(count > 0) {
+			addr = offset / RBUFSIZE;
+			addr += boff;
+			o = offset % RBUFSIZE;
+			n = RBUFSIZE - o;
+			if(n > count)
+				n = count;
+
+			p1 = getbuf(dev, addr, Brd);
+			if(p1) {
+				memmove(ou->data+nread, p1->iobuf+o, n);
+				putbuf(p1);
+			} else
+				memset(ou->data+nread, 0, n);
+			count -= n;
+			nread += n;
+			offset += n;
+		}
+		goto out;
+	}
+
+	if(offset+count > d->size)
+		count = d->size - offset;
+	while(count > 0) {
+		if(p == 0) {
+			p = getbuf(f->fs->dev, f->addr, Brd);
+			d = getdir(p, f->slot);
+			if(!d || !(d->mode & DALLOC)) {
+				ou->err = Ealloc;
+				goto out;
+			}
+		}
+		addr = offset / BUFSIZE;
+		f->lastra = dbufread(p, d, addr, f->lastra, f->uid);
+		o = offset % BUFSIZE;
+		n = BUFSIZE - o;
+		if(n > count)
+			n = count;
+		p1 = dnodebuf1(p, d, addr, 0, f->uid);
+		p = 0;
+		if(p1) {
+			if(checktag(p1, Tfile, QPNONE)) {
+				ou->err = Ephase;
+				putbuf(p1);
+				goto out;
+			}
+			memmove(ou->data+nread, p1->iobuf+o, n);
+			putbuf(p1);
+		} else
+			memset(ou->data+nread, 0, n);
+		count -= n;
+		nread += n;
+		offset += n;
+	}
+	goto out;
+
+dread:
+	for (;;) {
+		if(p == 0) {
+			p = getbuf(f->fs->dev, f->addr, Brd);
+			d = getdir(p, f->slot);
+			if(!d || !(d->mode & DALLOC)) {
+				ou->err = Ealloc;
+				goto out;
+			}
+		}
+		p1 = dnodebuf1(p, d, addr, 0, f->uid);
+		p = 0;
+		if(!p1)
+			goto out;
+		if(checktag(p1, Tdir, QPNONE)) {
+			ou->err = Ephase;
+			putbuf(p1);
+			goto out;
+		}
+		n = DIRREC;
+		for(slot=0; slot<DIRPERBUF; slot++) {
+			d1 = getdir(p1, slot);
+			if(!(d1->mode & DALLOC))
+				continue;
+			if(offset >= n) {
+				offset -= n;
+				continue;
+			}
+			if(count < n) {
+				putbuf(p1);
+				goto out;
+			}
+			if(convD2M9p1(d1, ou->data+nread) != n)
+				print("9p1: dirread convD2M1990\n");
+			nread += n;
+			count -= n;
+		}
+		putbuf(p1);
+		addr++;
+	}
+out:
+	count = in->count - nread;
+	if(count > 0)
+		memset(ou->data+nread, 0, count);
+	if(p)
+		putbuf(p);
+	if(f)
+		qunlock(f);
+	ou->fid = in->fid;
+	ou->count = nread;
+	if(CHAT(cp))
+		print("\tnread = %d\n", nread);
+}
+
+static void
+f_write(Chan *cp, Fcall *in, Fcall *ou)
+{
+	Iobuf *p, *p1;
+	Dentry *d;
+	File *f;
+	Tlock *t;
+	Off offset, addr, qpath;
+	Timet tim;
+	int count, nwrite, o, n;
+
+	if(CHAT(cp)) {
+		print("c_write %d\n", cp->chan);
+		print("\tfid = %d\n", in->fid);
+		print("\toffset = %lld\n", (Wideoff)in->offset);
+		print("\tcount = %ld\n", in->count);
+	}
+
+	offset = in->offset;
+	count = in->count;
+	nwrite = 0;
+	p = 0;
+	f = filep(cp, in->fid, 0);
+	if(!f) {
+		ou->err = Efid;
+		goto out;
+	}
+	if(!(f->open & FWRITE)) {
+		ou->err = Eopen;
+		goto out;
+	}
+	if(f->fs->dev->type == Devro) {
+		ou->err = Eronly;
+		goto out;
+	}
+	if(count < 0 || count > MAXDAT) {
+		ou->err = Ecount;
+		goto out;
+	}
+	if(offset < 0) {
+		ou->err = Eoffset;
+		goto out;
+	}
+	p = getbuf(f->fs->dev, f->addr, Brd|Bmod);
+	d = getdir(p, f->slot);
+	if(!d || !(d->mode & DALLOC)) {
+		ou->err = Ealloc;
+		goto out;
+	}
+	if(ou->err = mkqidcmp(&f->qid, d))
+		goto out;
+	if(t = f->tlock) {
+		tim = toytime();
+		if(t->time < tim || t->file != f) {
+			ou->err = Ebroken;
+			goto out;
+		}
+		/* renew the lock */
+		t->time = tim + TLOCK;
+	}
+	accessdir(p, d, FWRITE, f->uid);
+	if(d->mode & DAPND)
+		offset = d->size;
+	if(offset+count > d->size)
+		d->size = offset+count;
+	while(count > 0) {
+		if(p == 0) {
+			p = getbuf(f->fs->dev, f->addr, Brd|Bmod);
+			d = getdir(p, f->slot);
+			if(!d || !(d->mode & DALLOC)) {
+				ou->err = Ealloc;
+				goto out;
+			}
+		}
+		addr = offset / BUFSIZE;
+		o = offset % BUFSIZE;
+		n = BUFSIZE - o;
+		if(n > count)
+			n = count;
+		qpath = d->qid.path;
+		p1 = dnodebuf1(p, d, addr, Tfile, f->uid);
+		p = 0;
+		if(p1 == 0) {
+			ou->err = Efull;
+			goto out;
+		}
+		if(checktag(p1, Tfile, qpath)) {
+			putbuf(p1);
+			ou->err = Ephase;
+			goto out;
+		}
+		memmove(p1->iobuf+o, in->data+nwrite, n);
+		p1->flags |= Bmod;
+		putbuf(p1);
+		count -= n;
+		nwrite += n;
+		offset += n;
+	}
+	if(CHAT(cp))
+		print("\tnwrite = %d\n", nwrite);
+
+out:
+	if(p)
+		putbuf(p);
+	if(f)
+		qunlock(f);
+	ou->fid = in->fid;
+	ou->count = nwrite;
+}
+
+int
+doremove(File *f, int wok)
+{
+	Iobuf *p, *p1;
+	Dentry *d, *d1;
+	Off addr;
+	int slot, err;
+
+	p = 0;
+	p1 = 0;
+	if(f->fs->dev->type == Devro) {
+		err = Eronly;
+		goto out;
+	}
+	/*
+	 * check on parent directory of file to be deleted
+	 */
+	if(f->wpath == 0 || f->wpath->addr == f->addr) {
+		err = Ephase;
+		goto out;
+	}
+	p1 = getbuf(f->fs->dev, f->wpath->addr, Brd);
+	d1 = getdir(p1, f->wpath->slot);
+	if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
+		err = Ephase;
+		goto out;
+	}
+	if(iaccess(f, d1, DWRITE) && !wok) {
+		err = Eaccess;
+		goto out;
+	}
+	accessdir(p1, d1, FWRITE, f->uid);
+	putbuf(p1);
+	p1 = 0;
+
+	/*
+	 * check on file to be deleted
+	 */
+	p = getbuf(f->fs->dev, f->addr, Brd);
+	d = getdir(p, f->slot);
+	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
+		err = Ealloc;
+		goto out;
+	}
+	if(err = mkqidcmp(&f->qid, d))
+		goto out;
+
+	/*
+	 * if deleting a directory, make sure it is empty
+	 */
+	if((d->mode & DDIR))
+	for(addr=0;; addr++) {
+		p1 = dnodebuf(p, d, addr, 0, f->uid);
+		if(!p1)
+			break;
+		if(checktag(p1, Tdir, d->qid.path)) {
+			err = Ephase;
+			goto out;
+		}
+		for(slot=0; slot<DIRPERBUF; slot++) {
+			d1 = getdir(p1, slot);
+			if(!(d1->mode & DALLOC))
+				continue;
+			err = Eempty;
+			goto out;
+		}
+		putbuf(p1);
+	}
+
+	/*
+	 * do it
+	 */
+	dtrunc(p, d, f->uid);
+	memset(d, 0, sizeof(Dentry));
+	settag(p, Tdir, QPNONE);
+
+out:
+	if(p1)
+		putbuf(p1);
+	if(p)
+		putbuf(p);
+	return err;
+}
+
+static int
+doclunk(File* f, int remove, int wok)
+{
+	Tlock *t;
+	int err;
+
+	err = 0;
+	if(t = f->tlock) {
+		if(t->file == f)
+			t->time = 0;	/* free the lock */
+		f->tlock = 0;
+	}
+	if(remove)
+		err = doremove(f, wok);
+	f->open = 0;
+	freewp(f->wpath);
+	freefp(f);
+
+	return err;
+}
+
+static void
+f_clunk(Chan *cp, Fcall *in, Fcall *ou)
+{
+	File *f;
+
+	if(CHAT(cp)) {
+		print("c_clunk %d\n", cp->chan);
+		print("\tfid = %d\n", in->fid);
+	}
+
+	f = filep(cp, in->fid, 0);
+	if(!f)
+		ou->err = Efid;
+	else {
+		doclunk(f, f->open & FREMOV, 0);
+		qunlock(f);
+	}
+	ou->fid = in->fid;
+}
+
+static void
+f_remove(Chan *cp, Fcall *in, Fcall *ou)
+{
+	File *f;
+
+	if(CHAT(cp)) {
+		print("c_remove %d\n", cp->chan);
+		print("\tfid = %d\n", in->fid);
+	}
+
+	f = filep(cp, in->fid, 0);
+	if(!f)
+		ou->err = Efid;
+	else {
+		ou->err = doclunk(f, 1, cp==cons.chan);
+		qunlock(f);
+	}
+	ou->fid = in->fid;
+}
+
+static void
+f_stat(Chan *cp, Fcall *in, Fcall *ou)
+{
+	Iobuf *p;
+	Dentry *d;
+	File *f;
+
+	if(CHAT(cp)) {
+		print("c_stat %d\n", cp->chan);
+		print("\tfid = %d\n", in->fid);
+	}
+
+	p = 0;
+	memset(ou->stat, 0, sizeof(ou->stat));
+	f = filep(cp, in->fid, 0);
+	if(!f) {
+		ou->err = Efid;
+		goto out;
+	}
+	p = getbuf(f->fs->dev, f->addr, Brd);
+	d = getdir(p, f->slot);
+	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
+		ou->err = Ealloc;
+		goto out;
+	}
+	if(ou->err = mkqidcmp(&f->qid, d))
+		goto out;
+	if(d->qid.path == QPROOT)	/* stat of root gives time */
+		d->atime = time(nil);
+	if(convD2M9p1(d, ou->stat) != DIRREC)
+		print("9p1: stat convD2M\n");
+
+out:
+	if(p)
+		putbuf(p);
+	if(f)
+		qunlock(f);
+	ou->fid = in->fid;
+}
+
+static void
+f_wstat(Chan *cp, Fcall *in, Fcall *ou)
+{
+	Iobuf *p, *p1;
+	Dentry *d, *d1, xd;
+	File *f;
+	int slot;
+	Off addr;
+
+	if(CHAT(cp)) {
+		print("c_wstat %d\n", cp->chan);
+		print("\tfid = %d\n", in->fid);
+	}
+
+	p = 0;
+	p1 = 0;
+	d1 = 0;
+	f = filep(cp, in->fid, 0);
+	if(!f) {
+		ou->err = Efid;
+		goto out;
+	}
+	if(f->fs->dev->type == Devro) {
+		ou->err = Eronly;
+		goto out;
+	}
+
+	/*
+	 * first get parent
+	 */
+	if(f->wpath) {
+		p1 = getbuf(f->fs->dev, f->wpath->addr, Brd);
+		d1 = getdir(p1, f->wpath->slot);
+		if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
+			ou->err = Ephase;
+			goto out;
+		}
+	}
+
+	p = getbuf(f->fs->dev, f->addr, Brd);
+	d = getdir(p, f->slot);
+	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
+		ou->err = Ealloc;
+		goto out;
+	}
+	if(ou->err = mkqidcmp(&f->qid, d))
+		goto out;
+
+	convM2D9p1(in->stat, &xd);
+	if(CHAT(cp)) {
+		print("\td.name = %s\n", xd.name);
+		print("\td.uid  = %d\n", xd.uid);
+		print("\td.gid  = %d\n", xd.gid);
+		print("\td.mode = %o\n", xd.mode);
+	}
+
+	/*
+	 * if user none,
+	 * cant do anything
+	 */
+	if(f->uid == 0) {
+		ou->err = Eaccess;
+		goto out;
+	}
+
+	/*
+	 * if chown,
+	 * must be god
+	 */
+	if(xd.uid != d->uid && !wstatallow) { /* set to allow chown during boot */
+		ou->err = Ewstatu;
+		goto out;
+	}
+
+	/*
+	 * if chgroup,
+	 * must be either
+	 *	a) owner and in new group
+	 *	b) leader of both groups
+	 */
+	if (xd.gid != d->gid &&
+	    (!wstatallow && !writeallow &&  /* set to allow chgrp during boot */
+	     (d->uid != f->uid || !ingroup(f->uid, xd.gid)) &&
+	     (!leadgroup(f->uid, xd.gid) || !leadgroup(f->uid, d->gid)))) {
+		ou->err = Ewstatg;
+		goto out;
+	}
+
+	/*
+	 * if rename,
+	 * must have write permission in parent
+	 */
+	if (strncmp(d->name, xd.name, sizeof(d->name)) != 0) {
+		if (checkname(xd.name) || !d1 ||
+		    strcmp(xd.name, ".") == 0 || strcmp(xd.name, "..") == 0) {
+			ou->err = Ename;
+			goto out;
+		}
+
+		/*
+		 * drop entry to prevent lock, then
+		 * check that destination name is unique,
+		 */
+		putbuf(p);
+		for(addr=0;; addr++) {
+			p = dnodebuf(p1, d1, addr, 0, f->uid);
+			if(!p)
+				break;
+			if(checktag(p, Tdir, d1->qid.path)) {
+				putbuf(p);
+				continue;
+			}
+			for(slot=0; slot<DIRPERBUF; slot++) {
+				d = getdir(p, slot);
+				if(!(d->mode & DALLOC))
+					continue;
+				if(!strncmp(xd.name, d->name, sizeof(xd.name))) {
+					ou->err = Eexist;
+					goto out;
+				}
+			}
+			putbuf(p);
+		}
+
+		/*
+		 * reacquire entry
+		 */
+		p = getbuf(f->fs->dev, f->addr, Brd);
+		d = getdir(p, f->slot);
+		if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
+			ou->err = Ephase;
+			goto out;
+		}
+
+		if (!wstatallow && !writeallow && /* set to allow rename during boot */
+		    (!d1 || iaccess(f, d1, DWRITE))) {
+			ou->err = Eaccess;
+			goto out;
+		}
+	}
+
+	/*
+	 * if mode/time, either
+	 *	a) owner
+	 *	b) leader of either group
+	 */
+	if (d->mtime != xd.mtime ||
+	    ((d->mode^xd.mode) & (DAPND|DLOCK|0777)))
+		if (!wstatallow &&	/* set to allow chmod during boot */
+		    d->uid != f->uid &&
+		    !leadgroup(f->uid, xd.gid) &&
+		    !leadgroup(f->uid, d->gid)) {
+			ou->err = Ewstatu;
+			goto out;
+		}
+	d->mtime = xd.mtime;
+	d->uid = xd.uid;
+	d->gid = xd.gid;
+	d->mode = (xd.mode & (DAPND|DLOCK|0777)) | (d->mode & (DALLOC|DDIR));
+
+	strncpy(d->name, xd.name, sizeof(d->name));
+	accessdir(p, d, FREAD, f->uid);
+
+out:
+	if(p)
+		putbuf(p);
+	if(p1)
+		putbuf(p1);
+	if(f)
+		qunlock(f);
+	ou->fid = in->fid;
+}
+
+static void
+f_clwalk(Chan *cp, Fcall *in, Fcall *ou)
+{
+	int er, fid;
+
+	if(CHAT(cp))
+		print("c_clwalk macro\n");