Browse Source

Plan 9 from Bell Labs 2002-12-13

David du Colombier 21 years ago
parent
commit
79b935b594
91 changed files with 2722 additions and 1577 deletions
  1. 411 408
      dist/replica/plan9.db
  2. 522 0
      dist/replica/plan9.log
  3. 2 0
      sys/include/draw.h
  4. 11 10
      sys/include/memdraw.h
  5. 7 1
      sys/man/2/print
  6. 52 6
      sys/man/8/ventiaux
  7. 6 4
      sys/src/9/alphapc/apc
  8. 6 3
      sys/src/9/alphapc/apccpu
  9. 40 4
      sys/src/9/alphapc/devarch.c
  10. 57 19
      sys/src/9/alphapc/devether.c
  11. 6 0
      sys/src/9/alphapc/etherif.h
  12. 3 2
      sys/src/9/alphapc/initcode
  13. 151 14
      sys/src/9/alphapc/main.c
  14. 2 1
      sys/src/9/alphapc/mkfile
  15. 4 5
      sys/src/9/alphapc/pci.c
  16. 1 138
      sys/src/9/alphapc/random.c
  17. 1 532
      sys/src/9/alphapc/screen.c
  18. 2 0
      sys/src/9/alphapc/screen.h
  19. 1 1
      sys/src/9/bitsy/main.c
  20. 8 8
      sys/src/9/bitsy/screen.c
  21. 3 3
      sys/src/9/boot/bootauth.c
  22. 3 3
      sys/src/9/boot/bootcache.c
  23. 1 1
      sys/src/9/boot/bootip.c
  24. 3 3
      sys/src/9/boot/embed.c
  25. 2 2
      sys/src/9/boot/local.c
  26. 1 1
      sys/src/9/boot/paq.c
  27. 37 0
      sys/src/9/boot/testboot.c
  28. 3 2
      sys/src/9/mtx/initcode
  29. 1 1
      sys/src/9/mtx/mkfile
  30. 5 3
      sys/src/9/mtx/mtx
  31. 6 3
      sys/src/9/mtx/mtxcpu
  32. 3 2
      sys/src/9/pc/devvga.c
  33. 1 1
      sys/src/9/pc/kbd.c
  34. 5 5
      sys/src/9/pc/mkfile
  35. 5 3
      sys/src/9/pc/pc
  36. 7 4
      sys/src/9/pc/pcauth
  37. 6 5
      sys/src/9/pc/pccd
  38. 6 2
      sys/src/9/pc/pccpu
  39. 8 6
      sys/src/9/pc/pcdisk
  40. 11 5
      sys/src/9/pc/screen.c
  41. 3 0
      sys/src/9/pc/screen.h
  42. 6 6
      sys/src/9/pc/vga.c
  43. 65 21
      sys/src/9/port/devdraw.c
  44. 27 13
      sys/src/9/port/devmnt.c
  45. 102 38
      sys/src/9/port/devroot.c
  46. 26 0
      sys/src/9/port/initcode.c
  47. 26 0
      sys/src/9/port/mkbootrules
  48. 17 2
      sys/src/9/port/mkdevc
  49. 13 2
      sys/src/9/port/mkdevlist
  50. 1 1
      sys/src/9/port/mkextract
  51. 8 3
      sys/src/9/port/mkroot
  52. 1 1
      sys/src/9/port/portfns.h
  53. 10 49
      sys/src/9/port/portmkfile
  54. 2 2
      sys/src/cmd/crop.c
  55. 1 2
      sys/src/cmd/exportfs/exportfs.c
  56. 20 8
      sys/src/cmd/fax/mkfile
  57. 1 1
      sys/src/cmd/iconv.c
  58. 1 1
      sys/src/cmd/jpg/multichan.c
  59. 1 1
      sys/src/cmd/jpg/onechan.c
  60. 1 1
      sys/src/cmd/jpg/writepng.c
  61. 2 2
      sys/src/cmd/postscript/p9bitpost/pslib.c
  62. 2 2
      sys/src/cmd/resample.c
  63. 25 0
      sys/src/cmd/venti/backup.example
  64. 181 0
      sys/src/cmd/venti/copy.c
  65. 1 0
      sys/src/cmd/venti/mkfile
  66. 16 7
      sys/src/cmd/venti/read.c
  67. 1 0
      sys/src/cmd/vl/l.h
  68. 49 15
      sys/src/cmd/vnc/devdraw.c
  69. 5 1
      sys/src/cmd/vnc/kbd_vwr.c
  70. 10 10
      sys/src/cmd/vnc/screen.c
  71. 38 13
      sys/src/cmd/vnc/vncs.c
  72. 22 6
      sys/src/libc/fmt/dofmt.c
  73. 1 0
      sys/src/libmemdraw/alloc.c
  74. 6 6
      sys/src/libmemdraw/arc.c
  75. 529 87
      sys/src/libmemdraw/draw.c
  76. 6 4
      sys/src/libmemdraw/ellipse.c
  77. 16 16
      sys/src/libmemdraw/fillpoly.c
  78. 32 12
      sys/src/libmemdraw/line.c
  79. 13 11
      sys/src/libmemdraw/openmemsubfont.c
  80. 2 2
      sys/src/libmemdraw/poly.c
  81. 1 1
      sys/src/libmemdraw/string.c
  82. 6 4
      sys/src/libmemlayer/draw.c
  83. 1 1
      sys/src/libmemlayer/lalloc.c
  84. 1 1
      sys/src/libmemlayer/layerop.c
  85. 1 1
      sys/src/libmemlayer/ldelete.c
  86. 2 2
      sys/src/libmemlayer/lhide.c
  87. 7 5
      sys/src/libmemlayer/line.c
  88. 1 1
      sys/src/libmemlayer/load.c
  89. 2 2
      sys/src/libmemlayer/lorigin.c
  90. 0 1
      sys/src/libmemlayer/mkfile
  91. 1 1
      sys/src/libmemlayer/unload.c

File diff suppressed because it is too large
+ 411 - 408
dist/replica/plan9.db


+ 522 - 0
dist/replica/plan9.log

@@ -16222,3 +16222,525 @@
 1039674725 1 c 386/bin/ape/dirname - 775 sys sys 1039673023 135007
 1039674725 2 c 386/bin/aux/lpdsend - 775 sys sys 1039673024 156055
 1039721575 0 c sys/games/lib/fortunes - 664 sys sys 1039720623 237691
