From 45bab89362ebe122d60d5e9b1e2b949b26168db3 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Mon, 11 Apr 2011 19:47:05 +0000 Subject: livecd --- mnt/acme/.dummy | 0 mnt/apeselect/.dummy | 0 mnt/apm/.dummy | 0 mnt/arch/.dummy | 0 mnt/cd/.dummy | 0 mnt/cons/.dummy | 0 mnt/cons/cons/.dummy | 0 mnt/cons/consctl/.dummy | 0 mnt/consoles/.dummy | 0 mnt/doc/.dummy | 0 mnt/exportfs/.dummy | 0 mnt/exportfs/0/.dummy | 0 mnt/exportfs/1/.dummy | 0 mnt/exportfs/10/.dummy | 0 mnt/exportfs/11/.dummy | 0 mnt/exportfs/12/.dummy | 0 mnt/exportfs/13/.dummy | 0 mnt/exportfs/14/.dummy | 0 mnt/exportfs/15/.dummy | 0 mnt/exportfs/16/.dummy | 0 mnt/exportfs/2/.dummy | 0 mnt/exportfs/3/.dummy | 0 mnt/exportfs/4/.dummy | 0 mnt/exportfs/5/.dummy | 0 mnt/exportfs/6/.dummy | 0 mnt/exportfs/7/.dummy | 0 mnt/exportfs/8/.dummy | 0 mnt/exportfs/9/.dummy | 0 mnt/keys/.dummy | 0 mnt/lp/.dummy | 0 mnt/netkeys/.dummy | 0 mnt/news/.dummy | 0 mnt/plumb/.dummy | 0 mnt/rdb/.dummy | 0 mnt/temp/.dummy | 0 mnt/term/.dummy | 0 mnt/ums/.dummy | 0 mnt/vmware/.dummy | 0 mnt/web/.dummy | 0 mnt/webcookies/.dummy | 0 mnt/wiki/.dummy | 0 mnt/wrap/.dummy | 0 mnt/wsys/.dummy | 0 n/.dummy | 0 sys/lib/dist.old/cdstub/.dummy | 0 sys/lib/dist.old/cmd/bargraph.c | 346 ++++++++ sys/lib/dist.old/cmd/bflz.c | 374 ++++++++ sys/lib/dist.old/cmd/bzfs/bzfs.h | 11 + sys/lib/dist.old/cmd/bzfs/mkext.c | 288 +++++++ sys/lib/dist.old/cmd/bzfs/mkfile | 20 + sys/lib/dist.old/cmd/bzfs/oramfs.c | 927 ++++++++++++++++++++ sys/lib/dist.old/cmd/bzfs/unbflz.c | 108 +++ sys/lib/dist.old/cmd/bzfs/unbzip.c | 861 +++++++++++++++++++ sys/lib/dist.old/cmd/cdsh.c | 133 +++ sys/lib/dist.old/cmd/clog.c | 59 ++ sys/lib/dist.old/cmd/mkfile | 24 + sys/lib/dist.old/cmd/multi/mkfile | 76 ++ sys/lib/dist.old/cmd/multi/mkmulti | 70 ++ sys/lib/dist.old/cmd/multi/multi.c | 38 + sys/lib/dist.old/cmd/tailfsrv.c | 17 + sys/lib/dist.old/cmd/touchfs.c | 66 ++ sys/lib/dist.old/cmd/unbflz.c | 109 +++ sys/lib/dist.old/logcompress.awk | 15 + sys/lib/dist.old/logtime.awk | 3 + sys/lib/dist.old/mkfile | 221 +++++ sys/lib/dist.old/pc/cd0.proto | 1 + sys/lib/dist.old/pc/emptyfile | 0 sys/lib/dist.old/pc/glenda/bin/rc/riostart | 4 + sys/lib/dist.old/pc/glenda/lib/first.window | 11 + sys/lib/dist.old/pc/glenda/lib/profile | 16 + sys/lib/dist.old/pc/inst/bootfloppy | 47 + sys/lib/dist.old/pc/inst/bootplan9 | 55 ++ sys/lib/dist.old/pc/inst/bootsetup | 125 +++ sys/lib/dist.old/pc/inst/bootwin9x | 117 +++ sys/lib/dist.old/pc/inst/bootwinnt | 47 + sys/lib/dist.old/pc/inst/configarch | 40 + sys/lib/dist.old/pc/inst/configdist | 22 + sys/lib/dist.old/pc/inst/configether | 53 ++ sys/lib/dist.old/pc/inst/configfs | 23 + sys/lib/dist.old/pc/inst/configip | 64 ++ sys/lib/dist.old/pc/inst/confignet | 67 ++ sys/lib/dist.old/pc/inst/configppp | 63 ++ sys/lib/dist.old/pc/inst/copydist | 31 + sys/lib/dist.old/pc/inst/defs | 162 ++++ sys/lib/dist.old/pc/inst/download | 56 ++ sys/lib/dist.old/pc/inst/finish | 19 + sys/lib/dist.old/pc/inst/fmtfossil | 91 ++ sys/lib/dist.old/pc/inst/fmtventi | 190 +++++ sys/lib/dist.old/pc/inst/gui | 7 + sys/lib/dist.old/pc/inst/halt | 18 + sys/lib/dist.old/pc/inst/hasmbr | 12 + sys/lib/dist.old/pc/inst/hdrs | 7 + sys/lib/dist.old/pc/inst/is9660 | 12 + sys/lib/dist.old/pc/inst/isext2 | 11 + sys/lib/dist.old/pc/inst/isfat | 22 + sys/lib/dist.old/pc/inst/isfossil | 16 + sys/lib/dist.old/pc/inst/isventi | 13 + sys/lib/dist.old/pc/inst/isventiarenas | 13 + sys/lib/dist.old/pc/inst/isventiisect | 13 + sys/lib/dist.old/pc/inst/main | 115 +++ sys/lib/dist.old/pc/inst/mainloop | 23 + sys/lib/dist.old/pc/inst/mkini.awk | 59 ++ sys/lib/dist.old/pc/inst/mountdist | 222 +++++ sys/lib/dist.old/pc/inst/mountfossil | 104 +++ sys/lib/dist.old/pc/inst/mountfs | 14 + sys/lib/dist.old/pc/inst/moveoldfs | 72 ++ sys/lib/dist.old/pc/inst/partdisk | 73 ++ sys/lib/dist.old/pc/inst/prepdisk | 63 ++ sys/lib/dist.old/pc/inst/replcfg | 18 + sys/lib/dist.old/pc/inst/startether | 30 + sys/lib/dist.old/pc/inst/startppp | 30 + sys/lib/dist.old/pc/inst/startwin | 46 + sys/lib/dist.old/pc/inst/stop | 50 ++ sys/lib/dist.old/pc/inst/stopether | 20 + sys/lib/dist.old/pc/inst/stopppp | 19 + sys/lib/dist.old/pc/inst/textonly | 15 + sys/lib/dist.old/pc/inst/watchfd | 17 + sys/lib/dist.old/pc/inst/xxx | 9 + sys/lib/dist.old/pc/mkfile | 100 +++ sys/lib/dist.old/pc/plan9.ini | 37 + sys/lib/dist.old/pc/plan9.ini.blank | 10 + sys/lib/dist.old/pc/plan9.ini.cd | 40 + sys/lib/dist.old/pc/plan9.ini.vmware | 20 + sys/lib/dist.old/pc/proto | 175 ++++ sys/lib/dist.old/pc/sub/D003753 | 22 + sys/lib/dist.old/pc/sub/F004116 | 24 + sys/lib/dist.old/pc/sub/bind | 21 + sys/lib/dist.old/pc/sub/bunzip2 | 4 + sys/lib/dist.old/pc/sub/common | 123 +++ sys/lib/dist.old/pc/sub/compactdb | 4 + sys/lib/dist.old/pc/sub/local | 8 + sys/lib/dist.old/pc/sub/mkdir | 3 + sys/lib/dist.old/pc/sub/ndist | 16 + sys/lib/dist.old/pc/sub/pci | 5 + sys/lib/dist.old/pc/sub/pwd | 3 + sys/lib/dist.old/pc/sub/ramfs | 4 + sys/lib/dist.old/pc/sub/sleep | 8 + sys/lib/dist.old/pc/sub/termrc | 121 +++ sys/lib/dist.old/pc/sub/unmount | 3 + sys/lib/dist.old/pc/sub/users | 7 + sys/lib/dist.old/pc/sub/vmware | 10 + sys/lib/dist.old/pc/subst/plan9.ini | 40 + sys/lib/dist.old/setup | 10 + sys/lib/dist/cdstub/.dummy | 0 sys/lib/dist/cdstub/bootdisk.img | 0 sys/lib/dist/cmd/bargraph.c | 346 -------- sys/lib/dist/cmd/bflz.c | 374 -------- sys/lib/dist/cmd/bzfs/bzfs.h | 11 - sys/lib/dist/cmd/bzfs/mkext.c | 288 ------- sys/lib/dist/cmd/bzfs/mkfile | 20 - sys/lib/dist/cmd/bzfs/oramfs.c | 927 -------------------- sys/lib/dist/cmd/bzfs/unbflz.c | 108 --- sys/lib/dist/cmd/bzfs/unbzip.c | 861 ------------------- sys/lib/dist/cmd/cdsh.c | 133 --- sys/lib/dist/cmd/clog.c | 59 -- sys/lib/dist/cmd/mkfile | 24 - sys/lib/dist/cmd/multi/mkfile | 76 -- sys/lib/dist/cmd/multi/mkmulti | 70 -- sys/lib/dist/cmd/multi/multi.c | 38 - sys/lib/dist/cmd/tailfsrv.c | 17 - sys/lib/dist/cmd/touchfs.c | 66 -- sys/lib/dist/cmd/unbflz.c | 109 --- sys/lib/dist/logcompress.awk | 15 - sys/lib/dist/logtime.awk | 3 - sys/lib/dist/mkfile | 238 +----- sys/lib/dist/pc/cd0.proto | 1 - sys/lib/dist/pc/plan9.ini | 20 +- sys/lib/dist/pc/plan9.ini.cd | 23 +- sys/lib/dist/setup | 10 - sys/src/boot/pc/iso.c | 14 +- sys/src/cmd/aux/mkfile | 3 +- sys/src/cmd/aux/realemu/arg.c | 163 ++++ sys/src/cmd/aux/realemu/dat.h | 362 ++++++++ sys/src/cmd/aux/realemu/decode.c | 619 ++++++++++++++ sys/src/cmd/aux/realemu/fmt.c | 385 +++++++++ sys/src/cmd/aux/realemu/fns.h | 31 + sys/src/cmd/aux/realemu/loadcom.c | 43 + sys/src/cmd/aux/realemu/main.c | 784 +++++++++++++++++ sys/src/cmd/aux/realemu/mkfile | 13 + sys/src/cmd/aux/realemu/notes | 22 + sys/src/cmd/aux/realemu/pit.c | 357 ++++++++ sys/src/cmd/aux/realemu/realemu.man | 104 +++ sys/src/cmd/aux/realemu/vgalist | 9 + sys/src/cmd/aux/realemu/xec.c | 1224 +++++++++++++++++++++++++++ tmp/.dummy | 0 usr/glenda/bin/rc/pull | 17 + usr/glenda/bin/rc/riostart | 17 + usr/glenda/bin/rc/screensize | 9 + usr/glenda/lib/acme.dump | 12 + usr/glenda/lib/acme.dump.small | 16 + usr/glenda/lib/first.window | 5 + usr/glenda/lib/newstime | 0 usr/glenda/lib/plumbing | 6 + usr/glenda/lib/profile | 36 + usr/glenda/readme.acme | 102 +++ usr/glenda/readme.rio | 178 ++++ 196 files changed, 11580 insertions(+), 3819 deletions(-) create mode 100644 mnt/acme/.dummy create mode 100644 mnt/apeselect/.dummy create mode 100644 mnt/apm/.dummy create mode 100644 mnt/arch/.dummy create mode 100644 mnt/cd/.dummy create mode 100644 mnt/cons/.dummy create mode 100644 mnt/cons/cons/.dummy create mode 100644 mnt/cons/consctl/.dummy create mode 100644 mnt/consoles/.dummy create mode 100644 mnt/doc/.dummy create mode 100644 mnt/exportfs/.dummy create mode 100644 mnt/exportfs/0/.dummy create mode 100644 mnt/exportfs/1/.dummy create mode 100644 mnt/exportfs/10/.dummy create mode 100644 mnt/exportfs/11/.dummy create mode 100644 mnt/exportfs/12/.dummy create mode 100644 mnt/exportfs/13/.dummy create mode 100644 mnt/exportfs/14/.dummy create mode 100644 mnt/exportfs/15/.dummy create mode 100644 mnt/exportfs/16/.dummy create mode 100644 mnt/exportfs/2/.dummy create mode 100644 mnt/exportfs/3/.dummy create mode 100644 mnt/exportfs/4/.dummy create mode 100644 mnt/exportfs/5/.dummy create mode 100644 mnt/exportfs/6/.dummy create mode 100644 mnt/exportfs/7/.dummy create mode 100644 mnt/exportfs/8/.dummy create mode 100644 mnt/exportfs/9/.dummy create mode 100644 mnt/keys/.dummy create mode 100644 mnt/lp/.dummy create mode 100644 mnt/netkeys/.dummy create mode 100644 mnt/news/.dummy create mode 100644 mnt/plumb/.dummy create mode 100644 mnt/rdb/.dummy create mode 100644 mnt/temp/.dummy create mode 100644 mnt/term/.dummy create mode 100644 mnt/ums/.dummy create mode 100644 mnt/vmware/.dummy create mode 100644 mnt/web/.dummy create mode 100644 mnt/webcookies/.dummy create mode 100644 mnt/wiki/.dummy create mode 100644 mnt/wrap/.dummy create mode 100644 mnt/wsys/.dummy create mode 100644 n/.dummy create mode 100644 sys/lib/dist.old/cdstub/.dummy create mode 100644 sys/lib/dist.old/cmd/bargraph.c create mode 100644 sys/lib/dist.old/cmd/bflz.c create mode 100644 sys/lib/dist.old/cmd/bzfs/bzfs.h create mode 100644 sys/lib/dist.old/cmd/bzfs/mkext.c create mode 100644 sys/lib/dist.old/cmd/bzfs/mkfile create mode 100644 sys/lib/dist.old/cmd/bzfs/oramfs.c create mode 100644 sys/lib/dist.old/cmd/bzfs/unbflz.c create mode 100644 sys/lib/dist.old/cmd/bzfs/unbzip.c create mode 100644 sys/lib/dist.old/cmd/cdsh.c create mode 100644 sys/lib/dist.old/cmd/clog.c create mode 100644 sys/lib/dist.old/cmd/mkfile create mode 100644 sys/lib/dist.old/cmd/multi/mkfile create mode 100644 sys/lib/dist.old/cmd/multi/mkmulti create mode 100644 sys/lib/dist.old/cmd/multi/multi.c create mode 100644 sys/lib/dist.old/cmd/tailfsrv.c create mode 100644 sys/lib/dist.old/cmd/touchfs.c create mode 100644 sys/lib/dist.old/cmd/unbflz.c create mode 100755 sys/lib/dist.old/logcompress.awk create mode 100755 sys/lib/dist.old/logtime.awk create mode 100644 sys/lib/dist.old/mkfile create mode 100644 sys/lib/dist.old/pc/cd0.proto create mode 100644 sys/lib/dist.old/pc/emptyfile create mode 100755 sys/lib/dist.old/pc/glenda/bin/rc/riostart create mode 100644 sys/lib/dist.old/pc/glenda/lib/first.window create mode 100644 sys/lib/dist.old/pc/glenda/lib/profile create mode 100755 sys/lib/dist.old/pc/inst/bootfloppy create mode 100755 sys/lib/dist.old/pc/inst/bootplan9 create mode 100755 sys/lib/dist.old/pc/inst/bootsetup create mode 100755 sys/lib/dist.old/pc/inst/bootwin9x create mode 100755 sys/lib/dist.old/pc/inst/bootwinnt create mode 100755 sys/lib/dist.old/pc/inst/configarch create mode 100755 sys/lib/dist.old/pc/inst/configdist create mode 100755 sys/lib/dist.old/pc/inst/configether create mode 100755 sys/lib/dist.old/pc/inst/configfs create mode 100755 sys/lib/dist.old/pc/inst/configip create mode 100755 sys/lib/dist.old/pc/inst/confignet create mode 100755 sys/lib/dist.old/pc/inst/configppp create mode 100755 sys/lib/dist.old/pc/inst/copydist create mode 100755 sys/lib/dist.old/pc/inst/defs create mode 100755 sys/lib/dist.old/pc/inst/download create mode 100755 sys/lib/dist.old/pc/inst/finish create mode 100755 sys/lib/dist.old/pc/inst/fmtfossil create mode 100755 sys/lib/dist.old/pc/inst/fmtventi create mode 100755 sys/lib/dist.old/pc/inst/gui create mode 100755 sys/lib/dist.old/pc/inst/halt create mode 100755 sys/lib/dist.old/pc/inst/hasmbr create mode 100755 sys/lib/dist.old/pc/inst/hdrs create mode 100755 sys/lib/dist.old/pc/inst/is9660 create mode 100755 sys/lib/dist.old/pc/inst/isext2 create mode 100755 sys/lib/dist.old/pc/inst/isfat create mode 100755 sys/lib/dist.old/pc/inst/isfossil create mode 100755 sys/lib/dist.old/pc/inst/isventi create mode 100755 sys/lib/dist.old/pc/inst/isventiarenas create mode 100755 sys/lib/dist.old/pc/inst/isventiisect create mode 100755 sys/lib/dist.old/pc/inst/main create mode 100755 sys/lib/dist.old/pc/inst/mainloop create mode 100755 sys/lib/dist.old/pc/inst/mkini.awk create mode 100755 sys/lib/dist.old/pc/inst/mountdist create mode 100755 sys/lib/dist.old/pc/inst/mountfossil create mode 100755 sys/lib/dist.old/pc/inst/mountfs create mode 100755 sys/lib/dist.old/pc/inst/moveoldfs create mode 100755 sys/lib/dist.old/pc/inst/partdisk create mode 100755 sys/lib/dist.old/pc/inst/prepdisk create mode 100755 sys/lib/dist.old/pc/inst/replcfg create mode 100755 sys/lib/dist.old/pc/inst/startether create mode 100755 sys/lib/dist.old/pc/inst/startppp create mode 100755 sys/lib/dist.old/pc/inst/startwin create mode 100755 sys/lib/dist.old/pc/inst/stop create mode 100755 sys/lib/dist.old/pc/inst/stopether create mode 100755 sys/lib/dist.old/pc/inst/stopppp create mode 100755 sys/lib/dist.old/pc/inst/textonly create mode 100755 sys/lib/dist.old/pc/inst/watchfd create mode 100755 sys/lib/dist.old/pc/inst/xxx create mode 100644 sys/lib/dist.old/pc/mkfile create mode 100644 sys/lib/dist.old/pc/plan9.ini create mode 100644 sys/lib/dist.old/pc/plan9.ini.blank create mode 100644 sys/lib/dist.old/pc/plan9.ini.cd create mode 100644 sys/lib/dist.old/pc/plan9.ini.vmware create mode 100644 sys/lib/dist.old/pc/proto create mode 100755 sys/lib/dist.old/pc/sub/D003753 create mode 100755 sys/lib/dist.old/pc/sub/F004116 create mode 100755 sys/lib/dist.old/pc/sub/bind create mode 100755 sys/lib/dist.old/pc/sub/bunzip2 create mode 100755 sys/lib/dist.old/pc/sub/common create mode 100755 sys/lib/dist.old/pc/sub/compactdb create mode 100755 sys/lib/dist.old/pc/sub/local create mode 100755 sys/lib/dist.old/pc/sub/mkdir create mode 100755 sys/lib/dist.old/pc/sub/ndist create mode 100755 sys/lib/dist.old/pc/sub/pci create mode 100755 sys/lib/dist.old/pc/sub/pwd create mode 100755 sys/lib/dist.old/pc/sub/ramfs create mode 100755 sys/lib/dist.old/pc/sub/sleep create mode 100755 sys/lib/dist.old/pc/sub/termrc create mode 100755 sys/lib/dist.old/pc/sub/unmount create mode 100755 sys/lib/dist.old/pc/sub/users create mode 100755 sys/lib/dist.old/pc/sub/vmware create mode 100644 sys/lib/dist.old/pc/subst/plan9.ini create mode 100755 sys/lib/dist.old/setup delete mode 100644 sys/lib/dist/cdstub/.dummy delete mode 100644 sys/lib/dist/cdstub/bootdisk.img delete mode 100644 sys/lib/dist/cmd/bargraph.c delete mode 100644 sys/lib/dist/cmd/bflz.c delete mode 100644 sys/lib/dist/cmd/bzfs/bzfs.h delete mode 100644 sys/lib/dist/cmd/bzfs/mkext.c delete mode 100644 sys/lib/dist/cmd/bzfs/mkfile delete mode 100644 sys/lib/dist/cmd/bzfs/oramfs.c delete mode 100644 sys/lib/dist/cmd/bzfs/unbflz.c delete mode 100644 sys/lib/dist/cmd/bzfs/unbzip.c delete mode 100644 sys/lib/dist/cmd/cdsh.c delete mode 100644 sys/lib/dist/cmd/clog.c delete mode 100644 sys/lib/dist/cmd/mkfile delete mode 100644 sys/lib/dist/cmd/multi/mkfile delete mode 100644 sys/lib/dist/cmd/multi/mkmulti delete mode 100644 sys/lib/dist/cmd/multi/multi.c delete mode 100644 sys/lib/dist/cmd/tailfsrv.c delete mode 100644 sys/lib/dist/cmd/touchfs.c delete mode 100644 sys/lib/dist/cmd/unbflz.c delete mode 100644 sys/lib/dist/logcompress.awk delete mode 100644 sys/lib/dist/logtime.awk delete mode 100644 sys/lib/dist/pc/cd0.proto delete mode 100644 sys/lib/dist/setup create mode 100644 sys/src/cmd/aux/realemu/arg.c create mode 100644 sys/src/cmd/aux/realemu/dat.h create mode 100644 sys/src/cmd/aux/realemu/decode.c create mode 100644 sys/src/cmd/aux/realemu/fmt.c create mode 100644 sys/src/cmd/aux/realemu/fns.h create mode 100644 sys/src/cmd/aux/realemu/loadcom.c create mode 100644 sys/src/cmd/aux/realemu/main.c create mode 100644 sys/src/cmd/aux/realemu/mkfile create mode 100644 sys/src/cmd/aux/realemu/notes create mode 100644 sys/src/cmd/aux/realemu/pit.c create mode 100644 sys/src/cmd/aux/realemu/realemu.man create mode 100644 sys/src/cmd/aux/realemu/vgalist create mode 100644 sys/src/cmd/aux/realemu/xec.c create mode 100644 tmp/.dummy create mode 100755 usr/glenda/bin/rc/pull create mode 100755 usr/glenda/bin/rc/riostart create mode 100755 usr/glenda/bin/rc/screensize create mode 100644 usr/glenda/lib/acme.dump create mode 100644 usr/glenda/lib/acme.dump.small create mode 100755 usr/glenda/lib/first.window create mode 100644 usr/glenda/lib/newstime create mode 100644 usr/glenda/lib/plumbing create mode 100644 usr/glenda/lib/profile create mode 100644 usr/glenda/readme.acme create mode 100644 usr/glenda/readme.rio diff --git a/mnt/acme/.dummy b/mnt/acme/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/apeselect/.dummy b/mnt/apeselect/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/apm/.dummy b/mnt/apm/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/arch/.dummy b/mnt/arch/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/cd/.dummy b/mnt/cd/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/cons/.dummy b/mnt/cons/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/cons/cons/.dummy b/mnt/cons/cons/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/cons/consctl/.dummy b/mnt/cons/consctl/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/consoles/.dummy b/mnt/consoles/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/doc/.dummy b/mnt/doc/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/.dummy b/mnt/exportfs/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/0/.dummy b/mnt/exportfs/0/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/1/.dummy b/mnt/exportfs/1/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/10/.dummy b/mnt/exportfs/10/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/11/.dummy b/mnt/exportfs/11/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/12/.dummy b/mnt/exportfs/12/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/13/.dummy b/mnt/exportfs/13/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/14/.dummy b/mnt/exportfs/14/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/15/.dummy b/mnt/exportfs/15/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/16/.dummy b/mnt/exportfs/16/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/2/.dummy b/mnt/exportfs/2/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/3/.dummy b/mnt/exportfs/3/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/4/.dummy b/mnt/exportfs/4/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/5/.dummy b/mnt/exportfs/5/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/6/.dummy b/mnt/exportfs/6/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/7/.dummy b/mnt/exportfs/7/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/8/.dummy b/mnt/exportfs/8/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/9/.dummy b/mnt/exportfs/9/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/keys/.dummy b/mnt/keys/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/lp/.dummy b/mnt/lp/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/netkeys/.dummy b/mnt/netkeys/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/news/.dummy b/mnt/news/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/plumb/.dummy b/mnt/plumb/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/rdb/.dummy b/mnt/rdb/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/temp/.dummy b/mnt/temp/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/term/.dummy b/mnt/term/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/ums/.dummy b/mnt/ums/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/vmware/.dummy b/mnt/vmware/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/web/.dummy b/mnt/web/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/webcookies/.dummy b/mnt/webcookies/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/wiki/.dummy b/mnt/wiki/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/wrap/.dummy b/mnt/wrap/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/wsys/.dummy b/mnt/wsys/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/n/.dummy b/n/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/sys/lib/dist.old/cdstub/.dummy b/sys/lib/dist.old/cdstub/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/sys/lib/dist.old/cmd/bargraph.c b/sys/lib/dist.old/cmd/bargraph.c new file mode 100644 index 000000000..f7a142ea9 --- /dev/null +++ b/sys/lib/dist.old/cmd/bargraph.c @@ -0,0 +1,346 @@ +#include +#include +#include +#include +#include + +enum {PNCTL=3}; + +static char* rdenv(char*); +int newwin(char*); +Rectangle screenrect(void); + +int nokill; +int textmode; +char *title; + +Image *light; +Image *dark; +Image *text; + +void +initcolor(void) +{ + text = display->black; + light = allocimagemix(display, DPalegreen, DWhite); + dark = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DDarkgreen); +} + +Rectangle rbar; +Point ptext; +vlong n, d; +int last; +int lastp = -1; +int first = 1; + +char backup[80]; + +void +drawbar(void) +{ + int i, j; + int p; + char buf[200], bar[100], *s; + static char lastbar[100]; + + if(n > d || n < 0 || d <= 0) + return; + + i = (Dx(rbar)*n)/d; + p = (n*100LL)/d; + + if(textmode){ + bar[0] = '|'; + for(j=0; jr.min, Pt(Dx(rbar)-30, 4)), text, ZP, display->defaultfont, buf, light, ZP); + lastp = p; + } + + if(last != i){ + draw(screen, Rect(rbar.min.x+last, rbar.min.y, rbar.min.x+i, rbar.max.y), + dark, nil, ZP); + last = i; + } + flushimage(display, 1); +} + +void +eresized(int new) +{ + Point p, q; + Rectangle r; + + if(new && getwindow(display, Refnone) < 0) + fprint(2,"can't reattach to window"); + + r = screen->r; + draw(screen, r, light, nil, ZP); + p = string(screen, addpt(r.min, Pt(4,4)), text, ZP, + display->defaultfont, title); + + p.x = r.min.x+4; + p.y += display->defaultfont->height+4; + + q = subpt(r.max, Pt(4,4)); + rbar = Rpt(p, q); + + ptext = Pt(r.max.x-4-stringwidth(display->defaultfont, "100%"), r.min.x+4); + border(screen, rbar, -2, dark, ZP); + last = 0; + lastp = -1; + + drawbar(); +} + +void +bar(Biobuf *b) +{ + char *p, *f[2]; + Event e; + int k, die, parent, child; + + parent = getpid(); + + die = 0; + if(textmode) + child = -1; + else + switch(child = rfork(RFMEM|RFPROC)) { + case 0: + sleep(1000); + while(!die && (k = eread(Ekeyboard|Emouse, &e))) { + if(nokill==0 && k == Ekeyboard && (e.kbdc == 0x7F || e.kbdc == 0x03)) { /* del, ctl-c */ + die = 1; + postnote(PNPROC, parent, "interrupt"); + _exits("interrupt"); + } + } + _exits(0); + } + + while(!die && (p = Brdline(b, '\n'))) { + p[Blinelen(b)-1] = '\0'; + if(tokenize(p, f, 2) != 2) + continue; + n = strtoll(f[0], 0, 0); + d = strtoll(f[1], 0, 0); + drawbar(); + } + postnote(PNCTL, child, "kill"); +} + + +void +usage(void) +{ + fprint(2, "usage: bargraph [-kt] [-w minx,miny,maxx,maxy] 'title'\n"); + exits("usage"); +} + +void +main(int argc, char **argv) +{ + Biobuf b; + char *p, *q; + int lfd; + + p = "0,0,200,60"; + + ARGBEGIN{ + case 'w': + p = ARGF(); + break; + case 't': + textmode = 1; + break; + case 'k': + nokill = 1; + break; + default: + usage(); + }ARGEND; + + if(argc != 1) + usage(); + + title = argv[0]; + + lfd = dup(0, -1); + + while(q = strchr(p, ',')) + *q = ' '; + Binit(&b, lfd, OREAD); + if(textmode || newwin(p) < 0){ + textmode = 1; + rbar = Rect(0, 0, 60, 1); + }else{ + initdraw(0, 0, "bar"); + initcolor(); + einit(Emouse|Ekeyboard); + eresized(0); + } + bar(&b); +} + + +/* all code below this line should be in the library, but is stolen from colors instead */ +static char* +rdenv(char *name) +{ + char *v; + int fd, size; + + fd = open(name, OREAD); + if(fd < 0) + return 0; + size = seek(fd, 0, 2); + v = malloc(size+1); + if(v == 0){ + fprint(2, "%s: can't malloc: %r\n", argv0); + exits("no mem"); + } + seek(fd, 0, 0); + read(fd, v, size); + v[size] = 0; + close(fd); + return v; +} + +int +newwin(char *win) +{ + char *srv, *mntsrv; + char spec[100]; + int srvfd, cons, pid; + + switch(rfork(RFFDG|RFPROC|RFNAMEG|RFENVG|RFNOTEG|RFNOWAIT)){ + case -1: + fprint(2, "bargraph: can't fork: %r\n"); + return -1; + case 0: + break; + default: + exits(0); + } + + srv = rdenv("/env/wsys"); + if(srv == 0){ + mntsrv = rdenv("/mnt/term/env/wsys"); + if(mntsrv == 0){ + fprint(2, "bargraph: can't find $wsys\n"); + return -1; + } + srv = malloc(strlen(mntsrv)+10); + sprint(srv, "/mnt/term%s", mntsrv); + free(mntsrv); + pid = 0; /* can't send notes to remote processes! */ + }else + pid = getpid(); + USED(pid); + srvfd = open(srv, ORDWR); + free(srv); + if(srvfd == -1){ + fprint(2, "bargraph: can't open %s: %r\n", srv); + return -1; + } + sprint(spec, "new -r %s", win); + if(mount(srvfd, -1, "/mnt/wsys", 0, spec) == -1){ + fprint(2, "bargraph: can't mount /mnt/wsys: %r (spec=%s)\n", spec); + return -1; + } + close(srvfd); + unmount("/mnt/acme", "/dev"); + bind("/mnt/wsys", "/dev", MBEFORE); + cons = open("/dev/cons", OREAD); + if(cons==-1){ + NoCons: + fprint(2, "bargraph: can't open /dev/cons: %r"); + return -1; + } + dup(cons, 0); + close(cons); + cons = open("/dev/cons", OWRITE); + if(cons==-1) + goto NoCons; + dup(cons, 1); + dup(cons, 2); + close(cons); +// wctlfd = open("/dev/wctl", OWRITE); + return 0; +} + +Rectangle +screenrect(void) +{ + int fd; + char buf[12*5]; + + fd = open("/dev/screen", OREAD); + if(fd == -1) + fd=open("/mnt/term/dev/screen", OREAD); + if(fd == -1){ + fprint(2, "%s: can't open /dev/screen: %r\n", argv0); + exits("window read"); + } + if(read(fd, buf, sizeof buf) != sizeof buf){ + fprint(2, "%s: can't read /dev/screen: %r\n", argv0); + exits("screen read"); + } + close(fd); + return Rect(atoi(buf+12), atoi(buf+24), atoi(buf+36), atoi(buf+48)); +} + +int +postnote(int group, int pid, char *note) +{ + char file[128]; + int f, r; + + switch(group) { + case PNPROC: + sprint(file, "/proc/%d/note", pid); + break; + case PNGROUP: + sprint(file, "/proc/%d/notepg", pid); + break; + case PNCTL: + sprint(file, "/proc/%d/ctl", pid); + break; + default: + return -1; + } + + f = open(file, OWRITE); + if(f < 0) + return -1; + + r = strlen(note); + if(write(f, note, r) != r) { + close(f); + return -1; + } + close(f); + return 0; +} diff --git a/sys/lib/dist.old/cmd/bflz.c b/sys/lib/dist.old/cmd/bflz.c new file mode 100644 index 000000000..89cb361c2 --- /dev/null +++ b/sys/lib/dist.old/cmd/bflz.c @@ -0,0 +1,374 @@ +/* + * Extraordinarily brute force Lempel & Ziv-like + * compressor. The input file must fit in memory + * during compression, and the output file will + * be reconstructed in memory during decompression. + * We search for large common sequences and use a + * greedy algorithm to choose which sequence gets + * compressed first. + * + * Files begin with "BLZ\n" and a 32-bit uncompressed file length. + * + * Output format is a series of blocks followed by + * a raw data section. Each block begins with a 32-bit big-endian + * number. The top bit is type and the next 31 bits + * are uncompressed size. Type is one of + * 0 - use raw data for this length + * 1 - a 32-bit offset follows + * After the blocks come the raw data. (The end of the blocks can be + * noted by summing block lengths until you reach the file length.) + */ + +#include +#include +#include + +#define malloc sbrk + +int minrun = 16; +int win = 16; +ulong outn; +int verbose; +int mindist; + +enum { Prime = 16777213 }; /* smallest prime < 2^24 (so p*256+256 < 2^32) */ +enum { NOFF = 3 }; + +Biobuf bout; +ulong length; +uchar *data; +ulong sum32(ulong, void*, long); +uchar *odat; +int nodat; +int nraw; +int rawstart; +int acct; +int zlength; +int maxchain; +int maxrle[256]; +int nnew; + +typedef struct Node Node; +struct Node { + Node *link; + ulong key; + ulong offset[NOFF]; +}; + +Node *nodepool; +int nnodepool; + +Node **hash; +uint nhash; + +uint maxlen; +uint maxsame; +uint replacesame = 8*1024*1024; + +Node *freelist, **freeend; +uint nalloc; + +Node* +allocnode(void) +{ + int i; + Node *n; + + if(nnodepool == 0){ + nnodepool = 256*1024; + nodepool = malloc(sizeof(Node)*nnodepool); + } + if(freelist){ + n = freelist; + freelist = n->link; + return n; + } + assert(nnodepool > 0); + nalloc++; + n = &nodepool[--nnodepool]; + for(i=0; ioffset[i] = -1; + + return n; +} + +void +freenode(Node *n) +{ + if(freelist == nil) + freelist = n; + else + *freeend = n; + freeend = &n->link; + n->link = nil; +} + +Node** +llookup(ulong key) +{ + uint c; + Node **l, **top, *n; + + if(nhash == 0){ + uint x; + + x = length/8; + for(nhash=1; nhashlink){ + c++; + if((*l)->key == key){ + /* move to front */ + n = *l; + *l = n->link; + n->link = *top; + *top = n; + return top; + } + } + if(c > maxlen) + maxlen = c; + return l; +} + +Node* +lookup(ulong key) +{ + return *llookup(key); +} + +void +insertnode(ulong key, ulong offset) +{ + int i; + Node *n, **l; + + l = llookup(key); + if(*l == nil){ + if(l==&hash[key&(nhash-1)]) + nnew++; + *l = allocnode(); + (*l)->key = key; + } + n = *l; + + /* add or replace last */ + for(i=0; ioffset[i]!=-1; i++) + ; + n->offset[i] = offset; +} + +void +Bputint(Biobufhdr *b, int n) +{ + uchar p[4]; + + p[0] = n>>24; + p[1] = n>>16; + p[2] = n>>8; + p[3] = n; + Bwrite(b, p, 4); +} + +void +flushraw(void) +{ + if(nraw){ + if(verbose) + fprint(2, "Raw %d+%d\n", rawstart, nraw); + zlength += 4+nraw; + Bputint(&bout, (1<<31)|nraw); + memmove(odat+nodat, data+rawstart, nraw); + nodat += nraw; + nraw = 0; + } +} + +int +rawbyte(int i) +{ + assert(acct == i); + if(nraw == 0) + rawstart = i; + acct++; + nraw++; + return 1; +} + +int +refblock(int i, int len, int off) +{ + assert(acct == i); + acct += len; + if(nraw) + flushraw(); + if(verbose) + fprint(2, "Copy %d+%d from %d\n", i, len, off); + Bputint(&bout, len); + Bputint(&bout, off); + zlength += 4+4; + return len; +} + +int +cmprun(uchar *a, uchar *b, int len) +{ + int i; + + if(a==b) + return 0; + for(i=0; ioffset[o] == -1) + break; + run = cmprun(data+i, data+n->offset[o], length-i); + if(run > maxrun && n->offset[o]+mindist < i){ + maxrun = run; + maxoff = n->offset[o]; + best = o; + } + } + if(best > 0){ + o = n->offset[best]; + for(j=best; j>0; j--) + n->offset[j] = n->offset[j-1]; + n->offset[0] = o; + } + } + + if(maxrun >= minrun) + j = i+refblock(i, maxrun, maxoff); + else + j = i+rawbyte(i); + for(; imaxrle[data[i]]){ + maxrle[data[i]] = rle; + insertnode(sum, i); + } + sum = (sum*256+data[i+win]) % Prime; + sum = (sum + data[i]*outn) % Prime; + } + } + /* could do better here */ + for(; i 0){ + data = realloc(data, length+n); + if(data == nil) + sysfatal("realloc: %r"); + memmove(data+length, buf, n); + length += n; + if(n < sizeof buf) + break; + } + odat = malloc(length); + if(odat == nil) + sysfatal("malloc: %r"); + + Binit(&bout, 1, OWRITE); + Bprint(&bout, "BLZ\n"); + Bputint(&bout, length); + outn = 1; + for(i=0; i +#include +#include +#include +#include +#include "bzfs.h" + +enum{ + LEN = 8*1024, + NFLDS = 6, /* filename, modes, uid, gid, mtime, bytes */ +}; + +void mkdirs(char*, char*); +void mkdir(char*, ulong, ulong, char*, char*); +void extract(char*, ulong, ulong, char*, char*, ulong); +void seekpast(ulong); +void error(char*, ...); +void warn(char*, ...); +void usage(void); +char *mtpt; +Biobufhdr bin; +uchar binbuf[2*LEN]; + +void +usage(void) +{ + fprint(2, "usage: bzfs [-m mtpt] [-s] [-f file] [-h]\n"); + exits("usage"); +} + +/* + * floppy disks can only be read on 512-byte + * boundaries and in 512 byte multiples. + * feed one over a pipe to allow arbitrary reading. + */ +char zero[512]; +int +blockread(int in, char *first, int nfirst) +{ + int p[2], out, n, rv; + char blk[512]; + + if(pipe(p) < 0) + sysfatal("pipe: %r"); + rv = p[0]; + out = p[1]; + switch(rfork(RFPROC|RFNOTEG|RFFDG)){ + case -1: + sysfatal("fork: %r"); + case 0: + close(rv); + break; + default: + close(in); + close(out); + return rv; + } + + write(out, first, nfirst); + + while((n=read(in, blk, sizeof blk)) > 0){ + if(write(out, blk, n) != n) + break; + if(n == sizeof(blk) && memcmp(zero, blk, n) == n) + break; + } + _exits(0); + return -1; +} + +enum { NAMELEN = 28 }; + +void +main(int argc, char **argv) +{ + char *rargv[10]; + int rargc; + char *fields[NFLDS], name[2*LEN], *p, *namep; + char uid[NAMELEN], gid[NAMELEN]; + ulong mode, bytes, mtime; + char *file; + int i, n, stdin, fd, chatty; + char blk[512]; + + if(argc>1 && strcmp(argv[1], "RAMFS") == 0){ + argv[1] = argv[0]; + ramfsmain(argc-1, argv+1); + exits(nil); + } + if(argc>1 && strcmp(argv[1], "BUNZIP") == 0){ + _unbzip(0, 1); + exits(nil); + } + + rfork(RFNOTEG); + stdin = 0; + file = nil; + namep = name; + mtpt = "/root"; + chatty = 0; + ARGBEGIN{ + case 'd': + chatty = !chatty; + break; + case 'f': + file = ARGF(); + break; + case 's': + stdin++; + break; + case 'm': + mtpt = ARGF(); + break; + default: + usage(); + }ARGEND + + if(argc != 0) + usage(); + + if(file == nil) { + fprint(2, "must specify -f file\n"); + usage(); + } + + if((fd = open(file, OREAD)) < 0) { + fprint(2, "cannot open \"%s\": %r\n", file); + exits("open"); + } + + rargv[0] = "ramfs"; + rargc = 1; + if(stdin) + rargv[rargc++] = "-i"; + rargv[rargc++] = "-m"; + rargv[rargc++] = mtpt; + rargv[rargc] = nil; + ramfsmain(rargc, rargv); + + if(1 || strstr(file, "disk")) { /* search for archive on block boundary */ +if(chatty) fprint(2, "searching for bz\n"); + for(i=0;; i++){ + if((n = readn(fd, blk, sizeof blk)) != sizeof blk) + sysfatal("read %d gets %d: %r\n", i, n); + if(strncmp(blk, "bzfilesystem\n", 13) == 0) + break; + } +if(chatty) fprint(2, "found at %d\n", i); + } + + if(chdir(mtpt) < 0) + error("chdir %s: %r", mtpt); + + fd = unbflz(unbzip(blockread(fd, blk+13, sizeof(blk)-13))); + + Binits(&bin, fd, OREAD, binbuf, sizeof binbuf); + while(p = Brdline(&bin, '\n')){ + p[Blinelen(&bin)-1] = '\0'; +if(chatty) fprint(2, "%s\n", p); + if(strcmp(p, "end of archive") == 0){ + _exits(0); + } + if(getfields(p, fields, NFLDS, 0, " \t") != NFLDS){ + warn("too few fields in file header"); + continue; + } + strcpy(namep, fields[0]); + mode = strtoul(fields[1], 0, 8); + mtime = strtoul(fields[4], 0, 10); + bytes = strtoul(fields[5], 0, 10); + strncpy(uid, fields[2], NAMELEN); + strncpy(gid, fields[3], NAMELEN); + if(mode & DMDIR) + mkdir(name, mode, mtime, uid, gid); + else + extract(name, mode, mtime, uid, gid, bytes); + } + fprint(2, "premature end of archive\n"); + exits("premature end of archive"); +} + +char buf[8192]; + +int +ffcreate(char *name, ulong mode, char *uid, char *gid, ulong mtime, int length) +{ + int fd, om; + Dir nd; + + sprint(buf, "%s/%s", mtpt, name); + om = ORDWR; + if(mode&DMDIR) + om = OREAD; + if((fd = create(buf, om, (mode&DMDIR)|0666)) < 0) + error("create %s: %r", buf); + + nulldir(&nd); + nd.mode = mode; + nd.uid = uid; + nd.gid = gid; + nd.mtime = mtime; + if(length) + nd.length = length; + if(dirfwstat(fd, &nd) < 0) + error("fwstat %s: %r", buf); + + return fd; +} + +void +mkdir(char *name, ulong mode, ulong mtime, char *uid, char *gid) +{ + close(ffcreate(name, mode, uid, gid, mtime, 0)); +} + +void +extract(char *name, ulong mode, ulong mtime, char *uid, char *gid, ulong bytes) +{ + int fd, tot, n; + + fd = ffcreate(name, mode, uid, gid, mtime, bytes); + + for(tot = 0; tot < bytes; tot += n){ + n = sizeof buf; + if(tot + n > bytes) + n = bytes - tot; + n = Bread(&bin, buf, n); + if(n <= 0) + error("premature eof reading %s", name); + if(write(fd, buf, n) != n) + error("short write writing %s", name); + } + close(fd); +} + +void +error(char *fmt, ...) +{ + char buf[1024]; + va_list arg; + + sprint(buf, "%s: ", argv0); + va_start(arg, fmt); + vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg); + va_end(arg); + fprint(2, "%s\n", buf); + exits(0); +} + +void +warn(char *fmt, ...) +{ + char buf[1024]; + va_list arg; + + sprint(buf, "%s: ", argv0); + va_start(arg, fmt); + vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg); + va_end(arg); + fprint(2, "%s\n", buf); +} + +int +_efgfmt(Fmt*) +{ + return -1; +} diff --git a/sys/lib/dist.old/cmd/bzfs/mkfile b/sys/lib/dist.old/cmd/bzfs/mkfile new file mode 100644 index 000000000..df81b5641 --- /dev/null +++ b/sys/lib/dist.old/cmd/bzfs/mkfile @@ -0,0 +1,20 @@ + +#include +#include +#include +#include "bzfs.h" + +/* + * Rather than reading /adm/users, which is a lot of work for + * a toy program, we assume all groups have the form + * NNN:user:user: + * meaning that each user is the leader of his own group. + */ + +enum +{ + OPERM = 0x3, /* mask of all permission types in open mode */ + Nram = 512, + Maxsize = 512*1024*1024, + Maxfdata = 8192, +}; + +typedef struct Fid Fid; +typedef struct Ram Ram; + +struct Fid +{ + short busy; + short open; + short rclose; + int fid; + Fid *next; + char *user; + Ram *ram; +}; + +struct Ram +{ + short busy; + short open; + long parent; /* index in Ram array */ + Qid qid; + long perm; + char *name; + ulong atime; + ulong mtime; + char *user; + char *group; + char *muid; + char *data; + long ndata; +}; + +enum +{ + Pexec = 1, + Pwrite = 2, + Pread = 4, + Pother = 1, + Pgroup = 8, + Powner = 64, +}; + +ulong path; /* incremented for each new file */ +Fid *fids; +Ram ram[Nram]; +int nram; +int mfd[2]; +char *user; +uchar mdata[IOHDRSZ+Maxfdata]; +uchar rdata[Maxfdata]; /* buffer for data in reply */ +uchar statbuf[STATMAX]; +Fcall thdr; +Fcall rhdr; +int messagesize = sizeof mdata; + +Fid * newfid(int); +uint ramstat(Ram*, uchar*, uint); +void io(void); +void *erealloc(void*, ulong); +void *emalloc(ulong); +char *estrdup(char*); +void ramfsusage(void); +int perm(Fid*, Ram*, int); +char *atom(char*); + +char *rflush(Fid*), *rversion(Fid*), *rauth(Fid*), + *rattach(Fid*), *rwalk(Fid*), + *ropen(Fid*), *rcreate(Fid*), + *rread(Fid*), *rwrite(Fid*), *rclunk(Fid*), + *rremove(Fid*), *rstat(Fid*), *rwstat(Fid*); + +char *(*fcalls[])(Fid*) = { + [Tversion] rversion, + [Tflush] rflush, + [Tauth] rauth, + [Tattach] rattach, + [Twalk] rwalk, + [Topen] ropen, + [Tcreate] rcreate, + [Tread] rread, + [Twrite] rwrite, + [Tclunk] rclunk, + [Tremove] rremove, + [Tstat] rstat, + [Twstat] rwstat, +}; + +char Eperm[] = "permission denied"; +char Enotdir[] = "not a directory"; +char Enoauth[] = "no authentication in ramfs"; +char Enotexist[] = "file does not exist"; +char Einuse[] = "file in use"; +char Eexist[] = "file exists"; +char Eisdir[] = "file is a directory"; +char Enotowner[] = "not owner"; +char Eisopen[] = "file already open for I/O"; +char Excl[] = "exclusive use file already open"; +char Ename[] = "illegal name"; +char Eversion[] = "unknown 9P version"; + +int debug; + +void +notifyf(void *a, char *s) +{ + USED(a); + if(strncmp(s, "interrupt", 9) == 0) + noted(NCONT); + noted(NDFLT); +} + +void +ramfsmain(int argc, char *argv[]) +{ + Ram *r; + char *defmnt; + int p[2]; + char buf[32]; + int fd, srvfd; + int stdio = 0; + + srvfd = -1; + defmnt = "/tmp"; + ARGBEGIN{ + case 'D': + debug = 1; + break; + case 'i': /* this is DIFFERENT from normal ramfs; use 1 for both for kernel */ + defmnt = 0; + stdio = 1; + srvfd = 0; + mfd[0] = 1; + mfd[1] = 1; + break; + case 's': + defmnt = 0; + break; + case 'm': + defmnt = ARGF(); + break; + default: + ramfsusage(); + }ARGEND + + if(!stdio){ + if(pipe(p) < 0) + error("pipe failed"); + srvfd = p[1]; + mfd[0] = p[0]; + mfd[1] = p[0]; + if(defmnt == 0){ + fd = create("#s/ramfs", OWRITE, 0666); + if(fd < 0) + error("create of /srv/ramfs failed"); + sprint(buf, "%d", p[1]); + if(write(fd, buf, strlen(buf)) < 0) + error("writing /srv/ramfs"); + } + } + + user = atom(getuser()); + notify(notifyf); + nram = 1; + r = &ram[0]; + r->busy = 1; + r->data = 0; + r->ndata = 0; + r->perm = DMDIR | 0775; + r->qid.type = QTDIR; + r->qid.path = 0LL; + r->qid.vers = 0; + r->parent = 0; + r->user = user; + r->group = user; + r->muid = user; + r->atime = time(0); + r->mtime = r->atime; + r->name = estrdup("."); + + if(debug) + fmtinstall('F', fcallfmt); + switch(rfork(RFFDG|RFPROC|RFNAMEG|RFNOTEG)){ + case -1: + error("fork"); + case 0: + close(srvfd); + io(); + break; + default: + close(mfd[0]); /* don't deadlock if child fails */ + if(defmnt && mount(srvfd, -1, defmnt, MREPL|MCREATE, "") < 0) + error("mount failed: %r"); + } +} + +char* +rversion(Fid*) +{ + Fid *f; + + for(f = fids; f; f = f->next) + if(f->busy) + rclunk(f); + if(thdr.msize > sizeof mdata) + rhdr.msize = sizeof mdata; + else + rhdr.msize = thdr.msize; + messagesize = rhdr.msize; + if(strncmp(thdr.version, "9P2000", 6) != 0) + return Eversion; + rhdr.version = "9P2000"; + return 0; +} + +char* +rauth(Fid*) +{ + return "ramfs: no authentication required"; +} + +char* +rflush(Fid *f) +{ + USED(f); + return 0; +} + +char* +rattach(Fid *f) +{ + /* no authentication! */ + f->busy = 1; + f->rclose = 0; + f->ram = &ram[0]; + rhdr.qid = f->ram->qid; + if(thdr.uname[0]) + f->user = atom(thdr.uname); + else + f->user = atom("none"); + if(strcmp(user, "none") == 0) + user = f->user; + return 0; +} + +char* +clone(Fid *f, Fid **nf) +{ + if(f->open) + return Eisopen; + if(f->ram->busy == 0) + return Enotexist; + *nf = newfid(thdr.newfid); + (*nf)->busy = 1; + (*nf)->open = 0; + (*nf)->rclose = 0; + (*nf)->ram = f->ram; + (*nf)->user = f->user; /* no ref count; the leakage is minor */ + return 0; +} + +char* +rwalk(Fid *f) +{ + Ram *r, *fram; + char *name; + Ram *parent; + Fid *nf; + char *err; + ulong t; + int i; + + err = nil; + nf = nil; + rhdr.nwqid = 0; + if(rhdr.newfid != rhdr.fid){ + err = clone(f, &nf); + if(err) + return err; + f = nf; /* walk the new fid */ + } + fram = f->ram; + if(thdr.nwname > 0){ + t = time(0); + for(i=0; iqid.type & QTDIR) == 0){ + err = Enotdir; + break; + } + if(fram->busy == 0){ + err = Enotexist; + break; + } + fram->atime = t; + name = thdr.wname[i]; + if(strcmp(name, ".") == 0){ + Found: + rhdr.nwqid++; + rhdr.wqid[i] = fram->qid; + continue; + } + parent = &ram[fram->parent]; +#ifdef CHECKS + if(!perm(f, parent, Pexec)){ + err = Eperm; + break; + } +#endif + if(strcmp(name, "..") == 0){ + fram = parent; + goto Found; + } + for(r=ram; r < &ram[nram]; r++) + if(r->busy && r->parent==fram-ram && strcmp(name, r->name)==0){ + fram = r; + goto Found; + } + break; + } + if(i==0 && err == nil) + err = Enotexist; + } + if(nf != nil && (err!=nil || rhdr.nwqidbusy = 0; + f->ram = nil; + } + if(rhdr.nwqid == thdr.nwname) /* update the fid after a successful walk */ + f->ram = fram; + return err; +} + +char * +ropen(Fid *f) +{ + Ram *r; + int mode, trunc; + + if(f->open) + return Eisopen; + r = f->ram; + if(r->busy == 0) + return Enotexist; + if(r->perm & DMEXCL) + if(r->open) + return Excl; + mode = thdr.mode; + if(r->qid.type & QTDIR){ + if(mode != OREAD) + return Eperm; + rhdr.qid = r->qid; + return 0; + } + if(mode & ORCLOSE){ + /* can't remove root; must be able to write parent */ + if(r->qid.path==0 || !perm(f, &ram[r->parent], Pwrite)) + return Eperm; + f->rclose = 1; + } + trunc = mode & OTRUNC; + mode &= OPERM; + if(mode==OWRITE || mode==ORDWR || trunc) + if(!perm(f, r, Pwrite)) + return Eperm; + if(mode==OREAD || mode==ORDWR) + if(!perm(f, r, Pread)) + return Eperm; + if(mode==OEXEC) + if(!perm(f, r, Pexec)) + return Eperm; + if(trunc && (r->perm&DMAPPEND)==0){ + r->ndata = 0; + if(r->data) + free(r->data); + r->data = 0; + r->qid.vers++; + } + rhdr.qid = r->qid; + rhdr.iounit = messagesize-IOHDRSZ; + f->open = 1; + r->open++; + return 0; +} + +char * +rcreate(Fid *f) +{ + Ram *r; + char *name; + long parent, prm; + + if(f->open) + return Eisopen; + if(f->ram->busy == 0) + return Enotexist; + parent = f->ram - ram; + if((f->ram->qid.type&QTDIR) == 0) + return Enotdir; + /* must be able to write parent */ +#ifdef CHECKS + if(!perm(f, f->ram, Pwrite)) + return Eperm; +#endif + prm = thdr.perm; + name = thdr.name; + if(strcmp(name, ".")==0 || strcmp(name, "..")==0) + return Ename; + for(r=ram; r<&ram[nram]; r++) + if(r->busy && parent==r->parent) + if(strcmp((char*)name, r->name)==0) + return Einuse; + for(r=ram; r->busy; r++) + if(r == &ram[Nram-1]) + return "no free ram resources"; + r->busy = 1; + r->qid.path = ++path; + r->qid.vers = 0; + if(prm & DMDIR) + r->qid.type |= QTDIR; + r->parent = parent; + free(r->name); + r->name = estrdup(name); + r->user = f->user; + r->group = f->ram->group; + r->muid = f->ram->muid; + if(prm & DMDIR) + prm = (prm&~0777) | (f->ram->perm&prm&0777); + else + prm = (prm&(~0777|0111)) | (f->ram->perm&prm&0666); + r->perm = prm; + r->ndata = 0; + if(r-ram >= nram) + nram = r - ram + 1; + r->atime = time(0); + r->mtime = r->atime; + f->ram->mtime = r->atime; + f->ram = r; + rhdr.qid = r->qid; + rhdr.iounit = messagesize-IOHDRSZ; + f->open = 1; + if(thdr.mode & ORCLOSE) + f->rclose = 1; + r->open++; + return 0; +} + +char* +rread(Fid *f) +{ + Ram *r; + uchar *buf; + long off; + int n, m, cnt; + + if(f->ram->busy == 0) + return Enotexist; + n = 0; + rhdr.count = 0; + off = thdr.offset; + buf = rdata; + cnt = thdr.count; + if(cnt > messagesize) /* shouldn't happen, anyway */ + cnt = messagesize; + if(f->ram->qid.type & QTDIR){ + for(r=ram+1; off > 0; r++){ + if(r->busy && r->parent==f->ram-ram) + off -= ramstat(r, statbuf, sizeof statbuf); + if(r == &ram[nram-1]) + return 0; + } + for(; r<&ram[nram] && n < cnt; r++){ + if(!r->busy || r->parent!=f->ram-ram) + continue; + m = ramstat(r, buf+n, cnt-n); + if(m == 0) + break; + n += m; + } + rhdr.data = (char*)rdata; + rhdr.count = n; + return 0; + } + r = f->ram; + if(off >= r->ndata) + return 0; + r->atime = time(0); + n = cnt; + if(off+n > r->ndata) + n = r->ndata - off; + rhdr.data = r->data+off; + rhdr.count = n; + return 0; +} + +char* +rwrite(Fid *f) +{ + Ram *r; + ulong off; + int cnt; + + r = f->ram; + if(r->busy == 0) + return Enotexist; + off = thdr.offset; + if(r->perm & DMAPPEND) + off = r->ndata; + cnt = thdr.count; + if(r->qid.type & QTDIR) + return Eisdir; + if(off+cnt >= Maxsize) /* sanity check */ + return "write too big"; + if(off+cnt > r->ndata) + r->data = erealloc(r->data, off+cnt); + if(off > r->ndata) + memset(r->data+r->ndata, 0, off-r->ndata); + if(off+cnt > r->ndata) + r->ndata = off+cnt; + memmove(r->data+off, thdr.data, cnt); + r->qid.vers++; + r->mtime = time(0); + rhdr.count = cnt; + return 0; +} + +void +realremove(Ram *r) +{ + r->ndata = 0; + if(r->data) + free(r->data); + r->data = 0; + r->parent = 0; + memset(&r->qid, 0, sizeof r->qid); + free(r->name); + r->name = nil; + r->busy = 0; +} + +char * +rclunk(Fid *f) +{ + if(f->open) + f->ram->open--; + if(f->rclose) + realremove(f->ram); + f->busy = 0; + f->open = 0; + f->ram = 0; + return 0; +} + +char * +rremove(Fid *f) +{ + Ram *r; + + if(f->open) + f->ram->open--; + f->busy = 0; + f->open = 0; + r = f->ram; + f->ram = 0; +#ifdef CHECKS + if(r->qid.path == 0 || !perm(f, &ram[r->parent], Pwrite)) + return Eperm; +#endif + ram[r->parent].mtime = time(0); + realremove(r); + return 0; +} + +char * +rstat(Fid *f) +{ + if(f->ram->busy == 0) + return Enotexist; + rhdr.nstat = ramstat(f->ram, statbuf, sizeof statbuf); + rhdr.stat = statbuf; + return 0; +} + +char * +rwstat(Fid *f) +{ + Ram *r, *s; + Dir dir; + + if(f->ram->busy == 0) + return Enotexist; + convM2D(thdr.stat, thdr.nstat, &dir, (char*)statbuf); + r = f->ram; + + /* + * To change length, must have write permission on file. + */ +#ifdef CHECKS + if(dir.length!=~0 && dir.length!=r->ndata){ + if(!perm(f, r, Pwrite)) + return Eperm; + } +#endif + + /* + * To change name, must have write permission in parent + * and name must be unique. + */ + if(dir.name[0]!='\0' && strcmp(dir.name, r->name)!=0){ +#ifdef CHECKS + if(!perm(f, &ram[r->parent], Pwrite)) + return Eperm; +#endif + for(s=ram; s<&ram[nram]; s++) + if(s->busy && s->parent==r->parent) + if(strcmp(dir.name, s->name)==0) + return Eexist; + } + +#ifdef OWNERS + /* + * To change mode, must be owner or group leader. + * Because of lack of users file, leader=>group itself. + */ + if(dir.mode!=~0 && r->perm!=dir.mode){ + if(strcmp(f->user, r->user) != 0) + if(strcmp(f->user, r->group) != 0) + return Enotowner; + } + + /* + * To change group, must be owner and member of new group, + * or leader of current group and leader of new group. + * Second case cannot happen, but we check anyway. + */ + if(dir.gid[0]!='\0' && strcmp(r->group, dir.gid)!=0){ + if(strcmp(f->user, r->user) == 0) + if(strcmp(f->user, dir.gid) == 0) + goto ok; + if(strcmp(f->user, r->group) == 0) + if(strcmp(f->user, dir.gid) == 0) + goto ok; + return Enotowner; + ok:; + } +#endif + + /* all ok; do it */ + if(dir.mode != ~0){ + dir.mode &= ~DMDIR; /* cannot change dir bit */ + dir.mode |= r->perm&DMDIR; + r->perm = dir.mode; + } + if(dir.name[0] != '\0'){ + free(r->name); + r->name = estrdup(dir.name); + } + if(dir.gid[0] != '\0') + r->group = atom(dir.gid); + + if(dir.uid[0] != '\0') + r->user = atom(dir.uid); + + if(dir.length!=~0 && dir.length!=r->ndata){ + r->data = erealloc(r->data, dir.length); + if(r->ndata < dir.length) + memset(r->data+r->ndata, 0, dir.length-r->ndata); + r->ndata = dir.length; + } + + if(dir.mtime != ~0) + r->mtime = dir.mtime; + + ram[r->parent].mtime = time(0); + return 0; +} + +uint +ramstat(Ram *r, uchar *buf, uint nbuf) +{ + Dir dir; + + dir.name = r->name; + dir.qid = r->qid; + dir.mode = r->perm; + dir.length = r->ndata; + dir.uid = r->user; + dir.gid = r->group; + dir.muid = r->muid; + dir.atime = r->atime; + dir.mtime = r->mtime; + return convD2M(&dir, buf, nbuf); +} + +Fid * +newfid(int fid) +{ + Fid *f, *ff; + + ff = 0; + for(f = fids; f; f = f->next) + if(f->fid == fid) + return f; + else if(!ff && !f->busy) + ff = f; + if(ff){ + ff->fid = fid; + return ff; + } + f = emalloc(sizeof *f); + f->ram = nil; + f->fid = fid; + f->next = fids; + fids = f; + return f; +} + +void +io(void) +{ + char *err; + int n, pid; + + pid = getpid(); + + for(;;){ + /* + * reading from a pipe or a network device + * will give an error after a few eof reads. + * however, we cannot tell the difference + * between a zero-length read and an interrupt + * on the processes writing to us, + * so we wait for the error. + */ + n = read9pmsg(mfd[0], mdata, messagesize); + if(n < 0) + error("mount read: %r"); + if(n == 0) + continue; + if(convM2S(mdata, n, &thdr) == 0) + continue; + + if(debug) + fprint(2, "ramfs %d:<-%F\n", pid, &thdr); + + if(!fcalls[thdr.type]) + err = "bad fcall type"; + else + err = (*fcalls[thdr.type])(newfid(thdr.fid)); + if(err){ + rhdr.type = Rerror; + rhdr.ename = err; + }else{ + rhdr.type = thdr.type + 1; + rhdr.fid = thdr.fid; + } + rhdr.tag = thdr.tag; + if(debug) + fprint(2, "ramfs %d:->%F\n", pid, &rhdr);/**/ + n = convS2M(&rhdr, mdata, messagesize); + if(n == 0) + error("convS2M error on write"); + if(write(mfd[1], mdata, n) != n) + error("mount write"); + } +} + +int +perm(Fid *f, Ram *r, int p) +{ + if((p*Pother) & r->perm) + return 1; + if(strcmp(f->user, r->group)==0 && ((p*Pgroup) & r->perm)) + return 1; + if(strcmp(f->user, r->user)==0 && ((p*Powner) & r->perm)) + return 1; + return 0; +} + +void * +emalloc(ulong n) +{ + void *p; + + p = malloc(n); + if(!p) + error("out of memory"); + memset(p, 0, n); + return p; +} + +void * +erealloc(void *p, ulong n) +{ + p = realloc(p, n); + if(!p) + error("out of memory"); + return p; +} + +char * +estrdup(char *q) +{ + char *p; + int n; + + n = strlen(q)+1; + p = malloc(n); + if(!p) + error("out of memory"); + memmove(p, q, n); + return p; +} + +void +ramfsusage(void) +{ + fprint(2, "usage: %s [-is] [-m mountpoint]\n", argv0); + exits("usage"); +} + +/* + * Custom allocators to avoid malloc overheads on small objects. + * We never free these. (See below.) + */ +typedef struct Stringtab Stringtab; +struct Stringtab { + Stringtab *link; + char *str; +}; +static Stringtab* +taballoc(void) +{ + static Stringtab *t; + static uint nt; + + if(nt == 0){ + t = malloc(64*sizeof(Stringtab)); + if(t == 0) + sysfatal("out of memory"); + nt = 64; + } + nt--; + return t++; +} + +static char* +xstrdup(char *s) +{ + char *r; + int len; + static char *t; + static int nt; + + len = strlen(s)+1; + if(len >= 8192) + sysfatal("strdup big string"); + + if(nt < len){ + t = malloc(8192); + if(t == 0) + sysfatal("out of memory"); + nt = 8192; + } + r = t; + t += len; + nt -= len; + strcpy(r, s); + return r; +} + +/* + * Return a uniquely allocated copy of a string. + * Don't free these -- they stay in the table for the + * next caller who wants that particular string. + * String comparison can be done with pointer comparison + * if you know both strings are atoms. + */ +static Stringtab *stab[1024]; + +static uint +hash(char *s) +{ + uint h; + uchar *p; + + h = 0; + for(p=(uchar*)s; *p; p++) + h = h*37 + *p; + return h; +} + +char* +atom(char *str) +{ + uint h; + Stringtab *tab; + + h = hash(str) % nelem(stab); + for(tab=stab[h]; tab; tab=tab->link) + if(strcmp(str, tab->str) == 0) + return tab->str; + + tab = taballoc(); + tab->str = xstrdup(str); + tab->link = stab[h]; + stab[h] = tab; + return tab->str; +} diff --git a/sys/lib/dist.old/cmd/bzfs/unbflz.c b/sys/lib/dist.old/cmd/bzfs/unbflz.c new file mode 100644 index 000000000..661d65e4d --- /dev/null +++ b/sys/lib/dist.old/cmd/bzfs/unbflz.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include "bzfs.h" + +int +Bgetint(Biobuf *b) +{ + uchar p[4]; + + if(Bread(b, p, 4) != 4) + sysfatal("short read"); + return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3]; +} + +/* + * memmove but make sure overlap works properly. + */ +void +copy(uchar *dst, uchar *src, int n) +{ + while(n-- > 0) + *dst++ = *src++; +} + +int +unbflz(int in) +{ + int rv, out, p[2]; + Biobuf *b, bin; + char buf[5]; + uchar *data; + int i, j, length, n, m, o, sum; + ulong *blk; + int nblk, mblk; + + if(pipe(p) < 0) + sysfatal("pipe: %r"); + + rv = p[0]; + out = p[1]; + switch(rfork(RFPROC|RFFDG|RFNOTEG|RFMEM)){ + case -1: + sysfatal("fork: %r"); + case 0: + close(rv); + break; + default: + close(in); + close(out); + return rv; + } + + Binit(&bin, in, OREAD); + b = &bin; + + if(Bread(b, buf, 4) != 4) + sysfatal("short read"); + + if(memcmp(buf, "BLZ\n", 4) != 0) + sysfatal("bad header"); + + length = Bgetint(b); + data = malloc(length); + if(data == nil) + sysfatal("out of memory"); + sum = 0; + nblk = 0; + mblk = 0; + blk = nil; + while(sum < length){ + if(nblk>=mblk){ + mblk += 16384; + blk = realloc(blk, (mblk+1)*sizeof(blk[0])); + if(blk == nil) + sysfatal("out of memory"); + } + n = Bgetint(b); + blk[nblk++] = n; + if(n&(1<<31)) + n &= ~(1<<31); + else + blk[nblk++] = Bgetint(b); + sum += n; + } + if(sum != length) + sysfatal("bad compressed data %d %d", sum, length); + i = 0; + j = 0; + while(i < length){ + assert(j < nblk); + n = blk[j++]; + if(n&(1<<31)){ + n &= ~(1<<31); + if((m=Bread(b, data+i, n)) != n) + sysfatal("short read %d %d", n, m); + }else{ + o = blk[j++]; + copy(data+i, data+o, n); + } + i += n; + } + write(out, data, length); + close(in); + close(out); + _exits(0); + return -1; +} diff --git a/sys/lib/dist.old/cmd/bzfs/unbzip.c b/sys/lib/dist.old/cmd/bzfs/unbzip.c new file mode 100644 index 000000000..070e7ba48 --- /dev/null +++ b/sys/lib/dist.old/cmd/bzfs/unbzip.c @@ -0,0 +1,861 @@ +#include +#include +#include +#include "bzfs.h" + +/* + * THIS FILE IS NOT IDENTICAL TO THE ORIGINAL + * FROM THE BZIP2 DISTRIBUTION. + * + * It has been modified, mainly to break the library + * into smaller pieces. + * + * Russ Cox + * rsc@plan9.bell-labs.com + * July 2000 + */ + +/*---------------------------------------------*/ +/*-- + Place a 1 beside your platform, and 0 elsewhere. + Attempts to autosniff this even if you don't. +--*/ + + +/*-- + Plan 9 from Bell Labs +--*/ +#define BZ_PLAN9 1 +#define BZ_UNIX 0 + +#define exit(x) exits((x) ? "whoops" : nil) +#define size_t ulong + +#ifdef __GNUC__ +# define NORETURN __attribute__ ((noreturn)) +#else +# define NORETURN /**/ +#endif + +/*-- + Some more stuff for all platforms :-) + This might have to get moved into the platform-specific + header files if we encounter a machine with different sizes. +--*/ + +typedef char Char; +typedef unsigned char Bool; +typedef unsigned char UChar; +typedef int Int32; +typedef unsigned int UInt32; +typedef short Int16; +typedef unsigned short UInt16; + +#define True ((Bool)1) +#define False ((Bool)0) + +/*-- + IntNative is your platform's `native' int size. + Only here to avoid probs with 64-bit platforms. +--*/ +typedef int IntNative; + +#include "bzfs.h" +#include "bzlib.h" +#include "bzlib_private.h" + +static int +bunzip(int ofd, char *ofile, Biobuf *bin) +{ + int e, n, done, onemore; + char buf[8192]; + char obuf[8192]; + Biobuf bout; + bz_stream strm; + + USED(ofile); + + memset(&strm, 0, sizeof strm); + BZ2_bzDecompressInit(&strm, 0, 0); + + strm.next_in = buf; + strm.avail_in = 0; + strm.next_out = obuf; + strm.avail_out = sizeof obuf; + + done = 0; + Binit(&bout, ofd, OWRITE); + + /* + * onemore is a crummy hack to go 'round the loop + * once after we finish, to flush the output buffer. + */ + onemore = 1; + SET(e); + do { + if(!done && strm.avail_in < sizeof buf) { + if(strm.avail_in) + memmove(buf, strm.next_in, strm.avail_in); + + n = Bread(bin, buf+strm.avail_in, sizeof(buf)-strm.avail_in); + if(n <= 0) + done = 1; + else + strm.avail_in += n; + strm.next_in = buf; + } + if(strm.avail_out < sizeof obuf) { + Bwrite(&bout, obuf, sizeof(obuf)-strm.avail_out); + strm.next_out = obuf; + strm.avail_out = sizeof obuf; + } + + if(onemore == 0) + break; + } while((e=BZ2_bzDecompress(&strm)) == BZ_OK || onemore--); + + if(e != BZ_STREAM_END) { + fprint(2, "bunzip2: decompress failed\n"); + return 0; + } + + if(BZ2_bzDecompressEnd(&strm) != BZ_OK) { + fprint(2, "bunzip2: decompress end failed (can't happen)\n"); + return 0; + } + + Bterm(&bout); + + return 1; +} + +void +_unbzip(int in, int out) +{ + Biobuf bin; + + Binit(&bin, in, OREAD); + if(bunzip(out, nil, &bin) != 1) { + fprint(2, "bunzip2 failed\n"); + _exits("bunzip2"); + } +} + +int +unbzip(int in) +{ + int rv, out, p[2]; + + if(pipe(p) < 0) + sysfatal("pipe: %r"); + + rv = p[0]; + out = p[1]; + switch(rfork(RFPROC|RFFDG|RFNOTEG|RFMEM)){ + case -1: + sysfatal("fork: %r"); + case 0: + close(rv); + break; + default: + close(in); + close(out); + return rv; + } + + _unbzip(in, out); + _exits(0); + return -1; /* not reached */ +} + +int bz_config_ok ( void ) +{ + if (sizeof(int) != 4) return 0; + if (sizeof(short) != 2) return 0; + if (sizeof(char) != 1) return 0; + return 1; +} + +void* default_bzalloc(void *o, int items, int size) +{ + USED(o); + return sbrk(items*size); +} + +void default_bzfree(void*, void*) +{ +} + +void +bz_internal_error(int) +{ + abort(); +} + +/*-------------------------------------------------------------*/ +/*--- Decompression machinery ---*/ +/*--- decompress.c ---*/ +/*-------------------------------------------------------------*/ + +/*-- + This file is a part of bzip2 and/or libbzip2, a program and + library for lossless, block-sorting data compression. + + Copyright (C) 1996-2000 Julian R Seward. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + + 3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Julian Seward, Cambridge, UK. + jseward@acm.org + bzip2/libbzip2 version 1.0 of 21 March 2000 + + This program is based on (at least) the work of: + Mike Burrows + David Wheeler + Peter Fenwick + Alistair Moffat + Radford Neal + Ian H. Witten + Robert Sedgewick + Jon L. Bentley + + For more information on these sources, see the manual. +--*/ + + + +/*---------------------------------------------------*/ +static +void makeMaps_d ( DState* s ) +{ + Int32 i; + s->nInUse = 0; + for (i = 0; i < 256; i++) + if (s->inUse[i]) { + s->seqToUnseq[s->nInUse] = i; + s->nInUse++; + } +} + + +/*---------------------------------------------------*/ +#define RETURN(rrr) \ + { retVal = rrr; goto save_state_and_return; }; + +#define GET_BITS(lll,vvv,nnn) \ + case lll: \ + { int x; if((retVal = getbits(s, lll, &x, nnn)) != 99) \ + goto save_state_and_return; vvv=x; }\ + +int +getbits(DState *s, int lll, int *vvv, int nnn) +{ + s->state = lll; + + for(;;) { + if (s->bsLive >= nnn) { + UInt32 v; + v = (s->bsBuff >> + (s->bsLive-nnn)) & ((1 << nnn)-1); + s->bsLive -= nnn; + *vvv = v; + return 99; + } + if (s->strm->avail_in == 0) return BZ_OK; + s->bsBuff + = (s->bsBuff << 8) | + ((UInt32) + (*((UChar*)(s->strm->next_in)))); + s->bsLive += 8; + s->strm->next_in++; + s->strm->avail_in--; + s->strm->total_in_lo32++; + if (s->strm->total_in_lo32 == 0) + s->strm->total_in_hi32++; + } + return -1; /* KEN */ +} + +#define GET_UCHAR(lll,uuu) \ + GET_BITS(lll,uuu,8) + +#define GET_BIT(lll,uuu) \ + GET_BITS(lll,uuu,1) + +/*---------------------------------------------------*/ +#define GET_MTF_VAL(label1,label2,lval) \ +{ \ + if (groupPos == 0) { \ + groupNo++; \ + if (groupNo >= nSelectors) \ + RETURN(BZ_DATA_ERROR); \ + groupPos = BZ_G_SIZE; \ + gSel = s->selector[groupNo]; \ + gMinlen = s->minLens[gSel]; \ + gLimit = &(s->limit[gSel][0]); \ + gPerm = &(s->perm[gSel][0]); \ + gBase = &(s->base[gSel][0]); \ + } \ + groupPos--; \ + zn = gMinlen; \ + GET_BITS(label1, zvec, zn); \ + while (1) { \ + if (zn > 20 /* the longest code */) \ + RETURN(BZ_DATA_ERROR); \ + if (zvec <= gLimit[zn]) break; \ + zn++; \ + GET_BIT(label2, zj); \ + zvec = (zvec << 1) | zj; \ + }; \ + if (zvec - gBase[zn] < 0 \ + || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \ + RETURN(BZ_DATA_ERROR); \ + lval = gPerm[zvec - gBase[zn]]; \ +} + + +/*---------------------------------------------------*/ +Int32 BZ2_decompress ( DState* s ) +{ + UChar uc; + Int32 retVal; + Int32 minLen, maxLen; + bz_stream* strm = s->strm; + + /* stuff that needs to be saved/restored */ + Int32 i; + Int32 j; + Int32 t; + Int32 alphaSize; + Int32 nGroups; + Int32 nSelectors; + Int32 EOB; + Int32 groupNo; + Int32 groupPos; + Int32 nextSym; + Int32 nblockMAX; + Int32 nblock; + Int32 es; + Int32 N; + Int32 curr; + Int32 zt; + Int32 zn; + Int32 zvec; + Int32 zj; + Int32 gSel; + Int32 gMinlen; + Int32* gLimit; + Int32* gBase; + Int32* gPerm; + + if (s->state == BZ_X_MAGIC_1) { + /*initialise the save area*/ + s->save_i = 0; + s->save_j = 0; + s->save_t = 0; + s->save_alphaSize = 0; + s->save_nGroups = 0; + s->save_nSelectors = 0; + s->save_EOB = 0; + s->save_groupNo = 0; + s->save_groupPos = 0; + s->save_nextSym = 0; + s->save_nblockMAX = 0; + s->save_nblock = 0; + s->save_es = 0; + s->save_N = 0; + s->save_curr = 0; + s->save_zt = 0; + s->save_zn = 0; + s->save_zvec = 0; + s->save_zj = 0; + s->save_gSel = 0; + s->save_gMinlen = 0; + s->save_gLimit = NULL; + s->save_gBase = NULL; + s->save_gPerm = NULL; + } + + /*restore from the save area*/ + i = s->save_i; + j = s->save_j; + t = s->save_t; + alphaSize = s->save_alphaSize; + nGroups = s->save_nGroups; + nSelectors = s->save_nSelectors; + EOB = s->save_EOB; + groupNo = s->save_groupNo; + groupPos = s->save_groupPos; + nextSym = s->save_nextSym; + nblockMAX = s->save_nblockMAX; + nblock = s->save_nblock; + es = s->save_es; + N = s->save_N; + curr = s->save_curr; + zt = s->save_zt; + zn = s->save_zn; + zvec = s->save_zvec; + zj = s->save_zj; + gSel = s->save_gSel; + gMinlen = s->save_gMinlen; + gLimit = s->save_gLimit; + gBase = s->save_gBase; + gPerm = s->save_gPerm; + + retVal = BZ_OK; + + switch (s->state) { + + GET_UCHAR(BZ_X_MAGIC_1, uc); + if (uc != 'B') RETURN(BZ_DATA_ERROR_MAGIC); + + GET_UCHAR(BZ_X_MAGIC_2, uc); + if (uc != 'Z') RETURN(BZ_DATA_ERROR_MAGIC); + + GET_UCHAR(BZ_X_MAGIC_3, uc) + if (uc != 'h') RETURN(BZ_DATA_ERROR_MAGIC); + + GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8) + if (s->blockSize100k < '1' || + s->blockSize100k > '9') RETURN(BZ_DATA_ERROR_MAGIC); + s->blockSize100k -= '0'; + + if (0 && s->smallDecompress) { + s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) ); + s->ll4 = BZALLOC( + ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) + ); + if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR); + } else { + s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) ); + if (s->tt == NULL) RETURN(BZ_MEM_ERROR); + } + + GET_UCHAR(BZ_X_BLKHDR_1, uc); + + if (uc == 0x17) goto endhdr_2; + if (uc != 0x31) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_2, uc); + if (uc != 0x41) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_3, uc); + if (uc != 0x59) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_4, uc); + if (uc != 0x26) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_5, uc); + if (uc != 0x53) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_6, uc); + if (uc != 0x59) RETURN(BZ_DATA_ERROR); + + s->currBlockNo++; + // if (s->verbosity >= 2) + // VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo ); + + s->storedBlockCRC = 0; + GET_UCHAR(BZ_X_BCRC_1, uc); + s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_BCRC_2, uc); + s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_BCRC_3, uc); + s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_BCRC_4, uc); + s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); + + GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1); + + s->origPtr = 0; + GET_UCHAR(BZ_X_ORIGPTR_1, uc); + s->origPtr = (s->origPtr << 8) | ((Int32)uc); + GET_UCHAR(BZ_X_ORIGPTR_2, uc); + s->origPtr = (s->origPtr << 8) | ((Int32)uc); + GET_UCHAR(BZ_X_ORIGPTR_3, uc); + s->origPtr = (s->origPtr << 8) | ((Int32)uc); + + if (s->origPtr < 0) + RETURN(BZ_DATA_ERROR); + if (s->origPtr > 10 + 100000*s->blockSize100k) + RETURN(BZ_DATA_ERROR); + + /*--- Receive the mapping table ---*/ + for (i = 0; i < 16; i++) { + GET_BIT(BZ_X_MAPPING_1, uc); + if (uc == 1) + s->inUse16[i] = True; else + s->inUse16[i] = False; + } + + for (i = 0; i < 256; i++) s->inUse[i] = False; + + for (i = 0; i < 16; i++) + if (s->inUse16[i]) + for (j = 0; j < 16; j++) { + GET_BIT(BZ_X_MAPPING_2, uc); + if (uc == 1) s->inUse[i * 16 + j] = True; + } + makeMaps_d ( s ); + if (s->nInUse == 0) RETURN(BZ_DATA_ERROR); + alphaSize = s->nInUse+2; + + /*--- Now the selectors ---*/ + GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); + if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR); + GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); + if (nSelectors < 1) RETURN(BZ_DATA_ERROR); + for (i = 0; i < nSelectors; i++) { + j = 0; + while (True) { + GET_BIT(BZ_X_SELECTOR_3, uc); + if (uc == 0) break; + j++; + if (j >= nGroups) RETURN(BZ_DATA_ERROR); + } + s->selectorMtf[i] = j; + } + + /*--- Undo the MTF values for the selectors. ---*/ + { + UChar pos[BZ_N_GROUPS], tmp, v; + for (v = 0; v < nGroups; v++) pos[v] = v; + + for (i = 0; i < nSelectors; i++) { + v = s->selectorMtf[i]; + tmp = pos[v]; + while (v > 0) { pos[v] = pos[v-1]; v--; } + pos[0] = tmp; + s->selector[i] = tmp; + } + } + + /*--- Now the coding tables ---*/ + for (t = 0; t < nGroups; t++) { + GET_BITS(BZ_X_CODING_1, curr, 5); + for (i = 0; i < alphaSize; i++) { + while (True) { + if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR); + GET_BIT(BZ_X_CODING_2, uc); + if (uc == 0) break; + GET_BIT(BZ_X_CODING_3, uc); + if (uc == 0) curr++; else curr--; + } + s->len[t][i] = curr; + } + } + + /*--- Create the Huffman decoding tables ---*/ + for (t = 0; t < nGroups; t++) { + minLen = 32; + maxLen = 0; + for (i = 0; i < alphaSize; i++) { + if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; + if (s->len[t][i] < minLen) minLen = s->len[t][i]; + } + BZ2_hbCreateDecodeTables ( + &(s->limit[t][0]), + &(s->base[t][0]), + &(s->perm[t][0]), + &(s->len[t][0]), + minLen, maxLen, alphaSize + ); + s->minLens[t] = minLen; + } + + /*--- Now the MTF values ---*/ + + EOB = s->nInUse+1; + nblockMAX = 100000 * s->blockSize100k; + groupNo = -1; + groupPos = 0; + + for (i = 0; i <= 255; i++) s->unzftab[i] = 0; + + /*-- MTF init --*/ + { + Int32 ii, jj, kk; + kk = MTFA_SIZE-1; + for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) { + for (jj = MTFL_SIZE-1; jj >= 0; jj--) { + s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj); + kk--; + } + s->mtfbase[ii] = kk + 1; + } + } + /*-- end MTF init --*/ + + nblock = 0; + GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); + + while (True) { + + if (nextSym == EOB) break; + + if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) { + + es = -1; + N = 1; + do { + if (nextSym == BZ_RUNA) es = es + (0+1) * N; else + if (nextSym == BZ_RUNB) es = es + (1+1) * N; + N = N * 2; + GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym); + } + while (nextSym == BZ_RUNA || nextSym == BZ_RUNB); + + es++; + uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ]; + s->unzftab[uc] += es; + + if (0 && s->smallDecompress) + while (es > 0) { + if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); + s->ll16[nblock] = (UInt16)uc; + nblock++; + es--; + } + else + while (es > 0) { + if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); + s->tt[nblock] = (UInt32)uc; + nblock++; + es--; + }; + + continue; + + } else { + + if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); + + /*-- uc = MTF ( nextSym-1 ) --*/ + { + Int32 ii, jj, kk, pp, lno, off; + UInt32 nn; + nn = (UInt32)(nextSym - 1); + + if (nn < MTFL_SIZE) { + /* avoid general-case expense */ + pp = s->mtfbase[0]; + uc = s->mtfa[pp+nn]; + while (nn > 3) { + Int32 z = pp+nn; + s->mtfa[(z) ] = s->mtfa[(z)-1]; + s->mtfa[(z)-1] = s->mtfa[(z)-2]; + s->mtfa[(z)-2] = s->mtfa[(z)-3]; + s->mtfa[(z)-3] = s->mtfa[(z)-4]; + nn -= 4; + } + while (nn > 0) { + s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; + }; + s->mtfa[pp] = uc; + } else { + /* general case */ + lno = nn / MTFL_SIZE; + off = nn % MTFL_SIZE; + pp = s->mtfbase[lno] + off; + uc = s->mtfa[pp]; + while (pp > s->mtfbase[lno]) { + s->mtfa[pp] = s->mtfa[pp-1]; pp--; + }; + s->mtfbase[lno]++; + while (lno > 0) { + s->mtfbase[lno]--; + s->mtfa[s->mtfbase[lno]] + = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1]; + lno--; + } + s->mtfbase[0]--; + s->mtfa[s->mtfbase[0]] = uc; + if (s->mtfbase[0] == 0) { + kk = MTFA_SIZE-1; + for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) { + for (jj = MTFL_SIZE-1; jj >= 0; jj--) { + s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj]; + kk--; + } + s->mtfbase[ii] = kk + 1; + } + } + } + } + /*-- end uc = MTF ( nextSym-1 ) --*/ + + s->unzftab[s->seqToUnseq[uc]]++; + if (0 && s->smallDecompress) + s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else + s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]); + nblock++; + + GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym); + continue; + } + } + + /* Now we know what nblock is, we can do a better sanity + check on s->origPtr. + */ + if (s->origPtr < 0 || s->origPtr >= nblock) + RETURN(BZ_DATA_ERROR); + + s->state_out_len = 0; + s->state_out_ch = 0; + BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); + s->state = BZ_X_OUTPUT; + // if (s->verbosity >= 2) VPrintf0 ( "rt+rld" ); + + /*-- Set up cftab to facilitate generation of T^(-1) --*/ + s->cftab[0] = 0; + for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1]; + for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1]; + + if (0 && s->smallDecompress) { + + /*-- Make a copy of cftab, used in generation of T --*/ + for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i]; + + /*-- compute the T vector --*/ + for (i = 0; i < nblock; i++) { + uc = (UChar)(s->ll16[i]); + SET_LL(i, s->cftabCopy[uc]); + s->cftabCopy[uc]++; + } + + /*-- Compute T^(-1) by pointer reversal on T --*/ + i = s->origPtr; + j = GET_LL(i); + do { + Int32 tmp = GET_LL(j); + SET_LL(j, i); + i = j; + j = tmp; + } + while (i != s->origPtr); + + s->tPos = s->origPtr; + s->nblock_used = 0; + if (s->blockRandomised) { + BZ_RAND_INIT_MASK; + BZ_GET_SMALL(s->k0); s->nblock_used++; + BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; + } else { + BZ_GET_SMALL(s->k0); s->nblock_used++; + } + + } else { + + /*-- compute the T^(-1) vector --*/ + for (i = 0; i < nblock; i++) { + uc = (UChar)(s->tt[i] & 0xff); + s->tt[s->cftab[uc]] |= (i << 8); + s->cftab[uc]++; + } + + s->tPos = s->tt[s->origPtr] >> 8; + s->nblock_used = 0; + if (s->blockRandomised) { + BZ_RAND_INIT_MASK; + BZ_GET_FAST(s->k0); s->nblock_used++; + BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; + } else { + BZ_GET_FAST(s->k0); s->nblock_used++; + } + + } + + RETURN(BZ_OK); + + + + endhdr_2: + + GET_UCHAR(BZ_X_ENDHDR_2, uc); + if (uc != 0x72) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_ENDHDR_3, uc); + if (uc != 0x45) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_ENDHDR_4, uc); + if (uc != 0x38) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_ENDHDR_5, uc); + if (uc != 0x50) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_ENDHDR_6, uc); + if (uc != 0x90) RETURN(BZ_DATA_ERROR); + + s->storedCombinedCRC = 0; + GET_UCHAR(BZ_X_CCRC_1, uc); + s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_CCRC_2, uc); + s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_CCRC_3, uc); + s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_CCRC_4, uc); + s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); + + s->state = BZ_X_IDLE; + RETURN(BZ_STREAM_END); + + default: AssertH ( False, 4001 ); + } + + AssertH ( False, 4002 ); + + save_state_and_return: + + s->save_i = i; + s->save_j = j; + s->save_t = t; + s->save_alphaSize = alphaSize; + s->save_nGroups = nGroups; + s->save_nSelectors = nSelectors; + s->save_EOB = EOB; + s->save_groupNo = groupNo; + s->save_groupPos = groupPos; + s->save_nextSym = nextSym; + s->save_nblockMAX = nblockMAX; + s->save_nblock = nblock; + s->save_es = es; + s->save_N = N; + s->save_curr = curr; + s->save_zt = zt; + s->save_zn = zn; + s->save_zvec = zvec; + s->save_zj = zj; + s->save_gSel = gSel; + s->save_gMinlen = gMinlen; + s->save_gLimit = gLimit; + s->save_gBase = gBase; + s->save_gPerm = gPerm; + + return retVal; +} + + +/*-------------------------------------------------------------*/ +/*--- end decompress.c ---*/ +/*-------------------------------------------------------------*/ diff --git a/sys/lib/dist.old/cmd/cdsh.c b/sys/lib/dist.old/cmd/cdsh.c new file mode 100644 index 000000000..2162350bf --- /dev/null +++ b/sys/lib/dist.old/cmd/cdsh.c @@ -0,0 +1,133 @@ +/* + * The `cd' shell. + * Just has cd and lc. + */ + +#include +#include +#include + +char *pwd; +char *root = "/"; + +void +usage(void) +{ + fprint(2, "usage: cdsh [-r root]\n"); + exits("usage"); +} + +int +system(char *cmd) +{ + int pid; + if((pid = fork()) < 0) + return -1; + + if(pid == 0) { + dup(2, 1); + execl("/bin/rc", "rc", "-c", cmd, nil); + exits("exec"); + } + waitpid(); + return 0; +} + +int +cd(char *s) +{ + char *newpwd; + int l; + + if(s[0] == '/') { + cleanname(s); + newpwd = strdup(s); + } else { + l = strlen(pwd)+1+strlen(s)+1+50; /* 50 = crud for unicode mistakes */ + newpwd = malloc(l); + snprint(newpwd, l, "%s/%s", pwd, s); + cleanname(newpwd); + assert(newpwd[0] == '/'); + } + + if(chdir(root) < 0 || (newpwd[1] != '\0' && chdir(newpwd+1) < 0)) { + chdir(root); + chdir(pwd+1); + free(newpwd); + return -1; + } else { + free(pwd); + pwd = newpwd; + return 0; + } +} + +void +main(int argc, char **argv) +{ + char *p; + Biobuf bin; + char *f[2]; + int nf; + + ARGBEGIN{ + case 'r': + root = ARGF(); + if(root == nil) + usage(); + if(root[0] != '/') { + fprint(2, "root must be rooted\n"); + exits("root"); + } + break; + default: + usage(); + }ARGEND; + + if(argc != 0) + usage(); + + cleanname(root); + if(cd("/") < 0) { + fprint(2, "cannot cd %s: %r\n", root); + exits("root"); + } + + Binit(&bin, 0, OREAD); + while(fprint(2, "%s%% ", pwd), (p = Brdline(&bin, '\n'))) { + p[Blinelen(&bin)-1] = '\0'; + nf = tokenize(p, f, nelem(f)); + if(nf < 1) + continue; + if(strcmp(f[0], "exit") == 0) + break; + if(strcmp(f[0], "lc") == 0) { + if(nf == 1) { + if(system("/bin/lc") < 0) + fprint(2, "lc: %r\n"); + } else if(nf == 2) { + if(strpbrk(p, "'`{}^@$#&()|\\;><")) + fprint(2, "no shell characters allowed\n"); + else { + p = f[1]; + *--p = ' '; + *--p = 'c'; + *--p = 'l'; + if(system(p) < 0) + fprint(2, "lc: %r\n"); + } + } + continue; + } + if(strcmp(f[0], "cd") == 0) { + if(nf < 2) + fprint(2, "usage: cd dir\n"); + else if(cd(f[1]) < 0) + fprint(2, "cd: %r\n"); + continue; + } + fprint(2, "commands are cd, lc, and exit\n"); + } + + print("%s\n", pwd); +} diff --git a/sys/lib/dist.old/cmd/clog.c b/sys/lib/dist.old/cmd/clog.c new file mode 100644 index 000000000..98d1cf5f5 --- /dev/null +++ b/sys/lib/dist.old/cmd/clog.c @@ -0,0 +1,59 @@ +#include +#include +#include + +char *argv0; + +int +openlog(char *name) +{ + int fd; + + fd = open(name, OWRITE); + if(fd < 0){ + fprint(2, "%s: can't open %s: %r\n", argv0, name); + return -1; + } + seek(fd, 0, 2); + return fd; +} + +void +main(int argc, char **argv) +{ + Biobuf in; + int fd; + char *p, *t; + char buf[8192]; + + argv0 = argv[0]; + if(argc != 4){ + fprint(2, "usage: %s console logfile prefix\n", argv0); + exits("usage"); + } + + fd = open(argv[1], OREAD); + if(fd < 0){ + fprint(2, "%s: can't open %s: %r\n", argv0, argv[1]); + exits("open"); + } + Binit(&in, fd, OREAD); + + fd = openlog(argv[2]); + + for(;;){ + if(p = Brdline(&in, '\n')){ + p[Blinelen(&in)-1] = 0; + if(fprint(fd, "%s: %s\n", argv[3], p) < 0){ + close(fd); + fd = openlog(argv[2]); + fprint(fd, "%s: %s\n", t, p); + } + } else if(Blinelen(&in) == 0) // true eof + break; + else { + Bread(&in, buf, sizeof buf); + } + } + exits(0); +} diff --git a/sys/lib/dist.old/cmd/mkfile b/sys/lib/dist.old/cmd/mkfile new file mode 100644 index 000000000..bbcd1351c --- /dev/null +++ b/sys/lib/dist.old/cmd/mkfile @@ -0,0 +1,24 @@ +>../../pc/multi/$b + chmod +x ../../pc/multi/$b + } + +BIN=/sys/lib/dist/bin/$objtype +multi.h +>multiproto.h + +for(i){ +echo $i... + b=`{basename $i} + p=$b + if(~ $b [0-9]*) + p=_$b + echo void $p^_main'(int, char**);' >>$dir/multiproto.h + echo "$b", $p^_main, >>$dir/multi.h + d=`{basename -d $i} + if(~ $i disk/prep disk/fdisk){ + cd /sys/src/cmd/disk/prep + rm 8.$b + files=`{mk 8.$b | getfiles} + } + if not if(test -d /sys/src/cmd/$i && @{cd /sys/src/cmd/$i && mk 8.out}){ + cd /sys/src/cmd/$i + rm 8.out + files=`{mk 8.out | getfiles} + } + if not if(test -d /sys/src/cmd/$i && @{cd /sys/src/cmd/$i && mk 8.$b}){ + cd /sys/src/cmd/$i + rm 8.out + files=`{mk 8.$b | getfiles} + } + if not if(test -d /sys/src/cmd/$d && @{cd /sys/src/cmd/$d && mk 8.$b}){ + cd /sys/src/cmd/$d + rm 8.$b + files=`{mk 8.$b | getfiles} + } + if not{ + echo do not know how to make $i + exit oops + } + aux/8prefix $p^_ $files + grab $files + switch(`{pwd}){ + case /sys/src/cmd /sys/src/cmd/aux /sys/src/cmd/ip + rm 8.$b + case * + mk clean + } +} +cd $dir +8c -FVw multi.c +8l -o 8.$targ multi.8 a.*.8 +# rm a.*.8 diff --git a/sys/lib/dist.old/cmd/multi/multi.c b/sys/lib/dist.old/cmd/multi/multi.c new file mode 100644 index 000000000..a2e3035ad --- /dev/null +++ b/sys/lib/dist.old/cmd/multi/multi.c @@ -0,0 +1,38 @@ +#include +#include + +#include "multiproto.h" +struct { + char *name; + void (*fn)(int, char**); +} mains[] = +{ +#include "multi.h" +}; + +void +main(int argc, char **argv) +{ + int i; + char *cmd, *p; + + if(argc == 1){ + fprint(2, "usage: multi cmd args...\n"); + exits("usage"); + } + + cmd = argv[1]; + if(p = strrchr(cmd, '/')) + cmd = p+1; + argv++; + argc--; + + for(i=0; i +#include + +void +main(void) +{ + int fd, p[2]; + char buf[8192], n; + + pipe(p); + fd = create("/srv/log", OWRITE, 0666); + fprint(fd, "%d", p[0]); + close(fd); + close(p[0]); + while((n = read(p[1], buf, sizeof buf)) >= 0) + write(1, buf, n); +} diff --git a/sys/lib/dist.old/cmd/touchfs.c b/sys/lib/dist.old/cmd/touchfs.c new file mode 100644 index 000000000..00fadf3f4 --- /dev/null +++ b/sys/lib/dist.old/cmd/touchfs.c @@ -0,0 +1,66 @@ +#include +#include +#include + +void +Bpass(Biobuf *bin, Biobuf *bout, int n) +{ + char buf[8192]; + int m; + + while(n > 0) { + m = sizeof buf; + if(m > n) + m = n; + m = Bread(bin, buf, m); + if(m <= 0) { + fprint(2, "corrupt archive\n"); + exits("notdone"); + } + Bwrite(bout, buf, m); + n -= m; + } + assert(n == 0); +} + +void +main(int argc, char **argv) +{ + char *p, *f[10]; + Biobuf bin, bout; + int nf; + ulong d, size; + + if(argc != 2) { + fprint(2, "usage: cat mkfs-archive | touchfs date (in seconds)\n"); + exits("usage"); + } + + d = strtoul(argv[1], 0, 0); + + quotefmtinstall(); + Binit(&bin, 0, OREAD); + Binit(&bout, 1, OWRITE); + + while(p = Brdline(&bin, '\n')) { + p[Blinelen(&bin)-1] = '\0'; + if(strcmp(p, "end of archive") == 0) { + Bprint(&bout, "end of archive\n"); + exits(0); + } + + nf = tokenize(p, f, nelem(f)); + if(nf != 6) { + fprint(2, "corrupt archive\n"); + exits("notdone"); + } + + Bprint(&bout, "%q %q %q %q %lud %q\n", + f[0], f[1], f[2], f[3], d, f[5]); + + size = strtoul(f[5], 0, 0); + Bpass(&bin, &bout, size); + } + fprint(2, "premature end of archive\n"); + exits("notdone"); +} diff --git a/sys/lib/dist.old/cmd/unbflz.c b/sys/lib/dist.old/cmd/unbflz.c new file mode 100644 index 000000000..5ddb821f9 --- /dev/null +++ b/sys/lib/dist.old/cmd/unbflz.c @@ -0,0 +1,109 @@ +#include +#include +#include + +void +usage(void) +{ + fprint(2, "usage: unbflz [file]\n"); + exits("usage"); +} + +int +Bgetint(Biobuf *b) +{ + uchar p[4]; + + if(Bread(b, p, 4) != 4) + sysfatal("short read"); + return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3]; +} + +/* + * memmove but make sure overlap works properly. + */ +void +copy(uchar *dst, uchar *src, int n) +{ + while(n-- > 0) + *dst++ = *src++; +} + +void +main(int argc, char **argv) +{ + Biobuf *b, bin; + char buf[5]; + uchar *data; + ulong *blk, l; + int nblk, mblk; + int sum; + int i, j, length, m, n, o; + + ARGBEGIN{ + default: + usage(); + }ARGEND + + switch(argc){ + default: + usage(); + case 0: + Binit(&bin, 0, OREAD); + b = &bin; + break; + case 1: + if((b = Bopen(argv[0], OREAD)) == nil) + sysfatal("open %s: %r", argv[0]); + break; + } + + if(Bread(b, buf, 4) != 4) + sysfatal("short read"); + + if(memcmp(buf, "BLZ\n", 4) != 0) + sysfatal("bad header"); + + length = Bgetint(b); + data = malloc(length); + if(data == nil) + sysfatal("out of memory"); + sum = 0; + nblk = 0; + mblk = 0; + blk = nil; + while(sum < length){ + if(nblk>=mblk){ + mblk += 16384; + blk = realloc(blk, (mblk+1)*sizeof(blk[0])); + if(blk == nil) + sysfatal("out of memory"); + } + l = Bgetint(b); + blk[nblk++] = l; + if(l&(1<<31)) + l &= ~(1<<31); + else + blk[nblk++] = Bgetint(b); + sum += l; + } + if(sum != length) + sysfatal("bad compressed data %d %d", sum, length); + i = 0; + j = 0; + while(i < length){ + assert(j < nblk); + n = blk[j++]; + if(n&(1<<31)){ + n &= ~(1<<31); + if((m=Bread(b, data+i, n)) != n) + sysfatal("short read %d %d", n, m); + }else{ + o = blk[j++]; + copy(data+i, data+o, n); + } + i += n; + } + write(1, data, length); + exits(nil); +} diff --git a/sys/lib/dist.old/logcompress.awk b/sys/lib/dist.old/logcompress.awk new file mode 100755 index 000000000..3267a48f7 --- /dev/null +++ b/sys/lib/dist.old/logcompress.awk @@ -0,0 +1,15 @@ +{ + verb[$4] = $3 + data[$4] = sprintf("%s %s %s %s %s %s", $5, $6, $7, $8, $9, $10) +} + +END{ + for(i in verb) + if(verb[i] != "d") + printf("a %s %s\n", i, data[i]) |"sort +1" + close("sort +1") + for(i in verb) + if(verb[i] == "d") + printf("d %s %s\n", i, data[i]) |"sort -r +1" + close("sort -r +1") +} diff --git a/sys/lib/dist.old/logtime.awk b/sys/lib/dist.old/logtime.awk new file mode 100755 index 000000000..f974f8db6 --- /dev/null +++ b/sys/lib/dist.old/logtime.awk @@ -0,0 +1,3 @@ +{ + printf("%s %d %s\n", t, NR, $0); +} diff --git a/sys/lib/dist.old/mkfile b/sys/lib/dist.old/mkfile new file mode 100644 index 000000000..f9739e427 --- /dev/null +++ b/sys/lib/dist.old/mkfile @@ -0,0 +1,221 @@ +# /sys/lib/dist/mkfile +src9=/n/sources/plan9 # what to export +dist=/sys/lib/dist.old # where this machinery lives +scr=/n/other/dist # scratch space before copying to web.protect +# import /sys/lib/dist/web.protect from the outside +x=`{setup} + +cd:V: $scr/plan9.iso + +ncd:V: $scr/plan9-new.iso.bz2 + +ncd-dist:V: $scr/plan9-new.iso.bz2 + mk $dist/web.protect/plan9-new.iso.bz2 + +cd-dist:V: $scr/plan9.iso.bz2 + mk $dist/web.protect/plan9.iso.bz2 + +contrib-cd:V: $scr/contrib.iso.bz2 + mk $dist/web.protect/contrib.iso.bz2 + +$scr/%.iso:D: $src9/dist/replica/plan9.log + @ { cd pc; mk cddisk } + rm -f $target + bind pc/cddisk cdstub/bootdisk.img + if(! test -f $src9/bootdisk.img) + bind -a cdstub $src9 + title=`{date | sed 's/(...) (...) (..) (..:..):.. (...) (....)/Plan 9 - \2 \3 \6 \4/'} + title=$"title + echo 'CD:' $title + disk/mk9660 -9cj -v $title -s $src9 -b bootdisk.img $target + +# copy compressed file from scratch space to the distribution, carefully +$dist/web.protect/%.iso.bz2: $scr/%.iso.bz2 + >>$target.new + chmod +t $target.new # waste write buf, not venti store + cp $prereq $target.new + # replace previous version with a flash cut + if (test -e $target) + mv $target $target.old # try to not clobber downloads in progress + mv $target.new $target + +cd-cleanup:V: + rm -f $dist/web.protect/*.iso.bz2.old # remove old versions after a delay + +# generate replica log & db for $src9 only +scan:V: + test -d $scr # make sure other was mounted above + test -d $src9 + test -d $dist/web.protect + lock scan.lock replica/scan $dist/sources.replica + chmod +t $src9/dist/replica/*.^(db log) + +# generate replica log & db for all of /n/sources +scanall:V: + @ { + rfork ne + d=/n/sources + test -d $src9 + lock scanall.lock replica/scan $dist/sourcesall.replica + chmod +t $src9/dist/replica/*.^(db log) + } + +compresslog:V: + { + awk -f logcompress.awk $src9/dist/replica/plan9.log | + awk -f logtime.awk -v 't='^`{date -n} >/tmp/plan9.log + rm -f $src9/dist/replica/plan9.new.log + cp /tmp/plan9.log $src9/dist/replica/plan9.new.log && + mv $src9/dist/replica/plan9.new.log $src9/dist/replica/plan9.log + } $src9/dist/replica/plan9.db +# chmod 664 $src9/dist/replica/plan9.log >$src9/dist/replica/plan9.log +# chmod +a $src9/dist/replica/plan9.log +# mk scan + +odump:V: + disk/dump9660 -9cj -v 'Plan 9 4e Dumps' -s $src9 \ + -p /sys/lib/sysconfig/proto/allproto $scr/distdump.iso + +cd.install:V: +# if(~ $sysname achille){ +# echo; echo; echo '*** run this on a real machine, like chips.' +# exit bad +# } + bzip2 -9 <$scr/plan9.iso >web.protect/nplan9.iso.bz2 + +D.install:V: + D=/n/roro/usr/rob/testplan9 + 9fs roro + test -d $D + cp $D$dist/pc/ndisk $dist/web.protect/ndisk + cp $D$dist/pc/9loaddebug $dist/web.protect/n9loaddebug + +reallyinstall:V: + if(! ~ $sysname achille){ + echo; echo; echo '*** this needs to run on achille.' + exit bad + } + cd web.protect + for (i in plan9.iso.bz2 disk 9loaddebug vmware.zip) + if(test -f n$i){ + mv $i _$i && { mv n$i $i || mv _$i $i } + } + rm /srv/ramfs.9down4e + $dist/startcache + +dump:V: + rm -f /srv/9660.xxx + 9660srv 9660.xxx + mount /srv/9660.xxx /n/kremvax $scr/plan9.iso + now=`{mtime $dist/web.protect/plan9.iso.bz2 | awk '{print $1}'} + ls -l /rls/plan9/4e.iso + disk/dump9660 -9cj -s /n/kremvax -n $now /rls/plan9/4e.iso + ls -l /rls/plan9/4e.iso + rm /srv/9660.xxx + +reencode:V: + rm -f $scr/nplan9.iso + rm -f /srv/9660.xxx + 9660srv 9660.xxx + mount /srv/9660.xxx /n/kremvax $scr/plan9.iso + disk/mk9660 -9cj -v 'Plan 9 4th Edition' -s /n/kremvax \ + -b bootdisk.img $scr/nplan9.iso + rm /srv/9660.xxx + +# compress a cd image in scratch space +$scr/%.iso.bz2:D: $scr/%.iso + @ { + cd $scr + bzip2 -9 <$stem.iso >n$stem.iso.bz2 && + { + if (test -e $stem.iso.bz2) + mv $stem.iso.bz2 _$stem.iso.bz2 + mv n$stem.iso.bz2 $stem.iso.bz2 + } + echo `{date} md5 `{md5sum <$stem.iso.bz2} \ + sha1 `{sha1sum <$stem.iso.bz2} \ + $stem.iso.bz2 >>/usr/web/plan9checksums.txt + } + +$scr/contrib.iso:DV: + rm -f $target + disk/mk9660 -9cj -v 'Plan 9 Extras' -s /n/sources \ + -p ./contrib.proto $target + +rebuild:V: + chmod +l build.lock >>build.lock + rebuild >build.lock + rebuild $target + +9-export:V: 9.tar.gz + 9fs sources + cp 9.tar.gz /n/sources/extra/9.tgz + chmod +t /n/sources/extra/9.tgz + +plan9.tar.bz2:V: + @{ + rfork n + 9fs sources + cd /n/sources + test -e $src9 + bind /n/empty $src9/lib/font + bind /n/empty $src9/sys/lib/postscript/font + bind /n/empty $src9/sys/lib/ghostscript + bind /n/empty $src9/sys/src/cmd/gs + tar c plan9/LICENSE* plan9/NOTICE plan9/*/mkfile plan9/*/include \ + plan9/acme/*/src plan9/acme/bin/source \ + plan9/^(adm cron lib lp mail rc sys tmp usr) + } | bzip2 >$target + +plan9-export:V: plan9.tar.bz2 + 9fs sources + chmod +t plan9.tar.bz2 + mv plan9.tar.bz2 /n/sources/extra/plan9.tar.bz2 diff --git a/sys/lib/dist.old/pc/cd0.proto b/sys/lib/dist.old/pc/cd0.proto new file mode 100644 index 000000000..62bdb1b10 --- /dev/null +++ b/sys/lib/dist.old/pc/cd0.proto @@ -0,0 +1 @@ +cddisk diff --git a/sys/lib/dist.old/pc/emptyfile b/sys/lib/dist.old/pc/emptyfile new file mode 100644 index 000000000..e69de29bb diff --git a/sys/lib/dist.old/pc/glenda/bin/rc/riostart b/sys/lib/dist.old/pc/glenda/bin/rc/riostart new file mode 100755 index 000000000..cc5dfa8f2 --- /dev/null +++ b/sys/lib/dist.old/pc/glenda/bin/rc/riostart @@ -0,0 +1,4 @@ +#!/bin/rc + +window '0 0 100 100' games/clock +window '80 80 610 360' /usr/glenda/lib/first.window diff --git a/sys/lib/dist.old/pc/glenda/lib/first.window b/sys/lib/dist.old/pc/glenda/lib/first.window new file mode 100644 index 000000000..c4f264ef2 --- /dev/null +++ b/sys/lib/dist.old/pc/glenda/lib/first.window @@ -0,0 +1,11 @@ +#!/bin/rc +echo -n readme > /dev/label +echo 'You have completed the Installation Process.' + +cat<<'!' + +Welcome to Plan 9. +This is rc. +! + +exec rc diff --git a/sys/lib/dist.old/pc/glenda/lib/profile b/sys/lib/dist.old/pc/glenda/lib/profile new file mode 100644 index 000000000..7767e8a01 --- /dev/null +++ b/sys/lib/dist.old/pc/glenda/lib/profile @@ -0,0 +1,16 @@ +if(test -f '#m/mousectl') { + echo -n accelerated > '#m/mousectl' + echo -n 'res 3' > '#m/mousectl' +} +user=`{cat /dev/user} +home=/usr/$user +bind -a $home/bin/rc /bin +bind -a $home/bin/$cputype /bin +bind -c $home/tmp /tmp +rio -si inst/gui +echo +echo +echo 'failed to start rio. you can start a text-based installation by running' +echo +echo ' inst/textonly' +echo diff --git a/sys/lib/dist.old/pc/inst/bootfloppy b/sys/lib/dist.old/pc/inst/bootfloppy new file mode 100755 index 000000000..c9aebbc51 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/bootfloppy @@ -0,0 +1,47 @@ +#!/bin/rc + +rfork e + +echo +echo 'Insert a disk other than your installation boot disk' +echo 'into your floppy drive; it will be erased to create' +echo 'the boot floppy.' +echo +echo -n 'Press enter when ready.' +read >/dev/null >[2]/dev/null + +if(~ $#adisk 1) + ; # do nothing +if not if(~ $#bootfile 0) + adisk=/dev/fd0disk +if not { + switch($bootfile) { + case sd* + adisk=`{echo $bootfile | sed 's#(sd..).*#/dev/\1/data#'} + case fd* + adisk=`{echo $bootfile | sed 's#(fd.).*#/dev/\1disk#'} + case * + echo 'unknown bootfile '^$bootfile^'; mail 9trouble@plan9.bell-labs.com' + exit oops + } +} + +if(! ~ `{ls -l $adisk | awk '{print $6}'} 1474560){ + echo 'Will not format non-floppy disk '^$"adisk. >[1=2] + exit 'bad adisk' +} + +log Formatting boot floppy +if (test -e /n/newfs/386/9loadnousb) + bind /n/newfs/386/9loadnousb /n/newfs/386/9load # cater to old bioses +disk/format -b /386/pbs \ + -fd $adisk /n/newfs/386/9load /n/newfs/386/9pcdisk.gz \ + /tmp/plan9ini.bak +x=$status + +if(~ $x ''){ + echo + echo 'Done!' + echo +} +exit $x diff --git a/sys/lib/dist.old/pc/inst/bootplan9 b/sys/lib/dist.old/pc/inst/bootplan9 new file mode 100755 index 000000000..942c043b0 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/bootplan9 @@ -0,0 +1,55 @@ +#!/bin/rc + +first=`{ls -p '#S' | sed 1q} +if(! ~ $first $disk) { + echo 'warning: The plan 9 partition is not on the boot disk,' + echo 'so making it the active partition will have no effect.' +} + +p9offset=`{grep '^part 9fat ' /dev/$disk/ctl |awk '{print $3}'} +if(! ~ $#p9offset 1) { + echo 'could not find plan 9 partition.' + echo 'cannot happen' + exit bad +} + +if(test $p9offset -gt 4128695) { # 65536 * 63 - 10 + echo + echo 'Your Plan 9 partition is more than 2GB into your disk,' + echo 'and the master boot records used by Windows 9x/ME' + echo 'cannot access it (and thus cannot boot it).' + echo + echo 'You can install the Plan 9 master boot record, which can load' + echo 'partitions far into the disk.' + echo +} + +echo 'If you use the Windows NT/2000/XP master boot record' +echo 'or a master boot record from a Unix clone (e.g., LILO or' +echo 'FreeBSD bootmgr), it is probably safe to continue using' +echo 'that boot record rather than install the Plan 9 boot record.' +echo +prompt 'Install the Plan 9 master boot record' y n +switch($rd) { +case n + ; +case y + disk/mbr -m /386/mbr /dev/$disk/data +} + +log Setting Plan 9 partition active. +p9part=`{disk/fdisk /dev/$disk/data >[2]/dev/null [1=2] + exit 'no plan 9 partition found' +} +p9part=$p9part(1) +{ echo 'A '^$p9part; echo w } | disk/fdisk /dev/$disk/data >[2]/dev/null >/dev/null +x=$status +if(~ $x '' '|'){ + echo + echo 'The Plan 9 partition is now marked as active.' + exit '' +} +exit $x diff --git a/sys/lib/dist.old/pc/inst/bootsetup b/sys/lib/dist.old/pc/inst/bootsetup new file mode 100755 index 000000000..cc22fe6ee --- /dev/null +++ b/sys/lib/dist.old/pc/inst/bootsetup @@ -0,0 +1,125 @@ +#!/bin/rc + +# desc: create a boot floppy or configure hard disk to boot plan 9 +# prereq: copydist + +switch($1) { +case go + echo + echo 'Initializing Plan 9 FAT configuration partition (9fat)' + echo + + fat=(/dev/sd*/9fat) + fat=$fat(1) + disk=`{echo $fat | sed 's:/dev/::;s:/9fat::'} + bootfs=`{echo $fs | sed 's:/dev/(sd..)/(.*):\1!\2:'} + bootfat=`{echo $fs | sed 's:/dev/(sd..)/(.*):\1!9fat:'} + if(! test -f /dev/$disk/9fat) { + echo 'You have no 9fat partition. Can''t setup booting.' + exit + } + + if(! test -f /tmp/plan9.ini) { + { + sfs=`{echo $fs | sed 's;/dev;#S;'} + if(~ $fstype fossil fossil+venti){ + echo bootfile'='$bootfat!9pcf + echo 'bootargs=local!'^$sfs + echo 'bootdisk=local!'^$sfs + } + if not { + echo bootfile'='$bootfs!/386/9pcdisk + echo 'bootdisk=local!'^$sfs + } + if(~ $fstype fossil+venti){ + venti=`{echo $ventiarena | sed 's;/dev;#S;'} + echo venti'='^$venti + } + # sort -u avoids dups which could otherwise trigger + # pointless boot menus. + grep -v '(^\[)|menuitem|adisk|bootfile|bootdisk|bootargs|nobootprompt|mouseport|vgasize|monitor|cdboot' /tmp/plan9.orig | + sort -u + echo 'mouseport='^$mouseport + echo 'monitor='^$monitor + echo 'vgasize='^$vgasize + } >/tmp/plan9.ini + } + if(! test -f /tmp/plan9ini.bak) + cp /tmp/plan9.ini /tmp/plan9ini.bak + + need9fatformat=no + if(! isfat /dev/$disk/9fat) + need9fatformat=yes + if not if(! mount -c /srv/dos /n/9fat /dev/$disk/9fat >[2]/dev/null) + need9fatformat=yes + if not if(! test -f /n/9fat/plan9.ini) + need9fatformat=yes + + if (test -e /n/newfs/386/9loadnousb) + bind /n/newfs/386/9loadnousb /n/newfs/386/9load # cater to old bioses + if(~ $need9fatformat yes){ + log Initializing Plan 9 FAT partition. + disk/format -r 2 -d -b /386/pbs \ + /dev/$disk/9fat /n/newfs/386/9load + # silently install pbslba if the partition is way into the disk. + # it''s our only hope. only need this for >8.5GB into the disk. + # but... + # there are so few non-LBA bioses out + # there anymore that we'll do this even if we're only 2GB into + # the disk. it's just not worth the headaches of dealing with + # crappy bioses that don't address the whole 8.5GB properly + + 9fatoffset=`{grep '^part 9fat ' /dev/$disk/ctl | awk '{print $4}'} + if(! ~ $#9fatoffset 1) { + echo 'could not find plan 9 partition.' + echo 'cannot happen' + exit bad + } + if(test $9fatoffset -gt 2097152) # 2GB + disk/format -b /386/pbslba /dev/$disk/9fat + + mount -c /srv/dos /n/9fat /dev/$disk/9fat + } + + if(! test -f /n/9fat/4e){ + logprog cp /n/newfs/386/9load /n/9fat/9load + logprog cp /n/newfs/386/9pcf /n/9fat/9pcf + if(test -f /n/9fat/plan9.ini && ! test -f /n/9fat/plan9-3e.ini) + logprog mv /n/9fat/plan9.ini /n/9fat/plan9-3e.ini + if(test -f /n/9fat/9pcdisk && ! test -f /n/9fat/9pc3e) + logprog mv /n/9fat/9pcdisk /n/9fat/9pc3e + + awk -f /bin/inst/mkini.awk >/n/9fat/plan9.ini + >/n/9fat/4e + } + + echo + echo 'There are myriad ways to boot a Plan 9 system.' + echo 'You can use any of the following.' + echo + echo ' floppy - create a boot floppy' + echo ' plan9 - make the plan 9 disk partition the default for booting' + echo ' win9x - add a plan 9 option to windows 9x boot menu' + echo ' winnt - add a plan 9 option to windows nt/2000/xp boot manager' + echo + echo 'If you are upgrading an extant third edition installation and booting' + echo 'from something other than a floppy, you needn''t run anything here.' + echo 'Just type ctl-d.' + + oldbootsetup=$didbootsetup + didbootsetup=1 + export didbootsetup + prompt 'Enable boot method' floppy plan9 win9x winnt + + if(! boot$rd){ + didbootsetup=$oldbootsetup + export didbootsetup + } + +case checkdone + xxxfat=(/dev/sd*/9fat) + if(! isfat $xxxfat(1) || ! ~ $didbootsetup 1){ + bootsetup=ready + export bootsetup + } +} diff --git a/sys/lib/dist.old/pc/inst/bootwin9x b/sys/lib/dist.old/pc/inst/bootwin9x new file mode 100755 index 000000000..68c2d1923 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/bootwin9x @@ -0,0 +1,117 @@ +#!/bin/rc + +dosdisk=`{ls /dev/sd??/dos >[2]/dev/null | sed 1q | sed 's!.*/(.*)/dos!\1!'} +if(~ $#dosdisk 0 || ! c: || ! test -f /n/c:/autoexec.bat || ! test -f /n/c:/config.sys) { + echo 'Could not find autoexec.bat or config.sys on the first FAT disk.' + exit bad +} + +for (i in autoexec config msdos) + if(test -f /n/c:/$i.p9) { + echo 'A Plan 9 backup already exists; will not edit system files again.' + exit bad + } + +for (i in autoexec.bat config.sys msdos.sys) + if(! cp /n/c:/$i /n/c:/^`{echo $i | sed 's/\.(bat|sys)$/.p9/'}) { + echo 'Could not back up '^$i^'; will not continue.' + exit bad + } + +if(! test -d /n/c:/plan9 && ! mkdir /n/c:/plan9) { + echo 'Could not create directory /n/c:/plan9.' + exit bad +} + +if(! cp /n/newfs/386/^(9load ld.com 9pcdisk) /tmp/plan9ini.bak /n/c:/plan9) { + echo 'Could not copy Plan 9 boot files into /n/c:/plan9.' + exit bad +} + +chmod +w /n/c:/autoexec.bat /n/c:/config.sys /n/c:/msdos.sys + +if(grep -si 'Plan ?9' /n/c:/config.sys || grep -si 'Plan ?9' /n/c:/autoexec.bat) { + echo 'Plan 9 entries already in config.sys or autoexec.bat.' + echo 'Not changing them; refer to Plan 9 install documentation' + echo 'to configure manually.' + exit bad +} + +if(! grep -si '\[menu\]' /n/c:/config.sys) { + { + echo 1 + echo i + echo '[menu] ' + echo 'menuitem=windows, Windows ' + echo 'menudefault=windows ' + echo ' ' + echo '[common] ' + echo ' ' + echo '[windows] ' + echo . + echo w + echo q + } | ed /n/c:/config.sys >/dev/null >[2]/dev/null +} + +{ + echo 1 + echo '/\[[Mm][Ee][Nn][Uu]\]' + echo '?^[Mm][Ee][Nn][Uu][Ii][Tt][Ee][Mm]=' + echo a + echo 'menuitem=plan9, Plan 9 from Bell Labs ' + echo . + echo '$' + echo a + echo ' ' + echo '[plan9] ' + echo ' ' + echo . + echo w + echo q +} | ed /n/c:/config.sys >/dev/null>[2]/dev/null + +{ + echo 1 + echo i + echo '@echo off ' + echo 'if %config%==plan9 goto plan9 ' + echo 'goto notplan9 ' + echo ':plan9 ' + echo 'plan9\ld '^$dosdisk^'!dos!plan9/9load ' + echo ':notplan9 ' + echo . + echo w + echo q +} | ed /n/c:/autoexec.bat >/dev/null>[2]/dev/null + +fn zeroopt { + if(grep -s '^'^$1^'=1' /n/c:/msdos.sys) { + { + echo '/^'^$1^'=1/s/=1/=0/' + echo w + echo q + } | ed /n/c:/msdos.sys>/dev/null>[2]/dev/null + } + if not if (grep -s '^'^$1^'=0' /n/c:/msdos.sys) + ; + if not { + { + echo 1 + echo i + echo '[Options] ' + echo 'Logo=0 ' + echo . + echo w + echo q + } | ed /n/c:/msdos.sys>/dev/null>[2]/dev/null + } +} + +if(grep -si '^\[paths\]' /n/c:/msdos.sys){ # Windows 9x rather than DOS + zeroopt Logo +# zeroopt BootGUI +} + +echo 'Plan 9 added to Windows 9X boot menu.' +exit '' diff --git a/sys/lib/dist.old/pc/inst/bootwinnt b/sys/lib/dist.old/pc/inst/bootwinnt new file mode 100755 index 000000000..ee92f5d76 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/bootwinnt @@ -0,0 +1,47 @@ +#!/bin/rc + +if(! c: || ! test -f /n/c:/boot.ini) { + echo 'Could not find NT''s boot.ini on the first FAT disk.' + exit bad +} + +if(test -f /n/c:/boot.p9) { + echo 'A Plan 9 backup already exists; will not edit boot.ini again.' + exit bad +} + +if(! cp /n/c:/boot.ini /n/c:/boot.p9) { + echo 'Could not back up boot.ini; will not continue.' + exit bad +} + +chmod +w /n/c:/boot.ini + +if(! grep -si '\[operating systems\]' /n/c:/boot.ini) { + echo 'Could not parse boot.ini.' + exit bad +} + +if(grep -si 'Plan 9' /n/c:/boot.ini) { + p9file=`{grep 'Plan 9' /n/c:/boot.ini | sed 1q | sed 's/=.*//'} + if(! ~ $p9file [Cc]:'\'*) { + echo 'Unexpected Plan 9 entry in boot.ini already; not continuing.' + exit bad + } +} + +if not { + p9file='c:\bootsect.p9' + echo 'c:\bootsect.p9 = "Plan 9 from Bell Labs" ' >>/n/c:/boot.ini +} + +p9file=/n/^`{echo $p9file | sed 's!\\!/!g'} + + +if(dd -if /dev/$disk/plan9 -bs 512 -count 1 -of $p9file >/dev/null >[2]/dev/null) { + echo 'Plan 9 added to Windows NT boot menu.' + exit '' +} + +echo 'Error copying Plan 9 boot sector to file.' +exit bad diff --git a/sys/lib/dist.old/pc/inst/configarch b/sys/lib/dist.old/pc/inst/configarch new file mode 100755 index 000000000..61912bfdb --- /dev/null +++ b/sys/lib/dist.old/pc/inst/configarch @@ -0,0 +1,40 @@ +#!/bin/rc + +# desc: set source of distribution archives +# prereq: mountfs + +switch($1) { +case go + echo + echo 'Will you be using a distribution archive on local media or the internet?' + echo + + prompt 'Distribution is from' local internet + archmedium=$rd + export archmedium + + switch($archmedium) { + case local + exec configlocal go + case internet + exec configip go + } + +case checkdone + switch($#archmedium) { + case 1 + switch($archmedium) { + case local + exec configlocal checkdone + case internet + exec configip checkdone + case * + configarch=notdone + export configarch + } + case * + configarch=notdone + export configarch + } +} + diff --git a/sys/lib/dist.old/pc/inst/configdist b/sys/lib/dist.old/pc/inst/configdist new file mode 100755 index 000000000..3e99bea0d --- /dev/null +++ b/sys/lib/dist.old/pc/inst/configdist @@ -0,0 +1,22 @@ +#!/bin/rc + +# prereq: mountfs +# desc: choose the source of the distribution archive + +switch($1){ +case checkdone + if(! ~ $distisfrom net local){ + configdist=ready + export configdist + } + +case go + echo 'Are you going to download the distribution' + echo 'from the internet or do you have it on local media?' + echo + prompt -d local 'Distribution is from' local net + distisfrom=$rd + export distisfrom +} + + diff --git a/sys/lib/dist.old/pc/inst/configether b/sys/lib/dist.old/pc/inst/configether new file mode 100755 index 000000000..0922ea339 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/configether @@ -0,0 +1,53 @@ +#!/bin/rc + +# desc: configure your internet connection via an ethernet card + +switch($1) { +case go + echo + echo 'Please choose a method for configuring your ethernet connection.' + echo + echo ' manual - specify IP address, network mask, gateway IP address' + echo ' dhcp - use DHCP to automatically configure' + echo + + prompt 'Configuration method' manual dhcp + ethermethod=$rd + gwaddr=xxx + ipaddr=xxx + ipmask=xxx + switch($ethermethod){ + case dhcp + echo + echo 'Some ISPs, notably @HOME, require a host name passed with DHCP' + echo 'requests. An example for @HOME would be "cc1018221-a". If your' + echo 'ISP supplied you such a name, enter it.' + echo + prompt -d none 'host name'; dhcphost=$rd + switch($dhcphost){ + case none + dhcphost=(); + case * + dhcphost=(-h $dhcphost) + } + export dhcphost + case manual + prompt 'ip address'; ipaddr=$rd + prompt 'network mask'; ipmask=$rd + prompt 'gateway address'; gwaddr=$rd + export ipaddr ipmask gwaddr + } + + export ethermethod gwaddr ipaddr ipmask dhcphost + exec startether go + +case checkdone + if(! ~ $ethermethod manual dhcp) { + configether=notdone + export configether + } + if(~ $ethermethod manual && ~ 0 $#ipaddr $#ipmask $#gwaddr) { + configether=notdone + export configether + } +} diff --git a/sys/lib/dist.old/pc/inst/configfs b/sys/lib/dist.old/pc/inst/configfs new file mode 100755 index 000000000..81f82897c --- /dev/null +++ b/sys/lib/dist.old/pc/inst/configfs @@ -0,0 +1,23 @@ +#!/bin/rc + +# desc: choose the type of file system to install + +switch($1){ +case checkdone + if(! ~ $fstype fossil fossil+venti){ + configfs=ready + export configfs + } + +case go + echo 'You can install the following types of file systems:' + echo + echo ' fossil the new Plan9 fileserver' + echo ' fossil+venti fossil + a archival dump server' + echo + prompt -d fossil 'File system' fossil fossil+venti + fstype=$rd + export fstype +} + + diff --git a/sys/lib/dist.old/pc/inst/configip b/sys/lib/dist.old/pc/inst/configip new file mode 100755 index 000000000..a7873c9f1 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/configip @@ -0,0 +1,64 @@ +#!/bin/rc + +switch($1) { +case go + + devs='' + if(test -d '#l/ether0' >[2]/dev/null) + devs=$devs^ether + if(test -f '#t'/eia? >[2]/dev/null) + devs=$devs^ppp + + switch($devs){ + case '' + echo + echo 'Could not find ethernet card nor serial port nor modem.' + echo 'Please use a local copy of the distribution archive.' + echo + ifc=none + + case ppp + echo + echo 'No ethernet card was detected, but there is a serial port or modem.' + echo 'We will configure PPP.' + echo + ifc=ppp + + case ether + echo + echo 'No serial port or modem detected, but there is an ethernet card.' + echo 'We will configure the ethernet.' + echo + ifc=ether + + case etherppp + echo + echo 'You can connect to the internet via' + echo 'a local ethernet or a dial-up PPP connection.' + echo + prompt 'Interface to use' ether ppp + ifc=$rd + } + + ipinterface=$ifc + export ipinterface + + switch($ifc) { + case ether + exec configether go + case ppp + exec configppp go + } + +case checkdone + if(~ $#ipinterface 1) + switch($ipinterface) { + case ether + exec configether checkdone + case ppp + exec configppp checkdone + } + configarch=notdone + export configarch + +} diff --git a/sys/lib/dist.old/pc/inst/confignet b/sys/lib/dist.old/pc/inst/confignet new file mode 100755 index 000000000..182ed40cb --- /dev/null +++ b/sys/lib/dist.old/pc/inst/confignet @@ -0,0 +1,67 @@ +#!/bin/rc + +# prereq: configdist +# desc: configure the network to download the distribution + +switch($1){ +case checkready checkdone + if(! ~ $distisfrom net){ + confignet=notdone + export confignet + exit + } + if(~ $distisfrom net && ~ $netisfrom ppp ether){ + x=config$netisfrom + $x=done + config$netisfrom checkdone + confignet=$$x + export confignet + exit + } + confignet=ready + export confignet + exit + +case go + devs='' + if(test -d '#l/ether0' >[2]/dev/null) + devs=$devs^ether + if(test -f '#t'/eia? >[2]/dev/null) + devs=$devs^ppp + + switch($devs){ + case '' + echo + echo 'Could not find ethernet card nor serial port nor modem.' + echo 'Please use a local copy of the distribution archive.' + echo + netisfrom=none + + case ppp + echo + echo 'No ethernet card was detected, but there is a serial port or modem.' + echo 'We will configure PPP.' + echo + netisfrom=ppp + + case ether + echo + echo 'No serial port or modem detected, but there is an ethernet card.' + echo 'We will configure the ethernet.' + echo + netisfrom=ether + + case etherppp + echo + echo 'You can connect to the internet via' + echo 'a local ethernet or a dial-up PPP connection.' + echo + prompt 'Interface to use' ether ppp + netisfrom=$rd + } + + export netisfrom + if(~ $netisfrom ether ppp) + exec config$netisfrom go +} + diff --git a/sys/lib/dist.old/pc/inst/configppp b/sys/lib/dist.old/pc/inst/configppp new file mode 100755 index 000000000..6bbffc4f0 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/configppp @@ -0,0 +1,63 @@ +#!/bin/rc + +# desc: configure your internet connection via ppp over a modem + +switch($1) { +case go + devs=`{ls -p '#t/'eia? >[2]/dev/null} + if(~ $#devs 0) { + echo 'No serial port found; this can''t happen.' # because configip checks + exit + } + + # not going to use the mouse for PPP + if(~ eia^$mouseport $devs) + devs=`{echo $devs | sed 's/eia'^$mouseport^'//'} + + if(~ $#devs 0) { + echo 'The only serial port you have is your mouse.' + echo 'Cannot configure PPP.' + exit + } + + echo + echo 'Please choose the serial port or modem to use to connect to your ISP.' + echo + for(i in $devs) { + n=`{echo $i | sed 's/eia//'} + n=`{hoc -e 1+$n} + echo ' '^$i^'(Windows'' COM'^$n^')' + } + echo + prompt 'Serial device' $devs + pppdev=$rd + + echo + echo 'Pick a baud rate for the PPP connection.' + echo + prompt -d 115200 'Baud rate' + pppbaud=$rd + + echo + echo 'You can specify your dialup phone number, username, and password,' + echo 'or you can log in manually by typing the modem commands yourself.' + echo + prompt 'Dialing method' auto manual + pppmethod=$rd + + switch($pppmethod){ + case auto + prompt 'PPP phone number'; pppphone=$rd + prompt 'PPP phone username'; pppuser=$rd + prompt 'PPP phone password'; ppppasswd=$rd + } + + export pppdev pppmethod pppphone ppppasswd pppuser pppbaud + exec startppp go + +case checkdone + if(! ~ $#pppmethod 1 || ! test -f /dev/$pppdev){ + configppp=notdone + export configppp + } +} diff --git a/sys/lib/dist.old/pc/inst/copydist b/sys/lib/dist.old/pc/inst/copydist new file mode 100755 index 000000000..507d5602b --- /dev/null +++ b/sys/lib/dist.old/pc/inst/copydist @@ -0,0 +1,31 @@ +#!/bin/rc + +# prereq: mountdist +# desc: copy the distribution into the file system + +switch($1){ +case checkready + if(! test -d /n/dist/dist/replica){ + copydist=notdone + export copydist + exit + } + if(test -f /n/newfs/dist/replica/didplan9){ + copydist=done + export copydist + exit + } +case go + inst/watchfd applylog 0 `{ls -l /n/dist/dist/replica/plan9.log | awk '{print $6}'} 'Installing file system' & + replica/pull -c / /rc/bin/inst/replcfg + if(~ $status '' *conflicts || test -f /n/newfs/dist/replica/didplan9witherrors) + >/n/newfs/dist/replica/didplan9 + if not + >/n/newfs/dist/replica/didplan9witherrors + +case checkdone + if(! test -f /n/newfs/dist/replica/didplan9){ + copydist=notdone + export copydist + } +} diff --git a/sys/lib/dist.old/pc/inst/defs b/sys/lib/dist.old/pc/inst/defs new file mode 100755 index 000000000..f9c9454c0 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/defs @@ -0,0 +1,162 @@ +nl=' +' +tab=' ' +if(~ $#distname 0) + distname=plan9 + +wctl=/dev/null +if(test -w /dev/wctl) + wctl=/dev/wctl + +fn log { + echo $* >>/srv/log +} + +fn logprog { + echo '% '^$"* >>/srv/log + $* >[2=1] >>/srv/log +} + +fn sigint { + # nothing happens +} + +fn prompt { + def=() + what=() + if(~ $1 -d && ! ~ $#* 1){ + def=$2 + shift + shift + } + + optstr=() + if(~ $1 -w && ! ~ $#* 1){ + optstr=$2 + shift + shift + } + + pr=$1 + shift + + opts=($*) + if(~ $#opts 0) { + suf=' ' + } + if not if(! ~ $#optstr 0) { + if(~ $optstr '') + suf=' ' + if not { + pr=$pr^' ('^$"optstr^')' + suf='' + } + } + if not { + pr=$pr^' ('^$1 + shift + for(i) + pr=$pr^', '^$i + pr=$pr^')' + suf='' + } + + if(~ $#def 1) + pr=$pr^$suf^'['^$def^']' + if not + pr=$pr^$suf^'[no default]' + + pr=$pr^': ' + + + okay=no + while(~ $okay no) { + echo -n current >$wctl + echo -n top >$wctl + echo -n $pr >[1=2] + ifs='' {rd=`{read}} + if(~ $#rd 0) + exit notdone + if(~ $rd !*){ + ifs='' {rd=`{echo $rd | sed 's/!//'}} + echo $rd + rc -c $rd + echo !$status + } + if not{ + rd=`{echo $rd} + if(~ $#rd 0 || ~ $rd '') + rd=$def + + switch($#opts){ + case 0 + if(! ~ $rd '') + okay=yes + case * + if(~ $rd $opts) + okay=yes + } + } + } + echo -n $rd >/env/rd # just in case +} + +fn desc { + echo -n ' '^$1^' - ' + grep '^# desc: ' $1 | sed 's/# desc: //' +} + +fn prereq { + grep '^# prereq:' $1 | sed 's/# prereq://' +} + +fn mustdo { + echo You must `{grep '^# mustdo:' $1 | sed 's/# mustdo://'} +} + +# there's no easy way to pass shell variables +# up from children to parents; the parents have +# to be coerced into noticing that the environment +# changed, even when in the same environment group. +# +# instead, we explicitly export the variables we want +# to percolate, and the parent calls coherence to reread +# the variables. +# +# we just append to the vars file, so that later exports +# override earlier ones; when we call coherence, +# the duplicates are thrown out. + +fn export { + null=() + nonnull=() + for(i in $*){ + if(~ $#$i 0) + null=($null $i) + if not + nonnull=($nonnull $i) + } + if(! ~ $#nonnull 0) + whatis $nonnull |grep -v '^\./' >>/tmp/vars >[2]/dev/null + for(i in $null) + echo $i^'=()' >>/tmp/vars +} + +fn coherence { + if(test -f /tmp/vars) { + grep '^[a-z]*=' /tmp/vars >/tmp/vars2 + v=`{sed 's/^([a-z]*)=.*/\1/' /tmp/vars2 | sort -u} + . /tmp/vars2 + rm /tmp/vars2 + rm /tmp/vars + export $v + } +} + +# ip device stats + +fn isipdevup { + grep -s $1 /net/ipifc/*/status >[2]/dev/null +} + + diff --git a/sys/lib/dist.old/pc/inst/download b/sys/lib/dist.old/pc/inst/download new file mode 100755 index 000000000..70d7f5ba7 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/download @@ -0,0 +1,56 @@ +#!/bin/rc + +# prereq: mountfs +# desc: download or continue to download the distribution archives + +switch($1) { +case checkready + devs=(`{cat /net/ipifc/*/status >[2]/dev/null | + grep -v '127\.0\.0\.1' | + sed 's/ .*//'}) + if(~ $#devs 0) { + download=notdone + export download + } + if(~ $mountdist done){ + download=notdone + export download + } + +case go + if(! test -f /srv/cs) { + log starting cs, dns + logprog ndb/cs >>/srv/log >[2=1] + logprog ndb/dns -r >>/srv/log >[2=1] + } + if(! test -f /net/cs) { + logprog mount -a /srv/cs /net + logprog mount -a /srv/dns /net + } + + # BUG make restartable + echo 'Downloading distribution package...' + baropt='-w 145,129,445,168' + if(~ $textinst 1) + baropt=-t + if(! hget -vo /n/newfs/dist/_plan9.iso.bz2 $installurl/plan9.iso.bz2 |[2] bargraph $baropt 'downloading '^plan9.iso.bz2) + exit + mv /n/newfs/dist/_plan9.iso.bz2 /n/newfs/dist/plan9.iso.bz2 + if(~ $fstype fossil){ + echo fsys main sync >>/srv/fscons + } + + echo 'The distribution is downloaded.' + + srvmedia=() + mountmedia=(mount /srv/fossil /n/distmedia) + distmediadir=/dist + export distmediadir mountmedia distmedia + +case checkdone + if(! test -f /n/newfs/dist/plan9.iso.bz2) { + download=notdone + export download + } +} + diff --git a/sys/lib/dist.old/pc/inst/finish b/sys/lib/dist.old/pc/inst/finish new file mode 100755 index 000000000..e616e64e1 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/finish @@ -0,0 +1,19 @@ +#!/bin/rc + +# desc: finish the installation and reboot +# prereq: bootsetup +# mustdo: + +switch($1) { +case checkdone + finish=ready + export finish + +case go + if(~ $cdboot yes){ + echo 'Congratulations; you''ve completed the install.' + echo + halt + } + stop go finished +} diff --git a/sys/lib/dist.old/pc/inst/fmtfossil b/sys/lib/dist.old/pc/inst/fmtfossil new file mode 100755 index 000000000..98bf33fc1 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/fmtfossil @@ -0,0 +1,91 @@ +#!/bin/rc + +# desc: initialize disks for a fossil server +# prereq: configfs + +switch($1){ +case checkready checkdone + if(! ~ $fstype fossil+venti fossil){ + fmtfossil=notdone + export fmtfossil + exit + } + ff=`{ls /dev/sd*/fossil* /dev/fs/fossil* >[2]/dev/null} + if(~ $#ff 0){ + fmtfossil=notdone + export fmtfossil + exit + } + gg=() + for(f in $ff) + if(isfossil $f) + gg=($gg $f) + if(~ $#gg 0){ + fmtfossil=ready + export fmtfossil + exit + } + fmtfossil=done + export fmtfossil + exit + +case go + ff=`{ls /dev/sd*/fossil* /dev/fs/fossil* >[2]/dev/null} + if(~ $#ff 0){ + echo 'You need to create a partition or partitions to hold the Fossil write cache.' + echo 'The partition name must begin with "fossil".' + echo + fmtfossil=notdone + export fmtfossil + exit + } + default=() + if(~ $#ff 1){ + default=(-d $ff) + } + echo You have the following fossil partitions. + echo + prompt $default 'Fossil partition to format' $ff + f=$rd + + do=yes + if(isfossil $f){ + echo $f appears to already be formatted as Fossil file system. + echo Do you really want to reformat it? + echo + prompt -d no 'Reformat '$f yes no + do=$rd + } + if(~ $do yes){ + fossil/flfmt -y $f + n=`{cat /dev/swap | grep ' user' | sed 's/^[0-9]+\/([0-9]+) .*/\1/'} + if(test $n -gt 32768) + m=3000 # if have at least 128 user MB, use 24MB for fossil + if not if(test $n -gt 16384) + m=1500 # 64 user MB => 12MB for fossil + if not if(test $n -gt 8192) + m=750 # 32 user MB => 6MB for fossil + if not + m=256 # 2MB for fossil (this will be slow) + + # if we're using a venti in the back, take hourly snapshots + # that retire after three days, in addition to the daily dumps at 5am + if(~ $fstype fossil+venti){ + v='' + snap='fsys main snaptime -s 60 -a 0500 -t 2880' + } + # otherwise, take the daily dumps but nothing else -- + # we can't retire snapshots unless dumps are being archived + if not{ + v='-V' + snap='' + } + echo \ +'fsys main config '^$f^' +fsys main open '^$v^' -c '^$m^' +'^$snap^' +' | fossil/conf -w $f + } + + echo Done. +} diff --git a/sys/lib/dist.old/pc/inst/fmtventi b/sys/lib/dist.old/pc/inst/fmtventi new file mode 100755 index 000000000..db79440ac --- /dev/null +++ b/sys/lib/dist.old/pc/inst/fmtventi @@ -0,0 +1,190 @@ +#!/bin/rc + +# desc: initialize disks for a venti server +# prereq: mountdist + +switch($1){ +case checkready checkdone + if(! ~ $fstype fossil+venti){ + fmtventi=notdone + export fmtventi + exit + } + if(! test -e /bin/venti/fmtarenas || ! test -e /bin/venti/fmtisect || ! test -e /bin/venti/fmtindex){ + bind -a /n/dist/386/bin/venti /bin/venti + if(! test -e /bin/venti/fmtarenas || ! test -e /bin/venti/fmtisect || ! test -e /bin/venti/fmtindex){ + fmtventi=notdone + export fmtventi + exit + } + } + ff=`{ls /dev/sd*/arenas* /dev/fs/arenas* >[2]/dev/null} + if(~ $#ff 0){ + fmtventi=notdone + export fmtventi + exit + } + gg=() + for(f in $ff) + if(isventi $f) + gg=($gg $f) + if(~ $#gg 0){ + fmtventi=ready + export fmtventi + exit + } + + ventiarena=$gg(1) + export ventiarena + + fmtventi=done + export fmtventi + exit + +case go + ff=`{ls /dev/sd*/arenas* /dev/fs/arenas* >[2]/dev/null} + if(~ $#ff 0){ + echo 'You need to create a partition or partitions to hold the Venti arenas.' + echo 'The arena partition names must begin with "arenas".' + echo + fmtventi=notdone + export fmtventi + exit + } + default=(-d $"ff) + if(! ~ $#ventiarena 0){ + default=(-d $"ventiarena) + } + echo You have the following Venti arena partitions. + ls -l $ff + echo + + prompt $default 'Venti arena partitions to use' + aa=`{echo $rd} + bad=no + for(a in $aa){ + if(! ~ $a $ff){ + echo 'Bad venti arena partition' $a + fmtventi=notdone + export fmtventi + exit + } + } + ventiarena=$aa + export ventiarena + + gg=`{ls /dev/sd*/isect* /dev/fs/isect* >[2]/dev/null} + if(~ $#gg 0){ + echo 'You need to create a partition or partitions to hold the Venti indices.' + echo 'The index partition names must begin with "isect".' + echo + fmtventi=notdone + export fmtventi + exit + } + default=(-d $"gg) + if(! ~ $#ventiindex 0){ + default=(-d $"ventiindex) + } + + echo You have the following Venti index partitions. + ls -l $gg + echo + + prompt $default 'Venti index partitions to use' + aa=`{echo $rd} + bad=no + for(a in $aa){ + if(! ~ $a $gg){ + echo 'Bad venti index partition' $a + fmtventi=notdone + export fmtventi + exit + } + } + ventiindex=$aa + export ventiindex + + n=-1 + fmta=() + for(a in $ventiarena){ + do=yes + n=`{hoc -e 1+$n} + if(isventiarenas $a){ + echo File $a is already formatted as a Venti arenas partition. + prompt -d no 'Reformat '$a yes no + do=$rd + } + if(~ $do yes) + fmta=($fmta arenas$n:$a) + } + + n=-1 + fmti=() + for(a in $ventiindex){ + do=yes + n=`{hoc -e 1+$n} + if(isventiisect $a){ + echo File $a is already formatted as a Venti index section. + prompt -d no 'Reformat '$a yes no + do=$rd + } + if(~ $do yes) + fmti=($fmti isect$n:$a) + } + + echo Formatting Venti arenas and indices (this takes a while). + # do each disk in parallel + echo good >/tmp/fmt + dd=() + for(a in $fmta $fmti){ + d=`{echo $a | sed 's!.*:(/.*/).*!\1!'} + if(! ~ $d $dd) + dd=($dd $d) + } + for(d in $dd){ + { + for(a in $fmta){ + i=`{echo $a | sed 's!(.*):(/.*/)(.*)!\1 \2 \2\3!'} + if(~ $i(2) $d){ + echo $i(3) ... + venti/fmtarenas $i(1) $i(3) || echo bad >/tmp/fmt + echo done with $i(3) + } + } + for(a in $fmti){ + i=`{echo $a | sed 's!(.*):(/.*/)(.*)!\1 \2 \2\3!'} + if(~ $i(2) $d){ + echo $i(3) ... + venti/fmtisect $i(1) $i(3) || echo bad >/tmp/fmt + echo done with $i(3) + } + } + } & + } + wait + if(~ bad `{cat /tmp/fmt}){ + echo There were errors formatting the indices and arenas. + fmtventi=ready + export fmtventi + exit errors + } + + echo Done formatting Venti arenas and indices. + + v=$ventiarena(1) + echo Storing Venti config on $v... + { + echo index main + for(i in $ventiindex) + echo isect $i + for(a in $ventiarena) + echo arenas $a + } | venti/conf -w $v + + echo Initializing index... + venti/fmtindex $v + + echo Done with Venti! +} + diff --git a/sys/lib/dist.old/pc/inst/gui b/sys/lib/dist.old/pc/inst/gui new file mode 100755 index 000000000..afb0981d0 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/gui @@ -0,0 +1,7 @@ +#!/bin/rc + +cd /bin/inst +echo blanktime 0 >/dev/vgactl +. defs + +startwin 640 480 diff --git a/sys/lib/dist.old/pc/inst/halt b/sys/lib/dist.old/pc/inst/halt new file mode 100755 index 000000000..4554359f0 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/halt @@ -0,0 +1,18 @@ +#!/bin/rc + +echo -n 'Halting file systems...' + +if(ps | grep -s ' venti$') + venti/sync -h tcp!127.0.0.1!17034 +if(ps | grep -s ' fossil$'){ + echo fsys all halt >>/srv/fscons + slay fossil|rc +} + +echo done +echo +echo Remember to take the install disk out of the drive. +echo Feel free to turn off your computer. +while() + sleep 3600 + diff --git a/sys/lib/dist.old/pc/inst/hasmbr b/sys/lib/dist.old/pc/inst/hasmbr new file mode 100755 index 000000000..1adaa0a5b --- /dev/null +++ b/sys/lib/dist.old/pc/inst/hasmbr @@ -0,0 +1,12 @@ +#!/bin/rc + +if(! ~ $#* 1) { + echo 'usage: hasmbr /dev/sdC0/part' >[1=2] + exit usage +} + +x=`{xd -b $1 | sed -n '32p;32q'} +if(~ $x(16) 55 && ~ $x(17) aa) + exit '' +exit nope + diff --git a/sys/lib/dist.old/pc/inst/hdrs b/sys/lib/dist.old/pc/inst/hdrs new file mode 100755 index 000000000..0b934999f --- /dev/null +++ b/sys/lib/dist.old/pc/inst/hdrs @@ -0,0 +1,7 @@ +#!/bin/rc + +if(! ~ $#* 1) { + echo 'usage: hdrs file.9gz' >[1=2] + exit usage +} +gunzip < $1 | disk/mkext -h diff --git a/sys/lib/dist.old/pc/inst/is9660 b/sys/lib/dist.old/pc/inst/is9660 new file mode 100755 index 000000000..1d138e55e --- /dev/null +++ b/sys/lib/dist.old/pc/inst/is9660 @@ -0,0 +1,12 @@ +#!/bin/rc + +# 0000000 01 C D 0 0 1 01 00 P L A N 9 + +if(! ~ $#* 1) { + echo 'usage: is9660 /dev/sdC0/part' >[1=2] + exit usage +} + +ifs=$nl {id=`{dd -if $1 -bs 2048 -skip 16>[2]/dev/null | xd -c | sed 1q | sed 's/.........(....................).*/\1/'}} +~ $id '01 C D 0 0 1 01' +exit $status diff --git a/sys/lib/dist.old/pc/inst/isext2 b/sys/lib/dist.old/pc/inst/isext2 new file mode 100755 index 000000000..b79265f6a --- /dev/null +++ b/sys/lib/dist.old/pc/inst/isext2 @@ -0,0 +1,11 @@ +#!/bin/rc + +if(! ~ $#* 1) { + echo 'usage: isext2 /dev/sdC0/part' >[1=2] + exit usage +} + +cmp -s <{dd -if $1 -bs 1 -count 2 -skip 1080 >[2]/dev/null | xd -b |sed 1q} \ + <{echo '0000000 53 ef'} + +exit $status diff --git a/sys/lib/dist.old/pc/inst/isfat b/sys/lib/dist.old/pc/inst/isfat new file mode 100755 index 000000000..860278571 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/isfat @@ -0,0 +1,22 @@ +#!/bin/rc + +rfork e + +# 0000000 eb 3c 90 P l a n 9 . 0 0 00 02 04 02 00 +# 0000010 02 00 02 02 P f8 14 00 ? 00 ff 00 ~ 04 } 00 +# 0000020 02 P 00 00 80 00 ) a8 04 } 00 C Y L I N +# 0000030 D R I C A L F A T 1 6 fa 8c + +if(! ~ $#* 1) { + echo 'usage: isfat /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +fn fat { + cmp -s <{dd -if $arg -bs 1 -count 3 -skip $1 >[2]/dev/null} <{echo -n FAT} +} + +fat 54 || fat 82 +exit $status + diff --git a/sys/lib/dist.old/pc/inst/isfossil b/sys/lib/dist.old/pc/inst/isfossil new file mode 100755 index 000000000..21c7d3e29 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/isfossil @@ -0,0 +1,16 @@ +#!/bin/rc + +if(! ~ $#* 1){ + echo 'usage: isfossil /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 127 | + dd -quiet 1 -bs 14 -count 1} <{echo 'fossil config'}) + exit noconfig +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 128 | + dd -quiet 1 -bs 4 -count 1 | xd -b | sed 1q} <{echo '0000000 37 76 ae 89'}) + exit notwritebuffer +exit 0 + diff --git a/sys/lib/dist.old/pc/inst/isventi b/sys/lib/dist.old/pc/inst/isventi new file mode 100755 index 000000000..555c27a7f --- /dev/null +++ b/sys/lib/dist.old/pc/inst/isventi @@ -0,0 +1,13 @@ +#!/bin/rc + +if(! ~ $#* 1){ + echo 'usage: isventi /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 248 | + dd -quiet 1 -bs 13 -count 1} <{echo 'venti config'}) + exit noconfig +exit 0 + diff --git a/sys/lib/dist.old/pc/inst/isventiarenas b/sys/lib/dist.old/pc/inst/isventiarenas new file mode 100755 index 000000000..dfce274de --- /dev/null +++ b/sys/lib/dist.old/pc/inst/isventiarenas @@ -0,0 +1,13 @@ +#!/bin/rc + +if(! ~ $#* 1){ + echo 'usage: isventiarenas /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 256 | + dd -quiet 1 -bs 4 -count 1 | xd -b | sed 1q} <{echo '0000000 a9 e4 a5 e7'}) + exit notarenas +exit 0 + diff --git a/sys/lib/dist.old/pc/inst/isventiisect b/sys/lib/dist.old/pc/inst/isventiisect new file mode 100755 index 000000000..0b11c9c4e --- /dev/null +++ b/sys/lib/dist.old/pc/inst/isventiisect @@ -0,0 +1,13 @@ +#!/bin/rc + +if(! ~ $#* 1){ + echo 'usage: isventiisect /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 256 | + dd -quiet 1 -bs 4 -count 1 | xd -b | sed 1q} <{echo '0000000 d1 5c 5e c7'}) + exit notisect +exit 0 + diff --git a/sys/lib/dist.old/pc/inst/main b/sys/lib/dist.old/pc/inst/main new file mode 100755 index 000000000..25ac0d168 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/main @@ -0,0 +1,115 @@ +#!/bin/rc + +. defs + +while() +{ +div=-------------------------------------- +echo +echo $div +echo +echo -n 'Preparing menu...' + +# must be topologically sorted (by prereq) +tasks=(\ + configfs\ + partdisk prepdisk\ + fmtfossil\ + mountfs\ + configdist\ + confignet\ + mountdist\ + fmtventi\ + download\ + copydist\ + bootsetup finish stop\ + stopether stopppp\ +) +# startether startppp stopether stopppp download\ + +# these don't show up in the menu but still matter +pseudotasks=(configip havefiles etherup etherdown pppup pppdown) + +for(i in $tasks $pseudotasks) + $i=notdone + +coherence + +for(i in $tasks $pseudotasks) + if(~ $#$i 0) + $i=notdone + +# +# we believe the environment about what is done +# only if we've confirmed it. since the tasks list is sorted so that +# prereqs of xxx come before xxx, it's okay to assume xxx +# is done until proven otherwise -- either a prereq or checkdone +# will say so. +# + +done=() +ready=() +rm /env/done +rm /env/ready +for(i in $tasks) { + $i=done + for(j in `{prereq $i}) + if(! ~ $$j done) + $i=notdone + if(~ $$i done) { + export $i + $i checkdone + $i=`{grep '^'$i^'=' /tmp/vars | sed -n '$p' | sed 's/.*=//'} + } + + if(~ $$i notdone ready) { + okay=yes + for(j in `{prereq $i}) + if(! ~ $$j done) + okay=no + switch($okay){ + case yes + $i=ready + export $i + $i checkready + $i=`{grep '^'$i^'=' /tmp/vars | sed -n '$p' | sed 's/.*=//'} + case no + $i=notdone + } + } + + if(~ $$i done ready) + $$i=($$$i $i) # rc can be just as complicated as perl! +} + +export $tasks $pseudotasks done ready +coherence +echo + +if(! ~ $#done 0) { + echo 'The following tasks are done: ' + for(i in $done) + desc $i + echo +} + +echo 'The following unfinished tasks are ready to be done:' +for(i in $ready) + desc $i +echo + +if(~ $#ready 0) { + echo hey you finished everything! not supposed to happen. + sleep 100 + exit +} + +prompt -d $ready(1) -w '' 'Task to do' $done $ready + +echo +echo $div + +$rd go +$rd=done # if it's not, the check will figure that out +export $rd +} diff --git a/sys/lib/dist.old/pc/inst/mainloop b/sys/lib/dist.old/pc/inst/mainloop new file mode 100755 index 000000000..94d58efc4 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/mainloop @@ -0,0 +1,23 @@ +#!/bin/rc + +sleep 86400 & +cd /bin/inst +. defs +fn sigint { } + +coherence + +disks=`{ls /dev/sd*/data >[2]/dev/null | sed 's!/dev/(sd..)/data!\1!'} +for (i in /dev/sd*/data) + if(test -f $i) + disk/fdisk -p $i>`{basename -d $i}^/ctl >[2]/dev/null +for(i in /dev/sd*/plan9*) + if(test -f $i) + disk/prep -p $i >`{basename -d $i}^/ctl >[2]/dev/null + +# we run this while() here so that ctl-d won''t exit from us -- it''ll only exit main! +# main contains a while() loop too, to avoid the hit of +# continually reexecing from here. + +while() + main diff --git a/sys/lib/dist.old/pc/inst/mkini.awk b/sys/lib/dist.old/pc/inst/mkini.awk new file mode 100755 index 000000000..7ddf6a80f --- /dev/null +++ b/sys/lib/dist.old/pc/inst/mkini.awk @@ -0,0 +1,59 @@ +BEGIN{ + m = "common" + haveold = 0; + while(getline <"/n/9fat/plan9-3e.ini" > 0){ + haveold = 1 + if($0 ~ /\[.*\]/){ + m = substr($0, 2, length($0)-2) + continue + } + if(m=="menu" && $0 ~ /^menuitem=4e,/) + continue + a[m] = a[m] $0 "\n" + } + + a["4e"] = "" + while(getline <"/tmp/plan9.ini" > 0) + a["4e"] = a["4e"] $0 "\n" + + if(a["menu"] == "" && haveold){ + a["menu"] = "menuitem=3e, Plan 9 Third Edition\n" + a["3e"] = "" + } + + if(a["common"] != ""){ + for(i in a) + if(i != "4e" && i != "common" && i != "menu") + a[i] = a["common"] a[i] + delete a["common"] + } + + bootdisk4e=ENVIRON["fs"] + gsub("/dev/", "boot(args|disk|file)=local!#S/", bootdisk4e) + + if(!haveold) + print a["4e"] + else{ + print "[menu]" + print "menuitem=4e, Plan 9 Fourth Edition" + print a["menu"] + print "" + delete a["menu"] + + print "[4e]" + print a["4e"] + print "" + delete a["4e"] + + for(i in a){ + # BUG: if rootdir is already there we should rewrite it + # sometimes into /3e/whatwasthere + if(a[i] ~ bootdisk4e && !(a[i] ~ /rootdir=/)) + a[i] = "rootdir=/root/3e\n" a[i] + print "[" i "]" + gsub(/9fat!9pcdisk/, "9fat!9pc3e", a[i]) + print a[i] + print "" + } + } +} diff --git a/sys/lib/dist.old/pc/inst/mountdist b/sys/lib/dist.old/pc/inst/mountdist new file mode 100755 index 000000000..8d171a1cc --- /dev/null +++ b/sys/lib/dist.old/pc/inst/mountdist @@ -0,0 +1,222 @@ +#!/bin/rc + +# prereq: mountfs configdist +# desc: locate and mount the distribution + +fn domount{ + if(! test -e $mountmedia(2)) + logprog $srvmedia + unmount /n/distmedia >[2]/dev/null + logprog $mountmedia +} + +fn exitifdone{ + if(test -f /n/dist/dist/replica/plan9.db) + exit +} + +fn trycdimage{ + if(test -f $1){ + rm -f /srv/9660.dist + unmount /n/dist + 9660srv 9660.dist >[2]/dev/null + logprog mount /srv/9660.dist /n/dist $1 + exitifdone + mountdist=notdone + export mountdist + exit notdone + } +} + +fn trycdimagebz2 { + if(test -f $1){ + echo -n 'bunzip2 < '^$1^' >/n/newfs/dist/plan9.iso' + bunzip2 < $1 >/n/newfs/dist/_plan9.iso && + mv /n/newfs/dist/_plan9.iso /n/newfs/dist/plan9.iso + echo + trycdimage /n/newfs/dist/plan9.iso + mountdist=notdone + export mountdist + exit notdone + } +} + +fn havedist { + test -f $1/dist/replica/plan9.db || + test -f $1/plan9.iso || + test -f $1/plan9.iso.bz2 +} + +switch($1){ +case checkready + if(! ~ $distisfrom local && ! ~ $download done){ + mountdist=notdone + export mountdist + } + if(! ~ $#mountmedia 0 1){ + if(domount){ + mountdist=done + export mountdist + if(mountdist checkdone) + exit + } + srvmedia=() + mountmedia=() + mountdist=ready + export srvmedia mountmedia mountdist + } + +case go + fat=() + ext2=() + x9660=() + fossil=() + + echo Please wait... Scanning storage devices... + + parts=`{ls /dev/sd??/* >[2]/dev/null | grep -v '/(plan9.*|ctl|log|raw)$'} + for (i in $parts) { + echo -n ' '^$i + n=`{echo $i | sed 's;/;_;g'} + if(! test -f /tmp/localpart.$n) + dd -if $i -bs 2048 -count 32 -of /tmp/localpart.$n >[2]/dev/null + if(isfat /tmp/localpart.$n) + fat=($fat $i) + if(isext2 /tmp/localpart.$n) + ext2=($ext2 $i) + if(is9660 /tmp/localpart.$n) + x9660=($x9660 $i) + if(isfossil $i) + fossil=($fossil $i) + echo + } + echo + echo The following storage media were detected. + echo Choose the one containing the distribution. + echo + for(i in $parts){ + switch($i){ + case $fat + echo ' '^$i^' (microsoft fat)' + case $ext2 + echo ' '^$i^' (linux ext2)' + case $x9660 + echo ' '^$i^' (iso9660 cdrom)' + case $fossil + echo ' '^$i^' (plan9 fossil)' + } + } + echo + + mountstatus=x + while(! ~ $mountstatus ''){ + prompt -w '' 'Distribution disk' $fat $x9660 $fossil + disk=$rd + + srvmedia=() + mountmedia=() + switch($disk){ + case $fs + mountmedia=(bind /n/newfs /n/distmedia) + case $fat + srvmedia=(dossrv) + mountmedia=(mount /srv/dos /n/distmedia $disk) + case $ext2 + srvmedia=(ext2srv -r) + mountmedia=(mount /srv/ext2 /n/distmedia $disk) + case $x9660 + srvmedia=(9660srv) + mountmedia=(mount /srv/9660 /n/distmedia $disk) + case $fossil + echo 'srv fossil.mountdist' > /tmp/fossi.conf + echo 'fsys main config '^$disk >> /tmp/fossil.conf + echo 'fsys main open -AWVP' >> /tmp/fossil.conf + echo 'fsys main' >> /tmp/fossil.conf + srvmedia=(fossil/fossil -c '. /tmp/fossil.conf') + mountmedia=(mount /srv/fossil.mountdist /n/distmedia) + case * + echo Unknown disk type '(cannot happen)' + exit oops + } + export srvmedia mountmedia + domount + mountstatus=$status + } + + first=yes + dir=/ + while(~ $first yes || ! havedist /n/distmedia/$dir){ + if(~ $first yes){ + echo + echo Which directory contains the distribution? + echo 'Any of the following will suffice (in order of preference):' + echo ' - the root directory of the cd image' + echo ' - the directory containing plan9.iso' + echo ' - the directory containing plan9.iso.bz2' + echo 'Typing `browse'' will put you in a shell that you can use to' + echo 'look for the directory.' + echo + first=no + } + + prompt -d browse 'Location of archives' + dir=$rd + if(~ $dir browse){ + echo This is a simple shell. Commands are: + echo ' cd directory - change to directory' + echo ' lc - list contents of current directory' + echo ' exit - exit shell' + echo + echo 'Move to the directory containing the distribution' + echo 'and then exit.' + echo + oifs=$ifs + ifs=$nl + dir=`{cdsh -r /n/distmedia} + ifs=$oifs + } + if(~ $#dir 0) + dir=safdsfdsfdsf + if(! ~ $#dir 1) + dir=$"dir + if(! havedist /n/distmedia/$dir) + echo 'No distribution found in '^`{cleanname /$dir} + } + + distmediadir=$dir + export distmediadir + +case checkdone + if(! ~ $#distmediadir 1){ + mountdist=notdone + export mountdist + exit notdone + } + if(! havedist /n/distmedia/$distmediadir && ! havedist /n/newfs/dist){ + mountdist=notdone + export mountdist + exit notdone + } + + exitifdone + + if(test -f /n/distmedia/$distmediadir/dist/replica/plan9.db){ + bind /n/distmedia/$distmediadir /n/dist + bind -a /n/dist/386/bin /bin + bind -a /n/dist/rc/bin /bin + exitifdone + mountdist=notdone + export mountdist + exit notdone + } + + trycdimage /n/distmedia/$distmediadir/plan9.iso + trycdimage /n/newfs/dist/plan9.iso + + trycdimagebz2 /n/distmedia/$distmediadir/plan9.iso.bz2 + trycdimagebz2 /n/newfs/dist/plan9.iso.bz2 + + mountdist=notdone + export mountdist + exit notdone +} diff --git a/sys/lib/dist.old/pc/inst/mountfossil b/sys/lib/dist.old/pc/inst/mountfossil new file mode 100755 index 000000000..e98a3f48c --- /dev/null +++ b/sys/lib/dist.old/pc/inst/mountfossil @@ -0,0 +1,104 @@ +#!/bin/rc + +switch($1){ +case checkready checkdone + if(! ~ $fmtfossil done){ + mountfs=notdone + export mountfs + exit + } + if(! test -f /dev/sd*/fossil* && ! test -f /dev/fs/fossil*){ + mountfs=notdone + export mountfs + exit + } + if(! ~ $#fossil 1 || ! test -f $fossil){ + mountfs=ready + export mountfs + exit + } + if(! ps | grep -s ' fossil$'){ + echo 'srv -p fscons' > /env/fossilconf + echo 'srv -AP fossil' >> /env/fossilconf + fossil/conf $fossil | sed 's/^fsys main open .*/& -AWVP/' | + sed 's/^fsys main snaptime .*//' >> /env/fossilconf + if(! logprog fossil/fossil -c .' /env/fossilconf'>>[2]/srv/log){ + echo 'fossil: '^$status + mountfs=ready + export mountfs + exit oops + } + if(! test -f /srv/fossil){ + echo 'fossil did not create /srv/fossil' + mountfs=ready + exit oops + } + cat /srv/fscons >>/srv/log & + if(! logprog mount -c /srv/fossil /n/newfs){ + echo 'mount: '^$status + mountfs=ready + export mountfs + exit oops + } + fs=$fossil + export fs + } + if(! test -s /n/newfs/adm/users){ + echo fsys main create /active/adm adm sys d775 >>/srv/fscons + echo fsys main create /active/adm/users adm sys 664 >>/srv/fscons + echo uname upas :upas >>/srv/fscons + echo users -w >>/srv/fscons + sleep 2 + } + if(! test -s /n/newfs/adm/users){ + echo 'could not create /adm/users' + mountfs=ready + export mountfs + exit oops + } + for(i in dist dist/replica dist/replica/client){ + if(! test -d /n/newfs/$i) + echo fsys main create /active/$i sys sys d775 >>/srv/fscons + sleep 2 + } + if(! test -d /n/newfs/dist/replica/client){ + echo 'could not create /dist/replica/client' + mountfs=ready + export mountfs + exit oops + } + if(! test -e /n/newfs/dist/replica/client/plan9.db){ + echo fsys main create /active/dist/replica/client/plan9.db sys sys 664 >>/srv/fscons + echo fsys main create /active/dist/replica/client/plan9.log sys sys a664 >>/srv/fscons + } + if(test -d /n/newfs/dist/replica/client && test -f /n/newfs/adm/users){ + mountfs=done + export mountfs + exit + } + mountfs=ready + export mountfs + exit + +case go + echo 'The following partitions named fossil* were found.' + echo + echo 'Please choose one to use as the installation file system' + echo 'for your Plan 9 installation.' + echo + files=(`{ls /dev/sd*/fossil* /dev/fs/fossil* >[2]/dev/null}) + ls -l $files + echo + if(~ $#fossil 1 && ~ $fossil $files) + default=(-d $fossil) + if not if(~ $#files 1) + default=(-d $files) + if not + default=() + prompt $default 'Fossil partition' $files + slay fossil|rc + fossil=$rd + export fossil +} + + diff --git a/sys/lib/dist.old/pc/inst/mountfs b/sys/lib/dist.old/pc/inst/mountfs new file mode 100755 index 000000000..8aa9b16ff --- /dev/null +++ b/sys/lib/dist.old/pc/inst/mountfs @@ -0,0 +1,14 @@ +#!/bin/rc + +# desc: choose and mount file system partition +# prereq: configfs + +switch($fstype){ +case fossil fossil+venti + exec mountfossil $* +case * + mountfs=notdone + export mountfs + exit +} + diff --git a/sys/lib/dist.old/pc/inst/moveoldfs b/sys/lib/dist.old/pc/inst/moveoldfs new file mode 100755 index 000000000..819beeb39 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/moveoldfs @@ -0,0 +1,72 @@ +#!/bin/rc + +# desc: move an old third edition plan 9 file system out of the way +# prereq: mountfs + +rootfiles=(\ + 386\ + 68000\ + 68020\ + LICENSE\ + NOTICE\ + acme\ + adm\ + alpha\ + arm\ + cron\ + dist\ + fd\ + lib\ + lp\ + mail\ + mips\ + mnt\ + n\ + power\ + rc\ + sparc\ + sys\ + tmp\ + usr/glenda\ + wrap\ +) + +switch($1){ +case checkready + if(! test -d /n/kfs/wrap){ + moveoldfs=done + export moveoldfs + } + +case go + if(test -d /n/kfs/wrap){ + echo 'You have a Third Edition Plan 9 installation on '^$fs^'.' + echo 'We need to move the old file system out of the way (into /3e)' + echo 'in order to continue.' + echo + prompt 'Move old file system' y n + switch($rd){ + case y + kname=`{kfsname $fs} + log Moving old Plan 9 installation into /3e on kfs + logprog disk/kfscmd -n$kname 'create /3e sys sys 555 d' >>[2]/srv/log + logprog disk/kfscmd -n$kname 'create /3e/usr sys sys 555 d' >>[2]/srv/log + for(i in $rootfiles) + if(test -e /n/kfs/$i) + logprog disk/kfscmd -n$kname 'rename /'^$i^' /3e/'^$i + # copy extant /adm/users in case there have been modifications + logprog disk/kfscmd -n$kname 'create /adm adm adm 555 d' >>[2]/srv/log + logprog cp /n/kfs/3e/adm/users /n/kfs/adm/users >>[2]/srv/log + + case n + echo 'Okay, but we can''t continue.' + echo + } + } + +case checkdone + if(test -d /n/kfs/wrap){ + moveoldfs=notdone + export moveoldfs + } +} diff --git a/sys/lib/dist.old/pc/inst/partdisk b/sys/lib/dist.old/pc/inst/partdisk new file mode 100755 index 000000000..430d45f3f --- /dev/null +++ b/sys/lib/dist.old/pc/inst/partdisk @@ -0,0 +1,73 @@ +#!/bin/rc + +# desc: edit partition tables (e.g., to create a plan 9 partition) +# prereq: configfs + +switch($1){ +case go + disks=`{ls /dev/sd*/data >[2]/dev/null | sed 's!/dev/(sd..)/data!\1!'} + if(~ $#disks 0) { + echo 'No disk devices were found on your system.' + echo 'The installation process cannot continue.' + exit giveup + } + + echo 'The following disk devices were found.' + echo + for(i in $disks) { + desc=`{cat /dev/$i/ctl | sed 1q | sed 's/inquiry //'} + echo $i '-' $desc + echo e | disk/fdisk -r /dev/$i/data >[2]/dev/null | grep -v '^ mbr' + echo + } + + okay=no + defdisk=$disks(1) + + if(~ $#disks 1) + default=(-d $disks) + if not + default=() + prompt $default 'Disk to partition' $disks + disk=$rd + + if(! hasmbr /dev/$disk/data) { + echo 'The disk you selected HAS NO master boot record on its first sector.' + echo '(Perhaps it is a completely blank disk.)' + echo 'You need a master boot record to use the disk.' + echo 'Should we install a default master boot record?' + echo + prompt 'Install mbr' y n + switch($rd) { + case y + disk/mbr -m /386/mbr /dev/$disk/data + pickdisk=done + } + } + echo + echo 'This is disk/fdisk; use it to create a Plan 9 partition.' + echo 'If there is enough room, a Plan 9 partition will be' + echo 'suggested; you can probably just type ''w'' and then ''q''.' + echo + disk/fdisk -a /dev/$disk/data + disk/fdisk -p /dev/$disk/data >/dev/$disk/ctl >[2]/dev/null + for(i in /dev/sd*/plan9*){ + if(test -f $i){ + d=`{basename -d $i} + disk/prep -p $i >$d/ctl >[2]/dev/null + } + } + +case checkdone + # we want at least one disk with both an mbr and a plan9 partition + mbrandplan9=0 + disks=`{ls /dev/sd*/plan9 >[2]/dev/null | sed 's!/dev/(sd..)/plan9!\1!'} + for(disk in $disks) { + if(hasmbr /dev/$disk/data) + mbrandplan9=1 + } + if(~ $mbrandplan9 0){ + partdisk=notdone + export partdisk + } +} diff --git a/sys/lib/dist.old/pc/inst/prepdisk b/sys/lib/dist.old/pc/inst/prepdisk new file mode 100755 index 000000000..6ef4a92f8 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/prepdisk @@ -0,0 +1,63 @@ +#!/bin/rc + +# desc: subdivide plan 9 disk partition +# prereq: partdisk + +fn autotype { + if(~ $fstype fossil) + echo -a 9fat -a nvram -a fossil -a swap + if(~ $fstype fossil+venti) + echo -a 9fat -a nvram -a arenas -a isect -a fossil -a swap # -a other +} + +switch($1) { +case checkready + if(! test -f /dev/sd*/plan9*){ + prepdisk=notdone + export prepdisk + } + +case go + echo 'The following Plan 9 disk partitions were found.' + echo + disks=(/dev/sd*/plan9*) + for (i in $disks){ + echo $i + echo q | disk/prep -r $i >[2]/dev/null + echo + } + if(~ $#disks 1) + default=(-d $disks) + if not + default=() + prompt $default 'Plan 9 partition to subdivide' $disks + disk=$rd + + echo 'This is disk/prep; use it to subdivide the Plan 9 partition.' + echo 'If it is not yet subdivided, a sensible layout will be suggested;' + echo 'you can probably just type ''w'' and then ''q''.' + echo + disk/prep `{autotype} $disk + disk/prep -p $disk >`{basename -d $disk}^/ctl >[2]/dev/null + +case checkdone + if(! test -f /dev/sd*/9fat) + prepdisk=ready + + if(! ~ $prepdisk ready){ + prepdisk=done + switch($fstype){ + case fossil + if(! test -f /dev/sd*/fossil* && ! test -f /dev/fs/fossil*) + prepdisk=ready + case fossil+venti + if(! test -f /dev/sd*/fossil* && ! test -f /dev/fs/fossil*) + prepdisk=ready + if(! test -f /dev/sd*/arenas && ! test -f /dev/fs/arenas*) + prepdisk=ready + if(! test -f /dev/sd*/isect && ! test -f /dev/fs/isect*) + prepdisk=ready + } + } + export prepdisk +} diff --git a/sys/lib/dist.old/pc/inst/replcfg b/sys/lib/dist.old/pc/inst/replcfg new file mode 100755 index 000000000..30aed8607 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/replcfg @@ -0,0 +1,18 @@ +#!/bin/rc + +s=/n/dist/dist/replica +serverroot=/n/dist +serverlog=$s/plan9.log +serverproto=$s/plan9.proto +fn servermount { status='' } +fn serverupdate { status='' } + +fn clientmount { status='' } +c=/n/newfs/dist/replica +clientroot=/n/newfs +clientproto=$c/plan9.proto +clientdb=$c/client/plan9.db +clientexclude=(dist/replica/client) +clientlog=$c/client/plan9.log + +applyopt=(-t -u -T$c/client/plan9.time) diff --git a/sys/lib/dist.old/pc/inst/startether b/sys/lib/dist.old/pc/inst/startether new file mode 100755 index 000000000..077504c1a --- /dev/null +++ b/sys/lib/dist.old/pc/inst/startether @@ -0,0 +1,30 @@ +#!/bin/rc + +# desc: activate ethernet card +# prereq: configether + +switch($1) { +case checkready + if(isipdevup /net/ether0) { + startether=done + export startether + } + +case go + if(isipdevup /net/ether0) + exit + + log starting ethernet $ethermethod config + switch($ethermethod) { + case manual + ip/ipconfig -g $gwaddr ether /net/ether0 $ipaddr $ipmask >>[2]/srv/log + case dhcp + ip/ipconfig $dhcphost -D >>/srv/log >[2=1] + } + +case checkdone + if(! isipdevup /net/ether0) { + startether=notdone + export startether + } +} diff --git a/sys/lib/dist.old/pc/inst/startppp b/sys/lib/dist.old/pc/inst/startppp new file mode 100755 index 000000000..02bc090ef --- /dev/null +++ b/sys/lib/dist.old/pc/inst/startppp @@ -0,0 +1,30 @@ +#!/bin/rc + +# desc: activate ppp connection +# prereq: configppp + +switch($1) { +case checkready checkdone + if (isipdevup '^pkt[0-9]') + startppp=done + export startppp + +case go + if(isipdevup '^pkt[0-9]') + exit + + ctl=$pppdev^ctl + echo b115200 >$ctl + + switch($pppmethod) { + case manual + echo + echo 'Please dial the modem, and type ctl-d when PPP has started.' + echo 'You may need to type ctl-m to send modem commands.' + echo + ip/ppp -f -u -b b^$pppbaud -p /dev/^$pppdev + + case auto + ip/ppp -f -b b^$pppbaud -p /dev/^$pppdev -s $"pppuser:$"ppppasswd -t 'atdt'^$"pppphone + } +} diff --git a/sys/lib/dist.old/pc/inst/startwin b/sys/lib/dist.old/pc/inst/startwin new file mode 100755 index 000000000..bcd542890 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/startwin @@ -0,0 +1,46 @@ +#!/bin/rc + +fn time { date | sed 's/.........$//'} + +rm -f /srv/log + +if(~ $#* 2) { + wid=$1 + ht=$2 +} +if not { + scr=(`{cat /dev/draw/new >[2]/dev/null || status=''}) + wid=$scr(7) + ht=$scr(8) +} + +if(test $ht -gt 800) + ht=800 + +if(test $wid -gt 800) + wid=800 + +statwid=`{hoc -e $wid^'*.2'} +if(test $statwid -lt 180) + statwid=180 +if(test $statwid -gt 300) + statwid=300 + +logwid=`{hoc -e $wid^-$statwid} +if(test $logwid -gt 1000) + logwid=1000 + +loght=`{hoc -e $ht^'*.25'} +if(test $loght -lt 130) + loght=130 + +textht=`{hoc -e $ht^-$loght} + +window 0,$textht,$statwid,$ht stats -lmisce +window $statwid,$textht,^`{hoc -e $logwid+$statwid}^,$ht tailfsrv +window 0,0,^`{hoc -e $logwid+$statwid}^,$textht inst/mainloop + +while(! test -f /srv/log) + sleep 1 + +log `{time} Installation process started diff --git a/sys/lib/dist.old/pc/inst/stop b/sys/lib/dist.old/pc/inst/stop new file mode 100755 index 000000000..a1d48694f --- /dev/null +++ b/sys/lib/dist.old/pc/inst/stop @@ -0,0 +1,50 @@ +#!/bin/rc + +# desc: save the current installation state, to be resumed later +# prereq: +# mustdo: + +switch($1) { +case checkdone + stop=notdone + export stop + +case checkready + if(~ $cdboot yes){ + stop=notdone + export stop + } + +case go + coherence + switch($2){ + case finished + echo 'We need to write the state of the current installation to the install floppy,' + echo 'so that you can pick up from here if, for example, you want to set up' + echo 'more boot methods.' + echo + case * + echo 'We need to write the state of the current installation to the install floppy.' + echo 'so that you can pick up from here when you wish to continue.' + echo + } + echo -n 'Please make sure the install floppy is in the floppy drive and press enter.' + read >/dev/null >[2]/dev/null + + if(! a:) { + echo 'Couldn''t mount the floppy disk; sorry.' + exit + } + + if(cp /tmp/vars /n/a:/9inst.cnf || cp /tmp/vars /n/a:/9inst.cnf) { + echo 'Your install state has been saved to the install floppy.' + if(~ $2 finished){ + echo + echo 'Congratulations; you''ve completed the install.' + } + echo + halt + } + + echo 'Couldn''t save the state to your install floppy. Sorry.' +} diff --git a/sys/lib/dist.old/pc/inst/stopether b/sys/lib/dist.old/pc/inst/stopether new file mode 100755 index 000000000..59063f0e0 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/stopether @@ -0,0 +1,20 @@ +#!/bin/rc + +# desc: shut down the ethernet connection +# prereq: + + +switch($1) { +case checkready + if(! isipdevup /net/ether0) { + stopether=notdone + export stopether + } + +case go + ip/ipconfig ether /net/ether0 unbind + +case checkdone + stopether=notdone + export stopether +} diff --git a/sys/lib/dist.old/pc/inst/stopppp b/sys/lib/dist.old/pc/inst/stopppp new file mode 100755 index 000000000..70b9ce1fe --- /dev/null +++ b/sys/lib/dist.old/pc/inst/stopppp @@ -0,0 +1,19 @@ +#!/bin/rc + +# desc: shut down the ppp connection +# prereq: + +switch($1) { +case checkready + if(! ~ $#pppdev 1 || ! isipdevup '^pkt[0-9]') { + stopppp=notdone + export stopppp + } + +case go + kill ppp | rc + +case checkdone + stopppp=notdone + export stopppp +} diff --git a/sys/lib/dist.old/pc/inst/textonly b/sys/lib/dist.old/pc/inst/textonly new file mode 100755 index 000000000..1c3922ce4 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/textonly @@ -0,0 +1,15 @@ +#!/bin/rc + +# text-only install +cd /bin/inst +. defs + +textinst=1 +export textinst + +tailfsrv & +while(! test -f /srv/log) + sleep 1 +log `{date} Installation process started +inst/mainloop + diff --git a/sys/lib/dist.old/pc/inst/watchfd b/sys/lib/dist.old/pc/inst/watchfd new file mode 100755 index 000000000..ca37294e3 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/watchfd @@ -0,0 +1,17 @@ +#!/bin/rc + +p=`{ps | grep $1 | sed 's/[^ ]* +([^ ]+) .*/\1/' } +while(! ~ $#p 1) { + sleep 1 + p=`{ps | grep $1 | sed 's/[^ ]* +([^ ]+) .*/\1/'} +} +p=$p(1) + +baropt='-w 145,129,445,168' +if(~ $textinst 1) + baropt=-t + +{ + while(test -f /proc/$p/fd) + grep '^ *'^$2^' ' /proc/$p/fd >[2]/dev/null +} | awk '{print $9 " '^$3^'"; fflush("/dev/stdout")}' | bargraph $baropt $4 diff --git a/sys/lib/dist.old/pc/inst/xxx b/sys/lib/dist.old/pc/inst/xxx new file mode 100755 index 000000000..56b4eb23a --- /dev/null +++ b/sys/lib/dist.old/pc/inst/xxx @@ -0,0 +1,9 @@ +#!/bin/rc + +ip/ipconfig +echo ' auth=204.178.31.3 + authdom=cs.bell-labs.com' >>/net/ndb +ndb/cs +auth/factotum +bind -a /bin/auth / +cpu -e clear -h tcp!204.178.31.2 diff --git a/sys/lib/dist.old/pc/mkfile b/sys/lib/dist.old/pc/mkfile new file mode 100644 index 000000000..43ee0b751 --- /dev/null +++ b/sys/lib/dist.old/pc/mkfile @@ -0,0 +1,100 @@ +out=outside # outside web server +s=/sys/lib/dist/pc +x=`{bind -b /sys/lib/dist/bin/$cputype /bin} +default:V: ndisk + ls -l ndisk + +SUB=`{ls sub inst} +boot.raw:Q: proto $SUB + rm -rf boot + mkdir boot + bind /dev/null /sys/log/timesync + # make files writable for now. + cat proto | sed 's!d000!d775!;s!000!664!;s!555!775!;s!444!664!' >proto.cp + disk/mkfs -a proto.cp | disk/mkext -d boot + @{ + cd boot/386 + strip init + cd bin + strip * */* >[2]/dev/null || status='' + } + cat proto | sed 's!/.*!!' >proto.cp + disk/mkfs -a -s boot proto.cp | tee >{wc -c >[1=2]} | + touchfs 1000000000 >boot.raw + +boot.bz2:Q: boot.raw + ls -l boot.raw + bflz -n 32 < boot.raw >boot.bflz + ls -l boot.bflz + bzip2 -9 < boot.bflz >$target + ls -l $target + +root.bz2:Q: boot.bz2 + { + echo bzfilesystem + cat boot.bz2 + dd -if /dev/zero -bs 1024 -count 1 >[2]/dev/null + } >$target + ls -l $target + +/sys/src/9/pc/9pcflop.gz: root.bz2 + @{ + rfork n + cd /sys/src/9/pc + mk 'CONF=pcflop' 9pcflop.gz + } + +/sys/src/9/pc/9pccd.gz: + @{ + cd /sys/src/9/pc + mk 'CONF=pccd' 9pccd.gz + } + +# disk/format apparently uses stat to obtain a file's real name, so +# binding 9loadusb onto 9load will store the name 9loadusb in the +# generated fat filesystem. the same is true for plan9.ini.cd and plan9.ini. + +9load: /386/9loadlite +# cp $prereq $target + if (test -e /386/9loadnousb) + cp /386/9loadnousb $target # cater to old bioses + cp /386/9loadlitedebug 9loaddebug + +ndisk: 9load /sys/src/9/pc/9pcflop.gz plan9.ini /lib/vgadb + dd -if /dev/zero -of ndisk -bs 1024 -count 1440 >[2]/dev/null + disk/format -f -b /386/pbs -d ndisk \ + 9load /sys/src/9/pc/9pcflop.gz plan9.ini /lib/vgadb + ls -l ndisk + +# cannot list both 9pcflop.gz and 9pccd.gz because they cannot be built +# in parallel. stupid mk +cddisk:DV: 9load /sys/src/9/pc/9pcflop.gz plan9.ini.cd /lib/vgadb + mk -a /sys/src/9/pc/9pccd.gz + mk -a /sys/src/9/pc/9pcflop.gz + rfork n + cp -x plan9.ini.cd subst/plan9.ini + dd -if /dev/zero -of cddisk -bs 1024 -count 2880 >[2]/dev/null + disk/format -t 3½QD -f -b /386/pbs -d cddisk \ + 9load /sys/src/9/pc/^(9pcflop.gz 9pccd.gz) \ + subst/plan9.ini /lib/vgadb + ls -l cddisk + +clean:V: + if (! unmount 9load >[2]/dev/null) + ; + rm -rf boot boot.bz2 boot.bflz boot.raw root.bz2 9pcflop ndisk 9load cddisk proto.cp 9loaddebug + +install:V: ndisk 9loaddebug + 9fs $out + dst=/n/$out/sys/lib/dist/web.protect + cp 9loaddebug $dst + gzip -9 < ndisk > $dst/plan9.flp.gz + # mk clean + +test:V: ndisk 9loaddebug + cp 9loaddebug ../web.protect2/n9loaddebug + cp ndisk ../web.protect2/ndisk + +cd0:D: cddisk + rm -f cd0 + disk/mk9660 -9cj -v 'Plan 9 4th Edition' -s . -p cd0.proto -b cddisk cd0 diff --git a/sys/lib/dist.old/pc/plan9.ini b/sys/lib/dist.old/pc/plan9.ini new file mode 100644 index 000000000..71f98e5e1 --- /dev/null +++ b/sys/lib/dist.old/pc/plan9.ini @@ -0,0 +1,37 @@ +# config for initial floppy booting + +[menu] +menuitem=boot, Boot Plan 9 +# menuitem=debug, Boot Plan 9 and debug 9load +menudefault=boot, 10 + +[common] +# very cautious settings to get started. +# will defeat booting from usb devices. +*nomp=1 +*nobiosload=1 +# *noahciload=1 +# *debugload=1 +*nodumpstack=1 +# this would disable ether and usb probing. +# *nousbprobe=1 +# *noetherprobe=1 +distname=plan9 +partition=new +mouseport=ask +monitor=ask +vgasize=ask +dmamode=ask +nobootprompt=local!/boot/bzroot +installurl=http://plan9.bell-labs.com/plan9/download/plan9.iso.bz2 +# serial console on COM1 +#console=0 + +[boot] +bootargs=local!#S/sdD0/data +bootfile=sdD0!cdboot!9pccd.gz + +# [debug] +# bootargs=local!#S/sdD0/data +# bootfile=sdD0!cdboot!9pccd.gz +# *debugload=1 diff --git a/sys/lib/dist.old/pc/plan9.ini.blank b/sys/lib/dist.old/pc/plan9.ini.blank new file mode 100644 index 000000000..be51a5dd4 --- /dev/null +++ b/sys/lib/dist.old/pc/plan9.ini.blank @@ -0,0 +1,10 @@ +THIS IS A 512 byte BLANK PLAN9.INI + + + + + + + + + diff --git a/sys/lib/dist.old/pc/plan9.ini.cd b/sys/lib/dist.old/pc/plan9.ini.cd new file mode 100644 index 000000000..11a2435ca --- /dev/null +++ b/sys/lib/dist.old/pc/plan9.ini.cd @@ -0,0 +1,40 @@ +# config for initial cd booting + +[menu] +menuitem=install, Install Plan 9 from this CD +menuitem=cdboot, Boot Plan 9 from this CD +# menuitem=debug, Boot Plan 9 from this CD and debug 9load + +[common] +# very cautious settings to get started. +# will defeat booting from usb devices. +*nomp=1 +*nobiosload=1 +# *noahciload=1 +# *debugload=1 +*nodumpstack=1 +# this would disable ether and usb probing. +# *nousbprobe=1 +# *noetherprobe=1 +partition=new +mouseport=ask +monitor=ask +vgasize=ask +dmamode=ask +adisk=/dev/sdD0/cdboot +cdboot=yes +# console=0 +# baud=9600 + +[install] +nobootprompt=local!/boot/bzroot +bootfile=sdD0!cdboot!9pcflop.gz + +[cdboot] +bootargs=local!#S/sdD0/data +bootfile=sdD0!cdboot!9pccd.gz + +# [debug] +# bootargs=local!#S/sdD0/data +# bootfile=sdD0!cdboot!9pccd.gz +# *debugload=1 diff --git a/sys/lib/dist.old/pc/plan9.ini.vmware b/sys/lib/dist.old/pc/plan9.ini.vmware new file mode 100644 index 000000000..dfee230ad --- /dev/null +++ b/sys/lib/dist.old/pc/plan9.ini.vmware @@ -0,0 +1,20 @@ +# config for initial vmware booting + +# very cautious settings to get started. +# will defeat booting from usb devices. +*nomp=1 +*nobiosload=1 +# *noahciload=1 +# *debugload=1 +# *nodumpstack=1 + +partition=new +nobootprompt=local!/boot/bzroot +bootfile=fd0!9pcflop.gz + +mouseport=ps2 +monitor=xga +vgasize=1024x768x16 +#adisk=/dev/sdD0/cdboot +console=0 +baud=9600 diff --git a/sys/lib/dist.old/pc/proto b/sys/lib/dist.old/pc/proto new file mode 100644 index 000000000..a12695d44 --- /dev/null +++ b/sys/lib/dist.old/pc/proto @@ -0,0 +1,175 @@ +386 d775 sys sys +# 9load 555 sys sys + init 555 sys sys +# ld.com 555 sys sys + mbr 555 sys sys + pbs 555 sys sys + pbslba 555 sys sys + bin d775 sys sys + auth d555 sys sys +# i think factotum is only needed if we include cpu +# factotum 555 sys sys + aux d555 sys sys + isvmware 555 sys sys + mouse 555 sys sys /sys/lib/dist/pc/multi/mouse + pcmcia 555 sys sys /sys/lib/dist/pc/multi/pcmcia + # stub 555 sys sys + vga 555 sys sys /sys/lib/dist/pc/multi/vga + vmware 555 sys sys /sys/lib/dist/pc/sub/vmware + # vmware 555 sys sys + # vmwarefs 555 sys sys + # vmmousepoll 555 sys sys + zerotrunc 555 sys sys /sys/lib/dist/pc/multi/zerotrunc + disk d555 sys sys + fdisk 555 sys sys /sys/lib/dist/pc/multi/fdisk + format 555 sys sys /sys/lib/dist/pc/multi/format +# kfs 555 sys sys +# kfscmd 555 sys sys + mbr 555 sys sys /sys/lib/dist/pc/multi/mbr + prep 555 sys sys /sys/lib/dist/pc/multi/prep + fossil d555 sys sys + fossil 555 sys sys + flfmt 555 sys sys + conf 555 sys sys + ip d555 sys sys + ipconfig 555 sys sys /sys/lib/dist/pc/multi/ipconfig + ppp 555 sys sys /sys/lib/dist/pc/multi/ppp + ndb d555 sys sys +# csquery and dnsquery could go + cs 555 sys sys /sys/lib/dist/pc/multi/cs +# csquery 555 sys sys + dns 555 sys sys /sys/lib/dist/pc/multi/dns +# dnsquery 555 sys sys + replica d555 sys sys + applylog 555 sys sys + changes 555 sys sys + compactdb 555 sys sys /sys/lib/dist/pc/sub/compactdb + pull 555 sys sys + venti d555 sys sys +# venti 555 sys sys +# conf 555 sys sys +# fmtarenas 555 sys sys +# fmtindex 555 sys sys +# fmtisect 555 sys sys + 9660srv 555 sys sys /sys/lib/dist/pc/multi/9660srv +# acme could go +# acme 555 sys sys + awk 555 sys sys + bargraph 555 sys sys /sys/lib/dist/bin/386/bargraph + basename 555 sys sys /sys/lib/dist/pc/multi/basename + cat 555 sys sys /sys/lib/dist/pc/multi/cat + chgrp 555 sys sys /sys/lib/dist/pc/multi/chgrp + chmod 555 sys sys /sys/lib/dist/pc/multi/chmod + cleanname 555 sys sys /sys/lib/dist/pc/multi/cleanname + cmp 555 sys sys /sys/lib/dist/pc/multi/cmp + cdsh 555 sys sys /sys/lib/dist/bin/386/cdsh + cp 555 sys sys /sys/lib/dist/pc/multi/cp +# cpu could go +# cpu 555 sys sys + date 555 sys sys /sys/lib/dist/pc/multi/date + dd 555 sys sys /sys/lib/dist/pc/multi/dd + dossrv 555 sys sys /sys/lib/dist/pc/multi/dossrv + echo 555 sys sys /sys/lib/dist/pc/multi/echo + ed 555 sys sys /sys/lib/dist/pc/multi/ed +# if cpu goes, exportfs could go +# exportfs 555 sys sys + ext2srv 555 sys sys /sys/lib/dist/pc/multi/ext2srv + fcp 555 sys sys + grep 555 sys sys /sys/lib/dist/pc/multi/grep + hget 555 sys sys /sys/lib/dist/pc/multi/hget + hoc 555 sys sys /sys/lib/dist/pc/multi/hoc + ls 555 sys sys /sys/lib/dist/pc/multi/ls + mc 555 sys sys /sys/lib/dist/pc/multi/mc + mount 555 sys sys /sys/lib/dist/pc/multi/mount + multi 555 sys sys /sys/lib/dist/bin/386/multi + mv 555 sys sys /sys/lib/dist/pc/multi/mv +# netkey 555 sys sys + ps 555 sys sys /sys/lib/dist/pc/multi/ps + rc 555 sys sys + read 555 sys sys /sys/lib/dist/pc/multi/read + rio 555 sys sys + rm 555 sys sys /sys/lib/dist/pc/multi/rm + sed 555 sys sys /sys/lib/dist/pc/multi/sed +# snoopy could go +# snoopy 555 sys sys + sort 555 sys sys /sys/lib/dist/pc/multi/sort + srv 555 sys sys /sys/lib/dist/pc/multi/srv +# ssh 555 sys sys + stats 555 sys sys + syscall 555 sys sys /sys/lib/dist/pc/multi/syscall + tail 555 sys sys /sys/lib/dist/pc/multi/tail + tailfsrv 555 sys sys /sys/lib/dist/bin/386/tailfsrv + tee 555 sys sys /sys/lib/dist/pc/multi/tee +# telnet 555 sys sys + test 555 sys sys /sys/lib/dist/pc/multi/test + wc 555 sys sys /sys/lib/dist/pc/multi/wc + xd 555 sys sys /sys/lib/dist/pc/multi/xd +adm d555 adm adm + timezone d555 sys sys + local 555 sys sys +lib d777 sys sys + font d555 sys sys + bit d555 sys sys + lucidasans d555 sys sys + lstr.12 444 sys sys + typelatin1.7.font 444 sys sys +# lucm d555 sys sys +# latin1.9 444 sys sys +# latin1.9.font 444 sys sys + namespace 444 sys sys + ndb d555 sys sys + common 444 sys sys /sys/lib/dist/pc/sub/common + local 444 sys sys /sys/lib/dist/pc/sub/local + vgadb 666 sys sys /dev/null +fd d555 sys sys +mnt d777 sys sys + arch d000 sys sys + temp d000 sys sys + vmware d000 sys sys + wsys d000 sys sys +n d777 sys sys + a: d000 sys sys + a d000 sys sys + c: d000 sys sys + c d000 sys sys + 9fat d000 sys sys + kremvax d000 sys sys /sys/lib/dist/pc/empty + newfs d000 sys sys + dist d000 sys sys /sys/lib/dist/pc/empty + distmedia d000 sys sys /sys/lib/dist/pc/empty +rc d555 sys sys + bin d775 sys sys + inst d775 sys sys /sys/lib/dist/pc/empty + + - sys sys /sys/lib/dist/pc/inst + 9fat: 555 sys sys + a: 555 sys sys /sys/lib/dist/pc/sub/a: + bind 555 sys sys /sys/lib/dist/pc/sub/bind + boota: 555 sys sys /sys/lib/dist/pc/sub/boota: + bunzip2 555 sys sys /sys/lib/dist/pc/sub/bunzip2 + c: 555 sys sys + dosmnt 555 sys sys + kill 555 sys sys + lc 555 sys sys + mkdir 555 sys sys /sys/lib/dist/pc/sub/mkdir + pci 555 sys sys + pwd 555 sys sys /sys/lib/dist/pc/sub/pwd + ramfs 555 sys sys /sys/lib/dist/pc/sub/ramfs + replica d555 sys sys + changes 555 sys sys + defs 555 sys sys + pull 555 sys sys + slay 555 sys sys + sleep 555 sys sys /sys/lib/dist/pc/sub/sleep + termrc 555 sys sys /sys/lib/dist/pc/sub/termrc + unmount 555 sys sys /sys/lib/dist/pc/sub/unmount + window 555 sys sys + lib d555 sys sys + rcmain 444 sys sys +sys d555 sys sys + log d555 sys sys + dns 444 sys sys /sys/lib/dist/pc/emptyfile + timesync 444 sys sys /sys/lib/dist/pc/emptyfile +tmp d555 sys sys +usr d555 sys sys + glenda d775 glenda glenda + + - glenda glenda /sys/lib/dist/pc/glenda diff --git a/sys/lib/dist.old/pc/sub/D003753 b/sys/lib/dist.old/pc/sub/D003753 new file mode 100755 index 000000000..8624d6ea1 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/D003753 @@ -0,0 +1,22 @@ +#!/bin/rc +if(! test -f /srv/dos) + dossrv >/dev/null [2]/dev/null +unmount /n/a:>[2]/dev/null + +if(~ $#adisk 1) + ; # do nothing +if not if(~ $#bootfile 0) + adisk=/dev/fd0disk +if not { + switch($bootfile) { + case sd* + adisk=`{echo $bootfile | sed 's#(sd..).*#/dev/\1/data#'} + case fd* + adisk=`{echo $bootfile | sed 's#(fd.).*#/dev/\1disk#'} + case * + echo 'unknown bootfile '^$bootfile^'; mail 9trouble@plan9.bell-labs.com' + exit oops + } +} + +mount -c /srv/dos /n/a: $adisk diff --git a/sys/lib/dist.old/pc/sub/F004116 b/sys/lib/dist.old/pc/sub/F004116 new file mode 100755 index 000000000..5f6809b3b --- /dev/null +++ b/sys/lib/dist.old/pc/sub/F004116 @@ -0,0 +1,24 @@ +#!/bin/rc + +rfork e +if(! test -f /srv/dos) + dossrv >/dev/null [2]/dev/null +unmount /n/a:>[2]/dev/null + +switch($bootfile) { +case sd*!cdboot!* + # just look for the right file. bootfile isn''t trustworthy + adisk=/dev/sd*/cdboot + if(! ~ $#adisk 1) + adisk=$adisk(1) +case sd* + adisk=`{echo $bootfile | sed 's#(sd..).*#/dev/\1/dos#'} +case fd* + adisk=`{echo $bootfile | sed 's#(fd.).*#/dev/\1disk#'} +case * + echo 'unknown bootfile '^$bootfile^'; mail 9trouble@plan9.bell-labs.com' + exit oops +} + +mount -c /srv/dos /n/a: $adisk + diff --git a/sys/lib/dist.old/pc/sub/bind b/sys/lib/dist.old/pc/sub/bind new file mode 100755 index 000000000..bc01455d7 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/bind @@ -0,0 +1,21 @@ +#!/bin/rc + +rfork e +flag=0 +while(~ $1 -*){ + switch($1){ + case -b + flag=1 + case -a + flag=2 + case -c + flag=4 + case -ac -ca + flag=6 + case -bc -cb + flag=5 + } + shift +} + +syscall bind $1 $2 $flag >[2]/dev/null diff --git a/sys/lib/dist.old/pc/sub/bunzip2 b/sys/lib/dist.old/pc/sub/bunzip2 new file mode 100755 index 000000000..0a876c6c2 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/bunzip2 @@ -0,0 +1,4 @@ +#!/bin/rc + +exec /boot/kfs BUNZIP +# kfs is bzfs \ No newline at end of file diff --git a/sys/lib/dist.old/pc/sub/common b/sys/lib/dist.old/pc/sub/common new file mode 100755 index 000000000..ec3e1bca2 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/common @@ -0,0 +1,123 @@ +# +# services +# +tcp=cs port=1 +tcp=echo port=7 +tcp=discard port=9 +tcp=systat port=11 +tcp=daytime port=13 +tcp=netstat port=15 +tcp=chargen port=19 +tcp=ftp-data port=20 +tcp=ftp port=21 +tcp=ssh port=22 +tcp=telnet port=23 +tcp=smtp port=25 +tcp=time port=37 +tcp=whois port=43 +tcp=domain port=53 +tcp=uucp port=64 +tcp=gopher port=70 +tcp=rje port=77 +tcp=finger port=79 +tcp=http port=80 +tcp=link port=87 +tcp=supdup port=95 +tcp=hostnames port=101 +tcp=iso-tsap port=102 +tcp=x400 port=103 +tcp=x400-snd port=104 +tcp=csnet-ns port=105 +tcp=pop-2 port=109 +tcp=pop3 port=110 +tcp=sunrpc port=111 +tcp=uucp-path port=117 +tcp=nntp port=119 +tcp=netbios port=139 +tcp=NeWS port=144 +tcp=print-srv port=170 +tcp=z39.50 port=210 +tcp=fsb port=400 +tcp=sysmon port=401 +tcp=proxy port=402 +tcp=proxyd port=404 +tcp=https port=443 +tcp=ssmtp port=465 +tcp=snntp port=563 +tcp=rexec port=512 restricted= +tcp=login port=513 restricted= +tcp=shell port=514 restricted= +tcp=printer port=515 +tcp=courier port=530 +tcp=cscan port=531 +tcp=uucp port=540 +tcp=9fs port=564 +tcp=whoami port=565 +tcp=guard port=566 +tcp=ticket port=567 +tcp=fmclient port=729 +tcp=ingreslock port=1524 +tcp=webster port=2627 +tcp=weather port=3000 +tcp=Xdisplay port=6000 +tcp=styx port=6666 +tcp=mpeg port=6667 +tcp=rstyx port=6668 +tcp=infdb port=6669 +tcp=infsigner port=6671 +tcp=infcsigner port=6672 +tcp=inflogin port=6673 +tcp=bandt port=7330 +tcp=face port=32000 +tcp=ocpu port=17005 +tcp=ocpunote port=17006 +tcp=exportfs port=17007 +tcp=rexexec port=17009 +tcp=ncpu port=17010 +tcp=ncpunote port=17011 +tcp=cpu port=17013 +tcp=video port=17028 +tcp=vgen port=17029 +tcp=alefnslook port=17030 +tcp=411 port=17031 +tcp=flyboy port=17032 + +il=echo port=7 +il=discard port=9 +il=chargen port=19 +il=whoami port=565 +il=ticket port=566 +il=challbox port=567 +il=ocpu port=17005 +il=ocpunote port=17006 +il=exportfs port=17007 +il=9fs port=17008 +il=rexexec port=17009 +il=ncpu port=17010 +il=ncpunote port=17011 +il=tcpu port=17012 +il=cpu port=17013 +il=fsauth port=17020 +il=rexauth port=17021 +il=changekey port=17022 +il=chal port=17023 +il=check port=17024 +il=juke port=17026 +il=video port=17028 +il=vgen port=17029 +il=alefnslook port=17030 +il=ramfs port=17031 + +udp=echo port=7 +udp=tacacs port=49 +udp=tftp port=69 +udp=bootpc port=68 +udp=bootp port=67 +udp=dns port=53 +udp=ntp port=123 +udp=rip port=520 +udp=bfs port=2201 +udp=virgil port=2202 +udp=bandt2 port=7331 + +gre=ppp port=34827 diff --git a/sys/lib/dist.old/pc/sub/compactdb b/sys/lib/dist.old/pc/sub/compactdb new file mode 100755 index 000000000..6033f7a0a --- /dev/null +++ b/sys/lib/dist.old/pc/sub/compactdb @@ -0,0 +1,4 @@ +#!/bin/rc + +exec cat $* + diff --git a/sys/lib/dist.old/pc/sub/local b/sys/lib/dist.old/pc/sub/local new file mode 100755 index 000000000..ec278a401 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/local @@ -0,0 +1,8 @@ + +# +# files comprising the database, use as many as you like +# +database= + file=/lib/ndb/local + file=/lib/ndb/common + diff --git a/sys/lib/dist.old/pc/sub/mkdir b/sys/lib/dist.old/pc/sub/mkdir new file mode 100755 index 000000000..b4452b9a9 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/mkdir @@ -0,0 +1,3 @@ +#!/bin/rc + +syscall create $1 0 020000000775 >[2]/dev/null diff --git a/sys/lib/dist.old/pc/sub/ndist b/sys/lib/dist.old/pc/sub/ndist new file mode 100755 index 000000000..2916986a1 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/ndist @@ -0,0 +1,16 @@ +#!/bin/rc + +s=/n/dist/dist/replica +serverroot=/n/dist +serverlog=$s/plan9.log +serverproto=$s/plan9.proto +fn servermount { status='' } +fn serverupdate { status='' } + +fn clientmount { status='' } +c=/n/kfs/dist/replica +clientroot=/n/kfs +clientproto=$c/plan9.proto +clientdb=$c/client/plan9.db +clientexclude=(dist/replica/client) +clientlog=$c/client/plan9.log diff --git a/sys/lib/dist.old/pc/sub/pci b/sys/lib/dist.old/pc/sub/pci new file mode 100755 index 000000000..c55d4b397 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/pci @@ -0,0 +1,5 @@ +#!/bin/rc + +rfork n +bind '#$' /mnt +cat /mnt/pci/*ctl diff --git a/sys/lib/dist.old/pc/sub/pwd b/sys/lib/dist.old/pc/sub/pwd new file mode 100755 index 000000000..f75568e7c --- /dev/null +++ b/sys/lib/dist.old/pc/sub/pwd @@ -0,0 +1,3 @@ +#!/bin/rc + +syscall -o fd2path 0 buf 1024 < . >[2]/dev/null diff --git a/sys/lib/dist.old/pc/sub/ramfs b/sys/lib/dist.old/pc/sub/ramfs new file mode 100755 index 000000000..285cd8717 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/ramfs @@ -0,0 +1,4 @@ +#!/bin/rc + +exec boot/kfs RAMFS $* +# kfs is bzfs diff --git a/sys/lib/dist.old/pc/sub/sleep b/sys/lib/dist.old/pc/sub/sleep new file mode 100755 index 000000000..07e6bb8be --- /dev/null +++ b/sys/lib/dist.old/pc/sub/sleep @@ -0,0 +1,8 @@ +#!/bin/rc + +if(! ~ $#* 1) { + echo 'usage: sleep n' >[1=2] + exit usage +} + +syscall sleep $1^000 >/dev/null >[2]/dev/null diff --git a/sys/lib/dist.old/pc/sub/termrc b/sys/lib/dist.old/pc/sub/termrc new file mode 100755 index 000000000..a194ee9b0 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/termrc @@ -0,0 +1,121 @@ +#!/bin/rc + +if(~ $#debug 1 && ~ $debug yes) + flag x + +if not + debug=0 + +if(~ $debug yes) echo env... +sysname=gnot +font=/lib/font/bit/lucidasans/typelatin1.7.font + +for (i in '#P' '#f' '#m' '#t' '#v') { + if(~ $debug yes) echo bind $i + bind -a $i /dev >/dev/null >[2=1] +} +if(~ $debug yes) echo binddev done + +for(disk in /dev/sd??) { + if(test -f $disk/data && test -f $disk/ctl){ + disk/fdisk -p $disk/data >$disk/ctl >[2]/dev/null +# if(~ $#nosddma 0) +# echo dma on >$disk/ctl +# if(~ $#nosdrwm 0) +# echo rwm on >$disk/ctl + } +} + +for (i in /sys/log/*) { + if(~ $debug yes) echo bind $i + bind /dev/null $i +} + +if(~ $debug yes) echo bindlog done + +bind -a '#l' /net >/dev/null >[2=1] + +dossrv +boota: +boota: # again, just in case a timeout made the earlier one fail +cp /n/a:/plan9.ini /tmp/plan9.orig +if(! ~ $cdboot yes){ + pci >/n/a:/pci.txt >[2]/dev/null + cp /dev/kmesg /n/a:/boot.txt >[2]/dev/null +} + +# restore a partial install +if(test -f /n/a:/9inst.cnf) + cp /n/a:/9inst.cnf /tmp/vars + +# make vgadb easier to edit +if(test -f /n/a:/vgadb) + cp /n/a:/vgadb /lib/vgadb + +aux/vmware + +# configure loopback device without touching /net/ndb +{ + echo bind loopback /dev/null + echo add 127.0.0.1 255.255.255.0 +} >/net/ipifc/clone + +if(~ $#dmamode 0) + dmamode=ask +if(~ $dmamode ask){ + echo -n 'use DMA for ide drives[yes]: ' + dmamode=`{read} + if(~ $#dmamode 0) + dmamode=yes +} +if(~ $dmamode yes) + for(i in /dev/sd*/ctl) + if(test -f $i) + {echo dma on; echo rwm on >[2]/dev/null} >$i + +if(~ $installmode ask){ + echo -n 'install mode is (text, graphics)[graphics]: ' + installmode=`{read} + if(~ $#installmode 0) + installmode=graphics +} +if(~ $installmode text){ + mouseport=() + vgasize=() + monitor=() +} +if not + installmode=graphics + +if(~ $mouseport ask){ + echo -n 'mouseport is (ps2, ps2intellimouse, 0, 1, 2)[ps2]: ' + mouseport=`{read} + if(~ $#mouseport 0) + mouseport=ps2 +} +if(~ $vgasize ask){ + echo -n 'vgasize [640x480x8]: ' + vgasize=`{read} + if(~ $#vgasize 0) + vgasize=640x480x8 +} +if(~ $monitor ask){ + echo -n 'monitor is [xga]: ' + monitor=`{read} + if(~ $#monitor 0) + monitor=xga +} +if(~ $#mouseport 1) { + aux/mouse $mouseport + if(~ $#vgasize 1 && ! ~ $vgasize '') { + vgasize=`{echo $vgasize} + if(! ~ $cdboot yes) + aux/vga -vip $vgasize >/n/a:/vgainfo.txt + sleep 2 # wait for floppy to finish + aux/vga -l $vgasize + if(! ~ $#novgaaccel 0) + echo -n 'hwaccel off' >'#v/vgactl' >[2]/dev/null + if(! ~ $#novgablank 0) + echo -n 'hwblank off' >'#v/vgactl' >[2]/dev/null + } +} + diff --git a/sys/lib/dist.old/pc/sub/unmount b/sys/lib/dist.old/pc/sub/unmount new file mode 100755 index 000000000..0c736afa6 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/unmount @@ -0,0 +1,3 @@ +#!/bin/rc + +syscall unmount 0 $1 >[2]/dev/null diff --git a/sys/lib/dist.old/pc/sub/users b/sys/lib/dist.old/pc/sub/users new file mode 100755 index 000000000..fd2edbe3d --- /dev/null +++ b/sys/lib/dist.old/pc/sub/users @@ -0,0 +1,7 @@ +-1:adm:adm: +0:none:none: +1:tor:tor: +2:glenda:glenda: +10000:sys:: +10001:upas:upas: +10002:bootes:bootes: diff --git a/sys/lib/dist.old/pc/sub/vmware b/sys/lib/dist.old/pc/sub/vmware new file mode 100755 index 000000000..8b398c972 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/vmware @@ -0,0 +1,10 @@ +#!/bin/rc +# vmware - if we're running in a vmware virtual machine, tweak set up +if(aux/isvmware -s){ + echo hwaccel off >'#v/vgactl' + echo -n off >'#P/i8253timerset' + for (ctl in '#S'/sd[C-H]?/ctl) + if (test -e $ctl && grep -s '^config .* dma ' $ctl && + ! grep -s '^config (848A|.* dma 00000000 )' $ctl) + echo 'dma on' >$ctl +} diff --git a/sys/lib/dist.old/pc/subst/plan9.ini b/sys/lib/dist.old/pc/subst/plan9.ini new file mode 100644 index 000000000..11a2435ca --- /dev/null +++ b/sys/lib/dist.old/pc/subst/plan9.ini @@ -0,0 +1,40 @@ +# config for initial cd booting + +[menu] +menuitem=install, Install Plan 9 from this CD +menuitem=cdboot, Boot Plan 9 from this CD +# menuitem=debug, Boot Plan 9 from this CD and debug 9load + +[common] +# very cautious settings to get started. +# will defeat booting from usb devices. +*nomp=1 +*nobiosload=1 +# *noahciload=1 +# *debugload=1 +*nodumpstack=1 +# this would disable ether and usb probing. +# *nousbprobe=1 +# *noetherprobe=1 +partition=new +mouseport=ask +monitor=ask +vgasize=ask +dmamode=ask +adisk=/dev/sdD0/cdboot +cdboot=yes +# console=0 +# baud=9600 + +[install] +nobootprompt=local!/boot/bzroot +bootfile=sdD0!cdboot!9pcflop.gz + +[cdboot] +bootargs=local!#S/sdD0/data +bootfile=sdD0!cdboot!9pccd.gz + +# [debug] +# bootargs=local!#S/sdD0/data +# bootfile=sdD0!cdboot!9pccd.gz +# *debugload=1 diff --git a/sys/lib/dist.old/setup b/sys/lib/dist.old/setup new file mode 100755 index 000000000..a1c381bd7 --- /dev/null +++ b/sys/lib/dist.old/setup @@ -0,0 +1,10 @@ +#!/bin/rc +# setup - prep for the mkfile +9fs sources +9fs other +9fs outfsother +if (test -e /cfg/$sysname/config) + . /cfg/$sysname/config +if not + outip=204.178.31.2 +import -c tcp!$outip!666 $dist/web.protect diff --git a/sys/lib/dist/cdstub/.dummy b/sys/lib/dist/cdstub/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/sys/lib/dist/cdstub/bootdisk.img b/sys/lib/dist/cdstub/bootdisk.img deleted file mode 100644 index e69de29bb..000000000 diff --git a/sys/lib/dist/cmd/bargraph.c b/sys/lib/dist/cmd/bargraph.c deleted file mode 100644 index f7a142ea9..000000000 --- a/sys/lib/dist/cmd/bargraph.c +++ /dev/null @@ -1,346 +0,0 @@ -#include -#include -#include -#include -#include - -enum {PNCTL=3}; - -static char* rdenv(char*); -int newwin(char*); -Rectangle screenrect(void); - -int nokill; -int textmode; -char *title; - -Image *light; -Image *dark; -Image *text; - -void -initcolor(void) -{ - text = display->black; - light = allocimagemix(display, DPalegreen, DWhite); - dark = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DDarkgreen); -} - -Rectangle rbar; -Point ptext; -vlong n, d; -int last; -int lastp = -1; -int first = 1; - -char backup[80]; - -void -drawbar(void) -{ - int i, j; - int p; - char buf[200], bar[100], *s; - static char lastbar[100]; - - if(n > d || n < 0 || d <= 0) - return; - - i = (Dx(rbar)*n)/d; - p = (n*100LL)/d; - - if(textmode){ - bar[0] = '|'; - for(j=0; jr.min, Pt(Dx(rbar)-30, 4)), text, ZP, display->defaultfont, buf, light, ZP); - lastp = p; - } - - if(last != i){ - draw(screen, Rect(rbar.min.x+last, rbar.min.y, rbar.min.x+i, rbar.max.y), - dark, nil, ZP); - last = i; - } - flushimage(display, 1); -} - -void -eresized(int new) -{ - Point p, q; - Rectangle r; - - if(new && getwindow(display, Refnone) < 0) - fprint(2,"can't reattach to window"); - - r = screen->r; - draw(screen, r, light, nil, ZP); - p = string(screen, addpt(r.min, Pt(4,4)), text, ZP, - display->defaultfont, title); - - p.x = r.min.x+4; - p.y += display->defaultfont->height+4; - - q = subpt(r.max, Pt(4,4)); - rbar = Rpt(p, q); - - ptext = Pt(r.max.x-4-stringwidth(display->defaultfont, "100%"), r.min.x+4); - border(screen, rbar, -2, dark, ZP); - last = 0; - lastp = -1; - - drawbar(); -} - -void -bar(Biobuf *b) -{ - char *p, *f[2]; - Event e; - int k, die, parent, child; - - parent = getpid(); - - die = 0; - if(textmode) - child = -1; - else - switch(child = rfork(RFMEM|RFPROC)) { - case 0: - sleep(1000); - while(!die && (k = eread(Ekeyboard|Emouse, &e))) { - if(nokill==0 && k == Ekeyboard && (e.kbdc == 0x7F || e.kbdc == 0x03)) { /* del, ctl-c */ - die = 1; - postnote(PNPROC, parent, "interrupt"); - _exits("interrupt"); - } - } - _exits(0); - } - - while(!die && (p = Brdline(b, '\n'))) { - p[Blinelen(b)-1] = '\0'; - if(tokenize(p, f, 2) != 2) - continue; - n = strtoll(f[0], 0, 0); - d = strtoll(f[1], 0, 0); - drawbar(); - } - postnote(PNCTL, child, "kill"); -} - - -void -usage(void) -{ - fprint(2, "usage: bargraph [-kt] [-w minx,miny,maxx,maxy] 'title'\n"); - exits("usage"); -} - -void -main(int argc, char **argv) -{ - Biobuf b; - char *p, *q; - int lfd; - - p = "0,0,200,60"; - - ARGBEGIN{ - case 'w': - p = ARGF(); - break; - case 't': - textmode = 1; - break; - case 'k': - nokill = 1; - break; - default: - usage(); - }ARGEND; - - if(argc != 1) - usage(); - - title = argv[0]; - - lfd = dup(0, -1); - - while(q = strchr(p, ',')) - *q = ' '; - Binit(&b, lfd, OREAD); - if(textmode || newwin(p) < 0){ - textmode = 1; - rbar = Rect(0, 0, 60, 1); - }else{ - initdraw(0, 0, "bar"); - initcolor(); - einit(Emouse|Ekeyboard); - eresized(0); - } - bar(&b); -} - - -/* all code below this line should be in the library, but is stolen from colors instead */ -static char* -rdenv(char *name) -{ - char *v; - int fd, size; - - fd = open(name, OREAD); - if(fd < 0) - return 0; - size = seek(fd, 0, 2); - v = malloc(size+1); - if(v == 0){ - fprint(2, "%s: can't malloc: %r\n", argv0); - exits("no mem"); - } - seek(fd, 0, 0); - read(fd, v, size); - v[size] = 0; - close(fd); - return v; -} - -int -newwin(char *win) -{ - char *srv, *mntsrv; - char spec[100]; - int srvfd, cons, pid; - - switch(rfork(RFFDG|RFPROC|RFNAMEG|RFENVG|RFNOTEG|RFNOWAIT)){ - case -1: - fprint(2, "bargraph: can't fork: %r\n"); - return -1; - case 0: - break; - default: - exits(0); - } - - srv = rdenv("/env/wsys"); - if(srv == 0){ - mntsrv = rdenv("/mnt/term/env/wsys"); - if(mntsrv == 0){ - fprint(2, "bargraph: can't find $wsys\n"); - return -1; - } - srv = malloc(strlen(mntsrv)+10); - sprint(srv, "/mnt/term%s", mntsrv); - free(mntsrv); - pid = 0; /* can't send notes to remote processes! */ - }else - pid = getpid(); - USED(pid); - srvfd = open(srv, ORDWR); - free(srv); - if(srvfd == -1){ - fprint(2, "bargraph: can't open %s: %r\n", srv); - return -1; - } - sprint(spec, "new -r %s", win); - if(mount(srvfd, -1, "/mnt/wsys", 0, spec) == -1){ - fprint(2, "bargraph: can't mount /mnt/wsys: %r (spec=%s)\n", spec); - return -1; - } - close(srvfd); - unmount("/mnt/acme", "/dev"); - bind("/mnt/wsys", "/dev", MBEFORE); - cons = open("/dev/cons", OREAD); - if(cons==-1){ - NoCons: - fprint(2, "bargraph: can't open /dev/cons: %r"); - return -1; - } - dup(cons, 0); - close(cons); - cons = open("/dev/cons", OWRITE); - if(cons==-1) - goto NoCons; - dup(cons, 1); - dup(cons, 2); - close(cons); -// wctlfd = open("/dev/wctl", OWRITE); - return 0; -} - -Rectangle -screenrect(void) -{ - int fd; - char buf[12*5]; - - fd = open("/dev/screen", OREAD); - if(fd == -1) - fd=open("/mnt/term/dev/screen", OREAD); - if(fd == -1){ - fprint(2, "%s: can't open /dev/screen: %r\n", argv0); - exits("window read"); - } - if(read(fd, buf, sizeof buf) != sizeof buf){ - fprint(2, "%s: can't read /dev/screen: %r\n", argv0); - exits("screen read"); - } - close(fd); - return Rect(atoi(buf+12), atoi(buf+24), atoi(buf+36), atoi(buf+48)); -} - -int -postnote(int group, int pid, char *note) -{ - char file[128]; - int f, r; - - switch(group) { - case PNPROC: - sprint(file, "/proc/%d/note", pid); - break; - case PNGROUP: - sprint(file, "/proc/%d/notepg", pid); - break; - case PNCTL: - sprint(file, "/proc/%d/ctl", pid); - break; - default: - return -1; - } - - f = open(file, OWRITE); - if(f < 0) - return -1; - - r = strlen(note); - if(write(f, note, r) != r) { - close(f); - return -1; - } - close(f); - return 0; -} diff --git a/sys/lib/dist/cmd/bflz.c b/sys/lib/dist/cmd/bflz.c deleted file mode 100644 index 89cb361c2..000000000 --- a/sys/lib/dist/cmd/bflz.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Extraordinarily brute force Lempel & Ziv-like - * compressor. The input file must fit in memory - * during compression, and the output file will - * be reconstructed in memory during decompression. - * We search for large common sequences and use a - * greedy algorithm to choose which sequence gets - * compressed first. - * - * Files begin with "BLZ\n" and a 32-bit uncompressed file length. - * - * Output format is a series of blocks followed by - * a raw data section. Each block begins with a 32-bit big-endian - * number. The top bit is type and the next 31 bits - * are uncompressed size. Type is one of - * 0 - use raw data for this length - * 1 - a 32-bit offset follows - * After the blocks come the raw data. (The end of the blocks can be - * noted by summing block lengths until you reach the file length.) - */ - -#include -#include -#include - -#define malloc sbrk - -int minrun = 16; -int win = 16; -ulong outn; -int verbose; -int mindist; - -enum { Prime = 16777213 }; /* smallest prime < 2^24 (so p*256+256 < 2^32) */ -enum { NOFF = 3 }; - -Biobuf bout; -ulong length; -uchar *data; -ulong sum32(ulong, void*, long); -uchar *odat; -int nodat; -int nraw; -int rawstart; -int acct; -int zlength; -int maxchain; -int maxrle[256]; -int nnew; - -typedef struct Node Node; -struct Node { - Node *link; - ulong key; - ulong offset[NOFF]; -}; - -Node *nodepool; -int nnodepool; - -Node **hash; -uint nhash; - -uint maxlen; -uint maxsame; -uint replacesame = 8*1024*1024; - -Node *freelist, **freeend; -uint nalloc; - -Node* -allocnode(void) -{ - int i; - Node *n; - - if(nnodepool == 0){ - nnodepool = 256*1024; - nodepool = malloc(sizeof(Node)*nnodepool); - } - if(freelist){ - n = freelist; - freelist = n->link; - return n; - } - assert(nnodepool > 0); - nalloc++; - n = &nodepool[--nnodepool]; - for(i=0; ioffset[i] = -1; - - return n; -} - -void -freenode(Node *n) -{ - if(freelist == nil) - freelist = n; - else - *freeend = n; - freeend = &n->link; - n->link = nil; -} - -Node** -llookup(ulong key) -{ - uint c; - Node **l, **top, *n; - - if(nhash == 0){ - uint x; - - x = length/8; - for(nhash=1; nhashlink){ - c++; - if((*l)->key == key){ - /* move to front */ - n = *l; - *l = n->link; - n->link = *top; - *top = n; - return top; - } - } - if(c > maxlen) - maxlen = c; - return l; -} - -Node* -lookup(ulong key) -{ - return *llookup(key); -} - -void -insertnode(ulong key, ulong offset) -{ - int i; - Node *n, **l; - - l = llookup(key); - if(*l == nil){ - if(l==&hash[key&(nhash-1)]) - nnew++; - *l = allocnode(); - (*l)->key = key; - } - n = *l; - - /* add or replace last */ - for(i=0; ioffset[i]!=-1; i++) - ; - n->offset[i] = offset; -} - -void -Bputint(Biobufhdr *b, int n) -{ - uchar p[4]; - - p[0] = n>>24; - p[1] = n>>16; - p[2] = n>>8; - p[3] = n; - Bwrite(b, p, 4); -} - -void -flushraw(void) -{ - if(nraw){ - if(verbose) - fprint(2, "Raw %d+%d\n", rawstart, nraw); - zlength += 4+nraw; - Bputint(&bout, (1<<31)|nraw); - memmove(odat+nodat, data+rawstart, nraw); - nodat += nraw; - nraw = 0; - } -} - -int -rawbyte(int i) -{ - assert(acct == i); - if(nraw == 0) - rawstart = i; - acct++; - nraw++; - return 1; -} - -int -refblock(int i, int len, int off) -{ - assert(acct == i); - acct += len; - if(nraw) - flushraw(); - if(verbose) - fprint(2, "Copy %d+%d from %d\n", i, len, off); - Bputint(&bout, len); - Bputint(&bout, off); - zlength += 4+4; - return len; -} - -int -cmprun(uchar *a, uchar *b, int len) -{ - int i; - - if(a==b) - return 0; - for(i=0; ioffset[o] == -1) - break; - run = cmprun(data+i, data+n->offset[o], length-i); - if(run > maxrun && n->offset[o]+mindist < i){ - maxrun = run; - maxoff = n->offset[o]; - best = o; - } - } - if(best > 0){ - o = n->offset[best]; - for(j=best; j>0; j--) - n->offset[j] = n->offset[j-1]; - n->offset[0] = o; - } - } - - if(maxrun >= minrun) - j = i+refblock(i, maxrun, maxoff); - else - j = i+rawbyte(i); - for(; imaxrle[data[i]]){ - maxrle[data[i]] = rle; - insertnode(sum, i); - } - sum = (sum*256+data[i+win]) % Prime; - sum = (sum + data[i]*outn) % Prime; - } - } - /* could do better here */ - for(; i 0){ - data = realloc(data, length+n); - if(data == nil) - sysfatal("realloc: %r"); - memmove(data+length, buf, n); - length += n; - if(n < sizeof buf) - break; - } - odat = malloc(length); - if(odat == nil) - sysfatal("malloc: %r"); - - Binit(&bout, 1, OWRITE); - Bprint(&bout, "BLZ\n"); - Bputint(&bout, length); - outn = 1; - for(i=0; i -#include -#include -#include -#include -#include "bzfs.h" - -enum{ - LEN = 8*1024, - NFLDS = 6, /* filename, modes, uid, gid, mtime, bytes */ -}; - -void mkdirs(char*, char*); -void mkdir(char*, ulong, ulong, char*, char*); -void extract(char*, ulong, ulong, char*, char*, ulong); -void seekpast(ulong); -void error(char*, ...); -void warn(char*, ...); -void usage(void); -char *mtpt; -Biobufhdr bin; -uchar binbuf[2*LEN]; - -void -usage(void) -{ - fprint(2, "usage: bzfs [-m mtpt] [-s] [-f file] [-h]\n"); - exits("usage"); -} - -/* - * floppy disks can only be read on 512-byte - * boundaries and in 512 byte multiples. - * feed one over a pipe to allow arbitrary reading. - */ -char zero[512]; -int -blockread(int in, char *first, int nfirst) -{ - int p[2], out, n, rv; - char blk[512]; - - if(pipe(p) < 0) - sysfatal("pipe: %r"); - rv = p[0]; - out = p[1]; - switch(rfork(RFPROC|RFNOTEG|RFFDG)){ - case -1: - sysfatal("fork: %r"); - case 0: - close(rv); - break; - default: - close(in); - close(out); - return rv; - } - - write(out, first, nfirst); - - while((n=read(in, blk, sizeof blk)) > 0){ - if(write(out, blk, n) != n) - break; - if(n == sizeof(blk) && memcmp(zero, blk, n) == n) - break; - } - _exits(0); - return -1; -} - -enum { NAMELEN = 28 }; - -void -main(int argc, char **argv) -{ - char *rargv[10]; - int rargc; - char *fields[NFLDS], name[2*LEN], *p, *namep; - char uid[NAMELEN], gid[NAMELEN]; - ulong mode, bytes, mtime; - char *file; - int i, n, stdin, fd, chatty; - char blk[512]; - - if(argc>1 && strcmp(argv[1], "RAMFS") == 0){ - argv[1] = argv[0]; - ramfsmain(argc-1, argv+1); - exits(nil); - } - if(argc>1 && strcmp(argv[1], "BUNZIP") == 0){ - _unbzip(0, 1); - exits(nil); - } - - rfork(RFNOTEG); - stdin = 0; - file = nil; - namep = name; - mtpt = "/root"; - chatty = 0; - ARGBEGIN{ - case 'd': - chatty = !chatty; - break; - case 'f': - file = ARGF(); - break; - case 's': - stdin++; - break; - case 'm': - mtpt = ARGF(); - break; - default: - usage(); - }ARGEND - - if(argc != 0) - usage(); - - if(file == nil) { - fprint(2, "must specify -f file\n"); - usage(); - } - - if((fd = open(file, OREAD)) < 0) { - fprint(2, "cannot open \"%s\": %r\n", file); - exits("open"); - } - - rargv[0] = "ramfs"; - rargc = 1; - if(stdin) - rargv[rargc++] = "-i"; - rargv[rargc++] = "-m"; - rargv[rargc++] = mtpt; - rargv[rargc] = nil; - ramfsmain(rargc, rargv); - - if(1 || strstr(file, "disk")) { /* search for archive on block boundary */ -if(chatty) fprint(2, "searching for bz\n"); - for(i=0;; i++){ - if((n = readn(fd, blk, sizeof blk)) != sizeof blk) - sysfatal("read %d gets %d: %r\n", i, n); - if(strncmp(blk, "bzfilesystem\n", 13) == 0) - break; - } -if(chatty) fprint(2, "found at %d\n", i); - } - - if(chdir(mtpt) < 0) - error("chdir %s: %r", mtpt); - - fd = unbflz(unbzip(blockread(fd, blk+13, sizeof(blk)-13))); - - Binits(&bin, fd, OREAD, binbuf, sizeof binbuf); - while(p = Brdline(&bin, '\n')){ - p[Blinelen(&bin)-1] = '\0'; -if(chatty) fprint(2, "%s\n", p); - if(strcmp(p, "end of archive") == 0){ - _exits(0); - } - if(getfields(p, fields, NFLDS, 0, " \t") != NFLDS){ - warn("too few fields in file header"); - continue; - } - strcpy(namep, fields[0]); - mode = strtoul(fields[1], 0, 8); - mtime = strtoul(fields[4], 0, 10); - bytes = strtoul(fields[5], 0, 10); - strncpy(uid, fields[2], NAMELEN); - strncpy(gid, fields[3], NAMELEN); - if(mode & DMDIR) - mkdir(name, mode, mtime, uid, gid); - else - extract(name, mode, mtime, uid, gid, bytes); - } - fprint(2, "premature end of archive\n"); - exits("premature end of archive"); -} - -char buf[8192]; - -int -ffcreate(char *name, ulong mode, char *uid, char *gid, ulong mtime, int length) -{ - int fd, om; - Dir nd; - - sprint(buf, "%s/%s", mtpt, name); - om = ORDWR; - if(mode&DMDIR) - om = OREAD; - if((fd = create(buf, om, (mode&DMDIR)|0666)) < 0) - error("create %s: %r", buf); - - nulldir(&nd); - nd.mode = mode; - nd.uid = uid; - nd.gid = gid; - nd.mtime = mtime; - if(length) - nd.length = length; - if(dirfwstat(fd, &nd) < 0) - error("fwstat %s: %r", buf); - - return fd; -} - -void -mkdir(char *name, ulong mode, ulong mtime, char *uid, char *gid) -{ - close(ffcreate(name, mode, uid, gid, mtime, 0)); -} - -void -extract(char *name, ulong mode, ulong mtime, char *uid, char *gid, ulong bytes) -{ - int fd, tot, n; - - fd = ffcreate(name, mode, uid, gid, mtime, bytes); - - for(tot = 0; tot < bytes; tot += n){ - n = sizeof buf; - if(tot + n > bytes) - n = bytes - tot; - n = Bread(&bin, buf, n); - if(n <= 0) - error("premature eof reading %s", name); - if(write(fd, buf, n) != n) - error("short write writing %s", name); - } - close(fd); -} - -void -error(char *fmt, ...) -{ - char buf[1024]; - va_list arg; - - sprint(buf, "%s: ", argv0); - va_start(arg, fmt); - vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg); - va_end(arg); - fprint(2, "%s\n", buf); - exits(0); -} - -void -warn(char *fmt, ...) -{ - char buf[1024]; - va_list arg; - - sprint(buf, "%s: ", argv0); - va_start(arg, fmt); - vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg); - va_end(arg); - fprint(2, "%s\n", buf); -} - -int -_efgfmt(Fmt*) -{ - return -1; -} diff --git a/sys/lib/dist/cmd/bzfs/mkfile b/sys/lib/dist/cmd/bzfs/mkfile deleted file mode 100644 index df81b5641..000000000 --- a/sys/lib/dist/cmd/bzfs/mkfile +++ /dev/null @@ -1,20 +0,0 @@ - -#include -#include -#include -#include "bzfs.h" - -/* - * Rather than reading /adm/users, which is a lot of work for - * a toy program, we assume all groups have the form - * NNN:user:user: - * meaning that each user is the leader of his own group. - */ - -enum -{ - OPERM = 0x3, /* mask of all permission types in open mode */ - Nram = 512, - Maxsize = 512*1024*1024, - Maxfdata = 8192, -}; - -typedef struct Fid Fid; -typedef struct Ram Ram; - -struct Fid -{ - short busy; - short open; - short rclose; - int fid; - Fid *next; - char *user; - Ram *ram; -}; - -struct Ram -{ - short busy; - short open; - long parent; /* index in Ram array */ - Qid qid; - long perm; - char *name; - ulong atime; - ulong mtime; - char *user; - char *group; - char *muid; - char *data; - long ndata; -}; - -enum -{ - Pexec = 1, - Pwrite = 2, - Pread = 4, - Pother = 1, - Pgroup = 8, - Powner = 64, -}; - -ulong path; /* incremented for each new file */ -Fid *fids; -Ram ram[Nram]; -int nram; -int mfd[2]; -char *user; -uchar mdata[IOHDRSZ+Maxfdata]; -uchar rdata[Maxfdata]; /* buffer for data in reply */ -uchar statbuf[STATMAX]; -Fcall thdr; -Fcall rhdr; -int messagesize = sizeof mdata; - -Fid * newfid(int); -uint ramstat(Ram*, uchar*, uint); -void io(void); -void *erealloc(void*, ulong); -void *emalloc(ulong); -char *estrdup(char*); -void ramfsusage(void); -int perm(Fid*, Ram*, int); -char *atom(char*); - -char *rflush(Fid*), *rversion(Fid*), *rauth(Fid*), - *rattach(Fid*), *rwalk(Fid*), - *ropen(Fid*), *rcreate(Fid*), - *rread(Fid*), *rwrite(Fid*), *rclunk(Fid*), - *rremove(Fid*), *rstat(Fid*), *rwstat(Fid*); - -char *(*fcalls[])(Fid*) = { - [Tversion] rversion, - [Tflush] rflush, - [Tauth] rauth, - [Tattach] rattach, - [Twalk] rwalk, - [Topen] ropen, - [Tcreate] rcreate, - [Tread] rread, - [Twrite] rwrite, - [Tclunk] rclunk, - [Tremove] rremove, - [Tstat] rstat, - [Twstat] rwstat, -}; - -char Eperm[] = "permission denied"; -char Enotdir[] = "not a directory"; -char Enoauth[] = "no authentication in ramfs"; -char Enotexist[] = "file does not exist"; -char Einuse[] = "file in use"; -char Eexist[] = "file exists"; -char Eisdir[] = "file is a directory"; -char Enotowner[] = "not owner"; -char Eisopen[] = "file already open for I/O"; -char Excl[] = "exclusive use file already open"; -char Ename[] = "illegal name"; -char Eversion[] = "unknown 9P version"; - -int debug; - -void -notifyf(void *a, char *s) -{ - USED(a); - if(strncmp(s, "interrupt", 9) == 0) - noted(NCONT); - noted(NDFLT); -} - -void -ramfsmain(int argc, char *argv[]) -{ - Ram *r; - char *defmnt; - int p[2]; - char buf[32]; - int fd, srvfd; - int stdio = 0; - - srvfd = -1; - defmnt = "/tmp"; - ARGBEGIN{ - case 'D': - debug = 1; - break; - case 'i': /* this is DIFFERENT from normal ramfs; use 1 for both for kernel */ - defmnt = 0; - stdio = 1; - srvfd = 0; - mfd[0] = 1; - mfd[1] = 1; - break; - case 's': - defmnt = 0; - break; - case 'm': - defmnt = ARGF(); - break; - default: - ramfsusage(); - }ARGEND - - if(!stdio){ - if(pipe(p) < 0) - error("pipe failed"); - srvfd = p[1]; - mfd[0] = p[0]; - mfd[1] = p[0]; - if(defmnt == 0){ - fd = create("#s/ramfs", OWRITE, 0666); - if(fd < 0) - error("create of /srv/ramfs failed"); - sprint(buf, "%d", p[1]); - if(write(fd, buf, strlen(buf)) < 0) - error("writing /srv/ramfs"); - } - } - - user = atom(getuser()); - notify(notifyf); - nram = 1; - r = &ram[0]; - r->busy = 1; - r->data = 0; - r->ndata = 0; - r->perm = DMDIR | 0775; - r->qid.type = QTDIR; - r->qid.path = 0LL; - r->qid.vers = 0; - r->parent = 0; - r->user = user; - r->group = user; - r->muid = user; - r->atime = time(0); - r->mtime = r->atime; - r->name = estrdup("."); - - if(debug) - fmtinstall('F', fcallfmt); - switch(rfork(RFFDG|RFPROC|RFNAMEG|RFNOTEG)){ - case -1: - error("fork"); - case 0: - close(srvfd); - io(); - break; - default: - close(mfd[0]); /* don't deadlock if child fails */ - if(defmnt && mount(srvfd, -1, defmnt, MREPL|MCREATE, "") < 0) - error("mount failed: %r"); - } -} - -char* -rversion(Fid*) -{ - Fid *f; - - for(f = fids; f; f = f->next) - if(f->busy) - rclunk(f); - if(thdr.msize > sizeof mdata) - rhdr.msize = sizeof mdata; - else - rhdr.msize = thdr.msize; - messagesize = rhdr.msize; - if(strncmp(thdr.version, "9P2000", 6) != 0) - return Eversion; - rhdr.version = "9P2000"; - return 0; -} - -char* -rauth(Fid*) -{ - return "ramfs: no authentication required"; -} - -char* -rflush(Fid *f) -{ - USED(f); - return 0; -} - -char* -rattach(Fid *f) -{ - /* no authentication! */ - f->busy = 1; - f->rclose = 0; - f->ram = &ram[0]; - rhdr.qid = f->ram->qid; - if(thdr.uname[0]) - f->user = atom(thdr.uname); - else - f->user = atom("none"); - if(strcmp(user, "none") == 0) - user = f->user; - return 0; -} - -char* -clone(Fid *f, Fid **nf) -{ - if(f->open) - return Eisopen; - if(f->ram->busy == 0) - return Enotexist; - *nf = newfid(thdr.newfid); - (*nf)->busy = 1; - (*nf)->open = 0; - (*nf)->rclose = 0; - (*nf)->ram = f->ram; - (*nf)->user = f->user; /* no ref count; the leakage is minor */ - return 0; -} - -char* -rwalk(Fid *f) -{ - Ram *r, *fram; - char *name; - Ram *parent; - Fid *nf; - char *err; - ulong t; - int i; - - err = nil; - nf = nil; - rhdr.nwqid = 0; - if(rhdr.newfid != rhdr.fid){ - err = clone(f, &nf); - if(err) - return err; - f = nf; /* walk the new fid */ - } - fram = f->ram; - if(thdr.nwname > 0){ - t = time(0); - for(i=0; iqid.type & QTDIR) == 0){ - err = Enotdir; - break; - } - if(fram->busy == 0){ - err = Enotexist; - break; - } - fram->atime = t; - name = thdr.wname[i]; - if(strcmp(name, ".") == 0){ - Found: - rhdr.nwqid++; - rhdr.wqid[i] = fram->qid; - continue; - } - parent = &ram[fram->parent]; -#ifdef CHECKS - if(!perm(f, parent, Pexec)){ - err = Eperm; - break; - } -#endif - if(strcmp(name, "..") == 0){ - fram = parent; - goto Found; - } - for(r=ram; r < &ram[nram]; r++) - if(r->busy && r->parent==fram-ram && strcmp(name, r->name)==0){ - fram = r; - goto Found; - } - break; - } - if(i==0 && err == nil) - err = Enotexist; - } - if(nf != nil && (err!=nil || rhdr.nwqidbusy = 0; - f->ram = nil; - } - if(rhdr.nwqid == thdr.nwname) /* update the fid after a successful walk */ - f->ram = fram; - return err; -} - -char * -ropen(Fid *f) -{ - Ram *r; - int mode, trunc; - - if(f->open) - return Eisopen; - r = f->ram; - if(r->busy == 0) - return Enotexist; - if(r->perm & DMEXCL) - if(r->open) - return Excl; - mode = thdr.mode; - if(r->qid.type & QTDIR){ - if(mode != OREAD) - return Eperm; - rhdr.qid = r->qid; - return 0; - } - if(mode & ORCLOSE){ - /* can't remove root; must be able to write parent */ - if(r->qid.path==0 || !perm(f, &ram[r->parent], Pwrite)) - return Eperm; - f->rclose = 1; - } - trunc = mode & OTRUNC; - mode &= OPERM; - if(mode==OWRITE || mode==ORDWR || trunc) - if(!perm(f, r, Pwrite)) - return Eperm; - if(mode==OREAD || mode==ORDWR) - if(!perm(f, r, Pread)) - return Eperm; - if(mode==OEXEC) - if(!perm(f, r, Pexec)) - return Eperm; - if(trunc && (r->perm&DMAPPEND)==0){ - r->ndata = 0; - if(r->data) - free(r->data); - r->data = 0; - r->qid.vers++; - } - rhdr.qid = r->qid; - rhdr.iounit = messagesize-IOHDRSZ; - f->open = 1; - r->open++; - return 0; -} - -char * -rcreate(Fid *f) -{ - Ram *r; - char *name; - long parent, prm; - - if(f->open) - return Eisopen; - if(f->ram->busy == 0) - return Enotexist; - parent = f->ram - ram; - if((f->ram->qid.type&QTDIR) == 0) - return Enotdir; - /* must be able to write parent */ -#ifdef CHECKS - if(!perm(f, f->ram, Pwrite)) - return Eperm; -#endif - prm = thdr.perm; - name = thdr.name; - if(strcmp(name, ".")==0 || strcmp(name, "..")==0) - return Ename; - for(r=ram; r<&ram[nram]; r++) - if(r->busy && parent==r->parent) - if(strcmp((char*)name, r->name)==0) - return Einuse; - for(r=ram; r->busy; r++) - if(r == &ram[Nram-1]) - return "no free ram resources"; - r->busy = 1; - r->qid.path = ++path; - r->qid.vers = 0; - if(prm & DMDIR) - r->qid.type |= QTDIR; - r->parent = parent; - free(r->name); - r->name = estrdup(name); - r->user = f->user; - r->group = f->ram->group; - r->muid = f->ram->muid; - if(prm & DMDIR) - prm = (prm&~0777) | (f->ram->perm&prm&0777); - else - prm = (prm&(~0777|0111)) | (f->ram->perm&prm&0666); - r->perm = prm; - r->ndata = 0; - if(r-ram >= nram) - nram = r - ram + 1; - r->atime = time(0); - r->mtime = r->atime; - f->ram->mtime = r->atime; - f->ram = r; - rhdr.qid = r->qid; - rhdr.iounit = messagesize-IOHDRSZ; - f->open = 1; - if(thdr.mode & ORCLOSE) - f->rclose = 1; - r->open++; - return 0; -} - -char* -rread(Fid *f) -{ - Ram *r; - uchar *buf; - long off; - int n, m, cnt; - - if(f->ram->busy == 0) - return Enotexist; - n = 0; - rhdr.count = 0; - off = thdr.offset; - buf = rdata; - cnt = thdr.count; - if(cnt > messagesize) /* shouldn't happen, anyway */ - cnt = messagesize; - if(f->ram->qid.type & QTDIR){ - for(r=ram+1; off > 0; r++){ - if(r->busy && r->parent==f->ram-ram) - off -= ramstat(r, statbuf, sizeof statbuf); - if(r == &ram[nram-1]) - return 0; - } - for(; r<&ram[nram] && n < cnt; r++){ - if(!r->busy || r->parent!=f->ram-ram) - continue; - m = ramstat(r, buf+n, cnt-n); - if(m == 0) - break; - n += m; - } - rhdr.data = (char*)rdata; - rhdr.count = n; - return 0; - } - r = f->ram; - if(off >= r->ndata) - return 0; - r->atime = time(0); - n = cnt; - if(off+n > r->ndata) - n = r->ndata - off; - rhdr.data = r->data+off; - rhdr.count = n; - return 0; -} - -char* -rwrite(Fid *f) -{ - Ram *r; - ulong off; - int cnt; - - r = f->ram; - if(r->busy == 0) - return Enotexist; - off = thdr.offset; - if(r->perm & DMAPPEND) - off = r->ndata; - cnt = thdr.count; - if(r->qid.type & QTDIR) - return Eisdir; - if(off+cnt >= Maxsize) /* sanity check */ - return "write too big"; - if(off+cnt > r->ndata) - r->data = erealloc(r->data, off+cnt); - if(off > r->ndata) - memset(r->data+r->ndata, 0, off-r->ndata); - if(off+cnt > r->ndata) - r->ndata = off+cnt; - memmove(r->data+off, thdr.data, cnt); - r->qid.vers++; - r->mtime = time(0); - rhdr.count = cnt; - return 0; -} - -void -realremove(Ram *r) -{ - r->ndata = 0; - if(r->data) - free(r->data); - r->data = 0; - r->parent = 0; - memset(&r->qid, 0, sizeof r->qid); - free(r->name); - r->name = nil; - r->busy = 0; -} - -char * -rclunk(Fid *f) -{ - if(f->open) - f->ram->open--; - if(f->rclose) - realremove(f->ram); - f->busy = 0; - f->open = 0; - f->ram = 0; - return 0; -} - -char * -rremove(Fid *f) -{ - Ram *r; - - if(f->open) - f->ram->open--; - f->busy = 0; - f->open = 0; - r = f->ram; - f->ram = 0; -#ifdef CHECKS - if(r->qid.path == 0 || !perm(f, &ram[r->parent], Pwrite)) - return Eperm; -#endif - ram[r->parent].mtime = time(0); - realremove(r); - return 0; -} - -char * -rstat(Fid *f) -{ - if(f->ram->busy == 0) - return Enotexist; - rhdr.nstat = ramstat(f->ram, statbuf, sizeof statbuf); - rhdr.stat = statbuf; - return 0; -} - -char * -rwstat(Fid *f) -{ - Ram *r, *s; - Dir dir; - - if(f->ram->busy == 0) - return Enotexist; - convM2D(thdr.stat, thdr.nstat, &dir, (char*)statbuf); - r = f->ram; - - /* - * To change length, must have write permission on file. - */ -#ifdef CHECKS - if(dir.length!=~0 && dir.length!=r->ndata){ - if(!perm(f, r, Pwrite)) - return Eperm; - } -#endif - - /* - * To change name, must have write permission in parent - * and name must be unique. - */ - if(dir.name[0]!='\0' && strcmp(dir.name, r->name)!=0){ -#ifdef CHECKS - if(!perm(f, &ram[r->parent], Pwrite)) - return Eperm; -#endif - for(s=ram; s<&ram[nram]; s++) - if(s->busy && s->parent==r->parent) - if(strcmp(dir.name, s->name)==0) - return Eexist; - } - -#ifdef OWNERS - /* - * To change mode, must be owner or group leader. - * Because of lack of users file, leader=>group itself. - */ - if(dir.mode!=~0 && r->perm!=dir.mode){ - if(strcmp(f->user, r->user) != 0) - if(strcmp(f->user, r->group) != 0) - return Enotowner; - } - - /* - * To change group, must be owner and member of new group, - * or leader of current group and leader of new group. - * Second case cannot happen, but we check anyway. - */ - if(dir.gid[0]!='\0' && strcmp(r->group, dir.gid)!=0){ - if(strcmp(f->user, r->user) == 0) - if(strcmp(f->user, dir.gid) == 0) - goto ok; - if(strcmp(f->user, r->group) == 0) - if(strcmp(f->user, dir.gid) == 0) - goto ok; - return Enotowner; - ok:; - } -#endif - - /* all ok; do it */ - if(dir.mode != ~0){ - dir.mode &= ~DMDIR; /* cannot change dir bit */ - dir.mode |= r->perm&DMDIR; - r->perm = dir.mode; - } - if(dir.name[0] != '\0'){ - free(r->name); - r->name = estrdup(dir.name); - } - if(dir.gid[0] != '\0') - r->group = atom(dir.gid); - - if(dir.uid[0] != '\0') - r->user = atom(dir.uid); - - if(dir.length!=~0 && dir.length!=r->ndata){ - r->data = erealloc(r->data, dir.length); - if(r->ndata < dir.length) - memset(r->data+r->ndata, 0, dir.length-r->ndata); - r->ndata = dir.length; - } - - if(dir.mtime != ~0) - r->mtime = dir.mtime; - - ram[r->parent].mtime = time(0); - return 0; -} - -uint -ramstat(Ram *r, uchar *buf, uint nbuf) -{ - Dir dir; - - dir.name = r->name; - dir.qid = r->qid; - dir.mode = r->perm; - dir.length = r->ndata; - dir.uid = r->user; - dir.gid = r->group; - dir.muid = r->muid; - dir.atime = r->atime; - dir.mtime = r->mtime; - return convD2M(&dir, buf, nbuf); -} - -Fid * -newfid(int fid) -{ - Fid *f, *ff; - - ff = 0; - for(f = fids; f; f = f->next) - if(f->fid == fid) - return f; - else if(!ff && !f->busy) - ff = f; - if(ff){ - ff->fid = fid; - return ff; - } - f = emalloc(sizeof *f); - f->ram = nil; - f->fid = fid; - f->next = fids; - fids = f; - return f; -} - -void -io(void) -{ - char *err; - int n, pid; - - pid = getpid(); - - for(;;){ - /* - * reading from a pipe or a network device - * will give an error after a few eof reads. - * however, we cannot tell the difference - * between a zero-length read and an interrupt - * on the processes writing to us, - * so we wait for the error. - */ - n = read9pmsg(mfd[0], mdata, messagesize); - if(n < 0) - error("mount read: %r"); - if(n == 0) - continue; - if(convM2S(mdata, n, &thdr) == 0) - continue; - - if(debug) - fprint(2, "ramfs %d:<-%F\n", pid, &thdr); - - if(!fcalls[thdr.type]) - err = "bad fcall type"; - else - err = (*fcalls[thdr.type])(newfid(thdr.fid)); - if(err){ - rhdr.type = Rerror; - rhdr.ename = err; - }else{ - rhdr.type = thdr.type + 1; - rhdr.fid = thdr.fid; - } - rhdr.tag = thdr.tag; - if(debug) - fprint(2, "ramfs %d:->%F\n", pid, &rhdr);/**/ - n = convS2M(&rhdr, mdata, messagesize); - if(n == 0) - error("convS2M error on write"); - if(write(mfd[1], mdata, n) != n) - error("mount write"); - } -} - -int -perm(Fid *f, Ram *r, int p) -{ - if((p*Pother) & r->perm) - return 1; - if(strcmp(f->user, r->group)==0 && ((p*Pgroup) & r->perm)) - return 1; - if(strcmp(f->user, r->user)==0 && ((p*Powner) & r->perm)) - return 1; - return 0; -} - -void * -emalloc(ulong n) -{ - void *p; - - p = malloc(n); - if(!p) - error("out of memory"); - memset(p, 0, n); - return p; -} - -void * -erealloc(void *p, ulong n) -{ - p = realloc(p, n); - if(!p) - error("out of memory"); - return p; -} - -char * -estrdup(char *q) -{ - char *p; - int n; - - n = strlen(q)+1; - p = malloc(n); - if(!p) - error("out of memory"); - memmove(p, q, n); - return p; -} - -void -ramfsusage(void) -{ - fprint(2, "usage: %s [-is] [-m mountpoint]\n", argv0); - exits("usage"); -} - -/* - * Custom allocators to avoid malloc overheads on small objects. - * We never free these. (See below.) - */ -typedef struct Stringtab Stringtab; -struct Stringtab { - Stringtab *link; - char *str; -}; -static Stringtab* -taballoc(void) -{ - static Stringtab *t; - static uint nt; - - if(nt == 0){ - t = malloc(64*sizeof(Stringtab)); - if(t == 0) - sysfatal("out of memory"); - nt = 64; - } - nt--; - return t++; -} - -static char* -xstrdup(char *s) -{ - char *r; - int len; - static char *t; - static int nt; - - len = strlen(s)+1; - if(len >= 8192) - sysfatal("strdup big string"); - - if(nt < len){ - t = malloc(8192); - if(t == 0) - sysfatal("out of memory"); - nt = 8192; - } - r = t; - t += len; - nt -= len; - strcpy(r, s); - return r; -} - -/* - * Return a uniquely allocated copy of a string. - * Don't free these -- they stay in the table for the - * next caller who wants that particular string. - * String comparison can be done with pointer comparison - * if you know both strings are atoms. - */ -static Stringtab *stab[1024]; - -static uint -hash(char *s) -{ - uint h; - uchar *p; - - h = 0; - for(p=(uchar*)s; *p; p++) - h = h*37 + *p; - return h; -} - -char* -atom(char *str) -{ - uint h; - Stringtab *tab; - - h = hash(str) % nelem(stab); - for(tab=stab[h]; tab; tab=tab->link) - if(strcmp(str, tab->str) == 0) - return tab->str; - - tab = taballoc(); - tab->str = xstrdup(str); - tab->link = stab[h]; - stab[h] = tab; - return tab->str; -} diff --git a/sys/lib/dist/cmd/bzfs/unbflz.c b/sys/lib/dist/cmd/bzfs/unbflz.c deleted file mode 100644 index 661d65e4d..000000000 --- a/sys/lib/dist/cmd/bzfs/unbflz.c +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#include -#include "bzfs.h" - -int -Bgetint(Biobuf *b) -{ - uchar p[4]; - - if(Bread(b, p, 4) != 4) - sysfatal("short read"); - return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3]; -} - -/* - * memmove but make sure overlap works properly. - */ -void -copy(uchar *dst, uchar *src, int n) -{ - while(n-- > 0) - *dst++ = *src++; -} - -int -unbflz(int in) -{ - int rv, out, p[2]; - Biobuf *b, bin; - char buf[5]; - uchar *data; - int i, j, length, n, m, o, sum; - ulong *blk; - int nblk, mblk; - - if(pipe(p) < 0) - sysfatal("pipe: %r"); - - rv = p[0]; - out = p[1]; - switch(rfork(RFPROC|RFFDG|RFNOTEG|RFMEM)){ - case -1: - sysfatal("fork: %r"); - case 0: - close(rv); - break; - default: - close(in); - close(out); - return rv; - } - - Binit(&bin, in, OREAD); - b = &bin; - - if(Bread(b, buf, 4) != 4) - sysfatal("short read"); - - if(memcmp(buf, "BLZ\n", 4) != 0) - sysfatal("bad header"); - - length = Bgetint(b); - data = malloc(length); - if(data == nil) - sysfatal("out of memory"); - sum = 0; - nblk = 0; - mblk = 0; - blk = nil; - while(sum < length){ - if(nblk>=mblk){ - mblk += 16384; - blk = realloc(blk, (mblk+1)*sizeof(blk[0])); - if(blk == nil) - sysfatal("out of memory"); - } - n = Bgetint(b); - blk[nblk++] = n; - if(n&(1<<31)) - n &= ~(1<<31); - else - blk[nblk++] = Bgetint(b); - sum += n; - } - if(sum != length) - sysfatal("bad compressed data %d %d", sum, length); - i = 0; - j = 0; - while(i < length){ - assert(j < nblk); - n = blk[j++]; - if(n&(1<<31)){ - n &= ~(1<<31); - if((m=Bread(b, data+i, n)) != n) - sysfatal("short read %d %d", n, m); - }else{ - o = blk[j++]; - copy(data+i, data+o, n); - } - i += n; - } - write(out, data, length); - close(in); - close(out); - _exits(0); - return -1; -} diff --git a/sys/lib/dist/cmd/bzfs/unbzip.c b/sys/lib/dist/cmd/bzfs/unbzip.c deleted file mode 100644 index 070e7ba48..000000000 --- a/sys/lib/dist/cmd/bzfs/unbzip.c +++ /dev/null @@ -1,861 +0,0 @@ -#include -#include -#include -#include "bzfs.h" - -/* - * THIS FILE IS NOT IDENTICAL TO THE ORIGINAL - * FROM THE BZIP2 DISTRIBUTION. - * - * It has been modified, mainly to break the library - * into smaller pieces. - * - * Russ Cox - * rsc@plan9.bell-labs.com - * July 2000 - */ - -/*---------------------------------------------*/ -/*-- - Place a 1 beside your platform, and 0 elsewhere. - Attempts to autosniff this even if you don't. ---*/ - - -/*-- - Plan 9 from Bell Labs ---*/ -#define BZ_PLAN9 1 -#define BZ_UNIX 0 - -#define exit(x) exits((x) ? "whoops" : nil) -#define size_t ulong - -#ifdef __GNUC__ -# define NORETURN __attribute__ ((noreturn)) -#else -# define NORETURN /**/ -#endif - -/*-- - Some more stuff for all platforms :-) - This might have to get moved into the platform-specific - header files if we encounter a machine with different sizes. ---*/ - -typedef char Char; -typedef unsigned char Bool; -typedef unsigned char UChar; -typedef int Int32; -typedef unsigned int UInt32; -typedef short Int16; -typedef unsigned short UInt16; - -#define True ((Bool)1) -#define False ((Bool)0) - -/*-- - IntNative is your platform's `native' int size. - Only here to avoid probs with 64-bit platforms. ---*/ -typedef int IntNative; - -#include "bzfs.h" -#include "bzlib.h" -#include "bzlib_private.h" - -static int -bunzip(int ofd, char *ofile, Biobuf *bin) -{ - int e, n, done, onemore; - char buf[8192]; - char obuf[8192]; - Biobuf bout; - bz_stream strm; - - USED(ofile); - - memset(&strm, 0, sizeof strm); - BZ2_bzDecompressInit(&strm, 0, 0); - - strm.next_in = buf; - strm.avail_in = 0; - strm.next_out = obuf; - strm.avail_out = sizeof obuf; - - done = 0; - Binit(&bout, ofd, OWRITE); - - /* - * onemore is a crummy hack to go 'round the loop - * once after we finish, to flush the output buffer. - */ - onemore = 1; - SET(e); - do { - if(!done && strm.avail_in < sizeof buf) { - if(strm.avail_in) - memmove(buf, strm.next_in, strm.avail_in); - - n = Bread(bin, buf+strm.avail_in, sizeof(buf)-strm.avail_in); - if(n <= 0) - done = 1; - else - strm.avail_in += n; - strm.next_in = buf; - } - if(strm.avail_out < sizeof obuf) { - Bwrite(&bout, obuf, sizeof(obuf)-strm.avail_out); - strm.next_out = obuf; - strm.avail_out = sizeof obuf; - } - - if(onemore == 0) - break; - } while((e=BZ2_bzDecompress(&strm)) == BZ_OK || onemore--); - - if(e != BZ_STREAM_END) { - fprint(2, "bunzip2: decompress failed\n"); - return 0; - } - - if(BZ2_bzDecompressEnd(&strm) != BZ_OK) { - fprint(2, "bunzip2: decompress end failed (can't happen)\n"); - return 0; - } - - Bterm(&bout); - - return 1; -} - -void -_unbzip(int in, int out) -{ - Biobuf bin; - - Binit(&bin, in, OREAD); - if(bunzip(out, nil, &bin) != 1) { - fprint(2, "bunzip2 failed\n"); - _exits("bunzip2"); - } -} - -int -unbzip(int in) -{ - int rv, out, p[2]; - - if(pipe(p) < 0) - sysfatal("pipe: %r"); - - rv = p[0]; - out = p[1]; - switch(rfork(RFPROC|RFFDG|RFNOTEG|RFMEM)){ - case -1: - sysfatal("fork: %r"); - case 0: - close(rv); - break; - default: - close(in); - close(out); - return rv; - } - - _unbzip(in, out); - _exits(0); - return -1; /* not reached */ -} - -int bz_config_ok ( void ) -{ - if (sizeof(int) != 4) return 0; - if (sizeof(short) != 2) return 0; - if (sizeof(char) != 1) return 0; - return 1; -} - -void* default_bzalloc(void *o, int items, int size) -{ - USED(o); - return sbrk(items*size); -} - -void default_bzfree(void*, void*) -{ -} - -void -bz_internal_error(int) -{ - abort(); -} - -/*-------------------------------------------------------------*/ -/*--- Decompression machinery ---*/ -/*--- decompress.c ---*/ -/*-------------------------------------------------------------*/ - -/*-- - This file is a part of bzip2 and/or libbzip2, a program and - library for lossless, block-sorting data compression. - - Copyright (C) 1996-2000 Julian R Seward. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - 3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - Julian Seward, Cambridge, UK. - jseward@acm.org - bzip2/libbzip2 version 1.0 of 21 March 2000 - - This program is based on (at least) the work of: - Mike Burrows - David Wheeler - Peter Fenwick - Alistair Moffat - Radford Neal - Ian H. Witten - Robert Sedgewick - Jon L. Bentley - - For more information on these sources, see the manual. ---*/ - - - -/*---------------------------------------------------*/ -static -void makeMaps_d ( DState* s ) -{ - Int32 i; - s->nInUse = 0; - for (i = 0; i < 256; i++) - if (s->inUse[i]) { - s->seqToUnseq[s->nInUse] = i; - s->nInUse++; - } -} - - -/*---------------------------------------------------*/ -#define RETURN(rrr) \ - { retVal = rrr; goto save_state_and_return; }; - -#define GET_BITS(lll,vvv,nnn) \ - case lll: \ - { int x; if((retVal = getbits(s, lll, &x, nnn)) != 99) \ - goto save_state_and_return; vvv=x; }\ - -int -getbits(DState *s, int lll, int *vvv, int nnn) -{ - s->state = lll; - - for(;;) { - if (s->bsLive >= nnn) { - UInt32 v; - v = (s->bsBuff >> - (s->bsLive-nnn)) & ((1 << nnn)-1); - s->bsLive -= nnn; - *vvv = v; - return 99; - } - if (s->strm->avail_in == 0) return BZ_OK; - s->bsBuff - = (s->bsBuff << 8) | - ((UInt32) - (*((UChar*)(s->strm->next_in)))); - s->bsLive += 8; - s->strm->next_in++; - s->strm->avail_in--; - s->strm->total_in_lo32++; - if (s->strm->total_in_lo32 == 0) - s->strm->total_in_hi32++; - } - return -1; /* KEN */ -} - -#define GET_UCHAR(lll,uuu) \ - GET_BITS(lll,uuu,8) - -#define GET_BIT(lll,uuu) \ - GET_BITS(lll,uuu,1) - -/*---------------------------------------------------*/ -#define GET_MTF_VAL(label1,label2,lval) \ -{ \ - if (groupPos == 0) { \ - groupNo++; \ - if (groupNo >= nSelectors) \ - RETURN(BZ_DATA_ERROR); \ - groupPos = BZ_G_SIZE; \ - gSel = s->selector[groupNo]; \ - gMinlen = s->minLens[gSel]; \ - gLimit = &(s->limit[gSel][0]); \ - gPerm = &(s->perm[gSel][0]); \ - gBase = &(s->base[gSel][0]); \ - } \ - groupPos--; \ - zn = gMinlen; \ - GET_BITS(label1, zvec, zn); \ - while (1) { \ - if (zn > 20 /* the longest code */) \ - RETURN(BZ_DATA_ERROR); \ - if (zvec <= gLimit[zn]) break; \ - zn++; \ - GET_BIT(label2, zj); \ - zvec = (zvec << 1) | zj; \ - }; \ - if (zvec - gBase[zn] < 0 \ - || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \ - RETURN(BZ_DATA_ERROR); \ - lval = gPerm[zvec - gBase[zn]]; \ -} - - -/*---------------------------------------------------*/ -Int32 BZ2_decompress ( DState* s ) -{ - UChar uc; - Int32 retVal; - Int32 minLen, maxLen; - bz_stream* strm = s->strm; - - /* stuff that needs to be saved/restored */ - Int32 i; - Int32 j; - Int32 t; - Int32 alphaSize; - Int32 nGroups; - Int32 nSelectors; - Int32 EOB; - Int32 groupNo; - Int32 groupPos; - Int32 nextSym; - Int32 nblockMAX; - Int32 nblock; - Int32 es; - Int32 N; - Int32 curr; - Int32 zt; - Int32 zn; - Int32 zvec; - Int32 zj; - Int32 gSel; - Int32 gMinlen; - Int32* gLimit; - Int32* gBase; - Int32* gPerm; - - if (s->state == BZ_X_MAGIC_1) { - /*initialise the save area*/ - s->save_i = 0; - s->save_j = 0; - s->save_t = 0; - s->save_alphaSize = 0; - s->save_nGroups = 0; - s->save_nSelectors = 0; - s->save_EOB = 0; - s->save_groupNo = 0; - s->save_groupPos = 0; - s->save_nextSym = 0; - s->save_nblockMAX = 0; - s->save_nblock = 0; - s->save_es = 0; - s->save_N = 0; - s->save_curr = 0; - s->save_zt = 0; - s->save_zn = 0; - s->save_zvec = 0; - s->save_zj = 0; - s->save_gSel = 0; - s->save_gMinlen = 0; - s->save_gLimit = NULL; - s->save_gBase = NULL; - s->save_gPerm = NULL; - } - - /*restore from the save area*/ - i = s->save_i; - j = s->save_j; - t = s->save_t; - alphaSize = s->save_alphaSize; - nGroups = s->save_nGroups; - nSelectors = s->save_nSelectors; - EOB = s->save_EOB; - groupNo = s->save_groupNo; - groupPos = s->save_groupPos; - nextSym = s->save_nextSym; - nblockMAX = s->save_nblockMAX; - nblock = s->save_nblock; - es = s->save_es; - N = s->save_N; - curr = s->save_curr; - zt = s->save_zt; - zn = s->save_zn; - zvec = s->save_zvec; - zj = s->save_zj; - gSel = s->save_gSel; - gMinlen = s->save_gMinlen; - gLimit = s->save_gLimit; - gBase = s->save_gBase; - gPerm = s->save_gPerm; - - retVal = BZ_OK; - - switch (s->state) { - - GET_UCHAR(BZ_X_MAGIC_1, uc); - if (uc != 'B') RETURN(BZ_DATA_ERROR_MAGIC); - - GET_UCHAR(BZ_X_MAGIC_2, uc); - if (uc != 'Z') RETURN(BZ_DATA_ERROR_MAGIC); - - GET_UCHAR(BZ_X_MAGIC_3, uc) - if (uc != 'h') RETURN(BZ_DATA_ERROR_MAGIC); - - GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8) - if (s->blockSize100k < '1' || - s->blockSize100k > '9') RETURN(BZ_DATA_ERROR_MAGIC); - s->blockSize100k -= '0'; - - if (0 && s->smallDecompress) { - s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) ); - s->ll4 = BZALLOC( - ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) - ); - if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR); - } else { - s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) ); - if (s->tt == NULL) RETURN(BZ_MEM_ERROR); - } - - GET_UCHAR(BZ_X_BLKHDR_1, uc); - - if (uc == 0x17) goto endhdr_2; - if (uc != 0x31) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_2, uc); - if (uc != 0x41) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_3, uc); - if (uc != 0x59) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_4, uc); - if (uc != 0x26) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_5, uc); - if (uc != 0x53) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_6, uc); - if (uc != 0x59) RETURN(BZ_DATA_ERROR); - - s->currBlockNo++; - // if (s->verbosity >= 2) - // VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo ); - - s->storedBlockCRC = 0; - GET_UCHAR(BZ_X_BCRC_1, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_2, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_3, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_4, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - - GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1); - - s->origPtr = 0; - GET_UCHAR(BZ_X_ORIGPTR_1, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - GET_UCHAR(BZ_X_ORIGPTR_2, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - GET_UCHAR(BZ_X_ORIGPTR_3, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - - if (s->origPtr < 0) - RETURN(BZ_DATA_ERROR); - if (s->origPtr > 10 + 100000*s->blockSize100k) - RETURN(BZ_DATA_ERROR); - - /*--- Receive the mapping table ---*/ - for (i = 0; i < 16; i++) { - GET_BIT(BZ_X_MAPPING_1, uc); - if (uc == 1) - s->inUse16[i] = True; else - s->inUse16[i] = False; - } - - for (i = 0; i < 256; i++) s->inUse[i] = False; - - for (i = 0; i < 16; i++) - if (s->inUse16[i]) - for (j = 0; j < 16; j++) { - GET_BIT(BZ_X_MAPPING_2, uc); - if (uc == 1) s->inUse[i * 16 + j] = True; - } - makeMaps_d ( s ); - if (s->nInUse == 0) RETURN(BZ_DATA_ERROR); - alphaSize = s->nInUse+2; - - /*--- Now the selectors ---*/ - GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); - if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR); - GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); - if (nSelectors < 1) RETURN(BZ_DATA_ERROR); - for (i = 0; i < nSelectors; i++) { - j = 0; - while (True) { - GET_BIT(BZ_X_SELECTOR_3, uc); - if (uc == 0) break; - j++; - if (j >= nGroups) RETURN(BZ_DATA_ERROR); - } - s->selectorMtf[i] = j; - } - - /*--- Undo the MTF values for the selectors. ---*/ - { - UChar pos[BZ_N_GROUPS], tmp, v; - for (v = 0; v < nGroups; v++) pos[v] = v; - - for (i = 0; i < nSelectors; i++) { - v = s->selectorMtf[i]; - tmp = pos[v]; - while (v > 0) { pos[v] = pos[v-1]; v--; } - pos[0] = tmp; - s->selector[i] = tmp; - } - } - - /*--- Now the coding tables ---*/ - for (t = 0; t < nGroups; t++) { - GET_BITS(BZ_X_CODING_1, curr, 5); - for (i = 0; i < alphaSize; i++) { - while (True) { - if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR); - GET_BIT(BZ_X_CODING_2, uc); - if (uc == 0) break; - GET_BIT(BZ_X_CODING_3, uc); - if (uc == 0) curr++; else curr--; - } - s->len[t][i] = curr; - } - } - - /*--- Create the Huffman decoding tables ---*/ - for (t = 0; t < nGroups; t++) { - minLen = 32; - maxLen = 0; - for (i = 0; i < alphaSize; i++) { - if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; - if (s->len[t][i] < minLen) minLen = s->len[t][i]; - } - BZ2_hbCreateDecodeTables ( - &(s->limit[t][0]), - &(s->base[t][0]), - &(s->perm[t][0]), - &(s->len[t][0]), - minLen, maxLen, alphaSize - ); - s->minLens[t] = minLen; - } - - /*--- Now the MTF values ---*/ - - EOB = s->nInUse+1; - nblockMAX = 100000 * s->blockSize100k; - groupNo = -1; - groupPos = 0; - - for (i = 0; i <= 255; i++) s->unzftab[i] = 0; - - /*-- MTF init --*/ - { - Int32 ii, jj, kk; - kk = MTFA_SIZE-1; - for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) { - for (jj = MTFL_SIZE-1; jj >= 0; jj--) { - s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj); - kk--; - } - s->mtfbase[ii] = kk + 1; - } - } - /*-- end MTF init --*/ - - nblock = 0; - GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); - - while (True) { - - if (nextSym == EOB) break; - - if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) { - - es = -1; - N = 1; - do { - if (nextSym == BZ_RUNA) es = es + (0+1) * N; else - if (nextSym == BZ_RUNB) es = es + (1+1) * N; - N = N * 2; - GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym); - } - while (nextSym == BZ_RUNA || nextSym == BZ_RUNB); - - es++; - uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ]; - s->unzftab[uc] += es; - - if (0 && s->smallDecompress) - while (es > 0) { - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - s->ll16[nblock] = (UInt16)uc; - nblock++; - es--; - } - else - while (es > 0) { - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - s->tt[nblock] = (UInt32)uc; - nblock++; - es--; - }; - - continue; - - } else { - - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - - /*-- uc = MTF ( nextSym-1 ) --*/ - { - Int32 ii, jj, kk, pp, lno, off; - UInt32 nn; - nn = (UInt32)(nextSym - 1); - - if (nn < MTFL_SIZE) { - /* avoid general-case expense */ - pp = s->mtfbase[0]; - uc = s->mtfa[pp+nn]; - while (nn > 3) { - Int32 z = pp+nn; - s->mtfa[(z) ] = s->mtfa[(z)-1]; - s->mtfa[(z)-1] = s->mtfa[(z)-2]; - s->mtfa[(z)-2] = s->mtfa[(z)-3]; - s->mtfa[(z)-3] = s->mtfa[(z)-4]; - nn -= 4; - } - while (nn > 0) { - s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; - }; - s->mtfa[pp] = uc; - } else { - /* general case */ - lno = nn / MTFL_SIZE; - off = nn % MTFL_SIZE; - pp = s->mtfbase[lno] + off; - uc = s->mtfa[pp]; - while (pp > s->mtfbase[lno]) { - s->mtfa[pp] = s->mtfa[pp-1]; pp--; - }; - s->mtfbase[lno]++; - while (lno > 0) { - s->mtfbase[lno]--; - s->mtfa[s->mtfbase[lno]] - = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1]; - lno--; - } - s->mtfbase[0]--; - s->mtfa[s->mtfbase[0]] = uc; - if (s->mtfbase[0] == 0) { - kk = MTFA_SIZE-1; - for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) { - for (jj = MTFL_SIZE-1; jj >= 0; jj--) { - s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj]; - kk--; - } - s->mtfbase[ii] = kk + 1; - } - } - } - } - /*-- end uc = MTF ( nextSym-1 ) --*/ - - s->unzftab[s->seqToUnseq[uc]]++; - if (0 && s->smallDecompress) - s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else - s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]); - nblock++; - - GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym); - continue; - } - } - - /* Now we know what nblock is, we can do a better sanity - check on s->origPtr. - */ - if (s->origPtr < 0 || s->origPtr >= nblock) - RETURN(BZ_DATA_ERROR); - - s->state_out_len = 0; - s->state_out_ch = 0; - BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); - s->state = BZ_X_OUTPUT; - // if (s->verbosity >= 2) VPrintf0 ( "rt+rld" ); - - /*-- Set up cftab to facilitate generation of T^(-1) --*/ - s->cftab[0] = 0; - for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1]; - for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1]; - - if (0 && s->smallDecompress) { - - /*-- Make a copy of cftab, used in generation of T --*/ - for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i]; - - /*-- compute the T vector --*/ - for (i = 0; i < nblock; i++) { - uc = (UChar)(s->ll16[i]); - SET_LL(i, s->cftabCopy[uc]); - s->cftabCopy[uc]++; - } - - /*-- Compute T^(-1) by pointer reversal on T --*/ - i = s->origPtr; - j = GET_LL(i); - do { - Int32 tmp = GET_LL(j); - SET_LL(j, i); - i = j; - j = tmp; - } - while (i != s->origPtr); - - s->tPos = s->origPtr; - s->nblock_used = 0; - if (s->blockRandomised) { - BZ_RAND_INIT_MASK; - BZ_GET_SMALL(s->k0); s->nblock_used++; - BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; - } else { - BZ_GET_SMALL(s->k0); s->nblock_used++; - } - - } else { - - /*-- compute the T^(-1) vector --*/ - for (i = 0; i < nblock; i++) { - uc = (UChar)(s->tt[i] & 0xff); - s->tt[s->cftab[uc]] |= (i << 8); - s->cftab[uc]++; - } - - s->tPos = s->tt[s->origPtr] >> 8; - s->nblock_used = 0; - if (s->blockRandomised) { - BZ_RAND_INIT_MASK; - BZ_GET_FAST(s->k0); s->nblock_used++; - BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; - } else { - BZ_GET_FAST(s->k0); s->nblock_used++; - } - - } - - RETURN(BZ_OK); - - - - endhdr_2: - - GET_UCHAR(BZ_X_ENDHDR_2, uc); - if (uc != 0x72) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_3, uc); - if (uc != 0x45) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_4, uc); - if (uc != 0x38) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_5, uc); - if (uc != 0x50) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_6, uc); - if (uc != 0x90) RETURN(BZ_DATA_ERROR); - - s->storedCombinedCRC = 0; - GET_UCHAR(BZ_X_CCRC_1, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_2, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_3, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_4, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - - s->state = BZ_X_IDLE; - RETURN(BZ_STREAM_END); - - default: AssertH ( False, 4001 ); - } - - AssertH ( False, 4002 ); - - save_state_and_return: - - s->save_i = i; - s->save_j = j; - s->save_t = t; - s->save_alphaSize = alphaSize; - s->save_nGroups = nGroups; - s->save_nSelectors = nSelectors; - s->save_EOB = EOB; - s->save_groupNo = groupNo; - s->save_groupPos = groupPos; - s->save_nextSym = nextSym; - s->save_nblockMAX = nblockMAX; - s->save_nblock = nblock; - s->save_es = es; - s->save_N = N; - s->save_curr = curr; - s->save_zt = zt; - s->save_zn = zn; - s->save_zvec = zvec; - s->save_zj = zj; - s->save_gSel = gSel; - s->save_gMinlen = gMinlen; - s->save_gLimit = gLimit; - s->save_gBase = gBase; - s->save_gPerm = gPerm; - - return retVal; -} - - -/*-------------------------------------------------------------*/ -/*--- end decompress.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/sys/lib/dist/cmd/cdsh.c b/sys/lib/dist/cmd/cdsh.c deleted file mode 100644 index 2162350bf..000000000 --- a/sys/lib/dist/cmd/cdsh.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * The `cd' shell. - * Just has cd and lc. - */ - -#include -#include -#include - -char *pwd; -char *root = "/"; - -void -usage(void) -{ - fprint(2, "usage: cdsh [-r root]\n"); - exits("usage"); -} - -int -system(char *cmd) -{ - int pid; - if((pid = fork()) < 0) - return -1; - - if(pid == 0) { - dup(2, 1); - execl("/bin/rc", "rc", "-c", cmd, nil); - exits("exec"); - } - waitpid(); - return 0; -} - -int -cd(char *s) -{ - char *newpwd; - int l; - - if(s[0] == '/') { - cleanname(s); - newpwd = strdup(s); - } else { - l = strlen(pwd)+1+strlen(s)+1+50; /* 50 = crud for unicode mistakes */ - newpwd = malloc(l); - snprint(newpwd, l, "%s/%s", pwd, s); - cleanname(newpwd); - assert(newpwd[0] == '/'); - } - - if(chdir(root) < 0 || (newpwd[1] != '\0' && chdir(newpwd+1) < 0)) { - chdir(root); - chdir(pwd+1); - free(newpwd); - return -1; - } else { - free(pwd); - pwd = newpwd; - return 0; - } -} - -void -main(int argc, char **argv) -{ - char *p; - Biobuf bin; - char *f[2]; - int nf; - - ARGBEGIN{ - case 'r': - root = ARGF(); - if(root == nil) - usage(); - if(root[0] != '/') { - fprint(2, "root must be rooted\n"); - exits("root"); - } - break; - default: - usage(); - }ARGEND; - - if(argc != 0) - usage(); - - cleanname(root); - if(cd("/") < 0) { - fprint(2, "cannot cd %s: %r\n", root); - exits("root"); - } - - Binit(&bin, 0, OREAD); - while(fprint(2, "%s%% ", pwd), (p = Brdline(&bin, '\n'))) { - p[Blinelen(&bin)-1] = '\0'; - nf = tokenize(p, f, nelem(f)); - if(nf < 1) - continue; - if(strcmp(f[0], "exit") == 0) - break; - if(strcmp(f[0], "lc") == 0) { - if(nf == 1) { - if(system("/bin/lc") < 0) - fprint(2, "lc: %r\n"); - } else if(nf == 2) { - if(strpbrk(p, "'`{}^@$#&()|\\;><")) - fprint(2, "no shell characters allowed\n"); - else { - p = f[1]; - *--p = ' '; - *--p = 'c'; - *--p = 'l'; - if(system(p) < 0) - fprint(2, "lc: %r\n"); - } - } - continue; - } - if(strcmp(f[0], "cd") == 0) { - if(nf < 2) - fprint(2, "usage: cd dir\n"); - else if(cd(f[1]) < 0) - fprint(2, "cd: %r\n"); - continue; - } - fprint(2, "commands are cd, lc, and exit\n"); - } - - print("%s\n", pwd); -} diff --git a/sys/lib/dist/cmd/clog.c b/sys/lib/dist/cmd/clog.c deleted file mode 100644 index 98d1cf5f5..000000000 --- a/sys/lib/dist/cmd/clog.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include - -char *argv0; - -int -openlog(char *name) -{ - int fd; - - fd = open(name, OWRITE); - if(fd < 0){ - fprint(2, "%s: can't open %s: %r\n", argv0, name); - return -1; - } - seek(fd, 0, 2); - return fd; -} - -void -main(int argc, char **argv) -{ - Biobuf in; - int fd; - char *p, *t; - char buf[8192]; - - argv0 = argv[0]; - if(argc != 4){ - fprint(2, "usage: %s console logfile prefix\n", argv0); - exits("usage"); - } - - fd = open(argv[1], OREAD); - if(fd < 0){ - fprint(2, "%s: can't open %s: %r\n", argv0, argv[1]); - exits("open"); - } - Binit(&in, fd, OREAD); - - fd = openlog(argv[2]); - - for(;;){ - if(p = Brdline(&in, '\n')){ - p[Blinelen(&in)-1] = 0; - if(fprint(fd, "%s: %s\n", argv[3], p) < 0){ - close(fd); - fd = openlog(argv[2]); - fprint(fd, "%s: %s\n", t, p); - } - } else if(Blinelen(&in) == 0) // true eof - break; - else { - Bread(&in, buf, sizeof buf); - } - } - exits(0); -} diff --git a/sys/lib/dist/cmd/mkfile b/sys/lib/dist/cmd/mkfile deleted file mode 100644 index bbcd1351c..000000000 --- a/sys/lib/dist/cmd/mkfile +++ /dev/null @@ -1,24 +0,0 @@ ->../../pc/multi/$b - chmod +x ../../pc/multi/$b - } - -BIN=/sys/lib/dist/bin/$objtype -multi.h ->multiproto.h - -for(i){ -echo $i... - b=`{basename $i} - p=$b - if(~ $b [0-9]*) - p=_$b - echo void $p^_main'(int, char**);' >>$dir/multiproto.h - echo "$b", $p^_main, >>$dir/multi.h - d=`{basename -d $i} - if(~ $i disk/prep disk/fdisk){ - cd /sys/src/cmd/disk/prep - rm 8.$b - files=`{mk 8.$b | getfiles} - } - if not if(test -d /sys/src/cmd/$i && @{cd /sys/src/cmd/$i && mk 8.out}){ - cd /sys/src/cmd/$i - rm 8.out - files=`{mk 8.out | getfiles} - } - if not if(test -d /sys/src/cmd/$i && @{cd /sys/src/cmd/$i && mk 8.$b}){ - cd /sys/src/cmd/$i - rm 8.out - files=`{mk 8.$b | getfiles} - } - if not if(test -d /sys/src/cmd/$d && @{cd /sys/src/cmd/$d && mk 8.$b}){ - cd /sys/src/cmd/$d - rm 8.$b - files=`{mk 8.$b | getfiles} - } - if not{ - echo do not know how to make $i - exit oops - } - aux/8prefix $p^_ $files - grab $files - switch(`{pwd}){ - case /sys/src/cmd /sys/src/cmd/aux /sys/src/cmd/ip - rm 8.$b - case * - mk clean - } -} -cd $dir -8c -FVw multi.c -8l -o 8.$targ multi.8 a.*.8 -# rm a.*.8 diff --git a/sys/lib/dist/cmd/multi/multi.c b/sys/lib/dist/cmd/multi/multi.c deleted file mode 100644 index a2e3035ad..000000000 --- a/sys/lib/dist/cmd/multi/multi.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include - -#include "multiproto.h" -struct { - char *name; - void (*fn)(int, char**); -} mains[] = -{ -#include "multi.h" -}; - -void -main(int argc, char **argv) -{ - int i; - char *cmd, *p; - - if(argc == 1){ - fprint(2, "usage: multi cmd args...\n"); - exits("usage"); - } - - cmd = argv[1]; - if(p = strrchr(cmd, '/')) - cmd = p+1; - argv++; - argc--; - - for(i=0; i -#include - -void -main(void) -{ - int fd, p[2]; - char buf[8192], n; - - pipe(p); - fd = create("/srv/log", OWRITE, 0666); - fprint(fd, "%d", p[0]); - close(fd); - close(p[0]); - while((n = read(p[1], buf, sizeof buf)) >= 0) - write(1, buf, n); -} diff --git a/sys/lib/dist/cmd/touchfs.c b/sys/lib/dist/cmd/touchfs.c deleted file mode 100644 index 00fadf3f4..000000000 --- a/sys/lib/dist/cmd/touchfs.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include - -void -Bpass(Biobuf *bin, Biobuf *bout, int n) -{ - char buf[8192]; - int m; - - while(n > 0) { - m = sizeof buf; - if(m > n) - m = n; - m = Bread(bin, buf, m); - if(m <= 0) { - fprint(2, "corrupt archive\n"); - exits("notdone"); - } - Bwrite(bout, buf, m); - n -= m; - } - assert(n == 0); -} - -void -main(int argc, char **argv) -{ - char *p, *f[10]; - Biobuf bin, bout; - int nf; - ulong d, size; - - if(argc != 2) { - fprint(2, "usage: cat mkfs-archive | touchfs date (in seconds)\n"); - exits("usage"); - } - - d = strtoul(argv[1], 0, 0); - - quotefmtinstall(); - Binit(&bin, 0, OREAD); - Binit(&bout, 1, OWRITE); - - while(p = Brdline(&bin, '\n')) { - p[Blinelen(&bin)-1] = '\0'; - if(strcmp(p, "end of archive") == 0) { - Bprint(&bout, "end of archive\n"); - exits(0); - } - - nf = tokenize(p, f, nelem(f)); - if(nf != 6) { - fprint(2, "corrupt archive\n"); - exits("notdone"); - } - - Bprint(&bout, "%q %q %q %q %lud %q\n", - f[0], f[1], f[2], f[3], d, f[5]); - - size = strtoul(f[5], 0, 0); - Bpass(&bin, &bout, size); - } - fprint(2, "premature end of archive\n"); - exits("notdone"); -} diff --git a/sys/lib/dist/cmd/unbflz.c b/sys/lib/dist/cmd/unbflz.c deleted file mode 100644 index 5ddb821f9..000000000 --- a/sys/lib/dist/cmd/unbflz.c +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include -#include - -void -usage(void) -{ - fprint(2, "usage: unbflz [file]\n"); - exits("usage"); -} - -int -Bgetint(Biobuf *b) -{ - uchar p[4]; - - if(Bread(b, p, 4) != 4) - sysfatal("short read"); - return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3]; -} - -/* - * memmove but make sure overlap works properly. - */ -void -copy(uchar *dst, uchar *src, int n) -{ - while(n-- > 0) - *dst++ = *src++; -} - -void -main(int argc, char **argv) -{ - Biobuf *b, bin; - char buf[5]; - uchar *data; - ulong *blk, l; - int nblk, mblk; - int sum; - int i, j, length, m, n, o; - - ARGBEGIN{ - default: - usage(); - }ARGEND - - switch(argc){ - default: - usage(); - case 0: - Binit(&bin, 0, OREAD); - b = &bin; - break; - case 1: - if((b = Bopen(argv[0], OREAD)) == nil) - sysfatal("open %s: %r", argv[0]); - break; - } - - if(Bread(b, buf, 4) != 4) - sysfatal("short read"); - - if(memcmp(buf, "BLZ\n", 4) != 0) - sysfatal("bad header"); - - length = Bgetint(b); - data = malloc(length); - if(data == nil) - sysfatal("out of memory"); - sum = 0; - nblk = 0; - mblk = 0; - blk = nil; - while(sum < length){ - if(nblk>=mblk){ - mblk += 16384; - blk = realloc(blk, (mblk+1)*sizeof(blk[0])); - if(blk == nil) - sysfatal("out of memory"); - } - l = Bgetint(b); - blk[nblk++] = l; - if(l&(1<<31)) - l &= ~(1<<31); - else - blk[nblk++] = Bgetint(b); - sum += l; - } - if(sum != length) - sysfatal("bad compressed data %d %d", sum, length); - i = 0; - j = 0; - while(i < length){ - assert(j < nblk); - n = blk[j++]; - if(n&(1<<31)){ - n &= ~(1<<31); - if((m=Bread(b, data+i, n)) != n) - sysfatal("short read %d %d", n, m); - }else{ - o = blk[j++]; - copy(data+i, data+o, n); - } - i += n; - } - write(1, data, length); - exits(nil); -} diff --git a/sys/lib/dist/logcompress.awk b/sys/lib/dist/logcompress.awk deleted file mode 100644 index 3267a48f7..000000000 --- a/sys/lib/dist/logcompress.awk +++ /dev/null @@ -1,15 +0,0 @@ -{ - verb[$4] = $3 - data[$4] = sprintf("%s %s %s %s %s %s", $5, $6, $7, $8, $9, $10) -} - -END{ - for(i in verb) - if(verb[i] != "d") - printf("a %s %s\n", i, data[i]) |"sort +1" - close("sort +1") - for(i in verb) - if(verb[i] == "d") - printf("d %s %s\n", i, data[i]) |"sort -r +1" - close("sort -r +1") -} diff --git a/sys/lib/dist/logtime.awk b/sys/lib/dist/logtime.awk deleted file mode 100644 index f974f8db6..000000000 --- a/sys/lib/dist/logtime.awk +++ /dev/null @@ -1,3 +0,0 @@ -{ - printf("%s %d %s\n", t, NR, $0); -} diff --git a/sys/lib/dist/mkfile b/sys/lib/dist/mkfile index 98dcd8fee..9fa156194 100644 --- a/sys/lib/dist/mkfile +++ b/sys/lib/dist/mkfile @@ -1,221 +1,21 @@ -# /sys/lib/dist/mkfile -src9=/n/sources/plan9 # what to export -dist=/sys/lib/dist # where this machinery lives -scr=/n/other/dist # scratch space before copying to web.protect -# import /sys/lib/dist/web.protect from the outside -x=`{setup} +src9=/n/src9 +scr=/tmp/dist -cd:V: $scr/plan9.iso - -ncd:V: $scr/plan9-new.iso.bz2 - -ncd-dist:V: $scr/plan9-new.iso.bz2 - mk $dist/web.protect/plan9-new.iso.bz2 - -cd-dist:V: $scr/plan9.iso.bz2 - mk $dist/web.protect/plan9.iso.bz2 - -contrib-cd:V: $scr/contrib.iso.bz2 - mk $dist/web.protect/contrib.iso.bz2 - -$scr/%.iso:D: $src9/dist/replica/plan9.log - @ { cd pc; mk cddisk } - rm -f $target - bind pc/cddisk cdstub/bootdisk.img - if(! test -f $src9/bootdisk.img) - bind -a cdstub $src9 - title=`{date | sed 's/(...) (...) (..) (..:..):.. (...) (....)/Plan 9 - \2 \3 \6 \4/'} - title=$"title - echo 'CD:' $title - disk/mk9660 -9cj -v $title -s $src9 -b bootdisk.img $target - -# copy compressed file from scratch space to the distribution, carefully -$dist/web.protect/%.iso.bz2: $scr/%.iso.bz2 - >>$target.new - chmod +t $target.new # waste write buf, not venti store - cp $prereq $target.new - # replace previous version with a flash cut - if (test -e $target) - mv $target $target.old # try to not clobber downloads in progress - mv $target.new $target - -cd-cleanup:V: - rm -f $dist/web.protect/*.iso.bz2.old # remove old versions after a delay - -# generate replica log & db for $src9 only -scan:V: - test -d $scr # make sure other was mounted above - test -d $src9 - test -d $dist/web.protect - lock scan.lock replica/scan $dist/sources.replica - chmod +t $src9/dist/replica/*.^(db log) - -# generate replica log & db for all of /n/sources -scanall:V: - @ { - rfork ne - d=/n/sources - test -d $src9 - lock scanall.lock replica/scan $dist/sourcesall.replica - chmod +t $src9/dist/replica/*.^(db log) - } - -compresslog:V: - { - awk -f logcompress.awk $src9/dist/replica/plan9.log | - awk -f logtime.awk -v 't='^`{date -n} >/tmp/plan9.log - rm -f $src9/dist/replica/plan9.new.log - cp /tmp/plan9.log $src9/dist/replica/plan9.new.log && - mv $src9/dist/replica/plan9.new.log $src9/dist/replica/plan9.log - } $src9/dist/replica/plan9.db -# chmod 664 $src9/dist/replica/plan9.log >$src9/dist/replica/plan9.log -# chmod +a $src9/dist/replica/plan9.log -# mk scan - -odump:V: - disk/dump9660 -9cj -v 'Plan 9 4e Dumps' -s $src9 \ - -p /sys/lib/sysconfig/proto/allproto $scr/distdump.iso - -cd.install:V: -# if(~ $sysname achille){ -# echo; echo; echo '*** run this on a real machine, like chips.' -# exit bad -# } - bzip2 -9 <$scr/plan9.iso >web.protect/nplan9.iso.bz2 +x=`{mkdir -p $scr} -D.install:V: - D=/n/roro/usr/rob/testplan9 - 9fs roro - test -d $D - cp $D$dist/pc/ndisk $dist/web.protect/ndisk - cp $D$dist/pc/9loaddebug $dist/web.protect/n9loaddebug - -reallyinstall:V: - if(! ~ $sysname achille){ - echo; echo; echo '*** this needs to run on achille.' - exit bad - } - cd web.protect - for (i in plan9.iso.bz2 disk 9loaddebug vmware.zip) - if(test -f n$i){ - mv $i _$i && { mv n$i $i || mv _$i $i } - } - rm /srv/ramfs.9down4e - $dist/startcache - -dump:V: - rm -f /srv/9660.xxx - 9660srv 9660.xxx - mount /srv/9660.xxx /n/kremvax $scr/plan9.iso - now=`{mtime $dist/web.protect/plan9.iso.bz2 | awk '{print $1}'} - ls -l /rls/plan9/4e.iso - disk/dump9660 -9cj -s /n/kremvax -n $now /rls/plan9/4e.iso - ls -l /rls/plan9/4e.iso - rm /srv/9660.xxx - -reencode:V: - rm -f $scr/nplan9.iso - rm -f /srv/9660.xxx - 9660srv 9660.xxx - mount /srv/9660.xxx /n/kremvax $scr/plan9.iso - disk/mk9660 -9cj -v 'Plan 9 4th Edition' -s /n/kremvax \ - -b bootdisk.img $scr/nplan9.iso - rm /srv/9660.xxx - -# compress a cd image in scratch space -$scr/%.iso.bz2:D: $scr/%.iso - @ { - cd $scr - bzip2 -9 <$stem.iso >n$stem.iso.bz2 && - { - if (test -e $stem.iso.bz2) - mv $stem.iso.bz2 _$stem.iso.bz2 - mv n$stem.iso.bz2 $stem.iso.bz2 - } - echo `{date} md5 `{md5sum <$stem.iso.bz2} \ - sha1 `{sha1sum <$stem.iso.bz2} \ - $stem.iso.bz2 >>/usr/web/plan9checksums.txt - } - -$scr/contrib.iso:DV: - rm -f $target - disk/mk9660 -9cj -v 'Plan 9 Extras' -s /n/sources \ - -p ./contrib.proto $target - -rebuild:V: - chmod +l build.lock >>build.lock - rebuild >build.lock - rebuild $target - -9-export:V: 9.tar.gz - 9fs sources - cp 9.tar.gz /n/sources/extra/9.tgz - chmod +t /n/sources/extra/9.tgz - -plan9.tar.bz2:V: - @{ - rfork n - 9fs sources - cd /n/sources - test -e $src9 - bind /n/empty $src9/lib/font - bind /n/empty $src9/sys/lib/postscript/font - bind /n/empty $src9/sys/lib/ghostscript - bind /n/empty $src9/sys/src/cmd/gs - tar c plan9/LICENSE* plan9/NOTICE plan9/*/mkfile plan9/*/include \ - plan9/acme/*/src plan9/acme/bin/source \ - plan9/^(adm cron lib lp mail rc sys tmp usr) - } | bzip2 >$target - -plan9-export:V: plan9.tar.bz2 - 9fs sources - chmod +t plan9.tar.bz2 - mv plan9.tar.bz2 /n/sources/extra/plan9.tar.bz2 +cd:V: $scr/plan9.iso + +clean:V: + rm -rf $scr + +$scr/cdstub:D: $src9/386/9bootiso + mkdir -p $target + cp $prereq $target + cp pc/plan9.ini.cd $target/plan9.ini + +$scr/plan9.iso: $scr/cdstub + bind -a $src9 $scr/cdstub + bind /n/empty $scr/cdstub/.hg + disk/mk9660 -9cj -s $scr/cdstub -B 9bootiso $target + unmount $scr/cdstub/.hg + unmount $scr/cdstub diff --git a/sys/lib/dist/pc/cd0.proto b/sys/lib/dist/pc/cd0.proto deleted file mode 100644 index 62bdb1b10..000000000 --- a/sys/lib/dist/pc/cd0.proto +++ /dev/null @@ -1 +0,0 @@ -cddisk diff --git a/sys/lib/dist/pc/plan9.ini b/sys/lib/dist/pc/plan9.ini index 71f98e5e1..c28f1ce43 100644 --- a/sys/lib/dist/pc/plan9.ini +++ b/sys/lib/dist/pc/plan9.ini @@ -1,15 +1,6 @@ -# config for initial floppy booting - -[menu] -menuitem=boot, Boot Plan 9 -# menuitem=debug, Boot Plan 9 and debug 9load -menudefault=boot, 10 - -[common] # very cautious settings to get started. # will defeat booting from usb devices. *nomp=1 -*nobiosload=1 # *noahciload=1 # *debugload=1 *nodumpstack=1 @@ -22,16 +13,7 @@ mouseport=ask monitor=ask vgasize=ask dmamode=ask -nobootprompt=local!/boot/bzroot -installurl=http://plan9.bell-labs.com/plan9/download/plan9.iso.bz2 # serial console on COM1 #console=0 - -[boot] bootargs=local!#S/sdD0/data -bootfile=sdD0!cdboot!9pccd.gz - -# [debug] -# bootargs=local!#S/sdD0/data -# bootfile=sdD0!cdboot!9pccd.gz -# *debugload=1 +bootfile=/386/9pccd diff --git a/sys/lib/dist/pc/plan9.ini.cd b/sys/lib/dist/pc/plan9.ini.cd index 11a2435ca..de8c1352f 100644 --- a/sys/lib/dist/pc/plan9.ini.cd +++ b/sys/lib/dist/pc/plan9.ini.cd @@ -1,15 +1,7 @@ # config for initial cd booting - -[menu] -menuitem=install, Install Plan 9 from this CD -menuitem=cdboot, Boot Plan 9 from this CD -# menuitem=debug, Boot Plan 9 from this CD and debug 9load - -[common] # very cautious settings to get started. # will defeat booting from usb devices. *nomp=1 -*nobiosload=1 # *noahciload=1 # *debugload=1 *nodumpstack=1 @@ -21,20 +13,9 @@ mouseport=ask monitor=ask vgasize=ask dmamode=ask -adisk=/dev/sdD0/cdboot +adisk=/dev/sdD0/data cdboot=yes # console=0 # baud=9600 - -[install] -nobootprompt=local!/boot/bzroot -bootfile=sdD0!cdboot!9pcflop.gz - -[cdboot] bootargs=local!#S/sdD0/data -bootfile=sdD0!cdboot!9pccd.gz - -# [debug] -# bootargs=local!#S/sdD0/data -# bootfile=sdD0!cdboot!9pccd.gz -# *debugload=1 +bootfile=/386/9pccd diff --git a/sys/lib/dist/setup b/sys/lib/dist/setup deleted file mode 100644 index a1c381bd7..000000000 --- a/sys/lib/dist/setup +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/rc -# setup - prep for the mkfile -9fs sources -9fs other -9fs outfsother -if (test -e /cfg/$sysname/config) - . /cfg/$sysname/config -if not - outip=204.178.31.2 -import -c tcp!$outip!666 $dist/web.protect diff --git a/sys/src/boot/pc/iso.c b/sys/src/boot/pc/iso.c index 9f0d010aa..1d6bea2b7 100644 --- a/sys/src/boot/pc/iso.c +++ b/sys/src/boot/pc/iso.c @@ -71,7 +71,7 @@ close(void *f) static int isowalk(Extend *ex, int drive, char *path) { - char name[Maxpath], pad, *end; + char name[Maxpath], c, *end; int i; Dir d; @@ -97,8 +97,16 @@ isowalk(Extend *ex, int drive, char *path) break; i = d.dirlen - (Dirsz + d.namelen); while(i-- > 0) - read(ex, &pad, 1); - name[d.namelen] = 0; + read(ex, &c, 1); + for(i=0; i= 'A' && c <= 'Z'){ + c -= 'A'; + c += 'a'; + } + name[i] = c; + } + name[i] = 0; while(*path == '/') path++; if((end = strchr(path, '/')) == 0) diff --git a/sys/src/cmd/aux/mkfile b/sys/src/cmd/aux/mkfile index daf2213f6..471e26a92 100644 --- a/sys/src/cmd/aux/mkfile +++ b/sys/src/cmd/aux/mkfile @@ -51,7 +51,8 @@ DIRS=mnihongo\ flashfs\ gps\ na\ - vga + vga\ + realemu all:V: $DIRS diff --git a/sys/src/cmd/aux/realemu/arg.c b/sys/src/cmd/aux/realemu/arg.c new file mode 100644 index 000000000..4a67e864b --- /dev/null +++ b/sys/src/cmd/aux/realemu/arg.c @@ -0,0 +1,163 @@ +#include +#include +#include "dat.h" +#include "fns.h" + +#define ause(cpu) (cpu->abuf + (cpu->iabuf++ % nelem(cpu->abuf))) + +Iarg* +adup(Iarg *x) +{ + Iarg *a; + + a = ause(x->cpu); + *a = *x; + return a; +} + +Iarg* +areg(Cpu *cpu, uchar len, uchar reg) +{ + Iarg *a; + + a = ause(cpu); + a->cpu = cpu; + a->tag = TREG; + a->len = len; + a->reg = reg; + return a; +} + +Iarg* +amem(Cpu *cpu, uchar len, uchar sreg, ulong off) +{ + Iarg *a; + + a = ause(cpu); + a->cpu = cpu; + a->tag = TMEM; + a->len = len; + a->sreg = sreg; + a->seg = cpu->reg[sreg]; + a->off = off; + return a; +} + +Iarg* +afar(Iarg *mem, uchar len, uchar alen) +{ + Iarg *a, *p; + + p = adup(mem); + p->len = alen; + a = amem(mem->cpu, len, R0S, ar(p)); + p->off += alen; + p->len = 2; + a->seg = ar(p); + return a; +} + +Iarg* +acon(Cpu *cpu, uchar len, ulong val) +{ + Iarg *a; + + a = ause(cpu); + a->cpu = cpu; + a->tag = TCON; + a->len = len; + a->val = val; + return a; +} + +ulong +ar(Iarg *a) +{ + ulong w, o; + Bus *io; + + switch(a->tag){ + default: + abort(); + case TMEM: + o = ((a->seg<<4) + (a->off & 0xFFFF)) & 0xFFFFF; + io = a->cpu->mem + (o>>16); + w = io->r(io->aux, o, a->len); + break; + case TREG: + w = a->cpu->reg[a->reg]; + break; + case TREG|TH: + w = a->cpu->reg[a->reg] >> 8; + break; + case TCON: + w = a->val; + break; + } + switch(a->len){ + default: + abort(); + case 1: + w &= 0xFF; + break; + case 2: + w &= 0xFFFF; + break; + case 4: + break; + } + return w; +} + +long +ars(Iarg *a) +{ + ulong w = ar(a); + switch(a->len){ + default: + abort(); + case 1: + return (char)w; + case 2: + return (short)w; + case 4: + return (long)w; + } +} + +void +aw(Iarg *a, ulong w) +{ + ulong *p, o; + Cpu *cpu; + Bus *io; + + cpu = a->cpu; + switch(a->tag){ + default: + abort(); + case TMEM: + o = ((a->seg<<4) + (a->off & 0xFFFF)) & 0xFFFFF; + io = cpu->mem + (o>>16); + io->w(io->aux, o, w, a->len); + break; + case TREG: + p = cpu->reg + a->reg; + switch(a->len){ + case 4: + *p = w; + break; + case 2: + *p = (*p & ~0xFFFF) | (w & 0xFFFF); + break; + case 1: + *p = (*p & ~0xFF) | (w & 0xFF); + break; + } + break; + case TREG|TH: + p = cpu->reg + a->reg; + *p = (*p & ~0xFF00) | (w & 0xFF)<<8; + break; + } +} diff --git a/sys/src/cmd/aux/realemu/dat.h b/sys/src/cmd/aux/realemu/dat.h new file mode 100644 index 000000000..9c8ece20d --- /dev/null +++ b/sys/src/cmd/aux/realemu/dat.h @@ -0,0 +1,362 @@ +typedef struct Iarg Iarg; +typedef struct Inst Inst; +typedef struct Bus Bus; +typedef struct Cpu Cpu; +typedef struct Pit Pit; + +enum { + RAX, + RCX, + RDX, + RBX, + RSP, + RBP, + RSI, + RDI, + + RES, + RCS, + RSS, + RDS, + RFS, + RGS, + + R0S, /* 0 segment */ + + RIP, + RFL, + + NREG, +}; + +struct Iarg +{ + Cpu *cpu; + + uchar tag; + uchar len; + uchar atype; + + union { + uchar reg; + struct { + uchar sreg; + ulong seg, off; + }; + ulong val; + }; +}; + +struct Inst +{ + uchar op; + uchar code; + uchar olen; + uchar alen; + + Iarg *a1, *a2, *a3; + + uchar rep; + + uchar mod; + uchar reg; + uchar rm; + + uchar scale; + uchar index; + uchar base; + + uchar sreg; + uchar dsreg; + + ulong off; + long disp; +}; + +struct Bus +{ + void *aux; + ulong (*r)(void *aux, ulong off, int len); + void (*w)(void *aux, ulong off, ulong data, int len); +}; + +struct Cpu +{ + ulong reg[NREG]; + + /* instruction counter */ + ulong ic; + + /* mem[16], one entry for each 64k block */ + Bus *mem; + + /* port[1], in/out */ + Bus *port; + + int trap; + ulong oldip; + jmp_buf jmp; + + /* default operand, address and stack pointer length */ + uchar olen, alen, slen; + + /* argument buffers */ + ulong iabuf; + Iarg abuf[0x80]; +}; + +struct Pit +{ + ulong count; + + /* set by setgate(), cleared by clockpit() */ + uchar gateraised; + + /* signals */ + uchar gate; + uchar out; + + /* mode and flags */ + uchar count0; + + uchar bcd; + uchar amode; + uchar omode; + + /* latch for wpit initial count */ + uchar wcount; + uchar wlatched; + uchar wlatch[2]; + + /* latch for rpit status/count */ + uchar rcount; + uchar rlatched; + uchar rlatch[2]; +}; + +/* processor flags */ +enum { + CF = 1<<0, /* carry flag */ + PF = 1<<2, /* parity flag */ + AF = 1<<4, /* aux carry flag */ + ZF = 1<<6, /* zero flag */ + SF = 1<<7, /* sign flag */ + TF = 1<<8, /* trap flag */ + IF = 1<<9, /* interrupts enabled flag */ + DF = 1<<10, /* direction flag */ + OF = 1<<11, /* overflow flag */ + IOPL= 3<<12, /* I/O privelege level */ + NT = 1<<14, /* nested task */ + RF = 1<<16, /* resume flag */ + VM = 1<<17, /* virtual-8086 mode */ + AC = 1<<18, /* alignment check */ + VIF = 1<<19, /* virtual interrupt flag */ + VIP = 1<<20, /* virtual interrupt pending */ + ID = 1<<21, /* ID flag */ +}; + +/* interrupts/traps */ +enum { + EDIV0, + EDEBUG, + ENMI, + EBRK, + EINTO, + EBOUND, + EBADOP, + ENOFPU, + EDBLF, + EFPUSEG, + EBADTSS, + ENP, + ESTACK, + EGPF, + EPF, + + EHALT = 256, /* pseudo-interrupts */ + EMEM, + EIO, +}; + +/* argument tags */ +enum { + TREG, + TMEM, + TCON, + + TH = 0x80, /* special flag for AH,BH,CH,DH */ +}; + +/* argument types */ +enum { + ANONE, /* no argument */ + A0, /* constant 0 */ + A1, /* constant 1 */ + A2, /* constant 2 */ + A3, /* constant 3 */ + A4, /* constant 4 */ + AAp, /* 32-bit or 48-bit direct address */ + AEb, /* r/m8 from modrm byte */ + AEv, /* r/m16 or r/m32 from modrm byte */ + AEw, /* r/m16 */ + AFv, /* flag word */ + AGb, /* r8 from modrm byte */ + AGv, /* r16 or r32 from modrm byte */ + AGw, /* r/m16 */ + AIb, /* immediate byte */ + AIc, /* immediate byte sign-extended */ + AIw, /* immediate 16-bit word */ + AIv, /* immediate 16-bit or 32-bit word */ + AJb, /* relative offset byte */ + AJv, /* relative offset 16-bit or 32-bit word */ + AJr, /* r/m16 or r/m32 register */ + AM, /* memory address from modrm */ + AMa, /* something for bound */ + AMa2, + AMp, /* 32-bit or 48-bit memory address */ + AOb, /* immediate word-sized offset to a byte */ + AOv, /* immediate word-size offset to a word */ + ASw, /* segment register selected by r field of modrm */ + AXb, /* byte at DS:SI */ + AXv, /* word at DS:SI */ + AYb, /* byte at ES:DI */ + AYv, /* word at ES:DI */ + + AAL, + ACL, + ADL, + ABL, + AAH, + ACH, + ADH, + ABH, + + AAX, + ACX, + ADX, + ABX, + ASP, + ABP, + ASI, + ADI, + + AES, + ACS, + ASS, + ADS, + AFS, + AGS, + + NATYPE, +}; + +/* operators */ +enum { + OBAD, + O0F, + OAAA, + OAAD, + OAAM, + OAAS, + OADC, + OADD, + OAND, + OARPL, + OASIZE, + OBOUND, + OBT, + OBTS, + OBTR, + OBTC, + OBSF, + OBSR, + OCALL, + OCBW, + OCLC, + OCLD, + OCLI, + OCMC, + OCMOV, + OCMP, + OCMPS, + OCPUID, + OCWD, + ODAA, + ODAS, + ODEC, + ODIV, + OENTER, + OGP1, + OGP2, + OGP3b, + OGP3v, + OGP4, + OGP5, + OGP10, + OGP12, + OHLT, + OIDIV, + OIMUL, + OIN, + OINC, + OINS, + OINT, + OIRET, + OJUMP, + OLAHF, + OLEA, + OLEAVE, + OLFP, + OLOCK, + OLODS, + OLOOP, + OLOOPNZ, + OLOOPZ, + OMOV, + OMOVS, + OMOVZX, + OMOVSX, + OMUL, + ONEG, + ONOP, + ONOT, + OOR, + OOSIZE, + OOUT, + OOUTS, + OPOP, + OPOPA, + OPOPF, + OPUSH, + OPUSHA, + OPUSHF, + ORCL, + ORCR, + OREPE, + OREPNE, + ORET, + ORETF, + OROL, + OROR, + OSAHF, + OSAR, + OSBB, + OSCAS, + OSEG, + OSET, + OSHL, + OSHLD, + OSHR, + OSHRD, + OSTC, + OSTD, + OSTI, + OSTOS, + OSUB, + OTEST, + OWAIT, + OXCHG, + OXLAT, + OXOR, + NUMOP, +}; diff --git a/sys/src/cmd/aux/realemu/decode.c b/sys/src/cmd/aux/realemu/decode.c new file mode 100644 index 000000000..e2022a2a5 --- /dev/null +++ b/sys/src/cmd/aux/realemu/decode.c @@ -0,0 +1,619 @@ +#include +#include +#include "dat.h" +#include "fns.h" + +typedef struct Optab Optab; +struct Optab { + uchar op; + uchar a1, a2, a3; +}; + +static Optab optab[256] = { +//00 + {OADD, AEb, AGb}, {OADD, AEv, AGv}, {OADD, AGb, AEb}, {OADD, AGv, AEv}, + {OADD, AAL, AIb}, {OADD, AAX, AIv}, {OPUSH, AES, }, {OPOP, AES }, + {OOR, AEb, AGb}, {OOR, AEv, AGv}, {OOR, AGb, AEb}, {OOR, AGv, AEv}, + {OOR, AAL, AIb}, {OOR, AAX, AIv}, {OPUSH, ACS, }, {O0F, }, +//10 + {OADC, AEb, AGb}, {OADC, AEv, AGv}, {OADC, AGb, AEb}, {OADC, AGv, AEv}, + {OADC, AAL, AIb}, {OADC, AAX, AIv}, {OPUSH, ASS, }, {OPOP, ASS, }, + {OSBB, AEb, AGb}, {OSBB, AEv, AGv}, {OSBB, AGb, AEb}, {OSBB, AGv, AEv}, + {OSBB, AAL, AIb}, {OSBB, AAX, AIv}, {OPUSH, ADS, }, {OPOP, ADS, }, +//20 + {OAND, AEb, AGb}, {OAND, AEv, AGv}, {OAND, AGb, AEb}, {OAND, AGv, AEv}, + {OAND, AAL, AIb}, {OAND, AAX, AIv}, {OSEG, AES, }, {ODAA, }, + {OSUB, AEb, AGb}, {OSUB, AEv, AGv}, {OSUB, AGb, AEb}, {OSUB, AGv, AEv}, + {OSUB, AAL, AIb}, {OSUB, AAX, AIv}, {OSEG, ACS, }, {ODAS, }, +//30 + {OXOR, AEb, AGb}, {OXOR, AEv, AGv}, {OXOR, AGb, AEb}, {OXOR, AGv, AEv}, + {OXOR, AAL, AIb}, {OXOR, AAX, AIv}, {OSEG, ASS, }, {OAAA, }, + {OCMP, AEb, AGb}, {OCMP, AEv, AGv}, {OCMP, AGb, AEb}, {OCMP, AGv, AEv}, + {OCMP, AAL, AIb}, {OCMP, AAX, AIv}, {OSEG, ADS, }, {OAAS, }, +//40 + {OINC, AAX, }, {OINC, ACX, }, {OINC, ADX, }, {OINC, ABX, }, + {OINC, ASP, }, {OINC, ABP, }, {OINC, ASI, }, {OINC, ADI, }, + {ODEC, AAX, }, {ODEC, ACX, }, {ODEC, ADX, }, {ODEC, ABX, }, + {ODEC, ASP, }, {ODEC, ABP, }, {ODEC, ASI, }, {ODEC, ADI, }, +//50 + {OPUSH, AAX, }, {OPUSH, ACX, }, {OPUSH, ADX, }, {OPUSH, ABX, }, + {OPUSH, ASP, }, {OPUSH, ABP, }, {OPUSH, ASI, }, {OPUSH, ADI, }, + {OPOP, AAX, }, {OPOP, ACX, }, {OPOP, ADX, }, {OPOP, ABX, }, + {OPOP, ASP, }, {OPOP, ABP, }, {OPOP, ASI, }, {OPOP, ADI, }, +//60 + {OPUSHA, }, {OPOPA, }, {OBOUND,AGv,AMa,AMa2}, {OARPL, AEw, AGw}, + {OSEG, AFS, }, {OSEG, AGS, }, {OOSIZE, }, {OASIZE, }, + {OPUSH, AIv, }, {OIMUL,AGv,AEv,AIv},{OPUSH, AIb, }, {OIMUL,AGv,AEv,AIb}, + {OINS, AYb, ADX}, {OINS, AYv, ADX}, {OOUTS, ADX, AXb}, {OOUTS, ADX, AXv}, +//70 + {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, + {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, + {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, + {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, +//80 + {OGP1, AEb, AIb}, {OGP1, AEv, AIv}, {OGP1, AEb, AIb}, {OGP1, AEv, AIc}, + {OTEST, AEb, AGb}, {OTEST, AEv, AGv}, {OXCHG, AEb, AGb}, {OXCHG, AEv, AGv}, + {OMOV, AEb, AGb}, {OMOV, AEv, AGv}, {OMOV, AGb, AEb}, {OMOV, AGv, AEv}, + {OMOV, AEw, ASw}, {OLEA, AGv, AM }, {OMOV, ASw, AEw}, {OGP10, }, +//90 + {ONOP, }, {OXCHG, ACX, AAX}, {OXCHG, ADX, AAX}, {OXCHG, ABX, AAX}, + {OXCHG, ASP, AAX}, {OXCHG, ABP, AAX}, {OXCHG, ASI, AAX}, {OXCHG, ADI, AAX}, + {OCBW, }, {OCWD, }, {OCALL, AAp, }, {OWAIT, }, + {OPUSHF,AFv, }, {OPOPF, AFv, }, {OSAHF, AAH, }, {OLAHF, AAH, }, +//A0 + {OMOV, AAL, AOb}, {OMOV, AAX, AOv}, {OMOV, AOb, AAL}, {OMOV, AOv, AAX}, + {OMOVS, AYb, AXb}, {OMOVS, AYv, AXv}, {OCMPS, AYb, AXb}, {OCMPS, AYv, AXv}, + {OTEST, AAL, AIb}, {OTEST, AAX, AIv}, {OSTOS, AYb, AAL}, {OSTOS, AYv, AAX}, + {OLODS, AAL, AXb}, {OLODS, AAX, AXv}, {OSCAS, AYb, AAL}, {OSCAS, AYv, AAX}, +//B0 + {OMOV, AAL, AIb}, {OMOV, ACL, AIb}, {OMOV, ADL, AIb}, {OMOV, ABL, AIb}, + {OMOV, AAH, AIb}, {OMOV, ACH, AIb}, {OMOV, ADH, AIb}, {OMOV, ABH, AIb}, + {OMOV, AAX, AIv}, {OMOV, ACX, AIv}, {OMOV, ADX, AIv}, {OMOV, ABX, AIv}, + {OMOV, ASP, AIv}, {OMOV, ABP, AIv}, {OMOV, ASI, AIv}, {OMOV, ADI, AIv}, +//C0 + {OGP2, AEb, AIb}, {OGP2, AEv, AIb}, {ORET, AIw, }, {ORET, A0, }, + {OLFP,AES,AGv,AMp},{OLFP,ADS,AGv,AMp},{OGP12, AEb, AIb}, {OGP12, AEv, AIv}, + {OENTER,AIw, AIb}, {OLEAVE, }, {ORETF, AIw, }, {ORETF, A0, }, + {OINT, A3, }, {OINT, AIb, }, {OINT, A4, }, {OIRET, }, +//D0 + {OGP2, AEb, A1 }, {OGP2, AEv, A1 }, {OGP2, AEb, ACL}, {OGP2, AEv, ACL}, + {OAAM, AIb, }, {OAAD, AIb, }, {OBAD, }, {OXLAT, AAL, ABX}, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//E0 + {OLOOPNZ,AJb, }, {OLOOPZ,AJb, }, {OLOOP, AJb, }, {OJUMP, AJb, }, + {OIN, AAL, AIb}, {OIN, AAX, AIb}, {OOUT, AIb, AAL}, {OOUT, AIb, AAX}, + {OCALL, AJv, }, {OJUMP, AJv, }, {OJUMP, AAp, }, {OJUMP, AJb, }, + {OIN, AAL, ADX}, {OIN, AAX, ADX}, {OOUT, ADX, AAL}, {OOUT, ADX, AAX}, +//F0 + {OLOCK, }, {OBAD, }, {OREPNE, }, {OREPE, }, + {OHLT, }, {OCMC, }, {OGP3b, }, {OGP3v, }, + {OCLC, }, {OSTC, }, {OCLI, }, {OSTI, }, + {OCLD, }, {OSTD, }, {OGP4, }, {OGP5, }, +}; + +static Optab optab0F[256] = { +//00 + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//10 - mostly floating point and quadword moves + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//20 - doubleword <-> control register moves, other arcana + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//30 - wrmsr, rdtsc, rdmsr, rdpmc, sysenter, sysexit + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//40 - conditional moves + {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, + {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, + {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, + {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, +//50 - floating point, mmx stuff + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//60 - floating point, mmx stuff + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//70 - floating point, mmx stuff + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//80 - long-displacement jumps + {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, + {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, + {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, + {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, +//90 - conditional byte set + {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, + {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, + {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, + {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, +//A0 + {OPUSH, AFS, }, {OPOP, AFS, }, {OCPUID, }, {OBT, AEv, AGv}, + {OSHLD,AEv,AGv,AIb}, {OSHLD,AEv,AGv,ACL}, {OBAD, }, {OBAD, }, + {OPUSH, AGS, }, {OPOP, AGS, }, {OBAD, }, {OBTS, AEv, AGv}, + {OSHRD,AEv,AGv,AIb}, {OSHRD,AEv,AGv,ACL}, {OBAD, }, {OIMUL, AGv,AGv,AEv}, +//B0 - mostly arcana + {OBAD, }, {OBAD, }, {OLFP,ASS,AGv,AMp},{OBTR,AEv,AGv }, + {OLFP,AFS,AGv,AMp},{OLFP,AGS,AGv,AMp},{OMOVZX,AGv,AEb }, {OMOVZX,AGv,AEw }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBSF,AGv,AEv }, {OBSR,AGv,AEv }, {OMOVSX,AGv,AEb }, {OMOVSX,AGv,AEw }, +//C0 - more arcana + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//D0 - mmx + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//E0 - mmx + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//F0 - mmx + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +}; + +/* some operands map to whole groups; group numbers from intel opcode map */ +/* args filled in already (in OGP1 entries) */ +static Optab optabgp1[8] = { + {OADD, }, {OOR, }, {OADC, }, {OSBB, }, + {OAND, }, {OSUB, }, {OXOR, }, {OCMP, }, +}; + +/* args filled in already (in OGP2 entries) */ +static Optab optabgp2[8] = { + {OROL, }, {OROR, }, {ORCL, }, {ORCR, }, + {OSHL, }, {OSHR, }, {OBAD, }, {OSAR, }, +}; + +static Optab optabgp3b[8] = { + {OTEST, AEb, AIb}, {OBAD, }, {ONOT, AEb, }, {ONEG, AEb, }, + {OMUL,AAX,AAL,AEb},{OIMUL,AAX,AAL,AEb},{ODIV, AEb, }, {OIDIV, AEb, }, +}; + +static Optab optabgp3v[8] = { + {OTEST, AEv, AIv}, {OBAD, }, {ONOT, AEv, }, {ONEG, AEv, }, + {OMUL,AAX,AAX,AEv},{OIMUL,AAX,AAX,AEv},{ODIV, AEv, }, {OIDIV, AEv, }, +}; + +static Optab optabgp4[8] = { + {OINC, AEb, }, {ODEC, AEb, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +}; + +static Optab optabgp5[8] = { + {OINC, AEv, }, {ODEC, AEv, }, {OCALL, AEv, }, {OCALL, AMp }, + {OJUMP, AEv, }, {OJUMP, AMp, }, {OPUSH, AEv, }, {OBAD, }, +}; + +static Optab optabgp10[8] = { + {OPOP, AEv, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +}; + +static Optab optabgp12[8] = { + {OMOV, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +}; + +/* optabg6 unimplemented - mostly segment manipulation */ +/* optabg7 unimplemented - more segment manipulation */ +/* optabg8 unimplemented - bit tests */ + +/* + * most of optabg9 - optabg16 decode differently depending on the mod value of + * the modrm byte. they're mostly arcane instructions so they're not + * implemented. + */ + +static Optab *optabgp[NUMOP] = { + [OGP1] optabgp1, + [OGP2] optabgp2, + [OGP3b] optabgp3b, + [OGP3v] optabgp3v, + [OGP4] optabgp4, + [OGP5] optabgp5, + [OGP10] optabgp10, + [OGP12] optabgp12, +}; + +static uchar modrmarg[NATYPE] = { + [AEb] 1, + [AEw] 1, + [AEv] 1, + [AGb] 1, + [AGw] 1, + [AGv] 1, + [AM] 1, + [AMp] 1, + [AMa] 1, + [AMa2] 1, + [ASw] 1, + [AJr] 1, +}; + +static void +getmodrm16(Iarg *ip, Inst *i) +{ + Iarg *p; + uchar b; + + b = ar(ip); ip->off++; + + i->mod = b>>6; + i->reg = (b>>3)&7; + i->rm = b&7; + + if(i->mod == 3) + return; + + switch(i->rm){ + case 0: + i->off = ar(areg(ip->cpu, 2, RBX)) + ar(areg(ip->cpu, 2, RSI)); + i->off &= 0xFFFF; + break; + case 1: + i->off = ar(areg(ip->cpu, 2, RBX)) + ar(areg(ip->cpu, 2, RDI)); + i->off &= 0xFFFF; + break; + case 2: + i->dsreg = RSS; + i->off = ar(areg(ip->cpu, 2, RBP)) + ar(areg(ip->cpu, 2, RSI)); + i->off &= 0xFFFF; + break; + case 3: + i->dsreg = RSS; + i->off = ar(areg(ip->cpu, 2, RBP)) + ar(areg(ip->cpu, 2, RDI)); + i->off &= 0xFFFF; + break; + case 4: + i->off = ar(areg(ip->cpu, 2, RSI)); + break; + case 5: + i->off = ar(areg(ip->cpu, 2, RDI)); + break; + case 6: + if(i->mod == 0){ + p = adup(ip); ip->off += 2; + p->len = 2; + i->off = ar(p); + return; + } + i->dsreg = RSS; + i->off = ar(areg(ip->cpu, 2, RBP)); + break; + case 7: + i->off = ar(areg(ip->cpu, 2, RBX)); + break; + } + switch(i->mod){ + case 1: + i->off += (i->disp = ars(ip)); ip->off++; + i->off &= 0xFFFF; + break; + case 2: + p = adup(ip); ip->off += 2; + p->len = 2; + i->off += (i->disp = ars(p)); + i->off &= 0xFFFF; + break; + } +} + +static void +getmodrm32(Iarg *ip, Inst *i) +{ + static uchar scaler[] = {1, 2, 4, 8}; + Iarg *p; + uchar b; + + b = ar(ip); ip->off++; + + i->mod = b>>6; + i->reg = (b>>3)&7; + i->rm = b&7; + + if(i->mod == 3) + return; + + switch(i->rm){ + case 0: + case 1: + case 2: + case 3: + case 6: + case 7: + i->off = ar(areg(ip->cpu, 4, i->rm + RAX)); + break; + case 4: + b = ar(ip); i->off++; + i->scale = b>>6; + i->index = (b>>3)&7; + i->base = b&7; + + if(i->base != 5){ + i->off = ar(areg(ip->cpu, 4, i->base + RAX)); + break; + } + case 5: + if(i->mod == 0){ + p = adup(ip); ip->off += 4; + p->len = 4; + i->off = ar(p); + } else { + i->dsreg = RSS; + i->off = ar(areg(ip->cpu, 4, RBP)); + } + break; + } + + if(i->rm == 4 && i->index != 4) + i->off += ar(areg(ip->cpu, 4, i->index + RAX)) * scaler[i->scale]; + + switch(i->mod){ + case 1: + i->off += (i->disp = ars(ip)); ip->off++; + break; + case 2: + p = adup(ip); ip->off += 4; + p->len = 4; + i->off += (i->disp = ars(p)); + break; + } +} + +static Iarg* +getarg(Iarg *ip, Inst *i, uchar atype) +{ + Iarg *a; + uchar len, reg; + + len = i->olen; + switch(atype){ + default: + abort(); + + case A0: + case A1: + case A2: + case A3: + case A4: + a = acon(ip->cpu, len, atype - A0); + break; + + case AEb: + len = 1; + if(0){ + case AEw: + len = 2; + } + case AEv: + if(i->mod == 3){ + reg = i->rm; + goto REG; + } + goto MEM; + + case AM: + case AMp: + case AMa: + case AMa2: + if(i->mod == 3) + trap(ip->cpu, EBADOP); + MEM: + a = amem(ip->cpu, len, i->sreg, i->off); + if(atype == AMa2) + a->off += i->olen; + break; + + case AGb: + len = 1; + if(0){ + case AGw: + len = 2; + } + case AGv: + reg = i->reg; + REG: + a = areg(ip->cpu, len, reg + RAX); + if(len == 1 && reg >= 4){ + a->reg -= 4; + a->tag |= TH; + } + break; + + case AIb: + case AIc: + len = 1; + if(0){ + case AIw: + len = 2; + } + case AIv: + a = adup(ip); ip->off += len; + a->len = len; + break; + + case AJb: + len = 1; + case AJv: + a = adup(ip); ip->off += len; + a->len = len; + a->off = ip->off + ars(a); + break; + + case AJr: + if(i->mod != 3) + trap(ip->cpu, EBADOP); + a = adup(ip); + a->off = ar(areg(ip->cpu, i->olen, i->rm + RAX)); + break; + + case AAp: + a = afar(ip, ip->len, len); ip->off += 2+len; + break; + + case AOb: + len = 1; + case AOv: + a = adup(ip); ip->off += i->alen; + a->len = i->alen; + a = amem(ip->cpu, len, i->sreg, ar(a)); + break; + + case ASw: + reg = i->reg; + SREG: + a = areg(ip->cpu, 2, reg + RES); + break; + + case AXb: + len = 1; + case AXv: + a = amem(ip->cpu, len, i->sreg, ar(areg(ip->cpu, i->alen, RSI))); + break; + + case AYb: + len = 1; + case AYv: + a = amem(ip->cpu, len, RES, ar(areg(ip->cpu, i->alen, RDI))); + break; + + case AFv: + a = areg(ip->cpu, len, RFL); + break; + + case AAL: + case ACL: + case ADL: + case ABL: + case AAH: + case ACH: + case ADH: + case ABH: + len = 1; + reg = atype - AAL; + goto REG; + + case AAX: + case ACX: + case ADX: + case ABX: + case ASP: + case ABP: + case ASI: + case ADI: + reg = atype - AAX; + goto REG; + + case AES: + case ACS: + case ASS: + case ADS: + case AFS: + case AGS: + reg = atype - AES; + goto SREG; + } + a->atype = atype; + return a; +} + +static int +otherlen(int a) +{ + if(a == 2) + return 4; + else if(a == 4) + return 2; + abort(); + return 0; +} + +void +decode(Iarg *ip, Inst *i) +{ + Optab *t, *t2; + Cpu *cpu; + + cpu = ip->cpu; + + i->op = 0; + i->rep = 0; + i->sreg = 0; + i->dsreg = RDS; + i->olen = cpu->olen; + i->alen = cpu->alen; + + for(;;){ + i->code = ar(ip); ip->off++; + t = optab + i->code; + switch(t->op){ + case OOSIZE: + i->olen = otherlen(cpu->olen); + continue; + case OASIZE: + i->alen = otherlen(cpu->alen); + continue; + case OREPE: + case OREPNE: + i->rep = t->op; + continue; + case OLOCK: + continue; + case OSEG: + i->sreg = t->a1-AES+RES; + continue; + case O0F: + i->code = ar(ip); ip->off++; + t = optab0F + i->code; + break; + } + break; + } + t2 = optabgp[t->op]; + if(t2 || modrmarg[t->a1] || modrmarg[t->a2] || modrmarg[t->a3]) + if(i->alen == 2) + getmodrm16(ip, i); + else + getmodrm32(ip, i); + if(i->sreg == 0) + i->sreg = i->dsreg; + + i->a1 = i->a2 = i->a3 = nil; + for(;;){ + if(t->a1) + i->a1 = getarg(ip, i, t->a1); + if(t->a2) + i->a2 = getarg(ip, i, t->a2); + if(t->a3) + i->a3 = getarg(ip, i, t->a3); + if(t2 == nil) + break; + t = t2 + i->reg; + t2 = nil; + } + i->op = t->op; +} diff --git a/sys/src/cmd/aux/realemu/fmt.c b/sys/src/cmd/aux/realemu/fmt.c new file mode 100644 index 000000000..8d65fe959 --- /dev/null +++ b/sys/src/cmd/aux/realemu/fmt.c @@ -0,0 +1,385 @@ +#include +#include +#include "dat.h" +#include "fns.h" + +static char *opstr[] = { /* Edit s/O(.*),/[O\1]= "\1",/g */ + [OBAD]= "BAD", + [O0F]= "0F", + [OAAA]= "AAA", + [OAAD]= "AAD", + [OAAM]= "AAM", + [OAAS]= "AAS", + [OADC]= "ADC", + [OADD]= "ADD", + [OAND]= "AND", + [OARPL]= "ARPL", + [OASIZE]= "ASIZE", + [OBOUND]= "BOUND", + [OBT]= "BT", + [OBTC]= "BTC", + [OBTR]= "BTR", + [OBTS]= "BTS", + [OBSF]= "BSF", + [OBSR]= "BSR", + [OCALL]= "CALL", + [OCBW]= "CBW", + [OCLC]= "CLC", + [OCLD]= "CLD", + [OCLI]= "CLI", + [OCMC]= "CMC", + [OCMOV]= "CMOV", + [OCMP]= "CMP", + [OCMPS]= "CMPS", + [OCWD]= "CWD", + [ODAA]= "DAA", + [ODAS]= "DAS", + [ODEC]= "DEC", + [ODIV]= "DIV", + [OENTER]= "ENTER", + [OGP1]= "GP1", + [OGP2]= "GP2", + [OGP3b]= "GP3b", + [OGP3v]= "GP3v", + [OGP4]= "GP4", + [OGP5]= "GP5", + [OHLT]= "HLT", + [OIDIV]= "IDIV", + [OIMUL]= "IMUL", + [OIN]= "IN", + [OINC]= "INC", + [OINS]= "INS", + [OINT]= "INT", + [OIRET]= "IRET", + [OJUMP]= "JUMP", + [OLAHF]= "LAHF", + [OLFP]= "LFP", + [OLEA]= "LEA", + [OLEAVE]= "LEAVE", + [OLOCK]= "LOCK", + [OLODS]= "LODS", + [OLOOP]= "LOOP", + [OLOOPNZ]= "LOOPNZ", + [OLOOPZ]= "LOOPZ", + [OMOV]= "MOV", + [OMOVS]= "MOVS", + [OMOVZX]= "MOVZX", + [OMOVSX]= "MOVSX", + [OMUL]= "MUL", + [ONEG]= "NEG", + [ONOP]= "NOP", + [ONOT]= "NOT", + [OOR]= "OR", + [OOSIZE]= "OSIZE", + [OOUT]= "OUT", + [OOUTS]= "OUTS", + [OPOP]= "POP", + [OPOPA]= "POPA", + [OPOPF]= "POPF", + [OPUSH]= "PUSH", + [OPUSHA]= "PUSHA", + [OPUSHF]= "PUSHF", + [ORCL]= "RCL", + [ORCR]= "RCR", + [OREPE]= "REPE", + [OREPNE]= "REPNE", + [ORET]= "RET", + [ORETF]= "RETF", + [OROL]= "ROL", + [OROR]= "ROR", + [OSAHF]= "SAHF", + [OSAR]= "SAR", + [OSBB]= "SBB", + [OSCAS]= "SCAS", + [OSEG]= "SEG", + [OSET]= "SET", + [OSHL]= "SHL", + [OSHLD]= "SHLD", + [OSHR]= "SHR", + [OSHRD]= "SHRD", + [OSTC]= "STC", + [OSTD]= "STD", + [OSTI]= "STI", + [OSTOS]= "STOS", + [OSUB]= "SUB", + [OTEST]= "TEST", + [OWAIT]= "WAIT", + [OXCHG]= "XCHG", + [OXLAT]= "XLAT", + [OXOR]= "XOR", +}; + +static char *memstr16[] = { + "BX+SI", + "BX+DI", + "BP+SI", + "BP+DI", + "SI", + "DI", + "BP", + "BX", +}; + +static char *memstr32[] = { + "EAX", + "ECX", + "EDX", + "EBX", + "0", + "EBP", + "ESI", + "EDI", +}; + +static int +argconv(char *p, Inst *i, Iarg *a) +{ + jmp_buf jmp; + char *s; + + s = p; + switch(a->tag){ + default: + abort(); + + case TCON: + return sprint(p, "%lud", a->val); + case TREG: + case TREG|TH: + switch(a->len){ + case 1: + return sprint(p, "%c%c", "ACDB"[a->reg], "LH"[(a->tag & TH) != 0]); + case 4: + *p++ = 'E'; + case 2: + p += sprint(p, "%c%c", + "ACDBSBSDECSDFGIF"[a->reg], + "XXXXPPIISSSSSSPL"[a->reg]); + return p - s; + } + case TMEM: + break; + } + + /* setup trap jump in case we dereference bad memory */ + memmove(jmp, a->cpu->jmp, sizeof jmp); + if(setjmp(a->cpu->jmp)){ + p += sprint(p, "<%.4lux:%.4lux>", a->seg, a->off); + goto out; + } + + switch(a->atype){ + default: + abort(); + + case AAp: + p += sprint(p, "[%.4lux:%.4lux]", a->seg, a->off); + break; + + case AJb: + case AJv: + p += sprint(p, "[%.4lux]", a->off); + break; + + case AIc: + p += sprint(p, "$%.2lx", ars(a)); + break; + case AIb: + case AIw: + case AIv: + p += sprint(p, "$%.*lux", (int)a->len*2, ar(a)); + break; + + case AMp: + *p++ = '*'; + case AEb: + case AEw: + case AEv: + case AM: + case AMa: + case AMa2: + case AOb: + case AOv: + if(i->sreg != RDS) + p += sprint(p, "%cS:", "ECSDFG"[i->sreg - RES]); + if(a->atype == AOb || a->atype == AOv || (i->mod == 0 && + (i->alen == 2 && i->rm == 6) || + (i->alen == 4 && ((i->rm == 5) || + (i->rm == 4 && i->index == 4 && i->base == 5))))){ + p += sprint(p, "[%.*lux]", (int)i->alen*2, a->off); + break; + } + *p++ = '['; + if(i->alen == 2) + p += sprint(p, "%s", memstr16[i->rm]); + else{ + if(i->rm == 4){ + if(i->index != 4) + p += sprint(p, "%c*%s+", "1248"[i->scale], memstr32[i->index]); + if(i->base != 5) + p += sprint(p, "%s", memstr32[i->base]); + else{ + if(i->mod == 0) + p += sprint(p, "%.4lux", i->off); + else + p += sprint(p, "EBP"); + } + } else + p += sprint(p, "%s", memstr32[i->rm]); + } + if(i->mod != 0) + p += sprint(p, "%+lx", i->disp); + *p++ = ']'; + break; + + case AXb: + case AXv: + if(a->sreg != RDS) + p += sprint(p, "%cS:", "ECSDFG"[a->sreg - RES]); + p += sprint(p, "[SI]"); + break; + case AYb: + case AYv: + if(a->sreg != RDS) + p += sprint(p, "%cS:", "ECSDFG"[a->sreg - RES]); + p += sprint(p, "[DI]"); + break; + } + +out: + memmove(a->cpu->jmp, jmp, sizeof jmp); + *p = 0; + return p - s; +} + +static char *jmpstr[] = { + "JO", "JNO", "JC", "JNC", "JZ", "JNZ", "JBE", "JA", + "JS", "JNS", "JP", "JNP", "JL", "JGE", "JLE", "JG", +}; + +int +instfmt(Fmt *fmt) +{ + Inst *i; + char *p, buf[256]; + + i = va_arg(fmt->args, Inst*); + p = buf; + + if(i->olen == 4) + p += sprint(p, "O32: "); + if(i->alen == 4) + p += sprint(p, "A32: "); + if(i->rep) + p += sprint(p, "%s: ", opstr[i->rep]); + + if(i->op == OXLAT && i->sreg != RDS) + p += sprint(p, "%cS:", "ECSDFG"[i->sreg - RES]); + + if(i->op == OJUMP){ + switch(i->code){ + case 0xE3: + p += sprint(p, "%s ", "JCXZ"); + break; + case 0xEB: + case 0xE9: + case 0xEA: + case 0xFF: + p += sprint(p, "%s ", "JMP"); + break; + default: + p += sprint(p, "%s ", jmpstr[i->code&0xF]); + break; + } + } else + p += sprint(p, "%s ", opstr[i->op]); + + + for(;;){ + if(i->a1 == nil) + break; + p += argconv(p, i, i->a1); + if(i->a2 == nil) + break; + *p++ = ','; + *p++ = ' '; + p += argconv(p, i, i->a2); + if(i->a3 == nil) + break; + *p++ = ','; + *p++ = ' '; + p += argconv(p, i, i->a3); + break; + } + *p = 0; + fmtstrcpy(fmt, buf); + return 0; +} + +int +flagfmt(Fmt *fmt) +{ + char buf[16]; + ulong f; + + f = va_arg(fmt->args, ulong); + sprint(buf, "%c%c%c%c%c%c%c", + (f & CF) ? 'C' : 'c', + (f & SF) ? 'S' : 's', + (f & ZF) ? 'Z' : 'z', + (f & OF) ? 'O' : 'o', + (f & PF) ? 'P' : 'p', + (f & DF) ? 'D' : 'd', + (f & IF) ? 'I' : 'i'); + fmtstrcpy(fmt, buf); + return 0; +} + +int +cpufmt(Fmt *fmt) +{ + char buf[512]; + jmp_buf jmp; + Cpu *cpu; + Inst i; + + cpu = va_arg(fmt->args, Cpu*); + + memmove(jmp, cpu->jmp, sizeof jmp); + if(setjmp(cpu->jmp) == 0) + decode(amem(cpu, 1, RCS, cpu->reg[RIP]), &i); + memmove(cpu->jmp, jmp, sizeof jmp); + + snprint(buf, sizeof(buf), + "%.6lux " + "%.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux " + "%.4lux %.4lux %.4lux %.4lux " + "%J %.4lux %.2ux %I", + + cpu->ic, + + cpu->reg[RAX], + cpu->reg[RBX], + cpu->reg[RCX], + cpu->reg[RDX], + + cpu->reg[RDI], + cpu->reg[RSI], + + cpu->reg[RBP], + cpu->reg[RSP], + + cpu->reg[RDS], + cpu->reg[RES], + cpu->reg[RSS], + cpu->reg[RCS], + + cpu->reg[RFL], + cpu->reg[RIP], + + i.code, + &i); + + fmtstrcpy(fmt, buf); + return 0; +} diff --git a/sys/src/cmd/aux/realemu/fns.h b/sys/src/cmd/aux/realemu/fns.h new file mode 100644 index 000000000..a25f6955a --- /dev/null +++ b/sys/src/cmd/aux/realemu/fns.h @@ -0,0 +1,31 @@ +/* arg */ +Iarg *adup(Iarg *x); +Iarg *areg(Cpu *cpu, uchar len, uchar reg); +Iarg *amem(Cpu *cpu, uchar len, uchar sreg, ulong off); +Iarg *afar(Iarg *mem, uchar len, uchar alen); +Iarg *acon(Cpu *cpu, uchar len, ulong val); +ulong ar(Iarg *a); +long ars(Iarg *a); +void aw(Iarg *a, ulong w); + +/* decode */ +void decode(Iarg *ip, Inst *i); + +/* xec */ +void trap(Cpu *cpu, int e); +int intr(Cpu *cpu, int v); +int xec(Cpu *cpu, int n); + +#pragma varargck type "I" Inst* +#pragma varargck type "J" ulong +#pragma varargck type "C" Cpu* + +int instfmt(Fmt *fmt); +int flagfmt(Fmt *fmt); +int cpufmt(Fmt *fmt); + +/* pit */ +void clockpit(Pit *pit, vlong cycles); +void setgate(Pit *ch, uchar gate); +uchar rpit(Pit *pit, uchar addr); +void wpit(Pit *pit, uchar addr, uchar data); diff --git a/sys/src/cmd/aux/realemu/loadcom.c b/sys/src/cmd/aux/realemu/loadcom.c new file mode 100644 index 000000000..28c5bf6e4 --- /dev/null +++ b/sys/src/cmd/aux/realemu/loadcom.c @@ -0,0 +1,43 @@ +#include +#include + +#include "/386/include/ureg.h" + +static uchar buf[0xFF01]; + +void +main(int argc, char *argv[]) +{ + struct Ureg u; + int fd, rreg, rmem, len; + + ARGBEGIN { + } ARGEND; + + if(argc == 0){ + fprint(2, "usage:\t%s file.com\n", argv0); + exits("usage"); + } + if((fd = open(*argv, OREAD)) < 0) + sysfatal("open: %r"); + + if((rreg = open("/dev/realmode", OWRITE)) < 0) + sysfatal("open realmode: %r"); + if((rmem = open("/dev/realmodemem", OWRITE)) < 0) + sysfatal("open realmodemem: %r"); + if((len = readn(fd, buf, sizeof buf)) < 2) + sysfatal("file too small"); + + memset(&u, 0, sizeof u); + u.cs = u.ds = u.es = u.fs = u.gs = 0x1000; + u.ss = 0x0000; + u.sp = 0xfffe; + u.pc = 0x0100; + + seek(rmem, (u.cs<<4) + u.pc, 0); + if(write(rmem, buf, len) != len) + sysfatal("write mem: %r"); + + if(write(rreg, &u, sizeof u) != sizeof u) + sysfatal("write reg: %r"); +} diff --git a/sys/src/cmd/aux/realemu/main.c b/sys/src/cmd/aux/realemu/main.c new file mode 100644 index 000000000..997e75121 --- /dev/null +++ b/sys/src/cmd/aux/realemu/main.c @@ -0,0 +1,784 @@ +#include +#include +#include "dat.h" +#include "fns.h" + +/* for fs */ +#include +#include +#include +#include <9p.h> + +#include "/386/include/ureg.h" + +enum { + MEMSIZE = 0x100000, + + RMBUF = 0x9000, + RMCODE = 0x8000, + + PITHZ = 1193182, + PITNS = 1000000000/PITHZ, +}; + +static Cpu cpu; +static uchar memory[MEMSIZE+4]; +static uchar pageregtmp[0x10]; +static int portfd[5]; +static int realmemfd; +static int cputrace; +static int porttrace; +static Pit pit[3]; + +static vlong pitclock; + +static void +startclock(void) +{ + pitclock = nsec(); +} + +static void +runclock(void) +{ + vlong now, dt; + + now = nsec(); + dt = now - pitclock; + if(dt >= PITNS){ + clockpit(pit, dt/PITNS); + pitclock = now; + } +} + +static ulong +gw1(uchar *p) +{ + return p[0]; +} +static ulong +gw2(uchar *p) +{ + return (ulong)p[0] | (ulong)p[1]<<8; +} +static ulong +gw4(uchar *p) +{ + return (ulong)p[0] | (ulong)p[1]<<8 | (ulong)p[2]<<16 | (ulong)p[3]<<24; +} +static ulong (*gw[5])(uchar *p) = { + [1] gw1, + [2] gw2, + [4] gw4, +}; + +static void +pw1(uchar *p, ulong w) +{ + p[0] = w & 0xFF; +} +static void +pw2(uchar *p, ulong w) +{ + p[0] = w & 0xFF; + p[1] = (w>>8) & 0xFF; +} +static void +pw4(uchar *p, ulong w) +{ + p[0] = w & 0xFF; + p[1] = (w>>8) & 0xFF; + p[2] = (w>>16) & 0xFF; + p[3] = (w>>24) & 0xFF; +} +static void (*pw[5])(uchar *p, ulong w) = { + [1] pw1, + [2] pw2, + [4] pw4, +}; + +static ulong +rbad(void *, ulong off, int) +{ + fprint(2, "bad mem read %.5lux\n", off); + trap(&cpu, EMEM); + + /* not reached */ + return 0; +} + +static void +wbad(void *, ulong off, ulong, int) +{ + fprint(2, "bad mem write %.5lux\n", off); + trap(&cpu, EMEM); +} + +static ulong +rmem(void *, ulong off, int len) +{ + return gw[len](memory + off); +} + +static void +wmem(void *, ulong off, ulong w, int len) +{ + pw[len](memory + off, w); +} + +static ulong +rrealmem(void *, ulong off, int len) +{ + uchar data[4]; + + if(pread(realmemfd, data, len, off) != len){ + fprint(2, "bad real mem read %.5lux: %r\n", off); + trap(&cpu, EMEM); + } + return gw[len](data); +} + +static void +wrealmem(void *, ulong off, ulong w, int len) +{ + uchar data[4]; + + pw[len](data, w); + if(pwrite(realmemfd, data, len, off) != len){ + fprint(2, "bad real mem write %.5lux: %r\n", off); + trap(&cpu, EMEM); + } +} + + +static ulong +rport(void *, ulong p, int len) +{ + uchar data[4]; + ulong w; + + switch(p){ + case 0x20: /* PIC 1 */ + case 0x21: + w = 0; + break; + case 0x40: + case 0x41: + case 0x42: + case 0x43: + runclock(); + w = rpit(pit, p - 0x40); + break; + case 0x60: /* keyboard data output buffer */ + w = 0; + break; + case 0x61: /* keyboard controller port b */ + runclock(); + w = pit[2].out<<5 | pit[2].gate; + break; + case 0x62: /* PPI (XT only) */ + runclock(); + w = pit[2].out<<5; + break; + case 0x63: /* PPI (XT only) read dip switches */ + w = 0; + break; + case 0x65: /* A20 gate */ + w = 1 << 2; + break; + case 0x80: /* extra dma registers (temp) */ + case 0x84: + case 0x85: + case 0x86: + case 0x88: + case 0x8c: + case 0x8d: + case 0x8e: + w = pageregtmp[p-0x80]; + break; + case 0x92: /* A20 gate (system control port a) */ + w = 1 << 1; + break; + case 0xa0: /* PIC 2 */ + case 0xa1: + w = 0; + break; + default: + if(pread(portfd[len], data, len, p) != len){ + fprint(2, "bad %d bit port read %.4lux: %r\n", len*8, p); + trap(&cpu, EIO); + } + w = gw[len](data); + } + if(porttrace) + fprint(2, "rport %.4lux %.*lux\n", p, len<<1, w); + return w; +} + +static void +wport(void *, ulong p, ulong w, int len) +{ + uchar data[4]; + + if(porttrace) + fprint(2, "wport %.4lux %.*lux\n", p, len<<1, w); + + switch(p){ + case 0x20: /* PIC 1 */ + case 0x21: + break; + case 0x40: + case 0x41: + case 0x42: + case 0x43: + runclock(); + wpit(pit, p - 0x40, w); + break; + case 0x60: /* keyboard controller data port */ + break; + case 0x61: /* keyboard controller port B */ + setgate(&pit[2], w & 1); + break; + case 0x62: /* PPI (XT only) */ + case 0x63: + case 0x64: /* KB controller input buffer (ISA, EISA) */ + case 0x65: /* A20 gate (bit 2) */ + break; + case 0x80: + case 0x84: + case 0x85: + case 0x86: + case 0x88: + case 0x8c: + case 0x8d: + case 0x8e: + pageregtmp[p-0x80] = w & 0xFF; + break; + case 0x92: /* system control port a */ + case 0x94: /* system port enable setup register */ + case 0x96: + break; + case 0xA0: /* PIC 2 */ + case 0xA1: + break; + + default: + pw[len](data, w); + if(pwrite(portfd[len], data, len, p) != len){ + fprint(2, "bad %d bit port write %.4lux: %r\n", len*8, p); + trap(&cpu, EIO); + } + } +} + +static Bus memio[] = { + /* 0 */ memory, rmem, wmem, /* RAM: IVT, BIOS data area */ + /* 1 */ memory, rmem, wmem, /* custom */ + /* 2 */ nil, rbad, wbad, + /* 3 */ nil, rbad, wbad, + /* 4 */ nil, rbad, wbad, + /* 5 */ nil, rbad, wbad, + /* 6 */ nil, rbad, wbad, + /* 7 */ nil, rbad, wbad, + /* 8 */ nil, rbad, wbad, + /* 9 */ memory, rmem, wmem, /* RAM: extended BIOS data area */ + /* A */ nil, rrealmem, wrealmem, /* RAM: VGA framebuffer */ + /* B */ nil, rrealmem, wrealmem, /* RAM: VGA framebuffer */ + /* C */ memory, rmem, wmem, /* ROM: VGA BIOS */ + /* D */ nil, rbad, wbad, + /* E */ memory, rmem, wbad, /* ROM: BIOS */ + /* F */ memory, rmem, wbad, /* ROM: BIOS */ +}; + +static Bus portio = { + nil, rport, wport, +}; + +static void +cpuinit(void) +{ + int i; + + fmtinstall('I', instfmt); + fmtinstall('J', flagfmt); + fmtinstall('C', cpufmt); + + if((portfd[1] = open("#P/iob", ORDWR)) < 0) + sysfatal("open iob: %r"); + if((portfd[2] = open("#P/iow", ORDWR)) < 0) + sysfatal("open iow: %r"); + if((portfd[4] = open("#P/iol", ORDWR)) < 0) + sysfatal("open iol: %r"); + + if((realmemfd = open("#P/realmodemem", ORDWR)) < 0) + sysfatal("open realmodemem: %r"); + + for(i=0; ix)]((uchar*)&u->x) +#define PUTUREG(x,y) pw[sizeof(u->x)]((uchar*)&u->x,y) + +static char* +realmode(Cpu *cpu, struct Ureg *u, void *r) +{ + char *err; + int i; + + cpu->reg[RDI] = GETUREG(di); + cpu->reg[RSI] = GETUREG(si); + cpu->reg[RBP] = GETUREG(bp); + cpu->reg[RBX] = GETUREG(bx); + cpu->reg[RDX] = GETUREG(dx); + cpu->reg[RCX] = GETUREG(cx); + cpu->reg[RAX] = GETUREG(ax); + + cpu->reg[RGS] = GETUREG(gs); + cpu->reg[RFS] = GETUREG(fs); + cpu->reg[RES] = GETUREG(es); + cpu->reg[RDS] = GETUREG(ds); + + cpu->reg[RFL] = GETUREG(flags); + + if(i = GETUREG(trap)){ + cpu->reg[RSS] = 0x0000; + cpu->reg[RSP] = 0x7C00; + cpu->reg[RCS] = (RMCODE>>4)&0xF000; + cpu->reg[RIP] = RMCODE & 0xFFFF; + memory[RMCODE] = 0xf4; /* HLT instruction */ + if(intr(cpu, i) < 0) + return Ebadtrap; + } else { + cpu->reg[RSS] = GETUREG(ss); + cpu->reg[RSP] = GETUREG(sp); + cpu->reg[RCS] = GETUREG(cs); + cpu->reg[RIP] = GETUREG(pc); + } + + startclock(); + for(;;){ + if(cputrace) + fprint(2, "%C\n", cpu); + switch(i = xec(cpu, (porttrace | cputrace) ? 1 : 100000)){ + case -1: + if(flushed(r)){ + err = Eintr; + break; + } + runclock(); + continue; + + /* normal interrupts */ + default: + if(intr(cpu, i) < 0){ + err = Ebadtrap; + break; + } + continue; + + /* pseudo-interrupts */ + case EHALT: + err = nil; + break; + case EIO: + err = Eio; + break; + case EMEM: + err = Emem; + break; + + /* processor traps */ + case EDIV0: + case EDEBUG: + case ENMI: + case EBRK: + case EINTO: + case EBOUND: + case EBADOP: + case ENOFPU: + case EDBLF: + case EFPUSEG: + case EBADTSS: + case ENP: + case ESTACK: + case EGPF: + case EPF: + PUTUREG(trap, i); + err = trapstr[i]; + break; + } + + break; + } + + if(err) + fprint(2, "%s\n%C\n", err, cpu); + + PUTUREG(di, cpu->reg[RDI]); + PUTUREG(si, cpu->reg[RSI]); + PUTUREG(bp, cpu->reg[RBP]); + PUTUREG(bx, cpu->reg[RBX]); + PUTUREG(dx, cpu->reg[RDX]); + PUTUREG(cx, cpu->reg[RCX]); + PUTUREG(ax, cpu->reg[RAX]); + + PUTUREG(gs, cpu->reg[RGS]); + PUTUREG(fs, cpu->reg[RFS]); + PUTUREG(es, cpu->reg[RES]); + PUTUREG(ds, cpu->reg[RDS]); + + PUTUREG(flags, cpu->reg[RFL]); + + PUTUREG(pc, cpu->reg[RIP]); + PUTUREG(cs, cpu->reg[RCS]); + PUTUREG(sp, cpu->reg[RSP]); + PUTUREG(ss, cpu->reg[RSS]); + + return err; +} + +enum { + Qroot, + Qcall, + Qmem, + Nqid, +}; + +static struct Qtab { + char *name; + int mode; + int type; + int length; +} qtab[Nqid] = { + "/", + DMDIR|0555, + QTDIR, + 0, + + "realmode", + 0666, + 0, + 0, + + "realmodemem", + 0666, + 0, + MEMSIZE, +}; + +static int +fillstat(ulong qid, Dir *d) +{ + struct Qtab *t; + + memset(d, 0, sizeof(Dir)); + d->uid = "realemu"; + d->gid = "realemu"; + d->muid = ""; + d->qid = (Qid){qid, 0, 0}; + d->atime = time(0); + t = qtab + qid; + d->name = t->name; + d->qid.type = t->type; + d->mode = t->mode; + d->length = t->length; + return 1; +} + +static void +fsattach(Req *r) +{ + char *spec; + + spec = r->ifcall.aname; + if(spec && spec[0]){ + respond(r, Ebadspec); + return; + } + r->fid->qid = (Qid){Qroot, 0, QTDIR}; + r->ofcall.qid = r->fid->qid; + respond(r, nil); +} + +static void +fsstat(Req *r) +{ + fillstat((ulong)r->fid->qid.path, &r->d); + r->d.name = estrdup9p(r->d.name); + r->d.uid = estrdup9p(r->d.uid); + r->d.gid = estrdup9p(r->d.gid); + r->d.muid = estrdup9p(r->d.muid); + respond(r, nil); +} + +static char* +fswalk1(Fid *fid, char *name, Qid *qid) +{ + int i; + ulong path; + + path = fid->qid.path; + switch(path){ + case Qroot: + if (strcmp(name, "..") == 0) { + *qid = (Qid){Qroot, 0, QTDIR}; + fid->qid = *qid; + return nil; + } + for(i = fid->qid.path; iqid = *qid; + return nil; + } + return Enonexist; + + default: + return Ewalk; + } +} + +static void +fsopen(Req *r) +{ + static int need[4] = { 4, 2, 6, 1 }; + struct Qtab *t; + int n; + + t = qtab + r->fid->qid.path; + n = need[r->ifcall.mode & 3]; + if((n & t->mode) != n) + respond(r, Eperm); + else + respond(r, nil); +} + +static int +readtopdir(Fid*, uchar *buf, long off, int cnt, int blen) +{ + int i, m, n; + long pos; + Dir d; + + n = 0; + pos = 0; + for (i = 1; i < Nqid; i++){ + fillstat(i, &d); + m = convD2M(&d, &buf[n], blen-n); + if(off <= pos){ + if(m <= BIT16SZ || m > cnt) + break; + n += m; + cnt -= m; + } + pos += m; + } + return n; +} + +static Channel *reqchan; + +static void +cpuproc(void *) +{ + static struct Ureg rmu; + ulong path; + vlong o; + ulong n; + char *p; + Req *r; + + threadsetname("cpuproc"); + + while(r = recvp(reqchan)){ + if(flushed(r)){ + respond(r, Eintr); + continue; + } + + path = r->fid->qid.path; + + p = r->ifcall.data; + n = r->ifcall.count; + o = r->ifcall.offset; + + switch(((int)r->ifcall.type<<8)|path){ + case (Tread<<8) | Qmem: + readbuf(r, memory, MEMSIZE); + respond(r, nil); + break; + + case (Tread<<8) | Qcall: + readbuf(r, &rmu, sizeof rmu); + respond(r, nil); + break; + + case (Twrite<<8) | Qmem: + if(o < 0 || o >= MEMSIZE || o+n > MEMSIZE){ + respond(r, Ebadoff); + break; + } + memmove(memory + o, p, n); + r->ofcall.count = n; + respond(r, nil); + break; + + case (Twrite<<8) | Qcall: + if(n != sizeof rmu){ + respond(r, Ebadureg); + break; + } + memmove(&rmu, p, n); + if(p = realmode(&cpu, &rmu, r)){ + respond(r, p); + break; + } + r->ofcall.count = n; + respond(r, nil); + break; + } + } +} + +static Channel *flushchan; + +static int +flushed(void *r) +{ + return nbrecvp(flushchan) == r; +} + +static void +fsflush(Req *r) +{ + nbsendp(flushchan, r->oldreq); + respond(r, nil); +} + +static void +dispatch(Req *r) +{ + if(!nbsendp(reqchan, r)) + respond(r, Ebusy); +} + +static void +fsread(Req *r) +{ + switch((ulong)r->fid->qid.path){ + case Qroot: + r->ofcall.count = readtopdir(r->fid, (void*)r->ofcall.data, r->ifcall.offset, + r->ifcall.count, r->ifcall.count); + respond(r, nil); + break; + default: + dispatch(r); + } +} + +static void +fsend(Srv*) +{ + threadexitsall(nil); +} + +static Srv fs = { + .attach= fsattach, + .walk1= fswalk1, + .open= fsopen, + .read= fsread, + .write= dispatch, + .stat= fsstat, + .flush= fsflush, + .end= fsend, +}; + +static void +usage(void) +{ + fprint(2, "usgae:\t%s [-Dpt] [-s srvname] [-m mountpoint]\n", argv0); + exits("usage"); +} + +void +threadmain(int argc, char *argv[]) +{ + char *mnt = "/dev"; + char *srv = nil; + + ARGBEGIN{ + case 'D': + chatty9p++; + break; + case 'p': + porttrace = 1; + break; + case 't': + cputrace = 1; + break; + case 's': + srv = EARGF(usage()); + mnt = nil; + break; + case 'm': + mnt = EARGF(usage()); + break; + default: + usage(); + }ARGEND + + cpuinit(); + + reqchan = chancreate(sizeof(Req*), 8); + flushchan = chancreate(sizeof(Req*), 8); + procrfork(cpuproc, nil, 16*1024, RFNAMEG|RFNOTEG); + threadpostmountsrv(&fs, srv, mnt, MBEFORE); +} diff --git a/sys/src/cmd/aux/realemu/mkfile b/sys/src/cmd/aux/realemu/mkfile new file mode 100644 index 000000000..47fdf53a1 --- /dev/null +++ b/sys/src/cmd/aux/realemu/mkfile @@ -0,0 +1,13 @@ + +#include +#include "dat.h" +#include "fns.h" + +enum { + AC0 = 0, + AC1, + AC2, + Actl, + + Readback = 3, + + RBC0 = 1<<1, + RBC1 = 1<<2, + RBC2 = 1<<3, + RBlatchstatus = 1<<4, + RBlatchcount = 1<<5, + + AMlatchcount = 0, + AMloonly, + AMhionly, + AMlohi, + + OM0 = 0, + OM1, + OM2, + OM3, + OM4, + OM5, + OM2b, + OM3b, +}; + +static void +latchstatus(Pit *ch) +{ + if(ch->rlatched) + return; + ch->rlatch[0] = ch->bcd | ch->omode<<1 | ch->amode<<4 | ch->count0<<6 | ch->out<<7; + ch->rcount = 0; + ch->rlatched = 1; +} + +static void +latchcount(Pit *ch) +{ + ulong w; + + if(ch->rlatched) + return; + w = ch->count & 0xFFFF; + if(ch->bcd) + w = (w % 10) + ((w/10) % 10)<<4 + ((w/100) % 10)<<8 + ((w/1000) % 10)<<12; + ch->rlatch[0] = w & 0xFF; + ch->rlatch[1] = (w >> 8) & 0xFF; + ch->rcount = 0; + ch->rlatched = 1; + switch(ch->amode){ + case AMhionly: + ch->rcount++; + break; + case AMlohi: + ch->rlatched++; + break; + } +} + +static void +setcount(Pit *ch) +{ + ulong w; + + w = (ulong)ch->wlatch[0] | (ulong)ch->wlatch[1] << 8; + if(ch->bcd) + w = (w & 0xF) + 10*((w >> 4)&0xF) + 100*((w >> 8)&0xF) + 1000*((w >> 12)&0xF); + ch->count = w; + ch->count0 = 0; +} + +static int +deccount(Pit *ch, vlong *cycles) +{ + if(ch->count0){ + *cycles = 0; + return 0; + } else { + vlong passed, remain; + + passed = *cycles; + if(ch->count == 0){ + ch->count = ch->bcd ? 9999 : 0xFFFF; + passed--; + } + if(passed <= ch->count){ + remain = 0; + ch->count -= passed; + } else { + remain = passed - ch->count; + ch->count = 0; + } + *cycles = remain; + return ch->count == 0; + } +} + +void +setgate(Pit *ch, uchar gate) +{ + if(ch->gate == 0 && gate) + ch->gateraised = 1; + ch->gate = gate; +} + +static void +clockpit1(Pit *ch, vlong *cycles) +{ + switch(ch->omode){ + case OM0: /* Interrupt On Terminal Count */ + if(ch->count0){ + setcount(ch); + ch->out = 0; + Next: + --*cycles; + return; + } + if(ch->gate && deccount(ch, cycles)){ + ch->out = 1; + return; + } + break; + + case OM1: /* Hardware Re-triggerable One-shot */ + if(ch->gateraised){ + ch->gateraised = 0; + setcount(ch); + ch->out = 0; + goto Next; + } + if(deccount(ch, cycles) && ch->out == 0){ + ch->out = 1; + return; + } + break; + + case OM2: /* Rate Generator */ + case OM2b: + ch->out = 1; + if(ch->count0){ + setcount(ch); + goto Next; + } + if(ch->gate == 0) + break; + if(ch->gateraised){ + ch->gateraised = 0; + setcount(ch); + goto Next; + } + if(deccount(ch, cycles)){ + setcount(ch); + ch->out = 0; + return; + } + break; + + case OM3: /* Square Wave Generator */ + case OM3b: + if(ch->count0){ + setcount(ch); + goto Next; + } + if(ch->gate == 0) + break; + if(ch->gateraised){ + ch->gateraised = 0; + setcount(ch); + goto Next; + } + if(deccount(ch, cycles)){ + setcount(ch); + ch->out ^= 1; + return; + } + break; + + case OM4: /* Software Triggered Strobe */ + ch->out = 1; + if(ch->count0){ + setcount(ch); + goto Next; + } + if(ch->gate && deccount(ch, cycles)){ + ch->out = 0; + return; + } + break; + + case OM5: /* Hardware Triggered Strobe */ + ch->out = 1; + if(ch->gateraised){ + ch->gateraised = 0; + setcount(ch); + goto Next; + } + if(deccount(ch, cycles)){ + ch->out = 0; + return; + } + break; + } + *cycles = 0; +} + +void +clockpit(Pit *pit, vlong cycles) +{ + Pit *ch; + int i; + + if(cycles <= 0) + return; + for(i = 0; iwlatched){ + vlong c; + + switch(ch->omode){ + case OM3: + case OM3b: + c = cycles * 2; + break; + default: + c = cycles; + } + while(c > 0) + clockpit1(ch, &c); + } + ch->gateraised = 0; + } +} + +uchar +rpit(Pit *pit, uchar addr) +{ + Pit *ch; + uchar data; + + if(addr >= Actl) + return 0; + ch = pit + addr; + if(ch->rlatched){ + data = ch->rlatch[ch->rcount & 1]; + ch->rlatched--; + } else { + data = 0; + switch(ch->amode){ + case AMloonly: + data = ch->count & 0xFF; + break; + case AMhionly: + data = (ch->count >> 8) & 0xFF; + break; + case AMlohi: + data = (ch->count >> ((ch->rcount & 1)<<3)) & 0xFF; + break; + } + } + ch->rcount++; + if(0) fprint(2, "rpit %p: %.2x %.2x\n", pit, (int)addr, (int)data); + return data; +} + +void +wpit(Pit *pit, uchar addr, uchar data) +{ + Pit *ch; + + if(0) fprint(2, "wpit %p: %.2x %.2x\n", pit, (int)addr, (int)data); + if(addr > Actl) + return; + if(addr == Actl){ + uchar sc, amode, omode, bcd; + + bcd = (data & 1); + omode = (data >> 1) & 7; + amode = (data >> 4) & 3; + sc = (data >> 6) & 3; + + if(sc == Readback){ + ch = nil; + for(;;){ + if(data & RBC0){ + ch = pit; + break; + } + if(data & RBC1){ + ch = pit + 1; + break; + } + if(data & RBC2){ + ch = pit + 2; + break; + } + break; + } + if(ch == nil) + return; + if((data & RBlatchcount) == 0) + latchcount(ch); + if((data & RBlatchstatus) == 0) + latchstatus(ch); + return; + } + + ch = pit + sc; + if(amode == AMlatchcount){ + latchcount(ch); + return; + } + ch->bcd = bcd; + + ch->amode = amode; + ch->omode = omode; + + ch->rlatched = 0; + ch->rcount = 0; + ch->rlatch[0] = 0; + ch->rlatch[1] = 0; + + ch->wlatched = 0; + ch->wcount = 0; + ch->wlatch[0] = 0; + ch->wlatch[1] = 0; + + ch->count0 = 1; + ch->out = !!omode; + return; + } + + ch = pit + addr; + switch(ch->amode){ + case AMloonly: + case AMhionly: + ch->wlatch[ch->amode - AMloonly] = data; + ch->wcount++; + break; + case AMlohi: + ch->wlatch[ch->wcount++ & 1] = data; + if(ch->wcount < 2) + return; + break; + } + ch->wlatched = ch->wcount; + ch->wcount = 0; + ch->count0 = 1; +} diff --git a/sys/src/cmd/aux/realemu/realemu.man b/sys/src/cmd/aux/realemu/realemu.man new file mode 100644 index 000000000..60763b385 --- /dev/null +++ b/sys/src/cmd/aux/realemu/realemu.man @@ -0,0 +1,104 @@ +.TH realemu 8 +.SH NAME +realemu \- software emulation of /dev/realmode +.SH SYNOPSIS +.B aux/realemu +[ +.B -Dpt +] [ +.B -s +.I srvname +] [ +.B -m +.I mountpoint +] +.SH DESCRIPTION +.PP +Originally, kernel provided +.B /dev/realmode +files with the +.IR arch (3) +device to access and call the +.SM BIOS. +.PP +Interrupts had to be disabled and the processor was switched in the +legacy 16-bit +.SM realmode +with memory protection disabled to execute +.SM BIOS +code. +.PP +This is problematic in case the +.SM BIOS +reprograms hardware currently +used by the operating system or when it reenables interrupts or just +crashes. This will freeze or reboot the machine with no way to +recover or diagnose the problem. +.PP +To avoid this, +.I realemu +is used to emulate the execution of the +.SM BIOS +routines by interpreting the machine instructions and intercepting +dangerous actions that would compromise the systems stability. +.PP +Running +.I realemu +with no arguments, it mounts itself before +.B /dev +and +replaces the original +.B /dev/realmode +file in the current namespace. +.PP +Then programs like +.IR vga (8) +can use it to make ther +.SM BIOS +calls. +.PP +The +.B D +flag will enable debug messages for 9P. The +.B p +and +.B t +flags +control tracing of i/o port access and cpu instructions to +stderr (fd 2). +.PP +When a +.I srvname +is given with the +.B s +argument, the default +.I mountpoint +is ignored and a +.SM 9P +channel is created in +.B /srv +that can be used to mount +the filesystem from another namespace. If a +.I mountpoint +is given before +the +.I srvname +argument then it is ignored, otherwise it will be used. +.SH EXAMPLES +The +.I realemu +process is only needed when accessing +.B /dev/realmode. +To invoke a subshell so that +.I realemu +exits normally after +.B aux/vga +completes: +.IP +.EX +% @{rfork n; aux/realemu; aux/vga -m vesa -l $vgasize} +.SH SOURCE +.B /sys/src/cmd/aux/realemu +.SH "SEE ALSO" +.IR vga (8), +.IR arch (3) diff --git a/sys/src/cmd/aux/realemu/vgalist b/sys/src/cmd/aux/realemu/vgalist new file mode 100644 index 000000000..3a0530584 --- /dev/null +++ b/sys/src/cmd/aux/realemu/vgalist @@ -0,0 +1,9 @@ +#vid did bios wired product name +100b 0030 5.30 STI NSC Geode GX2 +5533 8c2e 1.0 - T23 / S3 savage +1002 791e 01.00 - ATI RS690 +10de 002c B1 STI NVidia RivaTNT +15ad 0405 2.0 - VMware +- - 1.26 - Bochs +102b 0519 00 STI Matrox MILLENNIUM +5333 8901 Rev E - S3 Trio64V2/DX/GX diff --git a/sys/src/cmd/aux/realemu/xec.c b/sys/src/cmd/aux/realemu/xec.c new file mode 100644 index 000000000..8d63e6155 --- /dev/null +++ b/sys/src/cmd/aux/realemu/xec.c @@ -0,0 +1,1224 @@ +#include +#include +#include "dat.h" +#include "fns.h" + +#define sign(s) (1UL<<((s)-1)) +#define mask(s) (sign(s)|(sign(s)-1)) + +int cputrace; + +static void +push(Iarg *sp, Iarg *a) +{ + Iarg *p; + + p = amem(sp->cpu, a->len, RSS, ar(sp)); + p->off -= a->len; + aw(p, ar(a)); + aw(sp, p->off); +} + +static void +pop(Iarg *sp, Iarg *a) +{ + Iarg *p; + + p = amem(sp->cpu, a->len, RSS, ar(sp)); + aw(a, ar(p)); + aw(sp, p->off + a->len); +} + +static void +jump(Iarg *to) +{ + Cpu *cpu; + + cpu = to->cpu; + switch(to->atype){ + default: + abort(); + case AMp: + to = afar(to, 1, to->len); + case AAp: + cpu->reg[RCS] = to->seg; + case AJb: + case AJv: + cpu->reg[RIP] = to->off; + break; + case AEv: + cpu->reg[RIP] = ar(to); + break; + } +} + +static void +opcall(Cpu *cpu, Inst *i) +{ + Iarg *sp; + + sp = areg(cpu, cpu->slen, RSP); + switch(i->a1->atype){ + default: + abort(); + case AAp: + case AMp: + push(sp, areg(cpu, i->olen, RCS)); + case AJv: + case AEv: + push(sp, areg(cpu, i->olen, RIP)); + break; + } + jump(i->a1); +} + +static void +opint(Cpu *cpu, Inst *i) +{ + cpu->trap = ar(i->a1); + longjmp(cpu->jmp, 1); +} + +static void +opiret(Cpu *cpu, Inst *i) +{ + Iarg *sp; + + if(i->olen != 2) + trap(cpu, EBADOP); + sp = areg(cpu, cpu->slen, RSP); + pop(sp, areg(cpu, 2, RIP)); + pop(sp, areg(cpu, 2, RCS)); + pop(sp, areg(cpu, 2, RFL)); +} + +static void +opret(Cpu *cpu, Inst *i) +{ + Iarg *sp; + ulong c; + + sp = areg(cpu, cpu->slen, RSP); + pop(sp, areg(cpu, i->olen, RIP)); + if(c = ar(i->a1)) + aw(sp, ar(sp) + c); +} + +static void +opretf(Cpu *cpu, Inst *i) +{ + Iarg *sp; + ulong c; + + sp = areg(cpu, cpu->slen, RSP); + pop(sp, areg(cpu, i->olen, RIP)); + pop(sp, areg(cpu, i->olen, RCS)); + if(c = ar(i->a1)) + aw(sp, ar(sp) + c); +} + +static void +openter(Cpu *cpu, Inst *i) +{ + Iarg *sp, *bp; + ulong oframe, nframe; + int j, n; + + sp = areg(cpu, cpu->slen, RSP); + bp = areg(cpu, cpu->slen, RBP); + push(sp, bp); + oframe = ar(bp); + nframe = ar(sp); + n = ar(i->a2) % 32; + if(n > 0){ + for(j=1; jolen*j); + push(sp, bp); + } + push(sp, acon(cpu, i->olen, nframe)); + } + aw(bp, nframe); + aw(sp, nframe - ar(i->a1)); +} + +static void +opleave(Cpu *cpu, Inst *i) +{ + Iarg *sp; + + sp = areg(cpu, cpu->slen, RSP); + aw(sp, ar(areg(cpu, cpu->slen, RBP))); + pop(sp, areg(cpu, i->olen, RBP)); +} + +static void +oppush(Cpu *cpu, Inst *i) +{ + Iarg *sp; + + sp = areg(cpu, cpu->slen, RSP); + if(i->a1->len == 1) /* 0x6A push imm8 */ + push(sp, acon(cpu, i->olen, ar(i->a1))); + else + push(sp, i->a1); +} + +static void +oppop(Cpu *cpu, Inst *i) +{ + pop(areg(cpu, cpu->slen, RSP), i->a1); +} + +static void +oppusha(Cpu *cpu, Inst *i) +{ + Iarg *sp, *osp; + + sp = areg(cpu, cpu->slen, RSP); + osp = acon(cpu, i->olen, ar(sp)); + push(sp, areg(cpu, i->olen, RAX)); + push(sp, areg(cpu, i->olen, RCX)); + push(sp, areg(cpu, i->olen, RDX)); + push(sp, areg(cpu, i->olen, RBX)); + push(sp, osp); + push(sp, areg(cpu, i->olen, RBP)); + push(sp, areg(cpu, i->olen, RSI)); + push(sp, areg(cpu, i->olen, RDI)); +} + +static void +oppopa(Cpu *cpu, Inst *i) +{ + Iarg *sp; + + sp = areg(cpu, cpu->slen, RSP); + pop(sp, areg(cpu, i->olen, RDI)); + pop(sp, areg(cpu, i->olen, RSI)); + pop(sp, areg(cpu, i->olen, RBP)); + pop(sp, areg(cpu, i->olen, RBX)); // RSP + pop(sp, areg(cpu, i->olen, RBX)); + pop(sp, areg(cpu, i->olen, RDX)); + pop(sp, areg(cpu, i->olen, RCX)); + pop(sp, areg(cpu, i->olen, RAX)); +} + +static void +oppushf(Cpu *cpu, Inst *i) +{ + push(areg(cpu, cpu->slen, RSP), areg(cpu, i->olen, RFL)); +} + +static void +oppopf(Cpu *cpu, Inst *i) +{ + ulong *f, o; + + f = cpu->reg + RFL; + o = *f; + pop(areg(cpu, cpu->slen, RSP), areg(cpu, i->olen, RFL)); + *f &= ~(VM|RF); + *f |= (o & (VM|RF)); +} + +static void +oplahf(Cpu *cpu, Inst *i) +{ + aw(i->a1, cpu->reg[RFL]); +} + +static void +opsahf(Cpu *cpu, Inst *i) +{ + enum { MASK = SF|ZF|AF|PF|CF }; + ulong *f; + + f = cpu->reg + RFL; + *f &= ~MASK; + *f |= (ar(i->a1) & MASK); +} + +static void +opcli(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] &= ~IF; +} + +static void +opsti(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] |= IF; +} + +static void +opcld(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] &= ~DF; +} + +static void +opstd(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] |= DF; +} + +static void +opclc(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] &= ~CF; +} + +static void +opstc(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] |= CF; +} + +static void +opcmc(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] ^= CF; +} + +static void +parity(ulong *f, ulong r) +{ + static ulong tab[8] = { + 0x96696996, + 0x69969669, + 0x69969669, + 0x96696996, + 0x69969669, + 0x96696996, + 0x96696996, + 0x69969669, + }; + r &= 0xFF; + if((tab[r/32] >> (r%32)) & 1) + *f &= ~PF; + else + *f |= PF; +} + +static ulong +test(ulong *f, long r, int s) +{ + *f &= ~(CF|SF|ZF|OF|PF); + r &= mask(s); + if(r == 0) + *f |= ZF; + if(r & sign(s)) + *f |= SF; + parity(f, r); + return r; +} + +static void +opshl(Cpu *cpu, Inst *i) +{ + ulong *f, r, a, h; + int s, n; + + if((n = ar(i->a2) & 31) == 0) + return; + s = i->a1->len*8; + a = ar(i->a1); + f = cpu->reg + RFL; + r = test(f, a<a1, r); + if((a<<(n-1)) & h) + *f |= CF; + if(n == 1 && ((a^r) & h)) + *f |= OF; +} + +static void +opshr(Cpu *cpu, Inst *i) +{ + ulong *f, a; + int s, n; + + if((n = ar(i->a2) & 31) == 0) + return; + s = i->a1->len*8; + a = ar(i->a1); + f = cpu->reg + RFL; + aw(i->a1, test(f, a>>n, s)); + if(a & sign(n)) + *f |= CF; + if(n == 1 && (a & sign(s))) + *f |= OF; +} + +static void +opsar(Cpu *cpu, Inst *i) +{ + ulong *f; + long a; + int n; + + if((n = ar(i->a2) & 31) == 0) + return; + a = ars(i->a1); + f = cpu->reg + RFL; + aw(i->a1, test(f, a>>n, i->a1->len*8)); + if(a & sign(n)) + *f |= CF; +} + +static void +opshld(Cpu *cpu, Inst *i) +{ + ulong *f, a; + int s, n; + + if((n = ar(i->a3) & 31) == 0) + return; + s = i->a1->len*8; + a = ar(i->a1); + f = cpu->reg + RFL; + aw(i->a1, test(f, (a<a2)>>(s-n)), s)); + if((a<<(n-1)) & sign(s)) + *f |= CF; +} + +static void +opshrd(Cpu *cpu, Inst *i) +{ + ulong *f, a; + int s, n; + + if((n = ar(i->a3) & 31) == 0) + return; + s = i->a1->len*8; + a = ar(i->a1); + f = cpu->reg + RFL; + aw(i->a1, test(f, (a>>n)|(ar(i->a2)<<(s-n)), s)); + if(a & sign(n)) + *f |= CF; +} + + +static void +oprcl(Cpu *cpu, Inst *i) +{ + ulong *f, a, r; + int s, n; + + s = i->a1->len*8; + n = ar(i->a2) % (s+1); + a = ar(i->a1); + r = (a<>(s-n))>>1); + f = cpu->reg + RFL; + if(*f & CF) + r |= sign(n); + aw(i->a1, r); + *f &= ~(CF|OF); + if((a>>(s-n)) & 1) + *f |= CF; + if((a ^ r) & sign(s)) + *f |= OF; + parity(f, r); +} + +static void +oprcr(Cpu *cpu, Inst *i) +{ + ulong *f, a, r, h; + int s, n; + + s = i->a1->len*8; + n = ar(i->a2) % (s+1); + a = ar(i->a1); + h = a<<(s-n); + r = (a>>n) | (h<<1); + f = cpu->reg + RFL; + if(*f & CF) + r |= 1<<(s-n); + aw(i->a1, r); + *f &= ~(CF|OF); + if(h & sign(s)) + *f |= CF; + if((a ^ r) & sign(s)) + *f |= OF; + parity(f, r); +} + +static void +oprol(Cpu *cpu, Inst *i) +{ + ulong *f, a, r; + int s, n; + + s = i->a1->len*8; + n = ar(i->a2) & (s-1); + a = ar(i->a1); + r = (a<>(s-n)); + f = cpu->reg + RFL; + aw(i->a1, r); + *f &= ~(CF|OF); + if(r & 1) + *f |= CF; + if((a ^ r) & sign(s)) + *f |= OF; + parity(f, r); +} + +static void +opror(Cpu *cpu, Inst *i) +{ + ulong *f, a, r; + int s, n; + + s = i->a1->len*8; + n = ar(i->a2) & (s-1); + a = ar(i->a1); + r = (a>>n) | (a<<(s-n)); + aw(i->a1, r); + f = cpu->reg + RFL; + *f &= ~(CF|OF); + if(r & sign(s)) + *f |= CF; + if((a ^ r) & sign(s)) + *f |= OF; + parity(f, r); +} + +static void +opbts(Cpu *cpu, Inst *i) +{ + ulong a, m; + int n; + + a = ar(i->a1); + n = ar(i->a2) & 31; + m = 1<reg[RFL] |= CF; + else { + cpu->reg[RFL] &= ~CF; + aw(i->a1, a | m); + } +} + +static void +opbtr(Cpu *cpu, Inst *i) +{ + ulong a, m; + int n; + + a = ar(i->a1); + n = ar(i->a2) & 31; + m = 1<reg[RFL] |= CF; + aw(i->a1, a & ~m); + } else + cpu->reg[RFL] &= ~CF; +} + +static void +opbitscan(Cpu *cpu, Inst *i) +{ + ulong a; + + if((a = ar(i->a2)) == 0) + cpu->reg[RFL] |= ZF; + else { + int j; + + if(i->op == OBSF){ + for(j = 0; (a & (1<a2->len*8-1; (a & (1<a1, j); + cpu->reg[RFL] &= ~ZF; + } +} + +static void +opand(Cpu *cpu, Inst *i) +{ + aw(i->a1, test(cpu->reg + RFL, ars(i->a1) & ars(i->a2), i->a1->len*8)); +} + +static void +opor(Cpu *cpu, Inst *i) +{ + aw(i->a1, test(cpu->reg + RFL, ars(i->a1) | ars(i->a2), i->a1->len*8)); +} + +static void +opxor(Cpu *cpu, Inst *i) +{ + aw(i->a1, test(cpu->reg + RFL, ars(i->a1) ^ ars(i->a2), i->a1->len*8)); +} + +static void +opnot(Cpu *, Inst *i) +{ + aw(i->a1, ~ar(i->a1)); +} + +static void +optest(Cpu *cpu, Inst *i) +{ + test(cpu->reg + RFL, ars(i->a1) & ars(i->a2), i->a1->len*8); +} + +static ulong +add(ulong *f, long a, long b, int c, int s) +{ + ulong r, cc, m, n; + + *f &= ~(AF|CF|SF|ZF|OF|PF); + + n = sign(s); + m = mask(s); + r = a + b + c; + r &= m; + if(r == 0) + *f |= ZF; + if(r & n) + *f |= SF; + cc = (a & b) | (~r & (a | b)); + if(cc & n) + *f |= CF; + if((cc ^ (cc >> 1)) & (n>>1)) + *f |= OF; + parity(f, r); + return r; +} + +static ulong +sub(ulong *f, long a, long b, int c, int s) +{ + ulong r, bc, n; + + *f &= ~(AF|CF|SF|ZF|OF|PF); + + r = a - b - c; + n = sign(s); + r &= mask(s); + if(r == 0) + *f |= ZF; + if(r & n) + *f |= SF; + a = ~a; + bc = (a & b) | (r & (a | b)); + if(bc & n) + *f |= CF; + if((bc ^ (bc >> 1)) & (n>>1)) + *f |= OF; + parity(f, r); + return r; +} + +static void +opadd(Cpu *cpu, Inst *i) +{ + aw(i->a1, add(cpu->reg + RFL, ars(i->a1), ars(i->a2), 0, i->a1->len*8)); +} + +static void +opadc(Cpu *cpu, Inst *i) +{ + ulong *f = cpu->reg + RFL; + + aw(i->a1, add(f, ars(i->a1), ars(i->a2), (*f & CF) != 0, i->a1->len*8)); +} + +static void +opsub(Cpu *cpu, Inst *i) +{ + aw(i->a1, sub(cpu->reg + RFL, ars(i->a1), ars(i->a2), 0, i->a1->len*8)); +} + +static void +opsbb(Cpu *cpu, Inst *i) +{ + ulong *f = cpu->reg + RFL; + + aw(i->a1, sub(f, ars(i->a1), ars(i->a2), (*f & CF) != 0, i->a1->len*8)); +} + +static void +opneg(Cpu *cpu, Inst *i) +{ + aw(i->a1, sub(cpu->reg + RFL, 0, ars(i->a1), 0, i->a1->len*8)); +} + +static void +opcmp(Cpu *cpu, Inst *i) +{ + sub(cpu->reg + RFL, ars(i->a1), ars(i->a2), 0, i->a1->len*8); +} + +static void +opinc(Cpu *cpu, Inst *i) +{ + ulong *f, o; + + f = cpu->reg + RFL; + o = *f; + aw(i->a1, add(f, ars(i->a1), 1, 0, i->a1->len*8)); + *f = (*f & ~CF) | (o & CF); +} + +static void +opdec(Cpu *cpu, Inst *i) +{ + ulong *f, o; + + f = cpu->reg + RFL; + o = *f; + aw(i->a1, sub(f, ars(i->a1), 1, 0, i->a1->len*8)); + *f = (*f & ~CF) | (o & CF); +} + +static void +opmul(Cpu *cpu, Inst *i) +{ + Iarg *la, *ha; + ulong l, h, m; + uvlong r; + int s; + + s = i->a2->len*8; + m = mask(s); + r = ar(i->a2) * ar(i->a3); + l = r & m; + h = (r >> s) & m; + if(i->a1->atype != AAX) + abort(); + la = areg(cpu, i->a2->len, RAX); + if(s == 8){ + ha = adup(la); + ha->tag |= TH; + } else + ha = areg(cpu, i->a2->len, RDX); + aw(la, l); + aw(ha, h); + if(h) + cpu->reg[RFL] |= (CF|OF); + else + cpu->reg[RFL] &= ~(CF|OF); +} + +static void +opimul(Cpu *cpu, Inst *i) +{ + ulong l, h, m, n; + vlong r; + int s; + + s = i->a2->len*8; + m = mask(s); + n = sign(s); + r = ars(i->a2) * ars(i->a3); + h = (r >> s) & m; + l = r & m; + if(i->a1->atype == AAX){ + Iarg *la, *ha; + + la = areg(cpu, i->a2->len, RAX); + if(s == 8){ + ha = adup(la); + ha->tag |= TH; + }else + ha = areg(cpu, i->a2->len, RDX); + aw(la, l); + aw(ha, h); + } else + aw(i->a1, l); + if((r > (vlong)n-1) || (r < -(vlong)n)) + cpu->reg[RFL] |= (CF|OF); + else + cpu->reg[RFL] &= ~(CF|OF); +} + +static void +opdiv(Cpu *cpu, Inst *i) +{ + Iarg *qa, *ra; + uvlong n, q; + ulong m, r, d; + int s; + + s = i->a1->len*8; + m = mask(s); + d = ar(i->a1); + if(d == 0) + trap(cpu, EDIV0); + if(s == 8){ + qa = areg(cpu, 1, RAX); + ra = adup(qa); + ra->tag |= TH; + } else { + qa = areg(cpu, i->olen, RAX); + ra = areg(cpu, i->olen, RDX); + } + n = (uvlong)ar(ra)< m) + trap(cpu, EGPF); + r = n%d; + aw(ra, r); + aw(qa, q); +} + + +static int +cctrue(Cpu *cpu, Inst *i) +{ + enum { SO = 1<<16, /* pseudo-flag SF != OF */ }; + static ulong test[] = { + OF, /* JO, JNO */ + CF, /* JC, JNC */ + ZF, /* JZ, JNZ */ + CF|ZF, /* JBE,JA */ + SF, /* JS, JNS */ + PF, /* JP, JNP */ + SO, /* JL, JGE */ + SO|ZF, /* JLE,JG */ + }; + ulong f, t; + uchar c; + + c = i->code; + switch(c){ + case 0xE3: /* JCXZ */ + return ar(areg(cpu, i->alen, RCX)) == 0; + case 0xEB: /* JMP */ + case 0xE9: + case 0xEA: + case 0xFF: + return 1; + default: + f = cpu->reg[RFL]; + if(((f&SF)!=0) ^ ((f&OF)!=0)) + f |= SO; + t = test[(c>>1)&7]; + return ((t&f) != 0) ^ (c&1); + } +} + +static void +opjump(Cpu *cpu, Inst *i) +{ + if(cctrue(cpu, i)) + jump(i->a1); +} + +static void +oploop(Cpu *cpu, Inst *i) +{ + Iarg *cx; + ulong c; + + switch(i->op){ + default: + abort(); + case OLOOPNZ: + if(cpu->reg[RFL] & ZF) + return; + break; + case OLOOPZ: + if((cpu->reg[RFL] & ZF) == 0) + return; + break; + case OLOOP: + break; + } + cx = areg(cpu, i->alen, RCX); + c = ar(cx) - 1; + aw(cx, c); + if(c) + jump(i->a1); +} + +static void +oplea(Cpu *, Inst *i) +{ + aw(i->a1, i->a2->off); +} + +static void +opmov(Cpu *, Inst *i) +{ + aw(i->a1, ar(i->a2)); +} + +static void +opcbw(Cpu *cpu, Inst *i) +{ + aw(areg(cpu, i->olen, RAX), ars(areg(cpu, i->olen>>1, RAX))); +} + +static void +opcwd(Cpu *cpu, Inst *i) +{ + aw(areg(cpu, i->olen, RDX), ars(areg(cpu, i->olen, RAX))>>(i->olen*8-1)); +} + +static void +opmovsx(Cpu *, Inst *i) +{ + aw(i->a1, ars(i->a2)); +} + +static void +opxchg(Cpu *, Inst *i) +{ + ulong x; + + x = ar(i->a1); + aw(i->a1, ar(i->a2)); + aw(i->a2, x); +} + +static void +oplfp(Cpu *, Inst *i) +{ + Iarg *p; + + p = afar(i->a3, i->olen, i->olen); + aw(i->a1, p->seg); + aw(i->a2, p->off); +} + +static void +opbound(Cpu *cpu, Inst *i) +{ + ulong p, s, e; + + p = ar(i->a1); + s = ar(i->a2); + e = ar(i->a3); + if((p < s) || (p >= e)) + trap(cpu, EBOUND); +} + +static void +opxlat(Cpu *cpu, Inst *i) +{ + aw(i->a1, ar(amem(cpu, i->a1->len, i->sreg, ar(areg(cpu, i->alen, i->a2->reg)) + ar(i->a1)))); +} + +static void +opcpuid(Cpu *cpu, Inst *) +{ + static struct { + ulong level; + + ulong ax; + ulong bx; + ulong cx; + ulong dx; + } tab[] = { + 0, + 5, + 0x756e6547, + 0x49656e69, + 0x6c65746e, + 1, + 4<<8, + 0x00000000, + 0x00000000, + 0x00000000, + 2, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 3, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + }; + + int i; + + for(i=0; ireg[RAX]){ + cpu->reg[RAX] = tab[i].ax; + cpu->reg[RBX] = tab[i].bx; + cpu->reg[RCX] = tab[i].cx; + cpu->reg[RDX] = tab[i].dx; + return; + } + } + trap(cpu, EBADOP); +} + +static void +opmovs(Cpu *cpu, Inst *i) +{ + Iarg *cx, *d, *s; + ulong c; + int n; + + d = adup(i->a1); + s = adup(i->a2); + n = s->len; + if(cpu->reg[RFL] & DF) + n = -n; + if(i->rep){ + cx = areg(cpu, i->alen, RCX); + c = ar(cx); + } else { + cx = nil; + c = 1; + } + while(c){ + aw(d, ar(s)); + d->off += n; + s->off += n; + c--; + } + aw(areg(cpu, i->alen, RDI), d->off); + aw(areg(cpu, i->alen, RSI), s->off); + if(cx) + aw(cx, 0); +} + +static void +oplods(Cpu *cpu, Inst *i) +{ + Iarg *cx, *s; + ulong c; + int n; + + s = adup(i->a2); + n = s->len; + if(cpu->reg[RFL] & DF) + n = -n; + if(i->rep){ + cx = areg(cpu, i->alen, RCX); + c = ar(cx); + } else { + cx = nil; + c = 1; + } + if(c){ + s->off += n*(c-1); + aw(i->a1, ar(s)); + s->off += n; + } + aw(areg(cpu, i->alen, RSI), s->off); + if(cx) + aw(cx, 0); +} + +static void +opstos(Cpu *cpu, Inst *i) +{ + Iarg *cx, *d; + ulong c, a; + int n; + + d = adup(i->a1); + n = d->len; + if(cpu->reg[RFL] & DF) + n = -n; + if(i->rep){ + cx = areg(cpu, i->alen, RCX); + c = ar(cx); + } else { + cx = nil; + c = 1; + } + a = ar(i->a2); + while(c){ + aw(d, a); + d->off += n; + c--; + } + aw(areg(cpu, i->alen, RDI), d->off); + if(cx) + aw(cx, 0); +} + +static void +opin(Cpu *cpu, Inst *i) +{ + Bus *io; + + io = cpu->port; + aw(i->a1, io->r(io->aux, ar(i->a2) & 0xFFFF, i->a1->len)); +} + +static void +opout(Cpu *cpu, Inst *i) +{ + Bus *io; + + io = cpu->port; + io->w(io->aux, ar(i->a1) & 0xFFFF, ar(i->a2), i->a2->len); +} + +static void +opnop(Cpu *, Inst *) +{ +} + +static void +ophlt(Cpu *cpu, Inst *) +{ + trap(cpu, EHALT); +} + +static void (*exctab[NUMOP])(Cpu *cpu, Inst*) = { + [OINT] = opint, + [OIRET] = opiret, + + [OCALL] = opcall, + [OJUMP] = opjump, + + [OLOOP] = oploop, + [OLOOPZ] = oploop, + [OLOOPNZ] = oploop, + + [ORET] = opret, + [ORETF] = opretf, + + [OENTER] = openter, + [OLEAVE] = opleave, + + [OPUSH] = oppush, + [OPOP] = oppop, + + [OPUSHF] = oppushf, + [OPOPF] = oppopf, + [OLAHF] = oplahf, + [OSAHF] = opsahf, + + [OPUSHA] = oppusha, + [OPOPA] = oppopa, + + [OCLI] = opcli, + [OSTI] = opsti, + [OCLC] = opclc, + [OSTC] = opstc, + [OCMC] = opcmc, + [OCLD] = opcld, + [OSTD] = opstd, + + [OSHL] = opshl, + [OSHR] = opshr, + [OSAR] = opsar, + + [OSHLD] = opshld, + [OSHRD] = opshrd, + + [ORCL] = oprcl, + [ORCR] = oprcr, + [OROL] = oprol, + [OROR] = opror, + + [OBTS] = opbts, + [OBTR] = opbtr, + [OBSF] = opbitscan, + [OBSR] = opbitscan, + + [OAND] = opand, + [OOR] = opor, + [OXOR] = opxor, + [ONOT] = opnot, + [OTEST] = optest, + + [OADD] = opadd, + [OADC] = opadc, + [OSUB] = opsub, + [OSBB] = opsbb, + [ONEG] = opneg, + [OCMP] = opcmp, + + [OINC] = opinc, + [ODEC] = opdec, + + [OMUL] = opmul, + [OIMUL] = opimul, + [ODIV] = opdiv, + + [OLEA] = oplea, + [OMOV] = opmov, + [OCBW] = opcbw, + [OCWD] = opcwd, + [OMOVZX] = opmov, + [OMOVSX] = opmovsx, + [OXCHG] = opxchg, + [OLFP] = oplfp, + [OBOUND] = opbound, + [OXLAT] = opxlat, + + [OCPUID] = opcpuid, + + [OMOVS] = opmovs, + [OSTOS] = opstos, + [OLODS] = oplods, + + [OIN] = opin, + [OOUT] = opout, + + [ONOP] = opnop, + [OHLT] = ophlt, +}; + +void +trap(Cpu *cpu, int e) +{ + cpu->reg[RIP] = cpu->oldip; + cpu->trap = e; + longjmp(cpu->jmp, 1); +} + +int +intr(Cpu *cpu, int v) +{ + Iarg *sp, *ip, *cs, *iv; + + if(v < 0 || v > 0xff || cpu->olen != 2) + return -1; + + sp = areg(cpu, cpu->slen, RSP); + cs = areg(cpu, 2, RCS); + ip = areg(cpu, 2, RIP); + + iv = amem(cpu, 2, R0S, v * 4); + + push(sp, areg(cpu, 2, RFL)); + push(sp, cs); + push(sp, ip); + + cpu->reg[RIP] = ar(iv); + iv->off += 2; + cpu->reg[RCS] = ar(iv); + return 0; +} + +int +xec(Cpu *cpu, int n) +{ + if(setjmp(cpu->jmp)) + return cpu->trap; + while(n--){ + void (*f)(Cpu *, Inst *); + Iarg *ip; + Inst i; + + cpu->ic++; + + ip = amem(cpu, 1, RCS, cpu->oldip = cpu->reg[RIP]); + decode(ip, &i); + cpu->reg[RIP] = ip->off; + if((f = exctab[i.op]) == nil) + trap(cpu, EBADOP); + f(cpu, &i); + } + return n; +} diff --git a/tmp/.dummy b/tmp/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/usr/glenda/bin/rc/pull b/usr/glenda/bin/rc/pull new file mode 100755 index 000000000..42b5ecc27 --- /dev/null +++ b/usr/glenda/bin/rc/pull @@ -0,0 +1,17 @@ +#!/bin/rc + +rfork e +flags=() +while(! ~ $#* 0 && ~ $1 -*){ + if(~ $1 -c -s){ + flags=($flags $1) + shift + } + flags=($flags $1) + shift +} +if(test -f /srv/kfs.cmd) + disk/kfscmd allow +replica/pull -v $flags /dist/replica/network $* +if(test -f /srv/kfs.cmd) + disk/kfscmd disallow diff --git a/usr/glenda/bin/rc/riostart b/usr/glenda/bin/rc/riostart new file mode 100755 index 000000000..c8515d08e --- /dev/null +++ b/usr/glenda/bin/rc/riostart @@ -0,0 +1,17 @@ +#!/bin/rc + +scr=(`{cat /dev/draw/new >[2]/dev/null || status=''}) +wid=$scr(11) +ht=$scr(12) + +window 0,0,161,117 stats -lmisce +window 161,0,560,117 faces -i + +if(~ `{screensize} small) + dump=acme.dump.small +if not + dump=acme.dump + +a=`{echo $wid-35 | hoc } +window 60,90,$a,$ht acme -l lib/$dump +window 20,140,610,450 /usr/glenda/lib/first.window diff --git a/usr/glenda/bin/rc/screensize b/usr/glenda/bin/rc/screensize new file mode 100755 index 000000000..e38ed4d47 --- /dev/null +++ b/usr/glenda/bin/rc/screensize @@ -0,0 +1,9 @@ +#!/bin/rc + +scr=(`{cat /dev/draw/new >[2]/dev/null || status=''}) +wid=$scr(11) +ht=$scr(12) +if(test $wid -le 1024) + echo small +if not + echo normal diff --git a/usr/glenda/lib/acme.dump b/usr/glenda/lib/acme.dump new file mode 100644 index 000000000..1be4a18ec --- /dev/null +++ b/usr/glenda/lib/acme.dump @@ -0,0 +1,12 @@ +/usr/glenda +/lib/font/bit/lucidasans/unicode.8.font +/lib/font/bit/lucm/unicode.9.font + 0 20 75 +f 0 24 0 0 1 + 24 34 16 1 0 /usr/glenda/ Del Snarf Get | Look +f 1 25 567 567 1 + 25 34 567 0 0 readme.acme Del Snarf Undo | Look +e 2 0 0 0 1 + 23 49 52 0 0 /mail/fs/mbox/ Del Snarf | Look Put Mail Delmesg +/acme/mail +Mail mbox diff --git a/usr/glenda/lib/acme.dump.small b/usr/glenda/lib/acme.dump.small new file mode 100644 index 000000000..518a483f7 --- /dev/null +++ b/usr/glenda/lib/acme.dump.small @@ -0,0 +1,16 @@ +/usr/glenda +/lib/font/bit/lucidasans/unicode.7.font +/lib/font/bit/lucidasans/typelatin1.7.font + 0 20 75 +f 0 24 0 0 1 + 24 34 16 1 0 /usr/glenda/ Del Snarf Get | Look +e 0 0 0 0 8 + 28 51 6 0 1 /usr/glenda/-serzone Del Snarf | Look Send Noscroll +/usr/glenda +win +f 1 25 567 567 1 + 25 34 567 0 0 readme.acme Del Snarf Undo | Look +e 2 0 0 0 1 + 23 49 52 0 0 /mail/fs/mbox/ Del Snarf | Look Put Mail Delmesg +/acme/mail +Mail mbox diff --git a/usr/glenda/lib/first.window b/usr/glenda/lib/first.window new file mode 100755 index 000000000..cf9544e98 --- /dev/null +++ b/usr/glenda/lib/first.window @@ -0,0 +1,5 @@ +#!/bin/rc +echo -n readme > /dev/label +cat readme.rio +exec rc -i + diff --git a/usr/glenda/lib/newstime b/usr/glenda/lib/newstime new file mode 100644 index 000000000..e69de29bb diff --git a/usr/glenda/lib/plumbing b/usr/glenda/lib/plumbing new file mode 100644 index 000000000..b209d2d66 --- /dev/null +++ b/usr/glenda/lib/plumbing @@ -0,0 +1,6 @@ +# to update: cp /usr/glenda/lib/plumbing /mnt/plumb/rules + +editor = acme + +include basic + diff --git a/usr/glenda/lib/profile b/usr/glenda/lib/profile new file mode 100644 index 000000000..fe2728986 --- /dev/null +++ b/usr/glenda/lib/profile @@ -0,0 +1,36 @@ +bind -a $home/bin/rc /bin +bind -a $home/bin/$cputype /bin +bind -c tmp /tmp +if(! syscall create /tmp/xxx 1 0666 >[2]/dev/null) + ramfs # in case we're running off a cd +font = /lib/font/bit/pelm/euro.9.font +upas/fs +fn cd { builtin cd $* && awd } # for acme +switch($service){ +case terminal + plumber + echo -n accelerated > '#m/mousectl' + echo -n 'res 3' > '#m/mousectl' + prompt=('term% ' ' ') + fn term%{ $* } + exec rio -i riostart +case cpu + if (test -e /mnt/term/mnt/wsys) { # rio already running + bind -a /mnt/term/mnt/wsys /dev + if(test -w /dev/label) + echo -n $sysname > /dev/label + } + bind /mnt/term/dev/cons /dev/cons + bind /mnt/term/dev/consctl /dev/consctl + bind -a /mnt/term/dev /dev + prompt=('cpu% ' ' ') + fn cpu%{ $* } + news + if (! test -e /mnt/term/mnt/wsys) { # cpu call from drawterm + font=/lib/font/bit/pelm/latin1.8.font + exec rio + } +case con + prompt=('cpu% ' ' ') + news +} diff --git a/usr/glenda/readme.acme b/usr/glenda/readme.acme new file mode 100644 index 000000000..18cc16ad0 --- /dev/null +++ b/usr/glenda/readme.acme @@ -0,0 +1,102 @@ +Welcome to acme, the editor/shell/window system hybrid. Acme is a +complete environment you can use to edit, run programs, browse the +file system, etc. + +You can scroll the text this window by moving the mouse into +the window (no clicking necessary) and typing the up and down +arrows. + +When you start Acme, you see several windows layered into two +columns. Above each window, you can see a ``tag line'' (in blue). The +first thing to notice is that all the text you see is just that: +text. You can edit anything at will. + +For example, in the left column is a directory window. +If you look at the window's tag line, you will see that it contains + + /usr/glenda/ Del Snarf Get | Look + +(This might be truncated if the column is narrow.) +That is just text. + +Each mouse button (1, 2, 3, from left to right) does a different +thing in Acme: + + * Button 1 can be used to select text (press it, sweep, release it), + and also to select the point where text would be inserted in the + window. Use it now in your /usr/glenda window. + * Button 2 can be used to execute things. For example, use button 1 + to type "ls -l" before "lib/" in the window showing + /usr/glenda. Now use button 2 to select "ls -l lib/" (press + it, select, release it). As you can see, button 2 means + "execute this". + * Button 3 can be used to get things. For example, click button 3 on + "lib/" within the "/usr/glenda" window. Can you see how a new window + shows the contents of "/usr/glenda/lib"? Button 3 can also be used + to search within the body of a window. Just click button 3 on the + thing you want to search. Again, you can select something with + button 1 and then use button 3 on the selection. + +You can double-click with button 1 to select words; a double click at +the end or beginning of a line selects the whole line. Once you have +text selected, you can click on it with button 2 to execute the +selected text. A single click of button 2 would execute the word +clicked as a command. + +Now let's pay attention to the tag line once more. As you can see, +the left part has a path. That is the name for the window and shows +also the directory for the thing shown (file/directory/program +output). When you execute something using button 2, the current +directory for the command is the directory shown in the left part of +the tag (if the thing shown is a file, its directory is used). + +As you saw before in the example, there are windows labeled +"/dir/+Errors", that is where Acme shows the output of a command +executed in "/dir". + +Another thing you can see is that tag lines contain words like "New", +"Del", "Snarf", etc. Those are commands understood (implemented) by +Acme. When you request execution of one of them, Acme does the job. +For example, click with button 2 on "Del" in the +"/usr/glenda/+Errors" window: it's gone. + +The commands shown by Acme are just text and by no means special. Try +to type "Del" within the body of the window "/usr/glenda", and then +click (button-2) on it. + +These are some commands understood by Acme: + * Newcol: create a new column of windows + * Delcol: delete a column + * New: create a new window (edit it's tag to be a file name and you + would be creating a new file; you would need to click on "Put" to + put the file in the file system). + * Put: write the body to disk. The file is the one named in the tag. + * Get: refresh the body (e.g. if it's a directory, reread it and + show it). + * Snarf: What other window systems call "Copy". + * Paste: Can you guess it? + * Exit: exit acme + +Acme likes to place new windows itself. If you prefer to change the +layout of a window, you only need to drag the layout box at the left +of the tag line and drop it somewhere else. The point where you drop +it selects the column where the window is to be placed now, as well +as the line where the window should start. You can also click the +layout box to enlarge its window a small amount (button 1), as much +as possible without obscuring other tag lines in the column (button +2), and to fill the whole column (button 3). You can get your other +windows back by button-1- or button-2-clicking the layout box. + +This is mostly what you need to get started with Acme. You are +missing a very useful feature: using combinations (chords) of mouse +buttons to do things. You can cut, paste, snarf, and pass arguments +to programs using these mouse chords. You can read this in the +acme(1) manual page, but it's actually extremely simple: Select a +region with button 1 but don't release the button. Now clicking +button 2 deletes the selected text (putting it into the snarf +buffer); clicking button 3 replaces the selected text with the snarf +buffer. That's it! + +For more information, read /sys/doc/acme/acme.ps (you can just +button-3 click on that string to view the file). + diff --git a/usr/glenda/readme.rio b/usr/glenda/readme.rio new file mode 100644 index 000000000..0eb0e44db --- /dev/null +++ b/usr/glenda/readme.rio @@ -0,0 +1,178 @@ +Rio is the Plan 9 window system. + +To read more of this window, the up and down arrows +scroll the text up and down half screens. + +To effectively use rio, you need at least a three +button mouse. If you only have a two button mouse you +can emulate the middle button by holding down shift key +whilst pressing the right button. + +Button 1, 2, and 3 are used to refer to the left, +middle, and right buttons respectively. + +THE POP-UP MENU + +Pressing and holding down button 3 on the desktop or +shell window will give you a menu with the following +options: + + * New - create a new window + * Resize - reshape a window + * Move - move a window without reshaping it + * Delete - close a window + * Hide - hides a window from display (it will appear + in this menu) + *