Browse Source

Plan 9 from Bell Labs 2003-01-09

David du Colombier 17 years ago
parent
commit
a9fe9057c2
65 changed files with 26159 additions and 6 deletions
  1. 71 3
      dist/replica/plan9.db
  2. 77 0
      dist/replica/plan9.log
  3. 1164 0
      sys/doc/fossil.ms
  4. BIN
      sys/doc/fossil.pdf
  5. 5401 0
      sys/doc/fossil.ps
  6. 34 0
      sys/lib/sysconfig/fl/boot
  7. 7 0
      sys/lib/sysconfig/fl/flproto
  8. 8 0
      sys/lib/sysconfig/fl/venti.conf
  9. 428 0
      sys/man/4/fossil
  10. 806 0
      sys/man/8/fossilcons
  11. 2 1
      sys/src/9/pc/devether.c
  12. 122 0
      sys/src/9/pc/pcfl
  13. 30 0
      sys/src/9/port/dev.c
  14. 2 2
      sys/src/9/port/devfs.c
  15. 209 0
      sys/src/cmd/fossil/9.h
  16. 126 0
      sys/src/cmd/fossil/9auth.c
  17. 121 0
      sys/src/cmd/fossil/9dir.c
  18. 126 0
      sys/src/cmd/fossil/9excl.c
  19. 286 0
      sys/src/cmd/fossil/9fid.c
  20. 1460 0
      sys/src/cmd/fossil/9fsys.c
  21. 177 0
      sys/src/cmd/fossil/9lstn.c
  22. 1118 0
      sys/src/cmd/fossil/9p.c
  23. 109 0
      sys/src/cmd/fossil/9ping.c
  24. 415 0
      sys/src/cmd/fossil/9proc.c
  25. 195 0
      sys/src/cmd/fossil/9srv.c
  26. 960 0
      sys/src/cmd/fossil/9user.c
  27. 112 0
      sys/src/cmd/fossil/Ccli.c
  28. 417 0
      sys/src/cmd/fossil/Ccmd.c
  29. 390 0
      sys/src/cmd/fossil/Ccons.c
  30. 41 0
      sys/src/cmd/fossil/Clog.c
  31. 441 0
      sys/src/cmd/fossil/archive.c
  32. 19 0
      sys/src/cmd/fossil/build
  33. 40 0
      sys/src/cmd/fossil/buildsh
  34. 421 0
      sys/src/cmd/fossil/bwatch.c
  35. 2000 0
      sys/src/cmd/fossil/cache.c
  36. 298 0
      sys/src/cmd/fossil/dat.h
  37. 25 0
      sys/src/cmd/fossil/deadlock
  38. 332 0
      sys/src/cmd/fossil/disk.c
  39. 86 0
      sys/src/cmd/fossil/dump.c
  40. 36 0
      sys/src/cmd/fossil/error.c
  41. 31 0
      sys/src/cmd/fossil/error.h
  42. 1648 0
      sys/src/cmd/fossil/file.c
  43. 657 0
      sys/src/cmd/fossil/flchk.c
  44. 553 0
      sys/src/cmd/fossil/flfmt.c
  45. 13 0
      sys/src/cmd/fossil/flproto
  46. 98 0
      sys/src/cmd/fossil/fns.h
  47. 186 0
      sys/src/cmd/fossil/fossil-acid
  48. 94 0
      sys/src/cmd/fossil/fossil.c
  49. 819 0
      sys/src/cmd/fossil/fs.c
  50. 48 0
      sys/src/cmd/fossil/fs.h
  51. 17 0
      sys/src/cmd/fossil/history
  52. 121 0
      sys/src/cmd/fossil/invariants
  53. 96 0
      sys/src/cmd/fossil/mkfile
  54. 39 0
      sys/src/cmd/fossil/nobwatch.c
  55. 226 0
      sys/src/cmd/fossil/pack.c
  56. 84 0
      sys/src/cmd/fossil/periodic.c
  57. 958 0
      sys/src/cmd/fossil/source.c
  58. 271 0
      sys/src/cmd/fossil/srcload.c
  59. 11 0
      sys/src/cmd/fossil/stdinc.h
  60. 19 0
      sys/src/cmd/fossil/trunc.c
  61. 13 0
      sys/src/cmd/fossil/unpack
  62. 746 0
      sys/src/cmd/fossil/vac.c
  63. 107 0
      sys/src/cmd/fossil/vac.h
  64. 1127 0
      sys/src/cmd/fossil/view.c
  65. 65 0
      sys/src/cmd/fossil/walk.c

+ 71 - 3
dist/replica/plan9.db

@@ -198,6 +198,10 @@
 386/bin/file - 775 sys sys 1039758559 117145
 386/bin/fmt - 775 sys sys 1039758560 63811
 386/bin/fortune - 775 sys sys 1039758560 66329
+386/bin/fossil - 20000000775 sys sys 1042005470 0
+386/bin/fossil/flchk - 775 sys sys 1042005470 226919
+386/bin/fossil/flfmt - 775 sys sys 1042005471 225502
+386/bin/fossil/fossil - 775 sys sys 1042005469 329196
 386/bin/freq - 775 sys sys 1039758560 60443
 386/bin/fs - 20000000775 sys sys 954380769 0
 386/bin/fs/32vfs - 775 sys sys 1039758560 96155
@@ -2798,11 +2802,13 @@ n/c - 20000000555 sys sys 1015089577 0
 n/c: - 20000000555 sys sys 952641484 0
 n/d: - 20000000555 sys sys 958016621 0
 n/dist - 20000000555 sys sys 1020896384 0
+n/fossil - 20000000775 sys sys 1042005455 0
 n/ftp - 20000000555 sys sys 959261485 0
 n/kfs - 20000000555 sys sys 954008414 0
 n/kremvax - 20000000555 sys sys 985197951 0
 n/paq - 20000000555 sys sys 1017722329 0
 n/sid - 20000000555 sys sys 959261486 0
+n/snap - 20000000775 sys sys 1042005458 0
 n/sources - 20000000555 sys sys 1021926252 0
 n/sourcesdump - 20000000775 sys sys 1041013207 0
 n/sourcessnap - 20000000775 sys sys 1041013207 0
@@ -3040,6 +3046,9 @@ sys/doc/contents.ms - 664 sys sys 1019916701 4920
 sys/doc/contents.ps - 664 sys sys 1019916845 232629
 sys/doc/docfonts - 664 sys sys 1038117516 208
 sys/doc/fonts - 664 sys sys 944959649 137
+sys/doc/fossil.ms - 664 sys sys 1042044710 31440
+sys/doc/fossil.pdf - 664 sys sys 1042044711 65284
+sys/doc/fossil.ps - 664 sys sys 1042044711 110396
 sys/doc/fs - 20000000775 sys sys 945616779 0
 sys/doc/fs/fs.html - 664 sys sys 1020013937 21345
 sys/doc/fs/fs.pdf - 664 sys sys 1020384351 47177
@@ -4153,6 +4162,10 @@ sys/lib/sysconfig/auth/files/rewrite - 664 sys sys 1016833537 428
 sys/lib/sysconfig/auth/files/tcp566 - 775 sys sys 1016833537 36
 sys/lib/sysconfig/auth/files/tcp567 - 775 sys sys 1016833537 34
 sys/lib/sysconfig/auth/mkfile - 664 sys sys 1016833657 2937
+sys/lib/sysconfig/fl - 20000000775 sys sys 1042004836 0
+sys/lib/sysconfig/fl/boot - 775 sys sys 1042004836 773
+sys/lib/sysconfig/fl/flproto - 664 sys sys 1042004836 129
+sys/lib/sysconfig/fl/venti.conf - 664 sys sys 1042004837 139
 sys/lib/sysconfig/proto - 20000000775 sys sys 959740591 0
 sys/lib/sysconfig/proto/allproto - 664 sys sys 945018241 2
 sys/lib/sysconfig/proto/armpaqproto - 664 sys sys 1037173885 2270
@@ -4712,6 +4725,7 @@ sys/man/4/dossrv - 664 sys sys 1015024813 4176
 sys/man/4/execnet - 664 sys sys 1019866708 1069
 sys/man/4/exportfs - 664 sys sys 1018386776 3746
 sys/man/4/factotum - 664 sys sys 1021579982 13900
+sys/man/4/fossil - 664 sys sys 1042005418 8705
 sys/man/4/fs - 664 sys sys 1019058716 3387
 sys/man/4/ftpfs - 664 sys sys 1018386777 4113
 sys/man/4/import - 664 sys sys 1034195346 2204
@@ -4809,6 +4823,7 @@ sys/man/8/cpurc - 664 sys sys 971455510 1275
 sys/man/8/cron - 664 sys sys 944959679 1750
 sys/man/8/dhcpd - 664 sys sys 1032654987 5237
 sys/man/8/drawterm - 664 sys sys 958419689 2458
+sys/man/8/fossilcons - 664 sys sys 1042005415 12630
 sys/man/8/fs - 664 sys sys 1037805200 13843
 sys/man/8/fsconfig - 664 sys sys 1037805200 7966
 sys/man/8/httpd - 664 sys sys 1037690024 4516
@@ -5058,7 +5073,7 @@ sys/src/9/pc/cga.c - 664 sys sys 1015014513 1843
 sys/src/9/pc/clock.c - 664 sys sys 1032052912 899
 sys/src/9/pc/dat.h - 664 sys sys 1032052913 6070
 sys/src/9/pc/devarch.c - 664 sys sys 1036812831 16158
-sys/src/9/pc/devether.c - 664 sys sys 1026847635 10042
+sys/src/9/pc/devether.c - 664 sys sys 1042004805 10072
 sys/src/9/pc/devfloppy.c - 664 sys sys 1015014514 19930
 sys/src/9/pc/devi82365.c - 664 sys sys 1020284820 19987
 sys/src/9/pc/devlm78.c - 664 sys sys 1026847635 6038
@@ -5117,6 +5132,7 @@ sys/src/9/pc/pcauth - 664 sys sys 1039753496 600
 sys/src/9/pc/pccd - 664 sys sys 1039753495 1278
 sys/src/9/pc/pccpu - 664 sys sys 1039803186 785
 sys/src/9/pc/pcdisk - 664 sys sys 1039764711 1369
+sys/src/9/pc/pcfl - 664 sys sys 1042004821 1563
 sys/src/9/pc/pcflop - 664 sys sys 1032749195 1353
 sys/src/9/pc/pci.c - 664 sys sys 1032052921 23359
 sys/src/9/pc/pcmciamodem.c - 664 sys sys 1036812832 1499
@@ -5174,7 +5190,7 @@ sys/src/9/port/cache.c - 664 sys sys 1014931171 9242
 sys/src/9/port/chan.c - 664 sys sys 1031706300 28370
 sys/src/9/port/cis.c - 664 sys sys 1014931171 8087
 sys/src/9/port/debugalloc.c - 664 sys sys 1014931171 10402
-sys/src/9/port/dev.c - 664 sys sys 1032990930 6881
+sys/src/9/port/dev.c - 664 sys sys 1042004688 8082
 sys/src/9/port/devaudio.c - 664 sys sys 1026847546 21137
 sys/src/9/port/devbridge.c - 664 sys sys 1026847546 24311
 sys/src/9/port/devcap.c - 664 sys sys 1032052801 4070
@@ -5182,7 +5198,7 @@ sys/src/9/port/devcons.c - 664 sys sys 1036812998 20919
 sys/src/9/port/devdraw.c - 664 sys sys 1039753332 41987
 sys/src/9/port/devdup.c - 664 sys sys 1014931172 2332
 sys/src/9/port/devenv.c - 664 sys sys 1019762849 6562