+1039743615 0 c sys/man/8/ventiaux - 664 sys sys 1039743547 9089
+1039743615 1 c sys/src/9/port/devmnt.c - 664 sys sys 1039743586 21096
+1039743615 2 a sys/src/cmd/venti/backup.example - 775 sys sys 1039743539 490
+1039743615 3 a sys/src/cmd/venti/copy.c - 664 sys sys 1039743543 3405
+1039743615 4 c sys/src/cmd/venti/read.c - 664 sys sys 1039743542 1724
+1039744879 0 c sys/man/8/ventiaux - 664 sys sys 1039743887 9894
+1039748483 0 c sys/src/cmd/exportfs/exportfs.c - 664 sys sys 1039747665 15465
+1039750288 0 c 386/bin/venti/read - 775 sys sys 1039749306 102602
+1039750288 1 c 386/bin/scp - 775 sys sys 1039749303 159634
+1039750288 2 c 386/bin/ssh - 775 sys sys 1039749303 209458
+1039750288 3 c 386/bin/webfs - 775 sys sys 1039749307 342597
+1039750288 4 c 386/bin/auth/factotum - 775 sys sys 1039749299 300575
+1039750288 5 c 386/bin/auth/secretpem - 775 sys sys 1039749299 118326
+1039750288 6 c 386/bin/auth/secstore - 775 sys sys 1039749299 178795
+1039750288 7 c 386/bin/auth/secstored - 775 sys sys 1039749300 192673
+1039750288 8 c 386/bin/auth/secuser - 775 sys sys 1039749300 149083
+1039750288 9 c 386/bin/aux/X509gen - 775 sys sys 1039749301 126205
+1039750288 10 c 386/bin/aux/ssh_genkey - 775 sys sys 1039749301 194383
+1039750288 11 c 386/bin/aux/sshserve - 775 sys sys 1039749301 246300
+1039750288 12 c 386/bin/aux/timesync - 775 sys sys 1039749302 125513
+1039750288 13 c 386/bin/ip/httpd/httpd - 775 sys sys 1039749302 283378
+1039750288 14 c 386/bin/sshnet - 775 sys sys 1039749304 280813
+1039750288 15 c 386/bin/tlsclient - 775 sys sys 1039749304 191654
+1039750288 16 c 386/bin/tlssrv - 775 sys sys 1039749304 192019
+1039750288 17 c 386/bin/upas/fs - 775 sys sys 1039749305 325975
+1039750288 18 c 386/bin/upas/pop3 - 775 sys sys 1039749306 251371
+1039750288 19 c 386/bin/upas/smtp - 775 sys sys 1039749306 264502
+1039750288 20 c 386/lib/libmp.a - 664 sys sys 1039749307 77816
+1039750288 21 c sys/src/cmd/venti/mkfile - 664 sys sys 1039749273 1112
+1039753664 0 c 386/bin/exportfs - 775 sys sys 1039753145 145202
+1039753664 1 c 386/bin/scp - 775 sys sys 1039753145 159405
+1039753664 2 c 386/bin/ssh - 775 sys sys 1039753146 209227
+1039753664 3 c 386/bin/webfs - 775 sys sys 1039753149 342366
+1039753664 4 c 386/bin/auth/factotum - 775 sys sys 1039753142 300344
+1039753664 5 c 386/bin/auth/secretpem - 775 sys sys 1039753142 118095
+1039753664 6 c 386/bin/auth/secstore - 775 sys sys 1039753142 178566
+1039753664 7 c 386/bin/auth/secstored - 775 sys sys 1039753143 192442
+1039753664 8 c 386/bin/auth/secuser - 775 sys sys 1039753143 148854
+1039753664 9 c 386/bin/aux/X509gen - 775 sys sys 1039753143 125974
+1039753664 10 c 386/bin/aux/ssh_genkey - 775 sys sys 1039753144 194154
+1039753664 11 c 386/bin/aux/sshserve - 775 sys sys 1039753144 246069
+1039753664 12 c 386/bin/aux/timesync - 775 sys sys 1039753144 125282
+1039753664 13 c 386/bin/ip/httpd/httpd - 775 sys sys 1039753145 283147
+1039753664 14 c 386/bin/sshnet - 775 sys sys 1039753146 280584
+1039753664 15 c 386/bin/tlsclient - 775 sys sys 1039753147 191425
+1039753664 16 c 386/bin/tlssrv - 775 sys sys 1039753147 191788
+1039753664 17 c 386/bin/upas/fs - 775 sys sys 1039753148 325746
+1039753664 18 c 386/bin/upas/pop3 - 775 sys sys 1039753148 251142
+1039753664 19 c 386/bin/upas/smtp - 775 sys sys 1039753149 264273
+1039753664 20 c 386/lib/libmemdraw.a - 664 sys sys 1039753150 279612
+1039753664 21 c 386/lib/libmp.a - 664 sys sys 1039753150 76970
+1039753664 22 c sys/include/draw.h - 664 sys sys 1039752978 13954
+1039753664 23 c sys/include/memdraw.h - 664 sys sys 1039752978 5616
+1039753664 24 c sys/src/9/alphapc/apc - 664 sys sys 1039753420 621
+1039753664 25 c sys/src/9/alphapc/apccpu - 664 sys sys 1039753419 507
+1039753664 26 c sys/src/9/alphapc/devarch.c - 664 sys sys 1039753422 9760
+1039753664 27 c sys/src/9/alphapc/devether.c - 664 sys sys 1039753421 9659
+1039753664 28 c sys/src/9/alphapc/etherif.h - 664 sys sys 1039753421 1049
+1039753664 29 c sys/src/9/alphapc/initcode - 664 sys sys 1039753419 779
+1039753664 30 c sys/src/9/alphapc/main.c - 664 sys sys 1039753420 13626
+1039753664 31 c sys/src/9/alphapc/mkfile - 664 sys sys 1039753423 1985
+1039753664 32 c sys/src/9/alphapc/pci.c - 664 sys sys 1039753420 7868
+1039753664 33 c sys/src/9/alphapc/random.c - 664 sys sys 1039753421 26
+1039753664 34 c sys/src/9/alphapc/screen.c - 664 sys sys 1039753422 26
+1039753664 35 c sys/src/9/alphapc/screen.h - 664 sys sys 1039753422 3511
+1039753664 36 c sys/src/9/bitsy/main.c - 664 sys sys 1039753387 8929
+1039753664 37 c sys/src/9/bitsy/screen.c - 664 sys sys 1039753380 10145
+1039753664 38 c sys/src/9/mtx/initcode - 664 sys sys 1039753442 444
+1039753664 39 c sys/src/9/mtx/mkfile - 664 sys sys 1039753441 1475
+1039753664 40 c sys/src/9/mtx/mtx - 664 sys sys 1039753441 413
+1039753664 41 c sys/src/9/mtx/mtxcpu - 664 sys sys 1039753442 421
+1039753664 42 c sys/src/9/pc/devvga.c - 664 sys sys 1039753498 8625
+1039753664 43 c sys/src/9/pc/kbd.c - 664 sys sys 1039753498 9134
+1039753664 44 c sys/src/9/pc/mkfile - 664 sys sys 1039753495 2992
+1039753664 45 c sys/src/9/pc/pc - 664 sys sys 1039753496 1311
+1039753664 46 c sys/src/9/pc/pcauth - 664 sys sys 1039753496 600
+1039753664 47 c sys/src/9/pc/pccpu - 664 sys sys 1039753495 785
+1039753664 48 c sys/src/9/pc/pcdisk - 664 sys sys 1039753496 1369
+1039753664 49 c sys/src/9/pc/screen.c - 664 sys sys 1039753497 7266
+1039753664 50 c sys/src/9/pc/screen.h - 664 sys sys 1039753497 3742
+1039753664 51 c sys/src/9/pc/pccd - 664 sys sys 1039753495 1278
+1039753664 52 c sys/src/9/pc/vga.c - 664 sys sys 1039753497 4963
+1039753664 53 c sys/src/9/port/devdraw.c - 664 sys sys 1039753332 41987
+1039753664 54 c sys/src/9/port/devroot.c - 664 sys sys 1039753332 3593
+1039753664 55 c sys/src/9/port/mkdevc - 775 sys sys 1039753333 4054
+1039753664 56 c sys/src/9/port/mkdevlist - 775 sys sys 1039753333 700
+1039753664 57 c sys/src/9/port/mkextract - 775 sys sys 1039753334 435
+1039753664 58 c sys/src/9/port/mkroot - 775 sys sys 1039753334 235
+1039753664 59 c sys/src/9/port/portfns.h - 664 sys sys 1039753334 10472
+1039753664 60 c sys/src/9/port/portmkfile - 664 sys sys 1039753335 2372
+1039753664 61 a sys/src/9/port/initcode.c - 664 sys sys 1039753332 446
+1039753664 62 c sys/src/cmd/crop.c - 664 sys sys 1039753034 4136
+1039753664 63 c sys/src/cmd/fax/mkfile - 664 sys sys 1039753042 535
+1039753664 64 c sys/src/cmd/iconv.c - 664 sys sys 1039753035 1801
+1039753664 65 c sys/src/cmd/postscript/p9bitpost/pslib.c - 664 sys sys 1039753066 23150
+1039753664 66 c sys/src/cmd/vnc/devdraw.c - 664 sys sys 1039753056 42068
+1039753664 67 c sys/src/cmd/vnc/screen.c - 664 sys sys 1039753059 7424
+1039753664 68 c sys/src/cmd/vnc/vncs.c - 664 sys sys 1039753062 20594
+1039753664 69 c sys/src/cmd/jpg/multichan.c - 664 sys sys 1039753047 825
+1039753664 70 c sys/src/cmd/jpg/onechan.c - 664 sys sys 1039753044 3732
+1039753664 71 c sys/src/cmd/jpg/writepng.c - 664 sys sys 1039753051 4261
+1039753664 72 c sys/src/cmd/resample.c - 664 sys sys 1039753039 6268
+1039753664 73 c sys/src/cmd/vl/l.h - 664 sys sys 1039753053 5434
+1039753664 74 c sys/src/libmemdraw/alloc.c - 664 sys sys 1039752932 3152
+1039753664 75 c sys/src/libmemdraw/arc.c - 664 sys sys 1039752932 2608
+1039753664 76 c sys/src/libmemdraw/draw.c - 664 sys sys 1039752933 55250
+1039753664 77 c sys/src/libmemdraw/ellipse.c - 664 sys sys 1039752933 4866
+1039753664 78 c sys/src/libmemdraw/fillpoly.c - 664 sys sys 1039752933 9841
+1039753664 79 c sys/src/libmemdraw/line.c - 664 sys sys 1039752934 11041
+1039753664 80 c sys/src/libmemdraw/openmemsubfont.c - 664 sys sys 1039752934 900
+1039753664 81 c sys/src/libmemdraw/poly.c - 664 sys sys 1039752935 484
+1039753664 82 c sys/src/libmemdraw/string.c - 664 sys sys 1039752935 1054
+1039753664 83 c sys/src/libmemlayer/draw.c - 664 sys sys 1039752978 3947
+1039753664 84 c sys/src/libmemlayer/lalloc.c - 664 sys sys 1039752979 1760
+1039753664 85 c sys/src/libmemlayer/layerop.c - 664 sys sys 1039752979 2641
+1039753664 86 c sys/src/libmemlayer/ldelete.c - 664 sys sys 1039752979 1183
+1039753664 87 c sys/src/libmemlayer/lhide.c - 664 sys sys 1039752980 1693
+1039753664 88 c sys/src/libmemlayer/line.c - 664 sys sys 1039752980 2587
+1039753664 89 c sys/src/libmemlayer/load.c - 664 sys sys 1039752980 1032
+1039753664 90 c sys/src/libmemlayer/lorigin.c - 664 sys sys 1039752981 2507
+1039753664 91 c sys/src/libmemlayer/mkfile - 664 sys sys 1039752977 365
+1039753664 92 c sys/src/libmemlayer/unload.c - 664 sys sys 1039752981 1007
+1039753808 0 c sys/src/libc/fmt/dofmt.c - 664 sys sys 1039753802 8626
+1039754031 0 a sys/src/9/port/mkbootrules - 775 sys sys 1039754026 344
+1039758686 0 c 386/9pc - 775 sys sys 1039758620 1783164
+1039758686 1 c 386/9pccpu - 775 sys sys 1039758622 1429682
+1039758686 2 c 386/9pcdisk - 775 sys sys 1039758625 1987069
+1039758686 3 c 386/bin/8a - 775 sys sys 1039758526 113387
+1039758686 4 c 386/bin/8c - 775 sys sys 1039758527 298665
+1039758686 5 c 386/bin/8l - 775 sys sys 1039758527 107971
+1039758686 6 c 386/bin/9660srv - 775 sys sys 1039758527 105203
+1039758686 7 c 386/bin/aan - 775 sys sys 1039758528 127563
+1039758686 8 c 386/bin/acid - 775 sys sys 1039758528 377948
+1039758686 9 c 386/bin/acme - 775 sys sys 1039758529 413667
+1039758686 10 c 386/bin/ar - 775 sys sys 1039758530 113119
+1039758686 11 c 386/bin/archfs - 775 sys sys 1039758530 139484
+1039758686 12 c 386/bin/ascii - 775 sys sys 1039758530 63264
+1039758686 13 c 386/bin/astro - 775 sys sys 1039758530 139263
+1039758686 14 c 386/bin/basename - 775 sys sys 1039758547 38375
+1039758686 15 c 386/bin/bc - 775 sys sys 1039758548 80389
+1039758686 16 c 386/bin/bind - 775 sys sys 1039758548 58302
+1039758686 17 c 386/bin/bitsy/bitsyload - 775 sys sys 1039758548 62104
+1039758686 18 c 386/bin/bitsy/keyboard - 775 sys sys 1039758549 298691
+1039758686 19 c 386/bin/bitsy/params - 775 sys sys 1039758549 57274
+1039758686 20 c 386/bin/bitsy/pencal - 775 sys sys 1039758549 114495
+1039758686 21 c 386/bin/bitsy/prompter - 775 sys sys 1039758549 280856
+1039758686 22 c 386/bin/bunzip2 - 775 sys sys 1039758550 96083
+1039758686 23 c 386/bin/bzip2 - 775 sys sys 1039758550 112667
+1039758686 24 c 386/bin/cal - 775 sys sys 1039758550 66676
+1039758686 25 c 386/bin/calendar - 775 sys sys 1039758550 78193
+1039758686 26 c 386/bin/cat - 775 sys sys 1039758550 37944
+1039758686 27 c 386/bin/cdfs - 775 sys sys 1039758551 159924
+1039758686 28 c 386/bin/cfs - 775 sys sys 1039758551 129125
+1039758686 29 c 386/bin/chgrp - 775 sys sys 1039758551 58493
+1039758686 30 c 386/bin/chmod - 775 sys sys 1039758551 61736
+1039758686 31 c 386/bin/cleanname - 775 sys sys 1039758551 56650
+1039758686 32 c 386/bin/clock - 775 sys sys 1039758552 152556
+1039758686 33 c 386/bin/cmp - 775 sys sys 1039758552 41134
+1039758686 34 c 386/bin/colors - 775 sys sys 1039758552 145870
+1039758686 35 c 386/bin/comm - 775 sys sys 1039758552 60001
+1039758686 36 c 386/bin/con - 775 sys sys 1039758552 76698
+1039758686 37 c 386/bin/cp - 775 sys sys 1039758553 62687
+1039758686 38 c 386/bin/cpp - 775 sys sys 1039758553 148353
+1039758686 39 c 386/bin/cpu - 775 sys sys 1039758553 137158
+1039758686 40 c 386/bin/crop - 775 sys sys 1039758553 115496
+1039758686 41 c 386/bin/date - 775 sys sys 1039758553 43976
+1039758686 42 c 386/bin/db - 775 sys sys 1039758554 323623
+1039758686 43 c 386/bin/dc - 775 sys sys 1039758554 97868
+1039758686 44 c 386/bin/dd - 775 sys sys 1039758554 46046
+1039758686 45 c 386/bin/deroff - 775 sys sys 1039758555 73199
+1039758686 46 c 386/bin/dict - 775 sys sys 1039758555 168316
+1039758686 47 c 386/bin/diff - 775 sys sys 1039758555 82259
+1039758686 48 c 386/bin/dossrv - 775 sys sys 1039758558 139838
+1039758686 49 c 386/bin/du - 775 sys sys 1039758558 63064
+1039758686 50 c 386/bin/echo - 775 sys sys 1039758558 55830
+1039758686 51 c 386/bin/ed - 775 sys sys 1039758558 92160
+1039758686 52 c 386/bin/exportfs - 775 sys sys 1039758559 145630
+1039758686 53 c 386/bin/faces - 775 sys sys 1039758559 187144
+1039758686 54 c 386/bin/factor - 775 sys sys 1039758559 60135
+1039758686 55 c 386/bin/fs/32vfs - 775 sys sys 1039758560 96155
+1039758686 56 c 386/bin/fs/cpiofs - 775 sys sys 1039758560 94985
+1039758686 57 c 386/bin/fs/tapfs - 775 sys sys 1039758561 97453
+1039758686 58 c 386/bin/fs/tarfs - 775 sys sys 1039758561 95839
+1039758686 59 c 386/bin/fs/tpfs - 775 sys sys 1039758561 94691
+1039758686 60 c 386/bin/fs/v10fs - 775 sys sys 1039758561 96202
+1039758686 61 c 386/bin/fs/v6fs - 775 sys sys 1039758562 96121
+1039758686 62 c 386/bin/getmap - 775 sys sys 1039758562 63678
+1039758686 63 c 386/bin/gunzip - 775 sys sys 1039758563 79918
+1039758686 64 c 386/bin/gzip - 775 sys sys 1039758563 84015
+1039758686 65 c 386/bin/hget - 775 sys sys 1039758563 101403
+1039758686 66 c 386/bin/history - 775 sys sys 1039758564 71183
+1039758686 67 c 386/bin/htmlfmt - 775 sys sys 1039758564 158912
+1039758686 68 c 386/bin/iconv - 775 sys sys 1039758564 112738
+1039758686 69 c 386/bin/idiff - 775 sys sys 1039758565 75492
+1039758686 70 c 386/bin/lnfs - 775 sys sys 1039758574 100756
+1039758686 71 c 386/bin/nntpfs - 775 sys sys 1039758580 159773
+1039758686 72 c 386/bin/pipefile - 775 sys sys 1039758581 39893
+1039758686 73 c 386/bin/png - 775 sys sys 1039758582 157728
+1039758686 74 c 386/bin/replica/applychanges - 775 sys sys 1039758585 99044
+1039758686 75 c 386/bin/replica/applylog - 775 sys sys 1039758585 98429
+1039758686 76 c 386/bin/replica/compactdb - 775 sys sys 1039758586 77913
+1039758686 77 c 386/bin/replica/updatedb - 775 sys sys 1039758586 95939
+1039758686 78 c 386/bin/resample - 775 sys sys 1039758586 120283
+1039758686 79 c 386/bin/rtstats - 775 sys sys 1039758587 174824
+1039758686 80 c 386/bin/sha1sum - 775 sys sys 1039758589 59581
+1039758686 81 c 386/bin/snap - 775 sys sys 1039758590 288721
+1039758686 82 c 386/bin/snapfs - 775 sys sys 1039758591 357433
+1039758686 83 c 386/bin/srvold9p - 775 sys sys 1039758592 130502
+1039758686 84 c 386/bin/topng - 775 sys sys 1039758597 137880
+1039758686 85 c 386/bin/troff2html - 775 sys sys 1039758598 81032
+1039758686 86 c 386/bin/unzip - 775 sys sys 1039758599 90042
+1039758686 87 c 386/bin/usb/usbaudio - 775 sys sys 1039758606 173005
+1039758686 88 c 386/bin/usb/usbd - 775 sys sys 1039758606 121266
+1039758686 89 c 386/bin/usb/usbmouse - 775 sys sys 1039758606 136659
+1039758686 90 c 386/bin/venti/buildindex - 775 sys sys 1039758608 178668
+1039758686 91 c 386/bin/venti/checkarenas - 775 sys sys 1039758608 181667
+1039758686 92 c 386/bin/venti/checkindex - 775 sys sys 1039758608 179486
+1039758686 93 c 386/bin/venti/clumpstats - 775 sys sys 1039758609 168683
+1039758686 94 a 386/bin/venti/copy - 775 sys sys 1039758609 106664
+1039758686 95 c 386/bin/venti/findscore - 775 sys sys 1039758609 153272
+1039758686 96 c 386/bin/venti/fmtarenas - 775 sys sys 1039758609 154075
+1039758686 97 c 386/bin/venti/fmtindex - 775 sys sys 1039758610 168346
+1039758686 98 c 386/bin/venti/fmtisect - 775 sys sys 1039758610 168930
+1039758686 99 c 386/bin/venti/rdarena - 775 sys sys 1039758610 153014
+1039758686 100 c 386/bin/venti/read - 775 sys sys 1039758611 103030
+1039758686 101 c 386/bin/venti/sync - 775 sys sys 1039758611 102180
+1039758686 102 c 386/bin/venti/syncindex - 775 sys sys 1039758611 193823
+1039758686 103 c 386/bin/venti/venti - 775 sys sys 1039758612 248414
+1039758686 104 c 386/bin/venti/verifyarena - 775 sys sys 1039758612 127738
+1039758686 105 c 386/bin/venti/wrarena - 775 sys sys 1039758612 181345
+1039758686 106 c 386/bin/venti/write - 775 sys sys 1039758613 102982
+1039758686 107 c 386/bin/vncs - 775 sys sys 1039758613 440826
+1039758686 108 c 386/bin/vncv - 775 sys sys 1039758614 174057
+1039758686 109 c 386/bin/webcookies - 775 sys sys 1039758615 159686
+1039758686 110 c 386/bin/wikifs - 775 sys sys 1039758616 194294
+1039758686 111 c 386/bin/zip - 775 sys sys 1039758617 89314
+1039758686 112 c 386/bin/file - 775 sys sys 1039758559 117145
+1039758686 113 c 386/bin/fmt - 775 sys sys 1039758560 63811
+1039758686 114 c 386/bin/fortune - 775 sys sys 1039758560 66329
+1039758686 115 c 386/bin/freq - 775 sys sys 1039758560 60443
+1039758686 116 c 386/bin/ftpfs - 775 sys sys 1039758562 148301
+1039758686 117 c 386/bin/gif - 775 sys sys 1039758562 155652
+1039758686 118 c 386/bin/graph - 775 sys sys 1039758563 127337
+1039758686 119 c 386/bin/grep - 775 sys sys 1039758563 77890
+1039758686 120 c 386/bin/hayes - 775 sys sys 1039758563 63552
+1039758686 121 c 386/bin/hoc - 775 sys sys 1039758564 98955
+1039758686 122 c 386/bin/html2ms - 775 sys sys 1039758564 64730
+1039758686 123 c 386/bin/import - 775 sys sys 1039758565 87315
+1039758686 124 c 386/bin/iostats - 775 sys sys 1039758565 98800
+1039758686 125 c 386/bin/join - 775 sys sys 1039758572 114412
+1039758686 126 c 386/bin/jpg - 775 sys sys 1039758573 172380
+1039758686 127 c 386/bin/kprof - 775 sys sys 1039758573 101896
+1039758686 128 c 386/bin/ktrace - 775 sys sys 1039758573 115126
+1039758686 129 c 386/bin/lens - 775 sys sys 1039758573 122362
+1039758686 130 c 386/bin/lex - 775 sys sys 1039758573 97530
+1039758686 131 c 386/bin/look - 775 sys sys 1039758574 64460
+1039758686 132 c 386/bin/ls - 775 sys sys 1039758574 78970
+1039758686 133 c 386/bin/mc - 775 sys sys 1039758574 128609
+1039758686 134 c 386/bin/md5sum - 775 sys sys 1039758574 59713
+1039758686 135 c 386/bin/mk - 775 sys sys 1039758575 141369
+1039758686 136 c 386/bin/mkdir - 775 sys sys 1039758575 57836
+1039758686 137 c 386/bin/mount - 775 sys sys 1039758576 71032
+1039758686 138 c 386/bin/ms2html - 775 sys sys 1039758576 100101
+1039758686 139 c 386/bin/mv - 775 sys sys 1039758576 64993
+1039758686 140 c 386/bin/netkey - 775 sys sys 1039758579 70753
+1039758686 141 c 386/bin/netstat - 775 sys sys 1039758579 81376
+1039758686 142 c 386/bin/news - 775 sys sys 1039758579 70506
+1039758686 143 c 386/bin/nm - 775 sys sys 1039758580 123224
+1039758686 144 c 386/bin/ns - 775 sys sys 1039758580 63830
+1039758686 145 c 386/bin/p - 775 sys sys 1039758580 63746
+1039758686 146 c 386/bin/page - 775 sys sys 1039758581 214018
+1039758686 147 c 386/bin/passwd - 775 sys sys 1039758581 81058
+1039758686 148 c 386/bin/pcc - 775 sys sys 1039758581 66189
+1039758686 149 c 386/bin/plot - 775 sys sys 1039758582 216945
+1039758686 150 c 386/bin/plumb - 775 sys sys 1039758582 65473
+1039758686 151 c 386/bin/plumber - 775 sys sys 1039758582 169206
+1039758686 152 c 386/bin/ppm - 775 sys sys 1039758583 146744
+1039758686 153 c 386/bin/pr - 775 sys sys 1039758583 76437
+1039758686 154 c 386/bin/primes - 775 sys sys 1039758583 39290
+1039758686 155 c 386/bin/prof - 775 sys sys 1039758583 106372
+1039758686 156 c 386/bin/proof - 775 sys sys 1039758584 173099
+1039758686 157 c 386/bin/ps - 775 sys sys 1039758584 64633
+1039758686 158 c 386/bin/pwd - 775 sys sys 1039758584 37188
+1039758686 159 c 386/bin/ramfs - 775 sys sys 1039758584 89906
+1039758686 160 c 386/bin/rc - 775 sys sys 1039758584 139862
+1039758686 161 c 386/bin/rdbfs - 775 sys sys 1039758585 166622
+1039758686 162 c 386/bin/read - 775 sys sys 1039758585 56544
+1039758686 163 c 386/bin/rio - 775 sys sys 1039758587 300600
+1039758686 164 c 386/bin/rm - 775 sys sys 1039758587 60033
+1039758686 165 c 386/bin/rx - 775 sys sys 1039758587 78434
+1039758686 166 c 386/bin/sam - 775 sys sys 1039758588 156892
+1039758686 167 c 386/bin/scat - 775 sys sys 1039758588 277448
+1039758686 168 c 386/bin/scp - 775 sys sys 1039758589 159535
+1039758686 169 c 386/bin/scuzz - 775 sys sys 1039758589 110998
+1039758686 170 c 386/bin/sed - 775 sys sys 1039758589 88430
+1039758686 171 c 386/bin/seq - 775 sys sys 1039758589 38817
+1039758686 172 c 386/bin/size - 775 sys sys 1039758589 76292
+1039758686 173 c 386/bin/snoopy - 775 sys sys 1039758591 152394
+1039758686 174 c 386/bin/sort - 775 sys sys 1039758591 81296
+1039758686 175 c 386/bin/split - 775 sys sys 1039758591 74227
+1039758686 176 c 386/bin/srv - 775 sys sys 1039758591 80150
+1039758686 177 c 386/bin/srvfs - 775 sys sys 1039758592 39914
+1039758686 178 c 386/bin/ssh - 775 sys sys 1039758592 209655
+1039758686 179 c 386/bin/stats - 775 sys sys 1039758593 184849
+1039758686 180 c 386/bin/strings - 775 sys sys 1039758593 60879
+1039758686 181 c 386/bin/strip - 775 sys sys 1039758593 60826
+1039758686 182 c 386/bin/sum - 775 sys sys 1039758593 40355
+1039758686 183 c 386/bin/swap - 775 sys sys 1039758594 60844
+1039758686 184 c 386/bin/vtdump - 775 sys sys 1039758615 163138
+1039758686 185 c 386/bin/webfs - 775 sys sys 1039758616 342496
+1039758686 186 c 386/bin/winwatch - 775 sys sys 1039758616 139473
+1039758686 187 c 386/bin/ape/cc - 775 sys sys 1039758529 68927
+1039758686 188 c 386/bin/ape/stty - 775 sys sys 1039758529 41577
+1039758686 189 c 386/bin/ape/tar - 775 sys sys 1039758529 60413
+1039758686 190 c 386/bin/auth/aescbc - 775 sys sys 1039758531 120944
+1039758686 191 c 386/bin/auth/authsrv - 775 sys sys 1039758531 162132
+1039758686 192 c 386/bin/auth/changeuser - 775 sys sys 1039758531 96022
+1039758686 193 c 386/bin/auth/convkeys - 775 sys sys 1039758531 84013
+1039758686 194 c 386/bin/auth/convkeys2 - 775 sys sys 1039758532 84033
+1039758686 195 c 386/bin/auth/cron - 775 sys sys 1039758532 139996
+1039758686 196 c 386/bin/auth/debug - 775 sys sys 1039758532 100413
+1039758686 197 c 386/bin/auth/factotum - 775 sys sys 1039758533 300772
+1039758686 198 c 386/bin/auth/fgui - 775 sys sys 1039758533 210904
+1039758686 199 c 386/bin/auth/guard.srv - 775 sys sys 1039758533 139814
+1039758686 200 c 386/bin/auth/iam - 775 sys sys 1039758534 51077
+1039758686 201 c 386/bin/auth/keyfs - 775 sys sys 1039758534 114307
+1039758686 202 c 386/bin/auth/login - 775 sys sys 1039758534 99385
+1039758686 203 c 386/bin/auth/printnetkey - 775 sys sys 1039758534 40969
+1039758686 204 c 386/bin/auth/secretpem - 775 sys sys 1039758534 118523
+1039758686 205 c 386/bin/auth/secstore - 775 sys sys 1039758535 178992
+1039758686 206 c 386/bin/auth/secstored - 775 sys sys 1039758535 192870
+1039758686 207 c 386/bin/auth/secuser - 775 sys sys 1039758535 149280
+1039758686 208 c 386/bin/auth/uniq - 775 sys sys 1039758536 61773
+1039758686 209 c 386/bin/auth/warning - 775 sys sys 1039758536 97723
+1039758686 210 c 386/bin/auth/wrkey - 775 sys sys 1039758536 71296
+1039758686 211 c 386/bin/aux/9pcon - 775 sys sys 1039758536 96151
+1039758686 212 c 386/bin/aux/LOCK - 775 sys sys 1039758536 58689
+1039758686 213 c 386/bin/aux/X509gen - 775 sys sys 1039758537 126402
+1039758686 214 c 386/bin/aux/accupoint - 775 sys sys 1039758537 41111
+1039758686 215 c 386/bin/aux/acidleak - 775 sys sys 1039758537 67904
+1039758686 216 c 386/bin/aux/apm - 775 sys sys 1039758537 171807
+1039758686 217 c 386/bin/aux/astarld - 775 sys sys 1039758537 63522
+1039758686 218 c 386/bin/aux/cddb - 775 sys sys 1039758537 70432
+1039758686 219 c 386/bin/aux/clog - 775 sys sys 1039758538 65408
+1039758686 220 c 386/bin/aux/consolefs - 775 sys sys 1039758538 152994
+1039758686 221 c 386/bin/aux/data2s - 775 sys sys 1039758538 59178
+1039758686 222 c 386/bin/aux/depend - 775 sys sys 1039758538 145132
+1039758686 223 c 386/bin/aux/disksim - 775 sys sys 1039758539 142703
+1039758686 224 c 386/bin/aux/faxreceive - 775 sys sys 1039758539 83418
+1039758686 225 c 386/bin/aux/faxsend - 775 sys sys 1039758539 88816
+1039758686 226 c 386/bin/aux/flashfs - 775 sys sys 1039758539 158578
+1039758686 227 c 386/bin/aux/g3p9bit - 775 sys sys 1039758539 65837
+1039758686 228 c 386/bin/aux/getflags - 775 sys sys 1039758540 44343
+1039758686 229 c 386/bin/aux/lines - 775 sys sys 1039758540 59152
+1039758686 230 c 386/bin/aux/listen - 775 sys sys 1039758540 104208
+1039758686 231 c 386/bin/aux/listen1 - 775 sys sys 1039758540 91094
+1039758686 232 c 386/bin/aux/lpsend - 775 sys sys 1039758540 53107
+1039758686 233 c 386/bin/aux/mapd - 775 sys sys 1039758541 190944
+1039758686 234 c 386/bin/aux/mkflashfs - 775 sys sys 1039758541 66240
+1039758686 235 c 386/bin/aux/mklatinkbd - 775 sys sys 1039758541 62863
+1039758686 236 c 386/bin/aux/mnihongo - 775 sys sys 1039758541 134897
+1039758686 237 c 386/bin/aux/mouse - 775 sys sys 1039758541 44473
+1039758686 238 c 386/bin/aux/ms2 - 775 sys sys 1039758542 84047
+1039758686 239 c 386/bin/aux/mswordstrings - 775 sys sys 1039758542 64268
+1039758686 240 c 386/bin/aux/na - 775 sys sys 1039758542 152747
+1039758686 241 c 386/bin/aux/nfsserver - 775 sys sys 1039758542 171424
+1039758686 242 c 386/bin/aux/olefs - 775 sys sys 1039758543 142400
+1039758686 243 c 386/bin/aux/p9bitpost - 775 sys sys 1039758543 127979
+1039758686 244 c 386/bin/aux/pcmcia - 775 sys sys 1039758543 46790
+1039758686 245 c 386/bin/aux/pcnfsd - 775 sys sys 1039758543 127219
+1039758686 246 c 386/bin/aux/portmapper - 775 sys sys 1039758544 126116
+1039758686 247 c 386/bin/aux/rdwr - 775 sys sys 1039758544 38800
+1039758686 248 c 386/bin/aux/reboot - 775 sys sys 1039758544 59049
+1039758686 249 c 386/bin/aux/samterm - 775 sys sys 1039758544 242240
+1039758686 250 c 386/bin/aux/searchfs - 775 sys sys 1039758545 90974
+1039758686 251 c 386/bin/aux/sprog - 775 sys sys 1039758545 77768
+1039758686 252 c 386/bin/aux/ssh_genkey - 775 sys sys 1039758545 194580
+1039758686 253 c 386/bin/aux/sshserve - 775 sys sys 1039758546 246497
+1039758686 254 c 386/bin/aux/stub - 775 sys sys 1039758546 133120
+1039758686 255 c 386/bin/aux/text2post - 775 sys sys 1039758546 77253
+1039758686 256 c 386/bin/aux/timesync - 775 sys sys 1039758546 125710
+1039758686 257 c 386/bin/aux/tr2post - 775 sys sys 1039758547 175495
+1039758686 258 c 386/bin/aux/trampoline - 775 sys sys 1039758547 81154
+1039758686 259 c 386/bin/aux/typepasswd - 775 sys sys 1039758547 68151
+1039758686 260 c 386/bin/aux/vga - 775 sys sys 1039758547 299452
+1039758686 261 c 386/bin/disk/dump9660 - 775 sys sys 1039758555 151486
+1039758686 262 c 386/bin/disk/exsort - 775 sys sys 1039758556 58789
+1039758686 263 c 386/bin/disk/fdisk - 775 sys sys 1039758556 106823
+1039758686 264 c 386/bin/disk/format - 775 sys sys 1039758556 91866
+1039758686 265 c 386/bin/disk/kfs - 775 sys sys 1039758556 247140
+1039758686 266 c 386/bin/disk/kfscmd - 775 sys sys 1039758557 38719
+1039758686 267 c 386/bin/disk/mbr - 775 sys sys 1039758557 72334
+1039758686 268 c 386/bin/disk/mkext - 775 sys sys 1039758557 77815
+1039758686 269 c 386/bin/disk/mkfs - 775 sys sys 1039758557 87444
+1039758686 270 c 386/bin/disk/prep - 775 sys sys 1039758557 98783
+1039758686 271 c 386/bin/execnet - 775 sys sys 1039758558 168262
+1039758686 272 c 386/bin/ip/dhcpclient - 775 sys sys 1039758565 91652
+1039758686 273 c 386/bin/ip/dhcpd - 775 sys sys 1039758566 144971
+1039758686 274 c 386/bin/ip/dhcpleases - 775 sys sys 1039758566 84655
+1039758686 275 c 386/bin/ip/ftpd - 775 sys sys 1039758566 166832
+1039758686 276 c 386/bin/ip/gping - 775 sys sys 1039758567 178125
+1039758686 277 c 386/bin/ip/hogports - 775 sys sys 1039758567 43296
+1039758686 278 c 386/bin/ip/httpd/httpd - 775 sys sys 1039758567 283575
+1039758686 279 c 386/bin/ip/httpd/imagemap - 775 sys sys 1039758568 113595
+1039758686 280 c 386/bin/ip/httpd/man2html - 775 sys sys 1039758568 121860
+1039758686 281 c 386/bin/ip/httpd/save - 775 sys sys 1039758568 130924
+1039758686 282 c 386/bin/ip/httpd/wikipost - 775 sys sys 1039758568 111282
+1039758686 283 c 386/bin/ip/imap4d - 775 sys sys 1039758569 232588
+1039758686 284 c 386/bin/ip/ipconfig - 775 sys sys 1039758569 103748
+1039758686 285 c 386/bin/ip/ping - 775 sys sys 1039758569 74005
+1039758686 286 c 386/bin/ip/ppp - 775 sys sys 1039758570 211448
+1039758686 287 c 386/bin/ip/pppoe - 775 sys sys 1039758570 75475
+1039758686 288 c 386/bin/ip/pptp - 775 sys sys 1039758570 122528
+1039758686 289 c 386/bin/ip/pptpd - 775 sys sys 1039758570 123584
+1039758686 290 c 386/bin/ip/rarpd - 775 sys sys 1039758571 107218
+1039758686 291 c 386/bin/ip/rexexec - 775 sys sys 1039758571 86656
+1039758686 292 c 386/bin/ip/rip - 775 sys sys 1039758571 89757
+1039758686 293 c 386/bin/ip/rlogind - 775 sys sys 1039758571 66384
+1039758686 294 c 386/bin/ip/telnetd - 775 sys sys 1039758571 120147
+1039758686 295 c 386/bin/ip/tftpd - 775 sys sys 1039758572 102536
+1039758686 296 c 386/bin/ip/traceroute - 775 sys sys 1039758572 70850
+1039758686 297 c 386/bin/ip/udpecho - 775 sys sys 1039758572 43540
+1039758686 298 c 386/bin/mkpaqfs - 775 sys sys 1039758575 93491
+1039758686 299 c 386/bin/mkstate - 775 sys sys 1039758575 62173
+1039758686 300 c 386/bin/mntgen - 775 sys sys 1039758575 133926
+1039758686 301 c 386/bin/mtime - 775 sys sys 1039758576 57875
+1039758686 302 c 386/bin/ndb/cs - 775 sys sys 1039758576 143184
+1039758686 303 c 386/bin/ndb/csquery - 775 sys sys 1039758577 60136
+1039758686 304 c 386/bin/ndb/dns - 775 sys sys 1039758577 210800
+1039758686 305 c 386/bin/ndb/dnsdebug - 775 sys sys 1039758577 185793
+1039758686 306 c 386/bin/ndb/dnsquery - 775 sys sys 1039758578 62442
+1039758686 307 c 386/bin/ndb/dnstcp - 775 sys sys 1039758578 184617
+1039758686 308 c 386/bin/ndb/ipquery - 775 sys sys 1039758578 91675
+1039758686 309 c 386/bin/ndb/mkdb - 775 sys sys 1039758578 62632
+1039758686 310 c 386/bin/ndb/mkhash - 775 sys sys 1039758578 82288
+1039758686 311 c 386/bin/ndb/mkhosts - 775 sys sys 1039758579 83235
+1039758686 312 c 386/bin/ndb/query - 775 sys sys 1039758579 81033
+1039758686 313 c 386/bin/paqfs - 775 sys sys 1039758581 108073
+1039758686 314 c 386/bin/sshnet - 775 sys sys 1039758593 281010
+1039758686 315 c 386/bin/syscall - 775 sys sys 1039758594 72631
+1039758686 316 c 386/bin/tail - 775 sys sys 1039758594 64882
+1039758686 317 c 386/bin/tar - 775 sys sys 1039758594 81322
+1039758686 318 c 386/bin/tbl - 775 sys sys 1039758594 111800
+1039758686 319 c 386/bin/tcs - 775 sys sys 1039758595 278428
+1039758686 320 c 386/bin/tee - 775 sys sys 1039758595 38926
+1039758686 321 c 386/bin/telco - 775 sys sys 1039758595 105055
+1039758686 322 c 386/bin/telnet - 775 sys sys 1039758595 80800
+1039758686 323 c 386/bin/test - 775 sys sys 1039758595 63910
+1039758686 324 c 386/bin/time - 775 sys sys 1039758596 59810
+1039758686 325 c 386/bin/tlsclient - 775 sys sys 1039758596 191851
+1039758686 326 c 386/bin/tlssrv - 775 sys sys 1039758596 192216
+1039758686 327 c 386/bin/togif - 775 sys sys 1039758597 188561
+1039758686 328 c 386/bin/toppm - 775 sys sys 1039758597 163998
+1039758686 329 c 386/bin/touch - 775 sys sys 1039758597 63209
+1039758686 330 c 386/bin/tprof - 775 sys sys 1039758598 273463
+1039758686 331 c 386/bin/tr - 775 sys sys 1039758598 60540
+1039758686 332 c 386/bin/tweak - 775 sys sys 1039758598 188803
+1039758686 333 c 386/bin/unicode - 775 sys sys 1039758599 61093
+1039758686 334 c 386/bin/uniq - 775 sys sys 1039758599 60560
+1039758686 335 c 386/bin/units - 775 sys sys 1039758599 73879
+1039758686 336 c 386/bin/unmount - 775 sys sys 1039758599 37108
+1039758686 337 c 386/bin/upas/aliasmail - 775 sys sys 1039758599 100876
+1039758686 338 c 386/bin/upas/deliver - 775 sys sys 1039758599 68805
+1039758686 339 c 386/bin/upas/filter - 775 sys sys 1039758600 145556
+1039758686 340 c 386/bin/upas/fs - 775 sys sys 1039758600 326172
+1039758686 341 c 386/bin/upas/list - 775 sys sys 1039758601 81422
+1039758686 342 c 386/bin/upas/marshal - 775 sys sys 1039758601 126720
+1039758686 343 c 386/bin/upas/ml - 775 sys sys 1039758601 118090
+1039758686 344 c 386/bin/upas/mlmgr - 775 sys sys 1039758601 100861
+1039758686 345 c 386/bin/upas/mlowner - 775 sys sys 1039758602 92131
+1039758686 346 c 386/bin/upas/nedmail - 775 sys sys 1039758602 147378
+1039758686 347 c 386/bin/upas/pop3 - 775 sys sys 1039758602 251568
+1039758686 348 c 386/bin/upas/qer - 775 sys sys 1039758603 98517
+1039758686 349 c 386/bin/upas/ratfs - 775 sys sys 1039758603 112389
+1039758686 350 c 386/bin/upas/runq - 775 sys sys 1039758603 111302
+1039758686 351 c 386/bin/upas/scanmail - 775 sys sys 1039758603 126508
+1039758686 352 c 386/bin/upas/send - 775 sys sys 1039758604 188619
+1039758686 353 c 386/bin/upas/smtp - 775 sys sys 1039758604 264699
+1039758686 354 c 386/bin/upas/smtpd - 775 sys sys 1039758605 199198
+1039758686 355 c 386/bin/upas/testscan - 775 sys sys 1039758605 82381
+1039758686 356 c 386/bin/upas/token - 775 sys sys 1039758605 76178
+1039758686 357 c 386/bin/upas/vf - 775 sys sys 1039758605 90529
+1039758686 358 c 386/bin/vac - 775 sys sys 1039758607 173522
+1039758686 359 c 386/bin/vacfs - 775 sys sys 1039758607 179723
+1039758686 360 c 386/bin/vt - 775 sys sys 1039758614 169349
+1039758686 361 c 386/bin/wc - 775 sys sys 1039758615 42416
+1039758686 362 c 386/bin/xd - 775 sys sys 1039758616 62802
+1039758686 363 c 386/bin/xmr - 775 sys sys 1039758616 40652
+1039758686 364 c 386/bin/xms - 775 sys sys 1039758617 41233
+1039758686 365 c 386/bin/yacc - 775 sys sys 1039758617 100850
+1039758686 366 c 386/lib/libc.a - 664 sys sys 1039758626 496612
+1039758686 367 c 386/lib/libcontrol.a - 664 sys sys 1039758627 243294
+1039758686 368 c 386/lib/libdraw.a - 664 sys sys 1039758627 360966
+1039758686 369 c 386/lib/libframe.a - 664 sys sys 1039758628 65832
+1039758686 370 c 386/lib/libgeometry.a - 664 sys sys 1039758628 50806
+1039758686 371 c 386/lib/libhtml.a - 664 sys sys 1039758628 220944
+1039758686 372 c 386/lib/libmemdraw.a - 664 sys sys 1039758629 292324
+1039758686 373 c 386/lib/libmemlayer.a - 664 sys sys 1039758629 47116
+1039758686 374 c 386/lib/libplumb.a - 664 sys sys 1039758629 19000
+1039758686 375 c 386/lib/libscribble.a - 664 sys sys 1039758629 108138
+1039761098 0 c sys/man/2/print - 664 sys sys 1039759892 8890
+1039762899 0 c 386/init - 775 sys sys 1039762724 97616
+1039763807 0 c 386/9pcdisk - 775 sys sys 1039763781 1966876
+1039763807 1 c 386/9pcdisk.gz - 664 sys sys 1039763783 695837
+1039763807 2 c sys/src/9/boot/bootauth.c - 664 sys sys 1039763726 1097
+1039763807 3 c sys/src/9/boot/bootcache.c - 664 sys sys 1039763729 1518
+1039763807 4 c sys/src/9/boot/bootip.c - 664 sys sys 1039763724 3383
+1039763807 5 c sys/src/9/boot/embed.c - 664 sys sys 1039763720 1191
+1039763807 6 c sys/src/9/boot/local.c - 664 sys sys 1039763718 2041
+1039763807 7 c sys/src/9/boot/paq.c - 664 sys sys 1039763722 1099
+1039763807 8 a sys/src/9/boot/testboot.c - 664 sys sys 1039763734 496
+1039764701 0 a 386/_9pcdisk.gz - 664 sys sys 1039764191 695837
+1039764701 1 c sys/src/9/pc/pcdisk - 664 sys sys 1039764711 1369
+1039764868 0 c 386/9pc - 775 sys sys 1039764767 1783420
+1039764868 1 c 386/9pc.gz - 664 sys sys 1039764768 614091
+1039764868 2 c 386/9pccpu - 775 sys sys 1039764770 1429714
+1039764868 3 c 386/9pccpu.gz - 664 sys sys 1039764771 498997
+1039764868 4 c 386/9pcdisk - 775 sys sys 1039764751 1987341
+1039764868 5 c 386/9pcdisk.gz - 664 sys sys 1039764747 703133
+1039766123 0 c 386/9pcdisk - 775 sys sys 1039766107 1987341
+1039766123 1 c 386/9pcdisk.gz - 664 sys sys 1039766104 703132
+1039768304 0 c sys/src/cmd/vnc/kbd_vwr.c - 664 sys sys 1039767358 2361

+ 2 - 0
sys/include/draw.h

@@ -102,6 +102,8 @@ enum
 	DoverS	= DinS|DoutS|SoutD,
 	DatopS	= DinS|SoutD,
 	DxorS	= DoutS|SoutD,	/* == SxorD */
+
+	Ncomp = 12,
 };
 
 /*

+ 11 - 10
sys/include/memdraw.h

@@ -100,6 +100,7 @@ struct	Memdrawparam
 	Rectangle sr;
 	Memimage *mask;
 	Rectangle mr;
+	int op;
 
 	ulong state;
 	ulong mval;	/* if Simplemask, the mask pixel in mask format */
@@ -131,18 +132,18 @@ extern int		memsetchan(Memimage*, ulong);
 /*
  * Graphics
  */
-extern void	memdraw(Memimage*, Rectangle, Memimage*, Point, Memimage*, Point);
-extern void	memline(Memimage*, Point, Point, int, int, int, Memimage*, Point);
-extern void	mempoly(Memimage*, Point*, int, int, int, int, Memimage*, Point);
-extern void	memfillpoly(Memimage*, Point*, int, int, Memimage*, Point);
-extern void	_memfillpolysc(Memimage*, Point*, int, int, Memimage*, Point, int, int, int);
-extern void	memimagedraw(Memimage*, Rectangle, Memimage*, Point, Memimage*, Point);
+extern void	memdraw(Memimage*, Rectangle, Memimage*, Point, Memimage*, Point, int);
+extern void	memline(Memimage*, Point, Point, int, int, int, Memimage*, Point, int);
+extern void	mempoly(Memimage*, Point*, int, int, int, int, Memimage*, Point, int);
+extern void	memfillpoly(Memimage*, Point*, int, int, Memimage*, Point, int);
+extern void	_memfillpolysc(Memimage*, Point*, int, int, Memimage*, Point, int, int, int, int);
+extern void	memimagedraw(Memimage*, Rectangle, Memimage*, Point, Memimage*, Point, int);
 extern int	hwdraw(Memdrawparam*);
-extern void	memimageline(Memimage*, Point, Point, int, int, int, Memimage*, Point);
-extern void	_memimageline(Memimage*, Point, Point, int, int, int, Memimage*, Point, Rectangle);
+extern void	memimageline(Memimage*, Point, Point, int, int, int, Memimage*, Point, int);
+extern void	_memimageline(Memimage*, Point, Point, int, int, int, Memimage*, Point, Rectangle, int);
 extern Point	memimagestring(Memimage*, Point, Memimage*, Point, Memsubfont*, char*);
-extern void	memellipse(Memimage*, Point, int, int, int, Memimage*, Point);
-extern void	memarc(Memimage*, Point, int, int, int, Memimage*, Point, int, int);
+extern void	memellipse(Memimage*, Point, int, int, int, Memimage*, Point, int);
+extern void	memarc(Memimage*, Point, int, int, int, Memimage*, Point, int, int, int);
 extern Rectangle	memlinebbox(Point, Point, int, int, int);
 extern int	memlineendsize(int);
 extern void	_memmkcmap(void);

+ 7 - 1
sys/man/2/print

@@ -328,7 +328,7 @@ conversions, trailing zeros are not removed.
 .PP
 The
 .B s
-verb copies a string
+verb copies a nul-terminated string
 (pointer to
 .BR char )
 to the output.
@@ -342,6 +342,12 @@ These
 characters are justified within a field of
 .I width
 characters as described above.
+If a
+.I precision
+is given, it is safe for the string not to be nul-terminated
+as long as it is at least
+.I precision
+characters (not bytes!) long.
 The
 .B S
 verb is similar, but it interprets its pointer as an array

+ 52 - 6
sys/man/8/ventiaux

@@ -3,6 +3,7 @@
 buildindex,
 checkarenas,
 checkindex,
+copy,
 fmtarenas,
 fmtindex,
 fmtisect,
@@ -40,6 +41,17 @@ write \- Venti maintenance and debugging commands
 .I venti.config
 .I tmp
 .PP
+.B venti/copy
+[
+.B -f
+]
+.I src
+.I dst
+.I score
+[
+.I type
+]
+.PP
 .B venti/fmtarenas
 [
 .B -Z
@@ -83,11 +95,10 @@ write \- Venti maintenance and debugging commands
 .B -h
 .I host
 ]
+.I score
 [
-.B -t
 .I type
 ]
-.I score
 .PP
 .B venti/wrarena
 [
@@ -391,9 +402,7 @@ of which arenas have been processed.)
 .I Read
 and
 .I write
-interact with a running
-Venti
-server rather than access the data directly.
+read and write blocks from a running Venti server.
 They are intended to ease debugging of the server.
 The default
 .I host
@@ -403,7 +412,20 @@ followed by the network metaname
 .BR $venti .
 The
 .I type
-sets the block type to read or write; it is a decimal number.
+is the decimal type of block to be read or written.
+If no 
+.I type
+is specified for
+.I read ,
+all types are tried, and a command-line is printed to
+show the type that eventually worked.
+If no
+.I type
+is specified for
+.I write ,
+.B VtDataType
+(13)
+is used.
 .I Read
 reads the block named by
 .I score
@@ -413,6 +435,30 @@ from the Venti server and writes it to standard output.
 reads a block from standard input and attempts to write
 it to the Venti server.
 If successful, it prints the score of the block on the server.
+.PP
+.I Copy
+walks the entire tree of blocks rooted at
+.I score ,
+copying all the blocks visited during the walk from
+the Venti server at network address
+.I src
+to the Venti server at network address
+.I dst .
+If
+.I type
+(a decimal block type for
+.IR score )
+is omitted, all types will be tried in sequence
+until one is found that works.
+The
+.B -f
+flag runs the copy in ``fast'' mode: if a block is already on
+.IR dst ,
+the walk does not descend below it, on the assumption that all its
+children are also already on
+.IR dst .
+Without this flag, the copy often transfers many times more
+data than necessary.
 .SH SOURCE
 .B /sys/src/cmd/venti
 .SH "SEE ALSO"

+ 6 - 4
sys/src/9/alphapc/apc

@@ -35,10 +35,6 @@ link
 misc
 	arch164
 
-	ipconfig.root
-	kfs.root
-	factotum.root
-
 	sdata		pci sdscsi
 	sd53c8xx	pci sdscsi
 
@@ -62,3 +58,9 @@ port
 
 boot
 	il
+
+bootdir
+	bootapc.out boot
+	/alpha/bin/disk/kfs
+	factotum.hack factotum
+	ipconfig.hack ipconfig

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

@@ -31,9 +31,6 @@ link
 misc
 	arch164
 
-	ipconfig.root
-	factotum.root
-
 	sdata		pci sdscsi
 	sd53c8xx	pci sdscsi
 
@@ -54,3 +51,9 @@ port
 
 boot cpu
 	il
+
+bootdir
+	bootapccpu.out boot
+	ipconfig.hack ipconfig
+	factotum.hack factotum
+

+ 40 - 4
sys/src/9/alphapc/devarch.c