-sys/src/9/port/devfs.c - 664 sys sys 1041971958 10698
+sys/src/9/port/devfs.c - 664 sys sys 1042044133 10702
 sys/src/9/port/devkprof.c - 664 sys sys 1014931173 3111
 sys/src/9/port/devloopback.c - 664 sys sys 1018721201 14968
 sys/src/9/port/devmnt.c - 664 sys sys 1041443399 21588
@@ -6966,6 +6982,58 @@ sys/src/cmd/fax/subr.c - 664 sys sys 1015090401 1245
 sys/src/cmd/file.c - 664 sys sys 1038186733 20196
 sys/src/cmd/fmt.c - 664 sys sys 1025298248 3897
 sys/src/cmd/fortune.c - 664 sys sys 1035832953 1674
+sys/src/cmd/fossil - 20000000775 sys sys 1042005512 0
+sys/src/cmd/fossil/9.h - 664 sys sys 1042005502 3379
+sys/src/cmd/fossil/9auth.c - 664 sys sys 1042005502 2389
+sys/src/cmd/fossil/9dir.c - 664 sys sys 1042005502 1995
+sys/src/cmd/fossil/9excl.c - 664 sys sys 1042005502 1887
+sys/src/cmd/fossil/9fid.c - 664 sys sys 1042005502 5236
+sys/src/cmd/fossil/9fsys.c - 664 sys sys 1042005503 26731
+sys/src/cmd/fossil/9lstn.c - 664 sys sys 1042005503 2865
+sys/src/cmd/fossil/9p.c - 664 sys sys 1042005503 21328
+sys/src/cmd/fossil/9ping.c - 664 sys sys 1042005503 1563
+sys/src/cmd/fossil/9proc.c - 664 sys sys 1042005503 7358
+sys/src/cmd/fossil/9srv.c - 664 sys sys 1042005504 3215
+sys/src/cmd/fossil/9user.c - 664 sys sys 1042005504 17476
+sys/src/cmd/fossil/Ccli.c - 664 sys sys 1042005504 1624
+sys/src/cmd/fossil/Ccmd.c - 664 sys sys 1042005504 7169
+sys/src/cmd/fossil/Ccons.c - 664 sys sys 1042005504 6524
+sys/src/cmd/fossil/Clog.c - 664 sys sys 1042005505 591
+sys/src/cmd/fossil/archive.c - 664 sys sys 1042005505 9083
+sys/src/cmd/fossil/build - 664 sys sys 1042005505 449
+sys/src/cmd/fossil/buildsh - 775 sys sys 1042005505 561
+sys/src/cmd/fossil/bwatch.c - 664 sys sys 1042005505 6754
+sys/src/cmd/fossil/cache.c - 664 sys sys 1042005506 40534
+sys/src/cmd/fossil/dat.h - 664 sys sys 1042005506 7775
+sys/src/cmd/fossil/deadlock - 775 sys sys 1042005506 413
+sys/src/cmd/fossil/disk.c - 664 sys sys 1042005506 5634
+sys/src/cmd/fossil/dump.c - 664 sys sys 1042005506 1340
+sys/src/cmd/fossil/error.c - 664 sys sys 1042005507 1367
+sys/src/cmd/fossil/error.h - 664 sys sys 1042005507 744
+sys/src/cmd/fossil/file.c - 664 sys sys 1042005507 27500
+sys/src/cmd/fossil/flchk.c - 664 sys sys 1042005507 13670
+sys/src/cmd/fossil/flfmt.c - 664 sys sys 1042005507 10314
+sys/src/cmd/fossil/flproto - 664 sys sys 1042005508 210
+sys/src/cmd/fossil/fns.h - 664 sys sys 1042005508 2950
+sys/src/cmd/fossil/fossil-acid - 664 sys sys 1042005508 3965
+sys/src/cmd/fossil/fossil.c - 664 sys sys 1042005508 1256
+sys/src/cmd/fossil/fs.c - 664 sys sys 1042005508 16962
+sys/src/cmd/fossil/fs.h - 664 sys sys 1042005509 1222
+sys/src/cmd/fossil/history - 664 sys sys 1042005509 482
+sys/src/cmd/fossil/invariants - 664 sys sys 1042005509 4073
+sys/src/cmd/fossil/mkfile - 664 sys sys 1042005509 1589
+sys/src/cmd/fossil/nobwatch.c - 664 sys sys 1042005509 329
+sys/src/cmd/fossil/pack.c - 664 sys sys 1042005510 4683
+sys/src/cmd/fossil/periodic.c - 664 sys sys 1042005510 1091
+sys/src/cmd/fossil/source.c - 664 sys sys 1042005510 18124
+sys/src/cmd/fossil/srcload.c - 664 sys sys 1042005510 4178
+sys/src/cmd/fossil/stdinc.h - 664 sys sys 1042005510 155
+sys/src/cmd/fossil/trunc.c - 664 sys sys 1042005511 280
+sys/src/cmd/fossil/unpack - 775 sys sys 1042005511 286
+sys/src/cmd/fossil/vac.c - 664 sys sys 1042005511 12497
+sys/src/cmd/fossil/vac.h - 664 sys sys 1042005511 2782
+sys/src/cmd/fossil/view.c - 664 sys sys 1042005512 19708
+sys/src/cmd/fossil/walk.c - 664 sys sys 1042005512 963
 sys/src/cmd/freq.c - 664 sys sys 944961364 1682
 sys/src/cmd/getflags - 20000000775 sys sys 954036865 0
 sys/src/cmd/getflags/funcgetflags.c - 664 sys sys 944960998 4621

+ 77 - 0
dist/replica/plan9.log

@@ -16913,3 +16913,80 @@
 1041971572 11 c sys/man/7/INDEX - 664 sys sys 1041971551 89
 1041971572 12 c sys/man/8/INDEX - 664 sys sys 1041971551 2472
 1041973373 0 c sys/src/9/port/devfs.c - 664 sys sys 1041971958 10698
+1042005689 0 a 386/bin/fossil - 20000000775 sys sys 1042005470 0
+1042005689 1 a 386/bin/fossil/flchk - 775 sys sys 1042005470 226919
+1042005689 2 a 386/bin/fossil/flfmt - 775 sys sys 1042005471 225502
+1042005689 3 a 386/bin/fossil/fossil - 775 sys sys 1042005469 329196
+1042005689 4 a n/fossil - 20000000775 sys sys 1042005455 0
+1042005689 5 a n/snap - 20000000775 sys sys 1042005458 0
+1042005689 6 a sys/doc/fossil.ms - 664 sys sys 1042005621 30983
+1042005689 7 a sys/doc/fossil.ps - 664 sys sys 1042005622 105122
+1042005689 8 a sys/lib/sysconfig/fl - 20000000775 sys sys 1042004836 0
+1042005689 9 a sys/lib/sysconfig/fl/boot - 775 sys sys 1042004836 773
+1042005689 10 a sys/lib/sysconfig/fl/flproto - 664 sys sys 1042004836 129
+1042005689 11 a sys/lib/sysconfig/fl/venti.conf - 664 sys sys 1042004837 139
+1042005689 12 a sys/man/4/fossil - 664 sys sys 1042005418 8705
+1042005689 13 a sys/man/8/fossilcons - 664 sys sys 1042005415 12630
+1042005689 14 c sys/src/9/pc/devether.c - 664 sys sys 1042004805 10072
+1042005689 15 a sys/src/9/pc/pcfl - 664 sys sys 1042004821 1563
+1042005689 16 c sys/src/9/port/dev.c - 664 sys sys 1042004688 8082
+1042005689 17 a sys/src/cmd/fossil - 20000000775 sys sys 1042005512 0
+1042005689 18 a sys/src/cmd/fossil/9.h - 664 sys sys 1042005502 3379
+1042005689 19 a sys/src/cmd/fossil/9auth.c - 664 sys sys 1042005502 2389
+1042005689 20 a sys/src/cmd/fossil/9dir.c - 664 sys sys 1042005502 1995
+1042005689 21 a sys/src/cmd/fossil/9excl.c - 664 sys sys 1042005502 1887
+1042005689 22 a sys/src/cmd/fossil/9fid.c - 664 sys sys 1042005502 5236
+1042005689 23 a sys/src/cmd/fossil/9fsys.c - 664 sys sys 1042005503 26731
+1042005689 24 a sys/src/cmd/fossil/9lstn.c - 664 sys sys 1042005503 2865
+1042005689 25 a sys/src/cmd/fossil/9p.c - 664 sys sys 1042005503 21328
+1042005689 26 a sys/src/cmd/fossil/9ping.c - 664 sys sys 1042005503 1563
+1042005689 27 a sys/src/cmd/fossil/9proc.c - 664 sys sys 1042005503 7358
+1042005689 28 a sys/src/cmd/fossil/9srv.c - 664 sys sys 1042005504 3215
+1042005689 29 a sys/src/cmd/fossil/9user.c - 664 sys sys 1042005504 17476
+1042005689 30 a sys/src/cmd/fossil/Ccli.c - 664 sys sys 1042005504 1624
+1042005689 31 a sys/src/cmd/fossil/Ccmd.c - 664 sys sys 1042005504 7169
+1042005689 32 a sys/src/cmd/fossil/Ccons.c - 664 sys sys 1042005504 6524
+1042005689 33 a sys/src/cmd/fossil/Clog.c - 664 sys sys 1042005505 591
+1042005689 34 a sys/src/cmd/fossil/archive.c - 664 sys sys 1042005505 9083
+1042005689 35 a sys/src/cmd/fossil/build - 664 sys sys 1042005505 449
+1042005689 36 a sys/src/cmd/fossil/buildsh - 775 sys sys 1042005505 561
+1042005689 37 a sys/src/cmd/fossil/bwatch.c - 664 sys sys 1042005505 6754
+1042005689 38 a sys/src/cmd/fossil/cache.c - 664 sys sys 1042005506 40534
+1042005689 39 a sys/src/cmd/fossil/dat.h - 664 sys sys 1042005506 7775
+1042005689 40 a sys/src/cmd/fossil/deadlock - 775 sys sys 1042005506 413
+1042005689 41 a sys/src/cmd/fossil/disk.c - 664 sys sys 1042005506 5634
+1042005689 42 a sys/src/cmd/fossil/dump.c - 664 sys sys 1042005506 1340
+1042005689 43 a sys/src/cmd/fossil/error.c - 664 sys sys 1042005507 1367
+1042005689 44 a sys/src/cmd/fossil/error.h - 664 sys sys 1042005507 744
+1042005689 45 a sys/src/cmd/fossil/file.c - 664 sys sys 1042005507 27500
+1042005689 46 a sys/src/cmd/fossil/flchk.c - 664 sys sys 1042005507 13670
+1042005689 47 a sys/src/cmd/fossil/flfmt.c - 664 sys sys 1042005507 10314
+1042005689 48 a sys/src/cmd/fossil/flproto - 664 sys sys 1042005508 210
+1042005689 49 a sys/src/cmd/fossil/fns.h - 664 sys sys 1042005508 2950
+1042005689 50 a sys/src/cmd/fossil/fossil-acid - 664 sys sys 1042005508 3965
+1042005689 51 a sys/src/cmd/fossil/fossil.c - 664 sys sys 1042005508 1256
+1042005689 52 a sys/src/cmd/fossil/fs.c - 664 sys sys 1042005508 16962
+1042005689 53 a sys/src/cmd/fossil/fs.h - 664 sys sys 1042005509 1222
+1042005689 54 a sys/src/cmd/fossil/history - 664 sys sys 1042005509 482
+1042005689 55 a sys/src/cmd/fossil/invariants - 664 sys sys 1042005509 4073
+1042005689 56 a sys/src/cmd/fossil/mkfile - 664 sys sys 1042005509 1589
+1042005689 57 a sys/src/cmd/fossil/nobwatch.c - 664 sys sys 1042005509 329
+1042005689 58 a sys/src/cmd/fossil/pack.c - 664 sys sys 1042005510 4683
+1042005689 59 a sys/src/cmd/fossil/periodic.c - 664 sys sys 1042005510 1091
+1042005689 60 a sys/src/cmd/fossil/source.c - 664 sys sys 1042005510 18124
+1042005689 61 a sys/src/cmd/fossil/srcload.c - 664 sys sys 1042005510 4178
+1042005689 62 a sys/src/cmd/fossil/stdinc.h - 664 sys sys 1042005510 155
+1042005689 63 a sys/src/cmd/fossil/trunc.c - 664 sys sys 1042005511 280
+1042005689 64 a sys/src/cmd/fossil/unpack - 775 sys sys 1042005511 286
+1042005689 65 a sys/src/cmd/fossil/vac.c - 664 sys sys 1042005511 12497
+1042005689 66 a sys/src/cmd/fossil/vac.h - 664 sys sys 1042005511 2782
+1042005689 67 a sys/src/cmd/fossil/view.c - 664 sys sys 1042005512 19708
+1042005689 68 a sys/src/cmd/fossil/walk.c - 664 sys sys 1042005512 963
+1042005689 69 a sys/src/cmd/fossil/words - 664 sys sys 1042005512 1166
+1042006506 0 a sys/doc/fossil.pdf - 664 sys sys 1042006244 65276
+1042006506 1 c sys/doc/fossil.ps - 664 sys sys 1042006244 110324
+1042006877 0 d sys/src/cmd/fossil/words - 664 sys sys 1042005512 0
+1042045363 0 c sys/doc/fossil.ms - 664 sys sys 1042044710 31440
+1042045363 1 c sys/doc/fossil.pdf - 664 sys sys 1042044711 65284
+1042045363 2 c sys/doc/fossil.ps - 664 sys sys 1042044711 110396
+1042045363 3 c sys/src/9/port/devfs.c - 664 sys sys 1042044133 10702