@@ -401,13 +401,49 @@ PCArch archgeneric = {
 
 static char	*sysnames[] =
 {
-// [26]		"EB164",
-[26]		"AlphaPC 164",
+[1]		"Alpha Demo. Unit",
+[2]		"DEC 4000; Cobra",
+[3]		"DEC 7000; Ruby",
+[4]		"DEC 3000/500; Flamingo family (TC)",
+[6]		"DEC 2000/300; Jensen (EISA/ISA)",
+[7]		"DEC 3000/300; Pelican (TC)",
+[8]		"Avalon A12; Avalon Multicomputer",
+[9]		"DEC 2100/A500; Sable",
+[10]		"DEC APXVME/64; AXPvme (VME?)",
+[11]		"DEC AXPPCI/33; NoName (PCI/ISA)",
+[12]		"DEC 21000; TurboLaser (PCI/EISA)",
+[13]		"DEC 2100/A50; Avanti (PCI/ISA)",
+[14]		"DEC MUSTANG; Mustang",
+[15]		"DEC KN20AA; kn20aa (PCI/EISA)",
+[17]		"DEC 1000; Mikasa (PCI/ISA?)",
+[19]		"EB66; EB66 (PCI/ISA?)",		// DEC?
+[20]		"EB64P; EB64+ (PCI/ISA?)",		// DEC?
+[21]		"Alphabook1; Alphabook",
+[22]		"DEC 4100; Rawhide (PCI/EISA)",
+[23]		"DEC EV45/PBP; Lego",
+[24]		"DEC 2100A/A500; Lynx",
+[26]		"DEC AlphaPC 164",	// only supported one: "EB164 (PCI/ISA)"
+[27]		"DEC 1000A; Noritake",
+[28]		"DEC AlphaVME/224; Cortex",
+[30]		"DEC 550; Miata (PCI/ISA)",
+[32]		"DEC EV56/PBP; Takara",
+[33]		"DEC AlphaVME/320; Yukon (VME?)",
+[34]		"DEC 6600; MonetGoldrush",
+// 200 and up is Alpha Processor Inc. machines
+// [201]	"API UP1000; Nautilus",
 };
 
 static char	*cpunames[] =
 {
-[7]		"21164A",
+[1]		"EV3",
+[2]		"EV4: 21064",
+[3]		"Simulation",
+[4]		"LCA4: 2106[68]",
+[5]		"EV5: 21164",
+[6]		"EV45: 21064A",
+[7]		"21164A",		/* only supported one: EV56 */
+[8]		"EV6: 21264",
+[9]		"PCA256: 21164PC",
 };
 
 void
@@ -430,7 +466,7 @@ cpuidprint(void)
 		s = "<unknown>";
 		if (hwrpb->systype < nelem(sysnames))
 			s = sysnames[hwrpb->systype];
-		print("DEC %s (%llux, %llux, %llux)\n", s, hwrpb->systype, hwrpb->sysvar, hwrpb->sysrev);
+		print("%s (%llux, %llux, %llux)\n", s, hwrpb->systype, hwrpb->sysvar, hwrpb->sysrev);
 	}
 
 	for (i = 0; i < hwrpb->ncpu; i++) {

+ 57 - 19
sys/src/9/alphapc/devether.c

@@ -10,7 +10,7 @@
 
 #include "etherif.h"
 
-static Ether *etherxx[MaxEther];
+static volatile Ether *etherxx[MaxEther];
 
 Chan*
 etherattach(char* spec)
@@ -176,7 +176,8 @@ etheriq(Ether* ether, Block* bp, int fromwire)
 				else if(xbp = iallocb(len)){
 					memmove(xbp->wp, pkt, len);
 					xbp->wp += len;
-					qpass(f->in, xbp);
+					if(qpass(f->in, xbp) < 0)
+						ether->soverflows++;
 				}
 				else
 					ether->soverflows++;
@@ -239,21 +240,26 @@ etherwrite(Chan* chan, void* buf, long n, vlong)
 {
 	Ether *ether;
 	Block *bp;
+	int nn;
 
 	ether = etherxx[chan->dev];
-	if(NETTYPE(chan->qid.path) != Ndataqid){
-
+	if(NETTYPE(chan->qid.path) != Ndataqid) {
+		nn = netifwrite(ether, chan, buf, n);
+		if(nn >= 0)
+			return nn;
 		if(n == sizeof("nonblocking")-1 && strncmp((char*)buf, "nonblocking", n) == 0){
 			qnoblock(ether->oq, 1);
 			return n;
 		}
+		if(ether->ctl!=nil)
+			return ether->ctl(ether,buf,n);
 
-		return netifwrite(ether, chan, buf, n);
+		error(Ebadctl);
 	}
 
-	if(n > ETHERMAXTU)
+	if(n > ether->maxmtu)
 		error(Etoobig);
-	if(n < ETHERMINTU)
+	if(n < ether->minmtu)
 		error(Etoosmall);
 
 	bp = allocb(n);
@@ -276,18 +282,23 @@ etherbwrite(Chan* chan, Block* bp, ulong)
 	long n;
 
 	n = BLEN(bp);
-	ether = etherxx[chan->dev];
 	if(NETTYPE(chan->qid.path) != Ndataqid){
-		n = netifwrite(ether, chan, bp->rp, n);
+		if(waserror()) {
+			freeb(bp);
+			nexterror();
+		}
+		n = etherwrite(chan, bp->rp, n, 0);
+		poperror();
 		freeb(bp);
 		return n;
 	}
+	ether = etherxx[chan->dev];
 
-	if(n > ETHERMAXTU){
+	if(n > ether->maxmtu){
 		freeb(bp);
-		error(Ebadarg);
+		error(Etoobig);
 	}
-	if(n < ETHERMINTU){
+	if(n < ether->minmtu){
 		freeb(bp);
 		error(Etoosmall);
 	}
@@ -320,7 +331,7 @@ parseether(uchar *to, char *from)
 	int i;
 
 	p = from;
-	for(i = 0; i < 6; i++){
+	for(i = 0; i < Eaddrlen; i++){
 		if(*p == 0)
 			return -1;
 		nip[0] = *p++;
@@ -340,7 +351,7 @@ etherreset(void)
 {
 	Ether *ether;
 	int i, n, ctlrno;
-	char name[32], buf[128];
+	char name[32], buf[256];
 
 	for(ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++){
 		if(ether == 0)
@@ -359,9 +370,9 @@ etherreset(void)
 			for(i = 0; i < ether->nopt; i++){
 				if(strncmp(ether->opt[i], "ea=", 3))
 					continue;
-				if(parseether(ether->ea, &ether->opt[i][3]) == -1)
+				if(parseether(ether->ea, &ether->opt[i][3]))
 					memset(ether->ea, 0, Eaddrlen);
-			}	
+			}
 			if(cards[n].reset(ether))
 				break;
 
@@ -373,10 +384,17 @@ etherreset(void)
 			if(ether->irq == 2 && BUSTYPE(ether->tbdf) != BusPCI)
 				ether->irq = 9;
 			snprint(name, sizeof(name), "ether%d", ctlrno);
-			intrenable(ether->irq, ether->interrupt, ether, ether->tbdf, name);
+			/*
+			 * If ether->irq is 0, it is a hack to indicate no
+			 * interrupt used by ethersink.
+			 */
+			if(ether->irq > 0)
+				intrenable(ether->irq, ether->interrupt,
+					ether, ether->tbdf, name);
 
-			i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %lud",
-				ctlrno, ether->type, ether->mbps, ether->port, ether->irq);
+			i = sprint(buf, "#l%d (%s): %s: %dMbps port 0x%luX irq %lud",
+				ctlrno, name, ether->type, ether->mbps,
+				ether->port, ether->irq);
 			if(ether->mem)
 				i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem));
 			if(ether->size)
@@ -412,6 +430,26 @@ etherreset(void)
 		free(ether);
 }
 
+/* imported from ../pc; not ready for use yet */
+static void
+ethershutdown(void)
+{
+	Ether *ether;
+	int i;
+
+	for(i = 0; i < MaxEther; i++){
+		ether = etherxx[i];
+		if(ether == nil)
+			continue;
+		if(ether->shutdown == nil) {
+			print("#l%d: no shutdown fuction\n", i);
+			continue;
+		}
+		(*ether->shutdown)(ether);
+	}
+}
+
+
 #define POLY 0xedb88320
 
 /* really slow 32 bit crc for ethers */

+ 6 - 0
sys/src/9/alphapc/etherif.h

@@ -15,10 +15,15 @@ struct Ether {
 	uchar	ea[Eaddrlen];
 
 	void	(*attach)(Ether*);	/* filled in by reset routine */
+	void	(*detach)(Ether*);	/* NEW, from ../pc */
 	void	(*transmit)(Ether*);
 	void	(*interrupt)(Ureg*, void*);
 	long	(*ifstat)(Ether*, void*, long, ulong);
 	long 	(*ctl)(Ether*, void*, long); /* custom ctl messages */
+/* START NEW, from ../pc */
+	void	(*power)(Ether*, int);	/* power on/off */
+	void	(*shutdown)(Ether*);	/* shutdown hardware before reboot */
+/* END NEW */
 	void	*ctlr;
 
 	Queue*	oq;
@@ -29,6 +34,7 @@ struct Ether {
 extern Block* etheriq(Ether*, Block*, int);
 extern void addethercard(char*, int(*)(Ether*));
 extern ulong ethercrc(uchar*, int);
+extern int parseether(uchar*, char*);
 
 #define NEXT(x, l)	(((x)+1)%(l))
 #define PREV(x, l)	(((x) == 0) ? (l)-1: (x)-1)

+ 3 - 2
sys/src/9/alphapc/initcode

@@ -41,6 +41,7 @@ TEXT	exec(SB), $0
 	RET
 
 DATA	boot+0(SB)/5,$"/boot"
-DATA	bootv+0(SB)/4,$boot+1(SB)
-GLOBL	boot+0(SB),$6
+DATA	boot+5(SB)/5,$"/boot"
+DATA	bootv+0(SB)/4,$boot+6(SB)
+GLOBL	boot+0(SB),$11
 GLOBL	bootv+0(SB),$8

+ 151 - 14
sys/src/9/alphapc/main.c

@@ -32,6 +32,7 @@ options(void)
 	cp = bootargs;
 	strncpy(cp, bootconf->bootargs, BOOTARGSLEN);
 	cp[BOOTARGSLEN-1] = 0;
+	/* can't print in this routine, see below in main() */
 
 	/*
 	 * Strip out '\r', change '\t' -> ' '.
@@ -60,6 +61,18 @@ options(void)
 	}
 }
 
+/* debugging only */
+static void
+dumpopts(void)
+{
+	int i;
+
+	print("dumpopts: found /alpha/conf options at 0x%lux\n",
+		bootconf->bootargs);
+	for(i = 0; i < nconf; i++)
+		print("dumpopts: read %s=%s\n", confname[i], confval[i]);
+}
+
 void
 main(void)
 {
@@ -80,6 +93,8 @@ main(void)
 	trapinit();
 	screeninit();
 	printinit();
+	/* it's now safe to print */
+	/* dumpopts();			/* DEBUG */
 	kbdinit();
 	i8250console();
 	quotefmtinstall();
@@ -102,6 +117,26 @@ initfp.fpstatus = 0x68028000;
 	schedinit();
 }
 
+/* cpu->state bits */
+enum {
+	Cpubootinprog	= 1,	/* boot in progress */
+	Cpucanrestart	= 2,	/* restart possible */
+	Cpuavail	= 4,	/* processor available */
+	Cpuexists 	= 8,	/* processor present */
+	Cpuuserhalted	= 0x10,	/* user halted */
+	Cpuctxtokay	= 0x20,	/* context valid */
+	Cpupalokay	= 0x40,	/* PALcode valid */
+	Cpupalmemokay	= 0x80,	/* PALcode memory valid */
+	Cpupalloaded	= 0x100, /* PALcode loaded */
+	Cpuhaltmask	= 0xff0000, /* halt request mask */
+	Cpuhaltdflt	= 0,
+	Cpuhaltsaveexit = 0x10000,
+	Cpuhaltcoldboot = 0x20000,
+	Cpuhaltwarmboot = 0x30000,
+	Cpuhaltstayhalted = 0x40000,
+	Cpumustbezero = 0xffffffffff000000,	/* 24:63 -- must be zero */
+};
+
 /*
  *  initialize a processor's mach structure.  each processor does this
  *  for itself.
@@ -121,15 +156,16 @@ machinit(void)
 	active.machs = 1;
 
 	cpu = (Hwcpu*) ((ulong)hwrpb + hwrpb->cpuoff + n*hwrpb->cpulen);
-	cpu->state &= ~1;			/* boot in progress - not */
-/*	cpu->state |= (4<<16);		/* stay halted */
+	cpu->state &= ~Cpubootinprog;
+	if (0)
+		cpu->state |= Cpuhaltstayhalted;
 }
 
 void
 init0(void)
 {
 	int i;
-	char tstr[32];
+	char buf[2*KNAMELEN];
 
 	up->nerrlab = 0;
 
@@ -147,9 +183,9 @@ init0(void)
 	chandevinit();
 
 	if(!waserror()){
+		snprint(buf, sizeof(buf), "alpha %s alphapc", conffile);
+		ksetenv("terminal", buf, 0);
 		ksetenv("cputype", "alpha", 0);
-		sprint(tstr, "alpha %s alphapc", conffile);
-		ksetenv("terminal", tstr, 0);
 		if(cpuserver)
 			ksetenv("service", "cpu", 0);
 		else
@@ -254,15 +290,104 @@ procsave(Proc *p)
 	mmupark();
 }
 
-/* still to do */
 void
-reboot(void*, void*, ulong)
+setupboot(int halt)
 {
+	int n = 0;		// cpu id of primary cpu, not just m->machno
+	Hwcpu *cpu = (Hwcpu*)((ulong)hwrpb + hwrpb->cpuoff + n*hwrpb->cpulen);
+
+	cpu->state &= ~(Cpucanrestart | Cpuhaltmask);
+	cpu->state |= (halt? Cpuhaltstayhalted: Cpuhaltwarmboot);
+}
+
+/* from ../pc */
+static void
+shutdown(int ispanic)
+{
+	int ms, once;
+
+	lock(&active);
+	if(ispanic)
+		active.ispanic = ispanic;
+	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
+		active.ispanic = 0;
+	once = active.machs & (1<<m->machno);
+	active.machs &= ~(1<<m->machno);
+	active.exiting = 1;
+	unlock(&active);
+
+	if(once)
+		print("cpu%d: exiting\n", m->machno);
+	spllo();
+	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
+		delay(TK2MS(2));
+		if(active.machs == 0 && consactive() == 0)
+			break;
+	}
+
+	if(active.ispanic && m->machno == 0) {
+		if(cpuserver)
+			delay(10000);
+		else
+			for (;;)
+				continue;
+	} else
+		delay(1000);
+}
+
+/* from ../pc: */
+void
+reboot(void *entry, void *code, ulong size)
+{
+	// writeconf();		// pass kernel environment to next kernel
+	shutdown(0);
+
+	/*
+	 * should be the only processor running now
+	 */
+	print("shutting down...\n");
+	delay(200);
+
+	splhi();
+
+	/* turn off buffered serial console */
+	serialoq = nil;
+
+	/* shutdown devices */
+	chandevshutdown();
+
+#ifdef FUTURE
+{
+	ulong *pdb;
+	/*
+	 * Modify the machine page table to directly map the low 4MB of memory
+	 * This allows the reboot code to turn off the page mapping
+	 */
+	pdb = m->pdb;
+	pdb[PDX(0)] = pdb[PDX(KZERO)];
+	mmuflushtlb(PADDR(pdb));
+}
+	/* setup reboot trampoline function */
+{
+	void (*f)(ulong, ulong, ulong) = (void*)REBOOTADDR;
+
+	memmove(f, rebootcode, sizeof(rebootcode));
+#else
+	USED(entry, code, size);
+#endif
+
+	print("rebooting...\n");
+#ifdef FUTURE
+	/* off we go - never to return */
+	(*f)(PADDR(entry), PADDR(code), size);
+}
+#endif
+	setupboot(0);		// reboot, don't halt
 	exit(0);
 }
 
 void
-exit(int)
+exit(int ispanic)
 {
 	canlock(&active);
 	active.machs &= ~(1<<m->machno);
@@ -277,9 +402,21 @@ exit(int)
 
 	splhi();
 	delay(1000);	/* give serial fifo time to finish flushing */
+	if (getconf("*debug") != nil) {
+		USED(ispanic);
+		delay(60*1000);		/* give us time to read the screen */
+	}
 	if(arch->coredetach)
 		arch->coredetach();
-	firmware();
+	setupboot(1);			// set up to halt
+	for (; ; )
+		firmware();
+
+	// on PC is just:
+	if (0) {
+		shutdown(ispanic);
+		// arch->reset();
+	}
 }
 
 void
@@ -414,7 +551,7 @@ void
 memholes(void)
 {
 	Bank *b, *eb;
-	
+
 	b = bootconf->bank;
 	eb = b+bootconf->nbank;
 	while(b < eb) {
@@ -453,10 +590,10 @@ getconf(char *name)
 {
 	int n;
 
-	for(n = 0; n < nconf; n++){
-		if(cistrcmp(confname[n], name) == 0)
+	for(n = 0; n < nconf; n++)
+		if(cistrcmp(confname[n], name) == 0) {
 			return confval[n];
-	}
+		}
 	return 0;
 }
 
@@ -501,7 +638,7 @@ cistrcmp(char *a, char *b)
 	for(;;){
 		ac = *a++;
 		bc = *b++;
-	
+
 		if(ac >= 'A' && ac <= 'Z')
 			ac = 'a' + (ac - 'A');
 		if(bc >= 'A' && bc <= 'Z')

+ 2 - 1
sys/src/9/alphapc/mkfile

@@ -52,7 +52,6 @@ OBJ=\
 	trap.$O\
 	$DEVS\
 	$PORT\
-	boot$CONF.root.$O\
 
 LIB=\
 	/$objtype/lib/libmemlayer.a\
@@ -77,6 +76,7 @@ install:V: $p$CONF
 
 <../boot/bootmkfile
 <../port/portmkfile
+<|../port/mkbootrules $CONF
 
 init.h:	initcode /sys/src/libc/9syscall/sys.h
 	$AS initcode
@@ -96,6 +96,7 @@ sd53c8xx.i:	../pc/sd53c8xx.n
 devfloppy.$O:	../pc/devfloppy.c
 ether2114x.$O:	../pc/ether2114x.c
 mouse.$O:	../pc/mouse.c
+screen.$O:	../pc/screen.c
 sdata.$O:	../pc/sdata.c
 sdscsi.$O:	../pc/sdscsi.c
 uarti8250.$O:	../pc/uarti8250.c

+ 4 - 5
sys/src/9/alphapc/pci.c

@@ -197,15 +197,14 @@ pciscan(int bno, Pcidev** list)
 static void
 pcicfginit(void)
 {
-/*	char *p; */
+	char *p;
 
 	lock(&pcicfginitlock);
 	if(pcicfgmode == -1){
 		pcicfgmode = 0;
-/*		if(p = getconf("*pcimaxdno"))
-			pcimaxdno = strtoul(p, 0, 0); */
-pcimaxdno = 15 /* was 20; what is correct value??? */;
-
+		pcimaxdno = 15;		/* was 20; what is correct value??? */
+		if(p = getconf("*pcimaxdno"))
+			pcimaxdno = strtoul(p, 0, 0);
 		pciscan(0, &pciroot);
 	}
 	unlock(&pcicfginitlock);

+ 1 - 138
sys/src/9/alphapc/random.c

@@ -1,138 +1 @@
-#include	"u.h"
-#include	"../port/lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"../port/error.h"
-
-
-struct Rb
-{
-	QLock;
-	Rendez	producer;
-	Rendez	consumer;
-	ulong	randomcount;
-	uchar	buf[1024];
-	uchar	*ep;
-	uchar	*rp;
-	uchar	*wp;
-	uchar	next;
-	uchar	wakeme;
-	ushort	bits;
-	ulong	randn;
-} rb;
-
-static int
-rbnotfull(void*)
-{
-	int i;
-
-	i = rb.rp - rb.wp;
-	return i != 1 && i != (1 - sizeof(rb.buf));
-}
-
-static int
-rbnotempty(void*)
-{
-	return rb.wp != rb.rp;
-}
-
-void
-genrandom(void*)
-{
-	up->basepri = PriNormal;
-	up->priority = up->basepri;
-
-	for(;;){
-		for(;;)
-			if(++rb.randomcount > 100000)
-				break;
-		if(anyhigher())
-			sched();
-		if(!rbnotfull(0))
-			sleep(&rb.producer, rbnotfull, 0);
-	}
-}
-
-/*
- *  produce random bits in a circular buffer
- */
-static void
-randomclock(void)
-{
-	if(rb.randomcount == 0 || !rbnotfull(0))
-		return;
-
-	rb.bits = (rb.bits<<2) ^ rb.randomcount;
-	rb.randomcount = 0;
-
-	rb.next++;
-	if(rb.next != 8/2)
-		return;
-	rb.next = 0;
-
-	*rb.wp ^= rb.bits;
-	if(rb.wp+1 == rb.ep)
-		rb.wp = rb.buf;
-	else
-		rb.wp = rb.wp+1;
-
-	if(rb.wakeme)
-		wakeup(&rb.consumer);
-}
-
-void
-randominit(void)
-{
-	addclock0link(randomclock, 1000/HZ);
-	rb.ep = rb.buf + sizeof(rb.buf);
-	rb.rp = rb.wp = rb.buf;
-	kproc("genrandom", genrandom, 0);
-}
-
-/*
- *  consume random bytes from a circular buffer
- */
-ulong
-randomread(void *xp, ulong n)
-{
-	uchar *e, *p;
-	ulong x;
-
-	p = xp;
-
-	if(waserror()){
-		qunlock(&rb);
-		nexterror();
-	}
-
-	qlock(&rb);
-	for(e = p + n; p < e; ){
-		if(rb.wp == rb.rp){
-			rb.wakeme = 1;
-			wakeup(&rb.producer);
-			sleep(&rb.consumer, rbnotempty, 0);
-			rb.wakeme = 0;
-			continue;
-		}
-
-		/*
-		 *  beating clocks will be precictable if
-		 *  they are synchronized.  Use a cheap pseudo
-		 *  random number generator to obscure any cycles.
-		 */
-		x = rb.randn*1103515245 ^ *rb.rp;
-		*p++ = rb.randn = x;
-
-		if(rb.rp+1 == rb.ep)
-			rb.rp = rb.buf;
-		else
-			rb.rp = rb.rp+1;
-	}
-	qunlock(&rb);
-	poperror();
-
-	wakeup(&rb.producer);
-
-	return n;
-}
+#include "../pc/random.c"

+ 1 - 532
sys/src/9/alphapc/screen.c

@@ -1,532 +1 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "../port/error.h"
-
-#define	Image	IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-#define RGB2K(r,g,b)	((156763*(r)+307758*(g)+59769*(b))>>19)
-
-Point ZP = {0, 0};
-
-Rectangle physgscreenr;
-
-Memdata gscreendata;
-Memimage *gscreen;
-
-VGAscr vgascreen[1];
-
-Cursor	arrow = {
-	{ -1, -1 },
-	{ 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C, 
-	  0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04, 
-	  0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04, 
-	  0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40, 
-	},
-	{ 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0, 
-	  0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8, 
-	  0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8, 
-	  0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00, 
-	},
-};
-
-int
-screensize(int x, int y, int z, ulong chan)
-{
-	VGAscr *scr;
-
-	memimageinit();
-	scr = &vgascreen[0];
-
-	/*
-	 * BUG: need to check if any xalloc'ed memory needs to
-	 * be given back if aperture is set.
-	 */
-	if(scr->aperture == 0){
-		int width = (x*z)/BI2WD;
-
-		gscreendata.bdata = xalloc(width*BY2WD*y);
-		if(gscreendata.bdata == 0)
-			error("screensize: vga soft memory");
-		memset(gscreendata.bdata, Backgnd, width*BY2WD*y);
-		scr->useflush = 1;
-
-		scr->aperture = PADDR(arch->pcimem(0xA0000, 1<<16));
-		scr->apsize = 1<<16;
-	}
-	else
-		gscreendata.bdata = KADDR(scr->aperture);
-
-	if(gscreen)
-		freememimage(gscreen);
-
-	gscreen = allocmemimaged(Rect(0,0,x,y), chan, &gscreendata);
-	vgaimageinit(chan);
-	if(gscreen == nil)
-		return -1;
-
-/*	memset(gscreen->data->bdata, 0x15, (x*y*z+7)/8);	/* RSC BUG */
-	memfillcolor(gscreen, DRed);
-
-	scr->palettedepth = 6;	/* default */
-	scr->gscreendata = &gscreendata;
-	scr->memdefont = getmemdefont();
-	scr->gscreen = gscreen;
-
-	physgscreenr = gscreen->r;
-
-	drawcmap();
-	return 0;
-}
-
-int
-screenaperture(int size, int align)
-{
-	VGAscr *scr;
-	ulong aperture;
-
-	scr = &vgascreen[0];
-
-	if(size == 0){
-		if(scr->aperture && scr->isupamem)
-			upafree(scr->aperture, scr->apsize);
-		scr->aperture = 0;
-		scr->isupamem = 0;
-		return 0;
-	}
-	if(scr->dev && scr->dev->linear){
-		aperture = scr->dev->linear(scr, &size, &align);
-		if(aperture == 0)
-			return 1;
-	}else{
-		aperture = upamalloc(0, size, align);
-		if(aperture == 0)
-			return 1;
-
-		if(scr->aperture && scr->isupamem)
-			upafree(scr->aperture, scr->apsize);
-		scr->isupamem = 1;
-	}
-
-	scr->aperture = aperture;
-	scr->apsize = size;
-
-	return 0;
-}
-
-uchar*
-attachscreen(Rectangle* r, ulong* chan, int* d, int* width, int *softscreen)
-{
-	VGAscr *scr;
-
-	scr = &vgascreen[0];
-	if(scr->gscreen == nil || scr->gscreendata == nil)
-		return nil;
-
-	*r = scr->gscreen->r;
-	*chan = scr->gscreen->chan;
-	*d = scr->gscreen->depth;
-	*width = scr->gscreen->width;
-	*softscreen = scr->useflush;
-
-	return scr->gscreendata->bdata;
-}
-
-/*
- * It would be fair to say that this doesn't work for >8-bit screens.
- */
-void
-flushmemscreen(Rectangle r)
-{
-	VGAscr *scr;
-	uchar *sp, *disp, *sdisp, *edisp;
-	int y, len, incs, off, page;
-
-	scr = &vgascreen[0];
-	if(scr->gscreen == nil || scr->useflush == 0)
-		return;
-	if(scr->dev == nil || scr->dev->page == nil)
-		return;
-
-	if(rectclip(&r, scr->gscreen->r) == 0)
-		return;
-
-	incs = scr->gscreen->width * BY2WD;
-
-	switch(scr->gscreen->depth){
-	default:
-		len = 0;
-		panic("flushmemscreen: depth\n");
-		break;
-	case 8:
-		len = Dx(r);
-		break;
-	}
-	if(len < 1)
-		return;
-
-	off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8;
-	page = off/scr->apsize;
-	off %= scr->apsize;
-	disp = KADDR(scr->aperture);
-	sdisp = disp+off;
-	edisp = disp+scr->apsize;
-
-	off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8;
-
-	sp = scr->gscreendata->bdata + off;
-
-	scr->dev->page(scr, page);
-	for(y = r.min.y; y < r.max.y; y++) {
-		if(sdisp + incs < edisp) {
-			memmove(sdisp, sp, len);
-			sp += incs;
-			sdisp += incs;
-		}
-		else {
-			off = edisp - sdisp;
-			page++;
-			if(off <= len){
-				if(off > 0)
-					memmove(sdisp, sp, off);
-				scr->dev->page(scr, page);
-				if(len - off > 0)
-					memmove(disp, sp+off, len - off);
-			}
-			else {
-				memmove(sdisp, sp, len);
-				scr->dev->page(scr, page);
-			}
-			sp += incs;
-			sdisp += incs - scr->apsize;
-		}
-	}
-}
-
-void
-getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb)
-{
-	VGAscr *scr;
-	ulong x;
-
-	scr = &vgascreen[0];
-	if(scr->gscreen == nil)
-		return;
-
-	switch(scr->gscreen->depth){
-	default:
-		x = 0x0F;
-		break;
-	case 8:
-		x = 0xFF;
-		break;
-	}
-	p &= x;
-
-	lock(&cursor);
-	*pr = scr->colormap[p][0];
-	*pg = scr->colormap[p][1];
-	*pb = scr->colormap[p][2];
-	unlock(&cursor);
-}
-
-int
-setpalette(ulong p, ulong r, ulong g, ulong b)
-{
-	VGAscr *scr;
-	int d;
-
-	scr = &vgascreen[0];
-	d = scr->palettedepth;
-
-	lock(&cursor);
-	scr->colormap[p][0] = r;
-	scr->colormap[p][1] = g;
-	scr->colormap[p][2] = b;
-	vgao(PaddrW, p);
-	vgao(Pdata, r>>(32-d));
-	vgao(Pdata, g>>(32-d));
-	vgao(Pdata, b>>(32-d));
-	unlock(&cursor);
-
-	return ~0;
-}
-
-/*
- * On some video cards (e.g. Mach64), the palette is used as the 
- * DAC registers for >8-bit modes.  We don't want to set them when the user
- * is trying to set a colormap and the card is in one of these modes.
- */
-int
-setcolor(ulong p, ulong r, ulong g, ulong b)
-{
-	VGAscr *scr;
-	int x;
-
-	scr = &vgascreen[0];
-	if(scr->gscreen == nil)
-		return 0;
-
-	switch(scr->gscreen->depth){
-	case 1:
-	case 2:
-	case 4:
-		x = 0x0F;
-		break;
-	case 8:
-		x = 0xFF;
-		break;
-	default:
-		return 0;
-	}
-	p &= x;
-
-	return setpalette(p, r, g, b);
-}
-
-int
-cursoron(int dolock)
-{
-	VGAscr *scr;
-	int v;
-
-	scr = &vgascreen[0];
-	if(scr->cur == nil || scr->cur->move == nil)
-		return 0;
-
-	if(dolock)
-		lock(&cursor);
-	v = scr->cur->move(scr, mousexy());
-	if(dolock)
-		unlock(&cursor);
-
-	return v;
-}
-
-void
-cursoroff(int)
-{
-}
-
-void
-setcursor(Cursor* curs)
-{
-	VGAscr *scr;
-
-	scr = &vgascreen[0];
-	if(scr->cur == nil || scr->cur->load == nil)
-		return;
-
-	scr->cur->load(scr, curs);
-}
-
-static ulong
-pixelbits(Memimage *i, Point pt)
-{
-	uchar *p;
-	ulong val;
-	int off, bpp, npack;
-
-	val = 0;
-	p = byteaddr(i, pt);
-	switch(bpp=i->depth){
-	case 1:
-	case 2:
-	case 4:
-		npack = 8/bpp;
-		off = pt.x%npack;
-		val = p[0] >> bpp*(npack-1-off);
-		val &= (1<<bpp)-1;
-		break;
-	case 8:
-		val = p[0];
-		break;
-	case 16:
-		val = p[0]|(p[1]<<8);
-		break;
-	case 24:
-		val = p[0]|(p[1]<<8)|(p[2]<<16);
-		break;
-	case 32:
-		val = p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24);
-		break;
-	}
-	while(bpp<32){
-		val |= val<<bpp;
-		bpp *= 2;
-	}
-	return val;
-}
-
-
-static ulong
-imgtorgba(Memimage *img, ulong val)
-{
-	uchar r, g, b, a;
-	int nb, ov, v;
-	ulong chan;
-	uchar *p;
-
-	a = 0xFF;
-	r = g = b = 0xAA;	/* garbage */
-	for(chan=img->chan; chan; chan>>=8){
-		nb = NBITS(chan);
-		ov = v = val&((1<<nb)-1);
-		val >>= nb;
-
-		while(nb < 8){
-			v |= v<<nb;
-			nb *= 2;
-		}
-		v >>= (nb-8);
-
-		switch(TYPE(chan)){
-		case CRed:
-			r = v;
-			break;
-		case CGreen:
-			g = v;
-			break;
-		case CBlue:
-			b = v;
-			break;
-		case CAlpha:
-			a = v;
-			break;
-		case CGrey:
-			r = g = b = v;
-			break;
-		case CMap:
-			p = img->cmap->cmap2rgb+3*ov;
-			r = *p++;
-			g = *p++;	
-			b = *p;
-			break;
-		}
-	}
-	return (r<<24)|(g<<16)|(b<<8)|a;	
-}
-
-static ulong
-rgbatoimg(Memimage *img, ulong rgba)
-{
-	ulong chan;
-	int d, nb;
-	ulong v;
-	uchar *p, r, g, b, a, m;
-
-	v = 0;
-	r = rgba>>24;
-	g = rgba>>16;
-	b = rgba>>8;
-	a = rgba;
-	d = 0;
-	for(chan=img->chan; chan; chan>>=8){
-		nb = NBITS(chan);
-		switch(TYPE(chan)){
-		case CRed:
-			v |= (r>>(8-nb))<<d;
-			break;
-		case CGreen:
-			v |= (g>>(8-nb))<<d;
-			break;
-		case CBlue:
-			v |= (b>>(8-nb))<<d;
-			break;
-		case CAlpha:
-			v |= (a>>(8-nb))<<d;
-			break;
-		case CMap:
-			p = img->cmap->rgb2cmap;
-			m = p[(r>>4)*256+(g>>4)*16+(b>>4)];
-			v |= m<<d;
-			break;
-		case CGrey:
-			m = RGB2K(r,g,b);
-			v |= m<<d;
-			break;
-		}
-		d += nb;
-	}
-//	print("rgba2img %.8lux = %.*lux\n", rgba, 2*d/8, v);
-	return v;
-}
-
-Memimage *lastbadi;
-Memdata *lastbad;
-Memimage *lastbadsrc, *lastbaddst;
-int hwaccel = 1;
-int hwblank = 1;
-
-int
-hwdraw(Memdrawparam *par)
-{
-	int m;
-	VGAscr *scr;
-	Memimage *dst, *src;
-
-	if(hwaccel == 0)
-		return 0;
-
-	dst = par->dst;
-	scr = &vgascreen[0];
-	if(dst == nil || dst->data == nil)
-		return 0;
-
-	if(dst->data->bdata != gscreendata.bdata)
-		return 0;
-
-//	if(dst->data != &gscreendata){
-//		lastbad = dst->data;
-//		lastbadi = dst;
-//		return 0;
-//	}
-
-	if(scr->fill==nil && scr->scroll==nil)
-		return 0;
-
-	/*
-	 * If we have an opaque mask and source is one opaque
-	 * pixel we can convert to the destination format and just
-	 * replicate with memset.
-	 */
-	m = Simplesrc|Simplemask|Fullmask;
-	if(scr->fill && (par->state&m)==m && ((par->srgba&0xFF) == 0xFF))
-		return scr->fill(scr, par->r, par->sdval);
-
-	/*
-	 * If no source alpha, an opaque mask, we can just copy the
-	 * source onto the destination.  If the channels are the same and
-	 * the source is not replicated, memmove suffices.
-	 */
-	src = par->src;
-	if(scr->scroll && src->data->bdata==dst->data->bdata && !(src->flags&Falpha)
-	&& (par->state&(Simplemask|Fullmask))==(Simplemask|Fullmask)){
-//		if(src->zero != dst->zero){
-//			lastbadsrc = src;
-//			lastbaddst = dst;
-//			iprint("#");
-//		}
-		return scr->scroll(scr, par->r, par->sr);
-	}
-
-	return 0;	
-}
-
-void
-blankscreen(int blank)
-{
-	VGAscr *scr;
-
-	scr = &vgascreen[0];
-	if(hwblank && scr->blank)
-		scr->blank(scr, blank);
-}
+#include "../pc/screen.c"

+ 2 - 0
sys/src/9/alphapc/screen.h

@@ -47,6 +47,8 @@ enum {
 	Pwhite		= 0xFF,
 };
 
+#define VGAMEM()	PADDR(arch->pcimem(0xA0000, 1<<16))
+
 #define vgai(port)		inb(port)
 #define vgao(port, data)	outb(port, data)
 

+ 1 - 1
sys/src/9/bitsy/main.c

@@ -145,7 +145,7 @@ bootargs(ulong base)
 	 */
 	sp = (uchar*)base + BY2PG - sizeof(Sargs);
 
-	bootpath = pusharg("/boot");
+	bootpath = pusharg("/boot/boot");
 	ac = 0;
 	av[ac++] = pusharg("boot");
 

+ 8 - 8
sys/src/9/bitsy/screen.c

@@ -393,12 +393,12 @@ screenwin(void)
 
 	r = insetrect(gscreen->r, 4);
 
-	memimagedraw(gscreen, r, memblack, ZP, memopaque, ZP);
+	memimagedraw(gscreen, r, memblack, ZP, memopaque, ZP, S);
 	window = insetrect(r, 4);
-	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP);
+	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
 
 	memimagedraw(gscreen, Rect(window.min.x, window.min.y,
-			window.max.x, window.min.y+h+5+6), orange, ZP, nil, ZP);
+			window.max.x, window.min.y+h+5+6), orange, ZP, nil, ZP, S);
 	freememimage(orange);
 	window = insetrect(window, 5);
 
@@ -445,7 +445,7 @@ screenputc(char *buf)
 		pos = 4-(pos%4);
 		*xp++ = curpos.x;
 		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
-		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min);
+		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
 		flushmemscreen(r);
 		curpos.x += pos*w;
 		break;
@@ -454,7 +454,7 @@ screenputc(char *buf)
 			break;
 		xp--;
 		r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
-		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min);
+		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
 		flushmemscreen(r);
 		curpos.x = *xp;
 		break;
@@ -469,7 +469,7 @@ screenputc(char *buf)
 
 		*xp++ = curpos.x;
 		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
-		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min);
+		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
 		memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
 		flushmemscreen(r);
 		curpos.x += w;
@@ -486,10 +486,10 @@ scroll(void)
 	o = 8*h;
 	r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
 	p = Pt(window.min.x, window.min.y+o);
-	memimagedraw(gscreen, r, gscreen, p, nil, p);
+	memimagedraw(gscreen, r, gscreen, p, nil, p, S);
 	flushmemscreen(r);
 	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
-	memimagedraw(gscreen, r, back, ZP, nil, ZP);
+	memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
 	flushmemscreen(r);
 
 	curpos.y -= o;

+ 3 - 3
sys/src/9/boot/bootauth.c

@@ -13,7 +13,7 @@ authentication(int cpuflag)
 	char *argv[16], **av;
 	int ac;
 
-	if(access("/factotum", AEXEC) < 0){
+	if(access("/boot/factotum", AEXEC) < 0){
 		glenda();
 		return;
 	}
@@ -38,8 +38,8 @@ authentication(int cpuflag)
 	case -1:
 		fatal("starting factotum: %r");
 	case 0:
-		exec("/factotum", av);
-		fatal("execing /factotum");
+		exec("/boot/factotum", av);
+		fatal("execing /boot/factotum");
 	default:
 		break;
 	}

+ 3 - 3
sys/src/9/boot/bootcache.c

@@ -10,7 +10,7 @@ cache(int fd)
 	int argc, i, p[2];
 	char *argv[5], bd[32], buf[256], partition[64], *pp;
 
-	if(stat("/cfs", statbuf, sizeof statbuf) < 0)
+	if(stat("/boot/cfs", statbuf, sizeof statbuf) < 0)
 		return fd;
 
 	*partition = 0;
@@ -63,9 +63,9 @@ cache(int fd)
 		dup(p[0], 1);
 		close(p[0]);
 		if(fflag)
-			execl("/cfs", "bootcfs", "-rs", "-f", partition, 0);
+			execl("/boot/cfs", "bootcfs", "-rs", "-f", partition, 0);
 		else
-			execl("/cfs", "bootcfs", "-s", "-f", partition, 0);
+			execl("/boot/cfs", "bootcfs", "-s", "-f", partition, 0);
 		break;
 	default:
 		close(p[0]);

+ 1 - 1
sys/src/9/boot/bootip.c

@@ -60,7 +60,7 @@ configip(void)
 	case -1:
 		fatal("configuring ip: %r");
 	case 0:
-		exec("/ipconfig", arg);
+		exec("/boot/ipconfig", arg);
 		fatal("execing /ipconfig");
 	default:
 		break;

+ 3 - 3
sys/src/9/boot/embed.c

@@ -28,7 +28,7 @@ connectembed(void)
 	Dir *dir;
 	char **arg, **argp;
 
-	dir = dirstat("/paqfs");
+	dir = dirstat("/boot/paqfs");
 	if(dir == nil)
 		return -1;
 	free(dir);
@@ -51,7 +51,7 @@ connectembed(void)
 	case 0:
 		arg = malloc((bargc+5)*sizeof(char*));
 		argp = arg;
-		*argp++ = "/paqfs";
+		*argp++ = "/boot/paqfs";
 		*argp++ = "-iv";
 		*argp++ = paqfile;
 		for(i=1; i<bargc; i++)
@@ -62,7 +62,7 @@ connectembed(void)
 		dup(p[1], 1);
 		close(p[0]);
 		close(p[1]);
-		exec("/paqfs", arg);
+		exec("/boot/paqfs", arg);
 		fatal("can't exec paqfs");
 	default:
 		break;

+ 2 - 2
sys/src/9/boot/local.c

@@ -58,7 +58,7 @@ connectlocal(void)
 	char **arg, **argp;
 	ulong mode;
 
-	if(stat("/kfs", statbuf, sizeof statbuf) < 0)
+	if(stat("/boot/kfs", statbuf, sizeof statbuf) < 0)
 		return -1;
 
 	dev = disk ? disk : bootdisk;
@@ -100,7 +100,7 @@ connectlocal(void)
 		dup(p[1], 1);
 		close(p[0]);
 		close(p[1]);
-		exec("/kfs", arg);
+		exec("/boot/kfs", arg);
 		fatal("can't exec kfs");
 	default:
 		break;

+ 1 - 1
sys/src/9/boot/paq.c

@@ -55,7 +55,7 @@ connectpaq(void)
 		dup(p[1], 1);
 		close(p[0]);
 		close(p[1]);
-		exec("/paqfs", arg);
+		exec("/boot/paqfs", arg);
 		fatal("can't exec paqfs");
 	default:
 		break;

+ 37 - 0
sys/src/9/boot/testboot.c

@@ -0,0 +1,37 @@
+#include <u.h>
+#include <libc.h>
+#include <auth.h>
+
+void
+usage(void)
+{
+	fprint(2, "usage: testboot cmd args...\n");
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	int p[2];
+
+	if(argc == 1)
+		usage();
+
+	pipe(p);
+	switch(rfork(RFPROC|RFFDG|RFNAMEG)){
+	case -1:
+		sysfatal("fork: %r");
+
+	case 0:
+		dup(p[0], 0);
+		dup(p[1], 1);
+		exec(argv[1], argv+1);
+		sysfatal("exec: %r");
+
+	default:
+		if(amount(p[0], "/n/kremvax", MREPL, "") < 0)
+			sysfatal("amount: %r");
+		break;
+	}
+	exits(nil);
+}

+ 3 - 2
sys/src/9/mtx/initcode

@@ -19,6 +19,7 @@ loop:
 	BR	loop
 
 DATA	boot+0(SB)/5,$"/boot"
-DATA	bootv+0(SB)/4,$boot+1(SB)
-GLOBL	boot+0(SB),$6
+DATA	boot+5(SB)/5,$"/boot"
+DATA	bootv+0(SB)/4,$boot+6(SB)
+GLOBL	boot+0(SB),$11
 GLOBL	bootv+0(SB),$8

+ 1 - 1
sys/src/9/mtx/mkfile

@@ -50,7 +50,6 @@ OBJ=\
 	trap.$O\
 	$DEVS\
 	$PORT\
-	boot$CONF.root.$O\
 
 LIB=\
 	/$objtype/lib/libmemlayer.a\
@@ -75,6 +74,7 @@ install:V: $p$CONF
 
 <../boot/bootmkfile
 <../port/portmkfile
+<|../port/mkbootrules $CONF
 
 clock.$O devether.$O main.$O trap.$O:	/$objtype/include/ureg.h
 

+ 5 - 3
sys/src/9/mtx/mtx

@@ -24,9 +24,6 @@ link
 	netdevmedium
 
 misc
-	ipconfig.root
-	factotum.root
-
 	uarti8250
 
 ip
@@ -42,3 +39,8 @@ port
 
 boot
 	il
+
+bootdir
+	bootmtx.out boot
+	ipconfig.hack ipconfig
+	factotum.hack factotum

+ 6 - 3
sys/src/9/mtx/mtxcpu

@@ -24,9 +24,6 @@ link
 	netdevmedium
 
 misc
-	ipconfig.root
-	factotum.root
-
 	uarti8250
 
 ip
@@ -42,3 +39,9 @@ port
 
 boot cpu
 	il
+
+bootdir
+	bootmtxcpu.out boot
+	ipconfig.hack ipconfig
+	factotum.hack factotum
+

+ 3 - 2
sys/src/9/pc/devvga.c

@@ -179,7 +179,8 @@ vgaread(Chan* c, void* a, long n, vlong off)
 					physgscreenr.max.x, physgscreenr.max.y);
 		}
 