File diff suppressed because it is too large
+ 1164 - 0
sys/doc/fossil.ms


BIN
sys/doc/fossil.pdf


File diff suppressed because it is too large
+ 5401 - 0
sys/doc/fossil.ps


+ 34 - 0
sys/lib/sysconfig/fl/boot

@@ -0,0 +1,34 @@
+#!/boot/rc -m /boot/rcmain
+
+cpuserver=no
+cd /boot
+cp '#r/rtc' '#c/time'
+bind -a '#I' /net
+bind -a '#l0' /net
+bind -a '#S' /dev
+bind '#p' /proc
+bind '#d' /fd
+bind -a /boot /
+ipconfig loopback /dev/null 127.1
+if(~ $cpuserver yes){
+	factotum -sfactotum -S
+}
+if not{
+	factotum -sfactotum -u
+	# add a key so mount and fossil can authenticate each other
+	# remove this key once factotum is initialized with other keys
+	factotum -g 'proto=p9sk1 user=rsc dom=localhost !password=localhost'
+}
+venti -c venti.conf -B 8m -C 8m -h tcp!127.1!8000 -I 8m -w -a tcp!127.1!17034 &
+sleep 10
+venti=tcp!127.0.0.1!17034
+fossil -c '. flproto'
+mount -c /srv/boot /root
+bind -ac /root /
+rootdir=/root
+rootspec=''
+if(~ $cpuserver yes)
+	/386/init -c
+if not
+	/386/init -t
+exec ./rc -m/boot/rcmain -i

+ 7 - 0
sys/lib/sysconfig/fl/flproto

@@ -0,0 +1,7 @@
+srv -p fscons
+srv boot
+fsys main config /dev/sdC0/fossil
+fsys main open
+fsys main
+users /active/adm/users
+snaptime -s 60 -a 0500

+ 8 - 0
sys/lib/sysconfig/fl/venti.conf

@@ -0,0 +1,8 @@
+index main
+isect /dev/sdC0/v.index0
+isect /dev/sdC0/v.index1
+isect /dev/sdC0/v.index2
+isect /dev/sdC0/v.index3
+
+arenas /dev/sdC0/v.arenas
+

+ 428 - 0
sys/man/4/fossil

@@ -0,0 +1,428 @@
+.TH FOSSIL 4
+.SH NAME
+fossil \- archival file server
+.SH SYNOPSIS
+.B fossil/fossil
+[
+.B -Dt
+]
+[
+.B -c
+.I cmd
+]...
+.PP
+.B fossil/flchk
+[
+.B -f
+]
+[
+.B -c
+.I ncache
+]
+[
+.B -h
+.I host
+]
+.I file
+.PP
+.B fossil/flfmt
+[
+.B -y
+]
+[
+.B -b
+.I blocksize
+]
+[
+.B -h
+.I host
+]
+[
+.B -l
+.I label
+]
+[
+.B -v
+.BI vac: score
+]
+.I file
+.SH DESCRIPTION
+Fossil
+will become the main file system for Plan 9.
+Unlike the Plan 9 file servers of old,
+fossil
+is a collection of user-space programs that run on a standard Plan 9 kernel.
+The name of the main fossil file server at Murray Hill is
+.BR ehime .
+The Plan 9 distribution file server,
+.BR sources ,
+is also a fossil server.
+.PP
+Fossil
+is structured as a magnetic disk write buffer
+backed by a Venti server for archival storage.
+It serves the Plan 9 protocol via TCP.
+A fossil file server conventionally presents
+three trees in the root directory of each file system:
+.BR active ,
+.BR archive ,
+and
+.BR snapshot .
+.B /active
+is the root of a conventional file system
+whose blocks are stored in a disk file.
+In a typical configuration, the file server periodically
+marks the entire file system copy-on-write, effectively
+taking a snapshot of the file system at that moment.
+This snapshot is made available in a name
+created from the date and time of the snapshot:
+.BI /snapshot/ yyyy / mmdd / hhmm \fR,
+where
+.I yyyy
+is the full year,
+.I mm
+is the month number,
+.I dd
+is the day number,
+.I hh
+is the hour,
+and
+.I mm
+is the minute.
+The snapshots in
+.B /snapshot
+are ephemeral: eventually they are deleted
+to reclaim the disk space they occupy.
+Long-lasting snapshots stored on a Venti server
+are kept in 
+.B /archive
+and also named from the date (though not the time) of the snapshot:
+.BI /archive/ yyyy / mmdds \fR,
+where
+.IR yyyy ,
+.IR mm ,
+and
+.I dd
+are year, month, and day as before,
+and
+.I s
+is a sequence number if more than one
+archival snapshot is done in a day.
+For the first snapshot,
+.I s
+is null.
+For the subsequent snapshots,
+.I s
+is
+.BR .1 ,
+.BR .2 ,
+.BR .3 ,
+etc.
+The root of the main file system that is frozen
+for the first archival snapshot of December 15, 2002
+will be named
+.BR /archive/2002/1215/ .
+.PP
+The attach name used in
+.IR mount (1)
+(see also
+.IR mount (2)
+and
+.IR attach (5))
+selects a file system to be served
+and optionally a subtree,
+in the format
+.IB fs \fR[\fB/ dir \fR].
+An empty attach name selects
+.BR main/active .
+.PP
+Fossil normally requires all users except
+.L none
+to provide authentication tickets on each
+.IR attach (5).
+To keep just anyone from connecting,
+.L none
+is only allowed to attach after another user
+has successfully attached on the same
+connection.
+The other user effectively acts as a chaperone
+for
+.LR none .
+Authentication can be disabled using the
+.B -A
+flag to
+.B open
+(see
+.IR fossilcons (8)).
+.PP
+The groups called
+.B noworld
+and
+.B write
+are special on the file server.
+Any user belonging to
+.B noworld
+has attenuated access privileges.
+Specifically, when checking such a user's access to files,
+the file's permission buts are first ANDed
+with 0770 for normal files and 0771 for directories.
+The effect is to deny world access permissions to
+.B noworld
+users, except when walking into directories.
+If the
+.B write
+group exists, then the file system appears read-only
+to users not in the group.
+This is used to make the Plan 9 distribution file server
+.RI ( sources.cs.bell-labs.com )
+readable by the world but writable only to the developers.
+.PP
+.I Fossil
+starts a new instance of the fossil file server.
+It is configured mainly through console commands,
+documented in
+.IR fossilcons (8).
+.PP
+The options are:
+.TP
+.B -D
+Toggle the debugging flag, which is initially off.
+When the flag is set, information about authentication
+and all protocol messages are written to standard error.
+.TP
+.B -t
+Start a file server console on
+.BR /dev/cons .
+If this option is given,
+.I fossil
+does not fork itself into the background.
+.TP
+.BI -c " cmd
+Execute the console command
+.IR cmd .
+This option may be repeated to give multiple
+commands.
+Typically the only commands given on the
+command line are
+.RB `` . \fIfile \fR,''
+which executes a file containing commands,
+and
+.RB `` "srv -p" \fIcons \fR,''
+which starts a file server console on
+.BI /srv/ cons \fR.
+See
+.IR fossilcons (8)
+for more information.
+.PD
+.PP
+.I Flchk
+checks the fossil file system stored in
+.I file
+for inconsistencies.
+.I Flchk
+prints fossil console commands that may be
+executed to take care of
+bad pointers
+.RB ( clrp ),
+bad entries
+.RB ( clre ),
+bad directory entries
+.RB ( clri ),
+unreachable blocks
+.RB ( bfree ).
+Console commands are interspersed with
+more detailed commentary on the file system.
+The commands are distinguished by being prefixed with
+sharp signs.
+Note that all proposed fixes are rather drastic: offending
+pieces of file system are simply chopped off.
+.PP
+.I Flchk
+does
+.I not
+modify the file system, so it is safe to
+run concurrently with
+.IR fossil ,
+though in this case
+the list of unreachable
+blocks and any inconsistencies involving the active file system
+should be taken with a grain of salt.
+.PP
+The options are:
+.TP
+.B -f
+Fast mode.
+By default,
+.I flchk
+checks the entire file system image for consistency,
+which includes all the archives to Venti
+and can take a very long time.
+In fast mode,
+.I flchk
+avoids walking in Venti blocks
+whenever possible.
+.TP
+.BI -c " ncache
+Keep a cache of
+.I ncache
+(by default, 1000)
+file system blocks in memory during the check.
+.TP
+.BI -h " host
+Use
+.I host
+as the Venti server.
+.PD
+.PP
+.I Flfmt
+prepares
+.I file
+as a new fossil file system.
+The file system is initialized with three empty directories
+.BR active ,
+.BR archive ,
+and
+.BR snapshot ,
+as described above.
+The options are:
+.TP
+.B -y
+Yes mode.
+By default,
+.I flfmt
+will prompt for confirmation before formatting
+a file that already contains a fossil file system,
+and before formatting a file that is not served
+directly by a kernel device.
+If the
+.B -y
+flag is given, no such checks are made.
+.TP
+.BI -b " blocksize
+Set the file system block size (by default, 8192).
+.TP
+.BI -h " host
+Use
+.I host
+as the Venti server.
+.TP
+.BI -l " label
+Set the textual label on the file system to
+.IR label .
+The label is only a comment.
+.TP
+.BI "-v vac:" score
+Initialize the file system using the vac file
+system stored on Venti at
+.IR score .
+The score should have been generated by
+.I fossil
+rather than by
+.IR vac (1),
+so that the appropriate snapshot metadata is present.
+.PD
+.SH EXAMPLES
+.PP
+Place the root of the archive file system on
+.B /n/dump
+and show the modified times of the MIPS C compiler
+over all dumps in December 2002:
+.IP
+.EX
+9fs dump
+ls -l /n/dump/2002/12*/mips/bin/vc
+.EE
+.PP
+To get only one line of output for each version of the compiler:
+.IP
+.EX
+ls -lp /n/dump/2002/12*/mips/bin/vc | uniq
+.EE
+.ne 14
+.PP
+Initialize a new file system, start the server with permission
+checking turned off, create a users file, and mount the server:
+.IP
+.EX
+fossil/flfmt /dev/sdC0/fossil
+cat >flproto <<EOF
+fsys main config /dev/sdC0/fossil
+fsys main open -AWP
+fsys main
+create /active/adm adm sys d775
+create /active/adm/users adm sys 664
+users -w /active/adm/users
+srv -p fscons
+srv fossil
+EOF
+fossil/fossil -c '. flproto'
+mount /srv/fossil /n/fossil
+.EE
+.LP
+See the discussion of the
+.B users
+and
+.B uname
+commands in
+.IR fossilcons (8)
+for more about the user table.
+.ne 3
+.PP
+Perhaps because the disk has been corrupted or replaced,
+format a new file system using the last archive score printed
+on the console:
+.IP
+.EX
+fossil/flfmt -v vac:b9b3...5559 /dev/sdC0/fossil
+.EE
+.LP
+Note that while
+.B /snapshot
+will be lost,
+.B /active
+and
+.B /archive
+will be restored to their contents at the time of the
+last archival snapshot.
+.ne 3
+.PP
+Blindly accept the changes prescribed by
+.I flchk
+(not recommended):
+.IP
+.EX
+fossil/flchk /dev/sdC0/fossil | sed -n 's/^# //p' >>/srv/fscons
+.EE
+.LP
+A better strategy is to vet the output,
+filter out any suggestions you're not comfortable with,
+and then use the
+.I sed
+command to prepare the script.
+.SH SOURCE
+.B /sys/src/cmd/fossil
+.SH SEE ALSO
+.IR yesterday (1),
+.IR fs (4),
+.IR srv (4),
+.IR fossilcons (8),
+.IR venti (8)
+.SH BUGS
+It is likely that the disk format (but not the Venti format)
+will change in the future, to make the disk a full cache
+rather than just a write buffer.
+Changing to the new format will require reformatting
+the disk as in the example above,
+but note that this will preserve most of the file system
+(all but
+.B /snapshot
+) with little effort.
+.LP
+The implementation of
+.IR flush (5)
+has a race that will be fixed shortly.
+It is possible (though, in practice, it happens
+very rarely) that 
+.I fossil
+will respond to a message after responding
+to a flush of that message.