-		len += snprint(p+len, READSTR-len, "blanktime %lud\n", blanktime);
+		len += snprint(p+len, READSTR-len, "blank time %lud idle %d state %s\n",
+			blanktime, drawidletime(), scr->isblank ? "off" : "on");
 		len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "panning %s\n", panning ? "on" : "off");
@@ -321,7 +322,7 @@ vgactl(Cmdbuf *cb)
 		return;
 
 	case CMdrawinit:
-		memimagedraw(scr->gscreen, scr->gscreen->r, memblack, ZP, nil, ZP);
+		memimagedraw(scr->gscreen, scr->gscreen->r, memblack, ZP, nil, ZP, S);
 		if(scr && scr->dev && scr->dev->drawinit)
 			scr->dev->drawinit(scr);
 		return;

+ 1 - 1
sys/src/9/pc/kbd.c

@@ -383,7 +383,7 @@ i8042intr(Ureg*, void*)
 			 * come back into focus, Plan 9 thinks you want to type
 			 * a compose sequence (you just typed alt). 
 			 *
-			 * As a clusmy hack around this, we look for ctl-alt
+			 * As a clumsy hack around this, we look for ctl-alt
 			 * and don't treat it as the start of a compose sequence.
 			 */
 			if(!ctl){

+ 5 - 5
sys/src/9/pc/mkfile

@@ -50,7 +50,6 @@ OBJ=\
 	trap.$O\
 	$DEVS\
 	$PORT\
-	boot$CONF.root.$O\
 
 LIB=\
 	/$objtype/lib/libmemlayer.a\
@@ -77,6 +76,7 @@ install:V: $p$CONF $p$CONF.gz
 
 <../boot/bootmkfile
 <../port/portmkfile
+<|../port/mkbootrules $CONF
 
 $ETHER: 			etherif.h ../port/netif.h
 ether8003.$O ether8390.$O:	ether8390.h
@@ -94,11 +94,11 @@ devusb.$O usbuhci.$O usbohci.$O:	usb.h
 sd53c8xx.i:	sd53c8xx.n
 	aux/na $prereq > $target
 
-init.h:	initcode.s /sys/src/libc/9syscall/sys.h
-	$AS initcode.s
-	$LD -l -R4 -o init.out initcode.$O
+init.h:	../port/initcode.c /sys/src/libc/9syscall/sys.h
+	$CC ../port/initcode.c
+	$LD -l -R1 -o init.out initcode.$O /386/lib/libc.a
 	{echo 'uchar initcode[]={'
-	 xd -1x init.out |
+	 strip < init.out | xd -1x |
 		sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
 	 echo '};'} > init.h
 

+ 5 - 3
sys/src/9/pc/pc

@@ -60,9 +60,6 @@ link
 misc
 	archmp		mp apic
 
-	ipconfig.root
-	factotum.root
-
 	sdata		pci sdscsi
 	sd53c8xx	pci sdscsi
 	sdmylex		pci sdscsi
@@ -105,3 +102,8 @@ port
 
 boot
 	il
+
+bootdir
+	bootpc.out boot
+	/386/bin/ip/ipconfig
+	factotum.hack factotum

+ 7 - 4
sys/src/9/pc/pcauth

@@ -32,12 +32,9 @@ link
 	ether82557	pci
 	ethermedium
 	netdevmedium
+	loopbackmedium
 
 misc
-	factotum.root
-	ipconfig.root
-	kfs.root
-
 	sdata		pci sdscsi
 
 	uarti8250
@@ -59,3 +56,9 @@ port
 boot cpu boot #S/sdC0/
 	il
 	local
+
+bootdir
+	bootpcauth.out boot
+	/386/bin/ip/ipconfig
+	factotum.hack factotum
+	/386/bin/disk/kfs

+ 6 - 5
sys/src/9/pc/pccd

@@ -58,11 +58,6 @@ link
 misc
 	archmp		mp apic
 
-	ipconfig.root
-	9660srv.root
-	factotum.root
-	cfs.root
-
 	sdata		pci sdscsi
 	sd53c8xx		pci sdscsi
 	sdmylex		pci sdscsi
@@ -104,3 +99,9 @@ port
 boot boot #S/sdD0/data
 	il
 	local
+
+bootdir
+	bootpccd.out boot
+	/386/bin/ip/ipconfig ipconfig
+	/386/bin/9660srv kfs
+

+ 6 - 2
sys/src/9/pc/pccpu

@@ -32,6 +32,7 @@ link
 	ether79c970	pci
 	ether8003	ether8390
 	ether8139	pci
+	ether82543	pci ethermii
 	ether82543gc	pci
 	ether82557	pci
 	ether83815	pci
@@ -49,8 +50,6 @@ misc
 	sdata		pci sdscsi
 	sd53c8xx	pci sdscsi
 
-	ipconfig.root
-	factotum.root
 
 ip
 	il
@@ -69,3 +68,8 @@ port
 
 boot cpu
 	il
+
+bootdir
+	bootpccpu.out boot
+	/386/bin/ip/ipconfig ipconfig
+	factotum.hack factotum

+ 8 - 6
sys/src/9/pc/pcdisk

@@ -60,11 +60,6 @@ link
 misc
 	archmp		mp apic
 
-	ipconfig.root
-	kfs.root
-	factotum.root
-	cfs.root
-
 	sdata		pci sdscsi
 	sd53c8xx		pci sdscsi
 	sdmylex		pci sdscsi
@@ -105,5 +100,12 @@ port
 	int cpuserver = 0;
 
 boot boot #S/sdC0/
-	il
 	local
+	il
+
+bootdir
+	bootpcdisk.out boot
+	/386/bin/ip/ipconfig
+	factotum.hack factotum
+	/386/bin/disk/kfs
+	/386/bin/cfs

+ 11 - 5
sys/src/9/pc/screen.c

@@ -58,7 +58,7 @@ screensize(int x, int y, int z, ulong chan)
 			error("screensize: vga soft memory");
 /*		memset(gscreendata.bdata, 0x72, width*BY2WD*y);	/* not really black */
 		scr->useflush = 1;
-		scr->aperture = 0xA0000;
+		scr->aperture = VGAMEM();
 		scr->apsize = 1<<16;
 	}
 	else
@@ -362,7 +362,10 @@ hwdraw(Memdrawparam *par)
 	 * replicate with memset.
 	 */
 	m = Simplesrc|Simplemask|Fullmask;
-	if(scr->fill && (par->state&m)==m && ((par->srgba&0xFF) == 0xFF))
+	if(scr->fill
+	&& (par->state&m)==m
+	&& ((par->srgba&0xFF) == 0xFF)
+	&& (par->op&S) == S)
 		return scr->fill(scr, par->r, par->sdval);
 
 	/*
@@ -370,11 +373,14 @@ hwdraw(Memdrawparam *par)
 	 * source onto the destination.  If the channels are the same and
 	 * the source is not replicated, memmove suffices.
 	 */
+	m = Simplemask|Fullmask;
 	src = par->src;
-	if(scr->scroll && src->data->bdata==dst->data->bdata && !(src->flags&Falpha)
-	&& (par->state&(Simplemask|Fullmask))==(Simplemask|Fullmask)){
+	if(scr->scroll
+	&& src->data->bdata==dst->data->bdata
+	&& !(src->flags&Falpha)
+	&& (par->state&m)==m
+	&& (par->op&S) == S)
 		return scr->scroll(scr, par->r, par->sr);
-	}
 
 	return 0;	
 }

+ 3 - 0
sys/src/9/pc/screen.h

@@ -47,6 +47,7 @@ enum {
 	Pwhite		= 0xFF,
 };
 
+#define VGAMEM()	0xA0000
 #define vgai(port)		inb(port)
 #define vgao(port, data)	outb(port, data)
 
@@ -114,6 +115,7 @@ struct VGAscr {
 	int	(*scroll)(VGAscr*, Rectangle, Rectangle);
 	void	(*blank)(VGAscr*, int);
 	ulong	id;	/* internal identifier for driver use */
+	int isblank;
 };
 
 extern VGAscr vgascreen[];
@@ -146,6 +148,7 @@ extern int		drawhasclients(void);
 extern ulong	blanktime;
 extern void	setscreenimageclipr(Rectangle);
 extern void	drawflush(void);
+extern int drawidletime(void);
 
 /* vga.c */
 extern void	vgascreenwin(VGAscr*);

+ 6 - 6
sys/src/9/pc/vga.c

@@ -54,9 +54,9 @@ vgascroll(VGAscr* scr)
 	o = 8*h;
 	r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
 	p = Pt(window.min.x, window.min.y+o);
-	memimagedraw(scr->gscreen, r, scr->gscreen, p, nil, p);
+	memimagedraw(scr->gscreen, r, scr->gscreen, p, nil, p, S);
 	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
-	memimagedraw(scr->gscreen, r, back, ZP, nil, ZP);
+	memimagedraw(scr->gscreen, r, back, ZP, nil, ZP, S);
 
 	curpos.y -= o;
 }
@@ -99,7 +99,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
 		pos = 4-(pos%4);
 		*xp++ = curpos.x;
 		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
-		memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min);
+		memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
 		curpos.x += pos*w;
 		break;
 
@@ -108,7 +108,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
 			break;
 		xp--;
 		r = Rect(*xp, curpos.y, curpos.x, curpos.y+h);
-		memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP);
+		memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP, S);
 		combinerect(flushr, r);
 		curpos.x = *xp;
 		break;
@@ -125,7 +125,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
 
 		*xp++ = curpos.x;
 		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h);
-		memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min);
+		memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
 		memimagestring(scr->gscreen, curpos, conscol, ZP, scr->memdefont, buf);
 		combinerect(flushr, r);
 		curpos.x += w;
@@ -248,7 +248,7 @@ cornerstring(char *s)
 	h = scr->memdefont->height;
 
 	r = Rect(0, 0, w, h);
-	memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min);
+	memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
 	memimagestring(scr->gscreen, r.min, conscol, ZP, scr->memdefont, s);
 //	flushmemscreen(r);
 }

+ 65 - 21
sys/src/9/port/devdraw.c

@@ -80,6 +80,7 @@ struct Client
 	int		slot;
 	int		refreshme;
 	int		infoid;
+	int		op;
 };
 
 struct Refresh
@@ -384,6 +385,11 @@ dstflush(int dstid, Memimage *dst, Rectangle r)
 		combinerect(&flushrect, r);
 		return;
 	}
+	/* how can this happen? -rsc, dec 12 2002 */
+	if(dst == 0){
+		print("nil dstflush\n");
+		return;
+	}
 	l = dst->layer;
 	if(l == nil)
 		return;
@@ -750,10 +756,21 @@ drawnewclient(void)
 	memset(cl, 0, sizeof(Client));
 	cl->slot = i;
 	cl->clientid = ++sdraw.clientid;
+	cl->op = SoverD;
 	sdraw.client[i] = cl;
 	return cl;
 }
 
+static int
+drawclientop(Client *cl)
+{
+	int op;
+
+	op = cl->op;
+	cl->op = SoverD;
+	return op;
+}
+
 int
 drawhasclients(void)
 {
@@ -820,7 +837,7 @@ drawpoint(Point *p, uchar *a)
 }
 
 Point
-drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int index)
+drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int index, int op)
 {
 	FChar *fc;
 	Rectangle r;
@@ -833,7 +850,7 @@ drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int ind
 	r.max.y = r.min.y+(fc->maxy-fc->miny);
 	sp1.x = sp->x+fc->left;
 	sp1.y = sp->y+fc->miny;
-	memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny));
+	memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny), op);
 	p.x += fc->width;
 	sp->x += fc->width;
 	return p;
@@ -877,7 +894,7 @@ deletescreenimage(void)
 	qunlock(&sdraw);
 }
 
-Chan*
+static Chan*
 drawattach(char *spec)
 {
 	qlock(&sdraw);
@@ -889,7 +906,7 @@ drawattach(char *spec)
 	return devattach('i', spec);
 }
 
-Walkqid*
+static Walkqid*
 drawwalk(Chan *c, Chan *nc, char **name, int nname)
 {
 	if(screendata.bdata == nil)
@@ -1272,7 +1289,7 @@ printmesg(char *fmt, uchar *a, int plsprnt)
 void
 drawmesg(Client *client, void *av, int n)
 {
-	int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, ox, oy, esize, doflush;
+	int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, op, ox, oy, oesize, esize, doflush;
 	uchar *u, *a, refresh;
 	char *fmt;
 	ulong value, chan;
@@ -1427,7 +1444,8 @@ drawmesg(Client *client, void *av, int n)
 			drawrectangle(&r, a+13);
 			drawpoint(&p, a+29);
 			drawpoint(&q, a+37);
-			memdraw(dst, r, src, p, mask, q);
+			op = drawclientop(client);
+			memdraw(dst, r, src, p, mask, q, op);
 			dstflush(dstid, dst, r);
 			continue;
 
@@ -1464,13 +1482,14 @@ drawmesg(Client *client, void *av, int n)
 				c = -1;
 			ox = BGLONG(a+37);
 			oy = BGLONG(a+41);
+			op = drawclientop(client);
 			/* high bit indicates arc angles are present */
 			if(ox & (1<<31)){
 				if((ox & (1<<30)) == 0)
 					ox &= ~(1<<31);
-				memarc(dst, p, e0, e1, c, src, sp, ox, oy);
+				memarc(dst, p, e0, e1, c, src, sp, ox, oy, op);
 			}else
-				memellipse(dst, p, e0, e1, c, src, sp);
+				memellipse(dst, p, e0, e1, c, src, sp, op);
 			dstflush(dstid, dst, Rect(p.x-e0-j, p.y-e1-j, p.x+e0+j+1, p.y+e1+j+1));
 			continue;
 
@@ -1539,7 +1558,7 @@ drawmesg(Client *client, void *av, int n)
 				error(Eindex);
 			drawrectangle(&r, a+11);
 			drawpoint(&p, a+27);
-			memdraw(font->image, r, src, p, memopaque, p);
+			memdraw(font->image, r, src, p, memopaque, p, S);
 			fc = &font->fchar[ci];
 			fc->minx = r.min.x;
 			fc->maxx = r.max.x;
@@ -1566,7 +1585,8 @@ drawmesg(Client *client, void *av, int n)
 				error("negative line width");
 			src = drawimage(client, a+33);
 			drawpoint(&sp, a+37);
-			memline(dst, p, q, e0, e1, j, src, sp);
+			op = drawclientop(client);
+			memline(dst, p, q, e0, e1, j, src, sp, op);
 			/* avoid memlinebbox if possible */
 			if(dstid==0 || dst->layer!=nil){
 				/* BUG: this is terribly inefficient: update maximal containing rect*/
@@ -1672,6 +1692,15 @@ drawmesg(Client *client, void *av, int n)
 			}
 			continue;
 
+		/* set compositing operator for next draw operation: 'O' op */
+		case 'O':
+			printmesg(fmt="b", a, 0);
+			m = 1+1;
+			if(n < m)
+				error(Eshortdraw);
+			client->op = a[1];
+			continue;
+
 		/* filled polygon: 'P' dstid[4] n[2] wind[4] ignore[2*4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
 		/* polygon: 'p' dstid[4] n[2] end0[4] end1[4] radius[4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
 		case 'p':
@@ -1704,8 +1733,11 @@ drawmesg(Client *client, void *av, int n)
 			if(dstid==0 || (dst->layer && dst->layer->screen->image->data == screenimage->data))
 				doflush = 1;	/* simplify test in loop */
 			ox = oy = 0;
+			esize = 0;
 			u = a+m;
 			for(y=0; y<ni; y++){
+				q = p;
+				oesize = esize;
 				u = drawcoord(u, a+n, ox, &p.x);
 				u = drawcoord(u, a+n, oy, &p.y);
 				ox = p.x;
@@ -1726,16 +1758,22 @@ drawmesg(Client *client, void *av, int n)
 					}
 					if(*a=='P' && e0!=1 && e0 !=~0)
 						r = dst->clipr;
-					else
-						r = Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1);
-					dstflush(dstid, dst, r);
+					else if(y > 0){
+						r = Rect(q.x-oesize, q.y-oesize, q.x+oesize+1, q.y+oesize+1);
+						combinerect(&r, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
+					}
+					if(rectclip(&r, dst->clipr))		/* should perhaps be an arg to dstflush */
+						dstflush(dstid, dst, r);
 				}
 				pp[y] = p;
 			}
+			if(y == 1)
+				dstflush(dstid, dst, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
+			op = drawclientop(client);
 			if(*a == 'p')
-				mempoly(dst, pp, ni, e0, e1, j, src, sp);
+				mempoly(dst, pp, ni, e0, e1, j, src, sp, op);
 			else
-				memfillpoly(dst, pp, ni, e0, src, sp);
+				memfillpoly(dst, pp, ni, e0, src, sp, op);
 			free(pp);
 			m = u-a;
 			continue;
@@ -1793,6 +1831,7 @@ drawmesg(Client *client, void *av, int n)
 				error(Eshortdraw);
 			clipr = dst->clipr;
 			dst->clipr = r;
+			op = drawclientop(client);
 			if(*a == 'x'){
 				/* paint background */
 				l = drawimage(client, a+47);
@@ -1811,7 +1850,7 @@ drawmesg(Client *client, void *av, int n)
 					r.max.x += font->fchar[ci].width;
 					u += 2;
 				}
-				memdraw(dst, r, l, q, memopaque, ZP);
+				memdraw(dst, r, l, q, memopaque, ZP, op);
 				u -= 2*ni;
 			}
 			q = p;
@@ -1821,7 +1860,7 @@ drawmesg(Client *client, void *av, int n)
 					dst->clipr = clipr;
 					error(Eindex);
 				}
-				q = drawchar(dst, q, src, &sp, font, ci);
+				q = drawchar(dst, q, src, &sp, font, ci, op);
 				u += 2;
 			}
 			dst->clipr = clipr;