+ 806 - 0
sys/man/8/fossilcons

@@ -0,0 +1,806 @@
+.TH FOSSILCONS 8
+.SH NAME
+fossilcons \- fossil console commands
+.SH SYNOPSIS
+.B
+con /srv/fscons
+.PP
+.PD 0.1
+.B .
+.I file
+.PP
+.B 9p
+.I T-message
+...
+.PP
+.B dflag
+.PP
+.B echo
+[
+.B -n
+]
+[
+.I arg
+...
+]
+.PP
+.B listen
+[
+.B -d
+]
+[
+.I address
+]
+.PP
+.B msg
+[
+.B -m
+.I nmsg
+]
+[
+.B -p
+.I nproc
+]
+.PP
+.B uname
+.I uname
+[
+.I uid
+|
+.BI : uid
+|
+.BI % newname
+|
+.BI = leader
+|
+.BI + member
+|
+.BI - member
+]
+.PP
+.B users
+[
+.B -dw
+|
+.I file
+]
+.PP
+.B srv
+[
+.B -dp
+]
+.I name
+.sp
+.PP
+.B fsys
+.I name
+.PP
+.B fsys
+.I name
+.B config
+.I device
+.PP
+.B fsys
+.I name
+.B venti
+.B -d
+|
+[
+.B -r
+]
+[
+.I host
+]
+.PP
+.B fsys
+.I name
+.B open
+[
+.B -APWr
+]
+[
+.B -c
+.I ncache
+]
+.PP
+[
+.B fsys
+.I name
+]
+.B close
+.PP
+.B fsys
+.I name
+.B unconfig
+.sp
+.PP
+[
+.B fsys
+.I name
+]
+.B bfree
+.I addr
+.PP
+[
+.B fsys
+.I name
+]
+.B block
+.I addr
+.I offset
+[
+.I count
+[
+.I data
+]]
+.PP
+[
+.B fsys
+.I name
+]
+.B clre
+.I addr
+.I offsets
+\&...
+.PP
+[
+.B fsys
+.I name
+]
+.B clri
+.I files
+\&...
+.PP
+[
+.B fsys
+.I name
+]
+.B clrp
+.I addr
+.I offset
+\&...
+.PP
+[
+.B fsys
+.I name
+]
+.B create
+.I path
+.I uid
+.I gid
+.I perm
+.PP
+[
+.B fsys
+.I name
+]
+.B epoch
+[
+.B -y
+]
+.I n
+.PP
+[
+.B fsys
+.I name
+]
+.B label
+.I addr
+[
+.I type
+.I state
+.I epoch
+.I epochclose
+.I tag
+]
+.PP
+[
+.B fsys
+.I name
+]
+.B remove
+.I files
+\&...
+.PP
+[
+.B fsys
+.I name
+]
+.B snap
+[
+.B -a
+]
+.PP
+[
+.B fsys
+.I name
+]
+.B snaptime
+[
+.B -a
+.I hhmm
+]
+[
+.B -s
+.I interval
+]
+.PP
+[
+.B fsys
+.I name
+]
+.B stat
+.IR files ...
+.PP
+[
+.B fsys
+.I name
+]
+.B sync
+.PP
+[
+.B fsys
+.I name
+]
+.B vac
+.I dir
+.PP
+[
+.B fsys
+.I name
+]
+.B wstat
+.I file
+.I elem
+.I uid
+.I gid
+.I perm
+.I length
+.SH DESCRIPTION
+These are configuration and maintenance commands
+executed at the console of a 
+.IR fossil (4)
+file server.
+The commands are split into three groups above:
+file server configuration,
+file system configuration,
+and file system maintenance.
+This manual page is split in the same way.
+.SS File server configuration
+.PP
+The
+dot
+.RI ( . )
+command
+reads
+.IR file ,
+treating each line as a command to be executed.
+Blank lines and lines beginning with a 
+.L #
+character are ignored.
+Note that
+.I file
+is a file in the name space in which
+.I fossil
+was started,
+.I not
+a file in any file system served by
+.IR fossil .
+.PP
+.I 9p
+executes a 9P transaction; the arguments
+are in the same format used by
+.IR 9pcon (8).
+.PP
+.I Dflag
+toggles the debug flag and prints the new setting.
+When the debug flag is set, all protocol messages
+and information about authentication is printed to
+standard error.
+.PP
+.I Echo
+behaves identically to
+.IR echo (1),
+writing to the console.
+.PP
+.I Listen
+manages the network addresses at which
+fossil is listening.
+With no arguments,
+.I listen
+prints the current list of addresses and their network directories.
+With one argument, listen
+.I address
+starts a new listener at
+.IR address ;
+the
+.B -d
+flag causes 
+.I listen
+to remove the listener
+at the given address.
+.PP
+.I Msg
+prints the maximum internal 9P message queue size
+and the maximum number of 9P processes to
+allocate for serving the queue.
+The
+.B -m
+and
+.B -p
+options set the two variables.
+.PP
+.I Uname
+displays or edits one entry the in-memory user table.
+If the in-memory table was read from a file
+(see the
+.I users
+command below),
+the new table is written to
+.IR /active/adm/users .
+There is no distinction between users and groups:
+a user is a group with one member.
+The user table records a mapping between
+uids and unames, as well as recording the
+leader and members of each group.
+A
+.I uid
+is a string naming a user or group
+and stored in the on-disk data structures.
+A
+.I uname
+is the string naming a user or group and
+used in 9P protocol messages.
+There is a distinction so that unames can be
+safely reused, even though uids cannot.
+The first argument to
+.I uname
+is (confusingly) a
+uname
+.RI ` uname .'
+The second argument is an optional verb, one of:
+.TP
+.I uid
+add the user with uname
+.RI ` uname '
+and uid
+.RI ` uid ,'
+creating a home directory
+.BI /active/usr/ uname \fR.
+.TP
+.BI : uid
+add the user but do not create the home directory
+.TP
+.BI % newname
+rename
+.RI ` uname '
+to
+.RI ` newname ,'
+throughout the user table
+.TP
+.BI = leader
+set the group leader to the uname
+.IR leader .
+.TP
+.BI + member
+add the uname
+.RI ` member '
+to the group
+.TP
+.BI - member
+remove the uname
+.RI ` member '
+from the group
+.LP
+If the verb is omitted, the entire entry for
+.I uname
+is printed, in the form:
+.IP
+.IB uid : uname : leader :\fImembers
+.LP
+where
+.I members
+is a comma-separated list of unames.
+.PP
+.I Users
+reads
+.IR file
+from the file system named
+.B main
+and uses it to initialize the user table.
+With no arguments,
+.I users
+prints the file name of the current user table.
+.PP
+The user table is a list of lines in the form printed
+by the
+.I uname
+command.
+The
+.B -d
+flag resets the user table to the default:
+.IP
+.EX
+adm:adm:adm:sys
+none:none::
+noworld:noworld::
+sys:sys::
+.EE
+.PP
+These users are mandatory and must appear in all user files read.
+It is not possible to rename these unames.
+.PP
+The
+.B -w
+flag causes the file
+.I /active/adm/users
+to be written with the current in-memory table.
+The path
+.I /active/adm
+must exist.
+.PP
+.I Srv
+behaves like listen but uses
+.BI /srv/ name
+rather than a network address.
+With the
+.B -p
+flag, 
+.I srv 
+edits a list of console services rather than 9P services.
+.SS File system configuration
+.I Fsys
+sets the current file system to
+.IR name ,
+which must be configured and open (q.v.).
+The current file system name is
+displayed as the file server prompt.
+.PP
+.I Fsys
+takes as an optional argument
+(after
+.BR name )
+a command to execute on the named file system.
+Most commands require that the named file system
+be configured and open; these commands can be invoked
+without the
+.BI fsys " name
+prefix, in which case the current file system is used.
+A few commands
+.RB ( config ,
+.BR open ,
+and
+.BR unconfig )
+operate on unopened file systems; they require the prefix.
+.PP
+.I Config
+creates a new file system named
+.I name
+using disk file
+.I device .
+This just adds an entry to fossil's internal table.
+.PP
+.I Venti
+establishes a connection to the Venti server
+.I host
+(by default, the environment variable
+.B $venti
+or the network variable
+.BR $venti )
+for use by the named file system.
+If no
+.I venti
+command is issued before
+.IR open ,
+the default Venti server will be used.
+The
+.B -d
+flag closes the connection to the Venti server
+and can only be used when the file system is closed.
+The
+.B -r
+flag redials the Venti server and can only
+be used when the file system is open;
+.I host
+must be given again.
+.PP
+.I Open
+opens the file system, reading the
+root and super blocks and allocating an in-memory
+cache for disk and Venti blocks.
+The options are:
+.TP
+.B -A
+run with no authentication
+.TP
+.B -P
+run with no permission checking
+.TP
+.B -W
+allow wstat to make arbitrary changes to the user and group fields
+.TP
+.B -r
+open the file system read-only
+.TP
+.BI -c " ncache
+allocate an in-memory cache of 
+.I ncache
+(by default, 1000)
+blocks
+.PP
+.I Close
+flushes all dirty file system blocks to disk
+and then closes the device file.
+.PP
+.I Unconfig
+removes the named file system (which must be closed)
+from fossil's internal table.
+.SS File system maintenance
+.I Bfree
+marks the block at disk address
+.I addr
+as available for allocation.
+Before doing so, it prints a
+.I label
+command (q.v.)
+that can be used to restore the block to its previous state.
+.PP
+.I Block
+displays (in hexadecimal)
+the contents of the block at disk address
+.IR addr ,
+starting at
+.I offset
+and continuing for
+.I count
+bytes or until the end of the block.
+If 
+.I data
+(also hexadecimal)
+is given, the contents in that range are
+replaced with data.
+When writing to a block,
+.I block
+prints the old and new contents,
+so that the change is easily undone.
+Editing blocks is discouraged.
+.PP
+.I Clre
+zeros an entry from a disk block.
+Before doing so, it prints a
+.I block
+command that can be used 
+to restore the entry.
+.PP
+.I Clri
+removes the internal directory entry
+and abandons storage associated with
+.IR files .
+It ignores the usual rules for sanity, such as checking against
+removing a non-empty directory.
+A subsequent
+.I flchk
+(see
+.IR fossil (4))
+will identify the abandoned storage so it can be reclaimed with
+.I bfree
+commands.
+The
+.I perm
+is formatted as described in the
+.I stat
+command ;
+creating files or directories with the
+snapshot
+.RB ( s )
+bit set is not allowed.
+.PP
+.I Clrp
+zeros a pointer in a disk block.
+Before doing so, it prints a 
+.I block
+command that can be used to restore the entry.
+.PP
+.I Create
+creates a file on the current file system.
+.I Uid
+and
+.I gid
+are uids
+.RI ( not
+unames;
+see the discussion above, in the description
+of the 
+.I uname
+command).
+.I Perm
+is the low 9 bits of the permission mode of the file,
+in octal.
+The 
+.BR -a ,
+.BR -d ,
+and
+.B -l
+flags set the append-only, directory, and lock bits.
+.PP
+.I Epoch
+sets the low file system epoch.
+Snapshots in the file system are given increasing epoch numbers.
+The file system maintains a low and a high epoch number,
+and only allows access to snapshots in that range.
+The low epoch number can be moved forward to discard old snapshots
+and reclaim the disk space they occupy.
+(The high epoch number is always the epoch of the currently
+active file system.)
+.PP
+The command
+``\fLepoch\fI n''\fR
+is used to propose changing the low epoch to
+.IR n .
+In response, 
+.I fossil
+scans
+.B /archive
+and
+.B /snapshot
+for snapshots that would be discarded, printing their
+epoch numbers and the
+.I clri
+commands necessary to remove them.
+The epoch is changed only if no such paths are found.
+The usual sequence of commands is (1) run epoch to
+print the snapshots and their epochs, (2) clri some snapshots,
+(3) run epoch again.
+If the file system is completely full (there are no free blocks),
+.I clri
+may fail because it needs to allocate blocks.
+For this situation,
+the
+.B -y
+flag to epoch forces the epoch change even when
+it means discarding currently accessible snapshots.
+Note that when there are still snapshots in
+.BR /archive ,
+the archiver should take care
+of those snapshots (moving the blocks from disk to Venti)
+if you give it more time.
+.PP
+.I Label
+displays and edits the label associated with a block.
+When editing, a parameter of
+.B -
+means leave that field unchanged.
+Editing labels is discouraged.
+.PP
+.I Remove
+removes
+.IR files .
+.PP
+.I Snap
+takes a temporary snapshot of the current file system,
+recording it in 
+.BI /snapshot/ yyyy / mmdd / hhmm \fR,
+as described in 
+.IR fossil (4).
+The
+.B -a
+flag causes 
+.I snap
+to take an archival snapshot, recording it in
+.BI /archive/ yyyy / mmdd \fR,
+also described in
+.IR fossil (4).
+.PP
+.I Snaptime
+displays and edits the times at which snapshots are automatically
+taken.
+An archival snapshot is taken once a day, at
+.IR hhmm ,
+while temporary snapshots are taken at multiples of
+.I interval
+minutes.
+With no arguments,
+.I snaptime
+prints the current snapshot times.
+The
+.B -a
+and
+.B -s
+options set the archive and snapshot times.
+An
+.I hhmm
+or
+.I interval
+of
+.L none
+can be used to disable that kind of automatic snapshot.
+By default, both are disabled.
+.PP
+.I Stat
+displays metadata for each of the named
+.IR files ,
+in the form:
+.IP
+.EX
+stat \fIfile elem uid gid perm length
+.EE
+.LP
+(Replacing
+.B stat
+with
+.B wstat
+yields a valid command.)
+The
+.I perm
+is an octal number less than or equal to 777,
+prefixed with any of the following letters
+to indicate additional bits.
+.IP
+.EX
+.ta +4n
+a	\fRappend only
+d	\fRdirectory
+l	\fRexclusive use
+s	\fRis the root of a snapshot
+A	\fRMS-DOS archive bit
+G	\fRsetgid
+H	\fRMS-DOS hidden bit
+L	\fRsymbolic link
+S	\fRMS-DOS system bit
+T	\fRMS-DOS temporary bit
+U	\fRsetuid
+Y	\fRsticky
+.EE
+The bits denoted by capital letters are included
+to support non-Plan 9 systems.
+They are not made visible by the 9P protocol.
+.PP
+.I Sync
+writes dirty blocks in memory to the disk.
+.PP
+.I Vac
+prints the Venti score for a
+.IR vac (1)
+archive containing the tree rooted
+at
+.IR dir ,
+which must already be archived to Venti
+(typically
+.IR dir
+is a directory in the
+.B /archive
+tree).
+.PP
+.I Wstat
+changes the metadata of the named
+.IR file .
+Specifying
+.B -
+for any of the fields means ``don't change.''
+Attempts to change the
+.B d
+or
+.B s
+bits in the
+.I perm
+are silently ignored.
+.SH EXAMPLE
+.IR Sources ,
+the Plan 9 distribution file server,
+uses the following configuration file:
+.IP
+.EX
+srv -p fscons.sources
+srv -p fscons.sources.adduserd
+srv sources
+fsys main config /dev/sdC0/fossil.outside
+fsys main open -c 25600
+fsys main
+users /active/adm/users
+listen tcp!*!564
+msg -m 40 -p 10
+snaptime -a 0000 -s 15
+.EE
+.LP
+The second console is used by the daemon
+that creates new accounts.

+ 2 - 1
sys/src/9/pc/devether.c

@@ -228,7 +228,8 @@ etheroq(Ether* ether, Block* bp)
 
 	if(!loopback){
 		qbwrite(ether->oq, bp);
-		ether->transmit(ether);
+		if(ether->transmit != nil)
+			ether->transmit(ether);
 	} else
 		freeb(bp);
 

+ 122 - 0
sys/src/9/pc/pcfl

@@ -0,0 +1,122 @@
+dev
+	root
+	cons
+	arch
+	pnp		pci
+	env
+	pipe
+	proc
+	mnt
+	srv
+	dup
+	rtc
+	ssl
+	tls
+	cap
+	kprof
+
+	ether		netif
+	ip		arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum386 inferno
+
+	draw		screen vga vgax
+	mouse		mouse
+	vga
+
+	sd
+	floppy		dma
+	lpt
+
+	audio		dma
+	pccard
+	i82365		cis
+	uart
+	usb
+
+link
+	devpccard
+	devi82365
+	apm		apmjump
+	ether2000	ether8390
+	ether2114x	pci
+	ether589	etherelnk3
+	ether79c970	pci
+	ether8003	ether8390
+	ether8139
+	ether82557	pci
+	ether82543gc	pci
+	ether83815	pci
+	etherec2t	ether8390
+	etherga620	pci
+	etherelnk3	pci
+	ethersink
+	ethersmc	devi82365 cis
+	etherwavelan	wavelan devi82365 cis pci
+	ethermedium
+	pcmciamodem
+	netdevmedium
+	loopbackmedium
+	usbuhci
+
+misc
+	archmp		mp apic
+
+	sdata		pci sdscsi
+	sd53c8xx		pci sdscsi
+	sdmylex		pci sdscsi
+
+	uarti8250
+
+	vga3dfx		+cur
+	vgaark2000pv	+cur
+	vgabt485	=cur
+	vgaclgd542x	+cur
+	vgaclgd546x	+cur
+	vgact65545	+cur
+	vgacyber938x	+cur
+	vgaet4000	+cur
+	vgahiqvideo	+cur
+	vgai81x	+cur
+	vgamach64xx	+cur
+	vgamga2164w	+cur
+	vgamga4xx	+cur
+	vganeomagic	+cur
+	vganvidia	+cur
+	vgargb524	=cur
+	vgas3		+cur vgasavage
+	vgat2r4		+cur
+	vgatvp3020	=cur
+	vgatvp3026	=cur
+	vgavmware	+cur
+
+ip
+	il
+	tcp
+	udp
+	ipifc
+	icmp
+	icmp6
+
+port
+	int cpuserver = 0;
+
+boot boot #S/sdC0/
+	il
+	local
+
+bootdir
+	/386/bin/rc
+	/rc/lib/rcmain
+	/386/bin/bind
+	/386/bin/cat
+	/386/bin/cp
+	/386/bin/echo
+	/386/bin/mount
+	/386/bin/sleep
+	/386/bin/auth/factotum
+	/386/bin/fossil/fossil
+	/386/bin/ip/ipconfig
+	/386/bin/venti/venti
+	/sys/lib/sysconfig/fl/boot
+	/sys/lib/sysconfig/fl/flproto
+	/sys/lib/sysconfig/fl/venti.conf
+

+ 30 - 0
sys/src/9/port/dev.c

@@ -49,6 +49,36 @@ devdir(Chan *c, Qid qid, char *n, vlong length, char *user, long perm, Dir *db)
 	db->muid = user;
 }
 
+/*
+ * (here, Devgen is the prototype; devgen is the function in dev.c.)
+ * 
+ * a Devgen is expected to return the directory entry for ".."
+ * if you pass it s==DEVDOTDOT (-1).  otherwise...
+ * 
+ * there are two contradictory rules.
+ * 
+ * (i) if c is a directory, a Devgen is expected to list its children
+ * as you iterate s.
+ * 
+ * (ii) whether or not c is a directory, a Devgen is expected to list
+ * its siblings as you iterate s.
+ * 
+ * devgen always returns the list of children in the root
+ * directory.  thus it follows (i) when c is the root and (ii) otherwise.
+ * many other Devgens follow (i) when c is a directory and (ii) otherwise.
+ * 
+ * devwalk assumes (i).  it knows that devgen breaks (i)
+ * for children that are themselves directories, and explicitly catches them.
+ * 
+ * devstat assumes (ii).  if the Devgen in question follows (i)
+ * for this particular c, devstat will not find the necessary info.
+ * with our particular Devgen functions, this happens only for
+ * directories, so devstat makes something up, assuming
+ * c->name, c->qid, eve, DMDIR|0555.
+ * 
+ * devdirread assumes (i).  the callers have to make sure
+ * that the Devgen satisfies (i) for the chan being read.
+ */
 /*
  * the zeroth element of the table MUST be the directory itself for ..
 */

+ 2 - 2
sys/src/9/port/devfs.c

@@ -173,6 +173,8 @@ mconfig(char* a, long n)	// "name idev0 idev1"
 	char	*c;
 	vlong	size, start;
 
+	size = 0;
+	start = 0;
 	if (confstr[0] == 0)
 		seprint(confstr, confstr+sizeof(confstr), Cfgstr);
 	mp = nil;
@@ -395,7 +397,6 @@ catio(Fsdev *mp, int isread, void *a, long n, vlong off)
 	int	i;
 	Chan*	mc;
 	long	l, wl, res;
-	char*	s;
 	//print("catio %d %p %ld %lld\n", isread, a, n, off);
 	res = n;
 	for (i = 0; n >= 0 && i < mp->ndevs ; i++){
@@ -409,7 +410,6 @@ catio(Fsdev *mp, int isread, void *a, long n, vlong off)
 		else
 			l = n;
 		//print("\tdev %d %p %ld %lld\n", i, a, l, off);
-		s = a;
 
 		if (isread)
 			wl = devtab[mc->type]->read(mc, a, l, off);

+ 209 - 0
sys/src/cmd/fossil/9.h

@@ -0,0 +1,209 @@
+#include <auth.h>
+#include <fcall.h>
+
+enum {
+	NFidHash	= 503,
+};
+
+typedef struct Con Con;
+typedef struct DirBuf DirBuf;
+typedef struct Excl Excl;
+typedef struct Fid Fid;
+typedef struct Fsys Fsys;
+typedef struct Msg Msg;
+
+struct Msg {
+	uchar*	data;
+	u32int	msize;			/* actual size of data */
+	Fcall	t;
+	Fcall	r;
+	Con*	con;
+	int	flush;
+
+	Msg*	next;
+	Msg*	prev;
+};
+
+struct Con {
+	VtLock*	lock;
+	int	fd;
+	char*	name;
+	uchar*	data;			/* max, not negotiated */
+	u32int	msize;			/* negotiated with Tversion */
+	int	state;
+	int	aok;
+	Msg*	version;
+	int	isconsole;
+
+	Msg*	mhead;			/* active queue */
+	Msg*	mtail;
+	VtRendez* active;
+	int	nmsg;
+
+	VtLock*	fidlock;		/* */
+	Fid*	fidhash[NFidHash];
+	Fid*	fhead;
+	Fid*	ftail;
+	int	nfid;
+};
+
+enum {
+	CsDead,
+	CsNew,
+	CsDown,
+	CsInit,
+	CsUp,
+	CsMoribund,
+};
+
+struct Fid {
+	VtLock*	lock;
+	Con*	con;
+	u32int	fidno;
+	int	ref;			/* inc/dec under Con.fidlock */
+	int	flags;
+
+	int	open;
+	File*	file;
+	Qid	qid;
+	char*	uid;
+	char*	uname;
+	DirBuf*	db;
+	Excl*	excl;
+
+	VtLock*	alock;			/* Tauth/Tattach */
+	AuthRpc* rpc;
+	Fsys*	fsys;
+	char*	cuname;
+
+	Fid*	hash;			/* lookup by fidno */
+	Fid*	next;			/* clunk session with Tversion */
+	Fid*	prev;
+};
+
+enum {					/* Fid.flags and fidGet(..., flags) */
+	FidFCreate	= 0x01,
+	FidFWlock	= 0x02,
+};
+
+enum {					/* Fid.open */
+	FidOCreate	= 0x01,
+	FidORead	= 0x02,
+	FidOWrite	= 0x04,
+	FidORclose	= 0x08,
+};
+
+/*
+ * 9p.c
+ */
+extern int (*rFcall[Tmax])(Msg*);
+extern int validFileName(char*);
+
+/*
+ * 9auth.c
+ */
+extern int authCheck(Fcall*, Fid*, Fsys*);
+extern int authRead(Fid*, void*, int);
+extern int authWrite(Fid*, void*, int);
+
+/*
+ * 9dir.c
+ */
+extern void dirBufFree(DirBuf*);
+extern int dirDe2M(DirEntry*, uchar*, int);
+extern int dirRead(Fid*, uchar*, int, vlong);
+
+/*
+ * 9excl.c
+ */
+extern int exclAlloc(Fid*);
+extern void exclFree(Fid*);
+extern void exclInit(void);
+extern int exclUpdate(Fid*);
+
+/*
+ * 9fid.c
+ */
+extern void fidClunk(Fid*);
+extern Fid* fidGet(Con*, u32int, int);
+extern void fidInit(void);
+extern void fidPut(Fid*);
+
+/*
+ * 9fsys.c
+ */
+extern Fsys* fsysGet(char*);
+extern Fs* fsysGetFs(Fsys*);
+extern void fsysFsRlock(Fsys*);
+extern void fsysFsRUnlock(Fsys*);
+extern File* fsysGetRoot(Fsys*, char*);
+extern Fsys* fsysIncRef(Fsys*);
+extern int fsysInit(void);
+extern int fsysNoAuthCheck(Fsys*);
+extern int fsysNoPermCheck(Fsys*);
+extern void fsysPut(Fsys*);
+extern int fsysWstatAllow(Fsys*);
+
+/*
+ * 9lstn.c
+ */
+extern int lstnInit(void);
+
+/*
+ * 9proc.c
+ */
+extern Con* conAlloc(int, char*);
+extern void procInit(void);
+
+/*
+ * 9srv.c
+ */
+extern int srvInit(void);
+
+/*
+ * 9user.c
+ */
+extern int groupLeader(char*, char*);
+extern int groupMember(char*, char*);
+extern int groupWriteMember(char*);
+extern char* unameByUid(char*);
+extern char* uidByUname(char*);
+extern int usersInit(void);
+extern int validUserName(char*);
+
+extern char* uidadm;
+extern char* unamenone;
+extern char* uidnoworld;
+
+/*
+ * Ccli.c
+ */
+extern int cliAddCmd(char*, int (*)(int, char*[]));
+extern int cliError(char*, ...);
+extern int cliInit(void);
+extern int cliExec(char*);
+
+/*
+ * Ccmd.c
+ */
+extern int cmdInit(void);
+
+/*
+ * Ccons.c
+ */
+extern int consPrompt(char*);
+extern int consInit(void);
+extern int consOpen(int, int, int);
+extern int consTTY(void);
+extern int consWrite(char*, int);
+
+/*
+ * Clog.c
+ */
+extern int consPrint(char*, ...);
+extern int consVPrint(char*, va_list);
+
+/*
+ * fossil.c
+ */
+extern int Dflag;

+ 126 - 0
sys/src/cmd/fossil/9auth.c

@@ -0,0 +1,126 @@
+#include "stdinc.h"
+
+#include "9.h"
+
+int
+authRead(Fid* afid, void* data, int count)
+{
+	AuthInfo *ai;
+	AuthRpc *rpc;
+
+	if((rpc = afid->rpc) == nil)
+		return -1;
+
+	switch(auth_rpc(rpc, "read", nil, 0)){
+	default:
+		return -1;
+	case ARdone:
+		if((ai = auth_getinfo(rpc)) == nil)
+			break;
+		if(ai->cuid == nil || *ai->cuid == '\0'){
+			auth_freeAI(ai);
+			break;
+		}
+		assert(afid->cuname == nil);
+		afid->cuname = vtStrDup(ai->cuid);
+		auth_freeAI(ai);
+		if(Dflag)
+			fprint(2, "authRead cuname %s\n", afid->cuname);
+		assert(afid->uid == nil);
+		if((afid->uid = uidByUname(afid->cuname)) == nil)
+			break;
+		return 0;
+	case ARok:
+		if(count < rpc->narg)
+			break;
+		memmove(data, rpc->arg, rpc->narg);
+		return rpc->narg;
+	case ARphase:
+		break;
+	}
+	return -1;
+}
+
+int
+authWrite(Fid* afid, void* data, int count)
+{
+	assert(afid->rpc != nil);
+	if(auth_rpc(afid->rpc, "write", data, count) != ARok)
+		return -1;
+	return count;
+}
+
+int
+authCheck(Fcall* t, Fid* fid, Fs* fsys)
+{
+	Fid *afid;
+	uchar buf[1];
+
+	/*
+	 * Can't lookup with FidWlock here as there may be
+	 * protocol to do. Use a separate lock to protect altering
+	 * the auth information inside afid.
+	 */
+	if((afid = fidGet(fid->con, t->afid, 0)) == nil){
+		/*
+		 * If no authentication is asked for, allow
+		 * "none" provided the connection has already
+		 * been authenticatated.
+		 */
+		if(strcmp(fid->uname, unamenone) == 0 && fid->con->aok){
+			if((fid->uid = uidByUname(fid->uname)) == nil)
+				return 0;
+			return 1;
+		}
+
+		/*
+		 * The console is allowed to attach without
+		 * authentication.
+		 */
+		if(!fid->con->isconsole)
+			return 0;
+		if((fid->uid = uidByUname(fid->uname)) == nil)
+			return 0;
+		return 1;
+	}
+
+	/*
+	 * Check valid afid;
+	 * check uname and aname match.
+	 */
+	if(!(afid->qid.type & QTAUTH)){
+		fidPut(afid);
+		return 0;
+	}
+	if(strcmp(afid->uname, fid->uname) != 0 || afid->fsys != fsys){
+		fidPut(afid);
+		return 0;
+	}
+
+	vtLock(afid->alock);
+	if(afid->cuname == nil){
+		if(authRead(afid, buf, 0) != 0 || afid->cuname == nil){
+			vtUnlock(afid->alock);
+			fidPut(afid);
+			return 0;
+		}
+	}
+	vtUnlock(afid->alock);
+
+	assert(fid->uid == nil);
+	if((fid->uid = uidByUname(afid->cuname)) == nil){
+		fidPut(afid);
+		return 0;
+	}
+
+	vtMemFree(fid->uname);
+	fid->uname = vtStrDup(afid->cuname);
+	fidPut(afid);
+
+	/*
+	 * Allow "none" once the connection has been authenticated.
+	 */
+	fid->con->aok = 1;
+
+	return 1;
+}

+ 121 - 0
sys/src/cmd/fossil/9dir.c

@@ -0,0 +1,121 @@
+#include "stdinc.h"
+
+#include "9.h"
+
+/* one entry buffer for reading directories */
+struct DirBuf {
+	DirEntryEnum*	dee;
+	int		valid;
+	DirEntry	de;
+};
+
+static DirBuf*
+dirBufAlloc(File* file)
+{
+	DirBuf *db;
+
+	db = vtMemAllocZ(sizeof(DirBuf));
+	db->dee = deeOpen(file);
+
+	return db;
+}
+
+void
+dirBufFree(DirBuf* db)
+{
+	if(db == nil)
+		return;
+
+	if(db->valid)
+		deCleanup(&db->de);
+	deeClose(db->dee);
+	vtMemFree(db);
+}
+
+int
+dirDe2M(DirEntry* de, uchar* p, int np)
+{
+	int n;
+	Dir dir;
+
+	memset(&dir, 0, sizeof(Dir));
+
+	dir.qid.path = de->qid;
+	dir.qid.vers = de->mcount;
+	dir.mode = de->mode & 0777;
+	if(de->mode & ModeAppend){
+		dir.qid.type |= QTAPPEND;
+		dir.mode |= DMAPPEND;
+	}
+	if(de->mode & ModeExclusive){
+		dir.qid.type |= QTEXCL;
+		dir.mode |= DMEXCL;
+	}
+	if(de->mode & ModeDir){
+		dir.qid.type |= QTDIR;
+		dir.mode |= DMDIR;
+	}
+	if(de->mode & ModeSnapshot){
+		dir.qid.type |= QTMOUNT;	/* just for debugging */
+		dir.mode |= DMMOUNT;
+	}
+
+	dir.atime = de->atime;
+	dir.mtime = de->mtime;
+	dir.length = de->size;
+
+	dir.name = de->elem;
+	if((dir.uid = unameByUid(de->uid)) == nil)
+		dir.uid = smprint("(%s)", de->uid);
+	if((dir.gid = unameByUid(de->gid)) == nil)
+		dir.gid = smprint("(%s)", de->gid);
+	if((dir.muid = unameByUid(de->mid)) == nil)
+		dir.muid = smprint("(%s)", de->mid);
+
+	n = convD2M(&dir, p, np);
+
+	vtMemFree(dir.muid);
+	vtMemFree(dir.gid);
+	vtMemFree(dir.uid);
+
+	return n;
+}
+
+int
+dirRead(Fid* fid, uchar* p, int count, vlong offset)
+{
+	int n, nb;
+	DirBuf *db;
+
+	/*
+	 * special case of rewinding a directory
+	 * otherwise ignore the offset
+	 */
+	if(offset == 0 && fid->db){
+		dirBufFree(fid->db);
+		fid->db = nil;
+	}
+
+	if(fid->db == nil)
+		fid->db = dirBufAlloc(fid->file);
+
+	db = fid->db;
+
+	for(nb = 0; nb < count; nb += n){
+		if(!db->valid){
+			n = deeRead(db->dee, &db->de);
+			if(n < 0)
+				return -1;
+			if(n == 0)
+				break;
+			db->valid = 1;
+		}
+		n = dirDe2M(&db->de, p+nb, count-nb);
+		if(n <= BIT16SZ)
+			break;
+		db->valid = 0;
+		deCleanup(&db->de);
+	}
+
+	return nb;
+}

+ 126 - 0
sys/src/cmd/fossil/9excl.c

@@ -0,0 +1,126 @@
+#include "stdinc.h"
+
+#include "9.h"
+
+static struct {
+	VtLock*	lock;
+
+	Excl*	head;
+	Excl*	tail;
+} ebox;
+
+typedef struct Excl {
+	Fsys*	fsys;
+	uvlong	path;
+	ulong	time;
+
+	Excl*	next;
+	Excl*	prev;
+} Excl;
+
+enum {
+	LifeTime	= (5*60),
+};
+
+int
+exclAlloc(Fid* fid)
+{
+	ulong t;
+	Excl *excl;
+
+	assert(fid->excl == nil);
+
+	t = time(0L);
+	vtLock(ebox.lock);
+	for(excl = ebox.head; excl != nil; excl = excl->next){
+		if(excl->fsys != fid->fsys || excl->path != fid->qid.path)
+			continue;
+		/*
+		 * Found it.
+		 * Now, check if it's timed out.
+		 * If not, return error, it's locked.
+		 * If it has timed out, zap the old
+		 * one and continue on to allocate a
+		 * a new one.
+		 */
+		if(excl->time >= t){
+			vtUnlock(ebox.lock);
+			vtSetError("exclusive lock");
+			return 0;
+		}
+		excl->fsys = nil;
+	}
+
+	/*
+	 * Not found or timed-out.
+	 * Alloc a new one and initialise.
+	 */
+	excl = vtMemAllocZ(sizeof(Excl));
+	excl->fsys = fid->fsys;
+	excl->path = fid->qid.path;
+	excl->time = t+LifeTime;
+	if(ebox.tail != nil){
+		excl->prev = ebox.tail;
+		ebox.tail->next = excl;
+	}
+	else{
+		ebox.head = excl;
+		excl->prev = nil;
+	}
+	ebox.tail = excl;
+	excl->next = nil;
+	vtUnlock(ebox.lock);
+
+	fid->excl = excl;
+	return 1;
+}
+
+int
+exclUpdate(Fid* fid)
+{
+	ulong t;
+	Excl *excl;
+
+	excl = fid->excl;
+
+	t = time(0L);
+	vtLock(ebox.lock);
+	if(excl->time < t || excl->fsys != fid->fsys){
+		vtUnlock(ebox.lock);
+		vtSetError("exclusive lock broken");
+		return 0;
+	}
+	excl->time = t+LifeTime;
+	vtUnlock(ebox.lock);
+
+	return 1;
+}
+
+void
+exclFree(Fid* fid)
+{
+	Excl *excl;
+
+	if((excl = fid->excl) == nil)
+		return;
+	fid->excl = nil;
+
+	vtLock(ebox.lock);
+	if(excl->prev != nil)
+		excl->prev->next = excl->next;
+	else
+		ebox.head = excl->next;
+	if(excl->next != nil)
+		excl->next->prev = excl->prev;
+	else
+		ebox.tail = excl->prev;
+	vtUnlock(ebox.lock);
+
+	vtMemFree(excl);
+}
+
+void
+exclInit(void)
+{
+	ebox.lock = vtLockAlloc();
+}

+ 286 - 0
sys/src/cmd/fossil/9fid.c

@@ -0,0 +1,286 @@
+#include "stdinc.h"
+
+#include "9.h"
+
+static struct {
+	VtLock*	lock;
+
+	Fid*	free;
+	int	nfree;
+	int	inuse;
+} fbox;
+
+static void
+fidLock(Fid* fid, int flags)
+{
+	if(flags & FidFWlock){
+		vtLock(fid->lock);
+		fid->flags = flags;
+	}
+	else
+		vtRLock(fid->lock);
+
+	/*
+	 * Callers of file* routines are expected to lock fsys->fs->elk
+	 * before making any calls in order to make sure the epoch doesn't
+	 * change underfoot. With the exception of Tversion and Tattach,
+	 * that implies all 9P functions need to lock on entry and unlock
+	 * on exit. Fortunately, the general case is the 9P functions do
+	 * fidGet on entry and fidPut on exit, so this is a convenient place
+	 * to do the locking.
+	 * No fsys->fs->elk lock is required if the fid is being created
+	 * (Tauth, Tattach and Twalk). FidFCreate is always accompanied by
+	 * FidFWlock so the setting and testing of FidFCreate here and in
+	 * fidUnlock below is always done under fid->lock.
+	 * A side effect is that fidFree is called with the fid locked, and
+	 * must call fidUnlock only after it has disposed of any File
+	 * resources still held.
+	 */
+	if(!(flags & FidFCreate))
+		fsysFsRlock(fid->fsys);
+}
+
+static void
+fidUnlock(Fid* fid)
+{
+	if(!(fid->flags & FidFCreate))
+		fsysFsRUnlock(fid->fsys);
+	if(fid->flags & FidFWlock){
+		fid->flags = 0;
+		vtUnlock(fid->lock);
+		return;
+	}
+	vtRUnlock(fid->lock);
+}
+
+static Fid*
+fidAlloc(void)
+{
+	Fid *fid;
+
+	vtLock(fbox.lock);
+	if(fbox.nfree > 0){
+		fid = fbox.free;
+		fbox.free = fid->hash;
+		fbox.nfree--;
+	}
+	else{
+		fid = vtMemAllocZ(sizeof(Fid));
+		fid->lock = vtLockAlloc();
+		fid->alock = vtLockAlloc();
+	}
+	fbox.inuse++;
+	vtUnlock(fbox.lock);
+
+	fid->con = nil;
+	fid->fidno = NOFID;
+	fid->ref = 0;
+	fid->flags = 0;
+	fid->open = FidOCreate;
+	assert(fid->file == nil);
+	fid->qid = (Qid){0, 0, 0};
+	assert(fid->uid == nil);
+	assert(fid->uname == nil);
+	assert(fid->db == nil);
+	assert(fid->excl == nil);
+	assert(fid->rpc == nil);
+	assert(fid->fsys == nil);
+	assert(fid->cuname == nil);
+	fid->hash = fid->next = fid->prev = nil;
+
+	return fid;
+}
+
+static void
+fidFree(Fid* fid)
+{
+	if(fid->file != nil){
+		fileDecRef(fid->file);
+		fid->file = nil;
+	}
+	if(fid->db != nil){
+		dirBufFree(fid->db);
+		fid->db = nil;
+	}
+	fidUnlock(fid);
+
+	if(fid->uid != nil){
+		vtMemFree(fid->uid);
+		fid->uid = nil;
+	}
+	if(fid->uname != nil){
+		vtMemFree(fid->uname);
+		fid->uname = nil;
+	}
+	if(fid->excl != nil)
+		exclFree(fid);
+	if(fid->rpc != nil){
+		close(fid->rpc->afd);
+		auth_freerpc(fid->rpc);
+		fid->rpc = nil;
+	}
+	if(fid->fsys != nil){
+		fsysPut(fid->fsys);
+		fid->fsys = nil;
+	}
+	if(fid->cuname != nil){
+		vtMemFree(fid->cuname);
+		fid->cuname = nil;
+	}
+
+	vtLock(fbox.lock);
+	fbox.inuse--;
+	if(fbox.nfree < 10){
+		fid->hash = fbox.free;
+		fbox.free = fid;
+		fbox.nfree++;
+	}
+	else{
+		vtLockFree(fid->alock);
+		vtLockFree(fid->lock);
+		vtMemFree(fid);
+	}
+	vtUnlock(fbox.lock);
+}
+
+static void
+fidUnHash(Fid* fid)
+{
+	Fid *fp, **hash;
+
+	assert(fid->ref == 0);
+
+	hash = &fid->con->fidhash[fid->fidno % NFidHash];
+	for(fp = *hash; fp != nil; fp = fp->hash){
+		if(fp == fid){
+			*hash = fp->hash;
+			break;
+		}
+		hash = &fp->hash;
+	}
+	assert(fp == fid);
+
+	if(fid->prev != nil)
+		fid->prev->next = fid->next;
+	else
+		fid->con->fhead = fid->next;
+	if(fid->next != nil)
+		fid->next->prev = fid->prev;
+	else
+		fid->con->ftail = fid->prev;
+	fid->prev = fid->next = nil;
+
+	fid->con->nfid--;
+}
+
+Fid*
+fidGet(Con* con, u32int fidno, int flags)
+{
+	Fid *fid, **hash;
+
+	if(fidno == NOFID)
+		return nil;
+
+	hash = &con->fidhash[fidno % NFidHash];
+	vtLock(con->fidlock);
+	for(fid = *hash; fid != nil; fid = fid->hash){
+		if(fid->fidno != fidno)
+			continue;
+
+		/*
+		 * Already in use is an error
+		 * when called from attach, clone or walk.
+		 */
+		if(flags & FidFCreate){
+			vtUnlock(con->fidlock);
+			vtSetError("fid in use");
+			return nil;
+		}
+		fid->ref++;
+		vtUnlock(con->fidlock);
+
+		fidLock(fid, flags);
+		if((fid->open & FidOCreate) || fid->fidno == NOFID){
+			fidPut(fid);
+			vtSetError("fid invalid");
+			return nil;
+		}
+		return fid;
+	}
+
+	if((flags & FidFCreate) && (fid = fidAlloc()) != nil){
+		assert(flags & FidFWlock);
+		fid->con = con;
+		fid->fidno = fidno;
+		fid->ref = 1;
+
+		fid->hash = *hash;
+		*hash = fid;
+		if(con->ftail != nil){
+			fid->prev = con->ftail;
+			con->ftail->next = fid;
+		}
+		else{
+			con->fhead = fid;
+			fid->prev = nil;
+		}
+		con->ftail = fid;
+		fid->next = nil;
+
+		con->nfid++;
+		vtUnlock(con->fidlock);
+
+		/*
+		 * The FidOCreate flag is used to prevent any
+		 * accidental access to the Fid between unlocking the
+		 * hash and acquiring the Fid lock for return.
+		 */
+		fidLock(fid, flags);
+		fid->open &= ~FidOCreate;
+		return fid;
+	}
+	vtUnlock(con->fidlock);
+
+	vtSetError("fid not found");
+	return nil;
+}
+
+void
+fidPut(Fid* fid)
+{
+	vtLock(fid->con->fidlock);
+	assert(fid->ref > 0);
+	fid->ref--;
+	vtUnlock(fid->con->fidlock);
+
+	if(fid->ref == 0 && fid->fidno == NOFID){
+		fidFree(fid);
+		return;
+	}
+	fidUnlock(fid);
+}
+
+void
+fidClunk(Fid* fid)
+{
+	assert(fid->flags & FidFWlock);
+
+	vtLock(fid->con->fidlock);
+	assert(fid->ref > 0);
+	fid->ref--;
+	fidUnHash(fid);
+	fid->fidno = NOFID;
+	vtUnlock(fid->con->fidlock);
+
+	if(fid->ref > 0){
+		fidUnlock(fid);
+		return;
+	}
+	fidFree(fid);
+}
+
+void
+fidInit(void)
+{
+	fbox.lock = vtLockAlloc();
+}

File diff suppressed because it is too large
+ 1460 - 0
sys/src/cmd/fossil/9fsys.c


+ 177 - 0
sys/src/cmd/fossil/9lstn.c

@@ -0,0 +1,177 @@
+#include "stdinc.h"
+
+#include "9.h"
+
+typedef struct Lstn Lstn;
+typedef struct Lstn {
+	int	afd;
+	char*	address;
+	char	dir[NETPATHLEN];
+
+	Lstn*	next;
+	Lstn*	prev;
+} Lstn;
+
+static struct {
+	VtLock*	lock;
+
+	Lstn*	head;
+	Lstn*	tail;
+} lbox;
+
+static void
+lstnFree(Lstn* lstn)
+{
+	vtLock(lbox.lock);
+	if(lstn->prev != nil)
+		lstn->prev->next = lstn->next;
+	else
+		lbox.head = lstn->next;
+	if(lstn->next != nil)
+		lstn->next->prev = lstn->prev;
+	else
+		lbox.tail = lstn->prev;
+	vtUnlock(lbox.lock);
+
+	if(lstn->afd != -1)
+		close(lstn->afd);
+	vtMemFree(lstn->address);
+	vtMemFree(lstn);
+}
+
+static void
+lstnListen(void* a)
+{
+	Lstn *lstn;
+	int dfd, lfd;
+	char newdir[NETPATHLEN];
+
+ 	vtThreadSetName("listen");
+
+	lstn = a;
+	for(;;){
+		if((lfd = listen(lstn->dir, newdir)) < 0){
+			fprint(2, "listen: listen '%s': %r", lstn->dir);
+			break;
+		}
+
+		if((dfd = accept(lfd, newdir)) >= 0)
+			conAlloc(dfd, newdir);
+		else
+			fprint(2, "listen: accept '%s': %r", newdir);
+		close(lfd);
+	}
+	lstnFree(lstn);
+}
+
+static Lstn*
+lstnAlloc(char* address)
+{
+	int afd;
+	Lstn *lstn;
+	char dir[NETPATHLEN];
+
+	vtLock(lbox.lock);
+	for(lstn = lbox.head; lstn != nil; lstn = lstn->next){
+		if(strcmp(lstn->address, address) != 0)
+			continue;
+		vtSetError("listen: already serving '%s'", address);
+		vtUnlock(lbox.lock);
+		return nil;
+	}
+
+	if((afd = announce(address, dir)) < 0){
+		vtSetError("listen: announce '%s': %r", address);
+		vtUnlock(lbox.lock);
+		return nil;
+	}
+
+	lstn = vtMemAllocZ(sizeof(Lstn));
+	lstn->afd = afd;
+	lstn->address = vtStrDup(address);
+	memmove(lstn->dir, dir, NETPATHLEN);
+
+	if(lbox.tail != nil){
+		lstn->prev = lbox.tail;
+		lbox.tail->next = lstn;
+	}
+	else{
+		lbox.head = lstn;
+		lstn->prev = nil;
+	}
+	lbox.tail = lstn;
+	vtUnlock(lbox.lock);
+
+	if(vtThread(lstnListen, lstn) < 0){
+		vtSetError("listen: thread '%s': %r", lstn->address);
+		lstnFree(lstn);
+		return nil;
+	}
+
+	return lstn;
+}
+
+static int
+cmdLstn(int argc, char* argv[])
+{
+	int dflag;
+	Lstn *lstn;
+	char *usage = "usage: listen [-d] [address]";
+
+	dflag = 0;
+
+	ARGBEGIN{
+	default:
+		return cliError(usage);
+	case 'd':
+		dflag = 1;
+		break;
+	}ARGEND
+
+	switch(argc){
+	default:
+		return cliError(usage);
+	case 0:
+		vtRLock(lbox.lock);
+		for(lstn = lbox.head; lstn != nil; lstn = lstn->next)
+			consPrint("\t%s\t%s\n", lstn->address, lstn->dir);
+		vtRUnlock(lbox.lock);
+		break;
+	case 1:
+		if(!dflag){
+			if(lstnAlloc(argv[0]) == nil)
+				return 0;
+			break;
+		}
+
+		vtLock(lbox.lock);
+		for(lstn = lbox.head; lstn != nil; lstn = lstn->next){
+			if(strcmp(lstn->address, argv[0]) != 0)
+				continue;
+			if(lstn->afd != -1){
+				close(lstn->afd);
+				lstn->afd = -1;
+			}
+			break;
+		}
+		vtUnlock(lbox.lock);
+
+		if(lstn == nil){
+			vtSetError("listen: '%s' not found", argv[0]);
+			return 0;
+		}
+		break;
+	}
+
+	return 1;
+}
+
+int
+lstnInit(void)
+{
+	lbox.lock = vtLockAlloc();
+
+	cliAddCmd("listen", cmdLstn);
+
+	return 1;
+}

File diff suppressed because it is too large
+ 1118 - 0
sys/src/cmd/fossil/9p.c


+ 109 - 0
sys/src/cmd/fossil/9ping.c

@@ -0,0 +1,109 @@
+#include <u.h>
+#include <libc.h>
+
+typedef uvlong u64int;
+
+#define TWID64	((u64int)~(u64int)0)
+
+
+u64int
+unittoull(char *s)
+{
+	char *es;
+	u64int n;
+
+	if(s == nil)
+		return TWID64;
+	n = strtoul(s, &es, 0);
+	if(*es == 'k' || *es == 'K'){
+		n *= 1024;
+		es++;
+	}else if(*es == 'm' || *es == 'M'){
+		n *= 1024*1024;
+		es++;
+	}else if(*es == 'g' || *es == 'G'){
+		n *= 1024*1024*1024;
+		es++;
+	}
+	if(*es != '\0')
+		return TWID64;
+	return n;
+}
+
+void
+main(int argc, char *argv[])
+{
+	int fd, i;
+	int n = 1000, m;
+	int s = 1;
+	double *t, t0, t1;
+	uchar *buf;	
+	double a, d, max, min;
+
+	m = OREAD;
+	ARGBEGIN{
+	case 'n':
+		n = atoi(ARGF());
+		break;
+	case 's':
+		s = unittoull(ARGF());
+		if(s < 1 || s > 1024*1024)
+			sysfatal("bad size");
+		break;
+	case 'r':
+		m = OREAD;
+		break;
+	case 'w':
+		m = OWRITE;
+		break;
+	}ARGEND
+
+	fd = 0;
+	if(argc == 1){
+		fd = open(argv[0], m);
+		if(fd < 0)
+			sysfatal("could not open file: %s: %r", argv[0]);
+	}
+
+	buf = malloc(s);
+	t = malloc(n*sizeof(double));
+	
+	t0 = nsec();
+	for(i=0; i<n; i++){
+		if(m == OREAD){
+			if(pread(fd, buf, s, 0) < s)
+				sysfatal("bad read: %r");
+		}else{
+			if(pwrite(fd, buf, s, 0) < s)
+				sysfatal("bad write: %r");
+		}
+		t1 = nsec();
+		t[i] = (t1 - t0)*1e-3;
+		t0 = t1;
+	}
+
+	a = 0.;
+	d = 0.;
+	max = 0.;
+	min = 1e12;
+
+	for(i=0; i<n; i++){
+		a += t[i];
+		if(max < t[i])
+			max = t[i];
+		if(min > t[i])
+			min = t[i];
+	}
+
+	a /= n;
+	
+	for(i=0; i<n; i++)
+		d += (a - t[i]) * (a - t[i]);
+	d /= n;
+	d = sqrt(d);
+
+	print("avg = %.0fµs min = %.0fµs max = %.0fµs dev = %.0fµs\n", a, min, max, d);
+
+	exits(0);
+}
+

+ 415 - 0
sys/src/cmd/fossil/9proc.c

@@ -0,0 +1,415 @@
+#include "stdinc.h"
+
+#include "9.h"
+#include "dat.h"
+#include "fns.h"
+
+enum {
+	NConInit	= 128,
+	NMsgInit	= 20,
+	NMsgProcInit	= 4,
+	NMsizeInit	= 8192+IOHDRSZ,
+};
+
+static struct {
+	VtLock*	lock;
+	Con**	con;			/* arena */
+	int	ncon;			/* how many in arena */
+	int	hi;			/* high watermark */
+	int	cur;			/* hint for allocation */
+
+	u32int	msize;
+} cbox;
+
+static struct {
+	VtLock*	lock;
+
+	Msg*	free;
+	VtRendez* alloc;
+
+	Msg*	head;
+	Msg*	tail;
+	VtRendez* work;
+
+	int	maxmsg;
+	int	nmsg;
+	int	maxproc;
+	int	nproc;
+
+	u32int	msize;			/* immutable */
+} mbox;
+
+static void
+msgFree(Msg* m)
+{
+	vtLock(mbox.lock);
+	if(mbox.nmsg > mbox.maxmsg){
+		vtMemFree(m->data);
+		vtMemFree(m);
+		mbox.nmsg--;
+		vtUnlock(mbox.lock);
+		return;
+	}
+	m->next = mbox.free;
+	mbox.free = m;
+	if(m->next == nil)
+		vtWakeup(mbox.alloc);
+	vtUnlock(mbox.lock);
+}
+
+static void
+conFree(Con* con)
+{
+	if(con->fd >= 0){
+		close(con->fd);
+		con->fd = -1;
+	}