@@ -2020,11 +2059,16 @@ drawactive(int active)
 {
 	if(active){
 		drawblankscreen(0);
-		sdraw.blanktime = 0;
+		sdraw.blanktime = MACHP(0)->ticks;
 	}else{
-		if(blanktime && TK2SEC(sdraw.blanktime)/60 >= blanktime)
+		if(blanktime && sdraw.blanktime && TK2SEC(MACHP(0)->ticks - sdraw.blanktime)/60 >= blanktime)
 			drawblankscreen(1);
-		else
-			sdraw.blanktime++;
 	}
 }
+
+int
+drawidletime(void)
+{
+	return TK2SEC(MACHP(0)->ticks - sdraw.blanktime)/60;
+}
+

+ 27 - 13
sys/src/9/port/devmnt.c

@@ -829,6 +829,24 @@ mountio(Mnt *m, Mntrpc *r)
 	mntflushfree(m, r);
 }
 
+static int
+doread(Mnt *m, int len)
+{
+	Block *b;
+
+	while(qlen(m->q) < len){
+		b = devtab[m->c->type]->bread(m->c, m->msize, 0);
+		if(b == nil)
+			return -1;
+		if(BLEN(b) == 0){
+			freeblist(b);
+			return -1;
+		}
+		qaddlist(m->q, b);
+	}
+	return 0;
+}
+
 int
 mntrpcread(Mnt *m, Mntrpc *r)
 {
@@ -839,22 +857,18 @@ mntrpcread(Mnt *m, Mntrpc *r)
 	r->reply.tag = 0;
 
 	/* read at least length, type, and tag and pullup to a single block */
-	while(qlen(m->q) < BIT32SZ+BIT8SZ+BIT16SZ){
-		b = devtab[m->c->type]->bread(m->c, m->msize, 0);
-		if(b == nil)
-			return -1;
-		qaddlist(m->q, b);
-	}
+	if(doread(m, BIT32SZ+BIT8SZ+BIT16SZ) < 0)
+		return -1;
 	nb = pullupqueue(m->q, BIT32SZ+BIT8SZ+BIT16SZ);
-	len = GBIT32(nb->rp);
 
-	/* read in the rest of the message */
-	while(qlen(m->q) < len){
-		b = devtab[m->c->type]->bread(m->c, m->msize, 0);
-		if(b == nil)
-			return -1;
-		qaddlist(m->q, b);
+	/* read in the rest of the message, avoid rediculous (for now) message sizes */
+	len = GBIT32(nb->rp);
+	if(len > m->msize){
+		qdiscard(m->q, qlen(m->q));
+		return -1;
 	}
+	if(doread(m, len) < 0)
+		return -1;
 
 	/* pullup the header (i.e. everything except data) */
 	t = nb->rp[BIT32SZ];

+ 102 - 38
sys/src/9/port/devroot.c

@@ -5,61 +5,90 @@
 #include	"fns.h"
 #include	"../port/error.h"
 
-enum{
-	Qdir=	0,
+enum
+{
+	Qdir = 0,
+	Qboot = 0x1000,
 
-	Nfiles=32,	/* max root files */
+	Nrootfiles = 32,
+	Nbootfiles = 16,
 };
 
-extern ulong	bootlen;
-extern uchar	bootcode[];
+typedef struct Dirlist Dirlist;
+struct Dirlist
+{
+	uint base;
+	Dirtab *dir;
+	uchar **data;
+	int ndir;
+	int mdir;
+};
 
-Dirtab rootdir[Nfiles] = {
-	".",	{Qdir, 0, QTDIR},	0,		DMDIR|0555,
+static Dirtab rootdir[Nrootfiles] = {
+	"#/",		{Qdir, 0, QTDIR},	0,		DMDIR|0555,
+	"boot",	{Qboot, 0, QTDIR},	0,		DMDIR|0555,
+};
+static uchar *rootdata[Nrootfiles];
+static Dirlist rootlist = 
+{
+	0,
+	rootdir,
+	rootdata,
+	2,
+	Nrootfiles
 };
 
-static uchar	*rootdata[Nfiles];
-static int	nroot = 1;
+static Dirtab bootdir[Nbootfiles] = {
+	"boot",	{Qboot, 0, QTDIR},	0,		DMDIR|0555,
+};
+static uchar *bootdata[Nbootfiles];
+static Dirlist bootlist =
+{
+	Qboot,
+	bootdir,
+	bootdata,
+	1,
+	Nbootfiles
+};
 
 /*
- *  add a root file
+ *  add a file to the list
  */
 static void
-addroot(char *name, uchar *contents, ulong len, int perm)
+addlist(Dirlist *l, char *name, uchar *contents, ulong len, int perm)
 {
 	Dirtab *d;
 
-	if(nroot >= Nfiles)
+	if(l->ndir >= l->mdir)
 		panic("too many root files");
-	rootdata[nroot] = contents;
-	d = &rootdir[nroot];
+	l->data[l->ndir] = contents;
+	d = &l->dir[l->ndir];
 	strcpy(d->name, name);
 	d->length = len;
 	d->perm = perm;
 	d->qid.type = 0;
 	d->qid.vers = 0;
-	d->qid.path = nroot+1;
+	d->qid.path = ++l->ndir + l->base;
 	if(perm & DMDIR)
 		d->qid.type |= QTDIR;
-	nroot++;
 }
 
 /*
  *  add a root file
  */
 void
-addrootfile(char *name, uchar *contents, ulong len)
+addbootfile(char *name, uchar *contents, ulong len)
 {
-	addroot(name, contents, len, 0555);
+	addlist(&bootlist, name, contents, len, 0555);
 }
 
 /*
- *  add a root file
+ *  add a root directory
  */
 static void
 addrootdir(char *name)
 {
-	addroot(name, nil, 0, DMDIR|0555);
+	addlist(&rootlist, name, nil, 0, DMDIR|0555);
 }
 
 static void
@@ -75,8 +104,6 @@ rootreset(void)
 	addrootdir("proc");
 	addrootdir("root");
 	addrootdir("srv");
-
-	addrootfile("boot", bootcode, bootlen);	/* always have a boot file */
 }
 
 static Chan*
@@ -85,27 +112,57 @@ rootattach(char *spec)
 	return devattach('/', spec);
 }
 
+static int
+rootgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
+{
+	int t;
+	Dirtab *d;
+	Dirlist *l;
+
+	switch((int)c->qid.path){
+	case Qdir:
+		return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp);
+	case Qboot:
+		if(s == DEVDOTDOT){
+			devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
+			return 1;
+		}
+		return devgen(c, name, bootlist.dir, bootlist.ndir, s, dp);
+	default:
+		if((int)c->qid.path < Qboot){
+			t = c->qid.path-1;
+			l = &rootlist;
+		}else{
+			t = c->qid.path - Qboot - 1;
+			l = &bootlist;
+		}
+		if(t >= l->ndir)
+			return -1;
+		if(s != 0)
+			return -1;
+		d = &l->dir[t];
+		devdir(c, d->qid, d->name, d->length, eve, d->perm, dp);
+		return 1;
+	}
+	return -1;
+}
+
 static Walkqid*
 rootwalk(Chan *c, Chan *nc, char **name, int nname)
 {
-	return devwalk(c,  nc, name, nname, rootdir, nroot, devgen);
+	return devwalk(c,  nc, name, nname, nil, 0, rootgen);
 }
 
 static int
 rootstat(Chan *c, uchar *dp, int n)
 {
-	return devstat(c, dp, n, rootdir, nroot, devgen);
+	return devstat(c, dp, n, nil, 0, rootgen);
 }
 
 static Chan*
 rootopen(Chan *c, int omode)
 {
-	switch((ulong)c->qid.path) {
-	default:
-		break;
-	}
-
-	return devopen(c, omode, rootdir, nroot, devgen);
+	return devopen(c, omode, nil, 0, devgen);
 }
 
 /*
@@ -121,17 +178,26 @@ rootread(Chan *c, void *buf, long n, vlong off)
 {
 	ulong t;
 	Dirtab *d;
+	Dirlist *l;
 	uchar *data;
 	ulong offset = off;
 
 	t = c->qid.path;
 	switch(t){
 	case Qdir:
-		return devdirread(c, buf, n, rootdir, nroot, devgen);
+	case Qboot:
+		return devdirread(c, buf, n, nil, 0, rootgen);
+	}
+
+	if(t<Qboot)
+		l = &rootlist;
+	else{
+		t -= Qboot;
+		l = &bootlist;
 	}
 
-	d = &rootdir[t-1];
-	data = rootdata[t-1];
+	d = &l->dir[t-1];
+	data = l->data[t-1];
 	if(offset >= d->length)
 		return 0;
 	if(offset+n > d->length)
@@ -141,12 +207,9 @@ rootread(Chan *c, void *buf, long n, vlong off)
 }
 
 static long
-rootwrite(Chan *c, void*, long, vlong)
+rootwrite(Chan*, void*, long, vlong)
 {
-	switch((ulong)c->qid.path){
-	default:
-		error(Egreg);
-	}
+	error(Egreg);
 	return 0;
 }
 
@@ -170,3 +233,4 @@ Dev rootdevtab = {
 	devremove,
 	devwstat,
 };
+

+ 26 - 0
sys/src/9/port/initcode.c

@@ -0,0 +1,26 @@
+#include <u.h>
+#include <libc.h>
+
+char cons[] = "#c/cons";
+char boot[] = "/boot/boot";
+char dev[] = "/dev";
+char c[] = "#c";
+char e[] = "#e";
+char ec[] = "#ec";
+char s[] = "#s";
+char srv[] = "/srv";
+char env[] = "/env";
+
+void
+main(void)
+{
+	open(cons, OREAD);
+	open(cons, OWRITE);
+	open(cons, OWRITE);
+	bind(c, dev, MAFTER);
+	bind(ec, env, MAFTER);
+	bind(e, env, MCREATE|MAFTER);
+	bind(s, srv, MREPL|MCREATE);
+	execl(boot, boot, nil);
+	for(;;);
+}

+ 26 - 0
sys/src/9/port/mkbootrules

@@ -0,0 +1,26 @@
+#!/bin/rc
+
+awk -v 'objtype='$objtype '
+/^$/{
+		next;
+}
+/^#/{
+		next;
+}
+collect && /^[^ \t]/{
+		collect = 0;
+}
+collect && section ~ "bootdir"{
+		x = $1;
+		gsub(/[^a-zA-Z0-9_]/, "_", x);
+		printf "%s.root.s: %s\n\t../port/mkroot %s %s\n", x, $1, $1, x;
+}
+$0 ~ /^[^ \t]/{
+		if($0 ~ "bootdir"){
+			section = $0;
+			collect = 1;
+		}
+		next;
+}
+
+' $*

+ 17 - 2
sys/src/9/port/mkdevc

@@ -2,6 +2,7 @@
 
 awk -v 'objtype='$objtype '
 BEGIN{
+		nfs = 0;
 		if(ARGC < 2)
 			exit
 }
@@ -50,14 +51,28 @@ collect && section ~ "misc"{
 				x = "kfs";
 			if(x ~ "nfactotum")
 				x = "factotum";
+			fsname[nfs] = x;
 			fs[nfs++] = x;
 		}
 }
+collect && section ~ "bootdir"{
+		if(NF >= 2)
+			x = $2;
+		else{
+			x = $1;
+			sub(/.*\//, "", x);
+		}
+		fsname[nfs] = x;
+		x = $1;
+		gsub(/[^a-zA-Z0-9_]/, "_", x);
+		fs[nfs++] = x;
+}
+
 collect && section ~ "port"{
 		port[nport++] = $0;
 }
 $0 ~ /^[^ \t]/{
-		if($0 ~ "(dev|ip|link|misc|port)"){
+		if($0 ~ "(bootdir|dev|ip|link|misc|port)"){
 			section = $0;
 			collect = 1;
 		}
@@ -93,7 +108,7 @@ END{
 
 		printf "void links(void){\n";
 		for(i = 0; i < nfs; i++)
-			printf "\taddrootfile(\"%s\", %scode, %slen);\n", fs[i], fs[i], fs[i];
+			printf "\taddbootfile(\"%s\", %scode, %slen);\n", fsname[i], fs[i], fs[i];
 		for(i = 0; i < nlink; i++)
 			printf "\t%slink();\n", link[i];
 		printf "}\n\n";

+ 13 - 2
sys/src/9/port/mkdevlist

@@ -1,7 +1,7 @@
 #!/bin/rc
 
 awk '
-BEGIN{		collect = isdev = 0;
+BEGIN{		collect = isdev = isbootdir = 0;
 }
 
 /^$/{		next;
@@ -9,9 +9,15 @@ BEGIN{		collect = isdev = 0;
 /^#/{		next;
 }
 collect && /^[^	\t]/{
-		collect = isdev = 0;
+		collect = isdev = isbootdir = 0;
 }
 collect && $0 ~ /[^ \t]+/{
+		if(isbootdir){
+			x = $1;
+			gsub(/[^a-zA-Z0-9_]/, "_", x);
+			obj[x ".root.'$O'"]++;
+			next;
+		}
 		if(isdev)
 			obj["dev" $1 "'.$O'"]++;
 		else
@@ -28,10 +34,15 @@ $0 ~ /^[^ \t]/{
 		}
 		else if($1 ~ "misc" || $1 ~ "link" || $1 ~ "ip")
 			collect = 1;
+		else if($1 ~ "bootdir"){
+			isbootdir = 1;
+			collect = 1;
+		}
 		next
 }
 
 END{
+		x = ""
 		for(i in obj)
 			x = x i "\n"
 		printf x

+ 1 - 1
sys/src/9/port/mkextract

@@ -25,7 +25,7 @@ fn select {
 		/^#/			{ next }
 		doprint && /^[^	]/	{ doprint=0 }
 		doprint			{ print $'^$n^' }
-		$0 ~ "^'^$field^'"	{ doprint=1; next }
+		$1 ~ "^'^$field^'$"	{ doprint=1; next }
 	' $*
 }
 

+ 8 - 3
sys/src/9/port/mkroot

@@ -1,10 +1,15 @@
 #!/bin/rc
 
+rfork e
 echo mkroot $*
 if(! ~ $#* 2){
-	echo usage: mkroot file name >[2=1]
+	echo usage: mkroot path name >[2=1]
 	exit 1
 }
-strip $1.out
-aux/data2s $2 < $1.out > $1.root.s
+n=`{basename $1}
+cp $1 $2.out
+t=`{file $2.out}
+if(~ $"t *executable*)
+	strip $2.out
+aux/data2s $2 < $2.out > $2.root.s
 echo mkroot $* done

+ 1 - 1
sys/src/9/port/portfns.h

@@ -1,7 +1,7 @@
 void		accounttime(void);
 void		addclock0link(void (*)(void), int);
 int		addphysseg(Physseg*);
-void		addrootfile(char*, uchar*, ulong);
+void		addbootfile(char*, uchar*, ulong);
 Block*		adjustblock(Block*, int);
 void		alarmkproc(void*);
 Block*		allocb(int);

+ 10 - 49
sys/src/9/port/portmkfile

@@ -30,7 +30,7 @@ all:V:
 		mk 'CONF='$i
 
 clean:V:
-	rm -f *.[$OS] *.root.s cfs.h fs.h init.h conf.h *.out
+	rm -f *.[$OS] *.root.s cfs.h fs.h init.h conf.h *.out factotum.hack ipconfig.hack
 	for(i in $CONFLIST)
 		mk $i.clean
 
@@ -77,54 +77,15 @@ unthwack.$O:	../port/thwack.h
 devsdp.$O:	../port/thwack.h
 devrealtime.$O edf.$O realtime.$O: ../port/edf.h
 
-nkfs.root.s:	/$objtype/bin/disk/nkfs
-	cp $prereq nkfs.out
-	../port/mkroot nkfs kfs
-
-dossrv.root.s:	/$objtype/bin/dossrv
-	cp $prereq dossrv.out
-	../port/mkroot dossrv kfs
-
-bzfs.root.s: /sys/lib/dist/bin/$objtype/bzfs
-	cp $prereq bzfs.out
-	../port/mkroot bzfs kfs
-
-bzroot.root.s: /sys/lib/dist/pc/root.bz2
-	aux/data2s bzroot < /sys/lib/dist/pc/root.bz2 > bzroot.root.s
-
-9660srv.root.s: /$objtype/bin/9660srv
-	cp $prereq 9660srv.out	
-	../port/mkroot 9660srv kfs
-
-factotum.root.s:	/$objtype/bin/auth/factotum
-	cp $prereq factotum.out
-	../port/mkroot factotum factotum
-
-nfactotum.root.s: /$objtype/bin/auth/nfactotum
-	cp $prereq nfactotum.out
-	../port/mkroot nfactotum factotum
-
-rcmain.root.s: /rc/lib/rcmain
-	cp /rc/lib/rcmain rcmain.out
-	../port/mkroot rcmain rcmain
-
-%.root.s:	/$objtype/bin/%
-	cp $prereq $stem.out
-	../port/mkroot $stem $stem
-
-%.root.s:	/$objtype/bin/disk/%
-	cp $prereq $stem.out
-	../port/mkroot $stem $stem
-
-%.root.s:	/$objtype/bin/ip/%
-	cp $prereq $stem.out
-	../port/mkroot $stem $stem
-
-%.embed.root.s: ../embed/%
-	aux/data2s $stem < $prereq > $target
-
-boot$CONF.root.s: $CONF print.$O $BOOTDIR/boot.c $BOOTLIB
+boot$CONF.out: $CONF print.$O $BOOTDIR/boot.c $BOOTLIB
 	$BOOTDIR/mkboot $CONF > boot$CONF.c
 	$CC $CFLAGS boot$CONF.c
 	$LD -o boot$CONF.out boot$CONF.$O $BOOTLIB print.$O
-	../port/mkroot boot$CONF boot
+
+# this lets us say "factotum.hack factotum" instead of "/386/bin/auth/factotum factotum"
+# in the kernel config files.  the latter won't work until we have long file names.
+factotum.hack: /$objtype/bin/auth/factotum
+	cp $prereq $target
+
+ipconfig.hack: /$objtype/bin/ip/ipconfig
+	cp $prereq $target

+ 2 - 2
sys/src/cmd/crop.c

@@ -52,7 +52,7 @@ crop(Memimage *m, ulong c)
 		n = allocmemimage(m->r, RGBA32);
 		if(n == nil)
 			sysfatal("can't allocate temporary image: %r");
-		memimagedraw(n, n->r, m, m->r.min, nil, ZP);
+		memimagedraw(n, n->r, m, m->r.min, nil, ZP, S);
 		m = n;
 	}
 	wpl = wordsperline(m->r, m->depth);
@@ -201,7 +201,7 @@ main(int argc, char *argv[])
 	else
 		memfillcolor(new, 0x000000FF);
 
-	memimagedraw(new, m->clipr, m, m->clipr.min, nil, ZP);
+	memimagedraw(new, m->clipr, m, m->clipr.min, nil, ZP, S);
 	dw = byteaddr(new, ZP) - byteaddr(new, t);
 	new->r = rectaddpt(new->r, t);
 	new->zero += dw;

+ 1 - 2
sys/src/cmd/exportfs/exportfs.c

@@ -211,9 +211,8 @@ main(int argc, char **argv)
 	if(srv == nil && srvfd == -1 && write(0, "OK", 2) != 2)
 		fatal("open ack write");
 
-	if ((n = readn(netfd, &initial, sizeof(ulong))) < 0)
+	if (readn(netfd, &initial, sizeof(ulong)) < sizeof(ulong))
 		fatal("can't read initial string: %r\n");
-	assert(n == sizeof(ulong));
 
 	if (!strncmp((char *)&initial, "impo", sizeof(ulong))) {
 		char buf[128], *p, *args[3];

+ 20 - 8
sys/src/cmd/fax/mkfile

@@ -3,23 +3,35 @@
 TARG =	faxreceive\
 	faxsend\
 
-RECEIVE=\
+OFILES=\
 	fax2modem.$O\
-	fax2receive.$O\
 	file.$O\
-	receive.$O\
 	modem.$O\
 	subr.$O\
 
+RECEIVE=\
+	$OFILES\
+	receive.$O\
+	fax2receive.$O\
+
 SEND=\
-	fax2modem.$O\
-	fax2send.$O\
-	file.$O\
+	$OFILES\
 	send.$O\
-	modem.$O\
-	subr.$O\
+	fax2send.$O\
 
 BIN=/$objtype/bin/aux
+
+UPDATE=\
+	mkfile\
+	$HFILES\
+	${OFILES:%.$O=%.c}\
+	receive.c\
+	send.c\
+	fax2receive.c\
+	fax2send.c\
+	${TARG:%=%.c}\
+	${TARG:%=/386/bin/%}\
+
 </sys/src/cmd/mkmany
 
 $O.faxreceive: $RECEIVE

+ 1 - 1
sys/src/cmd/iconv.c

@@ -93,7 +93,7 @@ main(int argc, char *argv[])
 	if(n == nil)
 		sysfatal("can't allocate new image: %r");
 
-	memimagedraw(n, n->r, m, m->r.min, nil, ZP);
+	memimagedraw(n, n->r, m, m->r.min, nil, ZP, S);
 	if(uncompressed)
 		writeuncompressed(1, n);
 	else

+ 1 - 1
sys/src/cmd/jpg/multichan.c

@@ -49,6 +49,6 @@ memmultichan(Memimage *i)
 	ni = allocmemimage(i->r, RGB24);
 	if(ni == nil)
 		return ni;
-	memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min);
+	memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min, S);
 	return ni;
 }

+ 1 - 1
sys/src/cmd/jpg/onechan.c

@@ -210,7 +210,7 @@ memonechan(Memimage *i)
 		ni = allocmemimage(i->r, RGB24);
 		if(ni == nil)
 			return ni;
-		memimagedraw(ni, ni->r, i, i->r.min, nil, ZP);
+		memimagedraw(ni, ni->r, i, i->r.min, nil, ZP, S);
 		data = load(nil, ni);
 		freememimage(ni);
 	}

+ 1 - 1
sys/src/cmd/jpg/writepng.c

@@ -134,7 +134,7 @@ memRGB(Memimage *i)
 	ni = allocmemimage(i->r, RGB24);
 	if(ni == nil)
 		return ni;
-	memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min);
+	memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min, S);
 	return ni;
 }
 

+ 2 - 2
sys/src/cmd/postscript/p9bitpost/pslib.c

@@ -665,7 +665,7 @@ imagebits(Biobuf *ioutb, Memimage *im)
 			fprint(2, "p9bitpost: allocmemimage failed: %r\n");
 			exits("alloc");
 		}
-		memimagedraw(tmp, r, im, im->r.min, nil, ZP);
+		memimagedraw(tmp, r, im, im->r.min, nil, ZP, S);
 		im = tmp;
 	}
 	lsf = 0;
@@ -732,7 +732,7 @@ image2psfile(int fd, Memimage *im, int dpi) {
 		tmp = allocmemimage(im->r, strtochan("b8g8r8"));
 		if(tmp == nil)
 			return 1;
-		memimagedraw(tmp, tmp->r, im, im->r.min, nil, ZP);
+		memimagedraw(tmp, tmp->r, im, im->r.min, nil, ZP, S);
 		freememimage(im);
 		im = tmp;
 	}

+ 2 - 2
sys/src/cmd/resample.c

@@ -304,14 +304,14 @@ main(int argc, char *argv[])
 		t1 = allocmemimage(m->r, tchan);
 		if(t1 == nil)
 			sysfatal("can't allocate temporary image: %r");
-		memimagedraw(t1, t1->r, m, m->r.min, nil, ZP);
+		memimagedraw(t1, t1->r, m, m->r.min, nil, ZP, S);
 		t2 = resample(xsize, ysize, t1);
 		freememimage(t1);
 		new = allocmemimage(Rect(0, 0, xsize, ysize), m->chan);
 		if(new == nil)
 			sysfatal("can't allocate new image: %r");
 		/* should do error diffusion here */
-		memimagedraw(new, new->r, t2, t2->r.min, nil, ZP);
+		memimagedraw(new, new->r, t2, t2->r.min, nil, ZP, S);
 		freememimage(t2);
 		break;
 

+ 25 - 0
sys/src/cmd/venti/backup.example

@@ -0,0 +1,25 @@
+#!/bin/rc
+
+rfork e
+cd /usr/rsc
+. bkup.info
+fn x {
+	echo x $*
+	y=$1
+	if(~ $#$y 0){
+		$y=0
+	}
+	echo venti/wrarena -o $2 $3 $$y
+	end=`{venti/wrarena -o $2 $3 $$y | grep '^end offset ' | sed 's/^end offset //'}
+	if(~ $#end 1 && ! ~ $$y $end){
+		$y=$end
+		whatis $y >>bkup.info
+	}
+}
+hget http://127.1:8000/index | 
+awk '
+/^index=/ { blockSize=0+substr($3, 11); }
+/^arena=/ { arena=substr($1, 7); }
+/^	arena=/ { start=0+substr($5, 2)-blockSize; printf("x %s %d %s\n", arena, start, $3); }
+' |rc
+

+ 181 - 0
sys/src/cmd/venti/copy.c

@@ -0,0 +1,181 @@
+#include "stdinc.h"
+#include "dat.h"
+#include "fns.h"
+
+int fast;
+
+VtSession *zsrc, *zdst;
+
+void
+usage(void)
+{
+	fprint(2, "usage: copy src-host dst-host score [type]\n");
+	exits("usage");
+}
+
+int
+parseScore(uchar *score, char *buf, int n)
+{
+	int i, c;
+
+	memset(score, 0, VtScoreSize);
+
+	if(n < VtScoreSize*2)
+		return 0;
+	for(i=0; i<VtScoreSize*2; i++) {
+		if(buf[i] >= '0' && buf[i] <= '9')
+			c = buf[i] - '0';
+		else if(buf[i] >= 'a' && buf[i] <= 'f')
+			c = buf[i] - 'a' + 10;
+		else if(buf[i] >= 'A' && buf[i] <= 'F')
+			c = buf[i] - 'A' + 10;
+		else {
+			return 0;
+		}
+
+		if((i & 1) == 0)
+			c <<= 4;
+	
+		score[i>>1] |= c;
+	}
+	return 1;
+}
+
+void
+walk(uchar score[VtScoreSize], uint type, int base)
+{
+	int i, n, sub;
+	uchar *buf;
+	VtEntry e;
+	VtRoot root;
+
+	if(memcmp(score, vtZeroScore, VtScoreSize) == 0)
+		return;
+
+	buf = vtMemAllocZ(VtMaxLumpSize);
+	if(fast && vtRead(zdst, score, type, buf, VtMaxLumpSize) >= 0){
+		fprint(2, "skip %V\n", score);
+		free(buf);
+		return;
+	}
+
+	n = vtRead(zsrc, score, type, buf, VtMaxLumpSize);
+	if(n < 0){
+		fprint(2, "warning: could not read block %V %d: %R", score, type);
+		return;
+	}
+
+	switch(type){
+	case VtRootType:
+		if(!vtRootUnpack(&root, buf)){
+			fprint(2, "warning: could not unpack root in %V %d\n", score, type);
+			break;
+		}
+		walk(root.score, VtDirType, 0);
+		walk(root.prev, VtRootType, 0);
+		break;
+
+	case VtDirType:
+		for(i=0; i<n/VtEntrySize; i++){
+			if(!vtEntryUnpack(&e, buf, i)){
+				fprint(2, "warning: could not unpack entry #%d in %V %d\n", i, score, type);
+				continue;
+			}
+			if(!(e.flags & VtEntryActive))
+				continue;
+			if(e.flags&VtEntryDir)
+				base = VtDirType;
+			else
+				base = VtDataType;
+			if(e.depth == 0)
+				sub = base;
+			else
+				sub = VtPointerType0+e.depth-1;
+			walk(e.score, sub, base);
+		}
+		break;
+
+	case VtDataType:
+		break;
+
+	default:	/* pointers */
+		if(type == VtPointerType0)
+			sub = base;
+		else
+			sub = type-1;
+		for(i=0; i<n; i+=VtScoreSize)
+			if(memcmp(buf+i, vtZeroScore, VtScoreSize) != 0)
+				walk(buf+i, sub, base);
+		break;
+	}
+
+	if(!vtWrite(zdst, score, type, buf, n))
+		fprint(2, "warning: could not write block %V %d: %R", score, type);
+	free(buf);
+}
+
+int
+main(int argc, char *argv[])
+{
+	int type, n;
+	uchar score[VtScoreSize];
+	uchar *buf;
+
+	ARGBEGIN{
+	case 'f':
+		fast = 1;
+		break;
+	default:
+		usage();
+		break;
+	}ARGEND
+
+	if(argc != 3 && argc != 4)
+		usage();
+
+	vtAttach();
+
+	fmtinstall('V', vtScoreFmt);
+	fmtinstall('R', vtErrFmt);
+
+	if(!parseScore(score, argv[2], strlen(argv[2])))
+		vtFatal("could not parse score: %s", vtGetError());
+
+	buf = vtMemAllocZ(VtMaxLumpSize);
+
+	zsrc = vtDial(argv[0], 0);
+	if(zsrc == nil)
+		vtFatal("could not dial src server: %R");
+	if(!vtConnect(zsrc, 0))
+		sysfatal("vtConnect src: %r");
+
+	zdst = vtDial(argv[1], 0);
+	if(zdst == nil)
+		vtFatal("could not dial dst server: %R");
+	if(!vtConnect(zdst, 0))
+		sysfatal("vtConnect dst: %r");
+
+	if(argc == 4){
+		type = atoi(argv[3]);
+		n = vtRead(zsrc, score, type, buf, VtMaxLumpSize);
+		if(n < 0)
+			vtFatal("could not read block: %R");
+	}else{
+		for(type=0; type<VtMaxType; type++){
+			n = vtRead(zsrc, score, type, buf, VtMaxLumpSize);
+			if(n >= 0)
+				break;
+		}
+		if(type == VtMaxType)
+			vtFatal("could not find block %V of any type", score);
+	}
+
+	walk(score, type, VtDirType);
+
+	if(!vtSync(zdst))
+		vtFatal("could not sync dst server: %R");
+
+	vtDetach();
+	exits(0);
+	return 0;	/* shut up compiler */
+}

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

@@ -61,6 +61,7 @@ TARG=\
 	sync\
 	read\
 	write\
+	copy\
 #	dumparena\
 
 CFILES=${TARG:%=%.c} $LIBCFILES

+ 16 - 7
sys/src/cmd/venti/read.c

@@ -7,7 +7,7 @@ char *host;
 void
 usage(void)
 {
-	fprint(2, "usage: read [-h host] [-t type] score\n");
+	fprint(2, "usage: read [-h host] score [type]\n");
 	exits("usage");
 }
 
@@ -47,20 +47,16 @@ main(int argc, char *argv[])
 	uchar *buf;
 	VtSession *z;
 
-	type = VtDataType;
 	ARGBEGIN{
 	case 'h':
 		host = EARGF(usage());
 		break;
-	case 't':
-		type = atoi(EARGF(usage()));
-		break;
 	default:
 		usage();
 		break;
 	}ARGEND
 
-	if(argc != 1)
+	if(argc != 1 && argc != 2)
 		usage();
 
 	vtAttach();
@@ -80,7 +76,20 @@ main(int argc, char *argv[])
 	if(!vtConnect(z, 0))
 		sysfatal("vtConnect: %r");
 
-	n = vtRead(z, score, type, buf, VtMaxLumpSize);
+	if(argc == 1){
+		n = -1;
+		for(type=0; type<VtMaxType; type++){
+			n = vtRead(z, score, type, buf, VtMaxLumpSize);
+			if(n >= 0){
+				fprint(2, "venti/read%s%s %V %d\n", host ? " -h" : "", host ? host : "",
+					score, type);
+				break;
+			}
+		}
+	}else{
+		type = atoi(argv[1]);
+		n = vtRead(z, score, type, buf, VtMaxLumpSize);
+	}
 	vtClose(z);
 	if(n < 0)
 		vtFatal("could not read block: %s", vtGetError());

+ 1 - 0
sys/src/cmd/vl/l.h

@@ -203,6 +203,7 @@ EXTERN	long	datsize;
 EXTERN	char	debug[128];
 EXTERN	Prog*	etextp;
 EXTERN	Prog*	firstp;
+EXTERN	char	fnuxi4[4];	/* for 3l [sic] */
 EXTERN	char	fnuxi8[8];
 EXTERN	char*	noname;
 EXTERN	Sym*	hash[NHASH];

+ 49 - 15
sys/src/cmd/vnc/devdraw.c

@@ -77,6 +77,7 @@ struct Client
 	int		slot;
 	int		refreshme;
 	int		infoid;
+	int		op;
 };
 
 struct Refresh
@@ -774,10 +775,21 @@ drawnewclient(void)
 	memset(cl, 0, sizeof(Client));
 	cl->slot = i;
 	cl->clientid = ++sdraw.clientid;
+	cl->op = SoverD;
 	sdraw.client[i] = cl;
 	return cl;
 }
 
+static int
+drawclientop(Client *cl)
+{
+	int op;
+
+	op = cl->op;
+	cl->op = SoverD;
+	return op;
+}
+
 int
 drawhasclients(void)
 {
@@ -844,7 +856,7 @@ drawpoint(Point *p, uchar *a)
 }
 
 Point
-drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int index)
+drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int index, int op)
 {
 	FChar *fc;
 	Rectangle r;
@@ -857,7 +869,7 @@ drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int ind
 	r.max.y = r.min.y+(fc->maxy-fc->miny);
 	sp1.x = sp->x+fc->left;
 	sp1.y = sp->y+fc->miny;
-	memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny));
+	memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny), op);
 	p.x += fc->width;
 	sp->x += fc->width;
 	return p;
@@ -1299,7 +1311,7 @@ printmesg(char *fmt, uchar *a, int plsprnt)
 void
 drawmesg(Client *client, void *av, int n)
 {
-	int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, ox, oy, esize, doflush;
+	int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, op, ox, oy, oesize, esize, doflush;
 	uchar *u, *a, refresh;
 	char *fmt;
 	ulong value, chan;
@@ -1454,7 +1466,8 @@ drawmesg(Client *client, void *av, int n)
 			drawrectangle(&r, a+13);
 			drawpoint(&p, a+29);
 			drawpoint(&q, a+37);
-			memdraw(dst, r, src, p, mask, q);
+			op = drawclientop(client);
+			memdraw(dst, r, src, p, mask, q, op);
 			dstflush(dstid, dst, r);
 			continue;
 
@@ -1491,13 +1504,14 @@ drawmesg(Client *client, void *av, int n)
 				c = -1;
 			ox = BGLONG(a+37);
 			oy = BGLONG(a+41);
+			op = drawclientop(client);
 			/* high bit indicates arc angles are present */
 			if(ox & (1<<31)){
 				if((ox & (1<<30)) == 0)
 					ox &= ~(1<<31);
-				memarc(dst, p, e0, e1, c, src, sp, ox, oy);
+				memarc(dst, p, e0, e1, c, src, sp, ox, oy, op);
 			}else
-				memellipse(dst, p, e0, e1, c, src, sp);
+				memellipse(dst, p, e0, e1, c, src, sp, op);
 			dstflush(dstid, dst, Rect(p.x-e0-j, p.y-e1-j, p.x+e0+j+1, p.y+e1+j+1));
 			continue;
 
@@ -1564,7 +1578,7 @@ drawmesg(Client *client, void *av, int n)
 				error(Eindex);
 			drawrectangle(&r, a+11);
 			drawpoint(&p, a+27);
-			memdraw(font->image, r, src, p, memopaque, p);
+			memdraw(font->image, r, src, p, memopaque, p, S);
 			fc = &font->fchar[ci];
 			fc->minx = r.min.x;
 			fc->maxx = r.max.x;
@@ -1591,7 +1605,8 @@ drawmesg(Client *client, void *av, int n)
 				error("negative line width");
 			src = drawimage(client, a+33);
 			drawpoint(&sp, a+37);
-			memline(dst, p, q, e0, e1, j, src, sp);
+			op = drawclientop(client);
+			memline(dst, p, q, e0, e1, j, src, sp, op);
 			/* avoid memlinebbox if possible */
 			if(dstid==0 || dst->layer!=nil){
 				/* BUG: this is terribly inefficient: update maximal containing rect*/
@@ -1697,6 +1712,15 @@ drawmesg(Client *client, void *av, int n)
 			}
 			continue;
 
+		/* set compositing operator for next draw operation: 'O' op */
+		case 'O':
+			printmesg(fmt="b", a, 0);
+			m = 1+1;
+			if(n < m)
+				error(Eshortdraw);
+			client->op = a[1];
+			continue;
+
 		/* filled polygon: 'P' dstid[4] n[2] wind[4] ignore[2*4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
 		/* polygon: 'p' dstid[4] n[2] end0[4] end1[4] radius[4] srcid[4] sp[2*4] p0[2*4] dp[2*2*n] */
 		case 'p':
@@ -1729,8 +1753,11 @@ drawmesg(Client *client, void *av, int n)
 			if(dstid==0 || (dst->layer && dst->layer->screen->image->data == screenimage->data))
 				doflush = 1;	/* simplify test in loop */
 			ox = oy = 0;
+			esize = 0;
 			u = a+m;
 			for(y=0; y<ni; y++){
+				q = p;
+				oesize = esize;
 				u = drawcoord(u, a+n, ox, &p.x);
 				u = drawcoord(u, a+n, oy, &p.y);
 				ox = p.x;
@@ -1751,16 +1778,22 @@ drawmesg(Client *client, void *av, int n)
 					}
 					if(*a=='P' && e0!=1 && e0 !=~0)
 						r = dst->clipr;
-					else
-						r = Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1);
-					dstflush(dstid, dst, r);
+					else if(y > 0){
+						r = Rect(q.x-oesize, q.y-oesize, q.x+oesize+1, q.y+oesize+1);
+						combinerect(&r, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
+					}
+					if(rectclip(&r, dst->clipr))		/* should perhaps be an arg to dstflush */
+						dstflush(dstid, dst, r);
 				}
 				pp[y] = p;
 			}
+			if(y == 1)
+				dstflush(dstid, dst, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1));
+			op = drawclientop(client);
 			if(*a == 'p')
-				mempoly(dst, pp, ni, e0, e1, j, src, sp);
+				mempoly(dst, pp, ni, e0, e1, j, src, sp, op);
 			else
-				memfillpoly(dst, pp, ni, e0, src, sp);
+				memfillpoly(dst, pp, ni, e0, src, sp, op);
 			free(pp);
 			m = u-a;
 			continue;
@@ -1820,6 +1853,7 @@ drawmesg(Client *client, void *av, int n)
 				error(Eshortdraw);
 			clipr = dst->clipr;
 			dst->clipr = r;
+			op = drawclientop(client);
 			if(*a == 'x'){
 				/* paint background */
 				l = drawimage(client, a+47);
@@ -1838,7 +1872,7 @@ drawmesg(Client *client, void *av, int n)
 					r.max.x += font->fchar[ci].width;
 					u += 2;
 				}
-				memdraw(dst, r, l, q, memopaque, ZP);
+				memdraw(dst, r, l, q, memopaque, ZP, op);
 				u -= 2*ni;
 			}
 			q = p;
@@ -1848,7 +1882,7 @@ drawmesg(Client *client, void *av, int n)
 					dst->clipr = clipr;
 					error(Eindex);
 				}
-				q = drawchar(dst, q, src, &sp, font, ci);
+				q = drawchar(dst, q, src, &sp, font, ci, op);
 				u += 2;
 			}
 			dst->clipr = clipr;

+ 5 - 1
sys/src/cmd/vnc/kbd_vwr.c

@@ -113,8 +113,12 @@ readkbd(Vnc *v)
 				keyevent(v, Xctl, 1);
 				keyevent(v, r+0x60, 1);	/* 0x60: make capital letter */
 				keyevent(v, Xctl, 0);
-			} else
+			} else	{
 				keyevent(v, ks, 1);
+				keyevent(v, ks, 0);	/* vmware does autorepeat,
+							   shut it up with an UP
+							*/
+			}
 
 			if(alt) {
 				keyevent(v, Xalt, 0);

+ 10 - 10
sys/src/cmd/vnc/screen.c

@@ -113,9 +113,9 @@ screeninit(int x, int y, char *chanstr)
 	window.max.x = window.min.x + Dx(gscreen->r)*3/4-40;
 	window.max.y = window.min.y + Dy(gscreen->r)*3/4-100;
 
-	memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP);
+	memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S);
 	window = insetrect(window, 4);
-	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP);
+	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
 
 	/* a lot of work to get a grey color */
 	grey = allocmemimage(Rect(0,0,1,1), CMAP8);
@@ -123,7 +123,7 @@ screeninit(int x, int y, char *chanstr)
 	grey->clipr = gscreen->r;
 	memfillcolor(grey, 0xAAAAAAFF);
 	memimagedraw(gscreen, Rect(window.min.x, window.min.y,
-			window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP);
+			window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S);
 	freememimage(grey);
 	window = insetrect(window, 5);
 
@@ -196,8 +196,8 @@ cursordraw(Memimage *dst, Rectangle r)
 		loadmemimage(cursorclear, cursorr, clr, CURSORDIM*CURSORDIM/8);
 	}else
 		unlock(&cursor);
-	memimagedraw(dst, r, memwhite, ZP, cursorclear, ZP);
-	memimagedraw(dst, r, curscol, ZP, cursorset, ZP);
+	memimagedraw(dst, r, memwhite, ZP, cursorclear, ZP, S);
+	memimagedraw(dst, r, curscol, ZP, cursorset, ZP, S);
 }
 
 /*
@@ -280,9 +280,9 @@ scroll(void)
 	o = 8*h;
 	r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
 	p = Pt(window.min.x, window.min.y+o);
-	memimagedraw(gscreen, r, gscreen, p, nil, p);
+	memimagedraw(gscreen, r, gscreen, p, nil, p, S);
 	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
-	memimagedraw(gscreen, r, back, ZP, nil, ZP);
+	memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
 	flushmemscreen(gscreen->r);
 
 	curpos.y -= o;
@@ -318,7 +318,7 @@ screenputc(char *buf)
 		pos = (curpos.x-window.min.x)/w;
 		pos = 8-(pos%8);
 		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
-		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP);
+		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP, S);
 		addflush(r);
 		curpos.x += pos*w;
 		break;
@@ -327,7 +327,7 @@ screenputc(char *buf)
 			break;
 		xp--;
 		r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
-		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP);
+		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP, S);
 		addflush(r);
 		curpos.x = *xp;
 		break;
@@ -340,7 +340,7 @@ screenputc(char *buf)
 
 		*xp++ = curpos.x;
 		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
-		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP);
+		memimagedraw(gscreen, r, back, back->r.min, memopaque, ZP, S);
 		memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
 		addflush(r);
 		curpos.x += w;

+ 38 - 13
sys/src/cmd/vnc/vncs.c

@@ -6,6 +6,9 @@
 #include "screen.h"
 #include "kbd.h"
 
+#include <mp.h>
+#include <libsec.h>
+
 enum
 {
 	MaxCorreDim	= 48,
@@ -270,7 +273,7 @@ sendupdate(Vncs *v, int dowarp, Point warppt)
 	for(i = 0; i < updateregion.nrects; i++){
 		if(!docursor)
 			docursor = rectXrect(v->cursorr, updateregion.rects[i]);
-		memimagedraw(v->clientimage, updateregion.rects[i], gscreen, updateregion.rects[i].min, memopaque, ZP);
+		memimagedraw(v->clientimage, updateregion.rects[i], gscreen, updateregion.rects[i].min, memopaque, ZP, S);
 	}
 
 	if(docursor){
@@ -694,7 +697,7 @@ vnc_newclient(int dfd, int cfd)
 	Vncs * v;
 
 	/* caller returns to listen */
-	switch(rfork(RFPROC|RFMEM)){
+	switch(rfork(RFPROC|RFMEM|RFNAMEG)){
 	case -1:
 		close(dfd);
 		close(cfd);
@@ -834,15 +837,15 @@ noteshut(void*, char *msg)
  * auto:	/net | nil
  */
 int
-vncannounce(char *netmt, char * darg, char * adir)
+vncannounce(char *netmt, char * darg, char * adir, int bport)
 {
 	int port, eport, fd;
 	char portstr[NETPATHLEN];
 
-	port = 5900;
-	eport = port + 50;
+	port = bport;
+	eport = bport + 50;
 	if( darg != nil && darg[0] == ':' ) {
-		port = 5900 + strtol(&darg[1], nil, 10);
+		port = bport + strtol(&darg[1], nil, 10);
 		eport = port;
 	}
 
@@ -850,7 +853,7 @@ vncannounce(char *netmt, char * darg, char * adir)
 		snprint(portstr, NETPATHLEN, "%s/tcp!*!%d", netmt, port);
 		fd = announce(portstr, adir);
 		if( fd >= 0 ) {
-			fprint(2, "server started on display :%d\n", port-5900);
+			fprint(2, "server started on display :%d\n", port-bport);
 			return fd;
 		}
 	}
@@ -861,7 +864,7 @@ vncannounce(char *netmt, char * darg, char * adir)
 /* the user wants to kill the sever on a specified port 
 */
 static void
-vnckillsrv(char * netroot, char * portstr)
+vnckillsrv(char * netroot, char * portstr, int bport)
 {
 	int port, fd, lport;
 	char * p;
@@ -871,7 +874,7 @@ vnckillsrv(char * netroot, char * portstr)
 
 	port = atoi(portstr);
 	
-	port += 5900;
+	port += bport;
 	/* find the listener in /net/tcp/ */
 	snprint(buf, sizeof buf, "%s/tcp", netroot);
 	fdir = open(buf, OREAD);
@@ -924,9 +927,12 @@ void
 main(int argc, char * argv[])
 {
 	static char *defargv[] = { "/bin/rc", "-i", nil };
-	char *addr, netmt[NETPATHLEN], adir[NETPATHLEN], ldir[NETPATHLEN], *p, *darg, *karg;
-	int cfd, s, n, fd, w, h;
+	char *addr, netmt[NETPATHLEN], adir[NETPATHLEN], ldir[NETPATHLEN], *p, *darg, *karg, *pem;
+	int cfd, s, n, fd, w, h, vncport;
+	TLSconn *conn;
 
+	vncport = 5900;
+	pem = nil;
 	w = 1024;
 	h = 768;
 	addr = nil;
@@ -934,6 +940,12 @@ main(int argc, char * argv[])
 	karg = nil;
 	setnetmtpt(netmt, NETPATHLEN, nil);
 	ARGBEGIN{
+	case 'c':
+		pem = ARGF();
+		if(pem == nil)
+			usage();
+		vncport = 35729;	/* base port# for vnc/tls */
+		break;
 	case 'd':
 		darg = ARGF();
 		if(darg == nil || *darg != ':')
@@ -970,7 +982,7 @@ main(int argc, char * argv[])
 	if(karg != nil){
 		if(argc ||  darg != nil )
 			usage();
-		vnckillsrv(netmt, &karg[1]);
+		vnckillsrv(netmt, &karg[1], vncport);
 		exits(nil);
 	}
 
@@ -1045,7 +1057,7 @@ main(int argc, char * argv[])
 	/*
 	 * run the service
 	 */
-	srvfd = vncannounce(netmt, darg, adir);
+	srvfd = vncannounce(netmt, darg, adir, vncport);
 	if(srvfd < 0)
 		sysfatal("announce %s: %r", addr);
 
@@ -1063,6 +1075,19 @@ main(int argc, char * argv[])
 			fprint(2, "received call at %s\n", ldir);
 
 		s = accept(cfd, ldir);
+		if(pem != nil) {
+			/* this code requires the user's own
+				factotum running on the cpuserver
+			*/
+			conn = (TLSconn*)mallocz(sizeof *conn, 1);
+			conn->cert = readcert(pem, &conn->certlen);
+			s = tlsServer(s, conn);
+			if(conn->certlen) 
+				free(conn->cert);
+			if(conn->sessionIDlen)
+				free(conn->sessionID);
+			free(conn);
+		}
 		if(s < 0){
 			close(cfd);
 			continue;

+ 22 - 6
sys/src/libc/fmt/dofmt.c

@@ -239,8 +239,18 @@ _runefmt(Fmt *f)
 int
 fmtstrcpy(Fmt *f, char *s)
 {
+	int p, i;
 	if(!s)
 		return _fmtcpy(f, "<nil>", 5, 5);
+	/* if precision is specified, make sure we don't wander off the end */
+	if(f->flags & FmtPrec){
+		p = f->prec;
+		for(i = 0; i < p; i++)
+			if(s[i] == 0)
+				break;
+		return _fmtcpy(f, s, utfnlen(s, i), i);	/* BUG?: won't print a partial rune at end */
+	}
+
 	return _fmtcpy(f, s, utflen(s), strlen(s));
 }
 
@@ -259,15 +269,21 @@ int
 fmtrunestrcpy(Fmt *f, Rune *s)
 {
 	Rune *e;
-	int n;
+	int n, p;
 
 	if(!s)
 		return _fmtcpy(f, "<nil>", 5, 5);
-	for(e = s; *e; e++)
-		;
-	n = e - s;
-	if((f->flags & FmtPrec) && n > f->prec)
-		n = f->prec;
+	/* if precision is specified, make sure we don't wander off the end */
+	if(f->flags & FmtPrec){
+		p = f->prec;
+		for(n = 0; n < p; n++)
+			if(s[n] == 0)
+				break;
+	}else{
+		for(e = s; *e; e++)
+			;
+		n = e - s;
+	}
 	return _fmtrcpy(f, s, n);
 }
 

+ 1 - 0
sys/src/libmemdraw/alloc.c

@@ -95,6 +95,7 @@ allocmemimage(Rectangle r, ulong chan)
 
 	i = allocmemimaged(r, chan, md);
 	if(i == nil){
+		poolfree(imagmem, md->base);
 		free(md);
 		return nil;
 	}

+ 6 - 6
sys/src/libmemdraw/arc.c

@@ -33,7 +33,7 @@ Point p00;
  * wedge to make a mask through which to copy src to dst.
  */
 void
-memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int alpha, int phi)
+memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int alpha, int phi, int op)
 {
 	int i, w, beta, tmp, c1, c2, m, m1;
 	Rectangle rect;
@@ -57,7 +57,7 @@ memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int
 		phi = -phi;
 	}
 	if(phi >= 360){
-		memellipse(dst, c, a, b, t, src, sp);
+		memellipse(dst, c, a, b, t, src, sp, op);
 		return;
 	}
 	while(alpha < 0)
@@ -96,19 +96,19 @@ memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int
 	if(wedge == nil)
 		goto Return;
 	memfillcolor(wedge, DTransparent);
-	memfillpoly(wedge, bnd, i, ~0, memopaque, p00);
+	memfillpoly(wedge, bnd, i, ~0, memopaque, p00, S);
 	figure = allocmemimage(rect, GREY1);
 	if(figure == nil)
 		goto Return;
 	memfillcolor(figure, DTransparent);
-	memellipse(figure, p00, a, b, t, memopaque, p00);
+	memellipse(figure, p00, a, b, t, memopaque, p00, S);
 	mask = allocmemimage(rect, GREY1);
 	if(mask == nil)
 		goto Return;
 	memfillcolor(mask, DTransparent);
-	memimagedraw(mask, rect, figure, rect.min, wedge, rect.min);
+	memimagedraw(mask, rect, figure, rect.min, wedge, rect.min, S);
 	c = subpt(c, dst->r.min);
-	memdraw(dst, dst->r, src, subpt(sp, c), mask, subpt(p00, c));
+	memdraw(dst, dst->r, src, subpt(sp, c), mask, subpt(p00, c), op);
 
     Return:
 	freememimage(wedge);

File diff suppressed because it is too large
+ 529 - 87
sys/src/libmemdraw/draw.c


+ 6 - 4
sys/src/libmemdraw/ellipse.c

@@ -30,6 +30,7 @@ struct Param {
 	int			t;
 	Point			sp;
 	Memimage	*disc;
+	int			op;
 };
 
 /*
@@ -104,7 +105,7 @@ step(State *s)
 }
 
 void
-memellipse(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp)
+memellipse(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int op)
 {
 	State in, out;
 	int y, inb, inx, outx, u;
@@ -120,6 +121,7 @@ memellipse(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp)
 	p.t = t;
 	p.sp = subpt(sp, c);
 	p.disc = nil;
+	p.op = op;
 
 	u = (t<<1)*(a-b);
 	if(b<a && u>b*b || a<b && -u>a*a) {
@@ -178,7 +180,7 @@ bellipse(int y, State *s, Param *p)
 	if(p->disc == nil)
 		return;
 	memfillcolor(p->disc, DTransparent);
-	memellipse(p->disc, p00, t, t, -1, memopaque, p00);
+	memellipse(p->disc, p00, t, t, -1, memopaque, p00, p->op);
 	oy = y;
 	ox = 0;
 	nx = x = step(s);
@@ -209,7 +211,7 @@ erect(int x0, int y0, int x1, int y1, Param *p)
 
 /*	print("R %d,%d %d,%d\n", x0, y0, x1, y1); /**/
 	r = Rect(p->c.x+x0, p->c.y+y0, p->c.x+x1+1, p->c.y+y1+1);
-	memdraw(p->dst, r, p->src, addpt(p->sp, r.min), memopaque, p00);
+	memdraw(p->dst, r, p->src, addpt(p->sp, r.min), memopaque, p00, p->op);
 }
 
 /*
@@ -225,7 +227,7 @@ epoint(int x, int y, Param *p)
 /*	print("P%d %d,%d\n", p->t, x, y);	/**/
 	p0 = Pt(p->c.x+x, p->c.y+y);
 	r = Rpt(addpt(p0, p->disc->r.min), addpt(p0, p->disc->r.max));
-	memdraw(p->dst, r, p->src, addpt(p->sp, r.min), p->disc, p->disc->r.min);
+	memdraw(p->dst, r, p->src, addpt(p->sp, r.min), p->disc, p->disc->r.min, p->op);
 }
 
 /* 

+ 16 - 16
sys/src/libmemdraw/fillpoly.c

@@ -23,8 +23,8 @@ static	void	zsort(Seg **seg, Seg **ep);
 static	int	ycompare(void*, void*);
 static	int	xcompare(void*, void*);
 static	int	zcompare(void*, void*);
-static	void	xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int, int, int);
-static	void	yscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int);
+static	void	xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int, int, int, int);
+static	void	yscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int, int);
 
 static void
 fillcolor(Memimage *dst, int left, int right, int y, Memimage *src, Point p)
@@ -39,7 +39,7 @@ fillcolor(Memimage *dst, int left, int right, int y, Memimage *src, Point p)
 }
 
 static void
-fillline(Memimage *dst, int left, int right, int y, Memimage *src, Point p)
+fillline(Memimage *dst, int left, int right, int y, Memimage *src, Point p, int op)
 {
 	Rectangle r;
 
@@ -49,11 +49,11 @@ fillline(Memimage *dst, int left, int right, int y, Memimage *src, Point p)
 	r.max.y = y+1;
 	p.x += left;
 	p.y += y;
-	memdraw(dst, r, src, p, memopaque, p);
+	memdraw(dst, r, src, p, memopaque, p, op);
 }
 
 static void
-fillpoint(Memimage *dst, int x, int y, Memimage *src, Point p)
+fillpoint(Memimage *dst, int x, int y, Memimage *src, Point p, int op)
 {
 	Rectangle r;
 
@@ -63,17 +63,17 @@ fillpoint(Memimage *dst, int x, int y, Memimage *src, Point p)
 	r.max.y = y+1;
 	p.x += x;
 	p.y += y;
-	memdraw(dst, r, src, p, memopaque, p);
+	memdraw(dst, r, src, p, memopaque, p, op);
 }
 
 void
-memfillpoly(Memimage *dst, Point *vert, int nvert, int w, Memimage *src, Point sp)
+memfillpoly(Memimage *dst, Point *vert, int nvert, int w, Memimage *src, Point sp, int op)
 {
-	_memfillpolysc(dst, vert, nvert, w, src, sp, 0, 0, 0);
+	_memfillpolysc(dst, vert, nvert, w, src, sp, 0, 0, 0, op);
 }
 
 void
-_memfillpolysc(Memimage *dst, Point *vert, int nvert, int w, Memimage *src, Point sp, int detail, int fixshift, int clipped)
+_memfillpolysc(Memimage *dst, Point *vert, int nvert, int w, Memimage *src, Point sp, int detail, int fixshift, int clipped, int op)
 {
 	Seg **seg, *segtab;
 	Point p0;
@@ -111,9 +111,9 @@ _memfillpolysc(Memimage *dst, Point *vert, int nvert, int w, Memimage *src, Poin
 	if(!fixshift)
 		fixshift = 1;
 
-	xscan(dst, seg, segtab, nvert, w, src, sp, detail, fixshift, clipped);
+	xscan(dst, seg, segtab, nvert, w, src, sp, detail, fixshift, clipped, op);
 	if(detail)
-		yscan(dst, seg, segtab, nvert, w, src, sp, fixshift);
+		yscan(dst, seg, segtab, nvert, w, src, sp, fixshift, op);
 
 	free(seg);
 	free(segtab);
@@ -159,13 +159,13 @@ smuldivmod(long x, long y, long z, long *mod)
 }
 
 static void
-xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int detail, int fixshift, int clipped)
+xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int detail, int fixshift, int clipped, int op)
 {
 	long y, maxy, x, x2, xerr, xden, onehalf;
 	Seg **ep, **next, **p, **q, *s;
 	long n, i, iy, cnt, ix, ix2, minx, maxx;
 	Point pt;
-	void	(*fill)(Memimage*, int, int, int, Memimage*, Point);
+	void	(*fill)(Memimage*, int, int, int, Memimage*, Point, int);
 
 	fill = fillline;
 /*
@@ -300,7 +300,7 @@ xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src,
 				ix = (x + x2) >> (fixshift+1);
 				ix2 = ix+1;
 			}
-			(*fill)(dst, ix, ix2, iy, src, sp);
+			(*fill)(dst, ix, ix2, iy, src, sp, op);
 		}
 		y += (1<<fixshift);
 		iy++;
@@ -308,7 +308,7 @@ xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src,
 }
 
 static void
-yscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int fixshift)
+yscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int fixshift, int op)
 {
 	long x, maxx, y, y2, yerr, yden, onehalf;
 	Seg **ep, **next, **p, **q, *s;
@@ -428,7 +428,7 @@ yscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src,
 				if(yerr*p[0]->den + p[0]->zerr*yden > p[0]->den*yden)
 					y++;
 				iy = (y + y2) >> (fixshift+1);
-				fillpoint(dst, ix, iy, src, sp);
+				fillpoint(dst, ix, iy, src, sp, op);
 			}
 		}
 		x += (1<<fixshift);

+ 32 - 12
sys/src/libmemdraw/line.c

@@ -29,6 +29,7 @@ lmax(int a, int b)
 	return b;
 }
 
+#ifdef NOTUSED
 /*
  * Rather than line clip, we run the Bresenham loop over the full line,
  * and clip on each pixel.  This is more expensive but means that
@@ -240,6 +241,7 @@ verline(Memimage *dst, Point p0, Point p1, Memimage *src, Point dsrc, Rectangle
 		}
 	}
 }
+#endif /* NOTUSED */
 
 static Memimage*
 membrush(int radius)
@@ -252,7 +254,7 @@ membrush(int radius)
 		brush = allocmemimage(Rect(0, 0, 2*radius+1, 2*radius+1), memopaque->chan);
 		if(brush != nil){
 			memfillcolor(brush, DTransparent);	/* zeros */
-			memellipse(brush, Pt(radius, radius), radius, radius, -1, memopaque, Pt(radius, radius));
+			memellipse(brush, Pt(radius, radius), radius, radius, -1, memopaque, Pt(radius, radius), S);
 		}
 		brushradius = radius;
 	}
@@ -261,7 +263,7 @@ membrush(int radius)
 
 static
 void
-discend(Point p, int radius, Memimage *dst, Memimage *src, Point dsrc)
+discend(Point p, int radius, Memimage *dst, Memimage *src, Point dsrc, int op)
 {
 	Memimage *disc;
 	Rectangle r;
@@ -272,7 +274,7 @@ discend(Point p, int radius, Memimage *dst, Memimage *src, Point dsrc)
 		r.min.y = p.y - radius;
 		r.max.x = p.x + radius+1;
 		r.max.y = p.y + radius+1;
-		memdraw(dst, r, src, addpt(r.min, dsrc), disc, Pt(0,0));
+		memdraw(dst, r, src, addpt(r.min, dsrc), disc, Pt(0,0), op);
 	}
 }
 
@@ -311,7 +313,7 @@ arrowend(Point tip, Point *pp, int end, int sin, int cos, int radius)
 }
 
 void
-_memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr)
+_memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr, int op)
 {
 	/*
 	 * BUG: We should really really pick off purely horizontal and purely
@@ -321,7 +323,7 @@ _memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius,
 
 	int hor;
 	int sin, cos, dx, dy, t;
-	Rectangle oclipr;
+	Rectangle oclipr, r;
 	Point q, pts[10], *pp, d;
 
 	if(radius < 0)
@@ -354,6 +356,24 @@ _memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius,
 		end1 = t;
 	}
 
+	if((p0.x == p1.x || p0.y == p1.y) && (end0&0x1F) == Endsquare && (end1&0x1F) == Endsquare){
+		r.min = p0;
+		r.max = p1;
+		if(p0.x == p1.x){
+			r.min.x -= radius;
+			r.max.x += radius+1;
+		}
+		else{
+			r.min.y -= radius;
+			r.max.y += radius+1;
+		}
+		oclipr = dst->clipr;
+		dst->clipr = clipr;
+		memimagedraw(dst, r, src, sp, memopaque, sp, op);
+		dst->clipr = oclipr;
+		return;
+	}
+
 /*    Hard: */
 	/* draw thick line using polygon fill */
 	icossin2(p1.x-p0.x, p1.y-p0.y, &cos, &sin);
@@ -366,7 +386,7 @@ _memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius,
 	q.y = ICOSSCALE*p0.y+ICOSSCALE/2-sin/2;
 	switch(end0 & 0x1F){
 	case Enddisc:
-		discend(p0, radius, dst, src, d);
+		discend(p0, radius, dst, src, d, op);
 		/* fall through */
 	case Endsquare:
 	default:
@@ -379,7 +399,7 @@ _memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius,
 		break;
 	case Endarrow:
 		arrowend(q, pp, end0, -sin, -cos, radius);
-		_memfillpolysc(dst, pts, 5, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 1, 10, 1);
+		_memfillpolysc(dst, pts, 5, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 1, 10, 1, op);
 		pp[1] = pp[4];
 		pp += 2;
 	}
@@ -387,7 +407,7 @@ _memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius,
 	q.y = ICOSSCALE*p1.y+ICOSSCALE/2+sin/2;
 	switch(end1 & 0x1F){
 	case Enddisc:
-		discend(p1, radius, dst, src, d);
+		discend(p1, radius, dst, src, d, op);
 		/* fall through */
 	case Endsquare:
 	default:
@@ -400,19 +420,19 @@ _memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius,
 		break;
 	case Endarrow:
 		arrowend(q, pp, end1, sin, cos, radius);
-		_memfillpolysc(dst, pp, 5, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 1, 10, 1);
+		_memfillpolysc(dst, pp, 5, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 1, 10, 1, op);
 		pp[1] = pp[4];
 		pp += 2;
 	}
-	_memfillpolysc(dst, pts, pp-pts, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 0, 10, 1);
+	_memfillpolysc(dst, pts, pp-pts, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 0, 10, 1, op);
 	dst->clipr = oclipr;
 	return;
 }
 
 void
-memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp)
+memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, int op)
 {
-	_memimageline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr);
+	_memimageline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr, op);
 }
 
 /*

+ 13 - 11
sys/src/libmemdraw/openmemsubfont.c

@@ -16,26 +16,21 @@ openmemsubfont(char *name)
 	fd = open(name, OREAD);
 	if(fd < 0)
 		return nil;
+	p = nil;
 	i = readmemimage(fd);
 	if(i == nil)
-		return nil;
+		goto Err;
 	if(read(fd, hdr, 3*12) != 3*12){
-		freememimage(i);
 		werrstr("openmemsubfont: header read error: %r");
-		return nil;
+		goto Err;
 	}
 	n = atoi(hdr);
 	p = malloc(6*(n+1));
-	if(p == nil){
-		freememimage(i);
-		return nil;
-	}
+	if(p == nil)
+		goto Err;
 	if(read(fd, p, 6*(n+1)) != 6*(n+1)){
 		werrstr("openmemsubfont: fontchar read error: %r");
-    Err:
-		freememimage(i);
-		free(p);
-		return nil;
+		goto Err;
 	}
 	fc = malloc(sizeof(Fontchar)*(n+1));
 	if(fc == nil)
@@ -48,4 +43,11 @@ openmemsubfont(char *name)
 	}
 	free(p);
 	return sf;
+Err:
+	close(fd);
+	if (i != nil)
+		freememimage(i);
+	if (p != nil)
+		free(p);
+	return nil;
 }

+ 2 - 2
sys/src/libmemdraw/poly.c

@@ -5,7 +5,7 @@
 #include <memlayer.h>
 
 void
-mempoly(Memimage *dst, Point *vert, int nvert, int end0, int end1, int radius, Memimage *src, Point sp)
+mempoly(Memimage *dst, Point *vert, int nvert, int end0, int end1, int radius, Memimage *src, Point sp, int op)
 {
 	int i, e0, e1;
 	Point d;
@@ -19,6 +19,6 @@ mempoly(Memimage *dst, Point *vert, int nvert, int end0, int end1, int radius, M
 			e0 = end0;
 		if(i == nvert-1)
 			e1 = end1;
-		memline(dst, vert[i-1], vert[i], e0, e1, radius, src, addpt(d, vert[i-1]));
+		memline(dst, vert[i-1], vert[i], e0, e1, radius, src, addpt(d, vert[i-1]), op);
 	}
 }

+ 1 - 1
sys/src/libmemdraw/string.c

@@ -30,7 +30,7 @@ memimagestring(Memimage *b, Point p, Memimage *color, Point cp, Memsubfont *f, c
 		i = f->info+c;
 		width = i->width;
 		memdraw(b, Rect(p.x+i->left, p.y+i->top, p.x+i->left+(i[1].x-i[0].x), p.y+i->bottom),
-			color, cp, f->bits, Pt(i->x, i->top));
+			color, cp, f->bits, Pt(i->x, i->top), SoverD);
 	}
 	return p;
 }

+ 6 - 4
sys/src/libmemlayer/draw.c

@@ -12,6 +12,7 @@ struct Draw
 	Memlayer		*dstlayer;
 	Memimage	*src;
 	Memimage	*mask;
+	int	op;
 };
 
 static
@@ -47,11 +48,11 @@ ldrawop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave
 		if(!ok)
 			return;
 	}
-	memdraw(dst, r, d->src, p0, d->mask, p1);
+	memdraw(dst, r, d->src, p0, d->mask, p1, d->op);
 }
 
 void
-memdraw(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage *mask, Point p1)
+memdraw(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage *mask, Point p1, int op)
 {
 	struct Draw d;
 	Rectangle srcr, tr, mr;
@@ -70,7 +71,7 @@ if(drawdebug)	iprint("mask->layer != nil\n");
 
     Top:
 	if(dst->layer==nil && src->layer==nil){
-		memimagedraw(dst, r, src, p0, mask, p1);
+		memimagedraw(dst, r, src, p0, mask, p1, op);
 		return;
 	}
 
@@ -141,7 +142,7 @@ if(drawdebug)	iprint("drawclip dstcr %R srccr %R maskcr %R\n", dst->clipr, src->
 			memlhide(dst, srcr);
 		}
 		memdraw(dl->save, rectsubpt(r, dl->delta), dl->save,
-			subpt(srcr.min, src->layer->delta), mask, p1);
+			subpt(srcr.min, src->layer->delta), mask, p1, op);
 		memlexpose(dst, r);
 		return;
 	}
@@ -180,6 +181,7 @@ if(drawdebug)	iprint("drawclip dstcr %R srccr %R maskcr %R\n", dst->clipr, src->
 	d.deltam = subpt(p1, r.min);
 	d.dstlayer = dl;
 	d.src = src;
+	d.op = op;
 	d.mask = mask;
 	_memlayerop(ldrawop, dst, r, r, &d);
 }

+ 1 - 1
sys/src/libmemlayer/lalloc.c

@@ -73,7 +73,7 @@ memlalloc(Memscreen *s, Rectangle screenr, Refreshfn refreshfn, void *refreshptr
 	if(val != DNofill){
 		memsetchan(paint, n->chan);
 		memfillcolor(paint, val);
-		memdraw(n, n->r, paint, n->r.min, nil, n->r.min);
+		memdraw(n, n->r, paint, n->r.min, nil, n->r.min, S);
 	}
 	return n;
 }

+ 1 - 1
sys/src/libmemlayer/layerop.c

@@ -26,7 +26,7 @@ _layerop(
 	fr = front->layer->screenr;
 	if(rectXrect(r, fr) == 0){
 		/* r doesn't touch this window; continue on next rearmost */
-assert(front && front->layer && front->layer->screen && front->layer->rear);
+		// assert(front && front->layer && front->layer->screen && front->layer->rear);
 		front = front->layer->rear;
 		goto Top;
 	}

+ 1 - 1
sys/src/libmemlayer/ldelete.c

@@ -21,7 +21,7 @@ memldelete(Memimage *i)
 	s = i->layer->screen;
 	if(s->fill){
 		i->clipr = i->r;
-		memdraw(i, i->r, s->fill, i->r.min, nil, i->r.min);
+		memdraw(i, i->r, s->fill, i->r.min, nil, i->r.min, S);
 	}
 	if(l->front){
 		l->front->layer->rear = nil;

+ 2 - 2
sys/src/libmemlayer/lhide.c

@@ -27,7 +27,7 @@ lhideop(Memimage *src, Rectangle screenr, Rectangle clipr, void *etc, int insave
 	l = etc;
 	if(src != l->save){	/* do nothing if src is already in save area */
 		r = rectsubpt(screenr, l->delta);
-		memdraw(l->save, r, src, screenr.min, nil, screenr.min);
+		memdraw(l->save, r, src, screenr.min, nil, screenr.min, S);
 	}
 }
 
@@ -54,7 +54,7 @@ lexposeop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insa
 	l = etc;
 	r = rectsubpt(screenr, l->delta);
 	if(l->save)
-		memdraw(dst, screenr, l->save, r.min, nil, r.min);
+		memdraw(dst, screenr, l->save, r.min, nil, r.min, S);
 	else
 		l->refreshfn(dst, r, l->refreshptr);
 }

+ 7 - 5
sys/src/libmemlayer/line.c

@@ -15,13 +15,14 @@ struct Lline
 	Point			sp;
 	Memlayer		*dstlayer;
 	Memimage	*src;
+	int			op;
 };
 
 static void llineop(Memimage*, Rectangle, Rectangle, void*, int);
 
 static
 void
-_memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr)
+_memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr, int op)
 {
 	Rectangle r;
 	struct Lline ll;
@@ -38,7 +39,7 @@ _memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memi
    Top:
 	dl = dst->layer;
 	if(dl == nil){
-		_memimageline(dst, p0, p1, end0, end1, radius, src, sp, clipr);
+		_memimageline(dst, p0, p1, end0, end1, radius, src, sp, clipr, op);
 		return;
 	}
 	if(!srcclipped){
@@ -86,6 +87,7 @@ _memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memi
 	ll.src = src;
 	ll.radius = radius;
 	ll.delta = dl->delta;
+	ll.op = op;
 	_memlayerop(llineop, dst, r, r, &ll);
 }
 
@@ -110,11 +112,11 @@ llineop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave
 		p0 = ll->p0;
 		p1 = ll->p1;
 	}
-	_memline(dst, p0, p1, ll->end0, ll->end1, ll->radius, ll->src, ll->sp, clipr);
+	_memline(dst, p0, p1, ll->end0, ll->end1, ll->radius, ll->src, ll->sp, clipr, ll->op);
 }
 
 void
-memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp)
+memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, int op)
 {
-	_memline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr);
+	_memline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr, op);
 }

+ 1 - 1
sys/src/libmemlayer/load.c

@@ -49,7 +49,7 @@ memload(Memimage *dst, Rectangle r, uchar *data, int n, int iscompressed)
 	if(tmp == nil)
 		return -1;
 	n = loadfn(tmp, lr, data, n);
-	memdraw(dst, lr, tmp, lr.min, nil, lr.min);
+	memdraw(dst, lr, tmp, lr.min, nil, lr.min, S);
 	freememimage(tmp);
 	return n;
 }

+ 2 - 2
sys/src/libmemlayer/lorigin.c

@@ -39,7 +39,7 @@ memlorigin(Memimage *i, Point log, Point scr)
 	wasclear = l->clear;
 	if(nsave){
 		if(!wasclear)
-			memimagedraw(nsave, nsave->r, l->save, l->save->r.min, nil, Pt(0,0));
+			memimagedraw(nsave, nsave->r, l->save, l->save->r.min, nil, Pt(0,0), S);
 		freememimage(l->save);
 		l->save = nsave;
 	}
@@ -90,7 +90,7 @@ memlorigin(Memimage *i, Point log, Point scr)
 	 * Everything's covered.  Copy to new position and delete shadow window.
 	 */
 	if(wasclear)
-		memdraw(s->image, newr, s->image, oldr.min, nil, Pt(0,0));
+		memdraw(s->image, newr, s->image, oldr.min, nil, Pt(0,0), S);
 	else
 		memlexpose(i, newr);
 	memldelete(shad);

+ 0 - 1
sys/src/libmemlayer/mkfile

@@ -25,6 +25,5 @@ UPDATE=\
 	mkfile\
 	$HFILES\
 	${OFILES:%.$O=%.c}\
-	${LIB:/$objtype/%=/386/%}\
 
 </sys/src/cmd/mksyslib

+ 1 - 1
sys/src/libmemlayer/unload.c

@@ -45,7 +45,7 @@ memunload(Memimage *src, Rectangle r, uchar *data, int n)
 	tmp = allocmemimage(lr, src->chan);
 	if(tmp == nil)
 		return -1;
-	memdraw(tmp, lr, src, lr.min, nil, lr.min);
+	memdraw(tmp, lr, src, lr.min, nil, lr.min, S);
 	n = unloadmemimage(tmp, lr, data, n);
 	freememimage(tmp);
 	return n;

Some files were not shown because too many files changed in this diff