From 196013d337b14a1a2af03e7c04accc7460443f62 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sun, 30 Mar 2014 14:28:10 +0200 Subject: update to latest upstream version --- package/radvd/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/radvd/Makefile b/package/radvd/Makefile index 1dd5b6ccf..dc927a628 100644 --- a/package/radvd/Makefile +++ b/package/radvd/Makefile @@ -4,9 +4,9 @@ include ${TOPDIR}/rules.mk PKG_NAME:= radvd -PKG_VERSION:= 1.9.7 +PKG_VERSION:= 1.10.0 PKG_RELEASE:= 1 -PKG_MD5SUM:= 85141c7dc7d35e5499e16052742f1040 +PKG_MD5SUM:= 5ef15bc6c8316dba02147065f8dfdad3 PKG_DESCR:= Routing Advertisement Daemon for IPv6 PKG_SECTION:= ipv6 PKG_DEPENDS:= kmod-ipv6 libdaemon -- cgit v1.2.3 From 8aed1fcd443b550c15a21ddbf1b1d3899803120a Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sun, 30 Mar 2014 15:55:20 +0200 Subject: rework hosttools building, add tools into package stuff --- .gitignore | 42 +- adk/config/Config.in | 8 + adk/config/Kconfig-language.txt | 379 ++ adk/config/Makefile | 131 + adk/config/Makefile.in | 5 + adk/config/check.sh | 14 + adk/config/conf.c | 619 ++ adk/config/confdata.c | 899 +++ adk/config/expr.c | 1106 +++ adk/config/expr.h | 228 + adk/config/gconf.c | 1618 +++++ adk/config/gconf.glade | 648 ++ adk/config/images.c | 326 + adk/config/kconfig_load.c | 35 + adk/config/kxgettext.c | 233 + adk/config/lex.zconf.c_shipped | 2416 +++++++ adk/config/lkc.h | 169 + adk/config/lkc_proto.h | 45 + adk/config/lxdialog/.gitignore | 4 + adk/config/lxdialog/BIG.FAT.WARNING | 4 + adk/config/lxdialog/check-lxdialog.sh | 82 + adk/config/lxdialog/checklist.c | 326 + adk/config/lxdialog/dialog.h | 230 + adk/config/lxdialog/inputbox.c | 238 + adk/config/lxdialog/menubox.c | 434 ++ adk/config/lxdialog/textbox.c | 391 ++ adk/config/lxdialog/util.c | 657 ++ adk/config/lxdialog/yesno.c | 114 + adk/config/mconf.c | 940 +++ adk/config/menu.c | 533 ++ adk/config/symbol.c | 973 +++ adk/config/util.c | 133 + adk/config/zconf.gperf | 44 + adk/config/zconf.hash.c_shipped | 237 + adk/config/zconf.l | 359 + adk/config/zconf.tab.c_shipped | 2490 +++++++ adk/config/zconf.tab.h_shipped | 133 + adk/config/zconf.y | 706 ++ adk/tests/adk.exp.in | 5 + adk/tests/master.exp.in | 5 + adk/tools/Makefile | 17 + adk/tools/depmaker.c | 314 + adk/tools/dkgetsz.c | 95 + adk/tools/pkgmaker.c | 1194 ++++ adk/tools/pkgrebuild.c | 273 + adk/tools/sortfile.c | 153 + adk/tools/sortfile.h | 1 + adk/tools/strmap.c | 510 ++ adk/tools/strmap.h | 350 + config/Config.in | 8 - config/Kconfig-language.txt | 379 -- config/Makefile | 131 - config/Makefile.in | 5 - config/check.sh | 14 - config/conf.c | 619 -- config/confdata.c | 899 --- config/expr.c | 1106 --- config/expr.h | 228 - config/gconf.c | 1618 ----- config/gconf.glade | 648 -- config/images.c | 326 - config/kconfig_load.c | 35 - config/kxgettext.c | 233 - config/lex.zconf.c_shipped | 2416 ------- config/lkc.h | 169 - config/lkc_proto.h | 45 - config/lxdialog/.gitignore | 4 - config/lxdialog/BIG.FAT.WARNING | 4 - config/lxdialog/check-lxdialog.sh | 82 - config/lxdialog/checklist.c | 326 - config/lxdialog/dialog.h | 230 - config/lxdialog/inputbox.c | 238 - config/lxdialog/menubox.c | 434 -- config/lxdialog/textbox.c | 391 -- config/lxdialog/util.c | 657 -- config/lxdialog/yesno.c | 114 - config/mconf.c | 940 --- config/menu.c | 533 -- config/symbol.c | 973 --- config/util.c | 133 - config/zconf.gperf | 44 - config/zconf.hash.c_shipped | 237 - config/zconf.l | 359 - config/zconf.tab.c_shipped | 2490 ------- config/zconf.tab.h_shipped | 133 - config/zconf.y | 706 -- docs/how-openadk-works.txt | 25 +- docs/make-tips.txt | 4 +- docs/prerequisite.txt | 11 +- mk/build.mk | 67 +- mk/buildhlp.mk | 4 +- mk/fetch.mk | 1 - mk/host.mk | 2 + mk/image.mk | 6 +- mk/pkg-bottom.mk | 2 + mk/vars.mk | 3 +- package/Makefile | 2 + package/base-files/Makefile | 1 - package/bc/Makefile | 7 +- package/busybox/Makefile | 1 + package/bzip2/Makefile | 2 + package/ccache/Makefile | 24 + package/cdrtools/Makefile | 31 +- package/cfgfs/Makefile | 2 +- package/genext2fs/Makefile | 24 + package/heirloom-cpio/Makefile | 32 + package/heirloom-cpio/src/Makefile | 28 + package/heirloom-cpio/src/_alloca.h | 27 + package/heirloom-cpio/src/_malloc.h | 26 + package/heirloom-cpio/src/_utmpx.h | 89 + package/heirloom-cpio/src/asciitype.c | 59 + package/heirloom-cpio/src/asciitype.h | 60 + package/heirloom-cpio/src/atoll.h | 8 + package/heirloom-cpio/src/blank.h | 38 + package/heirloom-cpio/src/blast.c | 449 ++ package/heirloom-cpio/src/blast.h | 76 + package/heirloom-cpio/src/cpio.1 | 943 +++ package/heirloom-cpio/src/cpio.c | 7172 ++++++++++++++++++++ package/heirloom-cpio/src/cpio.h | 232 + package/heirloom-cpio/src/crc32.c | 115 + package/heirloom-cpio/src/expand.c | 193 + package/heirloom-cpio/src/explode.c | 1138 ++++ package/heirloom-cpio/src/flags.c | 257 + package/heirloom-cpio/src/getdir.c | 197 + package/heirloom-cpio/src/getdir.h | 33 + package/heirloom-cpio/src/getopt.c | 141 + package/heirloom-cpio/src/gmatch.c | 136 + package/heirloom-cpio/src/ib_alloc.c | 60 + package/heirloom-cpio/src/ib_close.c | 36 + package/heirloom-cpio/src/ib_free.c | 33 + package/heirloom-cpio/src/ib_getlin.c | 78 + package/heirloom-cpio/src/ib_getw.c | 81 + package/heirloom-cpio/src/ib_open.c | 48 + package/heirloom-cpio/src/ib_popen.c | 87 + package/heirloom-cpio/src/ib_read.c | 51 + package/heirloom-cpio/src/ib_seek.c | 53 + package/heirloom-cpio/src/iblok.h | 135 + package/heirloom-cpio/src/inflate.c | 991 +++ package/heirloom-cpio/src/mbtowi.h | 22 + package/heirloom-cpio/src/memalign.c | 51 + package/heirloom-cpio/src/memalign.h | 35 + package/heirloom-cpio/src/msgselect.h | 30 + package/heirloom-cpio/src/nonpax.c | 55 + package/heirloom-cpio/src/oblok.c | 260 + package/heirloom-cpio/src/oblok.h | 96 + package/heirloom-cpio/src/pathconf.c | 51 + package/heirloom-cpio/src/pathconf.h | 29 + package/heirloom-cpio/src/pax.1 | 919 +++ package/heirloom-cpio/src/pax.c | 757 +++ package/heirloom-cpio/src/pfmt.c | 39 + package/heirloom-cpio/src/pfmt.h | 46 + package/heirloom-cpio/src/pfmt_label.c | 1 + package/heirloom-cpio/src/regexp.h | 1211 ++++ package/heirloom-cpio/src/regexpr.c | 90 + package/heirloom-cpio/src/regexpr.h | 53 + package/heirloom-cpio/src/setlabel.c | 40 + package/heirloom-cpio/src/setuxlabel.c | 47 + package/heirloom-cpio/src/sfile.c | 99 + package/heirloom-cpio/src/sfile.h | 40 + package/heirloom-cpio/src/sighold.c | 42 + package/heirloom-cpio/src/sigignore.c | 45 + package/heirloom-cpio/src/signal.c | 46 + package/heirloom-cpio/src/sigpause.c | 48 + package/heirloom-cpio/src/sigrelse.c | 42 + package/heirloom-cpio/src/sigset.c | 57 + package/heirloom-cpio/src/sigset.h | 40 + package/heirloom-cpio/src/strtol.c | 117 + package/heirloom-cpio/src/unshrink.c | 307 + package/heirloom-cpio/src/unzip.h | 121 + package/heirloom-cpio/src/utmpx.c | 252 + package/heirloom-cpio/src/version.c | 26 + package/heirloom-cpio/src/vpfmt.c | 90 + package/liblzo/Makefile | 1 - package/lzma/Makefile | 28 + package/lzop/Makefile | 6 + package/mkcrypt/Makefile | 31 + package/mkcrypt/src/mkcrypt.c | 441 ++ package/mkimage/Makefile | 33 + package/mkimage/src/crc32.c | 200 + package/mkimage/src/image.h | 161 + package/mkimage/src/mkimage.c | 755 +++ package/mksh/Makefile | 18 +- package/mtd-utils/Makefile | 35 + package/mtd-utils/patches/patch-Makefile | 65 + package/mtd-utils/patches/patch-common_mk | 11 + package/mtd-utils/patches/patch-compr_c | 21 + package/mtd-utils/patches/patch-compr_lzo_c | 10 + package/mtd-utils/patches/patch-compr_zlib_c | 10 + .../patches/patch-include_mtd_jffs2-user_h | 16 + .../mtd-utils/patches/patch-include_mtd_mtd-abi_h | 14 + .../patches/patch-include_mtd_ubi-media_h | 18 + package/mtd-utils/patches/patch-lib_libfec_c | 20 + package/mtd-utils/patches/patch-lib_libmtd_c | 38 + .../mtd-utils/patches/patch-lib_libmtd_legacy_c | 11 + package/mtd-utils/patches/patch-mkfs_jffs2_c | 15 + package/mtd-utils/patches/patch-rbtree_h | 12 + package/pcre/Makefile | 4 + package/squashfs/Makefile | 37 + .../squashfs/patches/patch-squashfs-tools_Makefile | 11 + .../patches/patch-squashfs-tools_mksquashfs_c | 47 + .../patches/patch-squashfs-tools_unsquashfs_c | 39 + package/syslinux/Makefile | 35 +- package/xz/Makefile | 5 + scripts/adkprepare.sh | 10 +- target/config/Config.in | 5 +- target/config/Config.in.tools | 32 +- target/microblaze/sys-available/qemu-microblaze | 1 - target/microblaze/sys-available/qemu-microblazeel | 1 - tests/adk.exp.in | 5 - tests/master.exp.in | 5 - toolchain/binutils/Makefile.inc | 3 +- toolchain/gcc/Makefile.inc | 3 +- toolchain/gdb/Makefile.inc | 3 +- toolchain/uClibc/Makefile.inc | 4 +- tools/Makefile | 57 - tools/addpattern/Makefile | 4 - tools/addpattern/addpattern.c | 252 - tools/adk/Makefile | 17 - tools/adk/depmaker.c | 313 - tools/adk/dkgetsz.c | 95 - tools/adk/pkgmaker.c | 1194 ---- tools/adk/pkgrebuild.c | 273 - tools/adk/sortfile.c | 153 - tools/adk/sortfile.h | 1 - tools/adk/strmap.c | 510 -- tools/adk/strmap.h | 350 - tools/bc/Makefile | 25 - tools/bzip2/Makefile | 24 - tools/ccache/Makefile | 25 - tools/cdrtools/Makefile | 25 - tools/cpio/Makefile | 32 - tools/cpio/src/_alloca.h | 27 - tools/cpio/src/_malloc.h | 26 - tools/cpio/src/_utmpx.h | 89 - tools/cpio/src/asciitype.c | 59 - tools/cpio/src/asciitype.h | 60 - tools/cpio/src/atoll.h | 8 - tools/cpio/src/blank.h | 38 - tools/cpio/src/blast.c | 449 -- tools/cpio/src/blast.h | 76 - tools/cpio/src/cpio.1 | 943 --- tools/cpio/src/cpio.c | 7172 -------------------- tools/cpio/src/cpio.h | 232 - tools/cpio/src/crc32.c | 115 - tools/cpio/src/expand.c | 193 - tools/cpio/src/explode.c | 1138 ---- tools/cpio/src/flags.c | 257 - tools/cpio/src/getdir.c | 197 - tools/cpio/src/getdir.h | 33 - tools/cpio/src/getopt.c | 141 - tools/cpio/src/gmatch.c | 136 - tools/cpio/src/ib_alloc.c | 60 - tools/cpio/src/ib_close.c | 36 - tools/cpio/src/ib_free.c | 33 - tools/cpio/src/ib_getlin.c | 78 - tools/cpio/src/ib_getw.c | 81 - tools/cpio/src/ib_open.c | 48 - tools/cpio/src/ib_popen.c | 87 - tools/cpio/src/ib_read.c | 51 - tools/cpio/src/ib_seek.c | 53 - tools/cpio/src/iblok.h | 135 - tools/cpio/src/inflate.c | 991 --- tools/cpio/src/mbtowi.h | 22 - tools/cpio/src/memalign.c | 51 - tools/cpio/src/memalign.h | 35 - tools/cpio/src/msgselect.h | 30 - tools/cpio/src/nonpax.c | 55 - tools/cpio/src/oblok.c | 260 - tools/cpio/src/oblok.h | 96 - tools/cpio/src/pathconf.c | 51 - tools/cpio/src/pathconf.h | 29 - tools/cpio/src/pax.1 | 919 --- tools/cpio/src/pax.c | 757 --- tools/cpio/src/pfmt.c | 39 - tools/cpio/src/pfmt.h | 46 - tools/cpio/src/pfmt_label.c | 1 - tools/cpio/src/regexp.h | 1211 ---- tools/cpio/src/regexpr.c | 90 - tools/cpio/src/regexpr.h | 53 - tools/cpio/src/setlabel.c | 40 - tools/cpio/src/setuxlabel.c | 47 - tools/cpio/src/sfile.c | 99 - tools/cpio/src/sfile.h | 40 - tools/cpio/src/sighold.c | 42 - tools/cpio/src/sigignore.c | 45 - tools/cpio/src/signal.c | 46 - tools/cpio/src/sigpause.c | 48 - tools/cpio/src/sigrelse.c | 42 - tools/cpio/src/sigset.c | 57 - tools/cpio/src/sigset.h | 40 - tools/cpio/src/strtol.c | 117 - tools/cpio/src/unshrink.c | 307 - tools/cpio/src/unzip.h | 121 - tools/cpio/src/utmpx.c | 252 - tools/cpio/src/version.c | 26 - tools/cpio/src/vpfmt.c | 90 - tools/flex/Makefile | 25 - tools/genext2fs/Makefile | 25 - tools/lzma/Makefile | 25 - tools/lzo/Makefile | 28 - tools/lzop/Makefile | 30 - tools/m4/Makefile | 25 - tools/mkcrypt/Makefile | 11 - tools/mkcrypt/mkcrypt.c | 441 -- tools/mkfimage/Makefile | 4 - tools/mkfimage/mkfimage.c | 72 - tools/mkimage/Makefile | 11 - tools/mkimage/crc32.c | 200 - tools/mkimage/image.h | 161 - tools/mkimage/mkimage | Bin 23424 -> 0 bytes tools/mkimage/mkimage.c | 755 --- tools/mksh/Makefile | 29 - tools/mtd-utils/Makefile | 24 - tools/mtd-utils/patches/darwin.patch | 261 - tools/mtd-utils/patches/lzo.patch | 88 - tools/pcre/Makefile | 30 - tools/rules.mk | 7 - tools/squashfs/Makefile | 29 - tools/squashfs/patches/cppflags.patch | 12 - tools/squashfs/patches/darwin.patch | 88 - tools/srec2bin/Makefile | 4 - tools/srec2bin/srec2bin.c | 521 -- tools/syslinux/Makefile | 37 - tools/trx/Makefile | 4 - tools/trx/trx.c | 366 - tools/xz/Makefile | 28 - 326 files changed, 41449 insertions(+), 43006 deletions(-) create mode 100644 adk/config/Config.in create mode 100644 adk/config/Kconfig-language.txt create mode 100644 adk/config/Makefile create mode 100644 adk/config/Makefile.in create mode 100755 adk/config/check.sh create mode 100644 adk/config/conf.c create mode 100644 adk/config/confdata.c create mode 100644 adk/config/expr.c create mode 100644 adk/config/expr.h create mode 100644 adk/config/gconf.c create mode 100644 adk/config/gconf.glade create mode 100644 adk/config/images.c create mode 100644 adk/config/kconfig_load.c create mode 100644 adk/config/kxgettext.c create mode 100644 adk/config/lex.zconf.c_shipped create mode 100644 adk/config/lkc.h create mode 100644 adk/config/lkc_proto.h create mode 100644 adk/config/lxdialog/.gitignore create mode 100644 adk/config/lxdialog/BIG.FAT.WARNING create mode 100644 adk/config/lxdialog/check-lxdialog.sh create mode 100644 adk/config/lxdialog/checklist.c create mode 100644 adk/config/lxdialog/dialog.h create mode 100644 adk/config/lxdialog/inputbox.c create mode 100644 adk/config/lxdialog/menubox.c create mode 100644 adk/config/lxdialog/textbox.c create mode 100644 adk/config/lxdialog/util.c create mode 100644 adk/config/lxdialog/yesno.c create mode 100644 adk/config/mconf.c create mode 100644 adk/config/menu.c create mode 100644 adk/config/symbol.c create mode 100644 adk/config/util.c create mode 100644 adk/config/zconf.gperf create mode 100644 adk/config/zconf.hash.c_shipped create mode 100644 adk/config/zconf.l create mode 100644 adk/config/zconf.tab.c_shipped create mode 100644 adk/config/zconf.tab.h_shipped create mode 100644 adk/config/zconf.y create mode 100644 adk/tests/adk.exp.in create mode 100644 adk/tests/master.exp.in create mode 100644 adk/tools/Makefile create mode 100644 adk/tools/depmaker.c create mode 100644 adk/tools/dkgetsz.c create mode 100644 adk/tools/pkgmaker.c create mode 100644 adk/tools/pkgrebuild.c create mode 100644 adk/tools/sortfile.c create mode 100644 adk/tools/sortfile.h create mode 100644 adk/tools/strmap.c create mode 100644 adk/tools/strmap.h delete mode 100644 config/Config.in delete mode 100644 config/Kconfig-language.txt delete mode 100644 config/Makefile delete mode 100644 config/Makefile.in delete mode 100755 config/check.sh delete mode 100644 config/conf.c delete mode 100644 config/confdata.c delete mode 100644 config/expr.c delete mode 100644 config/expr.h delete mode 100644 config/gconf.c delete mode 100644 config/gconf.glade delete mode 100644 config/images.c delete mode 100644 config/kconfig_load.c delete mode 100644 config/kxgettext.c delete mode 100644 config/lex.zconf.c_shipped delete mode 100644 config/lkc.h delete mode 100644 config/lkc_proto.h delete mode 100644 config/lxdialog/.gitignore delete mode 100644 config/lxdialog/BIG.FAT.WARNING delete mode 100644 config/lxdialog/check-lxdialog.sh delete mode 100644 config/lxdialog/checklist.c delete mode 100644 config/lxdialog/dialog.h delete mode 100644 config/lxdialog/inputbox.c delete mode 100644 config/lxdialog/menubox.c delete mode 100644 config/lxdialog/textbox.c delete mode 100644 config/lxdialog/util.c delete mode 100644 config/lxdialog/yesno.c delete mode 100644 config/mconf.c delete mode 100644 config/menu.c delete mode 100644 config/symbol.c delete mode 100644 config/util.c delete mode 100644 config/zconf.gperf delete mode 100644 config/zconf.hash.c_shipped delete mode 100644 config/zconf.l delete mode 100644 config/zconf.tab.c_shipped delete mode 100644 config/zconf.tab.h_shipped delete mode 100644 config/zconf.y create mode 100644 package/ccache/Makefile create mode 100644 package/genext2fs/Makefile create mode 100644 package/heirloom-cpio/Makefile create mode 100644 package/heirloom-cpio/src/Makefile create mode 100644 package/heirloom-cpio/src/_alloca.h create mode 100644 package/heirloom-cpio/src/_malloc.h create mode 100644 package/heirloom-cpio/src/_utmpx.h create mode 100644 package/heirloom-cpio/src/asciitype.c create mode 100644 package/heirloom-cpio/src/asciitype.h create mode 100644 package/heirloom-cpio/src/atoll.h create mode 100644 package/heirloom-cpio/src/blank.h create mode 100644 package/heirloom-cpio/src/blast.c create mode 100644 package/heirloom-cpio/src/blast.h create mode 100644 package/heirloom-cpio/src/cpio.1 create mode 100644 package/heirloom-cpio/src/cpio.c create mode 100644 package/heirloom-cpio/src/cpio.h create mode 100644 package/heirloom-cpio/src/crc32.c create mode 100644 package/heirloom-cpio/src/expand.c create mode 100644 package/heirloom-cpio/src/explode.c create mode 100644 package/heirloom-cpio/src/flags.c create mode 100644 package/heirloom-cpio/src/getdir.c create mode 100644 package/heirloom-cpio/src/getdir.h create mode 100644 package/heirloom-cpio/src/getopt.c create mode 100644 package/heirloom-cpio/src/gmatch.c create mode 100644 package/heirloom-cpio/src/ib_alloc.c create mode 100644 package/heirloom-cpio/src/ib_close.c create mode 100644 package/heirloom-cpio/src/ib_free.c create mode 100644 package/heirloom-cpio/src/ib_getlin.c create mode 100644 package/heirloom-cpio/src/ib_getw.c create mode 100644 package/heirloom-cpio/src/ib_open.c create mode 100644 package/heirloom-cpio/src/ib_popen.c create mode 100644 package/heirloom-cpio/src/ib_read.c create mode 100644 package/heirloom-cpio/src/ib_seek.c create mode 100644 package/heirloom-cpio/src/iblok.h create mode 100644 package/heirloom-cpio/src/inflate.c create mode 100644 package/heirloom-cpio/src/mbtowi.h create mode 100644 package/heirloom-cpio/src/memalign.c create mode 100644 package/heirloom-cpio/src/memalign.h create mode 100644 package/heirloom-cpio/src/msgselect.h create mode 100644 package/heirloom-cpio/src/nonpax.c create mode 100644 package/heirloom-cpio/src/oblok.c create mode 100644 package/heirloom-cpio/src/oblok.h create mode 100644 package/heirloom-cpio/src/pathconf.c create mode 100644 package/heirloom-cpio/src/pathconf.h create mode 100644 package/heirloom-cpio/src/pax.1 create mode 100644 package/heirloom-cpio/src/pax.c create mode 100644 package/heirloom-cpio/src/pfmt.c create mode 100644 package/heirloom-cpio/src/pfmt.h create mode 100644 package/heirloom-cpio/src/pfmt_label.c create mode 100644 package/heirloom-cpio/src/regexp.h create mode 100644 package/heirloom-cpio/src/regexpr.c create mode 100644 package/heirloom-cpio/src/regexpr.h create mode 100644 package/heirloom-cpio/src/setlabel.c create mode 100644 package/heirloom-cpio/src/setuxlabel.c create mode 100644 package/heirloom-cpio/src/sfile.c create mode 100644 package/heirloom-cpio/src/sfile.h create mode 100644 package/heirloom-cpio/src/sighold.c create mode 100644 package/heirloom-cpio/src/sigignore.c create mode 100644 package/heirloom-cpio/src/signal.c create mode 100644 package/heirloom-cpio/src/sigpause.c create mode 100644 package/heirloom-cpio/src/sigrelse.c create mode 100644 package/heirloom-cpio/src/sigset.c create mode 100644 package/heirloom-cpio/src/sigset.h create mode 100644 package/heirloom-cpio/src/strtol.c create mode 100644 package/heirloom-cpio/src/unshrink.c create mode 100644 package/heirloom-cpio/src/unzip.h create mode 100644 package/heirloom-cpio/src/utmpx.c create mode 100644 package/heirloom-cpio/src/version.c create mode 100644 package/heirloom-cpio/src/vpfmt.c create mode 100644 package/lzma/Makefile create mode 100644 package/mkcrypt/Makefile create mode 100644 package/mkcrypt/src/mkcrypt.c create mode 100644 package/mkimage/Makefile create mode 100644 package/mkimage/src/crc32.c create mode 100644 package/mkimage/src/image.h create mode 100644 package/mkimage/src/mkimage.c create mode 100644 package/mtd-utils/Makefile create mode 100644 package/mtd-utils/patches/patch-Makefile create mode 100644 package/mtd-utils/patches/patch-common_mk create mode 100644 package/mtd-utils/patches/patch-compr_c create mode 100644 package/mtd-utils/patches/patch-compr_lzo_c create mode 100644 package/mtd-utils/patches/patch-compr_zlib_c create mode 100644 package/mtd-utils/patches/patch-include_mtd_jffs2-user_h create mode 100644 package/mtd-utils/patches/patch-include_mtd_mtd-abi_h create mode 100644 package/mtd-utils/patches/patch-include_mtd_ubi-media_h create mode 100644 package/mtd-utils/patches/patch-lib_libfec_c create mode 100644 package/mtd-utils/patches/patch-lib_libmtd_c create mode 100644 package/mtd-utils/patches/patch-lib_libmtd_legacy_c create mode 100644 package/mtd-utils/patches/patch-mkfs_jffs2_c create mode 100644 package/mtd-utils/patches/patch-rbtree_h create mode 100644 package/squashfs/Makefile create mode 100644 package/squashfs/patches/patch-squashfs-tools_Makefile create mode 100644 package/squashfs/patches/patch-squashfs-tools_mksquashfs_c create mode 100644 package/squashfs/patches/patch-squashfs-tools_unsquashfs_c delete mode 100644 tests/adk.exp.in delete mode 100644 tests/master.exp.in delete mode 100644 tools/Makefile delete mode 100644 tools/addpattern/Makefile delete mode 100644 tools/addpattern/addpattern.c delete mode 100644 tools/adk/Makefile delete mode 100644 tools/adk/depmaker.c delete mode 100644 tools/adk/dkgetsz.c delete mode 100644 tools/adk/pkgmaker.c delete mode 100644 tools/adk/pkgrebuild.c delete mode 100644 tools/adk/sortfile.c delete mode 100644 tools/adk/sortfile.h delete mode 100644 tools/adk/strmap.c delete mode 100644 tools/adk/strmap.h delete mode 100644 tools/bc/Makefile delete mode 100644 tools/bzip2/Makefile delete mode 100644 tools/ccache/Makefile delete mode 100644 tools/cdrtools/Makefile delete mode 100644 tools/cpio/Makefile delete mode 100644 tools/cpio/src/_alloca.h delete mode 100644 tools/cpio/src/_malloc.h delete mode 100644 tools/cpio/src/_utmpx.h delete mode 100644 tools/cpio/src/asciitype.c delete mode 100644 tools/cpio/src/asciitype.h delete mode 100644 tools/cpio/src/atoll.h delete mode 100644 tools/cpio/src/blank.h delete mode 100644 tools/cpio/src/blast.c delete mode 100644 tools/cpio/src/blast.h delete mode 100644 tools/cpio/src/cpio.1 delete mode 100644 tools/cpio/src/cpio.c delete mode 100644 tools/cpio/src/cpio.h delete mode 100644 tools/cpio/src/crc32.c delete mode 100644 tools/cpio/src/expand.c delete mode 100644 tools/cpio/src/explode.c delete mode 100644 tools/cpio/src/flags.c delete mode 100644 tools/cpio/src/getdir.c delete mode 100644 tools/cpio/src/getdir.h delete mode 100644 tools/cpio/src/getopt.c delete mode 100644 tools/cpio/src/gmatch.c delete mode 100644 tools/cpio/src/ib_alloc.c delete mode 100644 tools/cpio/src/ib_close.c delete mode 100644 tools/cpio/src/ib_free.c delete mode 100644 tools/cpio/src/ib_getlin.c delete mode 100644 tools/cpio/src/ib_getw.c delete mode 100644 tools/cpio/src/ib_open.c delete mode 100644 tools/cpio/src/ib_popen.c delete mode 100644 tools/cpio/src/ib_read.c delete mode 100644 tools/cpio/src/ib_seek.c delete mode 100644 tools/cpio/src/iblok.h delete mode 100644 tools/cpio/src/inflate.c delete mode 100644 tools/cpio/src/mbtowi.h delete mode 100644 tools/cpio/src/memalign.c delete mode 100644 tools/cpio/src/memalign.h delete mode 100644 tools/cpio/src/msgselect.h delete mode 100644 tools/cpio/src/nonpax.c delete mode 100644 tools/cpio/src/oblok.c delete mode 100644 tools/cpio/src/oblok.h delete mode 100644 tools/cpio/src/pathconf.c delete mode 100644 tools/cpio/src/pathconf.h delete mode 100644 tools/cpio/src/pax.1 delete mode 100644 tools/cpio/src/pax.c delete mode 100644 tools/cpio/src/pfmt.c delete mode 100644 tools/cpio/src/pfmt.h delete mode 100644 tools/cpio/src/pfmt_label.c delete mode 100644 tools/cpio/src/regexp.h delete mode 100644 tools/cpio/src/regexpr.c delete mode 100644 tools/cpio/src/regexpr.h delete mode 100644 tools/cpio/src/setlabel.c delete mode 100644 tools/cpio/src/setuxlabel.c delete mode 100644 tools/cpio/src/sfile.c delete mode 100644 tools/cpio/src/sfile.h delete mode 100644 tools/cpio/src/sighold.c delete mode 100644 tools/cpio/src/sigignore.c delete mode 100644 tools/cpio/src/signal.c delete mode 100644 tools/cpio/src/sigpause.c delete mode 100644 tools/cpio/src/sigrelse.c delete mode 100644 tools/cpio/src/sigset.c delete mode 100644 tools/cpio/src/sigset.h delete mode 100644 tools/cpio/src/strtol.c delete mode 100644 tools/cpio/src/unshrink.c delete mode 100644 tools/cpio/src/unzip.h delete mode 100644 tools/cpio/src/utmpx.c delete mode 100644 tools/cpio/src/version.c delete mode 100644 tools/cpio/src/vpfmt.c delete mode 100644 tools/flex/Makefile delete mode 100644 tools/genext2fs/Makefile delete mode 100644 tools/lzma/Makefile delete mode 100644 tools/lzo/Makefile delete mode 100644 tools/lzop/Makefile delete mode 100644 tools/m4/Makefile delete mode 100644 tools/mkcrypt/Makefile delete mode 100644 tools/mkcrypt/mkcrypt.c delete mode 100644 tools/mkfimage/Makefile delete mode 100644 tools/mkfimage/mkfimage.c delete mode 100644 tools/mkimage/Makefile delete mode 100644 tools/mkimage/crc32.c delete mode 100644 tools/mkimage/image.h delete mode 100755 tools/mkimage/mkimage delete mode 100644 tools/mkimage/mkimage.c delete mode 100644 tools/mksh/Makefile delete mode 100644 tools/mtd-utils/Makefile delete mode 100644 tools/mtd-utils/patches/darwin.patch delete mode 100644 tools/mtd-utils/patches/lzo.patch delete mode 100644 tools/pcre/Makefile delete mode 100644 tools/rules.mk delete mode 100644 tools/squashfs/Makefile delete mode 100644 tools/squashfs/patches/cppflags.patch delete mode 100644 tools/squashfs/patches/darwin.patch delete mode 100644 tools/srec2bin/Makefile delete mode 100644 tools/srec2bin/srec2bin.c delete mode 100644 tools/syslinux/Makefile delete mode 100644 tools/trx/Makefile delete mode 100644 tools/trx/trx.c delete mode 100644 tools/xz/Makefile diff --git a/.gitignore b/.gitignore index b2a8d1a21..b28f3e045 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,25 @@ -/config/conf -/config/conf.exe -/config/a.exe -/config/lex.backup -/config/lex.zconf.c -/config/lkc_defs.h -/config/gconf -/config/gconf.exe -/config/mconf -/config/mconf.exe -/config/zconf.hash.c -/config/zconf.output -/config/zconf.tab.c -/config/zconf.tab.h -/tests/master.exp -/tests/adk.exp -/tests/adk.exp.in.tmp +/adk/config/*.o +/adk/config/lxdialog/*.o +/adk/config/conf +/adk/config/conf.exe +/adk/config/a.exe +/adk/config/lex.backup +/adk/config/lex.zconf.c +/adk/config/lkc_defs.h +/adk/config/gconf +/adk/config/gconf.exe +/adk/config/mconf +/adk/config/mconf.exe +/adk/config/zconf.hash.c +/adk/config/zconf.output +/adk/config/zconf.tab.c +/adk/config/zconf.tab.h +/adk/tools/pkgmaker +/adk/tools/depmaker +/adk/tools/pkgrebuild +/adk/tests/master.exp +/adk/tests/adk.exp +/adk/tests/adk.exp.in.tmp /prereq.mk /toolchain_*/ /.ADK_HAVE_DOT_CONFIG @@ -32,8 +37,6 @@ /root_*/ /firmware/ /build_*/ -/config/*.o -/config/lxdialog/*.o /make.log /dl /package/Config.in.auto* @@ -41,7 +44,6 @@ /package/*/Config.in /package/*/Config.in.lib /package/*/Config.in.kmod -/tools_build/ /extra/ /.menu /.adkinit diff --git a/adk/config/Config.in b/adk/config/Config.in new file mode 100644 index 000000000..9a7778310 --- /dev/null +++ b/adk/config/Config.in @@ -0,0 +1,8 @@ +# + +config ADK_PACKAGE_CONFIG + bool"config" + default n + help + Add help text here. + diff --git a/adk/config/Kconfig-language.txt b/adk/config/Kconfig-language.txt new file mode 100644 index 000000000..c412c2458 --- /dev/null +++ b/adk/config/Kconfig-language.txt @@ -0,0 +1,379 @@ +Introduction +------------ + +The configuration database is a collection of configuration options +organized in a tree structure: + + +- Code maturity level options + | +- Prompt for development and/or incomplete code/drivers + +- General setup + | +- Networking support + | +- System V IPC + | +- BSD Process Accounting + | +- Sysctl support + +- Loadable module support + | +- Enable loadable module support + | +- Set version information on all module symbols + | +- Kernel module loader + +- ... + +Every entry has its own dependencies. These dependencies are used +to determine the visibility of an entry. Any child entry is only +visible if its parent entry is also visible. + +Menu entries +------------ + +Most entries define a config option; all other entries help to organize +them. A single configuration option is defined like this: + +config MODVERSIONS + bool "Set version information on all module symbols" + depends on MODULES + help + Usually, modules have to be recompiled whenever you switch to a new + kernel. ... + +Every line starts with a key word and can be followed by multiple +arguments. "config" starts a new config entry. The following lines +define attributes for this config option. Attributes can be the type of +the config option, input prompt, dependencies, help text and default +values. A config option can be defined multiple times with the same +name, but every definition can have only a single input prompt and the +type must not conflict. + +Menu attributes +--------------- + +A menu entry can have a number of attributes. Not all of them are +applicable everywhere (see syntax). + +- type definition: "bool"/"tristate"/"string"/"hex"/"int" + Every config option must have a type. There are only two basic types: + tristate and string; the other types are based on these two. The type + definition optionally accepts an input prompt, so these two examples + are equivalent: + + bool "Networking support" + and + bool + prompt "Networking support" + +- input prompt: "prompt" ["if" ] + Every menu entry can have at most one prompt, which is used to display + to the user. Optionally dependencies only for this prompt can be added + with "if". + +- default value: "default" ["if" ] + A config option can have any number of default values. If multiple + default values are visible, only the first defined one is active. + Default values are not limited to the menu entry where they are + defined. This means the default can be defined somewhere else or be + overridden by an earlier definition. + The default value is only assigned to the config symbol if no other + value was set by the user (via the input prompt above). If an input + prompt is visible the default value is presented to the user and can + be overridden by him. + Optionally, dependencies only for this default value can be added with + "if". + +- type definition + default value: + "def_bool"/"def_tristate" ["if" ] + This is a shorthand notation for a type definition plus a value. + Optionally dependencies for this default value can be added with "if". + +- dependencies: "depends on" + This defines a dependency for this menu entry. If multiple + dependencies are defined, they are connected with '&&'. Dependencies + are applied to all other options within this menu entry (which also + accept an "if" expression), so these two examples are equivalent: + + bool "foo" if BAR + default y if BAR + and + depends on BAR + bool "foo" + default y + +- reverse dependencies: "select" ["if" ] + While normal dependencies reduce the upper limit of a symbol (see + below), reverse dependencies can be used to force a lower limit of + another symbol. The value of the current menu symbol is used as the + minimal value can be set to. If is selected multiple + times, the limit is set to the largest selection. + Reverse dependencies can only be used with boolean or tristate + symbols. + Note: + select should be used with care. select will force + a symbol to a value without visiting the dependencies. + By abusing select you are able to select a symbol FOO even + if FOO depends on BAR that is not set. + In general use select only for non-visible symbols + (no prompts anywhere) and for symbols with no dependencies. + That will limit the usefulness but on the other hand avoid + the illegal configurations all over. + kconfig should one day warn about such things. + +- numerical ranges: "range" ["if" ] + This allows to limit the range of possible input values for int + and hex symbols. The user can only input a value which is larger than + or equal to the first symbol and smaller than or equal to the second + symbol. + +- help text: "help" or "---help---" + This defines a help text. The end of the help text is determined by + the indentation level, this means it ends at the first line which has + a smaller indentation than the first line of the help text. + "---help---" and "help" do not differ in behaviour, "---help---" is + used to help visually separate configuration logic from help within + the file as an aid to developers. + +- misc options: "option" [=] + Various less common options can be defined via this option syntax, + which can modify the behaviour of the menu entry and its config + symbol. These options are currently possible: + + - "defconfig_list" + This declares a list of default entries which can be used when + looking for the default configuration (which is used when the main + .config doesn't exists yet.) + + - "modules" + This declares the symbol to be used as the MODULES symbol, which + enables the third modular state for all config symbols. + + - "env"= + This imports the environment variable into Kconfig. It behaves like + a default, except that the value comes from the environment, this + also means that the behaviour when mixing it with normal defaults is + undefined at this point. The symbol is currently not exported back + to the build environment (if this is desired, it can be done via + another symbol). + +Menu dependencies +----------------- + +Dependencies define the visibility of a menu entry and can also reduce +the input range of tristate symbols. The tristate logic used in the +expressions uses one more state than normal boolean logic to express the +module state. Dependency expressions have the following syntax: + + ::= (1) + '=' (2) + '!=' (3) + '(' ')' (4) + '!' (5) + '&&' (6) + '||' (7) + +Expressions are listed in decreasing order of precedence. + +(1) Convert the symbol into an expression. Boolean and tristate symbols + are simply converted into the respective expression values. All + other symbol types result in 'n'. +(2) If the values of both symbols are equal, it returns 'y', + otherwise 'n'. +(3) If the values of both symbols are equal, it returns 'n', + otherwise 'y'. +(4) Returns the value of the expression. Used to override precedence. +(5) Returns the result of (2-/expr/). +(6) Returns the result of min(/expr/, /expr/). +(7) Returns the result of max(/expr/, /expr/). + +An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 +respectively for calculations). A menu entry becomes visible when it's +expression evaluates to 'm' or 'y'. + +There are two types of symbols: constant and non-constant symbols. +Non-constant symbols are the most common ones and are defined with the +'config' statement. Non-constant symbols consist entirely of alphanumeric +characters or underscores. +Constant symbols are only part of expressions. Constant symbols are +always surrounded by single or double quotes. Within the quote, any +other character is allowed and the quotes can be escaped using '\'. + +Menu structure +-------------- + +The position of a menu entry in the tree is determined in two ways. First +it can be specified explicitly: + +menu "Network device support" + depends on NET + +config NETDEVICES + ... + +endmenu + +All entries within the "menu" ... "endmenu" block become a submenu of +"Network device support". All subentries inherit the dependencies from +the menu entry, e.g. this means the dependency "NET" is added to the +dependency list of the config option NETDEVICES. + +The other way to generate the menu structure is done by analyzing the +dependencies. If a menu entry somehow depends on the previous entry, it +can be made a submenu of it. First, the previous (parent) symbol must +be part of the dependency list and then one of these two conditions +must be true: +- the child entry must become invisible, if the parent is set to 'n' +- the child entry must only be visible, if the parent is visible + +config MODULES + bool "Enable loadable module support" + +config MODVERSIONS + bool "Set version information on all module symbols" + depends on MODULES + +comment "module support disabled" + depends on !MODULES + +MODVERSIONS directly depends on MODULES, this means it's only visible if +MODULES is different from 'n'. The comment on the other hand is always +visible when MODULES is visible (the (empty) dependency of MODULES is +also part of the comment dependencies). + + +Kconfig syntax +-------------- + +The configuration file describes a series of menu entries, where every +line starts with a keyword (except help texts). The following keywords +end a menu entry: +- config +- menuconfig +- choice/endchoice +- comment +- menu/endmenu +- if/endif +- source +The first five also start the definition of a menu entry. + +config: + + "config" + + +This defines a config symbol and accepts any of above +attributes as options. + +menuconfig: + "menuconfig" + + +This is similar to the simple config entry above, but it also gives a +hint to front ends, that all suboptions should be displayed as a +separate list of options. + +choices: + + "choice" + + + "endchoice" + +This defines a choice group and accepts any of the above attributes as +options. A choice can only be of type bool or tristate, while a boolean +choice only allows a single config entry to be selected, a tristate +choice also allows any number of config entries to be set to 'm'. This +can be used if multiple drivers for a single hardware exists and only a +single driver can be compiled/loaded into the kernel, but all drivers +can be compiled as modules. +A choice accepts another option "optional", which allows to set the +choice to 'n' and no entry needs to be selected. + +comment: + + "comment" + + +This defines a comment which is displayed to the user during the +configuration process and is also echoed to the output files. The only +possible options are dependencies. + +menu: + + "menu" + + + "endmenu" + +This defines a menu block, see "Menu structure" above for more +information. The only possible options are dependencies. + +if: + + "if" + + "endif" + +This defines an if block. The dependency expression is appended +to all enclosed menu entries. + +source: + + "source" + +This reads the specified configuration file. This file is always parsed. + +mainmenu: + + "mainmenu" + +This sets the config program's title bar if the config program chooses +to use it. + + +Kconfig hints +------------- +This is a collection of Kconfig tips, most of which aren't obvious at +first glance and most of which have become idioms in several Kconfig +files. + +Adding common features and make the usage configurable +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is a common idiom to implement a feature/functionality that are +relevant for some architectures but not all. +The recommended way to do so is to use a config variable named HAVE_* +that is defined in a common Kconfig file and selected by the relevant +architectures. +An example is the generic IOMAP functionality. + +We would in lib/Kconfig see: + +# Generic IOMAP is used to ... +config HAVE_GENERIC_IOMAP + +config GENERIC_IOMAP + depends on HAVE_GENERIC_IOMAP && FOO + +And in lib/Makefile we would see: +obj-$(CONFIG_GENERIC_IOMAP) += iomap.o + +For each architecture using the generic IOMAP functionality we would see: + +config X86 + select ... + select HAVE_GENERIC_IOMAP + select ... + +Note: we use the existing config option and avoid creating a new +config variable to select HAVE_GENERIC_IOMAP. + +Note: the use of the internal config variable HAVE_GENERIC_IOMAP, it is +introduced to overcome the limitation of select which will force a +config option to 'y' no matter the dependencies. +The dependencies are moved to the symbol GENERIC_IOMAP and we avoid the +situation where select forces a symbol equals to 'y'. + +Build as module only +~~~~~~~~~~~~~~~~~~~~ +To restrict a component build to module-only, qualify its config symbol +with "depends on m". E.g.: + +config FOO + depends on BAR && m + +limits FOO to module (=m) or disabled (=n). + diff --git a/adk/config/Makefile b/adk/config/Makefile new file mode 100644 index 000000000..9dc08d3ac --- /dev/null +++ b/adk/config/Makefile @@ -0,0 +1,131 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +ifneq ($(filter-out clean,${MAKECMDGOALS}),) +include ${TOPDIR}/rules.mk +endif + +CP=cp -fpR +CFLAGS_FOR_BUILD:=-DKBUILD_NO_NLS -O2 -w + +all: ncurses conf mconf + +LIBS= -lncurses +ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h)) +CFLAGS_FOR_BUILD+= -I/usr/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h)) +CFLAGS_FOR_BUILD+= -I/usr/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/local/include/ncurses/ncurses.h, $(wildcard /usr/local/include/ncurses/ncurses.h)) +CFLAGS_FOR_BUILD+= -I/usr/local/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/local/include/ncurses/curses.h, $(wildcard /usr/local/include/ncurses/curses.h)) +CFLAGS_FOR_BUILD+= -I/usr/local/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/pkg/include/ncurses.h, $(wildcard /usr/pkg/include/ncurses.h)) +CFLAGS_FOR_BUILD+= -I/usr/pkg/include -DCURSES_LOC="" +LIBS+= -L/usr/pkg/lib -Wl,-rpath -Wl,/usr/pkg/lib +else +ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h)) +CFLAGS_FOR_BUILD+= -DCURSES_LOC="" +else +CFLAGS_FOR_BUILD+= -DCURSES_LOC="" +LIBS= -lcurses +endif +endif +endif +endif +endif +endif + +CONF_SRC =conf.c +MCONF_SRC =mconf.c $(wildcard lxdialog/*.c) +SHARED_SRC=zconf.tab.c +SHARED_DEPS:=lkc.h lkc_proto.h lkc_defs.h expr.h zconf.tab.h +CONF_OBJS =$(patsubst %.c,%.o, $(CONF_SRC)) +MCONF_OBJS=$(patsubst %.c,%.o, $(MCONF_SRC)) +SHARED_OBJS=$(patsubst %.c,%.o, $(SHARED_SRC)) + +conf: $(CONF_OBJS) $(SHARED_OBJS) + @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $^ -o $@ + +mconf: $(MCONF_OBJS) $(SHARED_OBJS) + @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $^ -o $@ $(LIBS) + +$(CONF_OBJS): %.o : %.c $(SHARED_DEPS) + @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c $< -o $@ + +$(MCONF_OBJS): %.o : %.c $(SHARED_DEPS) + @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c $< -o $@ + +glob.o: glob.c $(SHARED_DEPS) + @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c glob.c -o $@ + +lkc_defs.h: lkc_proto.h + @sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' + +### +# The following requires flex/bison +# By default we use the _shipped versions, uncomment the +# following line if you are modifying the flex/bison src. +#LKC_GENPARSER:= 1 + +ifdef LKC_GENPARSER + +%.tab.c %.tab.h: %.y + bison -t -d -v -b $* -p $(notdir $*) $< + +%.hash.c: %.gperf + gperf < $< > $@ + +lex.%.c: %.l + flex -P$(notdir $*) -o$@ $< + +lex.zconf.o: lex.zconf.c $(SHARED_DEPS) + @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c $< -o $@ + +zconf.tab.o: zconf.tab.c zconf.hash.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(SHARED_DEPS) + @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c $< -o $@ + +else + +lex.zconf.o: lex.zconf.c $(SHARED_DEPS) + @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c $< -o $@ + +lex.zconf.c: lex.zconf.c_shipped + @$(CP) lex.zconf.c_shipped lex.zconf.c + +zconf.hash.c: zconf.hash.c_shipped + @$(CP) zconf.hash.c_shipped zconf.hash.c + +zconf.tab.o: zconf.tab.c zconf.hash.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(SHARED_DEPS) + @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c $< -o $@ + +zconf.tab.c: zconf.tab.c_shipped + @$(CP) zconf.tab.c_shipped zconf.tab.c + +zconf.tab.h: zconf.tab.h_shipped + @$(CP) zconf.tab.h_shipped zconf.tab.h +endif + +.PHONY: ncurses + +ncurses: + @echo "int main(void) { return -1; }" > lxtemp.c + @if $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) lxtemp.c $(LIBS) ; then \ + rm -f lxtemp.c a.out; \ + else \ + rm -f lxtemp.c; \ + printf '\007'; \ + echo ">> Unable to find the Ncurses libraries." ;\ + echo ">>" ;\ + echo ">> You must have Ncurses installed in order" ;\ + echo ">> to use 'make menuconfig'" ;\ + echo ;\ + exit 1 ;\ + fi + +clean: + @rm -f *.o *~ core $(TARGETS) $(MCONF_OBJS) $(CONF_OBJS) zconf.hash.c \ + conf mconf zconf.tab.c zconf.tab.h lex.zconf.c lkc_defs.h diff --git a/adk/config/Makefile.in b/adk/config/Makefile.in new file mode 100644 index 000000000..0b3ac40a9 --- /dev/null +++ b/adk/config/Makefile.in @@ -0,0 +1,5 @@ +ifeq ($(strip $(ADK_PACKAGE_CONFIG)),y) +TARGETS+=config +endif + +include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/adk/config/check.sh b/adk/config/check.sh new file mode 100755 index 000000000..fa59cbf9d --- /dev/null +++ b/adk/config/check.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Needed for systems without gettext +$* -xc -o /dev/null - > /dev/null 2>&1 << EOF +#include +int main() +{ + gettext(""); + return 0; +} +EOF +if [ ! "$?" -eq "0" ]; then + echo -DKBUILD_NO_NLS; +fi + diff --git a/adk/config/conf.c b/adk/config/conf.c new file mode 100644 index 000000000..412656fec --- /dev/null +++ b/adk/config/conf.c @@ -0,0 +1,619 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +static void conf(struct menu *menu); +static void check_conf(struct menu *menu); + +enum { + ask_all, + ask_new, + ask_silent, + set_default, + set_yes, + set_mod, + set_no, + set_random +} input_mode = ask_all; +char *defconfig_file; + +static int indent = 1; +static int valid_stdin = 1; +static int sync_kconfig; +static int conf_cnt; +static char line[128]; +static struct menu *rootEntry; + +static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n"); + +static const char *get_help(struct menu *menu) +{ + if (menu_has_help(menu)) + return _(menu_get_help(menu)); + else + return nohelp_text; +} + +static void strip(char *str) +{ + char *p = str; + int l; + + while ((isspace(*p))) + p++; + l = strlen(p); + if (p != str) + memmove(str, p, l + 1); + if (!l) + return; + p = str + l - 1; + while ((isspace(*p))) + *p-- = 0; +} + +static void check_stdin(void) +{ + if (!valid_stdin) { + printf("aborted!\n\n"); + printf("Console input/output is redirected. "); + printf("Run 'make oldconfig' to update configuration.\n\n"); + exit(1); + } +} + +static int conf_askvalue(struct symbol *sym, const char *def) +{ + enum symbol_type type = sym_get_type(sym); + + if (!sym_has_value(sym)) + printf("(NEW) "); + + line[0] = '\n'; + line[1] = 0; + + if (!sym_is_changable(sym)) { + printf("%s\n", def); + line[0] = '\n'; + line[1] = 0; + return 0; + } + + switch (input_mode) { + case ask_new: + case ask_silent: + if (sym_has_value(sym)) { + printf("%s\n", def); + return 0; + } + check_stdin(); + case ask_all: + fflush(stdout); + if (fgets(line, 128, stdin) != NULL) + return 1; + default: + break; + } + + switch (type) { + case S_INT: + case S_HEX: + case S_STRING: + printf("%s\n", def); + return 1; + default: + ; + } + printf("%s", line); + return 1; +} + +int conf_string(struct menu *menu) +{ + struct symbol *sym = menu->sym; + const char *def; + + while (1) { + printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); + printf("(%s) ", sym->name); + def = sym_get_string_value(sym); + if (sym_get_string_value(sym)) + printf("[%s] ", def); + if (!conf_askvalue(sym, def)) + return 0; + switch (line[0]) { + case '\n': + break; + case '?': + /* print help */ + if (line[1] == '\n') { + printf("\n%s\n", get_help(menu)); + def = NULL; + break; + } + default: + line[strlen(line)-1] = 0; + def = line; + } + if (def && sym_set_string_value(sym, def)) + return 0; + } +} + +static int conf_sym(struct menu *menu) +{ + struct symbol *sym = menu->sym; + int type; + tristate oldval, newval; + + while (1) { + printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); + if (sym->name) + printf("(%s) ", sym->name); + type = sym_get_type(sym); + putchar('['); + oldval = sym_get_tristate_value(sym); + switch (oldval) { + case no: + putchar('N'); + break; + case mod: + putchar('M'); + break; + case yes: + putchar('Y'); + break; + } + if (oldval != no && sym_tristate_within_range(sym, no)) + printf("/n"); + if (oldval != mod && sym_tristate_within_range(sym, mod)) + printf("/m"); + if (oldval != yes && sym_tristate_within_range(sym, yes)) + printf("/y"); + if (menu_has_help(menu)) + printf("/?"); + printf("] "); + if (!conf_askvalue(sym, sym_get_string_value(sym))) + return 0; + strip(line); + + switch (line[0]) { + case 'n': + case 'N': + newval = no; + if (!line[1] || !strcmp(&line[1], "o")) + break; + continue; + case 'm': + case 'M': + newval = mod; + if (!line[1]) + break; + continue; + case 'y': + case 'Y': + newval = yes; + if (!line[1] || !strcmp(&line[1], "es")) + break; + continue; + case 0: + newval = oldval; + break; + case '?': + goto help; + default: + continue; + } + if (sym_set_tristate_value(sym, newval)) + return 0; +help: + printf("\n%s\n", get_help(menu)); + } +} + +static int conf_choice(struct menu *menu) +{ + struct symbol *sym, *def_sym; + struct menu *child; + int type; + bool is_new; + + sym = menu->sym; + type = sym_get_type(sym); + is_new = !sym_has_value(sym); + if (sym_is_changable(sym)) { + conf_sym(menu); + sym_calc_value(sym); + switch (sym_get_tristate_value(sym)) { + case no: + return 1; + case mod: + return 0; + case yes: + break; + } + } else { + switch (sym_get_tristate_value(sym)) { + case no: + return 1; + case mod: + printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); + return 0; + case yes: + break; + } + } + + while (1) { + int cnt, def; + + printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); + def_sym = sym_get_choice_value(sym); + cnt = def = 0; + line[0] = 0; + for (child = menu->list; child; child = child->next) { + if (!menu_is_visible(child)) + continue; + if (!child->sym) { + printf("%*c %s\n", indent, '*', _(menu_get_prompt(child))); + continue; + } + cnt++; + if (child->sym == def_sym) { + def = cnt; + printf("%*c", indent, '>'); + } else + printf("%*c", indent, ' '); + printf(" %d. %s", cnt, _(menu_get_prompt(child))); + if (child->sym->name) + printf(" (%s)", child->sym->name); + if (!sym_has_value(child->sym)) + printf(" (NEW)"); + printf("\n"); + } + printf(_("%*schoice"), indent - 1, ""); + if (cnt == 1) { + printf("[1]: 1\n"); + goto conf_childs; + } + printf("[1-%d", cnt); + if (menu_has_help(menu)) + printf("?"); + printf("]: "); + switch (input_mode) { + case ask_new: + case ask_silent: + if (!is_new) { + cnt = def; + printf("%d\n", cnt); + break; + } + check_stdin(); + case ask_all: + fflush(stdout); + if (fgets(line, 128, stdin) != NULL) + strip(line); + if (line[0] == '?') { + printf("\n%s\n", get_help(menu)); + continue; + } + if (!line[0]) + cnt = def; + else if (isdigit(line[0])) + cnt = atoi(line); + else + continue; + break; + default: + break; + } + + conf_childs: + for (child = menu->list; child; child = child->next) { + if (!child->sym || !menu_is_visible(child)) + continue; + if (!--cnt) + break; + } + if (!child) + continue; + if (line[strlen(line) - 1] == '?') { + printf("\n%s\n", get_help(child)); + continue; + } + sym_set_choice_value(sym, child->sym); + for (child = child->list; child; child = child->next) { + indent += 2; + conf(child); + indent -= 2; + } + return 1; + } +} + +static void conf(struct menu *menu) +{ + struct symbol *sym; + struct property *prop; + struct menu *child; + + if (!menu_is_visible(menu)) + return; + + sym = menu->sym; + prop = menu->prompt; + if (prop) { + const char *prompt; + + switch (prop->type) { + case P_MENU: + if (input_mode == ask_silent && rootEntry != menu) { + check_conf(menu); + return; + } + case P_COMMENT: + prompt = menu_get_prompt(menu); + if (prompt) + printf("%*c\n%*c %s\n%*c\n", + indent, '*', + indent, '*', _(prompt), + indent, '*'); + default: + ; + } + } + + if (!sym) + goto conf_childs; + + if (sym_is_choice(sym)) { + conf_choice(menu); + if (sym->curr.tri != mod) + return; + goto conf_childs; + } + + switch (sym->type) { + case S_INT: + case S_HEX: + case S_STRING: + conf_string(menu); + break; + default: + conf_sym(menu); + break; + } + +conf_childs: + if (sym) + indent += 2; + for (child = menu->list; child; child = child->next) + conf(child); + if (sym) + indent -= 2; +} + +static void check_conf(struct menu *menu) +{ + struct symbol *sym; + struct menu *child; + + if (!menu_is_visible(menu)) + return; + + sym = menu->sym; + if (sym && !sym_has_value(sym)) { + if (sym_is_changable(sym) || + (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { + if (!conf_cnt++) + printf("*\n* Restart config...\n*\n"); + rootEntry = menu_get_parent_menu(menu); + conf(rootEntry); + } + } + + for (child = menu->list; child; child = child->next) + check_conf(child); +} + +int main(int ac, char **av) +{ + int opt; + const char *name; + struct stat tmpstat; + +#ifndef KBUILD_NO_NLS + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); +#endif + + while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) { + switch (opt) { + case 'o': + input_mode = ask_silent; + break; + case 's': + input_mode = ask_silent; + sync_kconfig = 1; + break; + case 'd': + input_mode = set_default; + break; + case 'D': + input_mode = set_default; + defconfig_file = optarg; + break; + case 'n': + input_mode = set_no; + break; + case 'm': + input_mode = set_mod; + break; + case 'y': + input_mode = set_yes; + break; + case 'r': + { + struct timeval now; + unsigned int seed; + + /* + * Use microseconds derived seed, + * compensate for systems where it may be zero + */ + gettimeofday(&now, NULL); + + seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); + srand(seed); + + input_mode = set_random; + break; + } + case 'h': + printf("See README for usage info\n"); + exit(0); + break; + default: + fprintf(stderr, "See README for usage info\n"); + exit(1); + } + } + if (ac == optind) { + printf(_("%s: Kconfig file missing\n"), av[0]); + exit(1); + } + name = av[optind]; + conf_parse(name); + //zconfdump(stdout); + if (sync_kconfig) { + name = conf_get_configname(); + if (stat(name, &tmpstat)) { + fprintf(stderr, _("***\n" + "*** You have not yet configured your kernel!\n" + "*** (missing kernel config file \"%s\")\n" + "***\n" + "*** Please run some configurator (e.g. \"make oldconfig\" or\n" + "*** \"make menuconfig\" or \"make xconfig\").\n" + "***\n"), name); + exit(1); + } + } + + switch (input_mode) { + case set_default: + if (!defconfig_file) + defconfig_file = conf_get_default_confname(); + if (conf_read(defconfig_file)) { + printf(_("***\n" + "*** Can't find default configuration \"%s\"!\n" + "***\n"), defconfig_file); + exit(1); + } + break; + case ask_silent: + case ask_all: + case ask_new: + conf_read(NULL); + break; + case set_no: + case set_mod: + case set_yes: + case set_random: + name = getenv("KCONFIG_ALLCONFIG"); + if (name && !stat(name, &tmpstat)) { + conf_read_simple(name, S_DEF_USER); + break; + } + switch (input_mode) { + case set_no: name = "allno.config"; break; + case set_mod: name = "allmod.config"; break; + case set_yes: name = "allyes.config"; break; + case set_random: name = "allrandom.config"; break; + default: break; + } + if (!stat(name, &tmpstat)) + conf_read_simple(name, S_DEF_USER); + else if (!stat("all.config", &tmpstat)) + conf_read_simple("all.config", S_DEF_USER); + break; + default: + break; + } + + if (sync_kconfig) { + if (conf_get_changed()) { + name = getenv("KCONFIG_NOSILENTUPDATE"); + if (name && *name) { + fprintf(stderr, + "\n*** Kernel configuration requires explicit update.\n\n"); + return 1; + } + } + valid_stdin = isatty(0) && isatty(1) && isatty(2); + } + + switch (input_mode) { + case set_no: + conf_set_all_new_symbols(def_no); + break; + case set_yes: + conf_set_all_new_symbols(def_yes); + break; + case set_mod: + conf_set_all_new_symbols(def_mod); + break; + case set_random: + conf_set_all_new_symbols(def_random); + break; + case set_default: + conf_set_all_new_symbols(def_default); + break; + case ask_new: + case ask_all: + rootEntry = &rootmenu; + conf(&rootmenu); + input_mode = ask_silent; + /* fall through */ + case ask_silent: + /* Update until a loop caused no more changes */ + do { + conf_cnt = 0; + check_conf(&rootmenu); + } while (conf_cnt); + break; + } + + if (sync_kconfig) { + /* silentoldconfig is used during the build so we shall update autoconf. + * All other commands are only used to generate a config. + */ + if (conf_get_changed() && conf_write(NULL)) { + fprintf(stderr, "\n*** Error during writing of the kernel configuration.\n\n"); + exit(1); + } + if (conf_write_autoconf()) { + fprintf(stderr, "\n*** Error during update of the kernel configuration.\n\n"); + return 1; + } + } else { + if (conf_write(NULL)) { + fprintf(stderr, "\n*** Error during writing of the kernel configuration.\n\n"); + exit(1); + } + } + return 0; +} diff --git a/adk/config/confdata.c b/adk/config/confdata.c new file mode 100644 index 000000000..4a79c72bb --- /dev/null +++ b/adk/config/confdata.c @@ -0,0 +1,899 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +static void conf_warning(const char *fmt, ...) + __attribute__ ((format (printf, 1, 2))); + +static const char *conf_filename; +static int conf_lineno, conf_warnings, conf_unsaved; + +const char conf_defname[] = "arch/$ARCH/defconfig"; + +static void conf_warning(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + conf_warnings++; +} + +const char *conf_get_configname(void) +{ + char *name = getenv("KCONFIG_CONFIG"); + + return name ? name : ".config"; +} + +const char *conf_get_autoconfig_name(void) +{ + char *name = getenv("KCONFIG_AUTOCONFIG"); + + return name ? name : "include/config/auto.conf"; +} + +static char *conf_expand_value(const char *in) +{ + struct symbol *sym; + const char *src; + static char res_value[SYMBOL_MAXLENGTH]; + char *dst, name[SYMBOL_MAXLENGTH]; + + res_value[0] = 0; + dst = name; + while ((src = strchr(in, '$'))) { + strncat(res_value, in, src - in); + src++; + dst = name; + while (isalnum(*src) || *src == '_') + *dst++ = *src++; + *dst = 0; + sym = sym_lookup(name, 0); + sym_calc_value(sym); + strcat(res_value, sym_get_string_value(sym)); + in = src; + } + strcat(res_value, in); + + return res_value; +} + +char *conf_get_default_confname(void) +{ + struct stat buf; + static char fullname[PATH_MAX+1]; + char *env, *name; + + name = conf_expand_value(conf_defname); + env = getenv(SRCTREE); + if (env) { + sprintf(fullname, "%s/%s", env, name); + if (!stat(fullname, &buf)) + return fullname; + } + return name; +} + +static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) +{ + char *p2; + + switch (sym->type) { + case S_TRISTATE: + if (p[0] == 'm') { + sym->def[def].tri = mod; + sym->flags |= def_flags; + break; + } + case S_BOOLEAN: + if (p[0] == 'y') { + sym->def[def].tri = yes; + sym->flags |= def_flags; + break; + } + if (p[0] == 'n') { + sym->def[def].tri = no; + sym->flags |= def_flags; + break; + } + conf_warning("symbol value '%s' invalid for %s", p, sym->name); + break; + case S_OTHER: + if (*p != '"') { + for (p2 = p; *p2 && !isspace(*p2); p2++) + ; + sym->type = S_STRING; + goto done; + } + case S_STRING: + if (*p++ != '"') + break; + for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { + if (*p2 == '"') { + *p2 = 0; + break; + } + memmove(p2, p2 + 1, strlen(p2)); + } + if (!p2) { + conf_warning("invalid string found"); + return 1; + } + case S_INT: + case S_HEX: + done: + if (sym_string_valid(sym, p)) { + sym->def[def].val = strdup(p); + sym->flags |= def_flags; + } else { + conf_warning("symbol value '%s' invalid for %s", p, sym->name); + return 1; + } + break; + default: + ; + } + return 0; +} + +int conf_read_simple(const char *name, int def) +{ + FILE *in = NULL; + char line[1024]; + char *p, *p2; + struct symbol *sym; + int i, def_flags; + + if (name) { + in = zconf_fopen(name); + } else { + struct property *prop; + + name = conf_get_configname(); + in = zconf_fopen(name); + if (in) + goto load; + sym_add_change_count(1); + if (!sym_defconfig_list) + return 1; + + for_all_defaults(sym_defconfig_list, prop) { + if (expr_calc_value(prop->visible.expr) == no || + prop->expr->type != E_SYMBOL) + continue; + name = conf_expand_value(prop->expr->left.sym->name); + in = zconf_fopen(name); + if (in) { + printf(_("#\n" + "# using defaults found in %s\n" + "#\n"), name); + goto load; + } + } + } + if (!in) + return 1; + +load: + conf_filename = name; + conf_lineno = 0; + conf_warnings = 0; + conf_unsaved = 0; + + def_flags = SYMBOL_DEF << def; + for_all_symbols(i, sym) { + sym->flags |= SYMBOL_CHANGED; + sym->flags &= ~(def_flags|SYMBOL_VALID); + if (sym_is_choice(sym)) + sym->flags |= def_flags; + switch (sym->type) { + case S_INT: + case S_HEX: + case S_STRING: + if (sym->def[def].val) + free(sym->def[def].val); + default: + sym->def[def].val = NULL; + sym->def[def].tri = no; + } + } + + while (fgets(line, sizeof(line), in)) { + conf_lineno++; + sym = NULL; + switch (line[0]) { + case '#': + p = strchr(line + 2, ' '); + if (!p) + continue; + *p++ = 0; + if (strncmp(p, "is not set", 10)) + continue; + if (def == S_DEF_USER) { + sym = sym_find(line + 2); + if (!sym) { + sym_add_change_count(1); + break; + } + } else { + sym = sym_lookup(line + 2, 0); + if (sym->type == S_UNKNOWN) + sym->type = S_BOOLEAN; + } + if (sym->flags & def_flags) { + conf_warning("override: reassigning to symbol %s", sym->name); + } + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + sym->def[def].tri = no; + sym->flags |= def_flags; + break; + default: + ; + } + break; + default: + p = strchr(line, '='); + if (!p) + continue; + *p++ = 0; + p2 = strchr(p, '\n'); + if (p2) { + *p2-- = 0; + if (*p2 == '\r') + *p2 = 0; + } + if (def == S_DEF_USER) { + sym = sym_find(line); + if (!sym) { + sym_add_change_count(1); + break; + } + } else { + sym = sym_lookup(line, 0); + if (sym->type == S_UNKNOWN) + sym->type = S_OTHER; + } + if (sym->flags & def_flags) { + conf_warning("override: reassigning to symbol %s", sym->name); + } + if (conf_set_sym_val(sym, def, def_flags, p)) + continue; + break; + case '\r': + case '\n': + break; + } + if (sym && sym_is_choice_value(sym)) { + struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); + switch (sym->def[def].tri) { + case no: + break; + case mod: + if (cs->def[def].tri == yes) { + conf_warning("%s creates inconsistent choice state", sym->name); + cs->flags &= ~def_flags; + } + break; + case yes: + if (cs->def[def].tri != no) + conf_warning("override: %s changes choice state", sym->name); + cs->def[def].val = sym; + break; + } + cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri); + } + } + fclose(in); + + if (modules_sym) + sym_calc_value(modules_sym); + return 0; +} + +int conf_read(const char *name) +{ + struct symbol *sym, *choice_sym; + struct property *prop; + struct expr *e; + int i, flags; + + sym_set_change_count(0); + + if (conf_read_simple(name, S_DEF_USER)) + return 1; + + for_all_symbols(i, sym) { + sym_calc_value(sym); + if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) + goto sym_ok; + if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { + /* check that calculated value agrees with saved value */ + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) + break; + if (!sym_is_choice(sym)) + goto sym_ok; + default: + if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) + goto sym_ok; + break; + } + } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) + /* no previous value and not saved */ + goto sym_ok; + conf_unsaved++; + /* maybe print value in verbose mode... */ + sym_ok: + if (!sym_is_choice(sym)) + continue; + /* The choice symbol only has a set value (and thus is not new) + * if all its visible childs have values. + */ + prop = sym_get_choice_prop(sym); + flags = sym->flags; + expr_list_for_each_sym(prop->expr, e, choice_sym) + if (choice_sym->visible != no) + flags &= choice_sym->flags; + sym->flags &= flags | ~SYMBOL_DEF_USER; + } + + for_all_symbols(i, sym) { + if (sym_has_value(sym) && !sym_is_choice_value(sym)) { + /* Reset values of generates values, so they'll appear + * as new, if they should become visible, but that + * doesn't quite work if the Kconfig and the saved + * configuration disagree. + */ + if (sym->visible == no && !conf_unsaved) + sym->flags &= ~SYMBOL_DEF_USER; + switch (sym->type) { + case S_STRING: + case S_INT: + case S_HEX: + /* Reset a string value if it's out of range */ + if (sym_string_within_range(sym, sym->def[S_DEF_USER].val)) + break; + sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER); + conf_unsaved++; + break; + default: + break; + } + } + } + + sym_add_change_count(conf_warnings || conf_unsaved); + + return 0; +} + +int conf_write(const char *name) +{ + FILE *out; + struct symbol *sym; + struct menu *menu; + const char *basename; + char dirname[128], tmpname[128], newname[128]; + int type, l; + const char *str; + time_t now; + int use_timestamp = 1; + char *env; + + dirname[0] = 0; + if (name && name[0]) { + struct stat st; + char *slash; + + if (!stat(name, &st) && S_ISDIR(st.st_mode)) { + strcpy(dirname, name); + strcat(dirname, "/"); + basename = conf_get_configname(); + } else if ((slash = strrchr(name, '/'))) { + int size = slash - name + 1; + memcpy(dirname, name, size); + dirname[size] = 0; + if (slash[1]) + basename = slash + 1; + else + basename = conf_get_configname(); + } else + basename = name; + } else + basename = conf_get_configname(); + + sprintf(newname, "%s%s", dirname, basename); + env = getenv("KCONFIG_OVERWRITECONFIG"); + if (!env || !*env) { + sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); + out = fopen(tmpname, "w"); + } else { + *tmpname = 0; + out = fopen(newname, "w"); + } + if (!out) + return 1; + + sym = sym_lookup("ADKVERSION", 0); + sym_calc_value(sym); + time(&now); + env = getenv("KCONFIG_NOTIMESTAMP"); + if (env && *env) + use_timestamp = 0; + + fprintf(out, _("#\n" + "# Automatically generated make config: don't edit\n" + "# OpenADK version: %s\n" + "%s%s" + "#\n"), + sym_get_string_value(sym), + use_timestamp ? "# " : "", + use_timestamp ? ctime(&now) : ""); + + if (!conf_get_changed()) + sym_clear_all_valid(); + + menu = rootmenu.list; + while (menu) { + sym = menu->sym; + if (!sym) { + if (!menu_is_visible(menu)) + goto next; + str = menu_get_prompt(menu); + fprintf(out, "\n" + "#\n" + "# %s\n" + "#\n", str); + } else if (!(sym->flags & SYMBOL_CHOICE)) { + sym_calc_value(sym); + if (!(sym->flags & SYMBOL_WRITE)) + goto next; + sym->flags &= ~SYMBOL_WRITE; + type = sym->type; + if (type == S_TRISTATE) { + sym_calc_value(modules_sym); + if (modules_sym->curr.tri == no) + type = S_BOOLEAN; + } + switch (type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (sym_get_tristate_value(sym)) { + case no: + fprintf(out, "# %s is not set\n", sym->name); + break; + case mod: + fprintf(out, "%s=m\n", sym->name); + break; + case yes: + fprintf(out, "%s=y\n", sym->name); + break; + } + break; + case S_STRING: + str = sym_get_string_value(sym); + fprintf(out, "%s=\"", sym->name); + while (1) { + l = strcspn(str, "\"\\"); + if (l) { + fwrite(str, l, 1, out); + str += l; + } + if (!*str) + break; + fprintf(out, "\\%c", *str++); + } + fputs("\"\n", out); + break; + case S_HEX: + str = sym_get_string_value(sym); + if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { + fprintf(out, "%s=%s\n", sym->name, str); + break; + } + case S_INT: + str = sym_get_string_value(sym); + fprintf(out, "%s=%s\n", sym->name, str); + break; + } + } + + next: + if (menu->list) { + menu = menu->list; + continue; + } + if (menu->next) + menu = menu->next; + else while ((menu = menu->parent)) { + if (menu->next) { + menu = menu->next; + break; + } + } + } + fclose(out); + + if (*tmpname) { + strcat(dirname, basename); + strcat(dirname, ".old"); + rename(newname, dirname); + if (rename(tmpname, newname)) + return 1; + } + + printf(_("#\n" + "# configuration written to %s\n" + "#\n"), newname); + + sym_set_change_count(0); + + return 0; +} + +int conf_split_config(void) +{ + const char *name; + char path[128]; + char *s, *d, c; + struct symbol *sym; + struct stat sb; + int res, i, fd; + + name = conf_get_autoconfig_name(); + conf_read_simple(name, S_DEF_AUTO); + + if (chdir("include/config")) + return 1; + + res = 0; + for_all_symbols(i, sym) { + sym_calc_value(sym); + if ((sym->flags & SYMBOL_AUTO) || !sym->name) + continue; + if (sym->flags & SYMBOL_WRITE) { + if (sym->flags & SYMBOL_DEF_AUTO) { + /* + * symbol has old and new value, + * so compare them... + */ + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + if (sym_get_tristate_value(sym) == + sym->def[S_DEF_AUTO].tri) + continue; + break; + case S_STRING: + case S_HEX: + case S_INT: + if (!strcmp(sym_get_string_value(sym), + sym->def[S_DEF_AUTO].val)) + continue; + break; + default: + break; + } + } else { + /* + * If there is no old value, only 'no' (unset) + * is allowed as new value. + */ + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + if (sym_get_tristate_value(sym) == no) + continue; + break; + default: + break; + } + } + } else if (!(sym->flags & SYMBOL_DEF_AUTO)) + /* There is neither an old nor a new value. */ + continue; + /* else + * There is an old value, but no new value ('no' (unset) + * isn't saved in auto.conf, so the old value is always + * different from 'no'). + */ + + /* Replace all '_' and append ".h" */ + s = sym->name; + d = path; + while ((c = *s++)) { + c = tolower(c); + *d++ = (c == '_') ? '/' : c; + } + strcpy(d, ".h"); + + /* Assume directory path already exists. */ + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) { + if (errno != ENOENT) { + res = 1; + break; + } + /* + * Create directory components, + * unless they exist already. + */ + d = path; + while ((d = strchr(d, '/'))) { + *d = 0; + if (stat(path, &sb) && mkdir(path, 0755)) { + res = 1; + goto out; + } + *d++ = '/'; + } + /* Try it again. */ + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) { + res = 1; + break; + } + } + close(fd); + } +out: + if (chdir("../..")) + return 1; + + return res; +} + +int conf_write_autoconf(void) +{ + struct symbol *sym; + const char *str; + const char *name; + FILE *out, *out_h; + time_t now; + int i, l; + + sym_clear_all_valid(); + + file_write_dep("include/config/auto.conf.cmd"); + + if (conf_split_config()) + return 1; + + out = fopen(".tmpconfig", "w"); + if (!out) + return 1; + + out_h = fopen(".tmpconfig.h", "w"); + if (!out_h) { + fclose(out); + return 1; + } + + sym = sym_lookup("ADKVERSION", 0); + sym_calc_value(sym); + time(&now); + fprintf(out, "#\n" + "# Automatically generated make config: don't edit\n" + "# OpenADK version: %s\n" + "# %s" + "#\n", + sym_get_string_value(sym), ctime(&now)); + fprintf(out_h, "/*\n" + " * Automatically generated C config: don't edit\n" + " * OpenADK version: %s\n" + " * %s" + " */\n" + "#define AUTOCONF_INCLUDED\n", + sym_get_string_value(sym), ctime(&now)); + + for_all_symbols(i, sym) { + sym_calc_value(sym); + if (!(sym->flags & SYMBOL_WRITE) || !sym->name) + continue; + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (sym_get_tristate_value(sym)) { + case no: + break; + case mod: + fprintf(out, "%s=m\n", sym->name); + fprintf(out_h, "#define %s_MODULE 1\n", sym->name); + break; + case yes: + fprintf(out, "%s=y\n", sym->name); + fprintf(out_h, "#define %s 1\n", sym->name); + break; + } + break; + case S_STRING: + str = sym_get_string_value(sym); + fprintf(out, "%s=\"", sym->name); + fprintf(out_h, "#define %s \"", sym->name); + while (1) { + l = strcspn(str, "\"\\"); + if (l) { + fwrite(str, l, 1, out); + fwrite(str, l, 1, out_h); + str += l; + } + if (!*str) + break; + fprintf(out, "\\%c", *str); + fprintf(out_h, "\\%c", *str); + str++; + } + fputs("\"\n", out); + fputs("\"\n", out_h); + break; + case S_HEX: + str = sym_get_string_value(sym); + if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { + fprintf(out, "%s=%s\n", sym->name, str); + fprintf(out_h, "#define %s 0x%s\n", sym->name, str); + break; + } + case S_INT: + str = sym_get_string_value(sym); + fprintf(out, "%s=%s\n", sym->name, str); + fprintf(out_h, "#define %s %s\n", sym->name, str); + break; + default: + break; + } + } + fclose(out); + fclose(out_h); + + name = getenv("KCONFIG_AUTOHEADER"); + if (!name) + name = "include/linux/autoconf.h"; + if (rename(".tmpconfig.h", name)) + return 1; + name = conf_get_autoconfig_name(); + /* + * This must be the last step, kbuild has a dependency on auto.conf + * and this marks the successful completion of the previous steps. + */ + if (rename(".tmpconfig", name)) + return 1; + + return 0; +} + +static int sym_change_count; +static void (*conf_changed_callback)(void); + +void sym_set_change_count(int count) +{ + int _sym_change_count = sym_change_count; + sym_change_count = count; + if (conf_changed_callback && + (bool)_sym_change_count != (bool)count) + conf_changed_callback(); +} + +void sym_add_change_count(int count) +{ + sym_set_change_count(count + sym_change_count); +} + +bool conf_get_changed(void) +{ + return sym_change_count; +} + +void conf_set_changed_callback(void (*fn)(void)) +{ + conf_changed_callback = fn; +} + + +void conf_set_all_new_symbols(enum conf_def_mode mode) +{ + struct symbol *sym, *csym; + struct property *prop; + struct expr *e; + int i, cnt, def; + + for_all_symbols(i, sym) { + if (sym_has_value(sym)) + continue; + switch (sym_get_type(sym)) { + case S_BOOLEAN: + case S_TRISTATE: + switch (mode) { + case def_yes: + sym->def[S_DEF_USER].tri = yes; + break; + case def_mod: + sym->def[S_DEF_USER].tri = mod; + break; + case def_no: + sym->def[S_DEF_USER].tri = no; + break; + case def_random: + sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); + break; + default: + continue; + } + if (!(sym_is_choice(sym) && mode == def_random)) + sym->flags |= SYMBOL_DEF_USER; + break; + default: + break; + } + + } + + sym_clear_all_valid(); + + if (mode != def_random) + return; + /* + * We have different type of choice blocks. + * If curr.tri equal to mod then we can select several + * choice symbols in one block. + * In this case we do nothing. + * If curr.tri equal yes then only one symbol can be + * selected in a choice block and we set it to yes, + * and the rest to no. + */ + for_all_symbols(i, csym) { + if (sym_has_value(csym) || !sym_is_choice(csym)) + continue; + + sym_calc_value(csym); + + if (csym->curr.tri != yes) + continue; + + prop = sym_get_choice_prop(csym); + + /* count entries in choice block */ + cnt = 0; + expr_list_for_each_sym(prop->expr, e, sym) + cnt++; + + /* + * find a random value and set it to yes, + * set the rest to no so we have only one set + */ + def = (rand() % cnt); + + cnt = 0; + expr_list_for_each_sym(prop->expr, e, sym) { + if (def == cnt++) { + sym->def[S_DEF_USER].tri = yes; + csym->def[S_DEF_USER].val = sym; + } + else { + sym->def[S_DEF_USER].tri = no; + } + } + csym->flags |= SYMBOL_DEF_USER; + /* clear VALID to get value calculated */ + csym->flags &= ~(SYMBOL_VALID); + } +} diff --git a/adk/config/expr.c b/adk/config/expr.c new file mode 100644 index 000000000..579ece4fa --- /dev/null +++ b/adk/config/expr.c @@ -0,0 +1,1106 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +#define DEBUG_EXPR 0 + +struct expr *expr_alloc_symbol(struct symbol *sym) +{ + struct expr *e = malloc(sizeof(*e)); + memset(e, 0, sizeof(*e)); + e->type = E_SYMBOL; + e->left.sym = sym; + return e; +} + +struct expr *expr_alloc_one(enum expr_type type, struct expr *ce) +{ + struct expr *e = malloc(sizeof(*e)); + memset(e, 0, sizeof(*e)); + e->type = type; + e->left.expr = ce; + return e; +} + +struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2) +{ + struct expr *e = malloc(sizeof(*e)); + memset(e, 0, sizeof(*e)); + e->type = type; + e->left.expr = e1; + e->right.expr = e2; + return e; +} + +struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2) +{ + struct expr *e = malloc(sizeof(*e)); + memset(e, 0, sizeof(*e)); + e->type = type; + e->left.sym = s1; + e->right.sym = s2; + return e; +} + +struct expr *expr_alloc_and(struct expr *e1, struct expr *e2) +{ + if (!e1) + return e2; + return e2 ? expr_alloc_two(E_AND, e1, e2) : e1; +} + +struct expr *expr_alloc_or(struct expr *e1, struct expr *e2) +{ + if (!e1) + return e2; + return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; +} + +struct expr *expr_copy(struct expr *org) +{ + struct expr *e; + + if (!org) + return NULL; + + e = malloc(sizeof(*org)); + memcpy(e, org, sizeof(*org)); + switch (org->type) { + case E_SYMBOL: + e->left = org->left; + break; + case E_NOT: + e->left.expr = expr_copy(org->left.expr); + break; + case E_EQUAL: + case E_UNEQUAL: + e->left.sym = org->left.sym; + e->right.sym = org->right.sym; + break; + case E_AND: + case E_OR: + case E_LIST: + e->left.expr = expr_copy(org->left.expr); + e->right.expr = expr_copy(org->right.expr); + break; + default: + printf("can't copy type %d\n", e->type); + free(e); + e = NULL; + break; + } + + return e; +} + +void expr_free(struct expr *e) +{ + if (!e) + return; + + switch (e->type) { + case E_SYMBOL: + break; + case E_NOT: + expr_free(e->left.expr); + return; + case E_EQUAL: + case E_UNEQUAL: + break; + case E_OR: + case E_AND: + expr_free(e->left.expr); + expr_free(e->right.expr); + break; + default: + printf("how to free type %d?\n", e->type); + break; + } + free(e); +} + +static int trans_count; + +#define e1 (*ep1) +#define e2 (*ep2) + +static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2) +{ + if (e1->type == type) { + __expr_eliminate_eq(type, &e1->left.expr, &e2); + __expr_eliminate_eq(type, &e1->right.expr, &e2); + return; + } + if (e2->type == type) { + __expr_eliminate_eq(type, &e1, &e2->left.expr); + __expr_eliminate_eq(type, &e1, &e2->right.expr); + return; + } + if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && + e1->left.sym == e2->left.sym && + (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no)) + return; + if (!expr_eq(e1, e2)) + return; + trans_count++; + expr_free(e1); expr_free(e2); + switch (type) { + case E_OR: + e1 = expr_alloc_symbol(&symbol_no); + e2 = expr_alloc_symbol(&symbol_no); + break; + case E_AND: + e1 = expr_alloc_symbol(&symbol_yes); + e2 = expr_alloc_symbol(&symbol_yes); + break; + default: + ; + } +} + +void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) +{ + if (!e1 || !e2) + return; + switch (e1->type) { + case E_OR: + case E_AND: + __expr_eliminate_eq(e1->type, ep1, ep2); + default: + ; + } + if (e1->type != e2->type) switch (e2->type) { + case E_OR: + case E_AND: + __expr_eliminate_eq(e2->type, ep1, ep2); + default: + ; + } + e1 = expr_eliminate_yn(e1); + e2 = expr_eliminate_yn(e2); +} + +#undef e1 +#undef e2 + +int expr_eq(struct expr *e1, struct expr *e2) +{ + int res, old_count; + + if (e1->type != e2->type) + return 0; + switch (e1->type) { + case E_EQUAL: + case E_UNEQUAL: + return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym; + case E_SYMBOL: + return e1->left.sym == e2->left.sym; + case E_NOT: + return expr_eq(e1->left.expr, e2->left.expr); + case E_AND: + case E_OR: + e1 = expr_copy(e1); + e2 = expr_copy(e2); + old_count = trans_count; + expr_eliminate_eq(&e1, &e2); + res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL && + e1->left.sym == e2->left.sym); + expr_free(e1); + expr_free(e2); + trans_count = old_count; + return res; + case E_LIST: + case E_RANGE: + case E_NONE: + /* panic */; + } + + if (DEBUG_EXPR) { + expr_fprint(e1, stdout); + printf(" = "); + expr_fprint(e2, stdout); + printf(" ?\n"); + } + + return 0; +} + +struct expr *expr_eliminate_yn(struct expr *e) +{ + struct expr *tmp; + + if (e) switch (e->type) { + case E_AND: + e->left.expr = expr_eliminate_yn(e->left.expr); + e->right.expr = expr_eliminate_yn(e->right.expr); + if (e->left.expr->type == E_SYMBOL) { + if (e->left.expr->left.sym == &symbol_no) { + expr_free(e->left.expr); + expr_free(e->right.expr); + e->type = E_SYMBOL; + e->left.sym = &symbol_no; + e->right.expr = NULL; + return e; + } else if (e->left.expr->left.sym == &symbol_yes) { + free(e->left.expr); + tmp = e->right.expr; + *e = *(e->right.expr); + free(tmp); + return e; + } + } + if (e->right.expr->type == E_SYMBOL) { + if (e->right.expr->left.sym == &symbol_no) { + expr_free(e->left.expr); + expr_free(e->right.expr); + e->type = E_SYMBOL; + e->left.sym = &symbol_no; + e->right.expr = NULL; + return e; + } else if (e->right.expr->left.sym == &symbol_yes) { + free(e->right.expr); + tmp = e->left.expr; + *e = *(e->left.expr); + free(tmp); + return e; + } + } + break; + case E_OR: + e->left.expr = expr_eliminate_yn(e->left.expr); + e->right.expr = expr_eliminate_yn(e->right.expr); + if (e->left.expr->type == E_SYMBOL) { + if (e->left.expr->left.sym == &symbol_no) { + free(e->left.expr); + tmp = e->right.expr; + *e = *(e->right.expr); + free(tmp); + return e; + } else if (e->left.expr->left.sym == &symbol_yes) { + expr_free(e->left.expr); + expr_free(e->right.expr); + e->type = E_SYMBOL; + e->left.sym = &symbol_yes; + e->right.expr = NULL; + return e; + } + } + if (e->right.expr->type == E_SYMBOL) { + if (e->right.expr->left.sym == &symbol_no) { + free(e->right.expr); + tmp = e->left.expr; + *e = *(e->left.expr); + free(tmp); + return e; + } else if (e->right.expr->left.sym == &symbol_yes) { + expr_free(e->left.expr); + expr_free(e->right.expr); + e->type = E_SYMBOL; + e->left.sym = &symbol_yes; + e->right.expr = NULL; + return e; + } + } + break; + default: + ; + } + return e; +} + +/* + * bool FOO!=n => FOO + */ +struct expr *expr_trans_bool(struct expr *e) +{ + if (!e) + return NULL; + switch (e->type) { + case E_AND: + case E_OR: + case E_NOT: + e->left.expr = expr_trans_bool(e->left.expr); + e->right.expr = expr_trans_bool(e->right.expr); + break; + case E_UNEQUAL: + // FOO!=n -> FOO + if (e->left.sym->type == S_TRISTATE) { + if (e->right.sym == &symbol_no) { + e->type = E_SYMBOL; + e->right.sym = NULL; + } + } + break; + default: + ; + } + return e; +} + +/* + * e1 || e2 -> ? + */ +struct expr *expr_join_or(struct expr *e1, struct expr *e2) +{ + struct expr *tmp; + struct symbol *sym1, *sym2; + + if (expr_eq(e1, e2)) + return expr_copy(e1); + if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) + return NULL; + if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) + return NULL; + if (e1->type == E_NOT) { + tmp = e1->left.expr; + if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) + return NULL; + sym1 = tmp->left.sym; + } else + sym1 = e1->left.sym; + if (e2->type == E_NOT) { + if (e2->left.expr->type != E_SYMBOL) + return NULL; + sym2 = e2->left.expr->left.sym; + } else + sym2 = e2->left.sym; + if (sym1 != sym2) + return NULL; + if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) + return NULL; + if (sym1->type == S_TRISTATE) { + if (e1->type == E_EQUAL && e2->type == E_EQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || + (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) { + // (a='y') || (a='m') -> (a!='n') + return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no); + } + if (e1->type == E_EQUAL && e2->type == E_EQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) { + // (a='y') || (a='n') -> (a!='m') + return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod); + } + if (e1->type == E_EQUAL && e2->type == E_EQUAL && + ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) { + // (a='m') || (a='n') -> (a!='y') + return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes); + } + } + if (sym1->type == S_BOOLEAN && sym1 == sym2) { + if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) || + (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL)) + return expr_alloc_symbol(&symbol_yes); + } + + if (DEBUG_EXPR) { + printf("optimize ("); + expr_fprint(e1, stdout); + printf(") || ("); + expr_fprint(e2, stdout); + printf(")?\n"); + } + return NULL; +} + +struct expr *expr_join_and(struct expr *e1, struct expr *e2) +{ + struct expr *tmp; + struct symbol *sym1, *sym2; + + if (expr_eq(e1, e2)) + return expr_copy(e1); + if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) + return NULL; + if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) + return NULL; + if (e1->type == E_NOT) { + tmp = e1->left.expr; + if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) + return NULL; + sym1 = tmp->left.sym; + } else + sym1 = e1->left.sym; + if (e2->type == E_NOT) { + if (e2->left.expr->type != E_SYMBOL) + return NULL; + sym2 = e2->left.expr->left.sym; + } else + sym2 = e2->left.sym; + if (sym1 != sym2) + return NULL; + if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) + return NULL; + + if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) || + (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes)) + // (a) && (a='y') -> (a='y') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); + + if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) || + (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no)) + // (a) && (a!='n') -> (a) + return expr_alloc_symbol(sym1); + + if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) || + (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod)) + // (a) && (a!='m') -> (a='y') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); + + if (sym1->type == S_TRISTATE) { + if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) { + // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' + sym2 = e1->right.sym; + if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) + return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) + : expr_alloc_symbol(&symbol_no); + } + if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) { + // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' + sym2 = e2->right.sym; + if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) + return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) + : expr_alloc_symbol(&symbol_no); + } + if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) + // (a!='y') && (a!='n') -> (a='m') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod); + + if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || + (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) + // (a!='y') && (a!='m') -> (a='n') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_no); + + if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && + ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) + // (a!='m') && (a!='n') -> (a='m') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); + + if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) || + (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) || + (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) || + (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes)) + return NULL; + } + + if (DEBUG_EXPR) { + printf("optimize ("); + expr_fprint(e1, stdout); + printf(") && ("); + expr_fprint(e2, stdout); + printf(")?\n"); + } + return NULL; +} + +static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) +{ +#define e1 (*ep1) +#define e2 (*ep2) + struct expr *tmp; + + if (e1->type == type) { + expr_eliminate_dups1(type, &e1->left.expr, &e2); + expr_eliminate_dups1(type, &e1->right.expr, &e2); + return; + } + if (e2->type == type) { + expr_eliminate_dups1(type, &e1, &e2->left.expr); + expr_eliminate_dups1(type, &e1, &e2->right.expr); + return; + } + if (e1 == e2) + return; + + switch (e1->type) { + case E_OR: case E_AND: + expr_eliminate_dups1(e1->type, &e1, &e1); + default: + ; + } + + switch (type) { + case E_OR: + tmp = expr_join_or(e1, e2); + if (tmp) { + expr_free(e1); expr_free(e2); + e1 = expr_alloc_symbol(&symbol_no); + e2 = tmp; + trans_count++; + } + break; + case E_AND: + tmp = expr_join_and(e1, e2); + if (tmp) { + expr_free(e1); expr_free(e2); + e1 = expr_alloc_symbol(&symbol_yes); + e2 = tmp; + trans_count++; + } + break; + default: + ; + } +#undef e1 +#undef e2 +} + +static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2) +{ +#define e1 (*ep1) +#define e2 (*ep2) + struct expr *tmp, *tmp1, *tmp2; + + if (e1->type == type) { + expr_eliminate_dups2(type, &e1->left.expr, &e2); + expr_eliminate_dups2(type, &e1->right.expr, &e2); + return; + } + if (e2->type == type) { + expr_eliminate_dups2(type, &e1, &e2->left.expr); + expr_eliminate_dups2(type, &e1, &e2->right.expr); + } + if (e1 == e2) + return; + + switch (e1->type) { + case E_OR: + expr_eliminate_dups2(e1->type, &e1, &e1); + // (FOO || BAR) && (!FOO && !BAR) -> n + tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); + tmp2 = expr_copy(e2); + tmp = expr_extract_eq_and(&tmp1, &tmp2); + if (expr_is_yes(tmp1)) { + expr_free(e1); + e1 = expr_alloc_symbol(&symbol_no); + trans_count++; + } + expr_free(tmp2); + expr_free(tmp1); + expr_free(tmp); + break; + case E_AND: + expr_eliminate_dups2(e1->type, &e1, &e1); + // (FOO && BAR) || (!FOO || !BAR) -> y + tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); + tmp2 = expr_copy(e2); + tmp = expr_extract_eq_or(&tmp1, &tmp2); + if (expr_is_no(tmp1)) { + expr_free(e1); + e1 = expr_alloc_symbol(&symbol_yes); + trans_count++; + } + expr_free(tmp2); + expr_free(tmp1); + expr_free(tmp); + break; + default: + ; + } +#undef e1 +#undef e2 +} + +struct expr *expr_eliminate_dups(struct expr *e) +{ + int oldcount; + if (!e) + return e; + + oldcount = trans_count; + while (1) { + trans_count = 0; + switch (e->type) { + case E_OR: case E_AND: + expr_eliminate_dups1(e->type, &e, &e); + expr_eliminate_dups2(e->type, &e, &e); + default: + ; + } + if (!trans_count) + break; + e = expr_eliminate_yn(e); + } + trans_count = oldcount; + return e; +} + +struct expr *expr_transform(struct expr *e) +{ + struct expr *tmp; + + if (!e) + return NULL; + switch (e->type) { + case E_EQUAL: + case E_UNEQUAL: + case E_SYMBOL: + case E_LIST: + break; + default: + e->left.expr = expr_transform(e->left.expr); + e->right.expr = expr_transform(e->right.expr); + } + + switch (e->type) { + case E_EQUAL: + if (e->left.sym->type != S_BOOLEAN) + break; + if (e->right.sym == &symbol_no) { + e->type = E_NOT; + e->left.expr = expr_alloc_symbol(e->left.sym); + e->right.sym = NULL; + break; + } + if (e->right.sym == &symbol_mod) { + printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name); + e->type = E_SYMBOL; + e->left.sym = &symbol_no; + e->right.sym = NULL; + break; + } + if (e->right.sym == &symbol_yes) { + e->type = E_SYMBOL; + e->right.sym = NULL; + break; + } + break; + case E_UNEQUAL: + if (e->left.sym->type != S_BOOLEAN) + break; + if (e->right.sym == &symbol_no) { + e->type = E_SYMBOL; + e->right.sym = NULL; + break; + } + if (e->right.sym == &symbol_mod) { + printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name); + e->type = E_SYMBOL; + e->left.sym = &symbol_yes; + e->right.sym = NULL; + break; + } + if (e->right.sym == &symbol_yes) { + e->type = E_NOT; + e->left.expr = expr_alloc_symbol(e->left.sym); + e->right.sym = NULL; + break; + } + break; + case E_NOT: + switch (e->left.expr->type) { + case E_NOT: + // !!a -> a + tmp = e->left.expr->left.expr; + free(e->left.expr); + free(e); + e = tmp; + e = expr_transform(e); + break; + case E_EQUAL: + case E_UNEQUAL: + // !a='x' -> a!='x' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; + break; + case E_OR: + // !(a || b) -> !a && !b + tmp = e->left.expr; + e->type = E_AND; + e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); + tmp->type = E_NOT; + tmp->right.expr = NULL; + e = expr_transform(e); + break; + case E_AND: + // !(a && b) -> !a || !b + tmp = e->left.expr; + e->type = E_OR; + e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); + tmp->type = E_NOT; + tmp->right.expr = NULL; + e = expr_transform(e); + break; + case E_SYMBOL: + if (e->left.expr->left.sym == &symbol_yes) { + // !'y' -> 'n' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = E_SYMBOL; + e->left.sym = &symbol_no; + break; + } + if (e->left.expr->left.sym == &symbol_mod) { + // !'m' -> 'm' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = E_SYMBOL; + e->left.sym = &symbol_mod; + break; + } + if (e->left.expr->left.sym == &symbol_no) { + // !'n' -> 'y' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = E_SYMBOL; + e->left.sym = &symbol_yes; + break; + } + break; + default: + ; + } + break; + default: + ; + } + return e; +} + +int expr_contains_symbol(struct expr *dep, struct symbol *sym) +{ + if (!dep) + return 0; + + switch (dep->type) { + case E_AND: + case E_OR: + return expr_contains_symbol(dep->left.expr, sym) || + expr_contains_symbol(dep->right.expr, sym); + case E_SYMBOL: + return dep->left.sym == sym; + case E_EQUAL: + case E_UNEQUAL: + return dep->left.sym == sym || + dep->right.sym == sym; + case E_NOT: + return expr_contains_symbol(dep->left.expr, sym); + default: + ; + } + return 0; +} + +bool expr_depends_symbol(struct expr *dep, struct symbol *sym) +{ + if (!dep) + return false; + + switch (dep->type) { + case E_AND: + return expr_depends_symbol(dep->left.expr, sym) || + expr_depends_symbol(dep->right.expr, sym); + case E_SYMBOL: + return dep->left.sym == sym; + case E_EQUAL: + if (dep->left.sym == sym) { + if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod) + return true; + } + break; + case E_UNEQUAL: + if (dep->left.sym == sym) { + if (dep->right.sym == &symbol_no) + return true; + } + break; + default: + ; + } + return false; +} + +struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) +{ + struct expr *tmp = NULL; + expr_extract_eq(E_AND, &tmp, ep1, ep2); + if (tmp) { + *ep1 = expr_eliminate_yn(*ep1); + *ep2 = expr_eliminate_yn(*ep2); + } + return tmp; +} + +struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) +{ + struct expr *tmp = NULL; + expr_extract_eq(E_OR, &tmp, ep1, ep2); + if (tmp) { + *ep1 = expr_eliminate_yn(*ep1); + *ep2 = expr_eliminate_yn(*ep2); + } + return tmp; +} + +void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2) +{ +#define e1 (*ep1) +#define e2 (*ep2) + if (e1->type == type) { + expr_extract_eq(type, ep, &e1->left.expr, &e2); + expr_extract_eq(type, ep, &e1->right.expr, &e2); + return; + } + if (e2->type == type) { + expr_extract_eq(type, ep, ep1, &e2->left.expr); + expr_extract_eq(type, ep, ep1, &e2->right.expr); + return; + } + if (expr_eq(e1, e2)) { + *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1; + expr_free(e2); + if (type == E_AND) { + e1 = expr_alloc_symbol(&symbol_yes); + e2 = expr_alloc_symbol(&symbol_yes); + } else if (type == E_OR) { + e1 = expr_alloc_symbol(&symbol_no); + e2 = expr_alloc_symbol(&symbol_no); + } + } +#undef e1 +#undef e2 +} + +struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) +{ + struct expr *e1, *e2; + + if (!e) { + e = expr_alloc_symbol(sym); + if (type == E_UNEQUAL) + e = expr_alloc_one(E_NOT, e); + return e; + } + switch (e->type) { + case E_AND: + e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); + e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); + if (sym == &symbol_yes) + e = expr_alloc_two(E_AND, e1, e2); + if (sym == &symbol_no) + e = expr_alloc_two(E_OR, e1, e2); + if (type == E_UNEQUAL) + e = expr_alloc_one(E_NOT, e); + return e; + case E_OR: + e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); + e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); + if (sym == &symbol_yes) + e = expr_alloc_two(E_OR, e1, e2); + if (sym == &symbol_no) + e = expr_alloc_two(E_AND, e1, e2); + if (type == E_UNEQUAL) + e = expr_alloc_one(E_NOT, e); + return e; + case E_NOT: + return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); + case E_UNEQUAL: + case E_EQUAL: + if (type == E_EQUAL) { + if (sym == &symbol_yes) + return expr_copy(e); + if (sym == &symbol_mod) + return expr_alloc_symbol(&symbol_no); + if (sym == &symbol_no) + return expr_alloc_one(E_NOT, expr_copy(e)); + } else { + if (sym == &symbol_yes) + return expr_alloc_one(E_NOT, expr_copy(e)); + if (sym == &symbol_mod) + return expr_alloc_symbol(&symbol_yes); + if (sym == &symbol_no) + return expr_copy(e); + } + break; + case E_SYMBOL: + return expr_alloc_comp(type, e->left.sym, sym); + case E_LIST: + case E_RANGE: + case E_NONE: + /* panic */; + } + return NULL; +} + +tristate expr_calc_value(struct expr *e) +{ + tristate val1, val2; + const char *str1, *str2; + + if (!e) + return yes; + + switch (e->type) { + case E_SYMBOL: + sym_calc_value(e->left.sym); + return e->left.sym->curr.tri; + case E_AND: + val1 = expr_calc_value(e->left.expr); + val2 = expr_calc_value(e->right.expr); + return EXPR_AND(val1, val2); + case E_OR: + val1 = expr_calc_value(e->left.expr); + val2 = expr_calc_value(e->right.expr); + return EXPR_OR(val1, val2); + case E_NOT: + val1 = expr_calc_value(e->left.expr); + return EXPR_NOT(val1); + case E_EQUAL: + sym_calc_value(e->left.sym); + sym_calc_value(e->right.sym); + str1 = sym_get_string_value(e->left.sym); + str2 = sym_get_string_value(e->right.sym); + return !strcmp(str1, str2) ? yes : no; + case E_UNEQUAL: + sym_calc_value(e->left.sym); + sym_calc_value(e->right.sym); + str1 = sym_get_string_value(e->left.sym); + str2 = sym_get_string_value(e->right.sym); + return !strcmp(str1, str2) ? no : yes; + default: + printf("expr_calc_value: %d?\n", e->type); + return no; + } +} + +int expr_compare_type(enum expr_type t1, enum expr_type t2) +{ +#if 0 + return 1; +#else + if (t1 == t2) + return 0; + switch (t1) { + case E_EQUAL: + case E_UNEQUAL: + if (t2 == E_NOT) + return 1; + case E_NOT: + if (t2 == E_AND) + return 1; + case E_AND: + if (t2 == E_OR) + return 1; + case E_OR: + if (t2 == E_LIST) + return 1; + case E_LIST: + if (t2 == 0) + return 1; + default: + return -1; + } + printf("[%dgt%d?]", t1, t2); + return 0; +#endif +} + +void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken) +{ + if (!e) { + fn(data, NULL, "y"); + return; + } + + if (expr_compare_type(prevtoken, e->type) > 0) + fn(data, NULL, "("); + switch (e->type) { + case E_SYMBOL: + if (e->left.sym->name) + fn(data, e->left.sym, e->left.sym->name); + else + fn(data, NULL, ""); + break; + case E_NOT: + fn(data, NULL, "!"); + expr_print(e->left.expr, fn, data, E_NOT); + break; + case E_EQUAL: + if (e->left.sym->name) + fn(data, e->left.sym, e->left.sym->name); + else + fn(data, NULL, ""); + fn(data, NULL, "="); + fn(data, e->right.sym, e->right.sym->name); + break; + case E_UNEQUAL: + if (e->left.sym->name) + fn(data, e->left.sym, e->left.sym->name); + else + fn(data, NULL, ""); + fn(data, NULL, "!="); + fn(data, e->right.sym, e->right.sym->name); + break; + case E_OR: + expr_print(e->left.expr, fn, data, E_OR); + fn(data, NULL, " || "); + expr_print(e->right.expr, fn, data, E_OR); + break; + case E_AND: + expr_print(e->left.expr, fn, data, E_AND); + fn(data, NULL, " && "); + expr_print(e->right.expr, fn, data, E_AND); + break; + case E_LIST: + fn(data, e->right.sym, e->right.sym->name); + if (e->left.expr) { + fn(data, NULL, " ^ "); + expr_print(e->left.expr, fn, data, E_LIST); + } + break; + case E_RANGE: + fn(data, NULL, "["); + fn(data, e->left.sym, e->left.sym->name); + fn(data, NULL, " "); + fn(data, e->right.sym, e->right.sym->name); + fn(data, NULL, "]"); + break; + default: + { + char buf[32]; + sprintf(buf, "", e->type); + fn(data, NULL, buf); + break; + } + } + if (expr_compare_type(prevtoken, e->type) > 0) + fn(data, NULL, ")"); +} + +static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) +{ + fwrite(str, strlen(str), 1, data); +} + +void expr_fprint(struct expr *e, FILE *out) +{ + expr_print(e, expr_print_file_helper, out, E_NONE); +} + +static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) +{ + str_append((struct gstr*)data, str); +} + +void expr_gstr_print(struct expr *e, struct gstr *gs) +{ + expr_print(e, expr_print_gstr_helper, gs, E_NONE); +} diff --git a/adk/config/expr.h b/adk/config/expr.h new file mode 100644 index 000000000..6408fefae --- /dev/null +++ b/adk/config/expr.h @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#ifndef EXPR_H +#define EXPR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifndef __cplusplus +#include +#endif + +struct file { + struct file *next; + struct file *parent; + char *name; + int lineno; + int flags; +}; + +#define FILE_BUSY 0x0001 +#define FILE_SCANNED 0x0002 + +typedef enum tristate { + no, mod, yes +} tristate; + +enum expr_type { + E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE +}; + +union expr_data { + struct expr *expr; + struct symbol *sym; +}; + +struct expr { + enum expr_type type; + union expr_data left, right; +}; + +#define EXPR_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2)) +#define EXPR_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2)) +#define EXPR_NOT(dep) (2-(dep)) + +#define expr_list_for_each_sym(l, e, s) \ + for (e = (l); e && (s = e->right.sym); e = e->left.expr) + +struct expr_value { + struct expr *expr; + tristate tri; +}; + +struct symbol_value { + void *val; + tristate tri; +}; + +enum symbol_type { + S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER +}; + +/* enum values are used as index to symbol.def[] */ +enum { + S_DEF_USER, /* main user value */ + S_DEF_AUTO, /* values read from auto.conf */ + S_DEF_DEF3, /* Reserved for UI usage */ + S_DEF_DEF4, /* Reserved for UI usage */ + S_DEF_COUNT +}; + +struct symbol { + struct symbol *next; + char *name; + enum symbol_type type; + struct symbol_value curr; + struct symbol_value def[S_DEF_COUNT]; + tristate visible; + int flags; + struct property *prop; + struct expr_value rev_dep; +}; + +#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) + +#define SYMBOL_CONST 0x0001 /* symbol is const */ +#define SYMBOL_CHECK 0x0008 /* used during dependency checking */ +#define SYMBOL_CHOICE 0x0010 /* start of a choice block (null name) */ +#define SYMBOL_CHOICEVAL 0x0020 /* used as a value in a choice block */ +#define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */ +#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ +#define SYMBOL_WRITE 0x0200 /* ? */ +#define SYMBOL_CHANGED 0x0400 /* ? */ +#define SYMBOL_AUTO 0x1000 /* value from environment variable */ +#define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ +#define SYMBOL_WARNED 0x8000 /* warning has been issued */ + +/* Set when symbol.def[] is used */ +#define SYMBOL_DEF 0x10000 /* First bit of SYMBOL_DEF */ +#define SYMBOL_DEF_USER 0x10000 /* symbol.def[S_DEF_USER] is valid */ +#define SYMBOL_DEF_AUTO 0x20000 /* symbol.def[S_DEF_AUTO] is valid */ +#define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */ +#define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ + +#define SYMBOL_MAXLENGTH 256 +#define SYMBOL_HASHSIZE 257 +#define SYMBOL_HASHMASK 0xff + +/* A property represent the config options that can be associated + * with a config "symbol". + * Sample: + * config FOO + * default y + * prompt "foo prompt" + * select BAR + * config BAZ + * int "BAZ Value" + * range 1..255 + */ +enum prop_type { + P_UNKNOWN, + P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */ + P_COMMENT, /* text associated with a comment */ + P_MENU, /* prompt associated with a menuconfig option */ + P_DEFAULT, /* default y */ + P_CHOICE, /* choice value */ + P_SELECT, /* select BAR */ + P_RANGE, /* range 7..100 (for a symbol) */ + P_ENV, /* value from environment variable */ +}; + +struct property { + struct property *next; /* next property - null if last */ + struct symbol *sym; /* the symbol for which the property is associated */ + enum prop_type type; /* type of property */ + const char *text; /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */ + struct expr_value visible; + struct expr *expr; /* the optional conditional part of the property */ + struct menu *menu; /* the menu the property are associated with + * valid for: P_SELECT, P_RANGE, P_CHOICE, + * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */ + struct file *file; /* what file was this property defined */ + int lineno; /* what lineno was this property defined */ +}; + +#define for_all_properties(sym, st, tok) \ + for (st = sym->prop; st; st = st->next) \ + if (st->type == (tok)) +#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT) +#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE) +#define for_all_prompts(sym, st) \ + for (st = sym->prop; st; st = st->next) \ + if (st->text) + +struct menu { + struct menu *next; + struct menu *parent; + struct menu *list; + struct symbol *sym; + struct property *prompt; + struct expr *dep; + unsigned int flags; + char *help; + struct file *file; + int lineno; + void *data; +}; + +#define MENU_CHANGED 0x0001 +#define MENU_ROOT 0x0002 + +#ifndef SWIG + +extern struct file *file_list; +extern struct file *current_file; +struct file *lookup_file(const char *name); + +extern struct symbol symbol_yes, symbol_no, symbol_mod; +extern struct symbol *modules_sym; +extern struct symbol *sym_defconfig_list; +extern int cdebug; +struct expr *expr_alloc_symbol(struct symbol *sym); +struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); +struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2); +struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); +struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); +struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); +struct expr *expr_copy(struct expr *org); +void expr_free(struct expr *e); +int expr_eq(struct expr *e1, struct expr *e2); +void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); +tristate expr_calc_value(struct expr *e); +struct expr *expr_eliminate_yn(struct expr *e); +struct expr *expr_trans_bool(struct expr *e); +struct expr *expr_eliminate_dups(struct expr *e); +struct expr *expr_transform(struct expr *e); +int expr_contains_symbol(struct expr *dep, struct symbol *sym); +bool expr_depends_symbol(struct expr *dep, struct symbol *sym); +struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); +struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); +void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); +struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); + +void expr_fprint(struct expr *e, FILE *out); +struct gstr; /* forward */ +void expr_gstr_print(struct expr *e, struct gstr *gs); + +static inline int expr_is_yes(struct expr *e) +{ + return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes); +} + +static inline int expr_is_no(struct expr *e) +{ + return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no); +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EXPR_H */ diff --git a/adk/config/gconf.c b/adk/config/gconf.c new file mode 100644 index 000000000..681125e11 --- /dev/null +++ b/adk/config/gconf.c @@ -0,0 +1,1618 @@ +/* Hey EMACS -*- linux-c -*- */ +/* + * + * Copyright (C) 2002-2003 Romain Lievin + * Released under the terms of the GNU GPL v2.0. + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "lkc.h" +#include "images.c" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +//#define DEBUG + +enum { + SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW +}; + +static gint view_mode = FULL_VIEW; +static gboolean show_name = TRUE; +static gboolean show_range = TRUE; +static gboolean show_value = TRUE; +static gboolean show_all = FALSE; +static gboolean show_debug = FALSE; +static gboolean resizeable = FALSE; + +GtkWidget *main_wnd = NULL; +GtkWidget *tree1_w = NULL; // left frame +GtkWidget *tree2_w = NULL; // right frame +GtkWidget *text_w = NULL; +GtkWidget *hpaned = NULL; +GtkWidget *vpaned = NULL; +GtkWidget *back_btn = NULL; +GtkWidget *save_btn = NULL; +GtkWidget *save_menu_item = NULL; + +GtkTextTag *tag1, *tag2; +GdkColor color; + +GtkTreeStore *tree1, *tree2, *tree; +GtkTreeModel *model1, *model2; +static GtkTreeIter *parents[256]; +static gint indent; + +static struct menu *current; // current node for SINGLE view +static struct menu *browsed; // browsed node for SPLIT view + +enum { + COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE, + COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF, + COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD, + COL_NUMBER +}; + +static void display_list(void); +static void display_tree(struct menu *menu); +static void display_tree_part(void); +static void update_tree(struct menu *src, GtkTreeIter * dst); +static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row); +static gchar **fill_row(struct menu *menu); +static void conf_changed(void); + +/* Helping/Debugging Functions */ + + +const char *dbg_print_stype(int val) +{ + static char buf[256]; + + bzero(buf, 256); + + if (val == S_UNKNOWN) + strcpy(buf, "unknown"); + if (val == S_BOOLEAN) + strcpy(buf, "boolean"); + if (val == S_TRISTATE) + strcpy(buf, "tristate"); + if (val == S_INT) + strcpy(buf, "int"); + if (val == S_HEX) + strcpy(buf, "hex"); + if (val == S_STRING) + strcpy(buf, "string"); + if (val == S_OTHER) + strcpy(buf, "other"); + +#ifdef DEBUG + printf("%s", buf); +#endif + + return buf; +} + +const char *dbg_print_flags(int val) +{ + static char buf[256]; + + bzero(buf, 256); + + if (val & SYMBOL_CONST) + strcat(buf, "const/"); + if (val & SYMBOL_CHECK) + strcat(buf, "check/"); + if (val & SYMBOL_CHOICE) + strcat(buf, "choice/"); + if (val & SYMBOL_CHOICEVAL) + strcat(buf, "choiceval/"); + if (val & SYMBOL_VALID) + strcat(buf, "valid/"); + if (val & SYMBOL_OPTIONAL) + strcat(buf, "optional/"); + if (val & SYMBOL_WRITE) + strcat(buf, "write/"); + if (val & SYMBOL_CHANGED) + strcat(buf, "changed/"); + if (val & SYMBOL_AUTO) + strcat(buf, "auto/"); + + buf[strlen(buf) - 1] = '\0'; +#ifdef DEBUG + printf("%s", buf); +#endif + + return buf; +} + +const char *dbg_print_ptype(int val) +{ + static char buf[256]; + + bzero(buf, 256); + + if (val == P_UNKNOWN) + strcpy(buf, "unknown"); + if (val == P_PROMPT) + strcpy(buf, "prompt"); + if (val == P_COMMENT) + strcpy(buf, "comment"); + if (val == P_MENU) + strcpy(buf, "menu"); + if (val == P_DEFAULT) + strcpy(buf, "default"); + if (val == P_CHOICE) + strcpy(buf, "choice"); + +#ifdef DEBUG + printf("%s", buf); +#endif + + return buf; +} + + +void replace_button_icon(GladeXML * xml, GdkDrawable * window, + GtkStyle * style, gchar * btn_name, gchar ** xpm) +{ + GdkPixmap *pixmap; + GdkBitmap *mask; + GtkToolButton *button; + GtkWidget *image; + + pixmap = gdk_pixmap_create_from_xpm_d(window, &mask, + &style->bg[GTK_STATE_NORMAL], + xpm); + + button = GTK_TOOL_BUTTON(glade_xml_get_widget(xml, btn_name)); + image = gtk_image_new_from_pixmap(pixmap, mask); + gtk_widget_show(image); + gtk_tool_button_set_icon_widget(button, image); +} + +/* Main Window Initialization */ +void init_main_window(const gchar * glade_file) +{ + GladeXML *xml; + GtkWidget *widget; + GtkTextBuffer *txtbuf; + char title[256]; + GtkStyle *style; + + xml = glade_xml_new(glade_file, "window1", NULL); + if (!xml) + g_error(_("GUI loading failed !\n")); + glade_xml_signal_autoconnect(xml); + + main_wnd = glade_xml_get_widget(xml, "window1"); + hpaned = glade_xml_get_widget(xml, "hpaned1"); + vpaned = glade_xml_get_widget(xml, "vpaned1"); + tree1_w = glade_xml_get_widget(xml, "treeview1"); + tree2_w = glade_xml_get_widget(xml, "treeview2"); + text_w = glade_xml_get_widget(xml, "textview3"); + + back_btn = glade_xml_get_widget(xml, "button1"); + gtk_widget_set_sensitive(back_btn, FALSE); + + widget = glade_xml_get_widget(xml, "show_name1"); + gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, + show_name); + + widget = glade_xml_get_widget(xml, "show_range1"); + gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, + show_range); + + widget = glade_xml_get_widget(xml, "show_data1"); + gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, + show_value); + + save_btn = glade_xml_get_widget(xml, "button3"); + save_menu_item = glade_xml_get_widget(xml, "save1"); + conf_set_changed_callback(conf_changed); + + style = gtk_widget_get_style(main_wnd); + widget = glade_xml_get_widget(xml, "toolbar1"); + +#if 0 /* Use stock Gtk icons instead */ + replace_button_icon(xml, main_wnd->window, style, + "button1", (gchar **) xpm_back); + replace_button_icon(xml, main_wnd->window, style, + "button2", (gchar **) xpm_load); + replace_button_icon(xml, main_wnd->window, style, + "button3", (gchar **) xpm_save); +#endif + replace_button_icon(xml, main_wnd->window, style, + "button4", (gchar **) xpm_single_view); + replace_button_icon(xml, main_wnd->window, style, + "button5", (gchar **) xpm_split_view); + replace_button_icon(xml, main_wnd->window, style, + "button6", (gchar **) xpm_tree_view); + +#if 0 + switch (view_mode) { + case SINGLE_VIEW: + widget = glade_xml_get_widget(xml, "button4"); + g_signal_emit_by_name(widget, "clicked"); + break; + case SPLIT_VIEW: + widget = glade_xml_get_widget(xml, "button5"); + g_signal_emit_by_name(widget, "clicked"); + break; + case FULL_VIEW: + widget = glade_xml_get_widget(xml, "button6"); + g_signal_emit_by_name(widget, "clicked"); + break; + } +#endif + txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); + tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1", + "foreground", "red", + "weight", PANGO_WEIGHT_BOLD, + NULL); + tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2", + /*"style", PANGO_STYLE_OBLIQUE, */ + NULL); + + sprintf(title, _("OpenADK Configuration")); + gtk_window_set_title(GTK_WINDOW(main_wnd), title); + + gtk_widget_show(main_wnd); +} + +void init_tree_model(void) +{ + gint i; + + tree = tree2 = gtk_tree_store_new(COL_NUMBER, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_POINTER, GDK_TYPE_COLOR, + G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN); + model2 = GTK_TREE_MODEL(tree2); + + for (parents[0] = NULL, i = 1; i < 256; i++) + parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter)); + + tree1 = gtk_tree_store_new(COL_NUMBER, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_POINTER, GDK_TYPE_COLOR, + G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN); + model1 = GTK_TREE_MODEL(tree1); +} + +void init_left_tree(void) +{ + GtkTreeView *view = GTK_TREE_VIEW(tree1_w); + GtkCellRenderer *renderer; + GtkTreeSelection *sel; + GtkTreeViewColumn *column; + + gtk_tree_view_set_model(view, model1); + gtk_tree_view_set_headers_visible(view, TRUE); + gtk_tree_view_set_rules_hint(view, FALSE); + + column = gtk_tree_view_column_new(); + gtk_tree_view_append_column(view, column); + gtk_tree_view_column_set_title(column, _("Options")); + + renderer = gtk_cell_renderer_toggle_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "active", COL_BTNACT, + "inconsistent", COL_BTNINC, + "visible", COL_BTNVIS, + "radio", COL_BTNRAD, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "text", COL_OPTION, + "foreground-gdk", + COL_COLOR, NULL); + + sel = gtk_tree_view_get_selection(view); + gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); + gtk_widget_realize(tree1_w); +} + +static void renderer_edited(GtkCellRendererText * cell, + const gchar * path_string, + const gchar * new_text, gpointer user_data); +static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle, + gchar * arg1, gpointer user_data); + +void init_right_tree(void) +{ + GtkTreeView *view = GTK_TREE_VIEW(tree2_w); + GtkCellRenderer *renderer; + GtkTreeSelection *sel; + GtkTreeViewColumn *column; + gint i; + + gtk_tree_view_set_model(view, model2); + gtk_tree_view_set_headers_visible(view, TRUE); + gtk_tree_view_set_rules_hint(view, FALSE); + + column = gtk_tree_view_column_new(); + gtk_tree_view_append_column(view, column); + gtk_tree_view_column_set_title(column, _("Options")); + + renderer = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "pixbuf", COL_PIXBUF, + "visible", COL_PIXVIS, NULL); + renderer = gtk_cell_renderer_toggle_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "active", COL_BTNACT, + "inconsistent", COL_BTNINC, + "visible", COL_BTNVIS, + "radio", COL_BTNRAD, NULL); + /*g_signal_connect(G_OBJECT(renderer), "toggled", + G_CALLBACK(renderer_toggled), NULL); */ + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "text", COL_OPTION, + "foreground-gdk", + COL_COLOR, NULL); + + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + _("Name"), renderer, + "text", COL_NAME, + "foreground-gdk", + COL_COLOR, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "N", renderer, + "text", COL_NO, + "foreground-gdk", + COL_COLOR, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "M", renderer, + "text", COL_MOD, + "foreground-gdk", + COL_COLOR, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "Y", renderer, + "text", COL_YES, + "foreground-gdk", + COL_COLOR, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + _("Value"), renderer, + "text", COL_VALUE, + "editable", + COL_EDIT, + "foreground-gdk", + COL_COLOR, NULL); + g_signal_connect(G_OBJECT(renderer), "edited", + G_CALLBACK(renderer_edited), NULL); + + column = gtk_tree_view_get_column(view, COL_NAME); + gtk_tree_view_column_set_visible(column, show_name); + column = gtk_tree_view_get_column(view, COL_NO); + gtk_tree_view_column_set_visible(column, show_range); + column = gtk_tree_view_get_column(view, COL_MOD); + gtk_tree_view_column_set_visible(column, show_range); + column = gtk_tree_view_get_column(view, COL_YES); + gtk_tree_view_column_set_visible(column, show_range); + column = gtk_tree_view_get_column(view, COL_VALUE); + gtk_tree_view_column_set_visible(column, show_value); + + if (resizeable) { + for (i = 0; i < COL_VALUE; i++) { + column = gtk_tree_view_get_column(view, i); + gtk_tree_view_column_set_resizable(column, TRUE); + } + } + + sel = gtk_tree_view_get_selection(view); + gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); +} + + +/* Utility Functions */ + + +static void text_insert_help(struct menu *menu) +{ + GtkTextBuffer *buffer; + GtkTextIter start, end; + const char *prompt = _(menu_get_prompt(menu)); + struct gstr help = str_new(); + + menu_get_ext_help(menu, &help); + + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); + gtk_text_buffer_get_bounds(buffer, &start, &end); + gtk_text_buffer_delete(buffer, &start, &end); + gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15); + + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1, + NULL); + gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2); + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, str_get(&help), -1, tag2, + NULL); + str_free(&help); +} + + +static void text_insert_msg(const char *title, const char *message) +{ + GtkTextBuffer *buffer; + GtkTextIter start, end; + const char *msg = message; + + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); + gtk_text_buffer_get_bounds(buffer, &start, &end); + gtk_text_buffer_delete(buffer, &start, &end); + gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15); + + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1, + NULL); + gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2); + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2, + NULL); +} + + +/* Main Windows Callbacks */ + +void on_save_activate(GtkMenuItem * menuitem, gpointer user_data); +gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event, + gpointer user_data) +{ + GtkWidget *dialog, *label; + gint result; + + if (!conf_get_changed()) + return FALSE; + + dialog = gtk_dialog_new_with_buttons(_("Warning !"), + GTK_WINDOW(main_wnd), + (GtkDialogFlags) + (GTK_DIALOG_MODAL | + GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_STOCK_OK, + GTK_RESPONSE_YES, + GTK_STOCK_NO, + GTK_RESPONSE_NO, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, NULL); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), + GTK_RESPONSE_CANCEL); + + label = gtk_label_new(_("\nSave configuration ?\n")); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label); + gtk_widget_show(label); + + result = gtk_dialog_run(GTK_DIALOG(dialog)); + switch (result) { + case GTK_RESPONSE_YES: + on_save_activate(NULL, NULL); + return FALSE; + case GTK_RESPONSE_NO: + return FALSE; + case GTK_RESPONSE_CANCEL: + case GTK_RESPONSE_DELETE_EVENT: + default: + gtk_widget_destroy(dialog); + return TRUE; + } + + return FALSE; +} + + +void on_window1_destroy(GtkObject * object, gpointer user_data) +{ + gtk_main_quit(); +} + + +void +on_window1_size_request(GtkWidget * widget, + GtkRequisition * requisition, gpointer user_data) +{ + static gint old_h; + gint w, h; + + if (widget->window == NULL) + gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h); + else + gdk_window_get_size(widget->window, &w, &h); + + if (h == old_h) + return; + old_h = h; + + gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3); +} + + +/* Menu & Toolbar Callbacks */ + + +static void +load_filename(GtkFileSelection * file_selector, gpointer user_data) +{ + const gchar *fn; + + fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION + (user_data)); + + if (conf_read(fn)) + text_insert_msg(_("Error"), _("Unable to load configuration !")); + else + display_tree(&rootmenu); +} + +void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *fs; + + fs = gtk_file_selection_new(_("Load file...")); + g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), + "clicked", + G_CALLBACK(load_filename), (gpointer) fs); + g_signal_connect_swapped(GTK_OBJECT + (GTK_FILE_SELECTION(fs)->ok_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + (gpointer) fs); + g_signal_connect_swapped(GTK_OBJECT + (GTK_FILE_SELECTION(fs)->cancel_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + (gpointer) fs); + gtk_widget_show(fs); +} + + +void on_save_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + if (conf_write(NULL)) + text_insert_msg(_("Error"), _("Unable to save configuration !")); +} + + +static void +store_filename(GtkFileSelection * file_selector, gpointer user_data) +{ + const gchar *fn; + + fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION + (user_data)); + + if (conf_write(fn)) + text_insert_msg(_("Error"), _("Unable to save configuration !")); + + gtk_widget_destroy(GTK_WIDGET(user_data)); +} + +void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *fs; + + fs = gtk_file_selection_new(_("Save file as...")); + g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), + "clicked", + G_CALLBACK(store_filename), (gpointer) fs); + g_signal_connect_swapped(GTK_OBJECT + (GTK_FILE_SELECTION(fs)->ok_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + (gpointer) fs); + g_signal_connect_swapped(GTK_OBJECT + (GTK_FILE_SELECTION(fs)->cancel_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + (gpointer) fs); + gtk_widget_show(fs); +} + + +void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + if (!on_window1_delete_event(NULL, NULL, NULL)) + gtk_widget_destroy(GTK_WIDGET(main_wnd)); +} + + +void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkTreeViewColumn *col; + + show_name = GTK_CHECK_MENU_ITEM(menuitem)->active; + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME); + if (col) + gtk_tree_view_column_set_visible(col, show_name); +} + + +void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkTreeViewColumn *col; + + show_range = GTK_CHECK_MENU_ITEM(menuitem)->active; + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO); + if (col) + gtk_tree_view_column_set_visible(col, show_range); + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_MOD); + if (col) + gtk_tree_view_column_set_visible(col, show_range); + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_YES); + if (col) + gtk_tree_view_column_set_visible(col, show_range); + +} + + +void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkTreeViewColumn *col; + + show_value = GTK_CHECK_MENU_ITEM(menuitem)->active; + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE); + if (col) + gtk_tree_view_column_set_visible(col, show_value); +} + + +void +on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + show_all = GTK_CHECK_MENU_ITEM(menuitem)->active; + + gtk_tree_store_clear(tree2); + display_tree(&rootmenu); // instead of update_tree to speed-up +} + + +void +on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active; + update_tree(&rootmenu, NULL); +} + + +void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *dialog; + const gchar *intro_text = _( + "Welcome to gkc, the GTK+ graphical kernel configuration tool\n" + "for Linux.\n" + "For each option, a blank box indicates the feature is disabled, a\n" + "check indicates it is enabled, and a dot indicates that it is to\n" + "be compiled as a module. Clicking on the box will cycle through the three states.\n" + "\n" + "If you do not see an option (e.g., a device driver) that you\n" + "believe should be present, try turning on Show All Options\n" + "under the Options menu.\n" + "Although there is no cross reference yet to help you figure out\n" + "what other options must be enabled to support the option you\n" + "are interested in, you can still view the help of a grayed-out\n" + "option.\n" + "\n" + "Toggling Show Debug Info under the Options menu will show \n" + "the dependencies, which you can then match by examining other options."); + + dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_CLOSE, intro_text); + g_signal_connect_swapped(GTK_OBJECT(dialog), "response", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(dialog)); + gtk_widget_show_all(dialog); +} + + +void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *dialog; + const gchar *about_text = + _("gkc is copyright (c) 2002 Romain Lievin .\n" + "Based on the source code from Roman Zippel.\n"); + + dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_CLOSE, about_text); + g_signal_connect_swapped(GTK_OBJECT(dialog), "response", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(dialog)); + gtk_widget_show_all(dialog); +} + + +void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *dialog; + const gchar *license_text = + _("gkc is released under the terms of the GNU GPL v2.\n" + "For more information, please see the source code or\n" + "visit http://www.fsf.org/licenses/licenses.html\n"); + + dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_CLOSE, license_text); + g_signal_connect_swapped(GTK_OBJECT(dialog), "response", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(dialog)); + gtk_widget_show_all(dialog); +} + + +void on_back_clicked(GtkButton * button, gpointer user_data) +{ + enum prop_type ptype; + + current = current->parent; + ptype = current->prompt ? current->prompt->type : P_UNKNOWN; + if (ptype != P_MENU) + current = current->parent; + display_tree_part(); + + if (current == &rootmenu) + gtk_widget_set_sensitive(back_btn, FALSE); +} + + +void on_load_clicked(GtkButton * button, gpointer user_data) +{ + on_load1_activate(NULL, user_data); +} + + +void on_single_clicked(GtkButton * button, gpointer user_data) +{ + view_mode = SINGLE_VIEW; + gtk_paned_set_position(GTK_PANED(hpaned), 0); + gtk_widget_hide(tree1_w); + current = &rootmenu; + display_tree_part(); +} + + +void on_split_clicked(GtkButton * button, gpointer user_data) +{ + gint w, h; + view_mode = SPLIT_VIEW; + gtk_widget_show(tree1_w); + gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h); + gtk_paned_set_position(GTK_PANED(hpaned), w / 2); + if (tree2) + gtk_tree_store_clear(tree2); + display_list(); + + /* Disable back btn, like in full mode. */ + gtk_widget_set_sensitive(back_btn, FALSE); +} + + +void on_full_clicked(GtkButton * button, gpointer user_data) +{ + view_mode = FULL_VIEW; + gtk_paned_set_position(GTK_PANED(hpaned), 0); + gtk_widget_hide(tree1_w); + if (tree2) + gtk_tree_store_clear(tree2); + display_tree(&rootmenu); + gtk_widget_set_sensitive(back_btn, FALSE); +} + + +void on_collapse_clicked(GtkButton * button, gpointer user_data) +{ + gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w)); +} + + +void on_expand_clicked(GtkButton * button, gpointer user_data) +{ + gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); +} + + +/* CTree Callbacks */ + +/* Change hex/int/string value in the cell */ +static void renderer_edited(GtkCellRendererText * cell, + const gchar * path_string, + const gchar * new_text, gpointer user_data) +{ + GtkTreePath *path = gtk_tree_path_new_from_string(path_string); + GtkTreeIter iter; + const char *old_def, *new_def; + struct menu *menu; + struct symbol *sym; + + if (!gtk_tree_model_get_iter(model2, &iter, path)) + return; + + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + sym = menu->sym; + + gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1); + new_def = new_text; + + sym_set_string_value(sym, new_def); + + update_tree(&rootmenu, NULL); + + gtk_tree_path_free(path); +} + +/* Change the value of a symbol and update the tree */ +static void change_sym_value(struct menu *menu, gint col) +{ + struct symbol *sym = menu->sym; + tristate oldval, newval; + + if (!sym) + return; + + if (col == COL_NO) + newval = no; + else if (col == COL_MOD) + newval = mod; + else if (col == COL_YES) + newval = yes; + else + return; + + switch (sym_get_type(sym)) { + case S_BOOLEAN: + case S_TRISTATE: + oldval = sym_get_tristate_value(sym); + if (!sym_tristate_within_range(sym, newval)) + newval = yes; + sym_set_tristate_value(sym, newval); + if (view_mode == FULL_VIEW) + update_tree(&rootmenu, NULL); + else if (view_mode == SPLIT_VIEW) { + update_tree(browsed, NULL); + display_list(); + } + else if (view_mode == SINGLE_VIEW) + display_tree_part(); //fixme: keep exp/coll + break; + case S_INT: + case S_HEX: + case S_STRING: + default: + break; + } +} + +static void toggle_sym_value(struct menu *menu) +{ + if (!menu->sym) + return; + + sym_toggle_tristate_value(menu->sym); + if (view_mode == FULL_VIEW) + update_tree(&rootmenu, NULL); + else if (view_mode == SPLIT_VIEW) { + update_tree(browsed, NULL); + display_list(); + } + else if (view_mode == SINGLE_VIEW) + display_tree_part(); //fixme: keep exp/coll +} + +static void renderer_toggled(GtkCellRendererToggle * cell, + gchar * path_string, gpointer user_data) +{ + GtkTreePath *path, *sel_path = NULL; + GtkTreeIter iter, sel_iter; + GtkTreeSelection *sel; + struct menu *menu; + + path = gtk_tree_path_new_from_string(path_string); + if (!gtk_tree_model_get_iter(model2, &iter, path)) + return; + + sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree2_w)); + if (gtk_tree_selection_get_selected(sel, NULL, &sel_iter)) + sel_path = gtk_tree_model_get_path(model2, &sel_iter); + if (!sel_path) + goto out1; + if (gtk_tree_path_compare(path, sel_path)) + goto out2; + + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + toggle_sym_value(menu); + + out2: + gtk_tree_path_free(sel_path); + out1: + gtk_tree_path_free(path); +} + +static gint column2index(GtkTreeViewColumn * column) +{ + gint i; + + for (i = 0; i < COL_NUMBER; i++) { + GtkTreeViewColumn *col; + + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), i); + if (col == column) + return i; + } + + return -1; +} + + +/* User click: update choice (full) or goes down (single) */ +gboolean +on_treeview2_button_press_event(GtkWidget * widget, + GdkEventButton * event, gpointer user_data) +{ + GtkTreeView *view = GTK_TREE_VIEW(widget); + GtkTreePath *path; + GtkTreeViewColumn *column; + GtkTreeIter iter; + struct menu *menu; + gint col; + +#if GTK_CHECK_VERSION(2,1,4) // bug in ctree with earlier version of GTK + gint tx = (gint) event->x; + gint ty = (gint) event->y; + gint cx, cy; + + gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx, + &cy); +#else + gtk_tree_view_get_cursor(view, &path, &column); +#endif + if (path == NULL) + return FALSE; + + if (!gtk_tree_model_get_iter(model2, &iter, path)) + return FALSE; + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + + col = column2index(column); + if (event->type == GDK_2BUTTON_PRESS) { + enum prop_type ptype; + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + + if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) { + // goes down into menu + current = menu; + display_tree_part(); + gtk_widget_set_sensitive(back_btn, TRUE); + } else if ((col == COL_OPTION)) { + toggle_sym_value(menu); + gtk_tree_view_expand_row(view, path, TRUE); + } + } else { + if (col == COL_VALUE) { + toggle_sym_value(menu); + gtk_tree_view_expand_row(view, path, TRUE); + } else if (col == COL_NO || col == COL_MOD + || col == COL_YES) { + change_sym_value(menu, col); + gtk_tree_view_expand_row(view, path, TRUE); + } + } + + return FALSE; +} + +/* Key pressed: update choice */ +gboolean +on_treeview2_key_press_event(GtkWidget * widget, + GdkEventKey * event, gpointer user_data) +{ + GtkTreeView *view = GTK_TREE_VIEW(widget); + GtkTreePath *path; + GtkTreeViewColumn *column; + GtkTreeIter iter; + struct menu *menu; + gint col; + + gtk_tree_view_get_cursor(view, &path, &column); + if (path == NULL) + return FALSE; + + if (event->keyval == GDK_space) { + if (gtk_tree_view_row_expanded(view, path)) + gtk_tree_view_collapse_row(view, path); + else + gtk_tree_view_expand_row(view, path, FALSE); + return TRUE; + } + if (event->keyval == GDK_KP_Enter) { + } + if (widget == tree1_w) + return FALSE; + + gtk_tree_model_get_iter(model2, &iter, path); + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + + if (!strcasecmp(event->string, "n")) + col = COL_NO; + else if (!strcasecmp(event->string, "m")) + col = COL_MOD; + else if (!strcasecmp(event->string, "y")) + col = COL_YES; + else + col = -1; + change_sym_value(menu, col); + + return FALSE; +} + + +/* Row selection changed: update help */ +void +on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data) +{ + GtkTreeSelection *selection; + GtkTreeIter iter; + struct menu *menu; + + selection = gtk_tree_view_get_selection(treeview); + if (gtk_tree_selection_get_selected(selection, &model2, &iter)) { + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + text_insert_help(menu); + } +} + + +/* User click: display sub-tree in the right frame. */ +gboolean +on_treeview1_button_press_event(GtkWidget * widget, + GdkEventButton * event, gpointer user_data) +{ + GtkTreeView *view = GTK_TREE_VIEW(widget); + GtkTreePath *path; + GtkTreeViewColumn *column; + GtkTreeIter iter; + struct menu *menu; + + gint tx = (gint) event->x; + gint ty = (gint) event->y; + gint cx, cy; + + gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx, + &cy); + if (path == NULL) + return FALSE; + + gtk_tree_model_get_iter(model1, &iter, path); + gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1); + + if (event->type == GDK_2BUTTON_PRESS) { + toggle_sym_value(menu); + current = menu; + display_tree_part(); + } else { + browsed = menu; + display_tree_part(); + } + + gtk_widget_realize(tree2_w); + gtk_tree_view_set_cursor(view, path, NULL, FALSE); + gtk_widget_grab_focus(tree2_w); + + return FALSE; +} + + +/* Fill a row of strings */ +static gchar **fill_row(struct menu *menu) +{ + static gchar *row[COL_NUMBER]; + struct symbol *sym = menu->sym; + const char *def; + int stype; + tristate val; + enum prop_type ptype; + int i; + + for (i = COL_OPTION; i <= COL_COLOR; i++) + g_free(row[i]); + bzero(row, sizeof(row)); + + row[COL_OPTION] = + g_strdup_printf("%s %s", _(menu_get_prompt(menu)), + sym && sym_has_value(sym) ? "(NEW)" : ""); + + if (show_all && !menu_is_visible(menu)) + row[COL_COLOR] = g_strdup("DarkGray"); + else + row[COL_COLOR] = g_strdup("Black"); + + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + switch (ptype) { + case P_MENU: + row[COL_PIXBUF] = (gchar *) xpm_menu; + if (view_mode == SINGLE_VIEW) + row[COL_PIXVIS] = GINT_TO_POINTER(TRUE); + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); + break; + case P_COMMENT: + row[COL_PIXBUF] = (gchar *) xpm_void; + row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); + break; + default: + row[COL_PIXBUF] = (gchar *) xpm_void; + row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); + row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); + break; + } + + if (!sym) + return row; + row[COL_NAME] = g_strdup(sym->name); + + sym_calc_value(sym); + sym->flags &= ~SYMBOL_CHANGED; + + if (sym_is_choice(sym)) { // parse childs for getting final value + struct menu *child; + struct symbol *def_sym = sym_get_choice_value(sym); + struct menu *def_menu = NULL; + + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); + + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child) + && child->sym == def_sym) + def_menu = child; + } + + if (def_menu) + row[COL_VALUE] = + g_strdup(_(menu_get_prompt(def_menu))); + } + if (sym->flags & SYMBOL_CHOICEVAL) + row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); + + stype = sym_get_type(sym); + switch (stype) { + case S_BOOLEAN: + if (GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE) + row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); + if (sym_is_choice(sym)) + break; + case S_TRISTATE: + val = sym_get_tristate_value(sym); + switch (val) { + case no: + row[COL_NO] = g_strdup("N"); + row[COL_VALUE] = g_strdup("N"); + row[COL_BTNACT] = GINT_TO_POINTER(FALSE); + row[COL_BTNINC] = GINT_TO_POINTER(FALSE); + break; + case mod: + row[COL_MOD] = g_strdup("M"); + row[COL_VALUE] = g_strdup("M"); + row[COL_BTNINC] = GINT_TO_POINTER(TRUE); + break; + case yes: + row[COL_YES] = g_strdup("Y"); + row[COL_VALUE] = g_strdup("Y"); + row[COL_BTNACT] = GINT_TO_POINTER(TRUE); + row[COL_BTNINC] = GINT_TO_POINTER(FALSE); + break; + } + + if (val != no && sym_tristate_within_range(sym, no)) + row[COL_NO] = g_strdup("_"); + if (val != mod && sym_tristate_within_range(sym, mod)) + row[COL_MOD] = g_strdup("_"); + if (val != yes && sym_tristate_within_range(sym, yes)) + row[COL_YES] = g_strdup("_"); + break; + case S_INT: + case S_HEX: + case S_STRING: + def = sym_get_string_value(sym); + row[COL_VALUE] = g_strdup(def); + row[COL_EDIT] = GINT_TO_POINTER(TRUE); + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); + break; + } + + return row; +} + + +/* Set the node content with a row of strings */ +static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row) +{ + GdkColor color; + gboolean success; + GdkPixbuf *pix; + + pix = gdk_pixbuf_new_from_xpm_data((const char **) + row[COL_PIXBUF]); + + gdk_color_parse(row[COL_COLOR], &color); + gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1, + FALSE, FALSE, &success); + + gtk_tree_store_set(tree, node, + COL_OPTION, row[COL_OPTION], + COL_NAME, row[COL_NAME], + COL_NO, row[COL_NO], + COL_MOD, row[COL_MOD], + COL_YES, row[COL_YES], + COL_VALUE, row[COL_VALUE], + COL_MENU, (gpointer) menu, + COL_COLOR, &color, + COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]), + COL_PIXBUF, pix, + COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]), + COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]), + COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]), + COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]), + COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]), + -1); + + g_object_unref(pix); +} + + +/* Add a node to the tree */ +static void place_node(struct menu *menu, char **row) +{ + GtkTreeIter *parent = parents[indent - 1]; + GtkTreeIter *node = parents[indent]; + + gtk_tree_store_append(tree, node, parent); + set_node(node, menu, row); +} + + +/* Find a node in the GTK+ tree */ +static GtkTreeIter found; + +/* + * Find a menu in the GtkTree starting at parent. + */ +GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent, + struct menu *tofind) +{ + GtkTreeIter iter; + GtkTreeIter *child = &iter; + gboolean valid; + GtkTreeIter *ret; + + valid = gtk_tree_model_iter_children(model2, child, parent); + while (valid) { + struct menu *menu; + + gtk_tree_model_get(model2, child, 6, &menu, -1); + + if (menu == tofind) { + memcpy(&found, child, sizeof(GtkTreeIter)); + return &found; + } + + ret = gtktree_iter_find_node(child, tofind); + if (ret) + return ret; + + valid = gtk_tree_model_iter_next(model2, child); + } + + return NULL; +} + + +/* + * Update the tree by adding/removing entries + * Does not change other nodes + */ +static void update_tree(struct menu *src, GtkTreeIter * dst) +{ + struct menu *child1; + GtkTreeIter iter, tmp; + GtkTreeIter *child2 = &iter; + gboolean valid; + GtkTreeIter *sibling; + struct symbol *sym; + struct property *prop; + struct menu *menu1, *menu2; + + if (src == &rootmenu) + indent = 1; + + valid = gtk_tree_model_iter_children(model2, child2, dst); + for (child1 = src->list; child1; child1 = child1->next) { + + prop = child1->prompt; + sym = child1->sym; + + reparse: + menu1 = child1; + if (valid) + gtk_tree_model_get(model2, child2, COL_MENU, + &menu2, -1); + else + menu2 = NULL; // force adding of a first child + +#ifdef DEBUG + printf("%*c%s | %s\n", indent, ' ', + menu1 ? menu_get_prompt(menu1) : "nil", + menu2 ? menu_get_prompt(menu2) : "nil"); +#endif + + if (!menu_is_visible(child1) && !show_all) { // remove node + if (gtktree_iter_find_node(dst, menu1) != NULL) { + memcpy(&tmp, child2, sizeof(GtkTreeIter)); + valid = gtk_tree_model_iter_next(model2, + child2); + gtk_tree_store_remove(tree2, &tmp); + if (!valid) + return; // next parent + else + goto reparse; // next child + } else + continue; + } + + if (menu1 != menu2) { + if (gtktree_iter_find_node(dst, menu1) == NULL) { // add node + if (!valid && !menu2) + sibling = NULL; + else + sibling = child2; + gtk_tree_store_insert_before(tree2, + child2, + dst, sibling); + set_node(child2, menu1, fill_row(menu1)); + if (menu2 == NULL) + valid = TRUE; + } else { // remove node + memcpy(&tmp, child2, sizeof(GtkTreeIter)); + valid = gtk_tree_model_iter_next(model2, + child2); + gtk_tree_store_remove(tree2, &tmp); + if (!valid) + return; // next parent + else + goto reparse; // next child + } + } else if (sym && (sym->flags & SYMBOL_CHANGED)) { + set_node(child2, menu1, fill_row(menu1)); + } + + indent++; + update_tree(child1, child2); + indent--; + + valid = gtk_tree_model_iter_next(model2, child2); + } +} + + +/* Display the whole tree (single/split/full view) */ +static void display_tree(struct menu *menu) +{ + struct symbol *sym; + struct property *prop; + struct menu *child; + enum prop_type ptype; + + if (menu == &rootmenu) { + indent = 1; + current = &rootmenu; + } + + for (child = menu->list; child; child = child->next) { + prop = child->prompt; + sym = child->sym; + ptype = prop ? prop->type : P_UNKNOWN; + + if (sym) + sym->flags &= ~SYMBOL_CHANGED; + + if ((view_mode == SPLIT_VIEW) + && !(child->flags & MENU_ROOT) && (tree == tree1)) + continue; + + if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) + && (tree == tree2)) + continue; + + if (menu_is_visible(child) || show_all) + place_node(child, fill_row(child)); +#ifdef DEBUG + printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); + printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : ""); + dbg_print_ptype(ptype); + printf(" | "); + if (sym) { + dbg_print_stype(sym->type); + printf(" | "); + dbg_print_flags(sym->flags); + printf("\n"); + } else + printf("\n"); +#endif + if ((view_mode != FULL_VIEW) && (ptype == P_MENU) + && (tree == tree2)) + continue; +/* + if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) + || (view_mode == FULL_VIEW) + || (view_mode == SPLIT_VIEW))*/ + if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT)) + || (view_mode == FULL_VIEW) + || (view_mode == SPLIT_VIEW)) { + indent++; + display_tree(child); + indent--; + } + } +} + +/* Display a part of the tree starting at current node (single/split view) */ +static void display_tree_part(void) +{ + if (tree2) + gtk_tree_store_clear(tree2); + if (view_mode == SINGLE_VIEW) + display_tree(current); + else if (view_mode == SPLIT_VIEW) + display_tree(browsed); + gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); +} + +/* Display the list in the left frame (split view) */ +static void display_list(void) +{ + if (tree1) + gtk_tree_store_clear(tree1); + + tree = tree1; + display_tree(&rootmenu); + gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w)); + tree = tree2; +} + +void fixup_rootmenu(struct menu *menu) +{ + struct menu *child; + static int menu_cnt = 0; + + menu->flags |= MENU_ROOT; + for (child = menu->list; child; child = child->next) { + if (child->prompt && child->prompt->type == P_MENU) { + menu_cnt++; + fixup_rootmenu(child); + menu_cnt--; + } else if (!menu_cnt) + fixup_rootmenu(child); + } +} + + +/* Main */ +int main(int ac, char *av[]) +{ + const char *name; + char *env; + gchar *glade_file; + +#ifndef LKC_DIRECT_LINK + kconfig_load(); +#endif + + bindtextdomain(PACKAGE, LOCALEDIR); + bind_textdomain_codeset(PACKAGE, "UTF-8"); + textdomain(PACKAGE); + + /* GTK stuffs */ + gtk_set_locale(); + gtk_init(&ac, &av); + glade_init(); + + //add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps"); + //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps"); + + /* Determine GUI path */ + env = getenv(SRCTREE); + if (env) + glade_file = g_strconcat(env, "/scripts/kconfig/gconf.glade", NULL); + else if (av[0][0] == '/') + glade_file = g_strconcat(av[0], ".glade", NULL); + else + glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL); + + /* Load the interface and connect signals */ + init_main_window(glade_file); + init_tree_model(); + init_left_tree(); + init_right_tree(); + + /* Conf stuffs */ + if (ac > 1 && av[1][0] == '-') { + switch (av[1][1]) { + case 'a': + //showAll = 1; + break; + case 'h': + case '?': + printf("%s \n", av[0]); + exit(0); + } + name = av[2]; + } else + name = av[1]; + + conf_parse(name); + fixup_rootmenu(&rootmenu); + conf_read(NULL); + + switch (view_mode) { + case SINGLE_VIEW: + display_tree_part(); + break; + case SPLIT_VIEW: + display_list(); + break; + case FULL_VIEW: + display_tree(&rootmenu); + break; + } + + gtk_main(); + + return 0; +} + +static void conf_changed(void) +{ + bool changed = conf_get_changed(); + gtk_widget_set_sensitive(save_btn, changed); + gtk_widget_set_sensitive(save_menu_item, changed); +} diff --git a/adk/config/gconf.glade b/adk/config/gconf.glade new file mode 100644 index 000000000..b1c86c192 --- /dev/null +++ b/adk/config/gconf.glade @@ -0,0 +1,648 @@ + + + + + + + True + Gtk Kernel Configurator + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + 640 + 480 + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + + + + + + + True + False + 0 + + + + True + + + + True + _File + True + + + + + + + True + Load a config file + _Load + True + + + + + + True + gtk-open + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + Save the config in .config + _Save + True + + + + + + True + gtk-save + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + Save the config in a file + Save _as + True + + + + + True + gtk-save-as + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + + + + + + True + _Quit + True + + + + + + True + gtk-quit + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + + + + + True + _Options + True + + + + + + + True + Show name + Show _name + True + False + + + + + + + True + Show range (Y/M/N) + Show _range + True + False + + + + + + + True + Show value of the option + Show _data + True + False + + + + + + + True + + + + + + True + Show all options + Show all _options + True + False + + + + + + + True + Show masked options + Show _debug info + True + False + + + + + + + + + + + True + _Help + True + + + + + + + True + _Introduction + True + + + + + + True + gtk-dialog-question + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + _About + True + + + + + + True + gtk-properties + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + _License + True + + + + + True + gtk-justify-fill + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + + + + 0 + False + False + + + + + + True + GTK_SHADOW_OUT + GTK_POS_LEFT + GTK_POS_TOP + + + + True + GTK_ORIENTATION_HORIZONTAL + GTK_TOOLBAR_BOTH + True + True + + + + True + Goes up of one level (single view) + Back + True + gtk-undo + True + True + False + + + + False + True + + + + + + True + True + True + False + + + + True + + + + + False + False + + + + + + True + Load a config file + Load + True + gtk-open + True + True + False + + + + False + True + + + + + + True + Save a config file + Save + True + gtk-save + True + True + False + + + + False + True + + + + + + True + True + True + False + + + + True + + + + + False + False + + + + + + True + Single view + Single + True + gtk-missing-image + True + True + False + + + + False + True + + + + + + True + Split view + Split + True + gtk-missing-image + True + True + False + + + + False + True + + + + + + True + Full view + Full + True + gtk-missing-image + True + True + False + + + + False + True + + + + + + True + True + True + False + + + + True + + + + + False + False + + + + + + True + Collapse the whole tree in the right frame + Collapse + True + gtk-remove + True + True + False + + + + False + True + + + + + + True + Expand the whole tree in the right frame + Expand + True + gtk-add + True + True + False + + + + False + True + + + + + + + 0 + False + False + + + + + + 1 + True + True + 0 + + + + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + True + False + False + False + + + + + + + + True + False + + + + + + True + True + 0 + + + + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + True + True + False + False + False + + + + + + + + True + False + + + + + + True + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + False + False + True + GTK_JUSTIFY_LEFT + GTK_WRAP_WORD + True + 0 + 0 + 0 + 0 + 0 + 0 + Sorry, no help available for this option yet. + + + + + True + True + + + + + True + True + + + + + 0 + True + True + + + + + + + diff --git a/adk/config/images.c b/adk/config/images.c new file mode 100644 index 000000000..d4f84bd4a --- /dev/null +++ b/adk/config/images.c @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +static const char *xpm_load[] = { +"22 22 5 1", +". c None", +"# c #000000", +"c c #838100", +"a c #ffff00", +"b c #ffffff", +"......................", +"......................", +"......................", +"............####....#.", +"...........#....##.##.", +"..................###.", +".................####.", +".####...........#####.", +"#abab##########.......", +"#babababababab#.......", +"#ababababababa#.......", +"#babababababab#.......", +"#ababab###############", +"#babab##cccccccccccc##", +"#abab##cccccccccccc##.", +"#bab##cccccccccccc##..", +"#ab##cccccccccccc##...", +"#b##cccccccccccc##....", +"###cccccccccccc##.....", +"##cccccccccccc##......", +"###############.......", +"......................"}; + +static const char *xpm_save[] = { +"22 22 5 1", +". c None", +"# c #000000", +"a c #838100", +"b c #c5c2c5", +"c c #cdb6d5", +"......................", +".####################.", +".#aa#bbbbbbbbbbbb#bb#.", +".#aa#bbbbbbbbbbbb#bb#.", +".#aa#bbbbbbbbbcbb####.", +".#aa#bbbccbbbbbbb#aa#.", +".#aa#bbbccbbbbbbb#aa#.", +".#aa#bbbbbbbbbbbb#aa#.", +".#aa#bbbbbbbbbbbb#aa#.", +".#aa#bbbbbbbbbbbb#aa#.", +".#aa#bbbbbbbbbbbb#aa#.", +".#aaa############aaa#.", +".#aaaaaaaaaaaaaaaaaa#.", +".#aaaaaaaaaaaaaaaaaa#.", +".#aaa#############aa#.", +".#aaa#########bbb#aa#.", +".#aaa#########bbb#aa#.", +".#aaa#########bbb#aa#.", +".#aaa#########bbb#aa#.", +".#aaa#########bbb#aa#.", +"..##################..", +"......................"}; + +static const char *xpm_back[] = { +"22 22 3 1", +". c None", +"# c #000083", +"a c #838183", +"......................", +"......................", +"......................", +"......................", +"......................", +"...........######a....", +"..#......##########...", +"..##...####......##a..", +"..###.###.........##..", +"..######..........##..", +"..#####...........##..", +"..######..........##..", +"..#######.........##..", +"..########.......##a..", +"...............a###...", +"...............###....", +"......................", +"......................", +"......................", +"......................", +"......................", +"......................"}; + +static const char *xpm_tree_view[] = { +"22 22 2 1", +". c None", +"# c #000000", +"......................", +"......................", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......########........", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......########........", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......########........", +"......................", +"......................"}; + +static const char *xpm_single_view[] = { +"22 22 2 1", +". c None", +"# c #000000", +"......................", +"......................", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"......................", +"......................"}; + +static const char *xpm_split_view[] = { +"22 22 2 1", +". c None", +"# c #000000", +"......................", +"......................", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......................", +"......................"}; + +static const char *xpm_symbol_no[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" .......... ", +" "}; + +static const char *xpm_symbol_mod[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . . ", +" . .. . ", +" . .... . ", +" . .... . ", +" . .. . ", +" . . ", +" . . ", +" .......... ", +" "}; + +static const char *xpm_symbol_yes[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . . ", +" . . . ", +" . .. . ", +" . . .. . ", +" . .... . ", +" . .. . ", +" . . ", +" .......... ", +" "}; + +static const char *xpm_choice_no[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .... ", +" .. .. ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" .. .. ", +" .... ", +" "}; + +static const char *xpm_choice_yes[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .... ", +" .. .. ", +" . . ", +" . .. . ", +" . .... . ", +" . .... . ", +" . .. . ", +" . . ", +" .. .. ", +" .... ", +" "}; + +static const char *xpm_menu[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . .. . ", +" . .... . ", +" . ...... . ", +" . ...... . ", +" . .... . ", +" . .. . ", +" . . ", +" .......... ", +" "}; + +static const char *xpm_menu_inv[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" .......... ", +" .. ...... ", +" .. .... ", +" .. .. ", +" .. .. ", +" .. .... ", +" .. ...... ", +" .......... ", +" .......... ", +" "}; + +static const char *xpm_menuback[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . .. . ", +" . .... . ", +" . ...... . ", +" . ...... . ", +" . .... . ", +" . .. . ", +" . . ", +" .......... ", +" "}; + +static const char *xpm_void[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/adk/config/kconfig_load.c b/adk/config/kconfig_load.c new file mode 100644 index 000000000..dbdcaad82 --- /dev/null +++ b/adk/config/kconfig_load.c @@ -0,0 +1,35 @@ +#include +#include +#include + +#include "lkc.h" + +#define P(name,type,arg) type (*name ## _p) arg +#include "lkc_proto.h" +#undef P + +void kconfig_load(void) +{ + void *handle; + char *error; + + handle = dlopen("./libkconfig.so", RTLD_LAZY); + if (!handle) { + handle = dlopen("./scripts/kconfig/libkconfig.so", RTLD_LAZY); + if (!handle) { + fprintf(stderr, "%s\n", dlerror()); + exit(1); + } + } + +#define P(name,type,arg) \ +{ \ + name ## _p = dlsym(handle, #name); \ + if ((error = dlerror())) { \ + fprintf(stderr, "%s\n", error); \ + exit(1); \ + } \ +} +#include "lkc_proto.h" +#undef P +} diff --git a/adk/config/kxgettext.c b/adk/config/kxgettext.c new file mode 100644 index 000000000..8d9ce22b0 --- /dev/null +++ b/adk/config/kxgettext.c @@ -0,0 +1,233 @@ +/* + * Arnaldo Carvalho de Melo , 2005 + * + * Released under the terms of the GNU GPL v2.0 + */ + +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +static char *escape(const char* text, char *bf, int len) +{ + char *bfp = bf; + int multiline = strchr(text, '\n') != NULL; + int eol = 0; + int textlen = strlen(text); + + if ((textlen > 0) && (text[textlen-1] == '\n')) + eol = 1; + + *bfp++ = '"'; + --len; + + if (multiline) { + *bfp++ = '"'; + *bfp++ = '\n'; + *bfp++ = '"'; + len -= 3; + } + + while (*text != '\0' && len > 1) { + if (*text == '"') + *bfp++ = '\\'; + else if (*text == '\n') { + *bfp++ = '\\'; + *bfp++ = 'n'; + *bfp++ = '"'; + *bfp++ = '\n'; + *bfp++ = '"'; + len -= 5; + ++text; + goto next; + } + else if (*text == '\\') { + *bfp++ = '\\'; + len--; + } + *bfp++ = *text++; +next: + --len; + } + + if (multiline && eol) + bfp -= 3; + + *bfp++ = '"'; + *bfp = '\0'; + + return bf; +} + +struct file_line { + struct file_line *next; + char* file; + int lineno; +}; + +static struct file_line *file_line__new(char *file, int lineno) +{ + struct file_line *self = malloc(sizeof(*self)); + + if (self == NULL) + goto out; + + self->file = file; + self->lineno = lineno; + self->next = NULL; +out: + return self; +} + +struct message { + const char *msg; + const char *option; + struct message *next; + struct file_line *files; +}; + +static struct message *message__list; + +static struct message *message__new(const char *msg, char *option, char *file, int lineno) +{ + struct message *self = malloc(sizeof(*self)); + + if (self == NULL) + goto out; + + self->files = file_line__new(file, lineno); + if (self->files == NULL) + goto out_fail; + + self->msg = strdup(msg); + if (self->msg == NULL) + goto out_fail_msg; + + self->option = option; + self->next = NULL; +out: + return self; +out_fail_msg: + free(self->files); +out_fail: + free(self); + self = NULL; + goto out; +} + +static struct message *mesage__find(const char *msg) +{ + struct message *m = message__list; + + while (m != NULL) { + if (strcmp(m->msg, msg) == 0) + break; + m = m->next; + } + + return m; +} + +static int message__add_file_line(struct message *self, char *file, int lineno) +{ + int rc = -1; + struct file_line *fl = file_line__new(file, lineno); + + if (fl == NULL) + goto out; + + fl->next = self->files; + self->files = fl; + rc = 0; +out: + return rc; +} + +static int message__add(const char *msg, char *option, char *file, int lineno) +{ + int rc = 0; + char bf[16384]; + char *escaped = escape(msg, bf, sizeof(bf)); + struct message *m = mesage__find(escaped); + + if (m != NULL) + rc = message__add_file_line(m, file, lineno); + else { + m = message__new(escaped, option, file, lineno); + + if (m != NULL) { + m->next = message__list; + message__list = m; + } else + rc = -1; + } + return rc; +} + +void menu_build_message_list(struct menu *menu) +{ + struct menu *child; + + message__add(menu_get_prompt(menu), NULL, + menu->file == NULL ? "Root Menu" : menu->file->name, + menu->lineno); + + if (menu->sym != NULL && menu_has_help(menu)) + message__add(menu_get_help(menu), menu->sym->name, + menu->file == NULL ? "Root Menu" : menu->file->name, + menu->lineno); + + for (child = menu->list; child != NULL; child = child->next) + if (child->prompt != NULL) + menu_build_message_list(child); +} + +static void message__print_file_lineno(struct message *self) +{ + struct file_line *fl = self->files; + + putchar('\n'); + if (self->option != NULL) + printf("# %s:00000\n", self->option); + + printf("#: %s:%d", fl->file, fl->lineno); + fl = fl->next; + + while (fl != NULL) { + printf(", %s:%d", fl->file, fl->lineno); + fl = fl->next; + } + + putchar('\n'); +} + +static void message__print_gettext_msgid_msgstr(struct message *self) +{ + message__print_file_lineno(self); + + printf("msgid %s\n" + "msgstr \"\"\n", self->msg); +} + +void menu__xgettext(void) +{ + struct message *m = message__list; + + while (m != NULL) { + /* skip empty lines ("") */ + if (strlen(m->msg) > sizeof("\"\"")) + message__print_gettext_msgid_msgstr(m); + m = m->next; + } +} + +int main(int ac, char **av) +{ + conf_parse(av[1]); + + menu_build_message_list(menu_get_root_menu(NULL)); + menu__xgettext(); + return 0; +} diff --git a/adk/config/lex.zconf.c_shipped b/adk/config/lex.zconf.c_shipped new file mode 100644 index 000000000..dc3e81807 --- /dev/null +++ b/adk/config/lex.zconf.c_shipped @@ -0,0 +1,2416 @@ + +#line 3 "scripts/kconfig/lex.zconf.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define yy_create_buffer zconf_create_buffer +#define yy_delete_buffer zconf_delete_buffer +#define yy_flex_debug zconf_flex_debug +#define yy_init_buffer zconf_init_buffer +#define yy_flush_buffer zconf_flush_buffer +#define yy_load_buffer_state zconf_load_buffer_state +#define yy_switch_to_buffer zconf_switch_to_buffer +#define yyin zconfin +#define yyleng zconfleng +#define yylex zconflex +#define yylineno zconflineno +#define yyout zconfout +#define yyrestart zconfrestart +#define yytext zconftext +#define yywrap zconfwrap +#define yyalloc zconfalloc +#define yyrealloc zconfrealloc +#define yyfree zconffree + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE zconfrestart(zconfin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int zconfleng; + +extern FILE *zconfin, *zconfout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up zconftext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up zconftext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via zconfrestart()), so that the user can continue scanning by + * just pointing zconfin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when zconftext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int zconfleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow zconfwrap()'s to do buffer switches + * instead of setting up a fresh zconfin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void zconfrestart (FILE *input_file ); +void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE zconf_create_buffer (FILE *file,int size ); +void zconf_delete_buffer (YY_BUFFER_STATE b ); +void zconf_flush_buffer (YY_BUFFER_STATE b ); +void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer ); +void zconfpop_buffer_state (void ); + +static void zconfensure_buffer_stack (void ); +static void zconf_load_buffer_state (void ); +static void zconf_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER zconf_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE zconf_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE zconf_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE zconf_scan_bytes (yyconst char *bytes,int len ); + +void *zconfalloc (yy_size_t ); +void *zconfrealloc (void *,yy_size_t ); +void zconffree (void * ); + +#define yy_new_buffer zconf_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + zconfensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + zconf_create_buffer(zconfin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + zconfensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + zconf_create_buffer(zconfin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define zconfwrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +FILE *zconfin = (FILE *) 0, *zconfout = (FILE *) 0; + +typedef int yy_state_type; + +extern int zconflineno; + +int zconflineno = 1; + +extern char *zconftext; +#define yytext_ptr zconftext +static yyconst flex_int16_t yy_nxt[][17] = + { + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 + }, + + { + 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12 + }, + + { + 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12 + }, + + { + 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 18, 16, 16, 16 + }, + + { + 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 18, 16, 16, 16 + + }, + + { + 11, 19, 20, 21, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19 + }, + + { + 11, 19, 20, 21, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19 + }, + + { + 11, 22, 22, 23, 22, 24, 22, 22, 24, 22, + 22, 22, 22, 22, 22, 25, 22 + }, + + { + 11, 22, 22, 23, 22, 24, 22, 22, 24, 22, + 22, 22, 22, 22, 22, 25, 22 + }, + + { + 11, 26, 26, 27, 28, 29, 30, 31, 29, 32, + 33, 34, 35, 35, 36, 37, 38 + + }, + + { + 11, 26, 26, 27, 28, 29, 30, 31, 29, 32, + 33, 34, 35, 35, 36, 37, 38 + }, + + { + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11 + }, + + { + 11, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12 + }, + + { + 11, -13, 39, 40, -13, -13, 41, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13 + }, + + { + 11, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14 + + }, + + { + 11, 42, 42, 43, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42 + }, + + { + 11, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16 + }, + + { + 11, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17 + }, + + { + 11, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, 44, -18, -18, -18 + }, + + { + 11, 45, 45, -19, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45 + + }, + + { + 11, -20, 46, 47, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20 + }, + + { + 11, 48, -21, -21, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48 + }, + + { + 11, 49, 49, 50, 49, -22, 49, 49, -22, 49, + 49, 49, 49, 49, 49, -22, 49 + }, + + { + 11, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23 + }, + + { + 11, -24, -24, -24, -24, -24, -24, -24, -24, -24, + -24, -24, -24, -24, -24, -24, -24 + + }, + + { + 11, 51, 51, 52, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51 + }, + + { + 11, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26 + }, + + { + 11, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27 + }, + + { + 11, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, 53, -28, -28 + }, + + { + 11, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29 + + }, + + { + 11, 54, 54, -30, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54 + }, + + { + 11, -31, -31, -31, -31, -31, -31, 55, -31, -31, + -31, -31, -31, -31, -31, -31, -31 + }, + + { + 11, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32 + }, + + { + 11, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33 + }, + + { + 11, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, 56, 57, 57, -34, -34, -34 + + }, + + { + 11, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, 57, 57, 57, -35, -35, -35 + }, + + { + 11, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36 + }, + + { + 11, -37, -37, 58, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37 + }, + + { + 11, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, 59 + }, + + { + 11, -39, 39, 40, -39, -39, 41, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39 + + }, + + { + 11, -40, -40, -40, -40, -40, -40, -40, -40, -40, + -40, -40, -40, -40, -40, -40, -40 + }, + + { + 11, 42, 42, 43, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42 + }, + + { + 11, 42, 42, 43, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42 + }, + + { + 11, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43 + }, + + { + 11, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, 44, -44, -44, -44 + + }, + + { + 11, 45, 45, -45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45 + }, + + { + 11, -46, 46, 47, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46 + }, + + { + 11, 48, -47, -47, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48 + }, + + { + 11, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48 + }, + + { + 11, 49, 49, 50, 49, -49, 49, 49, -49, 49, + 49, 49, 49, 49, 49, -49, 49 + + }, + + { + 11, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50 + }, + + { + 11, -51, -51, 52, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51 + }, + + { + 11, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52 + }, + + { + 11, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53 + }, + + { + 11, 54, 54, -54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54 + + }, + + { + 11, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55 + }, + + { + 11, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, 60, 57, 57, -56, -56, -56 + }, + + { + 11, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, 57, 57, 57, -57, -57, -57 + }, + + { + 11, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58 + }, + + { + 11, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59 + + }, + + { + 11, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, 57, 57, 57, -60, -60, -60 + }, + + } ; + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up zconftext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + zconfleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 33 +#define YY_END_OF_BUFFER 34 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[61] = + { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 34, 5, 4, 2, 3, 7, 8, 6, 32, 29, + 31, 24, 28, 27, 26, 22, 17, 13, 16, 20, + 22, 11, 12, 19, 19, 14, 22, 22, 4, 2, + 3, 3, 1, 6, 32, 29, 31, 30, 24, 23, + 26, 25, 15, 20, 9, 19, 19, 21, 10, 18 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 6, 1, 1, 7, 8, 9, + 10, 1, 1, 1, 11, 12, 12, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, + 14, 1, 1, 1, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 1, 15, 1, 1, 13, 1, 13, 13, 13, 13, + + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 1, 16, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +extern int zconf_flex_debug; +int zconf_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *zconftext; +#define YY_NO_INPUT 1 + +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +#define START_STRSIZE 16 + +static struct { + struct file *file; + int lineno; +} current_pos; + +static char *text; +static int text_size, text_asize; + +struct buffer { + struct buffer *parent; + YY_BUFFER_STATE state; +}; + +struct buffer *current_buf; + +static int last_ts, first_ts; + +static void zconf_endhelp(void); +static void zconf_endfile(void); + +void new_string(void) +{ + text = malloc(START_STRSIZE); + text_asize = START_STRSIZE; + text_size = 0; + *text = 0; +} + +void append_string(const char *str, int size) +{ + int new_size = text_size + size + 1; + if (new_size > text_asize) { + new_size += START_STRSIZE - 1; + new_size &= -START_STRSIZE; + text = realloc(text, new_size); + text_asize = new_size; + } + memcpy(text + text_size, str, size); + text_size += size; + text[text_size] = 0; +} + +void alloc_string(const char *str, int size) +{ + text = malloc(size + 1); + memcpy(text, str, size); + text[size] = 0; +} + +#define INITIAL 0 +#define COMMAND 1 +#define HELP 2 +#define STRING 3 +#define PARAM 4 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int zconflex_destroy (void ); + +int zconfget_debug (void ); + +void zconfset_debug (int debug_flag ); + +YY_EXTRA_TYPE zconfget_extra (void ); + +void zconfset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *zconfget_in (void ); + +void zconfset_in (FILE * in_str ); + +FILE *zconfget_out (void ); + +void zconfset_out (FILE * out_str ); + +int zconfget_leng (void ); + +char *zconfget_text (void ); + +int zconfget_lineno (void ); + +void zconfset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int zconfwrap (void ); +#else +extern int zconfwrap (void ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO fwrite( zconftext, zconfleng, 1, zconfout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + errno=0; \ + while ( (result = read( fileno(zconfin), (char *) buf, max_size )) < 0 ) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(zconfin); \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int zconflex (void); + +#define YY_DECL int zconflex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after zconftext and zconfleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + + int str = 0; + int ts, i; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! zconfin ) + zconfin = stdin; + + if ( ! zconfout ) + zconfout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + zconfensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + zconf_create_buffer(zconfin,YY_BUF_SIZE ); + } + + zconf_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of zconftext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + while ( (yy_current_state = yy_nxt[yy_current_state][ yy_ec[YY_SC_TO_UI(*yy_cp)] ]) > 0 ) + ++yy_cp; + + yy_current_state = -yy_current_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ +case 1: +/* rule 1 can match eol */ +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +{ + current_file->lineno++; + return T_EOL; +} + YY_BREAK +case 3: +YY_RULE_SETUP + + YY_BREAK +case 4: +YY_RULE_SETUP +{ + BEGIN(COMMAND); +} + YY_BREAK +case 5: +YY_RULE_SETUP +{ + unput(zconftext[0]); + BEGIN(COMMAND); +} + YY_BREAK + +case 6: +YY_RULE_SETUP +{ + struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng); + BEGIN(PARAM); + current_pos.file = current_file; + current_pos.lineno = current_file->lineno; + if (id && id->flags & TF_COMMAND) { + zconflval.id = id; + return id->token; + } + alloc_string(zconftext, zconfleng); + zconflval.string = text; + return T_WORD; + } + YY_BREAK +case 7: +YY_RULE_SETUP + + YY_BREAK +case 8: +/* rule 8 can match eol */ +YY_RULE_SETUP +{ + BEGIN(INITIAL); + current_file->lineno++; + return T_EOL; + } + YY_BREAK + +case 9: +YY_RULE_SETUP +return T_AND; + YY_BREAK +case 10: +YY_RULE_SETUP +return T_OR; + YY_BREAK +case 11: +YY_RULE_SETUP +return T_OPEN_PAREN; + YY_BREAK +case 12: +YY_RULE_SETUP +return T_CLOSE_PAREN; + YY_BREAK +case 13: +YY_RULE_SETUP +return T_NOT; + YY_BREAK +case 14: +YY_RULE_SETUP +return T_EQUAL; + YY_BREAK +case 15: +YY_RULE_SETUP +return T_UNEQUAL; + YY_BREAK +case 16: +YY_RULE_SETUP +{ + str = zconftext[0]; + new_string(); + BEGIN(STRING); + } + YY_BREAK +case 17: +/* rule 17 can match eol */ +YY_RULE_SETUP +BEGIN(INITIAL); current_file->lineno++; return T_EOL; + YY_BREAK +case 18: +YY_RULE_SETUP +/* ignore */ + YY_BREAK +case 19: +YY_RULE_SETUP +{ + struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng); + if (id && id->flags & TF_PARAM) { + zconflval.id = id; + return id->token; + } + alloc_string(zconftext, zconfleng); + zconflval.string = text; + return T_WORD; + } + YY_BREAK +case 20: +YY_RULE_SETUP +/* comment */ + YY_BREAK +case 21: +/* rule 21 can match eol */ +YY_RULE_SETUP +current_file->lineno++; + YY_BREAK +case 22: +YY_RULE_SETUP + + YY_BREAK +case YY_STATE_EOF(PARAM): +{ + BEGIN(INITIAL); + } + YY_BREAK + +case 23: +/* rule 23 can match eol */ +*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ +(yy_c_buf_p) = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up zconftext again */ +YY_RULE_SETUP +{ + append_string(zconftext, zconfleng); + zconflval.string = text; + return T_WORD_QUOTE; + } + YY_BREAK +case 24: +YY_RULE_SETUP +{ + append_string(zconftext, zconfleng); + } + YY_BREAK +case 25: +/* rule 25 can match eol */ +*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ +(yy_c_buf_p) = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up zconftext again */ +YY_RULE_SETUP +{ + append_string(zconftext + 1, zconfleng - 1); + zconflval.string = text; + return T_WORD_QUOTE; + } + YY_BREAK +case 26: +YY_RULE_SETUP +{ + append_string(zconftext + 1, zconfleng - 1); + } + YY_BREAK +case 27: +YY_RULE_SETUP +{ + if (str == zconftext[0]) { + BEGIN(PARAM); + zconflval.string = text; + return T_WORD_QUOTE; + } else + append_string(zconftext, 1); + } + YY_BREAK +case 28: +/* rule 28 can match eol */ +YY_RULE_SETUP +{ + printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); + current_file->lineno++; + BEGIN(INITIAL); + return T_EOL; + } + YY_BREAK +case YY_STATE_EOF(STRING): +{ + BEGIN(INITIAL); + } + YY_BREAK + +case 29: +YY_RULE_SETUP +{ + ts = 0; + for (i = 0; i < zconfleng; i++) { + if (zconftext[i] == '\t') + ts = (ts & ~7) + 8; + else + ts++; + } + last_ts = ts; + if (first_ts) { + if (ts < first_ts) { + zconf_endhelp(); + return T_HELPTEXT; + } + ts -= first_ts; + while (ts > 8) { + append_string(" ", 8); + ts -= 8; + } + append_string(" ", ts); + } + } + YY_BREAK +case 30: +/* rule 30 can match eol */ +*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ +(yy_c_buf_p) = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up zconftext again */ +YY_RULE_SETUP +{ + current_file->lineno++; + zconf_endhelp(); + return T_HELPTEXT; + } + YY_BREAK +case 31: +/* rule 31 can match eol */ +YY_RULE_SETUP +{ + current_file->lineno++; + append_string("\n", 1); + } + YY_BREAK +case 32: +YY_RULE_SETUP +{ + while (zconfleng) { + if ((zconftext[zconfleng-1] != ' ') && (zconftext[zconfleng-1] != '\t')) + break; + zconfleng--; + } + append_string(zconftext, zconfleng); + if (!first_ts) + first_ts = last_ts; + } + YY_BREAK +case YY_STATE_EOF(HELP): +{ + zconf_endhelp(); + return T_HELPTEXT; + } + YY_BREAK + +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(COMMAND): +{ + if (current_file) { + zconf_endfile(); + return T_EOL; + } + fclose(zconfin); + yyterminate(); +} + YY_BREAK +case 33: +YY_RULE_SETUP +YY_FATAL_ERROR( "flex scanner jammed" ); + YY_BREAK + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed zconfin at a new source and called + * zconflex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = zconfin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( zconfwrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * zconftext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of zconflex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + zconfrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + zconfrestart(zconfin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) zconfrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + + yy_current_state = yy_nxt[yy_current_state][1]; + yy_is_jam = (yy_current_state <= 0); + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up zconftext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + zconfrestart(zconfin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( zconfwrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve zconftext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void zconfrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + zconfensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + zconf_create_buffer(zconfin,YY_BUF_SIZE ); + } + + zconf_init_buffer(YY_CURRENT_BUFFER,input_file ); + zconf_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * zconfpop_buffer_state(); + * zconfpush_buffer_state(new_buffer); + */ + zconfensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + zconf_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (zconfwrap()) processing, but the only time this flag + * is looked at is after zconfwrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void zconf_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + zconfin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE zconf_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) zconfalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + zconf_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with zconf_create_buffer() + * + */ + void zconf_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + zconffree((void *) b->yy_ch_buf ); + + zconffree((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a zconfrestart() or at EOF. + */ + static void zconf_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + zconf_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then zconf_init_buffer was _probably_ + * called from zconfrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void zconf_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + zconf_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + zconfensure_buffer_stack(); + + /* This block is copied from zconf_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from zconf_switch_to_buffer. */ + zconf_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void zconfpop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + zconf_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + zconf_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void zconfensure_buffer_stack (void) +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)zconfalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in zconfensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)zconfrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in zconfensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + zconf_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to zconflex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * zconf_scan_bytes() instead. + */ +YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr ) +{ + + return zconf_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE zconf_scan_bytes (yyconst char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) zconfalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = zconf_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in zconf_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up zconftext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + zconftext[zconfleng] = (yy_hold_char); \ + (yy_c_buf_p) = zconftext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + zconfleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int zconfget_lineno (void) +{ + + return zconflineno; +} + +/** Get the input stream. + * + */ +FILE *zconfget_in (void) +{ + return zconfin; +} + +/** Get the output stream. + * + */ +FILE *zconfget_out (void) +{ + return zconfout; +} + +/** Get the length of the current token. + * + */ +int zconfget_leng (void) +{ + return zconfleng; +} + +/** Get the current token. + * + */ + +char *zconfget_text (void) +{ + return zconftext; +} + +/** Set the current line number. + * @param line_number + * + */ +void zconfset_lineno (int line_number ) +{ + + zconflineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see zconf_switch_to_buffer + */ +void zconfset_in (FILE * in_str ) +{ + zconfin = in_str ; +} + +void zconfset_out (FILE * out_str ) +{ + zconfout = out_str ; +} + +int zconfget_debug (void) +{ + return zconf_flex_debug; +} + +void zconfset_debug (int bdebug ) +{ + zconf_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from zconflex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + zconfin = stdin; + zconfout = stdout; +#else + zconfin = (FILE *) 0; + zconfout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * zconflex_init() + */ + return 0; +} + +/* zconflex_destroy is for both reentrant and non-reentrant scanners. */ +int zconflex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + zconf_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + zconfpop_buffer_state(); + } + + /* Destroy the stack itself. */ + zconffree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * zconflex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *zconfalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *zconfrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void zconffree (void * ptr ) +{ + free( (char *) ptr ); /* see zconfrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +void zconf_starthelp(void) +{ + new_string(); + last_ts = first_ts = 0; + BEGIN(HELP); +} + +static void zconf_endhelp(void) +{ + zconflval.string = text; + BEGIN(INITIAL); +} + +/* + * Try to open specified file with following names: + * ./name + * $(srctree)/name + * The latter is used when srctree is separate from objtree + * when compiling the kernel. + * Return NULL if file is not found. + */ +FILE *zconf_fopen(const char *name) +{ + char *env, fullname[PATH_MAX+1]; + FILE *f; + + f = fopen(name, "r"); + if (!f && name != NULL && name[0] != '/') { + env = getenv(SRCTREE); + if (env) { + sprintf(fullname, "%s/%s", env, name); + f = fopen(fullname, "r"); + } + } + return f; +} + +void zconf_initscan(const char *name) +{ + zconfin = zconf_fopen(name); + if (!zconfin) { + printf("can't find file %s\n", name); + exit(1); + } + + current_buf = malloc(sizeof(*current_buf)); + memset(current_buf, 0, sizeof(*current_buf)); + + current_file = file_lookup(name); + current_file->lineno = 1; + current_file->flags = FILE_BUSY; +} + +void zconf_nextfile(const char *name) +{ + struct file *file = file_lookup(name); + struct buffer *buf = malloc(sizeof(*buf)); + memset(buf, 0, sizeof(*buf)); + + current_buf->state = YY_CURRENT_BUFFER; + zconfin = zconf_fopen(name); + if (!zconfin) { + printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); + exit(1); + } + zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE)); + buf->parent = current_buf; + current_buf = buf; + + if (file->flags & FILE_BUSY) { + printf("%s:%d: do not source '%s' from itself\n", + zconf_curname(), zconf_lineno(), name); + exit(1); + } + if (file->flags & FILE_SCANNED) { + printf("%s:%d: file '%s' is already sourced from '%s'\n", + zconf_curname(), zconf_lineno(), name, + file->parent->name); + exit(1); + } + file->flags |= FILE_BUSY; + file->lineno = 1; + file->parent = current_file; + current_file = file; +} + +static void zconf_endfile(void) +{ + struct buffer *parent; + + current_file->flags |= FILE_SCANNED; + current_file->flags &= ~FILE_BUSY; + current_file = current_file->parent; + + parent = current_buf->parent; + if (parent) { + fclose(zconfin); + zconf_delete_buffer(YY_CURRENT_BUFFER); + zconf_switch_to_buffer(parent->state); + } + free(current_buf); + current_buf = parent; +} + +int zconf_lineno(void) +{ + return current_pos.lineno; +} + +char *zconf_curname(void) +{ + return current_pos.file ? current_pos.file->name : ""; +} + diff --git a/adk/config/lkc.h b/adk/config/lkc.h new file mode 100644 index 000000000..f379b0bf8 --- /dev/null +++ b/adk/config/lkc.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#ifndef LKC_H +#define LKC_H + +#include "expr.h" + +#ifndef KBUILD_NO_NLS +# include +#else +static inline const char *gettext(const char *txt) { return txt; } +static inline void textdomain(const char *domainname) {} +static inline void bindtextdomain(const char *name, const char *dir) {} +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef LKC_DIRECT_LINK +#define P(name,type,arg) extern type name arg +#else +#include "lkc_defs.h" +#define P(name,type,arg) extern type (*name ## _p) arg +#endif +#include "lkc_proto.h" +#undef P + +#define SRCTREE "srctree" + +#define PACKAGE "linux" +#define LOCALEDIR "/usr/share/locale" + +#define _(text) gettext(text) +#define N_(text) (text) + + +#define TF_COMMAND 0x0001 +#define TF_PARAM 0x0002 +#define TF_OPTION 0x0004 + +enum conf_def_mode { + def_default, + def_yes, + def_mod, + def_no, + def_random +}; + +#define T_OPT_MODULES 1 +#define T_OPT_DEFCONFIG_LIST 2 +#define T_OPT_ENV 3 + +struct kconf_id { + int name; + int token; + unsigned int flags; + enum symbol_type stype; +}; + +int zconfparse(void); +void zconfdump(FILE *out); + +extern int zconfdebug; +void zconf_starthelp(void); +FILE *zconf_fopen(const char *name); +void zconf_initscan(const char *name); +void zconf_nextfile(const char *name); +int zconf_lineno(void); +char *zconf_curname(void); + +/* confdata.c */ +const char *conf_get_configname(void); +const char *conf_get_autoconfig_name(void); +char *conf_get_default_confname(void); +void sym_set_change_count(int count); +void sym_add_change_count(int count); +void conf_set_all_new_symbols(enum conf_def_mode mode); + +/* kconfig_load.c */ +void kconfig_load(void); + +/* menu.c */ +void menu_init(void); +void menu_warn(struct menu *menu, const char *fmt, ...); +struct menu *menu_add_menu(void); +void menu_end_menu(void); +void menu_add_entry(struct symbol *sym); +void menu_end_entry(void); +void menu_add_dep(struct expr *dep); +struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep); +struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); +void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); +void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); +void menu_add_option(int token, char *arg); +void menu_finalize(struct menu *parent); +void menu_set_type(int type); + +/* util.c */ +struct file *file_lookup(const char *name); +int file_write_dep(const char *name); + +struct gstr { + size_t len; + char *s; +}; +struct gstr str_new(void); +struct gstr str_assign(const char *s); +void str_free(struct gstr *gs); +void str_append(struct gstr *gs, const char *s); +void str_printf(struct gstr *gs, const char *fmt, ...); +const char *str_get(struct gstr *gs); + +/* symbol.c */ +extern struct expr *sym_env_list; + +void sym_init(void); +void sym_clear_all_valid(void); +void sym_set_all_changed(void); +void sym_set_changed(struct symbol *sym); +struct symbol *sym_check_deps(struct symbol *sym); +struct property *prop_alloc(enum prop_type type, struct symbol *sym); +struct symbol *prop_get_symbol(struct property *prop); +struct property *sym_get_env_prop(struct symbol *sym); + +static inline tristate sym_get_tristate_value(struct symbol *sym) +{ + return sym->curr.tri; +} + + +static inline struct symbol *sym_get_choice_value(struct symbol *sym) +{ + return (struct symbol *)sym->curr.val; +} + +static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval) +{ + return sym_set_tristate_value(chval, yes); +} + +static inline bool sym_is_choice(struct symbol *sym) +{ + return sym->flags & SYMBOL_CHOICE ? true : false; +} + +static inline bool sym_is_choice_value(struct symbol *sym) +{ + return sym->flags & SYMBOL_CHOICEVAL ? true : false; +} + +static inline bool sym_is_optional(struct symbol *sym) +{ + return sym->flags & SYMBOL_OPTIONAL ? true : false; +} + +static inline bool sym_has_value(struct symbol *sym) +{ + return sym->flags & SYMBOL_DEF_USER ? true : false; +} + +#ifdef __cplusplus +} +#endif + +#endif /* LKC_H */ diff --git a/adk/config/lkc_proto.h b/adk/config/lkc_proto.h new file mode 100644 index 000000000..8e6946131 --- /dev/null +++ b/adk/config/lkc_proto.h @@ -0,0 +1,45 @@ + +/* confdata.c */ +P(conf_parse,void,(const char *name)); +P(conf_read,int,(const char *name)); +P(conf_read_simple,int,(const char *name, int)); +P(conf_write,int,(const char *name)); +P(conf_write_autoconf,int,(void)); +P(conf_get_changed,bool,(void)); +P(conf_set_changed_callback, void,(void (*fn)(void))); + +/* menu.c */ +P(rootmenu,struct menu,); + +P(menu_is_visible,bool,(struct menu *menu)); +P(menu_get_prompt,const char *,(struct menu *menu)); +P(menu_get_root_menu,struct menu *,(struct menu *menu)); +P(menu_get_parent_menu,struct menu *,(struct menu *menu)); +P(menu_has_help,bool,(struct menu *menu)); +P(menu_get_help,const char *,(struct menu *menu)); + +/* symbol.c */ +P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); + +P(sym_lookup,struct symbol *,(const char *name, int flags)); +P(sym_find,struct symbol *,(const char *name)); +P(sym_re_search,struct symbol **,(const char *pattern)); +P(sym_type_name,const char *,(enum symbol_type type)); +P(sym_calc_value,void,(struct symbol *sym)); +P(sym_get_type,enum symbol_type,(struct symbol *sym)); +P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); +P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri)); +P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); +P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); +P(sym_string_within_range,bool,(struct symbol *sym, const char *str)); +P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); +P(sym_is_changable,bool,(struct symbol *sym)); +P(sym_get_choice_prop,struct property *,(struct symbol *sym)); +P(sym_get_default_prop,struct property *,(struct symbol *sym)); +P(sym_get_string_value,const char *,(struct symbol *sym)); + +P(prop_get_type_name,const char *,(enum prop_type type)); + +/* expr.c */ +P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); +P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)); diff --git a/adk/config/lxdialog/.gitignore b/adk/config/lxdialog/.gitignore new file mode 100644 index 000000000..90b08ff02 --- /dev/null +++ b/adk/config/lxdialog/.gitignore @@ -0,0 +1,4 @@ +# +# Generated files +# +lxdialog diff --git a/adk/config/lxdialog/BIG.FAT.WARNING b/adk/config/lxdialog/BIG.FAT.WARNING new file mode 100644 index 000000000..a8999d82b --- /dev/null +++ b/adk/config/lxdialog/BIG.FAT.WARNING @@ -0,0 +1,4 @@ +This is NOT the official version of dialog. This version has been +significantly modified from the original. It is for use by the Linux +kernel configuration script. Please do not bother Savio Lam with +questions about this program. diff --git a/adk/config/lxdialog/check-lxdialog.sh b/adk/config/lxdialog/check-lxdialog.sh new file mode 100644 index 000000000..fcef0f59d --- /dev/null +++ b/adk/config/lxdialog/check-lxdialog.sh @@ -0,0 +1,82 @@ +#!/bin/sh +# Check ncurses compatibility + +# What library to link +ldflags() +{ + for ext in so a dylib ; do + for lib in ncursesw ncurses curses ; do + $cc -print-file-name=lib${lib}.${ext} | grep -q / + if [ $? -eq 0 ]; then + echo "-l${lib}" + exit + fi + done + done + exit 1 +} + +# Where is ncurses.h? +ccflags() +{ + if [ -f /usr/include/ncurses/ncurses.h ]; then + echo '-I/usr/include/ncurses -DCURSES_LOC=""' + elif [ -f /usr/include/ncurses/curses.h ]; then + echo '-I/usr/include/ncurses -DCURSES_LOC=""' + elif [ -f /usr/include/ncurses.h ]; then + echo '-DCURSES_LOC=""' + else + echo '-DCURSES_LOC=""' + fi +} + +# Temp file, try to clean up after us +tmp=.lxdialog.tmp +trap "rm -f $tmp" 0 1 2 3 15 + +# Check if we can link to ncurses +check() { + $cc -xc - -o $tmp 2>/dev/null <<'EOF' +#include CURSES_LOC +main() {} +EOF + if [ $? != 0 ]; then + echo " *** Unable to find the ncurses libraries or the" 1>&2 + echo " *** required header files." 1>&2 + echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2 + echo " *** " 1>&2 + echo " *** Install ncurses (ncurses-devel) and try again." 1>&2 + echo " *** " 1>&2 + exit 1 + fi +} + +usage() { + printf "Usage: $0 [-check compiler options|-ccflags|-ldflags compiler options]\n" +} + +if [ $# -eq 0 ]; then + usage + exit 1 +fi + +cc="" +case "$1" in + "-check") + shift + cc="$@" + check + ;; + "-ccflags") + ccflags + ;; + "-ldflags") + shift + cc="$@" + ldflags + ;; + "*") + usage + exit 1 + ;; +esac diff --git a/adk/config/lxdialog/checklist.c b/adk/config/lxdialog/checklist.c new file mode 100644 index 000000000..bcc6f19c3 --- /dev/null +++ b/adk/config/lxdialog/checklist.c @@ -0,0 +1,326 @@ +/* + * checklist.c -- implements the checklist box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension + * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +static int list_width, check_x, item_x; + +/* + * Print list item + */ +static void print_item(WINDOW * win, int choice, int selected) +{ + int i; + + /* Clear 'residue' of last item */ + wattrset(win, dlg.menubox.atr); + wmove(win, choice, 0); + for (i = 0; i < list_width; i++) + waddch(win, ' '); + + wmove(win, choice, check_x); + wattrset(win, selected ? dlg.check_selected.atr + : dlg.check.atr); + if (!item_is_tag(':')) + wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); + + wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); + mvwaddch(win, choice, item_x, item_str()[0]); + wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); + waddstr(win, (char *)item_str() + 1); + if (selected) { + wmove(win, choice, check_x + 1); + wrefresh(win); + } +} + +/* + * Print the scroll indicators. + */ +static void print_arrows(WINDOW * win, int choice, int item_no, int scroll, + int y, int x, int height) +{ + wmove(win, y, x); + + if (scroll > 0) { + wattrset(win, dlg.uarrow.atr); + waddch(win, ACS_UARROW); + waddstr(win, "(-)"); + } else { + wattrset(win, dlg.menubox.atr); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + } + + y = y + height + 1; + wmove(win, y, x); + + if ((height < item_no) && (scroll + choice < item_no - 1)) { + wattrset(win, dlg.darrow.atr); + waddch(win, ACS_DARROW); + waddstr(win, "(+)"); + } else { + wattrset(win, dlg.menubox_border.atr); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + } +} + +/* + * Display the termination buttons + */ +static void print_buttons(WINDOW * dialog, int height, int width, int selected) +{ + int x = width / 2 - 11; + int y = height - 2; + + print_button(dialog, gettext("Select"), y, x, selected == 0); + print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); + + wmove(dialog, y, x + 1 + 14 * selected); + wrefresh(dialog); +} + +/* + * Display a dialog box with a list of options that can be turned on or off + * in the style of radiolist (only one option turned on at a time). + */ +int dialog_checklist(const char *title, const char *prompt, int height, + int width, int list_height) +{ + int i, x, y, box_x, box_y; + int key = 0, button = 0, choice = 0, scroll = 0, max_choice; + WINDOW *dialog, *list; + + /* which item to highlight */ + item_foreach() { + if (item_is_tag('X')) + choice = item_n(); + if (item_is_selected()) { + choice = item_n(); + break; + } + } + +do_resize: + if (getmaxy(stdscr) < (height + 6)) + return -ERRDISPLAYTOOSMALL; + if (getmaxx(stdscr) < (width + 6)) + return -ERRDISPLAYTOOSMALL; + + max_choice = MIN(list_height, item_count()); + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + + dialog = newwin(height, width, y, x); + keypad(dialog, TRUE); + + draw_box(dialog, 0, 0, height, width, + dlg.dialog.atr, dlg.border.atr); + wattrset(dialog, dlg.border.atr); + mvwaddch(dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch(dialog, ACS_HLINE); + wattrset(dialog, dlg.dialog.atr); + waddch(dialog, ACS_RTEE); + + print_title(dialog, title, width); + + wattrset(dialog, dlg.dialog.atr); + print_autowrap(dialog, prompt, width - 2, 1, 3); + + list_width = width - 6; + box_y = height - list_height - 5; + box_x = (width - list_width) / 2 - 1; + + /* create new window for the list */ + list = subwin(dialog, list_height, list_width, y + box_y + 1, + x + box_x + 1); + + keypad(list, TRUE); + + /* draw a box around the list items */ + draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, + dlg.menubox_border.atr, dlg.menubox.atr); + + /* Find length of longest item in order to center checklist */ + check_x = 0; + item_foreach() + check_x = MAX(check_x, strlen(item_str()) + 4); + + check_x = (list_width - check_x) / 2; + item_x = check_x + 4; + + if (choice >= list_height) { + scroll = choice - list_height + 1; + choice -= scroll; + } + + /* Print the list */ + for (i = 0; i < max_choice; i++) { + item_set(scroll + i); + print_item(list, i, i == choice); + } + + print_arrows(dialog, choice, item_count(), scroll, + box_y, box_x + check_x + 5, list_height); + + print_buttons(dialog, height, width, 0); + + wnoutrefresh(dialog); + wnoutrefresh(list); + doupdate(); + + while (key != KEY_ESC) { + key = wgetch(dialog); + + for (i = 0; i < max_choice; i++) { + item_set(i + scroll); + if (toupper(key) == toupper(item_str()[0])) + break; + } + + if (i < max_choice || key == KEY_UP || key == KEY_DOWN || + key == '+' || key == '-') { + if (key == KEY_UP || key == '-') { + if (!choice) { + if (!scroll) + continue; + /* Scroll list down */ + if (list_height > 1) { + /* De-highlight current first item */ + item_set(scroll); + print_item(list, 0, FALSE); + scrollok(list, TRUE); + wscrl(list, -1); + scrollok(list, FALSE); + } + scroll--; + item_set(scroll); + print_item(list, 0, TRUE); + print_arrows(dialog, choice, item_count(), + scroll, box_y, box_x + check_x + 5, list_height); + + wnoutrefresh(dialog); + wrefresh(list); + + continue; /* wait for another key press */ + } else + i = choice - 1; + } else if (key == KEY_DOWN || key == '+') { + if (choice == max_choice - 1) { + if (scroll + choice >= item_count() - 1) + continue; + /* Scroll list up */ + if (list_height > 1) { + /* De-highlight current last item before scrolling up */ + item_set(scroll + max_choice - 1); + print_item(list, + max_choice - 1, + FALSE); + scrollok(list, TRUE); + wscrl(list, 1); + scrollok(list, FALSE); + } + scroll++; + item_set(scroll + max_choice - 1); + print_item(list, max_choice - 1, TRUE); + + print_arrows(dialog, choice, item_count(), + scroll, box_y, box_x + check_x + 5, list_height); + + wnoutrefresh(dialog); + wrefresh(list); + + continue; /* wait for another key press */ + } else + i = choice + 1; + } + if (i != choice) { + /* De-highlight current item */ + item_set(scroll + choice); + print_item(list, choice, FALSE); + /* Highlight new item */ + choice = i; + item_set(scroll + choice); + print_item(list, choice, TRUE); + wnoutrefresh(dialog); + wrefresh(list); + } + continue; /* wait for another key press */ + } + switch (key) { + case 'H': + case 'h': + case '?': + button = 1; + /* fall-through */ + case 'S': + case 's': + case ' ': + case '\n': + item_foreach() + item_set_selected(0); + item_set(scroll + choice); + item_set_selected(1); + delwin(list); + delwin(dialog); + return button; + case TAB: + case KEY_LEFT: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) + ? 1 : (button > 1 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh(dialog); + break; + case 'X': + case 'x': + key = KEY_ESC; + break; + case KEY_ESC: + key = on_key_esc(dialog); + break; + case KEY_RESIZE: + delwin(list); + delwin(dialog); + on_key_resize(); + goto do_resize; + } + + /* Now, update everything... */ + doupdate(); + } + delwin(list); + delwin(dialog); + return key; /* ESC pressed */ +} diff --git a/adk/config/lxdialog/dialog.h b/adk/config/lxdialog/dialog.h new file mode 100644 index 000000000..b5211fce0 --- /dev/null +++ b/adk/config/lxdialog/dialog.h @@ -0,0 +1,230 @@ +/* + * dialog.h -- common declarations for all dialog modules + * + * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef KBUILD_NO_NLS +# include +#else +# define gettext(Msgid) ((const char *) (Msgid)) +#endif + +#ifdef __sun__ +#define CURS_MACROS +#endif +#include CURSES_LOC + +/* + * Colors in ncurses 1.9.9e do not work properly since foreground and + * background colors are OR'd rather than separately masked. This version + * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible + * with standard curses. The simplest fix (to make this work with standard + * curses) uses the wbkgdset() function, not used in the original hack. + * Turn it off if we're building with 1.9.9e, since it just confuses things. + */ +#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE) +#define OLD_NCURSES 1 +#undef wbkgdset +#define wbkgdset(w,p) /*nothing */ +#else +#define OLD_NCURSES 0 +#endif + +#define TR(params) _tracef params + +#define KEY_ESC 27 +#define TAB 9 +#define MAX_LEN 2048 +#define BUF_SIZE (10*1024) +#define MIN(x,y) (x < y ? x : y) +#define MAX(x,y) (x > y ? x : y) + +#ifndef ACS_ULCORNER +#define ACS_ULCORNER '+' +#endif +#ifndef ACS_LLCORNER +#define ACS_LLCORNER '+' +#endif +#ifndef ACS_URCORNER +#define ACS_URCORNER '+' +#endif +#ifndef ACS_LRCORNER +#define ACS_LRCORNER '+' +#endif +#ifndef ACS_HLINE +#define ACS_HLINE '-' +#endif +#ifndef ACS_VLINE +#define ACS_VLINE '|' +#endif +#ifndef ACS_LTEE +#define ACS_LTEE '+' +#endif +#ifndef ACS_RTEE +#define ACS_RTEE '+' +#endif +#ifndef ACS_UARROW +#define ACS_UARROW '^' +#endif +#ifndef ACS_DARROW +#define ACS_DARROW 'v' +#endif + +/* error return codes */ +#define ERRDISPLAYTOOSMALL (KEY_MAX + 1) + +/* + * Color definitions + */ +struct dialog_color { + chtype atr; /* Color attribute */ + int fg; /* foreground */ + int bg; /* background */ + int hl; /* highlight this item */ +}; + +struct dialog_info { + const char *backtitle; + struct dialog_color screen; + struct dialog_color shadow; + struct dialog_color dialog; + struct dialog_color title; + struct dialog_color border; + struct dialog_color button_active; + struct dialog_color button_inactive; + struct dialog_color button_key_active; + struct dialog_color button_key_inactive; + struct dialog_color button_label_active; + struct dialog_color button_label_inactive; + struct dialog_color inputbox; + struct dialog_color inputbox_border; + struct dialog_color searchbox; + struct dialog_color searchbox_title; + struct dialog_color searchbox_border; + struct dialog_color position_indicator; + struct dialog_color menubox; + struct dialog_color menubox_border; + struct dialog_color item; + struct dialog_color item_selected; + struct dialog_color tag; + struct dialog_color tag_selected; + struct dialog_color tag_key; + struct dialog_color tag_key_selected; + struct dialog_color check; + struct dialog_color check_selected; + struct dialog_color uarrow; + struct dialog_color darrow; +}; + +/* + * Global variables + */ +extern struct dialog_info dlg; +extern char dialog_input_result[]; + +/* + * Function prototypes + */ + +/* item list as used by checklist and menubox */ +void item_reset(void); +void item_make(const char *fmt, ...); +void item_add_str(const char *fmt, ...); +void item_set_tag(char tag); +void item_set_data(void *p); +void item_set_selected(int val); +int item_activate_selected(void); +void *item_data(void); +char item_tag(void); + +/* item list manipulation for lxdialog use */ +#define MAXITEMSTR 200 +struct dialog_item { + char str[MAXITEMSTR]; /* promtp displayed */ + char tag; + void *data; /* pointer to menu item - used by menubox+checklist */ + int selected; /* Set to 1 by dialog_*() function if selected. */ +}; + +/* list of lialog_items */ +struct dialog_list { + struct dialog_item node; + struct dialog_list *next; +}; + +extern struct dialog_list *item_cur; +extern struct dialog_list item_nil; +extern struct dialog_list *item_head; + +int item_count(void); +void item_set(int n); +int item_n(void); +const char *item_str(void); +int item_is_selected(void); +int item_is_tag(char tag); +#define item_foreach() \ + for (item_cur = item_head ? item_head: item_cur; \ + item_cur && (item_cur != &item_nil); item_cur = item_cur->next) + +/* generic key handlers */ +int on_key_esc(WINDOW *win); +int on_key_resize(void); + +int init_dialog(const char *backtitle); +void set_dialog_backtitle(const char *backtitle); +void end_dialog(int x, int y); +void attr_clear(WINDOW * win, int height, int width, chtype attr); +void dialog_clear(void); +void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x); +void print_button(WINDOW * win, const char *label, int y, int x, int selected); +void print_title(WINDOW *dialog, const char *title, int width); +void draw_box(WINDOW * win, int y, int x, int height, int width, chtype box, + chtype border); +void draw_shadow(WINDOW * win, int y, int x, int height, int width); + +int first_alpha(const char *string, const char *exempt); +int dialog_yesno(const char *title, const char *prompt, int height, int width); +int dialog_msgbox(const char *title, const char *prompt, int height, + int width, int pause); +int dialog_textbox(const char *title, const char *file, int height, int width); +int dialog_menu(const char *title, const char *prompt, + const void *selected, int *s_scroll); +int dialog_checklist(const char *title, const char *prompt, int height, + int width, int list_height); +extern char dialog_input_result[]; +int dialog_inputbox(const char *title, const char *prompt, int height, + int width, const char *init); + +/* + * This is the base for fictitious keys, which activate + * the buttons. + * + * Mouse-generated keys are the following: + * -- the first 32 are used as numbers, in addition to '0'-'9' + * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o') + * -- uppercase chars are used to invoke the button (M_EVENT + 'O') + */ +#define M_EVENT (KEY_MAX+1) diff --git a/adk/config/lxdialog/inputbox.c b/adk/config/lxdialog/inputbox.c new file mode 100644 index 000000000..616c60138 --- /dev/null +++ b/adk/config/lxdialog/inputbox.c @@ -0,0 +1,238 @@ +/* + * inputbox.c -- implements the input box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +char dialog_input_result[MAX_LEN + 1]; + +/* + * Print the termination buttons + */ +static void print_buttons(WINDOW * dialog, int height, int width, int selected) +{ + int x = width / 2 - 11; + int y = height - 2; + + print_button(dialog, gettext(" Ok "), y, x, selected == 0); + print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); + + wmove(dialog, y, x + 1 + 14 * selected); + wrefresh(dialog); +} + +/* + * Display a dialog box for inputing a string + */ +int dialog_inputbox(const char *title, const char *prompt, int height, int width, + const char *init) +{ + int i, x, y, box_y, box_x, box_width; + int input_x = 0, scroll = 0, key = 0, button = -1; + char *instr = dialog_input_result; + WINDOW *dialog; + + if (!init) + instr[0] = '\0'; + else + strcpy(instr, init); + +do_resize: + if (getmaxy(stdscr) <= (height - 2)) + return -ERRDISPLAYTOOSMALL; + if (getmaxx(stdscr) <= (width - 2)) + return -ERRDISPLAYTOOSMALL; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + + dialog = newwin(height, width, y, x); + keypad(dialog, TRUE); + + draw_box(dialog, 0, 0, height, width, + dlg.dialog.atr, dlg.border.atr); + wattrset(dialog, dlg.border.atr); + mvwaddch(dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch(dialog, ACS_HLINE); + wattrset(dialog, dlg.dialog.atr); + waddch(dialog, ACS_RTEE); + + print_title(dialog, title, width); + + wattrset(dialog, dlg.dialog.atr); + print_autowrap(dialog, prompt, width - 2, 1, 3); + + /* Draw the input field box */ + box_width = width - 6; + getyx(dialog, y, x); + box_y = y + 2; + box_x = (width - box_width) / 2; + draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, + dlg.dialog.atr, dlg.border.atr); + + print_buttons(dialog, height, width, 0); + + /* Set up the initial value */ + wmove(dialog, box_y, box_x); + wattrset(dialog, dlg.inputbox.atr); + + input_x = strlen(instr); + + if (input_x >= box_width) { + scroll = input_x - box_width + 1; + input_x = box_width - 1; + for (i = 0; i < box_width - 1; i++) + waddch(dialog, instr[scroll + i]); + } else { + waddstr(dialog, instr); + } + + wmove(dialog, box_y, box_x + input_x); + + wrefresh(dialog); + + while (key != KEY_ESC) { + key = wgetch(dialog); + + if (button == -1) { /* Input box selected */ + switch (key) { + case TAB: + case KEY_UP: + case KEY_DOWN: + break; + case KEY_LEFT: + continue; + case KEY_RIGHT: + continue; + case KEY_BACKSPACE: + case 127: + if (input_x || scroll) { + wattrset(dialog, dlg.inputbox.atr); + if (!input_x) { + scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1); + wmove(dialog, box_y, box_x); + for (i = 0; i < box_width; i++) + waddch(dialog, + instr[scroll + input_x + i] ? + instr[scroll + input_x + i] : ' '); + input_x = strlen(instr) - scroll; + } else + input_x--; + instr[scroll + input_x] = '\0'; + mvwaddch(dialog, box_y, input_x + box_x, ' '); + wmove(dialog, box_y, input_x + box_x); + wrefresh(dialog); + } + continue; + default: + if (key < 0x100 && isprint(key)) { + if (scroll + input_x < MAX_LEN) { + wattrset(dialog, dlg.inputbox.atr); + instr[scroll + input_x] = key; + instr[scroll + input_x + 1] = '\0'; + if (input_x == box_width - 1) { + scroll++; + wmove(dialog, box_y, box_x); + for (i = 0; i < box_width - 1; i++) + waddch(dialog, instr [scroll + i]); + } else { + wmove(dialog, box_y, input_x++ + box_x); + waddch(dialog, key); + } + wrefresh(dialog); + } else + flash(); /* Alarm user about overflow */ + continue; + } + } + } + switch (key) { + case 'O': + case 'o': + delwin(dialog); + return 0; + case 'H': + case 'h': + delwin(dialog); + return 1; + case KEY_UP: + case KEY_LEFT: + switch (button) { + case -1: + button = 1; /* Indicates "Cancel" button is selected */ + print_buttons(dialog, height, width, 1); + break; + case 0: + button = -1; /* Indicates input box is selected */ + print_buttons(dialog, height, width, 0); + wmove(dialog, box_y, box_x + input_x); + wrefresh(dialog); + break; + case 1: + button = 0; /* Indicates "OK" button is selected */ + print_buttons(dialog, height, width, 0); + break; + } + break; + case TAB: + case KEY_DOWN: + case KEY_RIGHT: + switch (button) { + case -1: + button = 0; /* Indicates "OK" button is selected */ + print_buttons(dialog, height, width, 0); + break; + case 0: + button = 1; /* Indicates "Cancel" button is selected */ + print_buttons(dialog, height, width, 1); + break; + case 1: + button = -1; /* Indicates input box is selected */ + print_buttons(dialog, height, width, 0); + wmove(dialog, box_y, box_x + input_x); + wrefresh(dialog); + break; + } + break; + case ' ': + case '\n': + delwin(dialog); + return (button == -1 ? 0 : button); + case 'X': + case 'x': + key = KEY_ESC; + break; + case KEY_ESC: + key = on_key_esc(dialog); + break; + case KEY_RESIZE: + delwin(dialog); + on_key_resize(); + goto do_resize; + } + } + + delwin(dialog); + return KEY_ESC; /* ESC pressed */ +} diff --git a/adk/config/lxdialog/menubox.c b/adk/config/lxdialog/menubox.c new file mode 100644 index 000000000..fa9d633f2 --- /dev/null +++ b/adk/config/lxdialog/menubox.c @@ -0,0 +1,434 @@ +/* + * menubox.c -- implements the menu box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Changes by Clifford Wolf (god@clifford.at) + * + * [ 1998-06-13 ] + * + * *) A bugfix for the Page-Down problem + * + * *) Formerly when I used Page Down and Page Up, the cursor would be set + * to the first position in the menu box. Now lxdialog is a bit + * smarter and works more like other menu systems (just have a look at + * it). + * + * *) Formerly if I selected something my scrolling would be broken because + * lxdialog is re-invoked by the Menuconfig shell script, can't + * remember the last scrolling position, and just sets it so that the + * cursor is at the bottom of the box. Now it writes the temporary file + * lxdialog.scrltmp which contains this information. The file is + * deleted by lxdialog if the user leaves a submenu or enters a new + * one, but it would be nice if Menuconfig could make another "rm -f" + * just to be sure. Just try it out - you will recognise a difference! + * + * [ 1998-06-14 ] + * + * *) Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files + * and menus change their size on the fly. + * + * *) If for some reason the last scrolling position is not saved by + * lxdialog, it sets the scrolling so that the selected item is in the + * middle of the menu box, not at the bottom. + * + * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net) + * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus. + * This fixes a bug in Menuconfig where using ' ' to descend into menus + * would leave mis-synchronized lxdialog.scrltmp files lying around, + * fscanf would read in 'scroll', and eventually that value would get used. + */ + +#include "dialog.h" + +static int menu_width, item_x; + +/* + * Print menu item + */ +static void do_print_item(WINDOW * win, const char *item, int line_y, + int selected, int hotkey) +{ + int j; + char *menu_item = malloc(menu_width + 1); + + strncpy(menu_item, item, menu_width - item_x); + menu_item[menu_width - item_x] = '\0'; + j = first_alpha(menu_item, "YyNnMmHh"); + + /* Clear 'residue' of last item */ + wattrset(win, dlg.menubox.atr); + wmove(win, line_y, 0); +#if OLD_NCURSES + { + int i; + for (i = 0; i < menu_width; i++) + waddch(win, ' '); + } +#else + wclrtoeol(win); +#endif + wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); + mvwaddstr(win, line_y, item_x, menu_item); + if (hotkey) { + wattrset(win, selected ? dlg.tag_key_selected.atr + : dlg.tag_key.atr); + mvwaddch(win, line_y, item_x + j, menu_item[j]); + } + if (selected) { + wmove(win, line_y, item_x + 1); + } + free(menu_item); + wrefresh(win); +} + +#define print_item(index, choice, selected) \ +do { \ + item_set(index); \ + do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \ +} while (0) + +/* + * Print the scroll indicators. + */ +static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x, + int height) +{ + int cur_y, cur_x; + + getyx(win, cur_y, cur_x); + + wmove(win, y, x); + + if (scroll > 0) { + wattrset(win, dlg.uarrow.atr); + waddch(win, ACS_UARROW); + waddstr(win, "(-)"); + } else { + wattrset(win, dlg.menubox.atr); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + } + + y = y + height + 1; + wmove(win, y, x); + wrefresh(win); + + if ((height < item_no) && (scroll + height < item_no)) { + wattrset(win, dlg.darrow.atr); + waddch(win, ACS_DARROW); + waddstr(win, "(+)"); + } else { + wattrset(win, dlg.menubox_border.atr); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + } + + wmove(win, cur_y, cur_x); + wrefresh(win); +} + +/* + * Display the termination buttons. + */ +static void print_buttons(WINDOW * win, int height, int width, int selected) +{ + int x = width / 2 - 16; + int y = height - 2; + + print_button(win, gettext("Select"), y, x, selected == 0); + print_button(win, gettext(" Exit "), y, x + 12, selected == 1); + print_button(win, gettext(" Help "), y, x + 24, selected == 2); + + wmove(win, y, x + 1 + 12 * selected); + wrefresh(win); +} + +/* scroll up n lines (n may be negative) */ +static void do_scroll(WINDOW *win, int *scroll, int n) +{ + /* Scroll menu up */ + scrollok(win, TRUE); + wscrl(win, n); + scrollok(win, FALSE); + *scroll = *scroll + n; + wrefresh(win); +} + +/* + * Display a menu for choosing among a number of options + */ +int dialog_menu(const char *title, const char *prompt, + const void *selected, int *s_scroll) +{ + int i, j, x, y, box_x, box_y; + int height, width, menu_height; + int key = 0, button = 0, scroll = 0, choice = 0; + int first_item = 0, max_choice; + WINDOW *dialog, *menu; + +do_resize: + height = getmaxy(stdscr); + width = getmaxx(stdscr); + if (height < 15 || width < 65) + return -ERRDISPLAYTOOSMALL; + + height -= 4; + width -= 5; + menu_height = height - 10; + + max_choice = MIN(menu_height, item_count()); + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + + dialog = newwin(height, width, y, x); + keypad(dialog, TRUE); + + draw_box(dialog, 0, 0, height, width, + dlg.dialog.atr, dlg.border.atr); + wattrset(dialog, dlg.border.atr); + mvwaddch(dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch(dialog, ACS_HLINE); + wattrset(dialog, dlg.dialog.atr); + wbkgdset(dialog, dlg.dialog.atr & A_COLOR); + waddch(dialog, ACS_RTEE); + + print_title(dialog, title, width); + + wattrset(dialog, dlg.dialog.atr); + print_autowrap(dialog, prompt, width - 2, 1, 3); + + menu_width = width - 6; + box_y = height - menu_height - 5; + box_x = (width - menu_width) / 2 - 1; + + /* create new window for the menu */ + menu = subwin(dialog, menu_height, menu_width, + y + box_y + 1, x + box_x + 1); + keypad(menu, TRUE); + + /* draw a box around the menu items */ + draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2, + dlg.menubox_border.atr, dlg.menubox.atr); + + if (menu_width >= 80) + item_x = (menu_width - 70) / 2; + else + item_x = 4; + + /* Set choice to default item */ + item_foreach() + if (selected && (selected == item_data())) + choice = item_n(); + /* get the saved scroll info */ + scroll = *s_scroll; + if ((scroll <= choice) && (scroll + max_choice > choice) && + (scroll >= 0) && (scroll + max_choice <= item_count())) { + first_item = scroll; + choice = choice - scroll; + } else { + scroll = 0; + } + if ((choice >= max_choice)) { + if (choice >= item_count() - max_choice / 2) + scroll = first_item = item_count() - max_choice; + else + scroll = first_item = choice - max_choice / 2; + choice = choice - scroll; + } + + /* Print the menu */ + for (i = 0; i < max_choice; i++) { + print_item(first_item + i, i, i == choice); + } + + wnoutrefresh(menu); + + print_arrows(dialog, item_count(), scroll, + box_y, box_x + item_x + 1, menu_height); + + print_buttons(dialog, height, width, 0); + wmove(menu, choice, item_x + 1); + wrefresh(menu); + + while (key != KEY_ESC) { + key = wgetch(menu); + + if (key < 256 && isalpha(key)) + key = tolower(key); + + if (strchr("ynmh", key)) + i = max_choice; + else { + for (i = choice + 1; i < max_choice; i++) { + item_set(scroll + i); + j = first_alpha(item_str(), "YyNnMmHh"); + if (key == tolower(item_str()[j])) + break; + } + if (i == max_choice) + for (i = 0; i < max_choice; i++) { + item_set(scroll + i); + j = first_alpha(item_str(), "YyNnMmHh"); + if (key == tolower(item_str()[j])) + break; + } + } + + if (i < max_choice || + key == KEY_UP || key == KEY_DOWN || + key == '-' || key == '+' || + key == KEY_PPAGE || key == KEY_NPAGE) { + /* Remove highligt of current item */ + print_item(scroll + choice, choice, FALSE); + + if (key == KEY_UP || key == '-') { + if (choice < 2 && scroll) { + /* Scroll menu down */ + do_scroll(menu, &scroll, -1); + + print_item(scroll, 0, FALSE); + } else + choice = MAX(choice - 1, 0); + + } else if (key == KEY_DOWN || key == '+') { + print_item(scroll+choice, choice, FALSE); + + if ((choice > max_choice - 3) && + (scroll + max_choice < item_count())) { + /* Scroll menu up */ + do_scroll(menu, &scroll, 1); + + print_item(scroll+max_choice - 1, + max_choice - 1, FALSE); + } else + choice = MIN(choice + 1, max_choice - 1); + + } else if (key == KEY_PPAGE) { + scrollok(menu, TRUE); + for (i = 0; (i < max_choice); i++) { + if (scroll > 0) { + do_scroll(menu, &scroll, -1); + print_item(scroll, 0, FALSE); + } else { + if (choice > 0) + choice--; + } + } + + } else if (key == KEY_NPAGE) { + for (i = 0; (i < max_choice); i++) { + if (scroll + max_choice < item_count()) { + do_scroll(menu, &scroll, 1); + print_item(scroll+max_choice-1, + max_choice - 1, FALSE); + } else { + if (choice + 1 < max_choice) + choice++; + } + } + } else + choice = i; + + print_item(scroll + choice, choice, TRUE); + + print_arrows(dialog, item_count(), scroll, + box_y, box_x + item_x + 1, menu_height); + + wnoutrefresh(dialog); + wrefresh(menu); + + continue; /* wait for another key press */ + } + + switch (key) { + case KEY_LEFT: + case TAB: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) + ? 2 : (button > 2 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh(menu); + break; + case ' ': + case 's': + case 'y': + case 'n': + case 'm': + case '/': + /* save scroll info */ + *s_scroll = scroll; + delwin(menu); + delwin(dialog); + item_set(scroll + choice); + item_set_selected(1); + switch (key) { + case 's': + return 3; + case 'y': + return 3; + case 'n': + return 4; + case 'm': + return 5; + case ' ': + return 6; + case '/': + return 7; + } + return 0; + case 'h': + case '?': + button = 2; + case '\n': + *s_scroll = scroll; + delwin(menu); + delwin(dialog); + item_set(scroll + choice); + item_set_selected(1); + return button; + case 'e': + case 'x': + key = KEY_ESC; + break; + case KEY_ESC: + key = on_key_esc(menu); + break; + case KEY_RESIZE: + on_key_resize(); + delwin(menu); + delwin(dialog); + goto do_resize; + } + } + delwin(menu); + delwin(dialog); + return key; /* ESC pressed */ +} diff --git a/adk/config/lxdialog/textbox.c b/adk/config/lxdialog/textbox.c new file mode 100644 index 000000000..c704712d0 --- /dev/null +++ b/adk/config/lxdialog/textbox.c @@ -0,0 +1,391 @@ +/* + * textbox.c -- implements the text box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +static void back_lines(int n); +static void print_page(WINDOW * win, int height, int width); +static void print_line(WINDOW * win, int row, int width); +static char *get_line(void); +static void print_position(WINDOW * win); + +static int hscroll; +static int begin_reached, end_reached, page_length; +static const char *buf; +static const char *page; + +/* + * refresh window content + */ +static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, + int cur_y, int cur_x) +{ + print_page(box, boxh, boxw); + print_position(dialog); + wmove(dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh(dialog); +} + + +/* + * Display text from a file in a dialog box. + */ +int dialog_textbox(const char *title, const char *tbuf, + int initial_height, int initial_width) +{ + int i, x, y, cur_x, cur_y, key = 0; + int height, width, boxh, boxw; + int passed_end; + WINDOW *dialog, *box; + + begin_reached = 1; + end_reached = 0; + page_length = 0; + hscroll = 0; + buf = tbuf; + page = buf; /* page is pointer to start of page to be displayed */ + +do_resize: + getmaxyx(stdscr, height, width); + if (height < 8 || width < 8) + return -ERRDISPLAYTOOSMALL; + if (initial_height != 0) + height = initial_height; + else + if (height > 4) + height -= 4; + else + height = 0; + if (initial_width != 0) + width = initial_width; + else + if (width > 5) + width -= 5; + else + width = 0; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + + dialog = newwin(height, width, y, x); + keypad(dialog, TRUE); + + /* Create window for box region, used for scrolling text */ + boxh = height - 4; + boxw = width - 2; + box = subwin(dialog, boxh, boxw, y + 1, x + 1); + wattrset(box, dlg.dialog.atr); + wbkgdset(box, dlg.dialog.atr & A_COLOR); + + keypad(box, TRUE); + + /* register the new window, along with its borders */ + draw_box(dialog, 0, 0, height, width, + dlg.dialog.atr, dlg.border.atr); + + wattrset(dialog, dlg.border.atr); + mvwaddch(dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch(dialog, ACS_HLINE); + wattrset(dialog, dlg.dialog.atr); + wbkgdset(dialog, dlg.dialog.atr & A_COLOR); + waddch(dialog, ACS_RTEE); + + print_title(dialog, title, width); + + print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE); + wnoutrefresh(dialog); + getyx(dialog, cur_y, cur_x); /* Save cursor position */ + + /* Print first page of text */ + attr_clear(box, boxh, boxw, dlg.dialog.atr); + refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); + + while ((key != KEY_ESC) && (key != '\n')) { + key = wgetch(dialog); + switch (key) { + case 'E': /* Exit */ + case 'e': + case 'X': + case 'x': + delwin(box); + delwin(dialog); + return 0; + case 'g': /* First page */ + case KEY_HOME: + if (!begin_reached) { + begin_reached = 1; + page = buf; + refresh_text_box(dialog, box, boxh, boxw, + cur_y, cur_x); + } + break; + case 'G': /* Last page */ + case KEY_END: + + end_reached = 1; + /* point to last char in buf */ + page = buf + strlen(buf); + back_lines(boxh); + refresh_text_box(dialog, box, boxh, boxw, + cur_y, cur_x); + break; + case 'K': /* Previous line */ + case 'k': + case KEY_UP: + if (!begin_reached) { + back_lines(page_length + 1); + + /* We don't call print_page() here but use + * scrolling to ensure faster screen update. + * However, 'end_reached' and 'page_length' + * should still be updated, and 'page' should + * point to start of next page. This is done + * by calling get_line() in the following + * 'for' loop. */ + scrollok(box, TRUE); + wscrl(box, -1); /* Scroll box region down one line */ + scrollok(box, FALSE); + page_length = 0; + passed_end = 0; + for (i = 0; i < boxh; i++) { + if (!i) { + /* print first line of page */ + print_line(box, 0, boxw); + wnoutrefresh(box); + } else + /* Called to update 'end_reached' and 'page' */ + get_line(); + if (!passed_end) + page_length++; + if (end_reached && !passed_end) + passed_end = 1; + } + + print_position(dialog); + wmove(dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh(dialog); + } + break; + case 'B': /* Previous page */ + case 'b': + case KEY_PPAGE: + if (begin_reached) + break; + back_lines(page_length + boxh); + refresh_text_box(dialog, box, boxh, boxw, + cur_y, cur_x); + break; + case 'J': /* Next line */ + case 'j': + case KEY_DOWN: + if (!end_reached) { + begin_reached = 0; + scrollok(box, TRUE); + scroll(box); /* Scroll box region up one line */ + scrollok(box, FALSE); + print_line(box, boxh - 1, boxw); + wnoutrefresh(box); + print_position(dialog); + wmove(dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh(dialog); + } + break; + case KEY_NPAGE: /* Next page */ + case ' ': + if (end_reached) + break; + + begin_reached = 0; + refresh_text_box(dialog, box, boxh, boxw, + cur_y, cur_x); + break; + case '0': /* Beginning of line */ + case 'H': /* Scroll left */ + case 'h': + case KEY_LEFT: + if (hscroll <= 0) + break; + + if (key == '0') + hscroll = 0; + else + hscroll--; + /* Reprint current page to scroll horizontally */ + back_lines(page_length); + refresh_text_box(dialog, box, boxh, boxw, + cur_y, cur_x); + break; + case 'L': /* Scroll right */ + case 'l': + case KEY_RIGHT: + if (hscroll >= MAX_LEN) + break; + hscroll++; + /* Reprint current page to scroll horizontally */ + back_lines(page_length); + refresh_text_box(dialog, box, boxh, boxw, + cur_y, cur_x); + break; + case KEY_ESC: + key = on_key_esc(dialog); + break; + case KEY_RESIZE: + back_lines(height); + delwin(box); + delwin(dialog); + on_key_resize(); + goto do_resize; + } + } + delwin(box); + delwin(dialog); + return key; /* ESC pressed */ +} + +/* + * Go back 'n' lines in text. Called by dialog_textbox(). + * 'page' will be updated to point to the desired line in 'buf'. + */ +static void back_lines(int n) +{ + int i; + + begin_reached = 0; + /* Go back 'n' lines */ + for (i = 0; i < n; i++) { + if (*page == '\0') { + if (end_reached) { + end_reached = 0; + continue; + } + } + if (page == buf) { + begin_reached = 1; + return; + } + page--; + do { + if (page == buf) { + begin_reached = 1; + return; + } + page--; + } while (*page != '\n'); + page++; + } +} + +/* + * Print a new page of text. Called by dialog_textbox(). + */ +static void print_page(WINDOW * win, int height, int width) +{ + int i, passed_end = 0; + + page_length = 0; + for (i = 0; i < height; i++) { + print_line(win, i, width); + if (!passed_end) + page_length++; + if (end_reached && !passed_end) + passed_end = 1; + } + wnoutrefresh(win); +} + +/* + * Print a new line of text. Called by dialog_textbox() and print_page(). + */ +static void print_line(WINDOW * win, int row, int width) +{ + int y, x; + char *line; + + line = get_line(); + line += MIN(strlen(line), hscroll); /* Scroll horizontally */ + wmove(win, row, 0); /* move cursor to correct line */ + waddch(win, ' '); + waddnstr(win, line, MIN(strlen(line), width - 2)); + + getyx(win, y, x); + /* Clear 'residue' of previous line */ +#if OLD_NCURSES + { + int i; + for (i = 0; i < width - x; i++) + waddch(win, ' '); + } +#else + wclrtoeol(win); +#endif +} + +/* + * Return current line of text. Called by dialog_textbox() and print_line(). + * 'page' should point to start of current line before calling, and will be + * updated to point to start of next line. + */ +static char *get_line(void) +{ + int i = 0; + static char line[MAX_LEN + 1]; + + end_reached = 0; + while (*page != '\n') { + if (*page == '\0') { + if (!end_reached) { + end_reached = 1; + break; + } + } else if (i < MAX_LEN) + line[i++] = *(page++); + else { + /* Truncate lines longer than MAX_LEN characters */ + if (i == MAX_LEN) + line[i++] = '\0'; + page++; + } + } + if (i <= MAX_LEN) + line[i] = '\0'; + if (!end_reached) + page++; /* move pass '\n' */ + + return line; +} + +/* + * Print current position + */ +static void print_position(WINDOW * win) +{ + int percent; + + wattrset(win, dlg.position_indicator.atr); + wbkgdset(win, dlg.position_indicator.atr & A_COLOR); + percent = (page - buf) * 100 / strlen(buf); + wmove(win, getmaxy(win) - 3, getmaxx(win) - 9); + wprintw(win, "(%3d%%)", percent); +} diff --git a/adk/config/lxdialog/util.c b/adk/config/lxdialog/util.c new file mode 100644 index 000000000..f2375ad7e --- /dev/null +++ b/adk/config/lxdialog/util.c @@ -0,0 +1,657 @@ +/* + * util.c + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "dialog.h" + +struct dialog_info dlg; + +static void set_mono_theme(void) +{ + dlg.screen.atr = A_NORMAL; + dlg.shadow.atr = A_NORMAL; + dlg.dialog.atr = A_NORMAL; + dlg.title.atr = A_BOLD; + dlg.border.atr = A_NORMAL; + dlg.button_active.atr = A_REVERSE; + dlg.button_inactive.atr = A_DIM; + dlg.button_key_active.atr = A_REVERSE; + dlg.button_key_inactive.atr = A_BOLD; + dlg.button_label_active.atr = A_REVERSE; + dlg.button_label_inactive.atr = A_NORMAL; + dlg.inputbox.atr = A_NORMAL; + dlg.inputbox_border.atr = A_NORMAL; + dlg.searchbox.atr = A_NORMAL; + dlg.searchbox_title.atr = A_BOLD; + dlg.searchbox_border.atr = A_NORMAL; + dlg.position_indicator.atr = A_BOLD; + dlg.menubox.atr = A_NORMAL; + dlg.menubox_border.atr = A_NORMAL; + dlg.item.atr = A_NORMAL; + dlg.item_selected.atr = A_REVERSE; + dlg.tag.atr = A_BOLD; + dlg.tag_selected.atr = A_REVERSE; + dlg.tag_key.atr = A_BOLD; + dlg.tag_key_selected.atr = A_REVERSE; + dlg.check.atr = A_BOLD; + dlg.check_selected.atr = A_REVERSE; + dlg.uarrow.atr = A_BOLD; + dlg.darrow.atr = A_BOLD; +} + +#define DLG_COLOR(dialog, f, b, h) \ +do { \ + dlg.dialog.fg = (f); \ + dlg.dialog.bg = (b); \ + dlg.dialog.hl = (h); \ +} while (0) + +static void set_classic_theme(void) +{ + DLG_COLOR(screen, COLOR_CYAN, COLOR_BLUE, true); + DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, true); + DLG_COLOR(dialog, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(title, COLOR_YELLOW, COLOR_WHITE, true); + DLG_COLOR(border, COLOR_WHITE, COLOR_WHITE, true); + DLG_COLOR(button_active, COLOR_WHITE, COLOR_BLUE, true); + DLG_COLOR(button_inactive, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(button_key_active, COLOR_WHITE, COLOR_BLUE, true); + DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_WHITE, false); + DLG_COLOR(button_label_active, COLOR_YELLOW, COLOR_BLUE, true); + DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_WHITE, true); + DLG_COLOR(inputbox, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(inputbox_border, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(searchbox, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_WHITE, true); + DLG_COLOR(searchbox_border, COLOR_WHITE, COLOR_WHITE, true); + DLG_COLOR(position_indicator, COLOR_YELLOW, COLOR_WHITE, true); + DLG_COLOR(menubox, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(menubox_border, COLOR_WHITE, COLOR_WHITE, true); + DLG_COLOR(item, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(item_selected, COLOR_WHITE, COLOR_BLUE, true); + DLG_COLOR(tag, COLOR_YELLOW, COLOR_WHITE, true); + DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_BLUE, true); + DLG_COLOR(tag_key, COLOR_YELLOW, COLOR_WHITE, true); + DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_BLUE, true); + DLG_COLOR(check, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(check_selected, COLOR_WHITE, COLOR_BLUE, true); + DLG_COLOR(uarrow, COLOR_GREEN, COLOR_WHITE, true); + DLG_COLOR(darrow, COLOR_GREEN, COLOR_WHITE, true); +} + +static void set_blackbg_theme(void) +{ + DLG_COLOR(screen, COLOR_RED, COLOR_BLACK, true); + DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false); + DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false); + DLG_COLOR(title, COLOR_RED, COLOR_BLACK, false); + DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true); + + DLG_COLOR(button_active, COLOR_YELLOW, COLOR_RED, false); + DLG_COLOR(button_inactive, COLOR_YELLOW, COLOR_BLACK, false); + DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_RED, true); + DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_BLACK, false); + DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_RED, false); + DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_BLACK, true); + + DLG_COLOR(inputbox, COLOR_YELLOW, COLOR_BLACK, false); + DLG_COLOR(inputbox_border, COLOR_YELLOW, COLOR_BLACK, false); + + DLG_COLOR(searchbox, COLOR_YELLOW, COLOR_BLACK, false); + DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_BLACK, true); + DLG_COLOR(searchbox_border, COLOR_BLACK, COLOR_BLACK, true); + + DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK, false); + + DLG_COLOR(menubox, COLOR_YELLOW, COLOR_BLACK, false); + DLG_COLOR(menubox_border, COLOR_BLACK, COLOR_BLACK, true); + + DLG_COLOR(item, COLOR_WHITE, COLOR_BLACK, false); + DLG_COLOR(item_selected, COLOR_WHITE, COLOR_RED, false); + + DLG_COLOR(tag, COLOR_RED, COLOR_BLACK, false); + DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_RED, true); + DLG_COLOR(tag_key, COLOR_RED, COLOR_BLACK, false); + DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED, true); + + DLG_COLOR(check, COLOR_YELLOW, COLOR_BLACK, false); + DLG_COLOR(check_selected, COLOR_YELLOW, COLOR_RED, true); + + DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false); + DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false); +} + +static void set_bluetitle_theme(void) +{ + set_classic_theme(); + DLG_COLOR(title, COLOR_BLUE, COLOR_WHITE, true); + DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_BLUE, true); + DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_BLUE, true); + DLG_COLOR(searchbox_title, COLOR_BLUE, COLOR_WHITE, true); + DLG_COLOR(position_indicator, COLOR_BLUE, COLOR_WHITE, true); + DLG_COLOR(tag, COLOR_BLUE, COLOR_WHITE, true); + DLG_COLOR(tag_key, COLOR_BLUE, COLOR_WHITE, true); + +} + +/* + * Select color theme + */ +static int set_theme(const char *theme) +{ + int use_color = 1; + if (!theme) + set_bluetitle_theme(); + else if (strcmp(theme, "classic") == 0) + set_classic_theme(); + else if (strcmp(theme, "bluetitle") == 0) + set_bluetitle_theme(); + else if (strcmp(theme, "blackbg") == 0) + set_blackbg_theme(); + else if (strcmp(theme, "mono") == 0) + use_color = 0; + + return use_color; +} + +static void init_one_color(struct dialog_color *color) +{ + static int pair = 0; + + pair++; + init_pair(pair, color->fg, color->bg); + if (color->hl) + color->atr = A_BOLD | COLOR_PAIR(pair); + else + color->atr = COLOR_PAIR(pair); +} + +static void init_dialog_colors(void) +{ + init_one_color(&dlg.screen); + init_one_color(&dlg.shadow); + init_one_color(&dlg.dialog); + init_one_color(&dlg.title); + init_one_color(&dlg.border); + init_one_color(&dlg.button_active); + init_one_color(&dlg.button_inactive); + init_one_color(&dlg.button_key_active); + init_one_color(&dlg.button_key_inactive); + init_one_color(&dlg.button_label_active); + init_one_color(&dlg.button_label_inactive); + init_one_color(&dlg.inputbox); + init_one_color(&dlg.inputbox_border); + init_one_color(&dlg.searchbox); + init_one_color(&dlg.searchbox_title); + init_one_color(&dlg.searchbox_border); + init_one_color(&dlg.position_indicator); + init_one_color(&dlg.menubox); + init_one_color(&dlg.menubox_border); + init_one_color(&dlg.item); + init_one_color(&dlg.item_selected); + init_one_color(&dlg.tag); + init_one_color(&dlg.tag_selected); + init_one_color(&dlg.tag_key); + init_one_color(&dlg.tag_key_selected); + init_one_color(&dlg.check); + init_one_color(&dlg.check_selected); + init_one_color(&dlg.uarrow); + init_one_color(&dlg.darrow); +} + +/* + * Setup for color display + */ +static void color_setup(const char *theme) +{ + int use_color; + + use_color = set_theme(theme); + if (use_color && has_colors()) { + start_color(); + init_dialog_colors(); + } else + set_mono_theme(); +} + +/* + * Set window to attribute 'attr' + */ +void attr_clear(WINDOW * win, int height, int width, chtype attr) +{ + int i, j; + + wattrset(win, attr); + for (i = 0; i < height; i++) { + wmove(win, i, 0); + for (j = 0; j < width; j++) + waddch(win, ' '); + } + touchwin(win); +} + +void dialog_clear(void) +{ + attr_clear(stdscr, LINES, COLS, dlg.screen.atr); + /* Display background title if it exists ... - SLH */ + if (dlg.backtitle != NULL) { + int i; + + wattrset(stdscr, dlg.screen.atr); + mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle); + wmove(stdscr, 1, 1); + for (i = 1; i < COLS - 1; i++) + waddch(stdscr, ACS_HLINE); + } + wnoutrefresh(stdscr); +} + +/* + * Do some initialization for dialog + */ +int init_dialog(const char *backtitle) +{ + int height, width; + + initscr(); /* Init curses */ + getmaxyx(stdscr, height, width); + if (height < 19 || width < 80) { + endwin(); + return -ERRDISPLAYTOOSMALL; + } + + dlg.backtitle = backtitle; + color_setup(getenv("MENUCONFIG_COLOR")); + + keypad(stdscr, TRUE); + cbreak(); + noecho(); + dialog_clear(); + + return 0; +} + +void set_dialog_backtitle(const char *backtitle) +{ + dlg.backtitle = backtitle; +} + +/* + * End using dialog functions. + */ +void end_dialog(int x, int y) +{ + /* move cursor back to original position */ + move(y, x); + refresh(); + endwin(); +} + +/* Print the title of the dialog. Center the title and truncate + * tile if wider than dialog (- 2 chars). + **/ +void print_title(WINDOW *dialog, const char *title, int width) +{ + if (title) { + int tlen = MIN(width - 2, strlen(title)); + wattrset(dialog, dlg.title.atr); + mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' '); + mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen); + waddch(dialog, ' '); + } +} + +/* + * Print a string of text in a window, automatically wrap around to the + * next line if the string is too long to fit on one line. Newline + * characters '\n' are replaced by spaces. We start on a new line + * if there is no room for at least 4 nonblanks following a double-space. + */ +void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) +{ + int newl, cur_x, cur_y; + int i, prompt_len, room, wlen; + char tempstr[MAX_LEN + 1], *word, *sp, *sp2; + + strcpy(tempstr, prompt); + + prompt_len = strlen(tempstr); + + /* + * Remove newlines + */ + for (i = 0; i < prompt_len; i++) { + if (tempstr[i] == '\n') + tempstr[i] = ' '; + } + + if (prompt_len <= width - x * 2) { /* If prompt is short */ + wmove(win, y, (width - prompt_len) / 2); + waddstr(win, tempstr); + } else { + cur_x = x; + cur_y = y; + newl = 1; + word = tempstr; + while (word && *word) { + sp = strchr(word, ' '); + if (sp) + *sp++ = 0; + + /* Wrap to next line if either the word does not fit, + or it is the first word of a new sentence, and it is + short, and the next word does not fit. */ + room = width - cur_x; + wlen = strlen(word); + if (wlen > room || + (newl && wlen < 4 && sp + && wlen + 1 + strlen(sp) > room + && (!(sp2 = strchr(sp, ' ')) + || wlen + 1 + (sp2 - sp) > room))) { + cur_y++; + cur_x = x; + } + wmove(win, cur_y, cur_x); + waddstr(win, word); + getyx(win, cur_y, cur_x); + cur_x++; + if (sp && *sp == ' ') { + cur_x++; /* double space */ + while (*++sp == ' ') ; + newl = 1; + } else + newl = 0; + word = sp; + } + } +} + +/* + * Print a button + */ +void print_button(WINDOW * win, const char *label, int y, int x, int selected) +{ + int i, temp; + + wmove(win, y, x); + wattrset(win, selected ? dlg.button_active.atr + : dlg.button_inactive.atr); + waddstr(win, "<"); + temp = strspn(label, " "); + label += temp; + wattrset(win, selected ? dlg.button_label_active.atr + : dlg.button_label_inactive.atr); + for (i = 0; i < temp; i++) + waddch(win, ' '); + wattrset(win, selected ? dlg.button_key_active.atr + : dlg.button_key_inactive.atr); + waddch(win, label[0]); + wattrset(win, selected ? dlg.button_label_active.atr + : dlg.button_label_inactive.atr); + waddstr(win, (char *)label + 1); + wattrset(win, selected ? dlg.button_active.atr + : dlg.button_inactive.atr); + waddstr(win, ">"); + wmove(win, y, x + temp + 1); +} + +/* + * Draw a rectangular box with line drawing characters + */ +void +draw_box(WINDOW * win, int y, int x, int height, int width, + chtype box, chtype border) +{ + int i, j; + + wattrset(win, 0); + for (i = 0; i < height; i++) { + wmove(win, y + i, x); + for (j = 0; j < width; j++) + if (!i && !j) + waddch(win, border | ACS_ULCORNER); + else if (i == height - 1 && !j) + waddch(win, border | ACS_LLCORNER); + else if (!i && j == width - 1) + waddch(win, box | ACS_URCORNER); + else if (i == height - 1 && j == width - 1) + waddch(win, box | ACS_LRCORNER); + else if (!i) + waddch(win, border | ACS_HLINE); + else if (i == height - 1) + waddch(win, box | ACS_HLINE); + else if (!j) + waddch(win, border | ACS_VLINE); + else if (j == width - 1) + waddch(win, box | ACS_VLINE); + else + waddch(win, box | ' '); + } +} + +/* + * Draw shadows along the right and bottom edge to give a more 3D look + * to the boxes + */ +void draw_shadow(WINDOW * win, int y, int x, int height, int width) +{ + int i; + + if (has_colors()) { /* Whether terminal supports color? */ + wattrset(win, dlg.shadow.atr); + wmove(win, y + height, x + 2); + for (i = 0; i < width; i++) + waddch(win, winch(win) & A_CHARTEXT); + for (i = y + 1; i < y + height + 1; i++) { + wmove(win, i, x + width); + waddch(win, winch(win) & A_CHARTEXT); + waddch(win, winch(win) & A_CHARTEXT); + } + wnoutrefresh(win); + } +} + +/* + * Return the position of the first alphabetic character in a string. + */ +int first_alpha(const char *string, const char *exempt) +{ + int i, in_paren = 0, c; + + for (i = 0; i < strlen(string); i++) { + c = tolower(string[i]); + + if (strchr("<[(", c)) + ++in_paren; + if (strchr(">])", c) && in_paren > 0) + --in_paren; + + if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0) + return i; + } + + return 0; +} + +/* + * ncurses uses ESC to detect escaped char sequences. This resutl in + * a small timeout before ESC is actually delivered to the application. + * lxdialog suggest which is correctly translated to two + * times esc. But then we need to ignore the second esc to avoid stepping + * out one menu too much. Filter away all escaped key sequences since + * keypad(FALSE) turn off ncurses support for escape sequences - and thats + * needed to make notimeout() do as expected. + */ +int on_key_esc(WINDOW *win) +{ + int key; + int key2; + int key3; + + nodelay(win, TRUE); + keypad(win, FALSE); + key = wgetch(win); + key2 = wgetch(win); + do { + key3 = wgetch(win); + } while (key3 != ERR); + nodelay(win, FALSE); + keypad(win, TRUE); + if (key == KEY_ESC && key2 == ERR) + return KEY_ESC; + else if (key != ERR && key != KEY_ESC && key2 == ERR) + ungetch(key); + + return -1; +} + +/* redraw screen in new size */ +int on_key_resize(void) +{ + dialog_clear(); + return KEY_RESIZE; +} + +struct dialog_list *item_cur; +struct dialog_list item_nil; +struct dialog_list *item_head; + +void item_reset(void) +{ + struct dialog_list *p, *next; + + for (p = item_head; p; p = next) { + next = p->next; + free(p); + } + item_head = NULL; + item_cur = &item_nil; +} + +void item_make(const char *fmt, ...) +{ + va_list ap; + struct dialog_list *p = malloc(sizeof(*p)); + + if (item_head) + item_cur->next = p; + else + item_head = p; + item_cur = p; + memset(p, 0, sizeof(*p)); + + va_start(ap, fmt); + vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap); + va_end(ap); +} + +void item_add_str(const char *fmt, ...) +{ + va_list ap; + size_t avail; + + avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str); + + va_start(ap, fmt); + vsnprintf(item_cur->node.str + strlen(item_cur->node.str), + avail, fmt, ap); + item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0'; + va_end(ap); +} + +void item_set_tag(char tag) +{ + item_cur->node.tag = tag; +} +void item_set_data(void *ptr) +{ + item_cur->node.data = ptr; +} + +void item_set_selected(int val) +{ + item_cur->node.selected = val; +} + +int item_activate_selected(void) +{ + item_foreach() + if (item_is_selected()) + return 1; + return 0; +} + +void *item_data(void) +{ + return item_cur->node.data; +} + +char item_tag(void) +{ + return item_cur->node.tag; +} + +int item_count(void) +{ + int n = 0; + struct dialog_list *p; + + for (p = item_head; p; p = p->next) + n++; + return n; +} + +void item_set(int n) +{ + int i = 0; + item_foreach() + if (i++ == n) + return; +} + +int item_n(void) +{ + int n = 0; + struct dialog_list *p; + + for (p = item_head; p; p = p->next) { + if (p == item_cur) + return n; + n++; + } + return 0; +} + +const char *item_str(void) +{ + return item_cur->node.str; +} + +int item_is_selected(void) +{ + return (item_cur->node.selected != 0); +} + +int item_is_tag(char tag) +{ + return (item_cur->node.tag == tag); +} diff --git a/adk/config/lxdialog/yesno.c b/adk/config/lxdialog/yesno.c new file mode 100644 index 000000000..4e6e8090c --- /dev/null +++ b/adk/config/lxdialog/yesno.c @@ -0,0 +1,114 @@ +/* + * yesno.c -- implements the yes/no box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +/* + * Display termination buttons + */ +static void print_buttons(WINDOW * dialog, int height, int width, int selected) +{ + int x = width / 2 - 10; + int y = height - 2; + + print_button(dialog, gettext(" Yes "), y, x, selected == 0); + print_button(dialog, gettext(" No "), y, x + 13, selected == 1); + + wmove(dialog, y, x + 1 + 13 * selected); + wrefresh(dialog); +} + +/* + * Display a dialog box with two buttons - Yes and No + */ +int dialog_yesno(const char *title, const char *prompt, int height, int width) +{ + int i, x, y, key = 0, button = 0; + WINDOW *dialog; + +do_resize: + if (getmaxy(stdscr) < (height + 4)) + return -ERRDISPLAYTOOSMALL; + if (getmaxx(stdscr) < (width + 4)) + return -ERRDISPLAYTOOSMALL; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + + dialog = newwin(height, width, y, x); + keypad(dialog, TRUE); + + draw_box(dialog, 0, 0, height, width, + dlg.dialog.atr, dlg.border.atr); + wattrset(dialog, dlg.border.atr); + mvwaddch(dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch(dialog, ACS_HLINE); + wattrset(dialog, dlg.dialog.atr); + waddch(dialog, ACS_RTEE); + + print_title(dialog, title, width); + + wattrset(dialog, dlg.dialog.atr); + print_autowrap(dialog, prompt, width - 2, 1, 3); + + print_buttons(dialog, height, width, 0); + + while (key != KEY_ESC) { + key = wgetch(dialog); + switch (key) { + case 'Y': + case 'y': + delwin(dialog); + return 0; + case 'N': + case 'n': + delwin(dialog); + return 1; + + case TAB: + case KEY_LEFT: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh(dialog); + break; + case ' ': + case '\n': + delwin(dialog); + return button; + case KEY_ESC: + key = on_key_esc(dialog); + break; + case KEY_RESIZE: + delwin(dialog); + on_key_resize(); + goto do_resize; + } + } + + delwin(dialog); + return key; /* ESC pressed */ +} diff --git a/adk/config/mconf.c b/adk/config/mconf.c new file mode 100644 index 000000000..6aa2c0d88 --- /dev/null +++ b/adk/config/mconf.c @@ -0,0 +1,940 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + * + * Introduced single menu mode (show all sub-menus in one large tree). + * 2002-11-06 Petr Baudis + * + * i18n, 2005, Arnaldo Carvalho de Melo + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" +#include "lxdialog/dialog.h" + +static const char mconf_readme[] = N_( +"Overview\n" +"--------\n" +"Some kernel features may be built directly into the kernel.\n" +"Some may be made into loadable runtime modules. Some features\n" +"may be completely removed altogether. There are also certain\n" +"kernel parameters which are not really features, but must be\n" +"entered in as decimal or hexadecimal numbers or possibly text.\n" +"\n" +"Menu items beginning with following braces represent features that\n" +" [ ] can be built in or removed\n" +" < > can be built in, modularized or removed\n" +" { } can be built in or modularized (selected by other feature)\n" +" - - are selected by other feature,\n" +"while *, M or whitespace inside braces means to build in, build as\n" +"a module or to exclude the feature respectively.\n" +"\n" +"To change any of these features, highlight it with the cursor\n" +"keys and press to build it in, to make it a module or\n" +" to removed it. You may also press the to cycle\n" +"through the available options (ie. Y->N->M->Y).\n" +"\n" +"Some additional keyboard hints:\n" +"\n" +"Menus\n" +"----------\n" +"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n" +" you wish to change or submenu wish to select and press .\n" +" Submenus are designated by \"--->\".\n" +"\n" +" Shortcut: Press the option's highlighted letter (hotkey).\n" +" Pressing a hotkey more than once will sequence\n" +" through all visible items which use that hotkey.\n" +"\n" +" You may also use the and keys to scroll\n" +" unseen options into view.\n" +"\n" +"o To exit a menu use the cursor keys to highlight the button\n" +" and press .\n" +"\n" +" Shortcut: Press or or if there is no hotkey\n" +" using those letters. You may press a single , but\n" +" there is a delayed response which you may find annoying.\n" +"\n" +" Also, the and cursor keys will cycle between and\n" +" \n" +"\n" +"\n" +"Data Entry\n" +"-----------\n" +"o Enter the requested information and press \n" +" If you are entering hexadecimal values, it is not necessary to\n" +" add the '0x' prefix to the entry.\n" +"\n" +"o For help, use the or cursor keys to highlight the help option\n" +" and press . You can try as well.\n" +"\n" +"\n" +"Text Box (Help Window)\n" +"--------\n" +"o Use the cursor keys to scroll up/down/left/right. The VI editor\n" +" keys h,j,k,l function here as do and for those\n" +" who are familiar with less and lynx.\n" +"\n" +"o Press , , or to exit.\n" +"\n" +"\n" +"Alternate Configuration Files\n" +"-----------------------------\n" +"Menuconfig supports the use of alternate configuration files for\n" +"those who, for various reasons, find it necessary to switch\n" +"between different kernel configurations.\n" +"\n" +"At the end of the main menu you will find two options. One is\n" +"for saving the current configuration to a file of your choosing.\n" +"The other option is for loading a previously saved alternate\n" +"configuration.\n" +"\n" +"Even if you don't use alternate configuration files, but you\n" +"find during a Menuconfig session that you have completely messed\n" +"up your settings, you may use the \"Load Alternate...\" option to\n" +"restore your previously saved settings from \".config\" without\n" +"restarting Menuconfig.\n" +"\n" +"Other information\n" +"-----------------\n" +"If you use Menuconfig in an XTERM window make sure you have your\n" +"$TERM variable set to point to a xterm definition which supports color.\n" +"Otherwise, Menuconfig will look rather bad. Menuconfig will not\n" +"display correctly in a RXVT window because rxvt displays only one\n" +"intensity of color, bright.\n" +"\n" +"Menuconfig will display larger menus on screens or xterms which are\n" +"set to display more than the standard 25 row by 80 column geometry.\n" +"In order for this to work, the \"stty size\" command must be able to\n" +"display the screen's current row and column geometry. I STRONGLY\n" +"RECOMMEND that you make sure you do NOT have the shell variables\n" +"LINES and COLUMNS exported into your environment. Some distributions\n" +"export those variables via /etc/profile. Some ncurses programs can\n" +"become confused when those variables (LINES & COLUMNS) don't reflect\n" +"the true screen size.\n" +"\n" +"Optional personality available\n" +"------------------------------\n" +"If you prefer to have all of the kernel options listed in a single\n" +"menu, rather than the default multimenu hierarchy, run the menuconfig\n" +"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n" +"\n" +"make MENUCONFIG_MODE=single_menu menuconfig\n" +"\n" +" will then unroll the appropriate category, or enfold it if it\n" +"is already unrolled.\n" +"\n" +"Note that this mode can eventually be a little more CPU expensive\n" +"(especially with a larger number of unrolled categories) than the\n" +"default mode.\n" +"\n" +"Different color themes available\n" +"--------------------------------\n" +"It is possible to select different color themes using the variable\n" +"MENUCONFIG_COLOR. To select a theme use:\n" +"\n" +"make MENUCONFIG_COLOR= menuconfig\n" +"\n" +"Available themes are\n" +" mono => selects colors suitable for monochrome displays\n" +" blackbg => selects a color scheme with black background\n" +" classic => theme with blue background. The classic look\n" +" bluetitle => a LCD friendly version of classic. (default)\n" +"\n"), +menu_instructions[] = N_( + "Arrow keys navigate the menu. " + " selects submenus --->. " + "Highlighted letters are hotkeys. " + "Pressing includes, excludes, modularizes features. " + "Press to exit, for Help, for Search. " + "Legend: [*] built-in [ ] excluded module < > module capable"), +radiolist_instructions[] = N_( + "Use the arrow keys to navigate this window or " + "press the hotkey of the item you wish to select " + "followed by the . " + "Press for additional information about this option."), +inputbox_instructions_int[] = N_( + "Please enter a decimal value. " + "Fractions will not be accepted. " + "Use the key to move from the input field to the buttons below it."), +inputbox_instructions_hex[] = N_( + "Please enter a hexadecimal value. " + "Use the key to move from the input field to the buttons below it."), +inputbox_instructions_string[] = N_( + "Please enter a string value. " + "Use the key to move from the input field to the buttons below it."), +setmod_text[] = N_( + "This feature depends on another which has been configured as a module.\n" + "As a result, this feature will be built as a module."), +nohelp_text[] = N_( + "There is no help available for this kernel option.\n"), +load_config_text[] = N_( + "Enter the name of the configuration file you wish to load. " + "Accept the name shown to restore the configuration you " + "last retrieved. Leave blank to abort."), +load_config_help[] = N_( + "\n" + "For various reasons, one may wish to keep several different kernel\n" + "configurations available on a single machine.\n" + "\n" + "If you have saved a previous configuration in a file other than the\n" + "kernel's default, entering the name of the file here will allow you\n" + "to modify that configuration.\n" + "\n" + "If you are uncertain, then you have probably never used alternate\n" + "configuration files. You should therefor leave this blank to abort.\n"), +save_config_text[] = N_( + "Enter a filename to which this configuration should be saved " + "as an alternate. Leave blank to abort."), +save_config_help[] = N_( + "\n" + "For various reasons, one may wish to keep different kernel\n" + "configurations available on a single machine.\n" + "\n" + "Entering a file name here will allow you to later retrieve, modify\n" + "and use the current configuration as an alternate to whatever\n" + "configuration options you have selected at that time.\n" + "\n" + "If you are uncertain what all this means then you should probably\n" + "leave this blank.\n"), +search_help[] = N_( + "\n" + "Search for CONFIG_ symbols and display their relations.\n" + "Regular expressions are allowed.\n" + "Example: search for \"^FOO\"\n" + "Result:\n" + "-----------------------------------------------------------------\n" + "Symbol: FOO [=m]\n" + "Prompt: Foo bus is used to drive the bar HW\n" + "Defined at drivers/pci/Kconfig:47\n" + "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" + "Location:\n" + " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" + " -> PCI support (PCI [=y])\n" + " -> PCI access mode ( [=y])\n" + "Selects: LIBCRC32\n" + "Selected by: BAR\n" + "-----------------------------------------------------------------\n" + "o The line 'Prompt:' shows the text used in the menu structure for\n" + " this CONFIG_ symbol\n" + "o The 'Defined at' line tell at what file / line number the symbol\n" + " is defined\n" + "o The 'Depends on:' line tell what symbols needs to be defined for\n" + " this symbol to be visible in the menu (selectable)\n" + "o The 'Location:' lines tell where in the menu structure this symbol\n" + " is located\n" + " A location followed by a [=y] indicate that this is a selectable\n" + " menu item - and current value is displayed inside brackets.\n" + "o The 'Selects:' line tell what symbol will be automatically\n" + " selected if this symbol is selected (y or m)\n" + "o The 'Selected by' line tell what symbol has selected this symbol\n" + "\n" + "Only relevant lines are shown.\n" + "\n\n" + "Search examples:\n" + "Examples: USB => find all CONFIG_ symbols containing USB\n" + " ^USB => find all CONFIG_ symbols starting with USB\n" + " USB$ => find all CONFIG_ symbols ending with USB\n" + "\n"); + +static int indent; +static struct menu *current_menu; +static int child_count; +static int single_menu_mode; + +static void conf(struct menu *menu); +static void conf_choice(struct menu *menu); +static void conf_string(struct menu *menu); +static void conf_load(void); +static void conf_save(void); +static void show_textbox(const char *title, const char *text, int r, int c); +static void show_helptext(const char *title, const char *text); +static void show_help(struct menu *menu); + +static void get_prompt_str(struct gstr *r, struct property *prop) +{ + int i, j; + struct menu *submenu[8], *menu; + + str_printf(r, _("Prompt: %s\n"), _(prop->text)); + str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, + prop->menu->lineno); + if (!expr_is_yes(prop->visible.expr)) { + str_append(r, _(" Depends on: ")); + expr_gstr_print(prop->visible.expr, r); + str_append(r, "\n"); + } + menu = prop->menu->parent; + for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) + submenu[i++] = menu; + if (i > 0) { + str_printf(r, _(" Location:\n")); + for (j = 4; --i >= 0; j += 2) { + menu = submenu[i]; + str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); + if (menu->sym) { + str_printf(r, " (%s [=%s])", menu->sym->name ? + menu->sym->name : _(""), + sym_get_string_value(menu->sym)); + } + str_append(r, "\n"); + } + } +} + +static void get_symbol_str(struct gstr *r, struct symbol *sym) +{ + bool hit; + struct property *prop; + + if (sym && sym->name) + str_printf(r, "Symbol: %s [=%s]\n", sym->name, + sym_get_string_value(sym)); + for_all_prompts(sym, prop) + get_prompt_str(r, prop); + hit = false; + for_all_properties(sym, prop, P_SELECT) { + if (!hit) { + str_append(r, " Selects: "); + hit = true; + } else + str_printf(r, " && "); + expr_gstr_print(prop->expr, r); + } + if (hit) + str_append(r, "\n"); + if (sym->rev_dep.expr) { + str_append(r, _(" Selected by: ")); + expr_gstr_print(sym->rev_dep.expr, r); + str_append(r, "\n"); + } + str_append(r, "\n\n"); +} + +static struct gstr get_relations_str(struct symbol **sym_arr) +{ + struct symbol *sym; + struct gstr res = str_new(); + int i; + + for (i = 0; sym_arr && (sym = sym_arr[i]); i++) + get_symbol_str(&res, sym); + if (!i) + str_append(&res, _("No matches found.\n")); + return res; +} + +static char filename[PATH_MAX+1]; +static void set_config_filename(const char *config_filename) +{ + static char menu_backtitle[PATH_MAX+128]; + int size; + struct symbol *sym; + + sym = sym_lookup("ADKVERSION", 0); + sym_calc_value(sym); + size = snprintf(menu_backtitle, sizeof(menu_backtitle), + _("%s - OpenADK v%s Configuration"), + config_filename, sym_get_string_value(sym)); + if (size >= sizeof(menu_backtitle)) + menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; + set_dialog_backtitle(menu_backtitle); + + size = snprintf(filename, sizeof(filename), "%s", config_filename); + if (size >= sizeof(filename)) + filename[sizeof(filename)-1] = '\0'; +} + + +static void search_conf(void) +{ + struct symbol **sym_arr; + struct gstr res; + char *dialog_input; + int dres; +again: + dialog_clear(); + dres = dialog_inputbox(_("Search Configuration Parameter"), + _("Enter CONFIG_ (sub)string to search for " + "(with or without \"CONFIG\")"), + 10, 75, ""); + switch (dres) { + case 0: + break; + case 1: + show_helptext(_("Search Configuration"), search_help); + goto again; + default: + return; + } + + /* strip CONFIG_ if necessary */ + dialog_input = dialog_input_result; + if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) + dialog_input += 7; + + sym_arr = sym_re_search(dialog_input); + res = get_relations_str(sym_arr); + free(sym_arr); + show_textbox(_("Search Results"), str_get(&res), 0, 0); + str_free(&res); +} + +static void build_conf(struct menu *menu) +{ + struct symbol *sym; + struct property *prop; + struct menu *child; + int type, tmp, doint = 2; + tristate val; + char ch; + + if (!menu_is_visible(menu)) + return; + + sym = menu->sym; + prop = menu->prompt; + if (!sym) { + if (prop && menu != current_menu) { + const char *prompt = menu_get_prompt(menu); + switch (prop->type) { + case P_MENU: + child_count++; + prompt = _(prompt); + if (single_menu_mode) { + item_make("%s%*c%s", + menu->data ? "-->" : "++>", + indent + 1, ' ', prompt); + } else + item_make(" %*c%s --->", indent + 1, ' ', prompt); + + item_set_tag('m'); + item_set_data(menu); + if (single_menu_mode && menu->data) + goto conf_childs; + return; + case P_COMMENT: + if (prompt) { + child_count++; + item_make(" %*c*** %s ***", indent + 1, ' ', _(prompt)); + item_set_tag(':'); + item_set_data(menu); + } + break; + default: + if (prompt) { + child_count++; + item_make("---%*c%s", indent + 1, ' ', _(prompt)); + item_set_tag(':'); + item_set_data(menu); + } + } + } else + doint = 0; + goto conf_childs; + } + + type = sym_get_type(sym); + if (sym_is_choice(sym)) { + struct symbol *def_sym = sym_get_choice_value(sym); + struct menu *def_menu = NULL; + + child_count++; + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child) && child->sym == def_sym) + def_menu = child; + } + + val = sym_get_tristate_value(sym); + if (sym_is_changable(sym)) { + switch (type) { + case S_BOOLEAN: + item_make("[%c]", val == no ? ' ' : '*'); + break; + case S_TRISTATE: + switch (val) { + case yes: ch = '*'; break; + case mod: ch = 'M'; break; + default: ch = ' '; break; + } + item_make("<%c>", ch); + break; + } + item_set_tag('t'); + item_set_data(menu); + } else { + item_make(" "); + item_set_tag(def_menu ? 't' : ':'); + item_set_data(menu); + } + + item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); + if (val == yes) { + if (def_menu) { + item_add_str(" (%s)", _(menu_get_prompt(def_menu))); + item_add_str(" --->"); + if (def_menu->list) { + indent += 2; + build_conf(def_menu); + indent -= 2; + } + } + return; + } + } else { + if (menu == current_menu) { + item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); + item_set_tag(':'); + item_set_data(menu); + goto conf_childs; + } + child_count++; + val = sym_get_tristate_value(sym); + if (sym_is_choice_value(sym) && val == yes) { + item_make(" "); + item_set_tag(':'); + item_set_data(menu); + } else { + switch (type) { + case S_BOOLEAN: + if (sym_is_changable(sym)) + item_make("[%c]", val == no ? ' ' : '*'); + else + item_make("-%c-", val == no ? ' ' : '*'); + item_set_tag('t'); + item_set_data(menu); + break; + case S_TRISTATE: + switch (val) { + case yes: ch = '*'; break; + case mod: ch = 'M'; break; + default: ch = ' '; break; + } + if (sym_is_changable(sym)) { + if (sym->rev_dep.tri == mod) + item_make("{%c}", ch); + else + item_make("<%c>", ch); + } else + item_make("-%c-", ch); + item_set_tag('t'); + item_set_data(menu); + break; + default: + tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */ + item_make("(%s)", sym_get_string_value(sym)); + tmp = indent - tmp + 4; + if (tmp < 0) + tmp = 0; + item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)), + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : _(" (NEW)")); + item_set_tag('s'); + item_set_data(menu); + goto conf_childs; + } + } + item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)), + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : _(" (NEW)")); + if (menu->prompt->type == P_MENU) { + item_add_str(" --->"); + return; + } + } + +conf_childs: + indent += doint; + for (child = menu->list; child; child = child->next) + build_conf(child); + indent -= doint; +} + +static void conf(struct menu *menu) +{ + struct menu *submenu; + const char *prompt = menu_get_prompt(menu); + struct symbol *sym; + struct menu *active_menu = NULL; + int res; + int s_scroll = 0; + + while (1) { + item_reset(); + current_menu = menu; + build_conf(menu); + if (!child_count) + break; + if (menu == &rootmenu) { + item_make("--- "); + item_set_tag(':'); + item_make(_(" Load an Alternate Configuration File")); + item_set_tag('L'); + item_make(_(" Save an Alternate Configuration File")); + item_set_tag('S'); + } + dialog_clear(); + res = dialog_menu(prompt ? _(prompt) : _("Main Menu"), + _(menu_instructions), + active_menu, &s_scroll); + if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) + break; + if (!item_activate_selected()) + continue; + if (!item_tag()) + continue; + + submenu = item_data(); + active_menu = item_data(); + if (submenu) + sym = submenu->sym; + else + sym = NULL; + + switch (res) { + case 0: + switch (item_tag()) { + case 'm': + if (single_menu_mode) + submenu->data = (void *) (long) !submenu->data; + else + conf(submenu); + break; + case 't': + if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) + conf_choice(submenu); + else if (submenu->prompt->type == P_MENU) + conf(submenu); + break; + case 's': + conf_string(submenu); + break; + case 'L': + conf_load(); + break; + case 'S': + conf_save(); + break; + } + break; + case 2: + if (sym) + show_help(submenu); + else + show_helptext(_("README"), _(mconf_readme)); + break; + case 3: + if (item_is_tag('t')) { + if (sym_set_tristate_value(sym, yes)) + break; + if (sym_set_tristate_value(sym, mod)) + show_textbox(NULL, setmod_text, 6, 74); + } + break; + case 4: + if (item_is_tag('t')) + sym_set_tristate_value(sym, no); + break; + case 5: + if (item_is_tag('t')) + sym_set_tristate_value(sym, mod); + break; + case 6: + if (item_is_tag('t')) + sym_toggle_tristate_value(sym); + else if (item_is_tag('m')) + conf(submenu); + break; + case 7: + search_conf(); + break; + } + } +} + +static void show_textbox(const char *title, const char *text, int r, int c) +{ + dialog_clear(); + dialog_textbox(title, text, r, c); +} + +static void show_helptext(const char *title, const char *text) +{ + show_textbox(title, text, 0, 0); +} + +static void show_help(struct menu *menu) +{ + struct gstr help = str_new(); + struct symbol *sym = menu->sym; + + if (menu_has_help(menu)) + { + if (sym->name) { + str_printf(&help, "CONFIG_%s:\n\n", sym->name); + str_append(&help, _(menu_get_help(menu))); + str_append(&help, "\n"); + } + } else { + str_append(&help, nohelp_text); + } + get_symbol_str(&help, sym); + show_helptext(_(menu_get_prompt(menu)), str_get(&help)); + str_free(&help); +} + +static void conf_choice(struct menu *menu) +{ + const char *prompt = _(menu_get_prompt(menu)); + struct menu *child; + struct symbol *active; + + active = sym_get_choice_value(menu->sym); + while (1) { + int res; + int selected; + item_reset(); + + current_menu = menu; + for (child = menu->list; child; child = child->next) { + if (!menu_is_visible(child)) + continue; + if (child->sym) + item_make("%s", _(menu_get_prompt(child))); + else { + item_make("*** %s ***", _(menu_get_prompt(child))); + item_set_tag(':'); + } + item_set_data(child); + if (child->sym == active) + item_set_selected(1); + if (child->sym == sym_get_choice_value(menu->sym)) + item_set_tag('X'); + } + dialog_clear(); + res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"), + _(radiolist_instructions), + 15, 70, 6); + selected = item_activate_selected(); + switch (res) { + case 0: + if (selected) { + child = item_data(); + if (!child->sym) + break; + + sym_set_tristate_value(child->sym, yes); + } + return; + case 1: + if (selected) { + child = item_data(); + show_help(child); + active = child->sym; + } else + show_help(menu); + break; + case KEY_ESC: + return; + case -ERRDISPLAYTOOSMALL: + return; + } + } +} + +static void conf_string(struct menu *menu) +{ + const char *prompt = menu_get_prompt(menu); + + while (1) { + int res; + const char *heading; + + switch (sym_get_type(menu->sym)) { + case S_INT: + heading = _(inputbox_instructions_int); + break; + case S_HEX: + heading = _(inputbox_instructions_hex); + break; + case S_STRING: + heading = _(inputbox_instructions_string); + break; + default: + heading = _("Internal mconf error!"); + } + dialog_clear(); + res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"), + heading, 10, 75, + sym_get_string_value(menu->sym)); + switch (res) { + case 0: + if (sym_set_string_value(menu->sym, dialog_input_result)) + return; + show_textbox(NULL, _("You have made an invalid entry."), 5, 43); + break; + case 1: + show_help(menu); + break; + case KEY_ESC: + return; + } + } +} + +static void conf_load(void) +{ + + while (1) { + int res; + dialog_clear(); + res = dialog_inputbox(NULL, load_config_text, + 11, 55, filename); + switch(res) { + case 0: + if (!dialog_input_result[0]) + return; + if (!conf_read(dialog_input_result)) { + set_config_filename(dialog_input_result); + sym_set_change_count(1); + return; + } + show_textbox(NULL, _("File does not exist!"), 5, 38); + break; + case 1: + show_helptext(_("Load Alternate Configuration"), load_config_help); + break; + case KEY_ESC: + return; + } + } +} + +static void conf_save(void) +{ + while (1) { + int res; + dialog_clear(); + res = dialog_inputbox(NULL, save_config_text, + 11, 55, filename); + switch(res) { + case 0: + if (!dialog_input_result[0]) + return; + if (!conf_write(dialog_input_result)) { + set_config_filename(dialog_input_result); + return; + } + show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60); + break; + case 1: + show_helptext(_("Save Alternate Configuration"), save_config_help); + break; + case KEY_ESC: + return; + } + } +} + +int main(int ac, char **av) +{ + int saved_x, saved_y; + char *mode; + int res; + +#ifndef KBUILD_NO_NLS + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); +#endif + + conf_parse(av[1]); + conf_read(NULL); + + mode = getenv("MENUCONFIG_MODE"); + if (mode) { + if (!strcasecmp(mode, "single_menu")) + single_menu_mode = 1; + } + + initscr(); + + getyx(stdscr, saved_y, saved_x); + if (init_dialog(NULL)) { + fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); + fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n")); + return 1; + } + + set_config_filename(conf_get_configname()); + do { + conf(&rootmenu); + dialog_clear(); + if (conf_get_changed()) + res = dialog_yesno(NULL, + _("Do you wish to save your " + "new OpenADK configuration?\n" + " to continue."), + 6, 60); + else + res = -1; + } while (res == KEY_ESC); + end_dialog(saved_x, saved_y); + + switch (res) { + case 0: + if (conf_write(filename)) { + fprintf(stderr, _("\n\n" + "Error during writing of the OpenADK configuration.\n" + "Your OpenADK configuration changes were NOT saved." + "\n\n")); + return 1; + } + case -1: + printf(_("\n\n" + "*** End of OpenADK configuration.\n" + "*** Execute 'make' to build the firmware or try 'make help'." + "\n\n")); + break; + default: + fprintf(stderr, _("\n\n" + "Your OpenADK configuration changes were NOT saved." + "\n\n")); + } + + return 0; +} + diff --git a/adk/config/menu.c b/adk/config/menu.c new file mode 100644 index 000000000..3e6405ac2 --- /dev/null +++ b/adk/config/menu.c @@ -0,0 +1,533 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +static const char nohelp_text[] = N_( + "There is no help available for this OpenADK option.\n"); + +struct menu rootmenu; +static struct menu **last_entry_ptr; + +struct file *file_list; +struct file *current_file; + +void menu_warn(struct menu *menu, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); +} + +static void prop_warn(struct property *prop, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); +} + +void menu_init(void) +{ + current_entry = current_menu = &rootmenu; + last_entry_ptr = &rootmenu.list; +} + +void menu_add_entry(struct symbol *sym) +{ + struct menu *menu; + + menu = malloc(sizeof(*menu)); + memset(menu, 0, sizeof(*menu)); + menu->sym = sym; + menu->parent = current_menu; + menu->file = current_file; + menu->lineno = zconf_lineno(); + + *last_entry_ptr = menu; + last_entry_ptr = &menu->next; + current_entry = menu; +} + +void menu_end_entry(void) +{ +} + +struct menu *menu_add_menu(void) +{ + menu_end_entry(); + last_entry_ptr = ¤t_entry->list; + return current_menu = current_entry; +} + +void menu_end_menu(void) +{ + last_entry_ptr = ¤t_menu->next; + current_menu = current_menu->parent; +} + +static struct expr *menu_check_dep(struct expr *e) +{ + if (!e) + return e; + + switch (e->type) { + case E_NOT: + e->left.expr = menu_check_dep(e->left.expr); + break; + case E_OR: + case E_AND: + e->left.expr = menu_check_dep(e->left.expr); + e->right.expr = menu_check_dep(e->right.expr); + break; + case E_SYMBOL: + /* change 'm' into 'm' && MODULES */ + if (e->left.sym == &symbol_mod) + return expr_alloc_and(e, expr_alloc_symbol(modules_sym)); + break; + default: + break; + } + return e; +} + +void menu_add_dep(struct expr *dep) +{ + current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); +} + +void menu_set_type(int type) +{ + struct symbol *sym = current_entry->sym; + + if (sym->type == type) + return; + if (sym->type == S_UNKNOWN) { + sym->type = type; + return; + } + menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'", + sym->name ? sym->name : "", + sym_type_name(sym->type), sym_type_name(type)); +} + +struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) +{ + struct property *prop = prop_alloc(type, current_entry->sym); + + prop->menu = current_entry; + prop->expr = expr; + prop->visible.expr = menu_check_dep(dep); + + if (prompt) { + if (isspace(*prompt)) { + prop_warn(prop, "leading whitespace ignored"); + while (isspace(*prompt)) + prompt++; + } + if (current_entry->prompt) + prop_warn(prop, "prompt redefined"); + current_entry->prompt = prop; + } + prop->text = prompt; + + return prop; +} + +struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep) +{ + return menu_add_prop(type, prompt, NULL, dep); +} + +void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) +{ + menu_add_prop(type, NULL, expr, dep); +} + +void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) +{ + menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); +} + +void menu_add_option(int token, char *arg) +{ + struct property *prop; + + switch (token) { + case T_OPT_MODULES: + prop = prop_alloc(P_DEFAULT, modules_sym); + prop->expr = expr_alloc_symbol(current_entry->sym); + break; + case T_OPT_DEFCONFIG_LIST: + if (!sym_defconfig_list) + sym_defconfig_list = current_entry->sym; + else if (sym_defconfig_list != current_entry->sym) + zconf_error("trying to redefine defconfig symbol"); + break; + case T_OPT_ENV: + prop_add_env(arg); + break; + } +} + +static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) +{ + return sym2->type == S_INT || sym2->type == S_HEX || + (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); +} + +static void sym_check_prop(struct symbol *sym) +{ + struct property *prop; + struct symbol *sym2; + for (prop = sym->prop; prop; prop = prop->next) { + switch (prop->type) { + case P_DEFAULT: + if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) && + prop->expr->type != E_SYMBOL) + prop_warn(prop, + "default for config symbol '%'" + " must be a single symbol", sym->name); + break; + case P_SELECT: + sym2 = prop_get_symbol(prop); + if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) + prop_warn(prop, + "config symbol '%s' uses select, but is " + "not boolean or tristate", sym->name); + else if (sym2->type != S_UNKNOWN && + sym2->type != S_BOOLEAN && + sym2->type != S_TRISTATE) + prop_warn(prop, + "'%s' has wrong type. 'select' only " + "accept arguments of boolean and " + "tristate type", sym2->name); + break; + case P_RANGE: + if (sym->type != S_INT && sym->type != S_HEX) + prop_warn(prop, "range is only allowed " + "for int or hex symbols"); + if (!menu_range_valid_sym(sym, prop->expr->left.sym) || + !menu_range_valid_sym(sym, prop->expr->right.sym)) + prop_warn(prop, "range is invalid"); + break; + default: + ; + } + } +} + +void menu_finalize(struct menu *parent) +{ + struct menu *menu, *last_menu; + struct symbol *sym; + struct property *prop; + struct expr *parentdep, *basedep, *dep, *dep2, **ep; + + sym = parent->sym; + if (parent->list) { + if (sym && sym_is_choice(sym)) { + if (sym->type == S_UNKNOWN) { + /* find the first choice value to find out choice type */ + current_entry = parent; + for (menu = parent->list; menu; menu = menu->next) { + if (menu->sym && menu->sym->type != S_UNKNOWN) { + menu_set_type(menu->sym->type); + break; + } + } + } + /* set the type of the remaining choice values */ + for (menu = parent->list; menu; menu = menu->next) { + current_entry = menu; + if (menu->sym && menu->sym->type == S_UNKNOWN) + menu_set_type(sym->type); + } + parentdep = expr_alloc_symbol(sym); + } else if (parent->prompt) + parentdep = parent->prompt->visible.expr; + else + parentdep = parent->dep; + + for (menu = parent->list; menu; menu = menu->next) { + basedep = expr_transform(menu->dep); + basedep = expr_alloc_and(expr_copy(parentdep), basedep); + basedep = expr_eliminate_dups(basedep); + menu->dep = basedep; + if (menu->sym) + prop = menu->sym->prop; + else + prop = menu->prompt; + for (; prop; prop = prop->next) { + if (prop->menu != menu) + continue; + dep = expr_transform(prop->visible.expr); + dep = expr_alloc_and(expr_copy(basedep), dep); + dep = expr_eliminate_dups(dep); + if (menu->sym && menu->sym->type != S_TRISTATE) + dep = expr_trans_bool(dep); + prop->visible.expr = dep; + if (prop->type == P_SELECT) { + struct symbol *es = prop_get_symbol(prop); + es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, + expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); + } + } + } + for (menu = parent->list; menu; menu = menu->next) + menu_finalize(menu); + } else if (sym) { + basedep = parent->prompt ? parent->prompt->visible.expr : NULL; + basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); + basedep = expr_eliminate_dups(expr_transform(basedep)); + last_menu = NULL; + for (menu = parent->next; menu; menu = menu->next) { + dep = menu->prompt ? menu->prompt->visible.expr : menu->dep; + if (!expr_contains_symbol(dep, sym)) + break; + if (expr_depends_symbol(dep, sym)) + goto next; + dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no); + dep = expr_eliminate_dups(expr_transform(dep)); + dep2 = expr_copy(basedep); + expr_eliminate_eq(&dep, &dep2); + expr_free(dep); + if (!expr_is_yes(dep2)) { + expr_free(dep2); + break; + } + expr_free(dep2); + next: + menu_finalize(menu); + menu->parent = parent; + last_menu = menu; + } + if (last_menu) { + parent->list = parent->next; + parent->next = last_menu->next; + last_menu->next = NULL; + } + } + for (menu = parent->list; menu; menu = menu->next) { + if (sym && sym_is_choice(sym) && + menu->sym && !sym_is_choice_value(menu->sym)) { + current_entry = menu; + menu->sym->flags |= SYMBOL_CHOICEVAL; + if (!menu->prompt) + menu_warn(menu, "choice value must have a prompt"); + for (prop = menu->sym->prop; prop; prop = prop->next) { + if (prop->type == P_DEFAULT) + prop_warn(prop, "defaults for choice " + "values not supported"); + if (prop->menu == menu) + continue; + if (prop->type == P_PROMPT && + prop->menu->parent->sym != sym) + prop_warn(prop, "choice value used outside its choice group"); + } + /* Non-tristate choice values of tristate choices must + * depend on the choice being set to Y. The choice + * values' dependencies were propagated to their + * properties above, so the change here must be re- + * propagated. + */ + if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) { + basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes); + menu->dep = expr_alloc_and(basedep, menu->dep); + for (prop = menu->sym->prop; prop; prop = prop->next) { + if (prop->menu != menu) + continue; + prop->visible.expr = expr_alloc_and(expr_copy(basedep), + prop->visible.expr); + } + } + menu_add_symbol(P_CHOICE, sym, NULL); + prop = sym_get_choice_prop(sym); + for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr) + ; + *ep = expr_alloc_one(E_LIST, NULL); + (*ep)->right.sym = menu->sym; + } + if (menu->list && (!menu->prompt || !menu->prompt->text)) { + for (last_menu = menu->list; ; last_menu = last_menu->next) { + last_menu->parent = parent; + if (!last_menu->next) + break; + } + last_menu->next = menu->next; + menu->next = menu->list; + menu->list = NULL; + } + } + + if (sym && !(sym->flags & SYMBOL_WARNED)) { + if (sym->type == S_UNKNOWN) + menu_warn(parent, "config symbol defined without type"); + + if (sym_is_choice(sym) && !parent->prompt) + menu_warn(parent, "choice must have a prompt"); + + /* Check properties connected to this symbol */ + sym_check_prop(sym); + sym->flags |= SYMBOL_WARNED; + } + + if (sym && !sym_is_optional(sym) && parent->prompt) { + sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr, + expr_alloc_and(parent->prompt->visible.expr, + expr_alloc_symbol(&symbol_mod))); + } +} + +bool menu_is_visible(struct menu *menu) +{ + struct menu *child; + struct symbol *sym; + tristate visible; + + if (!menu->prompt) + return false; + sym = menu->sym; + if (sym) { + sym_calc_value(sym); + visible = menu->prompt->visible.tri; + } else + visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr); + + if (visible != no) + return true; + if (!sym || sym_get_tristate_value(menu->sym) == no) + return false; + + for (child = menu->list; child; child = child->next) + if (menu_is_visible(child)) + return true; + return false; +} + +const char *menu_get_prompt(struct menu *menu) +{ + if (menu->prompt) + return menu->prompt->text; + else if (menu->sym) + return menu->sym->name; + return NULL; +} + +struct menu *menu_get_root_menu(struct menu *menu) +{ + return &rootmenu; +} + +struct menu *menu_get_parent_menu(struct menu *menu) +{ + enum prop_type type; + + for (; menu != &rootmenu; menu = menu->parent) { + type = menu->prompt ? menu->prompt->type : 0; + if (type == P_MENU) + break; + } + return menu; +} + +bool menu_has_help(struct menu *menu) +{ + return menu->help != NULL; +} + +const char *menu_get_help(struct menu *menu) +{ + if (menu->help) + return menu->help; + else + return ""; +} + +static void get_prompt_str(struct gstr *r, struct property *prop) +{ + int i, j; + struct menu *submenu[8], *menu; + + str_printf(r, _("Prompt: %s\n"), _(prop->text)); + str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, + prop->menu->lineno); + if (!expr_is_yes(prop->visible.expr)) { + str_append(r, _(" Depends on: ")); + expr_gstr_print(prop->visible.expr, r); + str_append(r, "\n"); + } + menu = prop->menu->parent; + for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) + submenu[i++] = menu; + if (i > 0) { + str_printf(r, _(" Location:\n")); + for (j = 4; --i >= 0; j += 2) { + menu = submenu[i]; + str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); + if (menu->sym) { + str_printf(r, " (%s [=%s])", menu->sym->name ? + menu->sym->name : _(""), + sym_get_string_value(menu->sym)); + } + str_append(r, "\n"); + } + } +} + +void get_symbol_str(struct gstr *r, struct symbol *sym) +{ + bool hit; + struct property *prop; + + if (sym && sym->name) + str_printf(r, "Symbol: %s [=%s]\n", sym->name, + sym_get_string_value(sym)); + for_all_prompts(sym, prop) + get_prompt_str(r, prop); + hit = false; + for_all_properties(sym, prop, P_SELECT) { + if (!hit) { + str_append(r, " Selects: "); + hit = true; + } else + str_printf(r, " && "); + expr_gstr_print(prop->expr, r); + } + if (hit) + str_append(r, "\n"); + if (sym->rev_dep.expr) { + str_append(r, _(" Selected by: ")); + expr_gstr_print(sym->rev_dep.expr, r); + str_append(r, "\n"); + } + str_append(r, "\n\n"); +} + +void menu_get_ext_help(struct menu *menu, struct gstr *help) +{ + struct symbol *sym = menu->sym; + + if (menu_has_help(menu)) { + if (sym->name) { + str_printf(help, "CONFIG_%s:\n\n", sym->name); + str_append(help, _(menu_get_help(menu))); + str_append(help, "\n"); + } + } else { + str_append(help, nohelp_text); + } + if (sym) + get_symbol_str(help, sym); +} diff --git a/adk/config/symbol.c b/adk/config/symbol.c new file mode 100644 index 000000000..18f3e5c33 --- /dev/null +++ b/adk/config/symbol.c @@ -0,0 +1,973 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +struct symbol symbol_yes = { + .name = "y", + .curr = { "y", yes }, + .flags = SYMBOL_CONST|SYMBOL_VALID, +}, symbol_mod = { + .name = "m", + .curr = { "m", mod }, + .flags = SYMBOL_CONST|SYMBOL_VALID, +}, symbol_no = { + .name = "n", + .curr = { "n", no }, + .flags = SYMBOL_CONST|SYMBOL_VALID, +}, symbol_empty = { + .name = "", + .curr = { "", no }, + .flags = SYMBOL_VALID, +}; + +struct symbol *sym_defconfig_list; +struct symbol *modules_sym; +tristate modules_val; + +struct expr *sym_env_list; + +void sym_add_default(struct symbol *sym, const char *def) +{ + struct property *prop = prop_alloc(P_DEFAULT, sym); + + prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST)); +} + +void sym_init(void) +{ + struct symbol *sym; + struct utsname uts; + static bool inited = false; + + if (inited) + return; + inited = true; + + uname(&uts); + + sym = sym_lookup("UNAME_RELEASE", 0); + sym->type = S_STRING; + sym->flags |= SYMBOL_AUTO; + sym_add_default(sym, uts.release); +} + +enum symbol_type sym_get_type(struct symbol *sym) +{ + enum symbol_type type = sym->type; + + if (type == S_TRISTATE) { + if (sym_is_choice_value(sym) && sym->visible == yes) + type = S_BOOLEAN; + else if (modules_val == no) + type = S_BOOLEAN; + } + return type; +} + +const char *sym_type_name(enum symbol_type type) +{ + switch (type) { + case S_BOOLEAN: + return "boolean"; + case S_TRISTATE: + return "tristate"; + case S_INT: + return "integer"; + case S_HEX: + return "hex"; + case S_STRING: + return "string"; + case S_UNKNOWN: + return "unknown"; + case S_OTHER: + break; + } + return "???"; +} + +struct property *sym_get_choice_prop(struct symbol *sym) +{ + struct property *prop; + + for_all_choices(sym, prop) + return prop; + return NULL; +} + +struct property *sym_get_env_prop(struct symbol *sym) +{ + struct property *prop; + + for_all_properties(sym, prop, P_ENV) + return prop; + return NULL; +} + +struct property *sym_get_default_prop(struct symbol *sym) +{ + struct property *prop; + + for_all_defaults(sym, prop) { + prop->visible.tri = expr_calc_value(prop->visible.expr); + if (prop->visible.tri != no) + return prop; + } + return NULL; +} + +struct property *sym_get_range_prop(struct symbol *sym) +{ + struct property *prop; + + for_all_properties(sym, prop, P_RANGE) { + prop->visible.tri = expr_calc_value(prop->visible.expr); + if (prop->visible.tri != no) + return prop; + } + return NULL; +} + +static int sym_get_range_val(struct symbol *sym, int base) +{ + sym_calc_value(sym); + switch (sym->type) { + case S_INT: + base = 10; + break; + case S_HEX: + base = 16; + break; + default: + break; + } + return strtol(sym->curr.val, NULL, base); +} + +static void sym_validate_range(struct symbol *sym) +{ + struct property *prop; + int base, val, val2; + char str[64]; + + switch (sym->type) { + case S_INT: + base = 10; + break; + case S_HEX: + base = 16; + break; + default: + return; + } + prop = sym_get_range_prop(sym); + if (!prop) + return; + val = strtol(sym->curr.val, NULL, base); + val2 = sym_get_range_val(prop->expr->left.sym, base); + if (val >= val2) { + val2 = sym_get_range_val(prop->expr->right.sym, base); + if (val <= val2) + return; + } + if (sym->type == S_INT) + sprintf(str, "%d", val2); + else + sprintf(str, "0x%x", val2); + sym->curr.val = strdup(str); +} + +static void sym_calc_visibility(struct symbol *sym) +{ + struct property *prop; + tristate tri; + + /* any prompt visible? */ + tri = no; + for_all_prompts(sym, prop) { + prop->visible.tri = expr_calc_value(prop->visible.expr); + tri = EXPR_OR(tri, prop->visible.tri); + } + if (tri == mod && (sym->type != S_TRISTATE || modules_val == no)) + tri = yes; + if (sym->visible != tri) { + sym->visible = tri; + sym_set_changed(sym); + } + if (sym_is_choice_value(sym)) + return; + tri = no; + if (sym->rev_dep.expr) + tri = expr_calc_value(sym->rev_dep.expr); + if (tri == mod && sym_get_type(sym) == S_BOOLEAN) + tri = yes; + if (sym->rev_dep.tri != tri) { + sym->rev_dep.tri = tri; + sym_set_changed(sym); + } +} + +static struct symbol *sym_calc_choice(struct symbol *sym) +{ + struct symbol *def_sym; + struct property *prop; + struct expr *e; + + /* is the user choice visible? */ + def_sym = sym->def[S_DEF_USER].val; + if (def_sym) { + sym_calc_visibility(def_sym); + if (def_sym->visible != no) + return def_sym; + } + + /* any of the defaults visible? */ + for_all_defaults(sym, prop) { + prop->visible.tri = expr_calc_value(prop->visible.expr); + if (prop->visible.tri == no) + continue; + def_sym = prop_get_symbol(prop); + sym_calc_visibility(def_sym); + if (def_sym->visible != no) + return def_sym; + } + + /* just get the first visible value */ + prop = sym_get_choice_prop(sym); + expr_list_for_each_sym(prop->expr, e, def_sym) { + sym_calc_visibility(def_sym); + if (def_sym->visible != no) + return def_sym; + } + + /* no choice? reset tristate value */ + sym->curr.tri = no; + return NULL; +} + +void sym_calc_value(struct symbol *sym) +{ + struct symbol_value newval, oldval; + struct property *prop; + struct expr *e; + + if (!sym) + return; + + if (sym->flags & SYMBOL_VALID) + return; + sym->flags |= SYMBOL_VALID; + + oldval = sym->curr; + + switch (sym->type) { + case S_INT: + case S_HEX: + case S_STRING: + newval = symbol_empty.curr; + break; + case S_BOOLEAN: + case S_TRISTATE: + newval = symbol_no.curr; + break; + default: + sym->curr.val = sym->name; + sym->curr.tri = no; + return; + } + if (!sym_is_choice_value(sym)) + sym->flags &= ~SYMBOL_WRITE; + + sym_calc_visibility(sym); + + /* set default if recursively called */ + sym->curr = newval; + + switch (sym_get_type(sym)) { + case S_BOOLEAN: + case S_TRISTATE: + if (sym_is_choice_value(sym) && sym->visible == yes) { + prop = sym_get_choice_prop(sym); + newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no; + } else { + if (sym->visible != no) { + /* if the symbol is visible use the user value + * if available, otherwise try the default value + */ + sym->flags |= SYMBOL_WRITE; + if (sym_has_value(sym)) { + newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri, + sym->visible); + goto calc_newval; + } + } + if (sym->rev_dep.tri != no) + sym->flags |= SYMBOL_WRITE; + if (!sym_is_choice(sym)) { + prop = sym_get_default_prop(sym); + if (prop) { + sym->flags |= SYMBOL_WRITE; + newval.tri = EXPR_AND(expr_calc_value(prop->expr), + prop->visible.tri); + } + } + calc_newval: + newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); + } + if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) + newval.tri = yes; + break; + case S_STRING: + case S_HEX: + case S_INT: + if (sym->visible != no) { + sym->flags |= SYMBOL_WRITE; + if (sym_has_value(sym)) { + newval.val = sym->def[S_DEF_USER].val; + break; + } + } + prop = sym_get_default_prop(sym); + if (prop) { + struct symbol *ds = prop_get_symbol(prop); + if (ds) { + sym->flags |= SYMBOL_WRITE; + sym_calc_value(ds); + newval.val = ds->curr.val; + } + } + break; + default: + ; + } + + sym->curr = newval; + if (sym_is_choice(sym) && newval.tri == yes) + sym->curr.val = sym_calc_choice(sym); + sym_validate_range(sym); + + if (memcmp(&oldval, &sym->curr, sizeof(oldval))) { + sym_set_changed(sym); + if (modules_sym == sym) { + sym_set_all_changed(); + modules_val = modules_sym->curr.tri; + } + } + + if (sym_is_choice(sym)) { + struct symbol *choice_sym; + int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); + + prop = sym_get_choice_prop(sym); + expr_list_for_each_sym(prop->expr, e, choice_sym) { + choice_sym->flags |= flags; + if (flags & SYMBOL_CHANGED) + sym_set_changed(choice_sym); + } + } + + if (sym->flags & SYMBOL_AUTO) + sym->flags &= ~SYMBOL_WRITE; +} + +void sym_clear_all_valid(void) +{ + struct symbol *sym; + int i; + + for_all_symbols(i, sym) + sym->flags &= ~SYMBOL_VALID; + sym_add_change_count(1); + if (modules_sym) + sym_calc_value(modules_sym); +} + +void sym_set_changed(struct symbol *sym) +{ + struct property *prop; + + sym->flags |= SYMBOL_CHANGED; + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->menu) + prop->menu->flags |= MENU_CHANGED; + } +} + +void sym_set_all_changed(void) +{ + struct symbol *sym; + int i; + + for_all_symbols(i, sym) + sym_set_changed(sym); +} + +bool sym_tristate_within_range(struct symbol *sym, tristate val) +{ + int type = sym_get_type(sym); + + if (sym->visible == no) + return false; + + if (type != S_BOOLEAN && type != S_TRISTATE) + return false; + + if (type == S_BOOLEAN && val == mod) + return false; + if (sym->visible <= sym->rev_dep.tri) + return false; + if (sym_is_choice_value(sym) && sym->visible == yes) + return val == yes; + return val >= sym->rev_dep.tri && val <= sym->visible; +} + +bool sym_set_tristate_value(struct symbol *sym, tristate val) +{ + tristate oldval = sym_get_tristate_value(sym); + + if (oldval != val && !sym_tristate_within_range(sym, val)) + return false; + + if (!(sym->flags & SYMBOL_DEF_USER)) { + sym->flags |= SYMBOL_DEF_USER; + sym_set_changed(sym); + } + /* + * setting a choice value also resets the new flag of the choice + * symbol and all other choice values. + */ + if (sym_is_choice_value(sym) && val == yes) { + struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); + struct property *prop; + struct expr *e; + + cs->def[S_DEF_USER].val = sym; + cs->flags |= SYMBOL_DEF_USER; + prop = sym_get_choice_prop(cs); + for (e = prop->expr; e; e = e->left.expr) { + if (e->right.sym->visible != no) + e->right.sym->flags |= SYMBOL_DEF_USER; + } + } + + sym->def[S_DEF_USER].tri = val; + if (oldval != val) + sym_clear_all_valid(); + + return true; +} + +tristate sym_toggle_tristate_value(struct symbol *sym) +{ + tristate oldval, newval; + + oldval = newval = sym_get_tristate_value(sym); + do { + switch (newval) { + case no: + newval = mod; + break; + case mod: + newval = yes; + break; + case yes: + newval = no; + break; + } + if (sym_set_tristate_value(sym, newval)) + break; + } while (oldval != newval); + return newval; +} + +bool sym_string_valid(struct symbol *sym, const char *str) +{ + signed char ch; + + switch (sym->type) { + case S_STRING: + return true; + case S_INT: + ch = *str++; + if (ch == '-') + ch = *str++; + if (!isdigit(ch)) + return false; + if (ch == '0' && *str != 0) + return false; + while ((ch = *str++)) { + if (!isdigit(ch)) + return false; + } + return true; + case S_HEX: + if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) + str += 2; + ch = *str++; + do { + if (!isxdigit(ch)) + return false; + } while ((ch = *str++)); + return true; + case S_BOOLEAN: + case S_TRISTATE: + switch (str[0]) { + case 'y': case 'Y': + case 'm': case 'M': + case 'n': case 'N': + return true; + } + return false; + default: + return false; + } +} + +bool sym_string_within_range(struct symbol *sym, const char *str) +{ + struct property *prop; + int val; + + switch (sym->type) { + case S_STRING: + return sym_string_valid(sym, str); + case S_INT: + if (!sym_string_valid(sym, str)) + return false; + prop = sym_get_range_prop(sym); + if (!prop) + return true; + val = strtol(str, NULL, 10); + return val >= sym_get_range_val(prop->expr->left.sym, 10) && + val <= sym_get_range_val(prop->expr->right.sym, 10); + case S_HEX: + if (!sym_string_valid(sym, str)) + return false; + prop = sym_get_range_prop(sym); + if (!prop) + return true; + val = strtol(str, NULL, 16); + return val >= sym_get_range_val(prop->expr->left.sym, 16) && + val <= sym_get_range_val(prop->expr->right.sym, 16); + case S_BOOLEAN: + case S_TRISTATE: + switch (str[0]) { + case 'y': case 'Y': + return sym_tristate_within_range(sym, yes); + case 'm': case 'M': + return sym_tristate_within_range(sym, mod); + case 'n': case 'N': + return sym_tristate_within_range(sym, no); + } + return false; + default: + return false; + } +} + +bool sym_set_string_value(struct symbol *sym, const char *newval) +{ + const char *oldval; + char *val; + int size; + + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (newval[0]) { + case 'y': case 'Y': + return sym_set_tristate_value(sym, yes); + case 'm': case 'M': + return sym_set_tristate_value(sym, mod); + case 'n': case 'N': + return sym_set_tristate_value(sym, no); + } + return false; + default: + ; + } + + if (!sym_string_within_range(sym, newval)) + return false; + + if (!(sym->flags & SYMBOL_DEF_USER)) { + sym->flags |= SYMBOL_DEF_USER; + sym_set_changed(sym); + } + + oldval = sym->def[S_DEF_USER].val; + size = strlen(newval) + 1; + if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { + size += 2; + sym->def[S_DEF_USER].val = val = malloc(size); + *val++ = '0'; + *val++ = 'x'; + } else if (!oldval || strcmp(oldval, newval)) + sym->def[S_DEF_USER].val = val = malloc(size); + else + return true; + + strcpy(val, newval); + free((void *)oldval); + sym_clear_all_valid(); + + return true; +} + +const char *sym_get_string_value(struct symbol *sym) +{ + tristate val; + + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + val = sym_get_tristate_value(sym); + switch (val) { + case no: + return "n"; + case mod: + return "m"; + case yes: + return "y"; + } + break; + default: + ; + } + return (const char *)sym->curr.val; +} + +bool sym_is_changable(struct symbol *sym) +{ + return sym->visible > sym->rev_dep.tri; +} + +struct symbol *sym_lookup(const char *name, int flags) +{ + struct symbol *symbol; + const char *ptr; + char *new_name; + int hash = 0; + + if (name) { + if (name[0] && !name[1]) { + switch (name[0]) { + case 'y': return &symbol_yes; + case 'm': return &symbol_mod; + case 'n': return &symbol_no; + } + } + for (ptr = name; *ptr; ptr++) + hash += *ptr; + hash &= 0xff; + + for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { + if (!strcmp(symbol->name, name) && + (flags ? symbol->flags & flags + : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) + return symbol; + } + new_name = strdup(name); + } else { + new_name = NULL; + hash = 256; + } + + symbol = malloc(sizeof(*symbol)); + memset(symbol, 0, sizeof(*symbol)); + symbol->name = new_name; + symbol->type = S_UNKNOWN; + symbol->flags |= flags; + + symbol->next = symbol_hash[hash]; + symbol_hash[hash] = symbol; + + return symbol; +} + +struct symbol *sym_find(const char *name) +{ + struct symbol *symbol = NULL; + const char *ptr; + int hash = 0; + + if (!name) + return NULL; + + if (name[0] && !name[1]) { + switch (name[0]) { + case 'y': return &symbol_yes; + case 'm': return &symbol_mod; + case 'n': return &symbol_no; + } + } + for (ptr = name; *ptr; ptr++) + hash += *ptr; + hash &= 0xff; + + for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { + if (!strcmp(symbol->name, name) && + !(symbol->flags & SYMBOL_CONST)) + break; + } + + return symbol; +} + +struct symbol **sym_re_search(const char *pattern) +{ + struct symbol *sym, **sym_arr = NULL; + int i, cnt, size; + regex_t re; + + cnt = size = 0; + /* Skip if empty */ + if (strlen(pattern) == 0) + return NULL; + if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE)) + return NULL; + + for_all_symbols(i, sym) { + if (sym->flags & SYMBOL_CONST || !sym->name) + continue; + if (regexec(&re, sym->name, 0, NULL, 0)) + continue; + if (cnt + 1 >= size) { + void *tmp = sym_arr; + size += 16; + sym_arr = realloc(sym_arr, size * sizeof(struct symbol *)); + if (!sym_arr) { + free(tmp); + return NULL; + } + } + sym_arr[cnt++] = sym; + } + if (sym_arr) + sym_arr[cnt] = NULL; + regfree(&re); + + return sym_arr; +} + + +static struct symbol *sym_check_expr_deps(struct expr *e) +{ + struct symbol *sym; + + if (!e) + return NULL; + switch (e->type) { + case E_OR: + case E_AND: + sym = sym_check_expr_deps(e->left.expr); + if (sym) + return sym; + return sym_check_expr_deps(e->right.expr); + case E_NOT: + return sym_check_expr_deps(e->left.expr); + case E_EQUAL: + case E_UNEQUAL: + sym = sym_check_deps(e->left.sym); + if (sym) + return sym; + return sym_check_deps(e->right.sym); + case E_SYMBOL: + return sym_check_deps(e->left.sym); + default: + break; + } + printf("Oops! How to check %d?\n", e->type); + return NULL; +} + +/* return NULL when dependencies are OK */ +static struct symbol *sym_check_sym_deps(struct symbol *sym) +{ + struct symbol *sym2; + struct property *prop; + + sym2 = sym_check_expr_deps(sym->rev_dep.expr); + if (sym2) + return sym2; + + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->type == P_CHOICE || prop->type == P_SELECT) + continue; + sym2 = sym_check_expr_deps(prop->visible.expr); + if (sym2) + break; + if (prop->type != P_DEFAULT || sym_is_choice(sym)) + continue; + sym2 = sym_check_expr_deps(prop->expr); + if (sym2) + break; + } + + return sym2; +} + +static struct symbol *sym_check_choice_deps(struct symbol *choice) +{ + struct symbol *sym, *sym2; + struct property *prop; + struct expr *e; + + prop = sym_get_choice_prop(choice); + expr_list_for_each_sym(prop->expr, e, sym) + sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); + + choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); + sym2 = sym_check_sym_deps(choice); + choice->flags &= ~SYMBOL_CHECK; + if (sym2) + goto out; + + expr_list_for_each_sym(prop->expr, e, sym) { + sym2 = sym_check_sym_deps(sym); + if (sym2) { + fprintf(stderr, " -> %s", sym->name); + break; + } + } +out: + expr_list_for_each_sym(prop->expr, e, sym) + sym->flags &= ~SYMBOL_CHECK; + + if (sym2 && sym_is_choice_value(sym2) && + prop_get_symbol(sym_get_choice_prop(sym2)) == choice) + sym2 = choice; + + return sym2; +} + +struct symbol *sym_check_deps(struct symbol *sym) +{ + struct symbol *sym2; + struct property *prop; + + if (sym->flags & SYMBOL_CHECK) { + fprintf(stderr, "%s:%d:error: found recursive dependency: %s", + sym->prop->file->name, sym->prop->lineno, + sym->name ? sym->name : ""); + return sym; + } + if (sym->flags & SYMBOL_CHECKED) + return NULL; + + if (sym_is_choice_value(sym)) { + /* for choice groups start the check with main choice symbol */ + prop = sym_get_choice_prop(sym); + sym2 = sym_check_deps(prop_get_symbol(prop)); + } else if (sym_is_choice(sym)) { + sym2 = sym_check_choice_deps(sym); + } else { + sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); + sym2 = sym_check_sym_deps(sym); + sym->flags &= ~SYMBOL_CHECK; + } + + if (sym2) { + fprintf(stderr, " -> %s", sym->name ? sym->name : ""); + if (sym2 == sym) { + fprintf(stderr, "\n"); + zconfnerrs++; + sym2 = NULL; + } + } + + return sym2; +} + +struct property *prop_alloc(enum prop_type type, struct symbol *sym) +{ + struct property *prop; + struct property **propp; + + prop = malloc(sizeof(*prop)); + memset(prop, 0, sizeof(*prop)); + prop->type = type; + prop->sym = sym; + prop->file = current_file; + prop->lineno = zconf_lineno(); + + /* append property to the prop list of symbol */ + if (sym) { + for (propp = &sym->prop; *propp; propp = &(*propp)->next) + ; + *propp = prop; + } + + return prop; +} + +struct symbol *prop_get_symbol(struct property *prop) +{ + if (prop->expr && (prop->expr->type == E_SYMBOL || + prop->expr->type == E_LIST)) + return prop->expr->left.sym; + return NULL; +} + +const char *prop_get_type_name(enum prop_type type) +{ + switch (type) { + case P_PROMPT: + return "prompt"; + case P_ENV: + return "env"; + case P_COMMENT: + return "comment"; + case P_MENU: + return "menu"; + case P_DEFAULT: + return "default"; + case P_CHOICE: + return "choice"; + case P_SELECT: + return "select"; + case P_RANGE: + return "range"; + case P_UNKNOWN: + break; + } + return "unknown"; +} + +void prop_add_env(const char *env) +{ + struct symbol *sym, *sym2; + struct property *prop; + char *p; + + sym = current_entry->sym; + sym->flags |= SYMBOL_AUTO; + for_all_properties(sym, prop, P_ENV) { + sym2 = prop_get_symbol(prop); + if (strcmp(sym2->name, env)) + menu_warn(current_entry, "redefining environment symbol from %s", + sym2->name); + return; + } + + prop = prop_alloc(P_ENV, sym); + prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST)); + + sym_env_list = expr_alloc_one(E_LIST, sym_env_list); + sym_env_list->right.sym = sym; + + p = getenv(env); + if (p) + sym_add_default(sym, p); + else + menu_warn(current_entry, "environment variable %s undefined", env); +} diff --git a/adk/config/util.c b/adk/config/util.c new file mode 100644 index 000000000..b6b2a46af --- /dev/null +++ b/adk/config/util.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2002-2005 Roman Zippel + * Copyright (C) 2002-2005 Sam Ravnborg + * + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include "lkc.h" + +/* file already present in list? If not add it */ +struct file *file_lookup(const char *name) +{ + struct file *file; + + for (file = file_list; file; file = file->next) { + if (!strcmp(name, file->name)) + return file; + } + + file = malloc(sizeof(*file)); + memset(file, 0, sizeof(*file)); + file->name = strdup(name); + file->next = file_list; + file_list = file; + return file; +} + +/* write a dependency file as used by kbuild to track dependencies */ +int file_write_dep(const char *name) +{ + struct symbol *sym, *env_sym; + struct expr *e; + struct file *file; + FILE *out; + + if (!name) + name = ".kconfig.d"; + out = fopen("..config.tmp", "w"); + if (!out) + return 1; + fprintf(out, "deps_config := \\\n"); + for (file = file_list; file; file = file->next) { + if (file->next) + fprintf(out, "\t%s \\\n", file->name); + else + fprintf(out, "\t%s\n", file->name); + } + fprintf(out, "\n%s: \\\n" + "\t$(deps_config)\n\n", conf_get_autoconfig_name()); + + expr_list_for_each_sym(sym_env_list, e, sym) { + struct property *prop; + const char *value; + + prop = sym_get_env_prop(sym); + env_sym = prop_get_symbol(prop); + if (!env_sym) + continue; + value = getenv(env_sym->name); + if (!value) + value = ""; + fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value); + fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name()); + fprintf(out, "endif\n"); + } + + fprintf(out, "\n$(deps_config): ;\n"); + fclose(out); + rename("..config.tmp", name); + return 0; +} + + +/* Allocate initial growable sting */ +struct gstr str_new(void) +{ + struct gstr gs; + gs.s = malloc(sizeof(char) * 64); + gs.len = 64; + strcpy(gs.s, "\0"); + return gs; +} + +/* Allocate and assign growable string */ +struct gstr str_assign(const char *s) +{ + struct gstr gs; + gs.s = strdup(s); + gs.len = strlen(s) + 1; + return gs; +} + +/* Free storage for growable string */ +void str_free(struct gstr *gs) +{ + if (gs->s) + free(gs->s); + gs->s = NULL; + gs->len = 0; +} + +/* Append to growable string */ +void str_append(struct gstr *gs, const char *s) +{ + size_t l; + if (s) { + l = strlen(gs->s) + strlen(s) + 1; + if (l > gs->len) { + gs->s = realloc(gs->s, l); + gs->len = l; + } + strcat(gs->s, s); + } +} + +/* Append printf formatted string to growable string */ +void str_printf(struct gstr *gs, const char *fmt, ...) +{ + va_list ap; + char s[10000]; /* big enough... */ + va_start(ap, fmt); + vsnprintf(s, sizeof(s), fmt, ap); + str_append(gs, s); + va_end(ap); +} + +/* Retrieve value of growable string */ +const char *str_get(struct gstr *gs) +{ + return gs->s; +} + diff --git a/adk/config/zconf.gperf b/adk/config/zconf.gperf new file mode 100644 index 000000000..25ef5d01c --- /dev/null +++ b/adk/config/zconf.gperf @@ -0,0 +1,44 @@ +%language=ANSI-C +%define hash-function-name kconf_id_hash +%define lookup-function-name kconf_id_lookup +%define string-pool-name kconf_id_strings +%compare-strncmp +%enum +%pic +%struct-type + +struct kconf_id; + +%% +mainmenu, T_MAINMENU, TF_COMMAND +menu, T_MENU, TF_COMMAND +endmenu, T_ENDMENU, TF_COMMAND +source, T_SOURCE, TF_COMMAND +choice, T_CHOICE, TF_COMMAND +endchoice, T_ENDCHOICE, TF_COMMAND +comment, T_COMMENT, TF_COMMAND +config, T_CONFIG, TF_COMMAND +menuconfig, T_MENUCONFIG, TF_COMMAND +help, T_HELP, TF_COMMAND +if, T_IF, TF_COMMAND|TF_PARAM +endif, T_ENDIF, TF_COMMAND +depends, T_DEPENDS, TF_COMMAND +optional, T_OPTIONAL, TF_COMMAND +default, T_DEFAULT, TF_COMMAND, S_UNKNOWN +prompt, T_PROMPT, TF_COMMAND +tristate, T_TYPE, TF_COMMAND, S_TRISTATE +def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE +bool, T_TYPE, TF_COMMAND, S_BOOLEAN +boolean, T_TYPE, TF_COMMAND, S_BOOLEAN +def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN +int, T_TYPE, TF_COMMAND, S_INT +hex, T_TYPE, TF_COMMAND, S_HEX +string, T_TYPE, TF_COMMAND, S_STRING +select, T_SELECT, TF_COMMAND +range, T_RANGE, TF_COMMAND +option, T_OPTION, TF_COMMAND +on, T_ON, TF_PARAM +modules, T_OPT_MODULES, TF_OPTION +defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION +env, T_OPT_ENV, TF_OPTION +%% diff --git a/adk/config/zconf.hash.c_shipped b/adk/config/zconf.hash.c_shipped new file mode 100644 index 000000000..5c73d5133 --- /dev/null +++ b/adk/config/zconf.hash.c_shipped @@ -0,0 +1,237 @@ +/* ANSI-C code produced by gperf version 3.0.3 */ +/* Command-line: gperf */ +/* Computed positions: -k'1,3' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +struct kconf_id; +/* maximum key range = 47, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +kconf_id_hash (register const char *str, register unsigned int len) +{ + static unsigned char asso_values[] = + { + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 11, 5, + 0, 0, 5, 49, 5, 20, 49, 49, 5, 20, + 5, 0, 30, 49, 0, 15, 0, 10, 0, 49, + 25, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval; +} + +struct kconf_id_strings_t + { + char kconf_id_strings_str2[sizeof("on")]; + char kconf_id_strings_str3[sizeof("env")]; + char kconf_id_strings_str5[sizeof("endif")]; + char kconf_id_strings_str6[sizeof("option")]; + char kconf_id_strings_str7[sizeof("endmenu")]; + char kconf_id_strings_str8[sizeof("optional")]; + char kconf_id_strings_str9[sizeof("endchoice")]; + char kconf_id_strings_str10[sizeof("range")]; + char kconf_id_strings_str11[sizeof("choice")]; + char kconf_id_strings_str12[sizeof("default")]; + char kconf_id_strings_str13[sizeof("def_bool")]; + char kconf_id_strings_str14[sizeof("help")]; + char kconf_id_strings_str15[sizeof("bool")]; + char kconf_id_strings_str16[sizeof("config")]; + char kconf_id_strings_str17[sizeof("def_tristate")]; + char kconf_id_strings_str18[sizeof("boolean")]; + char kconf_id_strings_str19[sizeof("defconfig_list")]; + char kconf_id_strings_str21[sizeof("string")]; + char kconf_id_strings_str22[sizeof("if")]; + char kconf_id_strings_str23[sizeof("int")]; + char kconf_id_strings_str26[sizeof("select")]; + char kconf_id_strings_str27[sizeof("modules")]; + char kconf_id_strings_str28[sizeof("tristate")]; + char kconf_id_strings_str29[sizeof("menu")]; + char kconf_id_strings_str31[sizeof("source")]; + char kconf_id_strings_str32[sizeof("comment")]; + char kconf_id_strings_str33[sizeof("hex")]; + char kconf_id_strings_str35[sizeof("menuconfig")]; + char kconf_id_strings_str36[sizeof("prompt")]; + char kconf_id_strings_str37[sizeof("depends")]; + char kconf_id_strings_str48[sizeof("mainmenu")]; + }; +static struct kconf_id_strings_t kconf_id_strings_contents = + { + "on", + "env", + "endif", + "option", + "endmenu", + "optional", + "endchoice", + "range", + "choice", + "default", + "def_bool", + "help", + "bool", + "config", + "def_tristate", + "boolean", + "defconfig_list", + "string", + "if", + "int", + "select", + "modules", + "tristate", + "menu", + "source", + "comment", + "hex", + "menuconfig", + "prompt", + "depends", + "mainmenu" + }; +#define kconf_id_strings ((const char *) &kconf_id_strings_contents) +#ifdef __GNUC__ +__inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +struct kconf_id * +kconf_id_lookup (register const char *str, register unsigned int len) +{ + enum + { + TOTAL_KEYWORDS = 31, + MIN_WORD_LENGTH = 2, + MAX_WORD_LENGTH = 14, + MIN_HASH_VALUE = 2, + MAX_HASH_VALUE = 48 + }; + + static struct kconf_id wordlist[] = + { + {-1}, {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_ON, TF_PARAM}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_OPT_ENV, TF_OPTION}, + {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_OPTION, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_OPTIONAL, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_RANGE, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_CHOICE, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_HELP, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str15, T_TYPE, TF_COMMAND, S_BOOLEAN}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_CONFIG, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_BOOLEAN}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19, T_OPT_DEFCONFIG_LIST,TF_OPTION}, + {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_TYPE, TF_COMMAND, S_STRING}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT}, + {-1}, {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SELECT, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND}, + {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SOURCE, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_TYPE, TF_COMMAND, S_HEX}, + {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_PROMPT, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_DEPENDS, TF_COMMAND}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = kconf_id_hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int o = wordlist[key].name; + if (o >= 0) + { + register const char *s = o + kconf_id_strings; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &wordlist[key]; + } + } + } + return 0; +} + diff --git a/adk/config/zconf.l b/adk/config/zconf.l new file mode 100644 index 000000000..21ff69c9a --- /dev/null +++ b/adk/config/zconf.l @@ -0,0 +1,359 @@ +%option backup nostdinit noyywrap never-interactive full ecs +%option 8bit backup nodefault perf-report perf-report +%option noinput +%x COMMAND HELP STRING PARAM +%{ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +#define START_STRSIZE 16 + +static struct { + struct file *file; + int lineno; +} current_pos; + +static char *text; +static int text_size, text_asize; + +struct buffer { + struct buffer *parent; + YY_BUFFER_STATE state; +}; + +struct buffer *current_buf; + +static int last_ts, first_ts; + +static void zconf_endhelp(void); +static void zconf_endfile(void); + +void new_string(void) +{ + text = malloc(START_STRSIZE); + text_asize = START_STRSIZE; + text_size = 0; + *text = 0; +} + +void append_string(const char *str, int size) +{ + int new_size = text_size + size + 1; + if (new_size > text_asize) { + new_size += START_STRSIZE - 1; + new_size &= -START_STRSIZE; + text = realloc(text, new_size); + text_asize = new_size; + } + memcpy(text + text_size, str, size); + text_size += size; + text[text_size] = 0; +} + +void alloc_string(const char *str, int size) +{ + text = malloc(size + 1); + memcpy(text, str, size); + text[size] = 0; +} +%} + +ws [ \n\t] +n [A-Za-z0-9_] + +%% + int str = 0; + int ts, i; + +[ \t]*#.*\n | +[ \t]*\n { + current_file->lineno++; + return T_EOL; +} +[ \t]*#.* + + +[ \t]+ { + BEGIN(COMMAND); +} + +. { + unput(yytext[0]); + BEGIN(COMMAND); +} + + +{ + {n}+ { + struct kconf_id *id = kconf_id_lookup(yytext, yyleng); + BEGIN(PARAM); + current_pos.file = current_file; + current_pos.lineno = current_file->lineno; + if (id && id->flags & TF_COMMAND) { + zconflval.id = id; + return id->token; + } + alloc_string(yytext, yyleng); + zconflval.string = text; + return T_WORD; + } + . + \n { + BEGIN(INITIAL); + current_file->lineno++; + return T_EOL; + } +} + +{ + "&&" return T_AND; + "||" return T_OR; + "(" return T_OPEN_PAREN; + ")" return T_CLOSE_PAREN; + "!" return T_NOT; + "=" return T_EQUAL; + "!=" return T_UNEQUAL; + \"|\' { + str = yytext[0]; + new_string(); + BEGIN(STRING); + } + \n BEGIN(INITIAL); current_file->lineno++; return T_EOL; + --- /* ignore */ + ({n}|[-/.])+ { + struct kconf_id *id = kconf_id_lookup(yytext, yyleng); + if (id && id->flags & TF_PARAM) { + zconflval.id = id; + return id->token; + } + alloc_string(yytext, yyleng); + zconflval.string = text; + return T_WORD; + } + #.* /* comment */ + \\\n current_file->lineno++; + . + <> { + BEGIN(INITIAL); + } +} + +{ + [^'"\\\n]+/\n { + append_string(yytext, yyleng); + zconflval.string = text; + return T_WORD_QUOTE; + } + [^'"\\\n]+ { + append_string(yytext, yyleng); + } + \\.?/\n { + append_string(yytext + 1, yyleng - 1); + zconflval.string = text; + return T_WORD_QUOTE; + } + \\.? { + append_string(yytext + 1, yyleng - 1); + } + \'|\" { + if (str == yytext[0]) { + BEGIN(PARAM); + zconflval.string = text; + return T_WORD_QUOTE; + } else + append_string(yytext, 1); + } + \n { + printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); + current_file->lineno++; + BEGIN(INITIAL); + return T_EOL; + } + <> { + BEGIN(INITIAL); + } +} + +{ + [ \t]+ { + ts = 0; + for (i = 0; i < yyleng; i++) { + if (yytext[i] == '\t') + ts = (ts & ~7) + 8; + else + ts++; + } + last_ts = ts; + if (first_ts) { + if (ts < first_ts) { + zconf_endhelp(); + return T_HELPTEXT; + } + ts -= first_ts; + while (ts > 8) { + append_string(" ", 8); + ts -= 8; + } + append_string(" ", ts); + } + } + [ \t]*\n/[^ \t\n] { + current_file->lineno++; + zconf_endhelp(); + return T_HELPTEXT; + } + [ \t]*\n { + current_file->lineno++; + append_string("\n", 1); + } + [^ \t\n].* { + while (yyleng) { + if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t')) + break; + yyleng--; + } + append_string(yytext, yyleng); + if (!first_ts) + first_ts = last_ts; + } + <> { + zconf_endhelp(); + return T_HELPTEXT; + } +} + +<> { + if (current_file) { + zconf_endfile(); + return T_EOL; + } + fclose(yyin); + yyterminate(); +} + +%% +void zconf_starthelp(void) +{ + new_string(); + last_ts = first_ts = 0; + BEGIN(HELP); +} + +static void zconf_endhelp(void) +{ + zconflval.string = text; + BEGIN(INITIAL); +} + + +/* + * Try to open specified file with following names: + * ./name + * $(srctree)/name + * The latter is used when srctree is separate from objtree + * when compiling the kernel. + * Return NULL if file is not found. + */ +FILE *zconf_fopen(const char *name) +{ + char *env, fullname[PATH_MAX+1]; + FILE *f; + + f = fopen(name, "r"); + if (!f && name != NULL && name[0] != '/') { + env = getenv(SRCTREE); + if (env) { + sprintf(fullname, "%s/%s", env, name); + f = fopen(fullname, "r"); + } + } + return f; +} + +void zconf_initscan(const char *name) +{ + yyin = zconf_fopen(name); + if (!yyin) { + printf("can't find file %s\n", name); + exit(1); + } + + current_buf = malloc(sizeof(*current_buf)); + memset(current_buf, 0, sizeof(*current_buf)); + + current_file = file_lookup(name); + current_file->lineno = 1; + current_file->flags = FILE_BUSY; +} + +void zconf_nextfile(const char *name) +{ + struct file *file = file_lookup(name); + struct buffer *buf = malloc(sizeof(*buf)); + memset(buf, 0, sizeof(*buf)); + + current_buf->state = YY_CURRENT_BUFFER; + yyin = zconf_fopen(name); + if (!yyin) { + printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); + exit(1); + } + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + buf->parent = current_buf; + current_buf = buf; + + if (file->flags & FILE_BUSY) { + printf("%s:%d: do not source '%s' from itself\n", + zconf_curname(), zconf_lineno(), name); + exit(1); + } + if (file->flags & FILE_SCANNED) { + printf("%s:%d: file '%s' is already sourced from '%s'\n", + zconf_curname(), zconf_lineno(), name, + file->parent->name); + exit(1); + } + file->flags |= FILE_BUSY; + file->lineno = 1; + file->parent = current_file; + current_file = file; +} + +static void zconf_endfile(void) +{ + struct buffer *parent; + + current_file->flags |= FILE_SCANNED; + current_file->flags &= ~FILE_BUSY; + current_file = current_file->parent; + + parent = current_buf->parent; + if (parent) { + fclose(yyin); + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer(parent->state); + } + free(current_buf); + current_buf = parent; +} + +int zconf_lineno(void) +{ + return current_pos.lineno; +} + +char *zconf_curname(void) +{ + return current_pos.file ? current_pos.file->name : ""; +} diff --git a/adk/config/zconf.tab.c_shipped b/adk/config/zconf.tab.c_shipped new file mode 100644 index 000000000..3bdcb3a97 --- /dev/null +++ b/adk/config/zconf.tab.c_shipped @@ -0,0 +1,2490 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.3" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* Substitute the variable and function names. */ +#define yyparse zconfparse +#define yylex zconflex +#define yyerror zconferror +#define yylval zconflval +#define yychar zconfchar +#define yydebug zconfdebug +#define yynerrs zconfnerrs + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_MAINMENU = 258, + T_MENU = 259, + T_ENDMENU = 260, + T_SOURCE = 261, + T_CHOICE = 262, + T_ENDCHOICE = 263, + T_COMMENT = 264, + T_CONFIG = 265, + T_MENUCONFIG = 266, + T_HELP = 267, + T_HELPTEXT = 268, + T_IF = 269, + T_ENDIF = 270, + T_DEPENDS = 271, + T_OPTIONAL = 272, + T_PROMPT = 273, + T_TYPE = 274, + T_DEFAULT = 275, + T_SELECT = 276, + T_RANGE = 277, + T_OPTION = 278, + T_ON = 279, + T_WORD = 280, + T_WORD_QUOTE = 281, + T_UNEQUAL = 282, + T_CLOSE_PAREN = 283, + T_OPEN_PAREN = 284, + T_EOL = 285, + T_OR = 286, + T_AND = 287, + T_EQUAL = 288, + T_NOT = 289 + }; +#endif +/* Tokens. */ +#define T_MAINMENU 258 +#define T_MENU 259 +#define T_ENDMENU 260 +#define T_SOURCE 261 +#define T_CHOICE 262 +#define T_ENDCHOICE 263 +#define T_COMMENT 264 +#define T_CONFIG 265 +#define T_MENUCONFIG 266 +#define T_HELP 267 +#define T_HELPTEXT 268 +#define T_IF 269 +#define T_ENDIF 270 +#define T_DEPENDS 271 +#define T_OPTIONAL 272 +#define T_PROMPT 273 +#define T_TYPE 274 +#define T_DEFAULT 275 +#define T_SELECT 276 +#define T_RANGE 277 +#define T_OPTION 278 +#define T_ON 279 +#define T_WORD 280 +#define T_WORD_QUOTE 281 +#define T_UNEQUAL 282 +#define T_CLOSE_PAREN 283 +#define T_OPEN_PAREN 284 +#define T_EOL 285 +#define T_OR 286 +#define T_AND 287 +#define T_EQUAL 288 +#define T_NOT 289 + + + + +/* Copy the first part of user declarations. */ + + +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +#include "zconf.hash.c" + +#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) + +#define PRINTD 0x0001 +#define DEBUG_PARSE 0x0002 + +int cdebug = PRINTD; + +extern int zconflex(void); +static void zconfprint(const char *err, ...); +static void zconf_error(const char *err, ...); +static void zconferror(const char *err); +static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); + +struct symbol *symbol_hash[257]; + +static struct menu *current_menu, *current_entry; + +#define YYDEBUG 0 +#if YYDEBUG +#define YYERROR_VERBOSE +#endif + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE + +{ + char *string; + struct file *file; + struct symbol *symbol; + struct expr *expr; + struct menu *menu; + struct kconf_id *id; +} +/* Line 187 of yacc.c. */ + + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 216 of yacc.c. */ + + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int i) +#else +static int +YYID (i) + int i; +#endif +{ + return i; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 3 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 259 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 35 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 46 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 110 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 180 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 289 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 5, 6, 9, 12, 15, 20, 23, + 28, 33, 37, 39, 41, 43, 45, 47, 49, 51, + 53, 55, 57, 59, 61, 63, 67, 70, 74, 77, + 81, 84, 85, 88, 91, 94, 97, 100, 103, 107, + 112, 117, 122, 128, 132, 133, 137, 138, 141, 145, + 148, 150, 154, 155, 158, 161, 164, 167, 170, 175, + 179, 182, 187, 188, 191, 195, 197, 201, 202, 205, + 208, 211, 215, 218, 220, 224, 225, 228, 231, 234, + 238, 242, 245, 248, 251, 252, 255, 258, 261, 266, + 267, 270, 272, 274, 277, 280, 283, 285, 288, 289, + 292, 294, 298, 302, 306, 309, 313, 317, 319, 321, + 322 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 36, 0, -1, 37, -1, -1, 37, 39, -1, 37, + 53, -1, 37, 64, -1, 37, 3, 74, 76, -1, + 37, 75, -1, 37, 25, 1, 30, -1, 37, 38, + 1, 30, -1, 37, 1, 30, -1, 16, -1, 18, + -1, 19, -1, 21, -1, 17, -1, 22, -1, 20, + -1, 30, -1, 59, -1, 68, -1, 42, -1, 44, + -1, 66, -1, 25, 1, 30, -1, 1, 30, -1, + 10, 25, 30, -1, 41, 45, -1, 11, 25, 30, + -1, 43, 45, -1, -1, 45, 46, -1, 45, 47, + -1, 45, 72, -1, 45, 70, -1, 45, 40, -1, + 45, 30, -1, 19, 73, 30, -1, 18, 74, 77, + 30, -1, 20, 78, 77, 30, -1, 21, 25, 77, + 30, -1, 22, 79, 79, 77, 30, -1, 23, 48, + 30, -1, -1, 48, 25, 49, -1, -1, 33, 74, + -1, 7, 80, 30, -1, 50, 54, -1, 75, -1, + 51, 56, 52, -1, -1, 54, 55, -1, 54, 72, + -1, 54, 70, -1, 54, 30, -1, 54, 40, -1, + 18, 74, 77, 30, -1, 19, 73, 30, -1, 17, + 30, -1, 20, 25, 77, 30, -1, -1, 56, 39, + -1, 14, 78, 76, -1, 75, -1, 57, 60, 58, + -1, -1, 60, 39, -1, 60, 64, -1, 60, 53, + -1, 4, 74, 30, -1, 61, 71, -1, 75, -1, + 62, 65, 63, -1, -1, 65, 39, -1, 65, 64, + -1, 65, 53, -1, 6, 74, 30, -1, 9, 74, + 30, -1, 67, 71, -1, 12, 30, -1, 69, 13, + -1, -1, 71, 72, -1, 71, 30, -1, 71, 40, + -1, 16, 24, 78, 30, -1, -1, 74, 77, -1, + 25, -1, 26, -1, 5, 30, -1, 8, 30, -1, + 15, 30, -1, 30, -1, 76, 30, -1, -1, 14, + 78, -1, 79, -1, 79, 33, 79, -1, 79, 27, + 79, -1, 29, 78, 28, -1, 34, 78, -1, 78, + 31, 78, -1, 78, 32, 78, -1, 25, -1, 26, + -1, -1, 25, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 104, 104, 106, 108, 109, 110, 111, 112, 113, + 114, 118, 122, 122, 122, 122, 122, 122, 122, 126, + 127, 128, 129, 130, 131, 135, 136, 142, 150, 156, + 164, 174, 176, 177, 178, 179, 180, 181, 184, 192, + 198, 208, 214, 220, 223, 225, 236, 237, 242, 251, + 256, 264, 267, 269, 270, 271, 272, 273, 276, 282, + 293, 299, 309, 311, 316, 324, 332, 335, 337, 338, + 339, 344, 351, 356, 364, 367, 369, 370, 371, 374, + 382, 389, 396, 402, 409, 411, 412, 413, 416, 424, + 426, 431, 432, 435, 436, 437, 441, 442, 445, 446, + 449, 450, 451, 452, 453, 454, 455, 458, 459, 462, + 463 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU", + "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG", + "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", + "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE", + "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", + "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL", + "T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt", + "option_error", "config_entry_start", "config_stmt", + "menuconfig_entry_start", "menuconfig_stmt", "config_option_list", + "config_option", "symbol_option", "symbol_option_list", + "symbol_option_arg", "choice", "choice_entry", "choice_end", + "choice_stmt", "choice_option_list", "choice_option", "choice_block", + "if_entry", "if_end", "if_stmt", "if_block", "menu", "menu_entry", + "menu_end", "menu_stmt", "menu_block", "source_stmt", "comment", + "comment_stmt", "help_start", "help", "depends_list", "depends", + "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", "symbol", + "word_opt", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 35, 36, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 38, 38, 38, 38, 38, 38, 38, 39, + 39, 39, 39, 39, 39, 40, 40, 41, 42, 43, + 44, 45, 45, 45, 45, 45, 45, 45, 46, 46, + 46, 46, 46, 47, 48, 48, 49, 49, 50, 51, + 52, 53, 54, 54, 54, 54, 54, 54, 55, 55, + 55, 55, 56, 56, 57, 58, 59, 60, 60, 60, + 60, 61, 62, 63, 64, 65, 65, 65, 65, 66, + 67, 68, 69, 70, 71, 71, 71, 71, 72, 73, + 73, 74, 74, 75, 75, 75, 76, 76, 77, 77, + 78, 78, 78, 78, 78, 78, 78, 79, 79, 80, + 80 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 0, 2, 2, 2, 4, 2, 4, + 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 2, 3, 2, 3, + 2, 0, 2, 2, 2, 2, 2, 2, 3, 4, + 4, 4, 5, 3, 0, 3, 0, 2, 3, 2, + 1, 3, 0, 2, 2, 2, 2, 2, 4, 3, + 2, 4, 0, 2, 3, 1, 3, 0, 2, 2, + 2, 3, 2, 1, 3, 0, 2, 2, 2, 3, + 3, 2, 2, 2, 0, 2, 2, 2, 4, 0, + 2, 1, 1, 2, 2, 2, 1, 2, 0, 2, + 1, 3, 3, 3, 2, 3, 3, 1, 1, 0, + 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 3, 0, 0, 1, 0, 0, 0, 0, 0, 109, + 0, 0, 0, 0, 0, 0, 12, 16, 13, 14, + 18, 15, 17, 0, 19, 0, 4, 31, 22, 31, + 23, 52, 62, 5, 67, 20, 84, 75, 6, 24, + 84, 21, 8, 11, 91, 92, 0, 0, 93, 0, + 110, 0, 94, 0, 0, 0, 107, 108, 0, 0, + 0, 100, 95, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 96, 7, 71, 79, 48, 80, 27, + 29, 0, 104, 0, 0, 64, 0, 0, 9, 10, + 0, 0, 0, 0, 89, 0, 0, 0, 44, 0, + 37, 36, 32, 33, 0, 35, 34, 0, 0, 89, + 0, 56, 57, 53, 55, 54, 63, 51, 50, 68, + 70, 66, 69, 65, 86, 87, 85, 76, 78, 74, + 77, 73, 97, 103, 105, 106, 102, 101, 26, 82, + 0, 98, 0, 98, 98, 98, 0, 0, 0, 83, + 60, 98, 0, 98, 0, 0, 0, 38, 90, 0, + 0, 98, 46, 43, 25, 0, 59, 0, 88, 99, + 39, 40, 41, 0, 0, 45, 58, 61, 42, 47 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 1, 2, 25, 26, 101, 27, 28, 29, 30, + 65, 102, 103, 147, 175, 31, 32, 117, 33, 67, + 113, 68, 34, 121, 35, 69, 36, 37, 129, 38, + 71, 39, 40, 41, 104, 105, 70, 106, 142, 143, + 42, 74, 156, 60, 61, 51 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -80 +static const yytype_int16 yypact[] = +{ + -80, 2, 132, -80, -13, -1, -1, -2, -1, 9, + 33, -1, 27, 40, -3, 38, -80, -80, -80, -80, + -80, -80, -80, 71, -80, 77, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, 57, 61, -80, 63, + -80, 76, -80, 87, 101, 133, -80, -80, -3, -3, + 195, -6, -80, 136, 149, 39, 104, 65, 150, 5, + 194, 5, 167, -80, 176, -80, -80, -80, -80, -80, + -80, 68, -80, -3, -3, 176, 72, 72, -80, -80, + 177, 187, 78, -1, -1, -3, 196, 72, -80, 222, + -80, -80, -80, -80, 221, -80, -80, 205, -1, -1, + 211, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, 206, -80, -80, -80, -80, -80, + -3, 223, 209, 223, 197, 223, 72, 7, 210, -80, + -80, 223, 212, 223, 201, -3, 213, -80, -80, 214, + 215, 223, 208, -80, -80, 216, -80, 217, -80, 113, + -80, -80, -80, 218, -1, -80, -80, -80, -80, -80 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -80, -80, -80, -80, 122, -34, -80, -80, -80, -80, + 220, -80, -80, -80, -80, -80, -80, -80, 59, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, 125, + -80, -80, -80, -80, -80, 183, 219, 22, 142, -5, + 147, 192, 69, -54, -79, -80 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -82 +static const yytype_int16 yytable[] = +{ + 46, 47, 3, 49, 81, 82, 53, 136, 137, 6, + 7, 8, 9, 10, 11, 12, 13, 43, 146, 14, + 15, 86, 56, 57, 44, 45, 58, 87, 48, 134, + 135, 59, 162, 112, 50, 24, 125, 163, 125, -28, + 90, 144, -28, -28, -28, -28, -28, -28, -28, -28, + -28, 91, 54, -28, -28, 92, -28, 93, 94, 95, + 96, 97, 98, 52, 99, 55, 90, 161, 62, 100, + -49, -49, 63, -49, -49, -49, -49, 91, 64, -49, + -49, 92, 107, 108, 109, 110, 154, 73, 141, 115, + 99, 75, 126, 76, 126, 111, 133, 56, 57, 83, + 84, 169, 140, 151, -30, 90, 77, -30, -30, -30, + -30, -30, -30, -30, -30, -30, 91, 78, -30, -30, + 92, -30, 93, 94, 95, 96, 97, 98, 120, 99, + 128, 79, -2, 4, 100, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 83, 84, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 7, 8, 23, 10, 11, + 12, 13, 24, 80, 14, 15, 88, -81, 90, 179, + -81, -81, -81, -81, -81, -81, -81, -81, -81, 89, + 24, -81, -81, 92, -81, -81, -81, -81, -81, -81, + 116, 119, 99, 127, 122, 90, 130, 124, -72, -72, + -72, -72, -72, -72, -72, -72, 132, 138, -72, -72, + 92, 155, 158, 159, 160, 118, 123, 139, 131, 99, + 165, 145, 167, 148, 124, 73, 83, 84, 83, 84, + 173, 168, 83, 84, 149, 150, 153, 155, 84, 157, + 164, 174, 166, 170, 171, 172, 176, 177, 178, 66, + 114, 152, 85, 0, 0, 0, 0, 0, 0, 72 +}; + +static const yytype_int16 yycheck[] = +{ + 5, 6, 0, 8, 58, 59, 11, 86, 87, 4, + 5, 6, 7, 8, 9, 10, 11, 30, 97, 14, + 15, 27, 25, 26, 25, 26, 29, 33, 30, 83, + 84, 34, 25, 67, 25, 30, 70, 30, 72, 0, + 1, 95, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 25, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 30, 25, 25, 1, 146, 30, 30, + 5, 6, 1, 8, 9, 10, 11, 12, 1, 14, + 15, 16, 17, 18, 19, 20, 140, 30, 93, 67, + 25, 30, 70, 30, 72, 30, 28, 25, 26, 31, + 32, 155, 24, 108, 0, 1, 30, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 30, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 69, 25, + 71, 30, 0, 1, 30, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 31, 32, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 5, 6, 25, 8, 9, + 10, 11, 30, 30, 14, 15, 30, 0, 1, 174, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 30, + 30, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 68, 69, 25, 71, 69, 1, 71, 30, 4, 5, + 6, 7, 8, 9, 10, 11, 30, 30, 14, 15, + 16, 14, 143, 144, 145, 68, 69, 30, 71, 25, + 151, 25, 153, 1, 30, 30, 31, 32, 31, 32, + 161, 30, 31, 32, 13, 30, 25, 14, 32, 30, + 30, 33, 30, 30, 30, 30, 30, 30, 30, 29, + 67, 109, 60, -1, -1, -1, -1, -1, -1, 40 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 36, 37, 0, 1, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 25, 30, 38, 39, 41, 42, 43, + 44, 50, 51, 53, 57, 59, 61, 62, 64, 66, + 67, 68, 75, 30, 25, 26, 74, 74, 30, 74, + 25, 80, 30, 74, 25, 25, 25, 26, 29, 34, + 78, 79, 30, 1, 1, 45, 45, 54, 56, 60, + 71, 65, 71, 30, 76, 30, 30, 30, 30, 30, + 30, 78, 78, 31, 32, 76, 27, 33, 30, 30, + 1, 12, 16, 18, 19, 20, 21, 22, 23, 25, + 30, 40, 46, 47, 69, 70, 72, 17, 18, 19, + 20, 30, 40, 55, 70, 72, 39, 52, 75, 39, + 53, 58, 64, 75, 30, 40, 72, 39, 53, 63, + 64, 75, 30, 28, 78, 78, 79, 79, 30, 30, + 24, 74, 73, 74, 78, 25, 79, 48, 1, 13, + 30, 74, 73, 25, 78, 14, 77, 30, 77, 77, + 77, 79, 25, 30, 30, 77, 30, 77, 30, 78, + 30, 30, 30, 77, 33, 49, 30, 30, 30, 74 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +#else +static void +yy_stack_print (bottom, top) + yytype_int16 *bottom; + yytype_int16 *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + fprintf (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + fprintf (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + case 51: /* "choice_entry" */ + + { + fprintf(stderr, "%s:%d: missing end statement for this entry\n", + (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); + if (current_menu == (yyvaluep->menu)) + menu_end_menu(); +}; + + break; + case 57: /* "if_entry" */ + + { + fprintf(stderr, "%s:%d: missing end statement for this entry\n", + (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); + if (current_menu == (yyvaluep->menu)) + menu_end_menu(); +}; + + break; + case 62: /* "menu_entry" */ + + { + fprintf(stderr, "%s:%d: missing end statement for this entry\n", + (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); + if (current_menu == (yyvaluep->menu)) + menu_end_menu(); +}; + + break; + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The look-ahead symbol. */ +int yychar; + +/* The semantic value of the look-ahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + int yystate; + int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Look-ahead token as an internal (translated) token number. */ + int yytoken = 0; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss = yyssa; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp; + + + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + look-ahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to look-ahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a look-ahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 8: + + { zconf_error("unexpected end statement"); ;} + break; + + case 9: + + { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); ;} + break; + + case 10: + + { + zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[(2) - (4)].id)->name); +;} + break; + + case 11: + + { zconf_error("invalid statement"); ;} + break; + + case 25: + + { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;} + break; + + case 26: + + { zconf_error("invalid option"); ;} + break; + + case 27: + + { + struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); +;} + break; + + case 28: + + { + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 29: + + { + struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); +;} + break; + + case 30: + + { + if (current_entry->prompt) + current_entry->prompt->type = P_MENU; + else + zconfprint("warning: menuconfig statement without prompt"); + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 38: + + { + menu_set_type((yyvsp[(1) - (3)].id)->stype); + printd(DEBUG_PARSE, "%s:%d:type(%u)\n", + zconf_curname(), zconf_lineno(), + (yyvsp[(1) - (3)].id)->stype); +;} + break; + + case 39: + + { + menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 40: + + { + menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr)); + if ((yyvsp[(1) - (4)].id)->stype != S_UNKNOWN) + menu_set_type((yyvsp[(1) - (4)].id)->stype); + printd(DEBUG_PARSE, "%s:%d:default(%u)\n", + zconf_curname(), zconf_lineno(), + (yyvsp[(1) - (4)].id)->stype); +;} + break; + + case 41: + + { + menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); + printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 42: + + { + menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr)); + printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 45: + + { + struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string))); + if (id && id->flags & TF_OPTION) + menu_add_option(id->token, (yyvsp[(3) - (3)].string)); + else + zconfprint("warning: ignoring unknown option %s", (yyvsp[(2) - (3)].string)); + free((yyvsp[(2) - (3)].string)); +;} + break; + + case 46: + + { (yyval.string) = NULL; ;} + break; + + case 47: + + { (yyval.string) = (yyvsp[(2) - (2)].string); ;} + break; + + case 48: + + { + struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE); + sym->flags |= SYMBOL_AUTO; + menu_add_entry(sym); + menu_add_expr(P_CHOICE, NULL, NULL); + printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 49: + + { + (yyval.menu) = menu_add_menu(); +;} + break; + + case 50: + + { + if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); + } +;} + break; + + case 58: + + { + menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 59: + + { + if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) { + menu_set_type((yyvsp[(1) - (3)].id)->stype); + printd(DEBUG_PARSE, "%s:%d:type(%u)\n", + zconf_curname(), zconf_lineno(), + (yyvsp[(1) - (3)].id)->stype); + } else + YYERROR; +;} + break; + + case 60: + + { + current_entry->sym->flags |= SYMBOL_OPTIONAL; + printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 61: + + { + if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) { + menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); + printd(DEBUG_PARSE, "%s:%d:default\n", + zconf_curname(), zconf_lineno()); + } else + YYERROR; +;} + break; + + case 64: + + { + printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); + menu_add_entry(NULL); + menu_add_dep((yyvsp[(2) - (3)].expr)); + (yyval.menu) = menu_add_menu(); +;} + break; + + case 65: + + { + if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); + } +;} + break; + + case 71: + + { + menu_add_entry(NULL); + menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL); + printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 72: + + { + (yyval.menu) = menu_add_menu(); +;} + break; + + case 73: + + { + if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); + } +;} + break; + + case 79: + + { + printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); + zconf_nextfile((yyvsp[(2) - (3)].string)); +;} + break; + + case 80: + + { + menu_add_entry(NULL); + menu_add_prompt(P_COMMENT, (yyvsp[(2) - (3)].string), NULL); + printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 81: + + { + menu_end_entry(); +;} + break; + + case 82: + + { + printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); + zconf_starthelp(); +;} + break; + + case 83: + + { + current_entry->help = (yyvsp[(2) - (2)].string); +;} + break; + + case 88: + + { + menu_add_dep((yyvsp[(3) - (4)].expr)); + printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 90: + + { + menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr)); +;} + break; + + case 93: + + { (yyval.id) = (yyvsp[(1) - (2)].id); ;} + break; + + case 94: + + { (yyval.id) = (yyvsp[(1) - (2)].id); ;} + break; + + case 95: + + { (yyval.id) = (yyvsp[(1) - (2)].id); ;} + break; + + case 98: + + { (yyval.expr) = NULL; ;} + break; + + case 99: + + { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;} + break; + + case 100: + + { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;} + break; + + case 101: + + { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} + break; + + case 102: + + { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} + break; + + case 103: + + { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;} + break; + + case 104: + + { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;} + break; + + case 105: + + { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} + break; + + case 106: + + { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} + break; + + case 107: + + { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;} + break; + + case 108: + + { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;} + break; + + case 109: + + { (yyval.string) = NULL; ;} + break; + + +/* Line 1267 of yacc.c. */ + + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (yymsg); + } + else + { + yyerror (YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse look-ahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEOF && yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + + + +void conf_parse(const char *name) +{ + struct symbol *sym; + int i; + + zconf_initscan(name); + + sym_init(); + menu_init(); + modules_sym = sym_lookup(NULL, 0); + modules_sym->type = S_BOOLEAN; + modules_sym->flags |= SYMBOL_AUTO; + rootmenu.prompt = menu_add_prompt(P_MENU, "OpenADK Configuration", NULL); + +#if YYDEBUG + if (getenv("ZCONF_DEBUG")) + zconfdebug = 1; +#endif + zconfparse(); + if (zconfnerrs) + exit(1); + if (!modules_sym->prop) { + struct property *prop; + + prop = prop_alloc(P_DEFAULT, modules_sym); + prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); + } + menu_finalize(&rootmenu); + for_all_symbols(i, sym) { + if (sym_check_deps(sym)) + zconfnerrs++; + } + if (zconfnerrs) + exit(1); + sym_set_change_count(1); +} + +const char *zconf_tokenname(int token) +{ + switch (token) { + case T_MENU: return "menu"; + case T_ENDMENU: return "endmenu"; + case T_CHOICE: return "choice"; + case T_ENDCHOICE: return "endchoice"; + case T_IF: return "if"; + case T_ENDIF: return "endif"; + case T_DEPENDS: return "depends"; + } + return ""; +} + +static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken) +{ + if (id->token != endtoken) { + zconf_error("unexpected '%s' within %s block", + kconf_id_strings + id->name, zconf_tokenname(starttoken)); + zconfnerrs++; + return false; + } + if (current_menu->file != current_file) { + zconf_error("'%s' in different file than '%s'", + kconf_id_strings + id->name, zconf_tokenname(starttoken)); + fprintf(stderr, "%s:%d: location of the '%s'\n", + current_menu->file->name, current_menu->lineno, + zconf_tokenname(starttoken)); + zconfnerrs++; + return false; + } + return true; +} + +static void zconfprint(const char *err, ...) +{ + va_list ap; + + fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); + va_start(ap, err); + vfprintf(stderr, err, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +static void zconf_error(const char *err, ...) +{ + va_list ap; + + zconfnerrs++; + fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); + va_start(ap, err); + vfprintf(stderr, err, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +static void zconferror(const char *err) +{ +#if YYDEBUG + fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); +#endif +} + +void print_quoted_string(FILE *out, const char *str) +{ + const char *p; + int len; + + putc('"', out); + while ((p = strchr(str, '"'))) { + len = p - str; + if (len) + fprintf(out, "%.*s", len, str); + fputs("\\\"", out); + str = p + 1; + } + fputs(str, out); + putc('"', out); +} + +void print_symbol(FILE *out, struct menu *menu) +{ + struct symbol *sym = menu->sym; + struct property *prop; + + if (sym_is_choice(sym)) + fprintf(out, "choice\n"); + else + fprintf(out, "config %s\n", sym->name); + switch (sym->type) { + case S_BOOLEAN: + fputs(" boolean\n", out); + break; + case S_TRISTATE: + fputs(" tristate\n", out); + break; + case S_STRING: + fputs(" string\n", out); + break; + case S_INT: + fputs(" integer\n", out); + break; + case S_HEX: + fputs(" hex\n", out); + break; + default: + fputs(" ???\n", out); + break; + } + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->menu != menu) + continue; + switch (prop->type) { + case P_PROMPT: + fputs(" prompt ", out); + print_quoted_string(out, prop->text); + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } + fputc('\n', out); + break; + case P_DEFAULT: + fputs( " default ", out); + expr_fprint(prop->expr, out); + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } + fputc('\n', out); + break; + case P_CHOICE: + fputs(" #choice value\n", out); + break; + default: + fprintf(out, " unknown prop %d!\n", prop->type); + break; + } + } + if (menu->help) { + int len = strlen(menu->help); + while (menu->help[--len] == '\n') + menu->help[len] = 0; + fprintf(out, " help\n%s\n", menu->help); + } + fputc('\n', out); +} + +void zconfdump(FILE *out) +{ + struct property *prop; + struct symbol *sym; + struct menu *menu; + + menu = rootmenu.list; + while (menu) { + if ((sym = menu->sym)) + print_symbol(out, menu); + else if ((prop = menu->prompt)) { + switch (prop->type) { + case P_COMMENT: + fputs("\ncomment ", out); + print_quoted_string(out, prop->text); + fputs("\n", out); + break; + case P_MENU: + fputs("\nmenu ", out); + print_quoted_string(out, prop->text); + fputs("\n", out); + break; + default: + ; + } + if (!expr_is_yes(prop->visible.expr)) { + fputs(" depends ", out); + expr_fprint(prop->visible.expr, out); + fputc('\n', out); + } + fputs("\n", out); + } + + if (menu->list) + menu = menu->list; + else if (menu->next) + menu = menu->next; + else while ((menu = menu->parent)) { + if (menu->prompt && menu->prompt->type == P_MENU) + fputs("\nendmenu\n", out); + if (menu->next) { + menu = menu->next; + break; + } + } + } +} + +#include "lex.zconf.c" +#include "util.c" +#include "confdata.c" +#include "expr.c" +#include "symbol.c" +#include "menu.c" + diff --git a/adk/config/zconf.tab.h_shipped b/adk/config/zconf.tab.h_shipped new file mode 100644 index 000000000..1b17df414 --- /dev/null +++ b/adk/config/zconf.tab.h_shipped @@ -0,0 +1,133 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_MAINMENU = 258, + T_MENU = 259, + T_ENDMENU = 260, + T_SOURCE = 261, + T_CHOICE = 262, + T_ENDCHOICE = 263, + T_COMMENT = 264, + T_CONFIG = 265, + T_MENUCONFIG = 266, + T_HELP = 267, + T_HELPTEXT = 268, + T_IF = 269, + T_ENDIF = 270, + T_DEPENDS = 271, + T_OPTIONAL = 272, + T_PROMPT = 273, + T_TYPE = 274, + T_DEFAULT = 275, + T_SELECT = 276, + T_RANGE = 277, + T_OPTION = 278, + T_ON = 279, + T_WORD = 280, + T_WORD_QUOTE = 281, + T_UNEQUAL = 282, + T_CLOSE_PAREN = 283, + T_OPEN_PAREN = 284, + T_EOL = 285, + T_OR = 286, + T_AND = 287, + T_EQUAL = 288, + T_NOT = 289 + }; +#endif +/* Tokens. */ +#define T_MAINMENU 258 +#define T_MENU 259 +#define T_ENDMENU 260 +#define T_SOURCE 261 +#define T_CHOICE 262 +#define T_ENDCHOICE 263 +#define T_COMMENT 264 +#define T_CONFIG 265 +#define T_MENUCONFIG 266 +#define T_HELP 267 +#define T_HELPTEXT 268 +#define T_IF 269 +#define T_ENDIF 270 +#define T_DEPENDS 271 +#define T_OPTIONAL 272 +#define T_PROMPT 273 +#define T_TYPE 274 +#define T_DEFAULT 275 +#define T_SELECT 276 +#define T_RANGE 277 +#define T_OPTION 278 +#define T_ON 279 +#define T_WORD 280 +#define T_WORD_QUOTE 281 +#define T_UNEQUAL 282 +#define T_CLOSE_PAREN 283 +#define T_OPEN_PAREN 284 +#define T_EOL 285 +#define T_OR 286 +#define T_AND 287 +#define T_EQUAL 288 +#define T_NOT 289 + + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +#line 44 "zconf.y" +{ + char *string; + struct file *file; + struct symbol *symbol; + struct expr *expr; + struct menu *menu; + struct kconf_id *id; +} +/* Line 1489 of yacc.c. */ +#line 126 "zconf.tab.h" + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +extern YYSTYPE zconflval; + diff --git a/adk/config/zconf.y b/adk/config/zconf.y new file mode 100644 index 000000000..b4240c846 --- /dev/null +++ b/adk/config/zconf.y @@ -0,0 +1,706 @@ +%{ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +#include "zconf.hash.c" + +#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) + +#define PRINTD 0x0001 +#define DEBUG_PARSE 0x0002 + +int cdebug = PRINTD; + +extern int zconflex(void); +static void zconfprint(const char *err, ...); +static void zconf_error(const char *err, ...); +static void zconferror(const char *err); +static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); + +struct symbol *symbol_hash[257]; + +static struct menu *current_menu, *current_entry; + +#define YYDEBUG 0 +#if YYDEBUG +#define YYERROR_VERBOSE +#endif +%} +%expect 26 + +%union +{ + char *string; + struct file *file; + struct symbol *symbol; + struct expr *expr; + struct menu *menu; + struct kconf_id *id; +} + +%token T_MAINMENU +%token T_MENU +%token T_ENDMENU +%token T_SOURCE +%token T_CHOICE +%token T_ENDCHOICE +%token T_COMMENT +%token T_CONFIG +%token T_MENUCONFIG +%token T_HELP +%token T_HELPTEXT +%token T_IF +%token T_ENDIF +%token T_DEPENDS +%token T_OPTIONAL +%token T_PROMPT +%token T_TYPE +%token T_DEFAULT +%token T_SELECT +%token T_RANGE +%token T_OPTION +%token T_ON +%token T_WORD +%token T_WORD_QUOTE +%token T_UNEQUAL +%token T_CLOSE_PAREN +%token T_OPEN_PAREN +%token T_EOL + +%left T_OR +%left T_AND +%left T_EQUAL T_UNEQUAL +%nonassoc T_NOT + +%type prompt +%type symbol +%type expr +%type if_expr +%type end +%type option_name +%type if_entry menu_entry choice_entry +%type symbol_option_arg word_opt + +%destructor { + fprintf(stderr, "%s:%d: missing end statement for this entry\n", + $$->file->name, $$->lineno); + if (current_menu == $$) + menu_end_menu(); +} if_entry menu_entry choice_entry + +%% +input: stmt_list; + +stmt_list: + /* empty */ + | stmt_list common_stmt + | stmt_list choice_stmt + | stmt_list menu_stmt + | stmt_list T_MAINMENU prompt nl + | stmt_list end { zconf_error("unexpected end statement"); } + | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } + | stmt_list option_name error T_EOL +{ + zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name); +} + | stmt_list error T_EOL { zconf_error("invalid statement"); } +; + +option_name: + T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT +; + +common_stmt: + T_EOL + | if_stmt + | comment_stmt + | config_stmt + | menuconfig_stmt + | source_stmt +; + +option_error: + T_WORD error T_EOL { zconf_error("unknown option \"%s\"", $1); } + | error T_EOL { zconf_error("invalid option"); } +; + + +/* config/menuconfig entry */ + +config_entry_start: T_CONFIG T_WORD T_EOL +{ + struct symbol *sym = sym_lookup($2, 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2); +}; + +config_stmt: config_entry_start config_option_list +{ + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +}; + +menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL +{ + struct symbol *sym = sym_lookup($2, 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2); +}; + +menuconfig_stmt: menuconfig_entry_start config_option_list +{ + if (current_entry->prompt) + current_entry->prompt->type = P_MENU; + else + zconfprint("warning: menuconfig statement without prompt"); + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +}; + +config_option_list: + /* empty */ + | config_option_list config_option + | config_option_list symbol_option + | config_option_list depends + | config_option_list help + | config_option_list option_error + | config_option_list T_EOL +; + +config_option: T_TYPE prompt_stmt_opt T_EOL +{ + menu_set_type($1->stype); + printd(DEBUG_PARSE, "%s:%d:type(%u)\n", + zconf_curname(), zconf_lineno(), + $1->stype); +}; + +config_option: T_PROMPT prompt if_expr T_EOL +{ + menu_add_prompt(P_PROMPT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_DEFAULT expr if_expr T_EOL +{ + menu_add_expr(P_DEFAULT, $2, $3); + if ($1->stype != S_UNKNOWN) + menu_set_type($1->stype); + printd(DEBUG_PARSE, "%s:%d:default(%u)\n", + zconf_curname(), zconf_lineno(), + $1->stype); +}; + +config_option: T_SELECT T_WORD if_expr T_EOL +{ + menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3); + printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_RANGE symbol symbol if_expr T_EOL +{ + menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); + printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); +}; + +symbol_option: T_OPTION symbol_option_list T_EOL +; + +symbol_option_list: + /* empty */ + | symbol_option_list T_WORD symbol_option_arg +{ + struct kconf_id *id = kconf_id_lookup($2, strlen($2)); + if (id && id->flags & TF_OPTION) + menu_add_option(id->token, $3); + else + zconfprint("warning: ignoring unknown option %s", $2); + free($2); +}; + +symbol_option_arg: + /* empty */ { $$ = NULL; } + | T_EQUAL prompt { $$ = $2; } +; + +/* choice entry */ + +choice: T_CHOICE word_opt T_EOL +{ + struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE); + sym->flags |= SYMBOL_AUTO; + menu_add_entry(sym); + menu_add_expr(P_CHOICE, NULL, NULL); + printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); +}; + +choice_entry: choice choice_option_list +{ + $$ = menu_add_menu(); +}; + +choice_end: end +{ + if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); + } +}; + +choice_stmt: choice_entry choice_block choice_end +; + +choice_option_list: + /* empty */ + | choice_option_list choice_option + | choice_option_list depends + | choice_option_list help + | choice_option_list T_EOL + | choice_option_list option_error +; + +choice_option: T_PROMPT prompt if_expr T_EOL +{ + menu_add_prompt(P_PROMPT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_TYPE prompt_stmt_opt T_EOL +{ + if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) { + menu_set_type($1->stype); + printd(DEBUG_PARSE, "%s:%d:type(%u)\n", + zconf_curname(), zconf_lineno(), + $1->stype); + } else + YYERROR; +}; + +choice_option: T_OPTIONAL T_EOL +{ + current_entry->sym->flags |= SYMBOL_OPTIONAL; + printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_DEFAULT T_WORD if_expr T_EOL +{ + if ($1->stype == S_UNKNOWN) { + menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); + printd(DEBUG_PARSE, "%s:%d:default\n", + zconf_curname(), zconf_lineno()); + } else + YYERROR; +}; + +choice_block: + /* empty */ + | choice_block common_stmt +; + +/* if entry */ + +if_entry: T_IF expr nl +{ + printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); + menu_add_entry(NULL); + menu_add_dep($2); + $$ = menu_add_menu(); +}; + +if_end: end +{ + if (zconf_endtoken($1, T_IF, T_ENDIF)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); + } +}; + +if_stmt: if_entry if_block if_end +; + +if_block: + /* empty */ + | if_block common_stmt + | if_block menu_stmt + | if_block choice_stmt +; + +/* menu entry */ + +menu: T_MENU prompt T_EOL +{ + menu_add_entry(NULL); + menu_add_prompt(P_MENU, $2, NULL); + printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); +}; + +menu_entry: menu depends_list +{ + $$ = menu_add_menu(); +}; + +menu_end: end +{ + if (zconf_endtoken($1, T_MENU, T_ENDMENU)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); + } +}; + +menu_stmt: menu_entry menu_block menu_end +; + +menu_block: + /* empty */ + | menu_block common_stmt + | menu_block menu_stmt + | menu_block choice_stmt +; + +source_stmt: T_SOURCE prompt T_EOL +{ + printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); + zconf_nextfile($2); +}; + +/* comment entry */ + +comment: T_COMMENT prompt T_EOL +{ + menu_add_entry(NULL); + menu_add_prompt(P_COMMENT, $2, NULL); + printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); +}; + +comment_stmt: comment depends_list +{ + menu_end_entry(); +}; + +/* help option */ + +help_start: T_HELP T_EOL +{ + printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); + zconf_starthelp(); +}; + +help: help_start T_HELPTEXT +{ + current_entry->help = $2; +}; + +/* depends option */ + +depends_list: + /* empty */ + | depends_list depends + | depends_list T_EOL + | depends_list option_error +; + +depends: T_DEPENDS T_ON expr T_EOL +{ + menu_add_dep($3); + printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); +}; + +/* prompt statement */ + +prompt_stmt_opt: + /* empty */ + | prompt if_expr +{ + menu_add_prompt(P_PROMPT, $1, $2); +}; + +prompt: T_WORD + | T_WORD_QUOTE +; + +end: T_ENDMENU T_EOL { $$ = $1; } + | T_ENDCHOICE T_EOL { $$ = $1; } + | T_ENDIF T_EOL { $$ = $1; } +; + +nl: + T_EOL + | nl T_EOL +; + +if_expr: /* empty */ { $$ = NULL; } + | T_IF expr { $$ = $2; } +; + +expr: symbol { $$ = expr_alloc_symbol($1); } + | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); } + | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } + | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; } + | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); } + | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); } + | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); } +; + +symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); } + | T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); } +; + +word_opt: /* empty */ { $$ = NULL; } + | T_WORD + +%% + +void conf_parse(const char *name) +{ + struct symbol *sym; + int i; + + zconf_initscan(name); + + sym_init(); + menu_init(); + modules_sym = sym_lookup(NULL, 0); + modules_sym->type = S_BOOLEAN; + modules_sym->flags |= SYMBOL_AUTO; + rootmenu.prompt = menu_add_prompt(P_MENU, "OpenADK Configuration", NULL); + +#if YYDEBUG + if (getenv("ZCONF_DEBUG")) + zconfdebug = 1; +#endif + zconfparse(); + if (zconfnerrs) + exit(1); + if (!modules_sym->prop) { + struct property *prop; + + prop = prop_alloc(P_DEFAULT, modules_sym); + prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); + } + menu_finalize(&rootmenu); + for_all_symbols(i, sym) { + if (sym_check_deps(sym)) + zconfnerrs++; + } + if (zconfnerrs) + exit(1); + sym_set_change_count(1); +} + +const char *zconf_tokenname(int token) +{ + switch (token) { + case T_MENU: return "menu"; + case T_ENDMENU: return "endmenu"; + case T_CHOICE: return "choice"; + case T_ENDCHOICE: return "endchoice"; + case T_IF: return "if"; + case T_ENDIF: return "endif"; + case T_DEPENDS: return "depends"; + } + return ""; +} + +static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken) +{ + if (id->token != endtoken) { + zconf_error("unexpected '%s' within %s block", + kconf_id_strings + id->name, zconf_tokenname(starttoken)); + zconfnerrs++; + return false; + } + if (current_menu->file != current_file) { + zconf_error("'%s' in different file than '%s'", + kconf_id_strings + id->name, zconf_tokenname(starttoken)); + fprintf(stderr, "%s:%d: location of the '%s'\n", + current_menu->file->name, current_menu->lineno, + zconf_tokenname(starttoken)); + zconfnerrs++; + return false; + } + return true; +} + +static void zconfprint(const char *err, ...) +{ + va_list ap; + + fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); + va_start(ap, err); + vfprintf(stderr, err, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +static void zconf_error(const char *err, ...) +{ + va_list ap; + + zconfnerrs++; + fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); + va_start(ap, err); + vfprintf(stderr, err, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +static void zconferror(const char *err) +{ +#if YYDEBUG + fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); +#endif +} + +void print_quoted_string(FILE *out, const char *str) +{ + const char *p; + int len; + + putc('"', out); + while ((p = strchr(str, '"'))) { + len = p - str; + if (len) + fprintf(out, "%.*s", len, str); + fputs("\\\"", out); + str = p + 1; + } + fputs(str, out); + putc('"', out); +} + +void print_symbol(FILE *out, struct menu *menu) +{ + struct symbol *sym = menu->sym; + struct property *prop; + + if (sym_is_choice(sym)) + fprintf(out, "choice\n"); + else + fprintf(out, "config %s\n", sym->name); + switch (sym->type) { + case S_BOOLEAN: + fputs(" boolean\n", out); + break; + case S_TRISTATE: + fputs(" tristate\n", out); + break; + case S_STRING: + fputs(" string\n", out); + break; + case S_INT: + fputs(" integer\n", out); + break; + case S_HEX: + fputs(" hex\n", out); + break; + default: + fputs(" ???\n", out); + break; + } + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->menu != menu) + continue; + switch (prop->type) { + case P_PROMPT: + fputs(" prompt ", out); + print_quoted_string(out, prop->text); + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } + fputc('\n', out); + break; + case P_DEFAULT: + fputs( " default ", out); + expr_fprint(prop->expr, out); + if (!expr_is_yes(prop->visible.expr)) { + fputs(" if ", out); + expr_fprint(prop->visible.expr, out); + } + fputc('\n', out); + break; + case P_CHOICE: + fputs(" #choice value\n", out); + break; + default: + fprintf(out, " unknown prop %d!\n", prop->type); + break; + } + } + if (menu->help) { + int len = strlen(menu->help); + while (menu->help[--len] == '\n') + menu->help[len] = 0; + fprintf(out, " help\n%s\n", menu->help); + } + fputc('\n', out); +} + +void zconfdump(FILE *out) +{ + struct property *prop; + struct symbol *sym; + struct menu *menu; + + menu = rootmenu.list; + while (menu) { + if ((sym = menu->sym)) + print_symbol(out, menu); + else if ((prop = menu->prompt)) { + switch (prop->type) { + case P_COMMENT: + fputs("\ncomment ", out); + print_quoted_string(out, prop->text); + fputs("\n", out); + break; + case P_MENU: + fputs("\nmenu ", out); + print_quoted_string(out, prop->text); + fputs("\n", out); + break; + default: + ; + } + if (!expr_is_yes(prop->visible.expr)) { + fputs(" depends ", out); + expr_fprint(prop->visible.expr, out); + fputc('\n', out); + } + fputs("\n", out); + } + + if (menu->list) + menu = menu->list; + else if (menu->next) + menu = menu->next; + else while ((menu = menu->parent)) { + if (menu->prompt && menu->prompt->type == P_MENU) + fputs("\nendmenu\n", out); + if (menu->next) { + menu = menu->next; + break; + } + } + } +} + +#include "lex.zconf.c" +#include "util.c" +#include "confdata.c" +#include "expr.c" +#include "symbol.c" +#include "menu.c" diff --git a/adk/tests/adk.exp.in b/adk/tests/adk.exp.in new file mode 100644 index 000000000..c5a7b8948 --- /dev/null +++ b/adk/tests/adk.exp.in @@ -0,0 +1,5 @@ +load_generic_config "unix"; +set_board_info hostname @ADK_TARGET_IP@ +set_board_info username root +set_board_info rsh_prog "/usr/bin/ssh -p @ADK_TARGET_PORT@" +set_board_info rcp_prog "/usr/bin/scp -P @ADK_TARGET_PORT@" diff --git a/adk/tests/master.exp.in b/adk/tests/master.exp.in new file mode 100644 index 000000000..72d8ab9e6 --- /dev/null +++ b/adk/tests/master.exp.in @@ -0,0 +1,5 @@ +lappend boards_dir @TOPDIR@/tests +lappend boards_dir /usr/share/dejagnu +set myboard adk +set target_list adk +set verbose 1 diff --git a/adk/tools/Makefile b/adk/tools/Makefile new file mode 100644 index 000000000..edd559f85 --- /dev/null +++ b/adk/tools/Makefile @@ -0,0 +1,17 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include $(TOPDIR)/rules.mk + +install: ${STAGING_HOST_DIR}/usr/bin/depmaker ${STAGING_HOST_DIR}/usr/bin/pkgrebuild ${STAGING_HOST_DIR}/usr/bin/dkgetsz + +${STAGING_HOST_DIR}/usr/bin/depmaker: depmaker.c + ${CC_FOR_BUILD} ${FLAGS_FOR_BUILD} -o $@ depmaker.c + +${STAGING_HOST_DIR}/usr/bin/pkgrebuild: pkgrebuild.c strmap.c + ${CC_FOR_BUILD} ${FLAGS_FOR_BUILD} -o $@ pkgrebuild.c strmap.c + +${STAGING_HOST_DIR}/usr/bin/dkgetsz: dkgetsz.c + ${CC_FOR_BUILD} ${FLAGS_FOR_BUILD} -o $@ dkgetsz.c + +include $(TOPDIR)/mk/tools.mk diff --git a/adk/tools/depmaker.c b/adk/tools/depmaker.c new file mode 100644 index 000000000..23d2d2898 --- /dev/null +++ b/adk/tools/depmaker.c @@ -0,0 +1,314 @@ +/* + * depmaker - create package/Depends.mk for OpenADK buildsystem + * + * Copyright (C) 2010-2014 Waldemar Brodkorb + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#define MAXLINE 1024 +#define MAXPATH 128 + +static int prefix = 0; +static int hprefix = 0; + +static int check_symbol(char *symbol) { + + FILE *config; + char buf[MAXLINE]; + char *sym; + int ret; + + if ((sym = malloc(strlen(symbol) + 2)) != NULL) + memset(sym, 0, strlen(symbol) + 2); + else { + perror("Can not allocate memory."); + exit(EXIT_FAILURE); + } + + strncat(sym, symbol, strlen(symbol)); + strncat(sym, "=", 1); + if ((config = fopen(".config", "r")) == NULL) { + perror("Can not open file \".config\"."); + exit(EXIT_FAILURE); + } + + ret = 1; + while (fgets(buf, MAXLINE, config) != NULL) { + if (strncmp(buf, sym, strlen(sym)) == 0) + ret = 0; + } + + free(sym); + if (fclose(config) != 0) + perror("Closing file stream failed"); + + return(ret); +} + +/*@null@*/ +static char *parse_line(char *package, char *pkgvar, char *string, int checksym, int pprefix, int system, int *prefixp) { + + char *key, *value, *dep, *key_sym, *pkgdeps; + char temp[MAXLINE]; + + string[strlen(string)-1] = '\0'; + if ((key = strtok(string, ":=")) == NULL) { + perror("Can not get key from string."); + exit(EXIT_FAILURE); + } + + if (checksym == 1) { + /* extract symbol */ + if ((key_sym = malloc(MAXLINE)) != NULL) + memset(key_sym, 0, MAXLINE); + else { + perror("Can not allocate memory."); + exit(EXIT_FAILURE); + } + if (system == 0) { + if (pprefix == 0) { + if (snprintf(key_sym, MAXLINE, "ADK_PACKAGE_%s_", pkgvar) < 0) + perror("Can not create string variable."); + } else { + if (snprintf(key_sym, MAXLINE, "ADK_PACKAGE_") < 0) + perror("Can not create string variable."); + } + strncat(key_sym, key+6, strlen(key)-6); + } else { + if (snprintf(key_sym, MAXLINE, "ADK_TARGET_SYSTEM_%s", pkgvar) < 0) + perror("Can not create string variable."); + } + + if (check_symbol(key_sym) != 0) { + free(key_sym); + return(NULL); + } + free(key_sym); + } + + if ((pkgdeps = malloc(MAXLINE)) != NULL) + memset(pkgdeps, 0, MAXLINE); + else { + perror("Can not allocate memory."); + exit(EXIT_FAILURE); + } + + value = strtok(NULL, "=\t"); + dep = strtok(value, " "); + while (dep != NULL) { + if (*prefixp == 0) { + *prefixp = 1; + if (snprintf(temp, MAXLINE, "%s-compile: %s-compile", package, dep) < 0) + perror("Can not create string variable."); + } else { + if (snprintf(temp, MAXLINE, " %s-compile", dep) < 0) + perror("Can not create string variable."); + } + strncat(pkgdeps, temp, strlen(temp)); + dep = strtok(NULL, " "); + } + return(pkgdeps); +} + +int main() { + + DIR *pkgdir; + struct dirent *pkgdirp; + FILE *pkg; + char buf[MAXLINE]; + char path[MAXPATH]; + char *string, *pkgvar, *pkgdeps, *hpkgdeps = NULL, *tmp, *fpkg, *cpkg, *spkg, *key, *check, *dpkg; + char *stringtmp; + int i; + + spkg = NULL; + cpkg = NULL; + fpkg = NULL; + + /* read Makefile's for all packages */ + pkgdir = opendir("package"); + while ((pkgdirp = readdir(pkgdir)) != NULL) { + /* skip dotfiles */ + if (strncmp(pkgdirp->d_name, ".", 1) > 0) { + if (snprintf(path, MAXPATH, "package/%s/Makefile", pkgdirp->d_name) < 0) + perror("Can not create string variable."); + pkg = fopen(path, "r"); + if (pkg == NULL) + continue; + + /* transform to uppercase variable name */ + pkgvar = strdup(pkgdirp->d_name); + for (i=0; i<(int)strlen(pkgvar); i++) { + if (pkgvar[i] == '+') + pkgvar[i] = 'X'; + if (pkgvar[i] == '-') + pkgvar[i] = '_'; + pkgvar[i] = toupper(pkgvar[i]); + } + + /* exclude manual maintained packages from package/Makefile */ + if ( + !(strncmp(pkgdirp->d_name, "libpthread", 10) == 0 && strlen(pkgdirp->d_name) == 10) && + !(strncmp(pkgdirp->d_name, "uclibc++", 8) == 0) && + !(strncmp(pkgdirp->d_name, "uclibc", 6) == 0) && + !(strncmp(pkgdirp->d_name, "musl", 4) == 0) && + !(strncmp(pkgdirp->d_name, "glibc", 5) == 0)) { + /* print result to stdout */ + printf("package-$(ADK_COMPILE_%s) += %s\n", pkgvar, pkgdirp->d_name); + printf("hostpackage-$(ADK_HOST_NEED_%s) += %s\n", pkgvar, pkgdirp->d_name); + } + + if ((pkgdeps = malloc(MAXLINE)) != NULL) + memset(pkgdeps, 0, MAXLINE); + else { + perror("Can not allocate memory."); + exit(EXIT_FAILURE); + } + prefix = 0; + hprefix = 0; + + /* generate build dependencies */ + while (fgets(buf, MAXLINE, pkg) != NULL) { + if ((tmp = malloc(MAXLINE)) != NULL) + memset(tmp, 0 , MAXLINE); + else { + perror("Can not allocate memory."); + exit(EXIT_FAILURE); + } + + /* just read variables prefixed with PKG */ + if (strncmp(buf, "PKG", 3) == 0) { + + string = strstr(buf, "PKG_BUILDDEP:="); + if (string != NULL) { + tmp = parse_line(pkgdirp->d_name, pkgvar, string, 0, 0, 0, &prefix); + if (tmp != NULL) { + strncat(pkgdeps, tmp, strlen(tmp)); + } + } + + string = strstr(buf, "PKG_BUILDDEP+="); + if (string != NULL) { + tmp = parse_line(pkgdirp->d_name, pkgvar, string, 0, 0, 0, &prefix); + if (tmp != NULL) + strncat(pkgdeps, tmp, strlen(tmp)); + } + + // We need to find the system name here + string = strstr(buf, "PKG_BUILDDEP_"); + if (string != NULL) { + check = strstr(buf, ":="); + if (check != NULL) { + stringtmp = strdup(string); + string[strlen(string)-1] = '\0'; + key = strtok(string, ":="); + dpkg = strdup(key+13); + tmp = parse_line(pkgdirp->d_name, dpkg, stringtmp, 1, 0, 1, &prefix); + if (tmp != NULL) + strncat(pkgdeps, tmp, strlen(tmp)); + } + } + + // We need to find the subpackage name here + string = strstr(buf, "PKG_FLAVOURS_"); + if (string != NULL) { + check = strstr(buf, ":="); + if (check != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, ":="); + fpkg = strdup(key+13); + } + } + + string = strstr(buf, "PKGFB_"); + if (string != NULL) { + tmp = parse_line(pkgdirp->d_name, fpkg, string, 1, 0, 0, &prefix); + if (tmp != NULL) + strncat(pkgdeps, tmp, strlen(tmp)); + } + + // We need to find the subpackage name here + string = strstr(buf, "PKG_CHOICES_"); + if (string != NULL) { + check = strstr(buf, ":="); + if (check != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, ":="); + cpkg = strdup(key+12); + } + } + string = strstr(buf, "PKGCB_"); + if (string != NULL) { + tmp = parse_line(pkgdirp->d_name, cpkg, string, 1, 0, 0, &prefix); + if (tmp != NULL) + strncat(pkgdeps, tmp, strlen(tmp)); + } + + // We need to find the subpackage name here + string = strstr(buf, "PKG_SUBPKGS_"); + if (string != NULL) { + check = strstr(buf, ":="); + if (check != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, ":="); + spkg = strdup(key+12); + } + } + + string = strstr(buf, "PKGSB_"); + if (string != NULL) { + tmp = parse_line(pkgdirp->d_name, spkg, string, 1, 1, 0, &prefix); + if (tmp != NULL) { + strncat(pkgdeps, tmp, strlen(tmp)); + } + } + } else if (strncmp(buf, "HOST_BUILDDEP", 13) == 0) { + asprintf(&string, "%s-host", pkgdirp->d_name); + // check retval; string for NULL + tmp = parse_line(string, NULL, buf, 0, 0, 0, &hprefix); + if (tmp && *tmp) { + asprintf(&string, "%s%s", + hpkgdeps ? hpkgdeps : "", + tmp); + free(hpkgdeps); + hpkgdeps = string; + } + } + free(tmp); + } + if (strlen(pkgdeps) != 0) + printf("%s\n", pkgdeps); + if (hpkgdeps && *hpkgdeps) + printf("%s\n", hpkgdeps); + free(hpkgdeps); + hpkgdeps = NULL; + free(pkgdeps); + free(pkgvar); + if (fclose(pkg) != 0) + perror("Closing file stream failed"); + } + } + if (closedir(pkgdir) != 0) + perror("Closing directory stream failed"); + + return(0); +} diff --git a/adk/tools/dkgetsz.c b/adk/tools/dkgetsz.c new file mode 100644 index 000000000..b8315be70 --- /dev/null +++ b/adk/tools/dkgetsz.c @@ -0,0 +1,95 @@ +/*- + * Copyright © 2010 + * Waldemar Brodkorb + * Thorsten Glaser + * + * Provided that these terms and disclaimer and all copyright notices + * are retained or reproduced in an accompanying document, permission + * is granted to deal in this work without restriction, including un‐ + * limited rights to use, publicly perform, distribute, sell, modify, + * merge, give away, or sublicence. + * + * This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to + * the utmost extent permitted by applicable law, neither express nor + * implied; without malicious intent or gross negligence. In no event + * may a licensor, author or contributor be held liable for indirect, + * direct, other damage, loss, or other issues arising in any way out + * of dealing in the work, even if advised of the possibility of such + * damage or existence of a defect, except proven that it results out + * of said person’s immediate fault when using the work as intended. + * + * Alternatively, this work may be distributed under the terms of the + * General Public License, any version, as published by the Free Soft- + * ware Foundation. + *- + * Display the size of a block device (e.g. USB stick, CF/SF/MMC card + * or hard disc) in 512-byte sectors. + */ + +#define _FILE_OFFSET_BITS 64 + +#include +#include +#include +#include + +#if defined(__APPLE__) +#include +#endif + +#if defined(DIOCGDINFO) +#include +#endif + +#include +#include +#include +#include + +unsigned long long numsecs(int); + +int +main(int argc, char *argv[]) { + int fd; + + if (argc != 2) + errx(255, "Syntax: dkgetsz /dev/sda"); + + if ((fd = open(argv[1], O_RDONLY)) == -1) + err(1, "open"); + printf("%llu\n", numsecs(fd)); + close(fd); + return (0); +} + +unsigned long long +numsecs(int fd) +{ +#if defined(BLKGETSIZE) || defined(DKIOCGETBLOCKCOUNT) +/* + * note: BLKGETSIZE64 returns bytes, not sectors, but the return + * type is size_t which is 32 bits on an ILP32 platform, so it + * fails interestingly here… thus we use BLKGETSIZE instead. + */ +#if defined(DKIOCGETBLOCKCOUNT) + uint64_t nsecs; +#define THEIOCTL DKIOCGETBLOCKCOUNT +#define STRIOCTL "DKIOCGETBLOCKCOUNT" +#else + unsigned long nsecs; +#define THEIOCTL BLKGETSIZE +#define STRIOCTL "BLKGETSIZE" +#endif + if (ioctl(fd, THEIOCTL, &nsecs) == -1) + err(1, "ioctl %s", STRIOCTL); + return ((unsigned long long)nsecs); +#elif defined(DIOCGDINFO) + struct disklabel dl; + + if (ioctl(fd, DIOCGDINFO, &dl) == -1) + err(1, "ioctl DIOCGDINFO"); + return ((unsigned long long)dl.d_secperunit); +#else +#warning PLEASE DO IMPLEMENT numsecs FOR THIS PLATFORM. +#endif +} diff --git a/adk/tools/pkgmaker.c b/adk/tools/pkgmaker.c new file mode 100644 index 000000000..51d31aa70 --- /dev/null +++ b/adk/tools/pkgmaker.c @@ -0,0 +1,1194 @@ +/* + * pkgmaker - create package meta-data for OpenADK buildsystem + * + * Copyright (C) 2010-2014 Waldemar Brodkorb + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sortfile.h" +#include "strmap.h" + +#define MAXLINE 4096 +#define MAXVALUE 168 +#define MAXVAR 64 +#define MAXPATH 320 +#define HASHSZ 96 + +static int nobinpkgs; + +#define fatal_error(...) { \ + fprintf(stderr, "Fatal error. "); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + exit(1); \ +} + +static int parse_var_hash(char *buf, const char *varname, StrMap *strmap) { + + char *key, *value, *string; + + string = strstr(buf, varname); + if (string != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, ":="); + value = strtok(NULL, "=\t"); + if (value != NULL) + strmap_put(strmap, key, value); + return(0); + } + return(1); +} + +static int parse_var(char *buf, const char *varname, char *pvalue, char **result) { + + char *pkg_var; + char *key, *value, *string; + char pkg_str[MAXVAR]; + + if ((pkg_var = malloc(MAXLINE)) != NULL) + memset(pkg_var, 0, MAXLINE); + else { + perror("Can not allocate memory"); + exit(EXIT_FAILURE); + } + + if (snprintf(pkg_str, MAXVAR, "%s:=", varname) < 0) + perror("can not create path variable."); + string = strstr(buf, pkg_str); + if (string != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, ":="); + value = strtok(NULL, "=\t"); + if (value != NULL) { + strncat(pkg_var, value, strlen(value)); + *result = strdup(pkg_var); + } else { + nobinpkgs = 1; + *result = NULL; + } + free(pkg_var); + return(0); + } else { + if (snprintf(pkg_str, MAXVAR, "%s+=", varname) < 0) + perror("can not create path variable."); + string = strstr(buf, pkg_str); + if (string != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, "+="); + value = strtok(NULL, "=\t"); + if (pvalue != NULL) + strncat(pkg_var, pvalue, strlen(pvalue)); + strncat(pkg_var, " ", 1); + if (value != NULL) + strncat(pkg_var, value, strlen(value)); + *result = strdup(pkg_var); + free(pkg_var); + return(0); + } + } + free(pkg_var); + return(1); +} + +static int parse_var_with_system(char *buf, const char *varname, char *pvalue, char **result, char **sysname, int varlen) { + + char *pkg_var, *check; + char *key, *value, *string; + + if ((pkg_var = malloc(MAXLINE)) != NULL) + memset(pkg_var, 0, MAXLINE); + else { + perror("Can not allocate memory"); + exit(EXIT_FAILURE); + } + + check = strstr(buf, ":="); + if (check != NULL) { + string = strstr(buf, varname); + if (string != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, ":="); + *sysname = strdup(key+varlen); + value = strtok(NULL, "=\t"); + if (value != NULL) { + strncat(pkg_var, value, strlen(value)); + *result = strdup(pkg_var); + } + free(pkg_var); + return(0); + } + } else { + string = strstr(buf, varname); + if (string != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, "+="); + value = strtok(NULL, "=\t"); + if (pvalue != NULL) + strncat(pkg_var, pvalue, strlen(pvalue)); + strncat(pkg_var, " ", 1); + if (value != NULL) + strncat(pkg_var, value, strlen(value)); + *result = strdup(pkg_var); + free(pkg_var); + return(0); + } + } + free(pkg_var); + return(1); +} + +static int parse_var_with_pkg(char *buf, const char *varname, char *pvalue, char **result, char **pkgname, int varlen) { + + char *pkg_var, *check; + char *key, *value, *string; + + if ((pkg_var = malloc(MAXLINE)) != NULL) + memset(pkg_var, 0, MAXLINE); + else { + perror("Can not allocate memory"); + exit(EXIT_FAILURE); + } + + check = strstr(buf, ":="); + if (check != NULL) { + string = strstr(buf, varname); + if (string != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, ":="); + *pkgname = strdup(key+varlen); + value = strtok(NULL, "=\t"); + if (value != NULL) { + strncat(pkg_var, value, strlen(value)); + *result = strdup(pkg_var); + } + free(pkg_var); + return(0); + } + } else { + string = strstr(buf, varname); + if (string != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, "+="); + value = strtok(NULL, "=\t"); + if (pvalue != NULL) + strncat(pkg_var, pvalue, strlen(pvalue)); + strncat(pkg_var, " ", 1); + if (value != NULL) + strncat(pkg_var, value, strlen(value)); + *result = strdup(pkg_var); + free(pkg_var); + return(0); + } + } + free(pkg_var); + return(1); +} + +#if 0 +static void iter_debug(const char *key, const char *value, const void *obj) { + fprintf(stderr, "HASHMAP key: %s value: %s\n", key, value); +} +#endif + +static int hash_str(char *string) { + + int i; + int hash; + + hash = 0; + for (i=0; i<(int)strlen(string); i++) { + hash += string[i]; + } + return(hash); +} + +static void iter(const char *key, const char *value, const void *obj) { + + FILE *config, *section; + int hash; + char *valuestr, *pkg, *subpkg; + char buf[MAXPATH]; + char infile[MAXPATH]; + char outfile[MAXPATH]; + + valuestr = strdup(value); + config = fopen("package/Config.in.auto", "a"); + if (config == NULL) + fatal_error("Can not open file package/Config.in.auto"); + + hash = hash_str(valuestr); + snprintf(infile, MAXPATH, "package/pkglist.d/sectionlst.%d", hash); + snprintf(outfile, MAXPATH, "package/pkglist.d/sectionlst.%d.sorted", hash); + + if (access(infile, F_OK) == 0) { + valuestr[strlen(valuestr)-1] = '\0'; + fprintf(config, "menu \"%s\"\n", valuestr); + sortfile(infile, outfile); + /* avoid duplicate section entries */ + unlink(infile); + section = fopen(outfile, "r"); + while (fgets(buf, MAXPATH, section) != NULL) { + buf[strlen(buf)-1] = '\0'; + if (buf[strlen(buf)-1] == '@') { + buf[strlen(buf)-1] = '\0'; + fprintf(config, "source \"package/%s/Config.in.manual\"\n", buf); + } else { + subpkg = strtok(buf, "|"); + subpkg[strlen(subpkg)-1] = '\0'; + pkg = strtok(NULL, "|"); + fprintf(config, "source \"package/pkgconfigs.d/%s/Config.in.%s\"\n", pkg, subpkg); + } + } + fprintf(config, "endmenu\n\n"); + fclose(section); + } + fclose(config); +} + +static char *tolowerstr(char *string) { + + int i; + char *str; + + /* transform to lowercase variable name */ + str = strdup(string); + for (i=0; i<(int)strlen(str); i++) { + if (str[i] == '_') + str[i] = '-'; + str[i] = tolower(str[i]); + } + return(str); +} + +static char *toupperstr(char *string) { + + int i; + char *str; + + /* transform to uppercase variable name */ + str = strdup(string); + for (i=0; i<(int)strlen(str); i++) { + if (str[i] == '+') + str[i] = 'X'; + if (str[i] == '-') + str[i] = '_'; + /* remove negation here, useful for package host depends */ + if (str[i] == '!') + str[i] = '_'; + str[i] = toupper(str[i]); + } + return(str); +} + + +int main() { + + DIR *pkgdir, *pkglistdir; + struct dirent *pkgdirp; + FILE *pkg, *cfg, *menuglobal, *section; + char hvalue[MAXVALUE]; + char buf[MAXPATH]; + char tbuf[MAXPATH]; + char path[MAXPATH]; + char spath[MAXPATH]; + char dir[MAXPATH]; + char variable[2*MAXVAR]; + char *key, *value, *token, *cftoken, *sp, *hkey, *val, *pkg_fd; + char *pkg_name, *pkg_depends, *pkg_depends_system, *pkg_section, *pkg_descr, *pkg_url; + char *pkg_cxx, *pkg_subpkgs, *pkg_cfline, *pkg_dflt, *pkg_multi; + char *pkg_need_cxx, *pkg_need_java, *pkgname, *sysname, *pkg_debug; + char *pkg_libc_depends, *pkg_host_depends, *pkg_system_depends, *pkg_arch_depends, *pkg_flavours, *pkg_flavours_string, *pkg_choices, *pseudo_name; + char *packages, *pkg_name_u, *pkgs, *pkg_opts, *pkg_libname; + char *saveptr, *p_ptr, *s_ptr, *pkg_helper; + int result; + StrMap *pkgmap, *sectionmap; + + pkg_name = NULL; + pkg_descr = NULL; + pkg_section = NULL; + pkg_url = NULL; + pkg_depends = NULL; + pkg_depends_system = NULL; + pkg_opts = NULL; + pkg_libname = NULL; + pkg_flavours = NULL; + pkg_flavours_string = NULL; + pkg_choices = NULL; + pkg_subpkgs = NULL; + pkg_arch_depends = NULL; + pkg_system_depends = NULL; + pkg_host_depends = NULL; + pkg_libc_depends = NULL; + pkg_cxx = NULL; + pkg_dflt = NULL; + pkg_cfline = NULL; + pkg_multi = NULL; + pkg_need_cxx = NULL; + pkg_need_java = NULL; + pkgname = NULL; + sysname = NULL; + pkg_helper = NULL; + pkg_debug = NULL; + + p_ptr = NULL; + s_ptr = NULL; + + unlink("package/Config.in.auto"); + /* open global sectionfile */ + menuglobal = fopen("package/Config.in.auto.global", "w"); + if (menuglobal == NULL) + fatal_error("global section file not writable."); + + /* read section list and create a hash table */ + section = fopen("package/section.lst", "r"); + if (section == NULL) + fatal_error("section listfile is missing"); + + sectionmap = strmap_new(HASHSZ); + while (fgets(tbuf, MAXPATH, section) != NULL) { + key = strtok(tbuf, "\t"); + value = strtok(NULL, "\t"); + strmap_put(sectionmap, key, value); + } + fclose(section); + + if (mkdir("package/pkgconfigs.d", S_IRWXU) > 0) + fatal_error("creation of package/pkgconfigs.d failed."); + if (mkdir("package/pkgconfigs.d/gcc", S_IRWXU) > 0) + fatal_error("creation of package/pkgconfigs.d/gcc failed."); + if (mkdir("package/pkglist.d", S_IRWXU) > 0) + fatal_error("creation of package/pkglist.d failed."); + + /* delete Config.in.dev */ + if (snprintf(path, MAXPATH, "package/pkgconfigs.d/gcc/Config.in.dev") < 0) + fatal_error("failed to create path variable."); + unlink(path); + cfg = fopen(path, "w"); + if (cfg == NULL) + fatal_error("Config.in.dev can not be opened"); + fprintf(cfg, "config ADK_PACKAGE_GLIBC_DEV\n"); + fprintf(cfg, "\tprompt \"glibc-dev............ development files for glibc\"\n"); + fprintf(cfg, "\ttristate\n"); + fprintf(cfg, "\tdefault n\n"); + fprintf(cfg, "\tdepends on ADK_TARGET_LIB_GLIBC\n"); + fprintf(cfg, "\thelp\n"); + fprintf(cfg, "\t GNU C library header files.\n\n"); + fprintf(cfg, "config ADK_PACKAGE_UCLIBC_DEV\n"); + fprintf(cfg, "\tprompt \"uclibc-dev........... development files for uclibc\"\n"); + fprintf(cfg, "\ttristate\n"); + fprintf(cfg, "\tdefault n\n"); + fprintf(cfg, "\tdepends on ADK_TARGET_LIB_UCLIBC\n"); + fprintf(cfg, "\thelp\n"); + fprintf(cfg, "\t C library header files.\n\n"); + fprintf(cfg, "config ADK_PACKAGE_MUSL_DEV\n"); + fprintf(cfg, "\tprompt \"musl-dev............. development files for musl\"\n"); + fprintf(cfg, "\ttristate\n"); + fprintf(cfg, "\tdefault n\n"); + fprintf(cfg, "\tdepends on ADK_TARGET_LIB_MUSL\n"); + fprintf(cfg, "\thelp\n"); + fprintf(cfg, "\t C library header files.\n\n"); + fclose(cfg); + + /* read Makefile's for all packages */ + pkgdir = opendir("package"); + while ((pkgdirp = readdir(pkgdir)) != NULL) { + /* skip dotfiles */ + if (strncmp(pkgdirp->d_name, ".", 1) > 0) { + if (snprintf(path, MAXPATH, "package/%s/Makefile", pkgdirp->d_name) < 0) + fatal_error("can not create path variable."); + pkg = fopen(path, "r"); + if (pkg == NULL) + continue; + + /* skip manually maintained packages */ + if (snprintf(path, MAXPATH, "package/%s/Config.in.manual", pkgdirp->d_name) < 0) + fatal_error("can not create path variable."); + if (!access(path, F_OK)) { + while (fgets(buf, MAXPATH, pkg) != NULL) { + if ((parse_var(buf, "PKG_SECTION", NULL, &pkg_section)) == 0) + continue; + } + + memset(hvalue, 0 , MAXVALUE); + result = strmap_get(sectionmap, pkg_section, hvalue, sizeof(hvalue)); + if (result == 1) { + if (snprintf(spath, MAXPATH, "package/pkglist.d/sectionlst.%d", hash_str(hvalue)) < 0) + fatal_error("can not create path variable."); + section = fopen(spath, "a"); + if (section != NULL) { + fprintf(section, "%s@\n", pkgdirp->d_name); + fclose(section); + } + } else + fatal_error("Can not find section description for package %s.", + pkgdirp->d_name); + + fclose(pkg); + continue; + } + + nobinpkgs = 0; + + /* create output directories */ + if (snprintf(dir, MAXPATH, "package/pkgconfigs.d/%s", pkgdirp->d_name) < 0) + fatal_error("can not create dir variable."); + if (mkdir(dir, S_IRWXU) > 0) + fatal_error("can not create directory."); + + + /* allocate memory */ + hkey = malloc(MAXVAR); + memset(hkey, 0, MAXVAR); + memset(variable, 0, 2*MAXVAR); + + pkgmap = strmap_new(HASHSZ); + + /* parse package Makefile */ + while (fgets(buf, MAXPATH, pkg) != NULL) { + /* just read variables prefixed with PKG */ + if (strncmp(buf, "PKG", 3) == 0) { + if ((parse_var(buf, "PKG_NAME", NULL, &pkg_name)) == 0) + continue; + if (pkg_name != NULL) + pkg_name_u = toupperstr(pkg_name); + else + pkg_name_u = toupperstr(pkgdirp->d_name); + + snprintf(variable, MAXVAR, "PKG_CFLINE_%s", pkg_name_u); + if ((parse_var(buf, variable, pkg_cfline, &pkg_cfline)) == 0) + continue; + snprintf(variable, MAXVAR, "PKG_DFLT_%s", pkg_name_u); + if ((parse_var(buf, variable, NULL, &pkg_dflt)) == 0) + continue; + if ((parse_var(buf, "PKG_LIBC_DEPENDS", NULL, &pkg_libc_depends)) == 0) + continue; + if ((parse_var(buf, "PKG_HOST_DEPENDS", NULL, &pkg_host_depends)) == 0) + continue; + if ((parse_var(buf, "PKG_ARCH_DEPENDS", NULL, &pkg_arch_depends)) == 0) + continue; + if ((parse_var(buf, "PKG_SYSTEM_DEPENDS", NULL, &pkg_system_depends)) == 0) + continue; + if ((parse_var(buf, "PKG_DESCR", NULL, &pkg_descr)) == 0) + continue; + if ((parse_var(buf, "PKG_SECTION", NULL, &pkg_section)) == 0) + continue; + if ((parse_var(buf, "PKG_URL", NULL, &pkg_url)) == 0) + continue; + if ((parse_var(buf, "PKG_CXX", NULL, &pkg_cxx)) == 0) + continue; + if ((parse_var(buf, "PKG_NEED_CXX", NULL, &pkg_need_cxx)) == 0) + continue; + if ((parse_var(buf, "PKG_NEED_JAVA", NULL, &pkg_need_java)) == 0) + continue; + if ((parse_var(buf, "PKG_MULTI", NULL, &pkg_multi)) == 0) + continue; + if ((parse_var(buf, "PKG_DEPENDS", pkg_depends, &pkg_depends)) == 0) + continue; + if ((parse_var_with_system(buf, "PKG_DEPENDS_", pkg_depends_system, &pkg_depends_system, &sysname, 12)) == 0) + continue; + if ((parse_var(buf, "PKG_LIBNAME", pkg_libname, &pkg_libname)) == 0) + continue; + if ((parse_var(buf, "PKG_OPTS", pkg_opts, &pkg_opts)) == 0) + continue; + if ((parse_var_with_pkg(buf, "PKG_FLAVOURS_STRING_", pkg_flavours_string, &pkg_flavours_string, &pkgname, 20)) == 0) + continue; + if ((parse_var_with_pkg(buf, "PKG_FLAVOURS_", pkg_flavours, &pkg_flavours, &pkgname, 13)) == 0) + continue; + if ((parse_var_hash(buf, "PKGFD_", pkgmap)) == 0) + continue; + if ((parse_var_hash(buf, "PKGFX_", pkgmap)) == 0) + continue; + if ((parse_var_hash(buf, "PKGFS_", pkgmap)) == 0) + continue; + if ((parse_var_hash(buf, "PKGFC_", pkgmap)) == 0) + continue; + if ((parse_var_with_pkg(buf, "PKG_CHOICES_", pkg_choices, &pkg_choices, &pkgname, 12)) == 0) + continue; + if ((parse_var_hash(buf, "PKGCD_", pkgmap)) == 0) + continue; + if ((parse_var_hash(buf, "PKGCS_", pkgmap)) == 0) + continue; + if ((parse_var(buf, "PKG_SUBPKGS", pkg_subpkgs, &pkg_subpkgs)) == 0) + continue; + if ((parse_var_hash(buf, "PKGSD_", pkgmap)) == 0) + continue; + if ((parse_var_hash(buf, "PKGSS_", pkgmap)) == 0) + continue; + if ((parse_var_hash(buf, "PKGSC_", pkgmap)) == 0) + continue; + } + } + + /* when PKG_LIBNAME exist use this instead of PKG_NAME, but only for !libmix */ + if (pkg_libname != NULL) + if (pkg_opts != NULL) + if (strstr(pkg_opts, "libmix") == NULL) + pkg_name = strdup(pkg_libname); + + /* end of package Makefile parsing */ + if (fclose(pkg) != 0) + perror("Failed to close file stream for Makefile"); + +#if 0 + if (pkg_name != NULL) + fprintf(stderr, "Package name is %s\n", pkg_name); + if (pkg_libname != NULL) + fprintf(stderr, "Package library name is %s\n", pkg_libname); + if (pkg_section != NULL) + fprintf(stderr, "Package section is %s\n", pkg_section); + if (pkg_descr != NULL) + fprintf(stderr, "Package description is %s\n", pkg_descr); + if (pkg_depends != NULL) + fprintf(stderr, "Package dependencies are %s\n", pkg_depends); + if (pkg_depends_system != NULL) + fprintf(stderr, "Package systemspecific dependencies are %s\n", pkg_depends_system); + if (pkg_subpkgs != NULL) + fprintf(stderr, "Package subpackages are %s\n", pkg_subpkgs); + if (pkg_flavours != NULL && pkgname != NULL) + fprintf(stderr, "Package flavours for %s are %s\n", pkgname, pkg_flavours); + if (pkg_flavours_string != NULL && pkgname != NULL) + fprintf(stderr, "Package string flavours for %s are %s\n", pkgname, pkg_flavours_string); + if (pkg_choices != NULL && pkgname != NULL) + fprintf(stderr, "Package choices for %s are %s\n", pkgname, pkg_choices); + if (pkg_url != NULL) + fprintf(stderr, "Package homepage is %s\n", pkg_url); + if (pkg_cfline != NULL) + fprintf(stderr, "Package cfline is %s\n", pkg_cfline); + if (pkg_multi != NULL) + fprintf(stderr, "Package multi is %s\n", pkg_multi); + if (pkg_opts != NULL) + fprintf(stderr, "Package options are %s\n", pkg_opts); + + strmap_enum(pkgmap, iter_debug, NULL); +#endif + + /* generate master source Config.in file */ + if (snprintf(path, MAXPATH, "package/pkgconfigs.d/%s/Config.in", pkgdirp->d_name) < 0) + fatal_error("path variable creation failed."); + fprintf(menuglobal, "source \"%s\"\n", path); + /* recreating file is faster than truncating with w+ */ + unlink(path); + cfg = fopen(path, "w"); + if (cfg == NULL) + continue; + + pkgs = NULL; + if (pkg_subpkgs != NULL) + pkgs = strdup(pkg_subpkgs); + + fprintf(cfg, "config ADK_COMPILE_%s\n", toupperstr(pkgdirp->d_name)); + fprintf(cfg, "\ttristate\n"); + if (nobinpkgs == 0) { + fprintf(cfg, "\tdepends on "); + if (pkgs != NULL) { + if (pkg_multi != NULL) + if (strncmp(pkg_multi, "1", 1) == 0) + fprintf(cfg, "ADK_HAVE_DOT_CONFIG || "); + token = strtok(pkgs, " "); + fprintf(cfg, "ADK_PACKAGE_%s", token); + token = strtok(NULL, " "); + while (token != NULL) { + fprintf(cfg, " || ADK_PACKAGE_%s", token); + token = strtok(NULL, " "); + } + fprintf(cfg, "\n"); + } else { + fprintf(cfg, "ADK_PACKAGE_%s\n", toupperstr(pkg_name)); + } + } + fprintf(cfg, "\tdefault n\n"); + fclose(cfg); + free(pkgs); + + + /* skip packages without binary package output */ + if (nobinpkgs == 1) + continue; + + /* generate binary package specific Config.in files */ + if (pkg_subpkgs != NULL) + packages = tolowerstr(pkg_subpkgs); + else + packages = strdup(pkg_name); + + token = strtok_r(packages, " ", &p_ptr); + while (token != NULL) { + strncat(hkey, "PKGSC_", 6); + strncat(hkey, toupperstr(token), strlen(token)); + memset(hvalue, 0 , MAXVALUE); + result = strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); + memset(hkey, 0 , MAXVAR); + if (result == 1) + pkg_section = strdup(hvalue); + + strncat(hkey, "PKGSD_", 6); + strncat(hkey, toupperstr(token), strlen(token)); + memset(hvalue, 0 , MAXVALUE); + result = strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); + memset(hkey, 0 , MAXVAR); + if (result == 1) + pkg_descr = strdup(hvalue); + + pseudo_name = malloc(MAXLINE); + memset(pseudo_name, 0, MAXLINE); + strncat(pseudo_name, token, strlen(token)); + while (strlen(pseudo_name) < 20) + strncat(pseudo_name, ".", 1); + + if (snprintf(path, MAXPATH, "package/pkgconfigs.d/%s/Config.in.%s", pkgdirp->d_name, token) < 0) + fatal_error("failed to create path variable."); + + /* create temporary section files */ + memset(hvalue, 0 , MAXVALUE); + result = strmap_get(sectionmap, pkg_section, hvalue, sizeof(hvalue)); + if (result == 1) { + if (snprintf(spath, MAXPATH, "package/pkglist.d/sectionlst.%d", hash_str(hvalue)) < 0) + fatal_error("failed to create path variable."); + section = fopen(spath, "a"); + if (section != NULL) { + fprintf(section, "%s |%s\n", token, pkgdirp->d_name); + fclose(section); + } + } else + fatal_error("Can not find section description for package %s.", pkgdirp->d_name); + + unlink(path); + cfg = fopen(path, "w"); + if (cfg == NULL) + perror("Can not open Config.in file"); + + if (pkg_need_cxx != NULL) { + fprintf(cfg, "comment \"%s... %s (disabled, c++ missing)\"\n", token, pkg_descr); + fprintf(cfg, "depends on !ADK_TOOLCHAIN_GCC_CXX\n\n"); + } + + /* save token in pkg_debug */ + pkg_debug = strdup(token); + fprintf(cfg, "config ADK_PACKAGE_%s\n", toupperstr(token)); + /* no prompt for devonly packages */ + if (pkg_opts != NULL) { + if (strstr(pkg_opts, "devonly") != NULL) { + fprintf(cfg, "\t#prompt \"%s. %s\"\n", pseudo_name, pkg_descr); + } else { + fprintf(cfg, "\tprompt \"%s. %s\"\n", pseudo_name, pkg_descr); + } + } else { + fprintf(cfg, "\tprompt \"%s. %s\"\n", pseudo_name, pkg_descr); + } + + fprintf(cfg, "\ttristate\n"); + if (pkg_multi != NULL) + if (strncmp(pkg_multi, "1", 1) == 0) + if (strncmp(toupperstr(token), toupperstr(pkgdirp->d_name), strlen(token)) != 0) + fprintf(cfg, "\tdepends on ADK_PACKAGE_%s\n", toupperstr(pkgdirp->d_name)); + + free(pseudo_name); + + /* print custom cf line */ + if (pkg_cfline != NULL) { + cftoken = strtok_r(pkg_cfline, "@", &saveptr); + while (cftoken != NULL) { + fprintf(cfg, "\t%s\n", cftoken); + cftoken = strtok_r(NULL, "@", &saveptr); + } + free(pkg_cfline); + pkg_cfline = NULL; + } + + /* add sub package dependencies */ + strncat(hkey, "PKGSS_", 6); + strncat(hkey, toupperstr(token), strlen(token)); + memset(hvalue, 0, MAXVALUE); + result = strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); + if (result == 1) { + val = strtok_r(hvalue, " ", &saveptr); + while (val != NULL) { + if (strncmp(val, "kmod", 4) == 0) + fprintf(cfg, "\tselect ADK_KPACKAGE_%s\n", toupperstr(val)); + else + fprintf(cfg, "\tselect ADK_PACKAGE_%s\n", toupperstr(val)); + val = strtok_r(NULL, " ", &saveptr); + } + } + memset(hkey, 0, MAXVAR); + + /* create package target system dependency information */ + if (pkg_system_depends != NULL) { + pkg_helper = strdup(pkg_system_depends); + token = strtok(pkg_helper, " "); + fprintf(cfg, "\tdepends on "); + sp = ""; + while (token != NULL) { + if(strncmp(token, "!", 1) == 0) { + fprintf(cfg, "%s!ADK_TARGET_SYSTEM%s", sp, toupperstr(token)); + sp = " && "; + } else { + fprintf(cfg, "%sADK_TARGET_SYSTEM_%s", sp, toupperstr(token)); + sp = " || "; + } + token = strtok(NULL, " "); + } + fprintf(cfg, "\n"); + free(pkg_helper); + pkg_helper = NULL; + } + /* create package host dependency information */ + if (pkg_host_depends != NULL) { + pkg_helper = strdup(pkg_host_depends); + token = strtok(pkg_helper, " "); + fprintf(cfg, "\tdepends on "); + sp = ""; + while (token != NULL) { + if(strncmp(token, "!", 1) == 0) { + fprintf(cfg, "%s!ADK_HOST%s", sp, toupperstr(token)); + sp = " && "; + } else { + fprintf(cfg, "%sADK_HOST_%s", sp, toupperstr(token)); + sp = " || "; + } + token = strtok(NULL, " "); + } + fprintf(cfg, "\n"); + free(pkg_helper); + pkg_helper = NULL; + } + + /* create package libc dependency information */ + if (pkg_libc_depends != NULL) { + pkg_helper = strdup(pkg_libc_depends); + token = strtok(pkg_helper, " "); + fprintf(cfg, "\tdepends on "); + sp = ""; + while (token != NULL) { + if(strncmp(token, "!", 1) == 0) { + fprintf(cfg, "%s!ADK_TARGET_LIB_%s", sp, toupperstr(token)); + sp = " && "; + } else { + fprintf(cfg, "%sADK_TARGET_LIB_%s", sp, toupperstr(token)); + sp = " || "; + } + token = strtok(NULL, " "); + } + fprintf(cfg, "\n"); + free(pkg_helper); + pkg_helper = NULL; + } + /* create package target architecture dependency information */ + if (pkg_arch_depends != NULL) { + pkg_helper = strdup(pkg_arch_depends); + token = strtok(pkg_helper, " "); + fprintf(cfg, "\tdepends on "); + sp = ""; + while (token != NULL) { + if(strncmp(token, "!", 1) == 0) { + fprintf(cfg, "%s!ADK_LINUX%s", sp, toupperstr(token)); + sp = " && "; + } else { + fprintf(cfg, "%sADK_LINUX_%s", sp, toupperstr(token)); + sp = " || "; + } + token = strtok(NULL, " "); + } + fprintf(cfg, "\n"); + free(pkg_helper); + pkg_helper = NULL; + } + + /* create package dependency information */ + if (pkg_depends != NULL) { + token = strtok(pkg_depends, " "); + while (token != NULL) { + if (strncmp(token, "kmod", 4) == 0) + fprintf(cfg, "\tselect ADK_KPACKAGE_%s\n", toupperstr(token)); + else + fprintf(cfg, "\tselect ADK_PACKAGE_%s\n", toupperstr(token)); + token = strtok(NULL, " "); + } + free(pkg_depends); + pkg_depends = NULL; + } + /* create system specific package dependency information */ + if (pkg_depends_system != NULL) { + token = strtok(pkg_depends_system, " "); + while (token != NULL) { + fprintf(cfg, "\tselect ADK_PACKAGE_%s if ADK_TARGET_SYSTEM_%s\n", toupperstr(token), sysname); + token = strtok(NULL, " "); + } + free(pkg_depends_system); + pkg_depends_system = NULL; + } + + if (pkg_need_cxx != NULL) { + fprintf(cfg, "\tdepends on ADK_TOOLCHAIN_GCC_CXX\n"); + } + if (pkg_need_java != NULL) { + fprintf(cfg, "\tdepends on ADK_TOOLCHAIN_GCC_JAVA\n"); + pkg_need_java = NULL; + } + + fprintf(cfg, "\tselect ADK_COMPILE_%s\n", toupperstr(pkgdirp->d_name)); + + if (pkg_dflt != NULL) { + fprintf(cfg, "\tdefault %s\n", pkg_dflt); + pkg_dflt = NULL; + } else { + fprintf(cfg, "\tdefault n\n"); + } + + fprintf(cfg, "\thelp\n"); + fprintf(cfg, "\t %s\n\n", pkg_descr); + if (pkg_url != NULL) + fprintf(cfg, "\t WWW: %s\n", pkg_url); + + /* handle special C++ packages */ + if (pkg_cxx != NULL) { + fprintf(cfg, "\nchoice\n"); + fprintf(cfg, "prompt \"C++ library to use\"\n"); + fprintf(cfg, "depends on ADK_COMPILE_%s\n\n", toupperstr(pkgdirp->d_name)); + fprintf(cfg, "default ADK_COMPILE_%s_WITH_STDCXX if ADK_TARGET_LIB_GLIBC\n", pkg_cxx); + fprintf(cfg, "default ADK_COMPILE_%s_WITH_UCLIBCXX if ADK_TARGET_LIB_UCLIBC\n\n", pkg_cxx); + fprintf(cfg, "config ADK_COMPILE_%s_WITH_STDCXX\n", pkg_cxx); + fprintf(cfg, "\tbool \"GNU C++ library\"\n"); + fprintf(cfg, "\tselect ADK_PACKAGE_LIBSTDCXX\n\n"); + fprintf(cfg, "config ADK_COMPILE_%s_WITH_UCLIBCXX\n", pkg_cxx); + fprintf(cfg, "\tbool \"uClibc++ library\"\n"); + fprintf(cfg, "\tselect ADK_PACKAGE_UCLIBCXX\n\n"); + fprintf(cfg, "endchoice\n"); + free(pkg_cxx); + pkg_cxx = NULL; + } + + /* handle debug subpackages */ + fprintf(cfg, "\nconfig ADK_PACKAGE_%s_DBG\n", toupperstr(pkg_debug)); + fprintf(cfg, "\tprompt \"add debug symbols package\"\n"); + fprintf(cfg, "\ttristate\n"); + fprintf(cfg, "\tdepends on ADK_PACKAGE_GDB\n"); + fprintf(cfg, "\tdepends on !ADK_DEBUG\n"); + fprintf(cfg, "\tdepends on ADK_PACKAGE_%s\n", toupperstr(pkg_debug)); + fprintf(cfg, "\tdefault n\n"); + fprintf(cfg, "\thelp\n\n"); + + /* package flavours */ + if (pkg_flavours != NULL) { + token = strtok(pkg_flavours, " "); + while (token != NULL) { + fprintf(cfg, "\nconfig ADK_PACKAGE_%s_%s\n", pkgname, toupperstr(token)); + + // process default value + strncat(hkey, "PKGFX_", 6); + strncat(hkey, token, strlen(token)); + memset(hvalue, 0 , MAXVALUE); + strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); + memset(hkey, 0 , MAXVAR); + pkg_fd = strdup(hvalue); + if (strlen(pkg_fd) > 0) + fprintf(cfg, "\tdefault %s\n", pkg_fd); + else + fprintf(cfg, "\tdefault n\n"); + + + // process flavour cfline + strncat(hkey, "PKGFC_", 6); + strncat(hkey, token, strlen(token)); + memset(hvalue, 0 , MAXVALUE); + strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); + memset(hkey, 0 , MAXVAR); + pkg_fd = strdup(hvalue); + if (strlen(pkg_fd) > 0) + fprintf(cfg, "\t%s\n", pkg_fd); + + fprintf(cfg, "\tboolean "); + strncat(hkey, "PKGFD_", 6); + strncat(hkey, token, strlen(token)); + memset(hvalue, 0 , MAXVALUE); + strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); + memset(hkey, 0 , MAXVAR); + pkg_fd = strdup(hvalue); + + fprintf(cfg, "\"%s\"\n", pkg_fd); + fprintf(cfg, "\tdepends on ADK_PACKAGE_%s\n", pkgname); + strncat(hkey, "PKGFS_", 6); + strncat(hkey, token, strlen(token)); + + result = strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); + if (result == 1) { + val = strtok_r(hvalue, " ", &saveptr); + while (val != NULL) { + if (strncmp(val, "kmod", 4) == 0) + fprintf(cfg, "\tselect ADK_KPACKAGE_%s\n", toupperstr(val)); + else + fprintf(cfg, "\tselect ADK_PACKAGE_%s\n", toupperstr(val)); + val = strtok_r(NULL, " ", &saveptr); + } + } + memset(hkey, 0, MAXVAR); + fprintf(cfg, "\thelp\n"); + fprintf(cfg, "\t %s\n", pkg_fd); + token = strtok(NULL, " "); + } + free(pkg_flavours); + pkg_flavours = NULL; + } + + /* package flavours string */ + if (pkg_flavours_string != NULL) { + token = strtok(pkg_flavours_string, " "); + while (token != NULL) { + fprintf(cfg, "\nconfig ADK_PACKAGE_%s_%s\n", pkgname, toupperstr(token)); + + // process default value + strncat(hkey, "PKGFX_", 6); + strncat(hkey, token, strlen(token)); + memset(hvalue, 0 , MAXVALUE); + strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); + memset(hkey, 0 , MAXVAR); + pkg_fd = strdup(hvalue); + if (strlen(pkg_fd) > 0) + fprintf(cfg, "\tdefault \"%s\"\n", pkg_fd); + + // process flavour cfline + strncat(hkey, "PKGFC_", 6); + strncat(hkey, token, strlen(token)); + memset(hvalue, 0 , MAXVALUE); + strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); + memset(hkey, 0 , MAXVAR); + pkg_fd = strdup(hvalue); + if (strlen(pkg_fd) > 0) + fprintf(cfg, "\t%s\n", pkg_fd); + + fprintf(cfg, "\tstring "); + strncat(hkey, "PKGFD_", 6); + strncat(hkey, token, strlen(token)); + memset(hvalue, 0 , MAXVALUE); + strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); + memset(hkey, 0 , MAXVAR); + pkg_fd = strdup(hvalue); + fprintf(cfg, "\"%s\"\n", pkg_fd); + + fprintf(cfg, "\tdepends on ADK_PACKAGE_%s\n", pkgname); + strncat(hkey, "PKGFS_", 6); + strncat(hkey, token, strlen(token)); + + result = strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); + if (result == 1) { + val = strtok_r(hvalue, " ", &saveptr); + while (val != NULL) { + if (strncmp(val, "kmod", 4) == 0) + fprintf(cfg, "\tselect ADK_KPACKAGE_%s\n", toupperstr(val)); + else + fprintf(cfg, "\tselect ADK_PACKAGE_%s\n", toupperstr(val)); + val = strtok_r(NULL, " ", &saveptr); + } + } + memset(hkey, 0, MAXVAR); + fprintf(cfg, "\thelp\n"); + fprintf(cfg, "\t %s\n", pkg_fd); + token = strtok(NULL, " "); + } + free(pkg_flavours_string); + pkg_flavours_string = NULL; + } + + /* package choices */ + if (pkg_choices != NULL) { + fprintf(cfg, "\nchoice\n"); + fprintf(cfg, "prompt \"Package flavour choice\"\n"); + fprintf(cfg, "depends on ADK_PACKAGE_%s\n\n", pkgname); + token = strtok(pkg_choices, " "); + while (token != NULL) { + fprintf(cfg, "config ADK_PACKAGE_%s_%s\n", pkgname, toupperstr(token)); + + fprintf(cfg, "\tbool "); + strncat(hkey, "PKGCD_", 6); + strncat(hkey, token, strlen(token)); + memset(hvalue, 0 , MAXVALUE); + strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); + memset(hkey, 0 , MAXVAR); + fprintf(cfg, "\"%s\"\n", hvalue); + + strncat(hkey, "PKGCS_", 6); + strncat(hkey, token, strlen(token)); + memset(hvalue, 0, MAXVALUE); + result = strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); + if (result == 1) { + val = strtok_r(hvalue, " ", &saveptr); + while (val != NULL) { + if (strncmp(val, "kmod", 4) == 0) + fprintf(cfg, "\tselect ADK_KPACKAGE_%s\n", toupperstr(val)); + else + fprintf(cfg, "\tselect ADK_PACKAGE_%s\n", toupperstr(val)); + val = strtok_r(NULL, " ", &saveptr); + } + } + memset(hkey, 0, MAXVAR); + token = strtok(NULL, " "); + } + fprintf(cfg, "\nendchoice\n"); + free(pkg_choices); + pkg_choices = NULL; + } + /* close file descriptor for Config.in file */ + fclose(cfg); + /* create Config.in files for development packages */ + if (pkg_opts != NULL) { + if (strstr(pkg_opts, "dev") != NULL) { + if (snprintf(path, MAXPATH, "package/pkgconfigs.d/gcc/Config.in.dev") < 0) + fatal_error("failed to create path variable."); + cfg = fopen(path, "a"); + if (cfg == NULL) + perror("Can not open Config.in.dev file"); + + if (pkg_libname == NULL) + pkg_libname = strdup(pkg_name); + + fprintf(cfg, "\n"); + fprintf(cfg, "config ADK_PACKAGE_%s_DEV\n", toupperstr(pkg_libname)); + + pseudo_name = malloc(MAXLINE); + memset(pseudo_name, 0, MAXLINE); + strncat(pseudo_name, pkg_libname, strlen(pkg_libname)); + strncat(pseudo_name, "-dev", 4); + while (strlen(pseudo_name) < 20) + strncat(pseudo_name, ".", 1); + + fprintf(cfg, "\tprompt \"%s. development files for %s\"\n", pseudo_name, pkg_libname); + fprintf(cfg, "\ttristate\n"); + + /* create package target architecture dependency information */ + if (pkg_arch_depends != NULL) { + pkg_helper = strdup(pkg_arch_depends); + token = strtok(pkg_helper, " "); + fprintf(cfg, "\tdepends on "); + sp = ""; + while (token != NULL) { + if(strncmp(token, "!", 1) == 0) { + fprintf(cfg, "%s!ADK_LINUX%s", sp, toupperstr(token)); + sp = " && "; + } else { + fprintf(cfg, "%sADK_LINUX_%s", sp, toupperstr(token)); + sp = " || "; + } + token = strtok(NULL, " "); + } + fprintf(cfg, "\n"); + free(pkg_helper); + pkg_helper = NULL; + } + + fprintf(cfg, "\tdepends on ADK_PACKAGE_GCC\n"); + fprintf(cfg, "\tselect ADK_PACKAGE_%s\n", toupperstr(pkg_libname)); + fprintf(cfg, "\tdefault n\n"); + fclose(cfg); + free(pseudo_name); + free(pkg_libname); + pkg_libname = NULL; + } + pkg_opts = NULL; + } + /* parse next package */ + token = strtok_r(NULL, " ", &p_ptr); + } + + /* end of package output generation */ + free(packages); + packages = NULL; + + pkg_need_cxx = NULL; + pkg_need_java = NULL; + /* reset flags, free memory */ + free(pkg_name); + free(pkg_libname); + free(pkg_descr); + free(pkg_section); + free(pkg_url); + free(pkg_depends); + free(pkg_flavours); + free(pkg_flavours_string); + free(pkg_choices); + free(pkg_subpkgs); + free(pkg_arch_depends); + free(pkg_system_depends); + free(pkg_host_depends); + free(pkg_libc_depends); + free(pkg_cxx); + free(pkg_dflt); + free(pkg_cfline); + free(pkg_multi); + pkg_name = NULL; + pkg_libname = NULL; + pkg_descr = NULL; + pkg_section = NULL; + pkg_url = NULL; + pkg_depends = NULL; + pkg_flavours = NULL; + pkg_flavours_string = NULL; + pkg_choices = NULL; + pkg_subpkgs = NULL; + pkg_arch_depends = NULL; + pkg_system_depends = NULL; + pkg_host_depends = NULL; + pkg_libc_depends = NULL; + pkg_cxx = NULL; + pkg_dflt = NULL; + pkg_cfline = NULL; + pkg_multi = NULL; + + strmap_delete(pkgmap); + nobinpkgs = 0; + free(hkey); + } + } + + /* add menu to gcc package */ + if (snprintf(path, MAXPATH, "package/pkgconfigs.d/gcc/Config.in.gcc") < 0) + fatal_error("failed to create path variable."); + cfg = fopen(path, "a"); + if (cfg == NULL) + perror("Can not open Config.in.gcc file"); + fprintf(cfg, "menu \"Development packages\"\n"); + fprintf(cfg, "depends on ADK_PACKAGE_GCC\n"); + fprintf(cfg, "source \"package/pkgconfigs.d/gcc/Config.in.dev\"\n"); + fprintf(cfg, "endmenu\n"); + fclose(cfg); + + /* create Config.in.auto */ + strmap_enum(sectionmap, iter, NULL); + + strmap_delete(sectionmap); + fclose(menuglobal); + closedir(pkgdir); + + /* remove temporary section files */ + pkglistdir = opendir("package/pkglist.d"); + while ((pkgdirp = readdir(pkglistdir)) != NULL) { + if (strncmp(pkgdirp->d_name, "sectionlst.", 11) == 0) { + if (snprintf(path, MAXPATH, "package/pkglist.d/%s", pkgdirp->d_name) < 0) + fatal_error("creating path variable failed."); + if (unlink(path) < 0) + fatal_error("removing file failed."); + } + } + closedir(pkglistdir); + return(0); +} diff --git a/adk/tools/pkgrebuild.c b/adk/tools/pkgrebuild.c new file mode 100644 index 000000000..e7f037ae5 --- /dev/null +++ b/adk/tools/pkgrebuild.c @@ -0,0 +1,273 @@ +/* + * pkgrebuild - recognize required package rebuilds in OpenADK + * + * Copyright (C) 2010,2011 Waldemar Brodkorb + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "strmap.h" + +StrMap *configmap, *configoldmap, *pkgmap; + +/* +static void iter(const char *key, const char *value, const void *obj) { + fprintf(stderr, "key: %s value: %s\n", key, value); +} +*/ + +static void iter_disabled(const char *key, const char *value, const void *obj) { + + char hvalue[256]; + char tfile[256]; + int fd; + + memset(hvalue, 0, 256); + if (strmap_exists(configmap, key) == 0) { + //fprintf(stderr, "disabled variables: %s\n", key); + if (strmap_get(pkgmap, key, hvalue, sizeof(hvalue)) == 1) { + //fprintf(stderr, "Symbol is a flavour/choice: %s\n", hvalue); + if (snprintf(tfile, 256, ".rebuild.%s", hvalue) < 0) + perror("can not create file variable."); + fd = open(tfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + close(fd); + } + } + +} + +static void iter_enabled(const char *key, const char *value, const void *obj) { + + char hvalue[256]; + char tfile[256]; + int fd; + + memset(hvalue, 0, 256); + if (strmap_exists(configoldmap, key) == 0) { + //fprintf(stderr, "enabled variables: %s\n", key); + if (strmap_get(pkgmap, key, hvalue, sizeof(hvalue)) == 1) { + //fprintf(stderr, "Symbol is a flavour/choice\n"); + if (snprintf(tfile, 256, ".rebuild.%s", hvalue) < 0) + perror("can not create file variable."); + fd = open(tfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + close(fd); + } + } +} + +static char *toupperstr(char *string) { + + int i; + char *str; + + /* transform to uppercase variable name */ + str = strdup(string); + for (i=0; i<(int)strlen(str); i++) { + if (str[i] == '+') + str[i] = 'X'; + if (str[i] == '-') + str[i] = '_'; + str[i] = toupper(str[i]); + } + return(str); +} + + + +int main() { + + FILE *config, *configold, *pkg; + char *key, *value, *string, *token, *check; + char *pkg_name, *keystr, *realpkgname; + char buf[128]; + char path[320]; + char pbuf[320]; + DIR *pkgdir; + struct dirent *pkgdirp; + + pkg_name = NULL; + /* read Makefile's for all packages */ + pkgmap = strmap_new(1024); + pkgdir = opendir("package"); + while ((pkgdirp = readdir(pkgdir)) != NULL) { + /* skip dotfiles */ + if (strncmp(pkgdirp->d_name, ".", 1) > 0) { + if (snprintf(path, 320, "package/%s/Makefile", pkgdirp->d_name) < 0) + perror("can not create path variable."); + pkg = fopen(path, "r"); + if (pkg == NULL) + continue; + + while (fgets(pbuf, 320, pkg) != NULL) { + if (strncmp(pbuf, "PKG", 3) == 0) { + string = strstr(pbuf, "PKG_NAME:="); + if (string != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, ":="); + value = strtok(NULL, "=\t"); + if (value != NULL) + pkg_name = strdup(value); + } + string = strstr(pbuf, "PKG_SUBPKGS:="); + if (string != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, ":="); + value = strtok(NULL, "=\t"); + token = strtok(value, " "); + while (token != NULL) { + keystr = malloc(256); + memset(keystr, 0, 256); + strncat(keystr, "ADK_PACKAGE_", 12); + strncat(keystr, token, strlen(token)); + strmap_put(pkgmap, keystr, pkgdirp->d_name); + token = strtok(NULL, " "); + free(keystr); + keystr = NULL; + } + } + string = strstr(pbuf, "PKG_SUBPKGS+="); + if (string != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, "+="); + value = strtok(NULL, "=\t"); + token = strtok(value, " "); + while (token != NULL) { + keystr = malloc(256); + memset(keystr, 0, 256); + strncat(keystr, "ADK_PACKAGE_", 12); + strncat(keystr, token, strlen(token)); + strmap_put(pkgmap, keystr, pkgdirp->d_name); + token = strtok(NULL, " "); + free(keystr); + keystr = NULL; + } + } + string = strstr(pbuf, "PKG_FLAVOURS_"); + if (string != NULL) { + check = strstr(pbuf, ":="); + if (check != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, ":="); + realpkgname = strdup(key+13); + value = strtok(NULL, "=\t"); + token = strtok(value, " "); + while (token != NULL) { + keystr = malloc(256); + memset(keystr, 0, 256); + strncat(keystr, "ADK_PACKAGE_", 12); + strncat(keystr, realpkgname, strlen(realpkgname)); + strncat(keystr, "_", 1); + strncat(keystr, token, strlen(token)); + strmap_put(pkgmap, keystr, pkgdirp->d_name); + token = strtok(NULL, " "); + free(keystr); + keystr = NULL; + } + } else { + string[strlen(string)-1] = '\0'; + key = strtok(string, "+="); + realpkgname = strdup(key+13); + value = strtok(NULL, "=\t"); + token = strtok(value, " "); + while (token != NULL) { + keystr = malloc(256); + memset(keystr, 0, 256); + strncat(keystr, "ADK_PACKAGE_", 12); + strncat(keystr, realpkgname, strlen(realpkgname)); + strncat(keystr, "_", 1); + strncat(keystr, token, strlen(token)); + strmap_put(pkgmap, keystr, pkgdirp->d_name); + token = strtok(NULL, " "); + free(keystr); + keystr = NULL; + } + } + } + string = strstr(pbuf, "PKG_CHOICES_"); + if (string != NULL) { + string[strlen(string)-1] = '\0'; + key = strtok(string, ":="); + value = strtok(NULL, "=\t"); + token = strtok(value, " "); + while (token != NULL) { + keystr = malloc(256); + memset(keystr, 0, 256); + strncat(keystr, "ADK_PACKAGE_", 12); + strncat(keystr, toupperstr(pkg_name), strlen(pkg_name)); + strncat(keystr, "_", 1); + strncat(keystr, token, strlen(token)); + strmap_put(pkgmap, keystr, pkgdirp->d_name); + token = strtok(NULL, " "); + free(keystr); + keystr = NULL; + } + } + } + } + fclose(pkg); + } + } + closedir(pkgdir); + + config = fopen(".config", "r"); + if (config == NULL) + perror(".config is missing."); + + configmap = strmap_new(1024); + while (fgets(buf, 128, config) != NULL) { + if (strncmp(buf, "ADK_PACKAGE", 11) == 0) { + key = strtok(buf, "="); + value = strtok(NULL, "="); + strmap_put(configmap, key, value); + } + } + fclose(config); + + configold = fopen(".config.old", "r"); + if (configold == NULL) + perror(".config.old is missing."); + + configoldmap = strmap_new(1024); + while (fgets(buf, 128, configold) != NULL) { + if (strncmp(buf, "ADK_PACKAGE", 11) == 0) { + key = strtok(buf, "="); + value = strtok(NULL, "="); + strmap_put(configoldmap, key, value); + } + } + fclose(configold); + + //fprintf(stdout, "Config Count: %d\n", strmap_get_count(configmap)); + //fprintf(stdout, "Config Old Count: %d\n", strmap_get_count(configoldmap)); + + strmap_enum(configoldmap, iter_disabled, NULL); + strmap_enum(configmap, iter_enabled, NULL); + //strmap_enum(pkgmap, iter, NULL); + + strmap_delete(pkgmap); + strmap_delete(configmap); + strmap_delete(configoldmap); + + return(0); +} diff --git a/adk/tools/sortfile.c b/adk/tools/sortfile.c new file mode 100644 index 000000000..1e9fc9623 --- /dev/null +++ b/adk/tools/sortfile.c @@ -0,0 +1,153 @@ +/*- + * Copyright (c) 2010 + * Thorsten Glaser + * + * Provided that these terms and disclaimer and all copyright notices + * are retained or reproduced in an accompanying document, permission + * is granted to deal in this work without restriction, including un- + * limited rights to use, publicly perform, distribute, sell, modify, + * merge, give away, or sublicence. + * + * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to + * the utmost extent permitted by applicable law, neither express nor + * implied; without malicious intent or gross negligence. In no event + * may a licensor, author or contributor be held liable for indirect, + * direct, other damage, loss, or other issues arising in any way out + * of dealing in the work, even if advised of the possibility of such + * damage or existence of a defect, except proven that it results out + * of said person's immediate fault when using the work as intended. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ptrsize { + const char *ptr; + size_t size; +}; + +static void *xrecalloc(void *, size_t, size_t); +static int cmpfn(const void *, const void *); + +#define MUL_NO_OVERFLOW (1UL << (sizeof (size_t) * 8 / 2)) + +#ifndef SIZE_MAX +#ifdef SIZE_T_MAX +#define SIZE_MAX SIZE_T_MAX +#else +#define SIZE_MAX ((size_t)-1) +#endif +#endif + +#if !defined(MAP_FAILED) +/* XXX imake style */ +# if defined(__linux) +#define MAP_FAILED ((void *)-1) +# elif defined(__bsdi__) || defined(__osf__) || defined(__ultrix) +#define MAP_FAILED ((caddr_t)-1) +# endif +#endif + +static void * +xrecalloc(void *ptr, size_t nmemb, size_t size) +{ + void *rv; + + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && SIZE_MAX / nmemb < size) + errx(1, "attempted integer overflow: %zu * %zu", nmemb, size); + size *= nmemb; + if ((rv = realloc(ptr, size)) == NULL) + err(1, "cannot allocate %zu bytes", size); + return (rv); +} + +int +sortfile(char *infile, char *outfile) +{ + int fd, fdout; + size_t fsz, asz, anents; + char *cp, *thefile, *endfile; + struct ptrsize *thearray; + + if ((fd = open(infile, O_RDONLY)) < 0) + err(1, "open: %s", infile); + else { + struct stat sb; + + /* reasonable maximum size: 3/4 of SIZE_MAX */ + fsz = (SIZE_MAX / 2) + (SIZE_MAX / 4); + + if (fstat(fd, &sb)) + err(1, "stat: %s", infile); + if (sb.st_size > fsz) + errx(1, "file %s too big, %llu > %zu", infile, + (unsigned long long)sb.st_size, fsz); + fsz = (size_t)sb.st_size; + } + + if ((thefile = mmap(NULL, fsz, PROT_READ, MAP_FILE | MAP_PRIVATE, + fd, (off_t)0)) == MAP_FAILED) + err(1, "mmap %zu bytes from %s", fsz, infile); + /* last valid byte in the file, must be newline anyway */ + endfile = thefile + fsz - 1; + + thearray = xrecalloc(NULL, (asz = 8), sizeof(thearray[0])); + thearray[(anents = 0)].ptr = cp = thefile; + + while ((cp = memchr(cp, '\n', endfile - cp)) != NULL) { + /* byte after the \n */ + if (++cp > endfile) + /* end of file */ + break; + thearray[anents].size = cp - thearray[anents].ptr; + if (++anents == asz) + /* resize array */ + thearray = xrecalloc(thearray, (asz <<= 1), + sizeof(thearray[0])); + thearray[anents].ptr = cp; + } + thearray[anents].size = endfile - thearray[anents].ptr + 1; + + qsort(thearray, ++anents, sizeof(thearray[0]), cmpfn); + + if ((fdout = open(outfile, O_WRONLY | O_CREAT, S_IRWXU)) < 0) + err(1, "open: %s", outfile); + else { + for (asz = 0; asz < anents; ++asz) + if ((size_t)write(fdout, thearray[asz].ptr, + thearray[asz].size) != thearray[asz].size) + err(1, "write %zu bytes", thearray[asz].size); + } + + if (munmap(thefile, fsz)) + warn("munmap"); + + free(thearray); + close(fd); + + return (0); +} + +static int +cmpfn(const void *p1, const void *p2) +{ + int rv; + const struct ptrsize *a1 = (const struct ptrsize *)p1; + const struct ptrsize *a2 = (const struct ptrsize *)p2; + + if ((rv = memcmp(a1->ptr, a2->ptr, (a1->size > a2->size ? + a2->size : a1->size) - /* '\n' */ 1)) != 0) + /* unequal in the common part */ + return (rv); + + /* shorter string is smaller */ + return (a1->size > a2->size ? 1 : a1->size == a2->size ? 0 : -1); +} diff --git a/adk/tools/sortfile.h b/adk/tools/sortfile.h new file mode 100644 index 000000000..c54294e69 --- /dev/null +++ b/adk/tools/sortfile.h @@ -0,0 +1 @@ +int sortfile(char *infile, char *outfile); diff --git a/adk/tools/strmap.c b/adk/tools/strmap.c new file mode 100644 index 000000000..f2c660e1f --- /dev/null +++ b/adk/tools/strmap.c @@ -0,0 +1,510 @@ +/* + * strmap version 1.0.0 + * + * ANSI C hash table for strings. + * + * strmap.c + * + * Copyright (c) 2009 Per Ola Kristensson. + * + * Per Ola Kristensson + * Inference Group, Department of Physics + * University of Cambridge + * Cavendish Laboratory + * JJ Thomson Avenue + * CB3 0HE Cambridge + * United Kingdom + * + * strmap is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * strmap is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with strmap. If not, see . + */ +#include "strmap.h" + +typedef struct Pair Pair; + +typedef struct Bucket Bucket; + +struct Pair { + char *key; + char *value; +}; + +struct Bucket { + unsigned int count; + Pair *pairs; +}; + +struct StrMap { + unsigned int count; + Bucket *buckets; +}; + +static Pair * get_pair(Bucket *bucket, const char *key); +static unsigned long hash(const char *str); + +StrMap * strmap_new(unsigned int capacity) +{ + StrMap *map; + + map = malloc(sizeof(StrMap)); + if (map == NULL) { + return NULL; + } + map->count = capacity; + map->buckets = malloc(map->count * sizeof(Bucket)); + if (map->buckets == NULL) { + free(map); + return NULL; + } + memset(map->buckets, 0, map->count * sizeof(Bucket)); + return map; +} + +void strmap_delete(StrMap *map) +{ + unsigned int i, j, n, m; + Bucket *bucket; + Pair *pair; + + if (map == NULL) { + return; + } + n = map->count; + bucket = map->buckets; + i = 0; + while (i < n) { + m = bucket->count; + pair = bucket->pairs; + j = 0; + while(j < m) { + free(pair->key); + free(pair->value); + pair++; + j++; + } + free(bucket->pairs); + bucket++; + i++; + } + free(map->buckets); + free(map); +} + +int strmap_get(const StrMap *map, const char *key, char *out_buf, unsigned int n_out_buf) +{ + unsigned int index; + Bucket *bucket; + Pair *pair; + + if (map == NULL) { + return 0; + } + if (key == NULL) { + return 0; + } + index = hash(key) % map->count; + bucket = &(map->buckets[index]); + pair = get_pair(bucket, key); + if (pair == NULL) { + return 0; + } + if (out_buf == NULL && n_out_buf == 0) { + return strlen(pair->value) + 1; + } + if (out_buf == NULL) { + return 0; + } + if (strlen(pair->value) >= n_out_buf) { + return 0; + } + strcpy(out_buf, pair->value); + return 1; +} + +int strmap_exists(const StrMap *map, const char *key) +{ + unsigned int index; + Bucket *bucket; + Pair *pair; + + if (map == NULL) { + return 0; + } + if (key == NULL) { + return 0; + } + index = hash(key) % map->count; + bucket = &(map->buckets[index]); + pair = get_pair(bucket, key); + if (pair == NULL) { + return 0; + } + return 1; +} + +int strmap_put(StrMap *map, const char *key, const char *value) +{ + unsigned int key_len, value_len, index; + Bucket *bucket; + Pair *tmp_pairs, *pair; + char *tmp_value; + char *new_key, *new_value; + + if (map == NULL) { + return 0; + } + if (key == NULL || value == NULL) { + return 0; + } + key_len = strlen(key); + value_len = strlen(value); + /* Get a pointer to the bucket the key string hashes to */ + index = hash(key) % map->count; + bucket = &(map->buckets[index]); + /* Check if we can handle insertion by simply replacing + * an existing value in a key-value pair in the bucket. + */ + if ((pair = get_pair(bucket, key)) != NULL) { + /* The bucket contains a pair that matches the provided key, + * change the value for that pair to the new value. + */ + if (strlen(pair->value) < value_len) { + /* If the new value is larger than the old value, re-allocate + * space for the new larger value. + */ + tmp_value = realloc(pair->value, (value_len + 1) * sizeof(char)); + if (tmp_value == NULL) { + return 0; + } + pair->value = tmp_value; + } + /* Copy the new value into the pair that matches the key */ + strcpy(pair->value, value); + return 1; + } + /* Allocate space for a new key and value */ + new_key = malloc((key_len + 1) * sizeof(char)); + if (new_key == NULL) { + return 0; + } + new_value = malloc((value_len + 1) * sizeof(char)); + if (new_value == NULL) { + free(new_key); + return 0; + } + /* Create a key-value pair */ + if (bucket->count == 0) { + /* The bucket is empty, lazily allocate space for a single + * key-value pair. + */ + bucket->pairs = malloc(sizeof(Pair)); + if (bucket->pairs == NULL) { + free(new_key); + free(new_value); + return 0; + } + bucket->count = 1; + } + else { + /* The bucket wasn't empty but no pair existed that matches the provided + * key, so create a new key-value pair. + */ + tmp_pairs = realloc(bucket->pairs, (bucket->count + 1) * sizeof(Pair)); + if (tmp_pairs == NULL) { + free(new_key); + free(new_value); + return 0; + } + bucket->pairs = tmp_pairs; + bucket->count++; + } + /* Get the last pair in the chain for the bucket */ + pair = &(bucket->pairs[bucket->count - 1]); + pair->key = new_key; + pair->value = new_value; + /* Copy the key and its value into the key-value pair */ + strcpy(pair->key, key); + strcpy(pair->value, value); + return 1; +} + +int strmap_get_count(const StrMap *map) +{ + unsigned int i, j, n, m; + unsigned int count; + Bucket *bucket; + Pair *pair; + + if (map == NULL) { + return 0; + } + bucket = map->buckets; + n = map->count; + i = 0; + count = 0; + while (i < n) { + pair = bucket->pairs; + m = bucket->count; + j = 0; + while (j < m) { + count++; + pair++; + j++; + } + bucket++; + i++; + } + return count; +} + +int strmap_enum(const StrMap *map, strmap_enum_func enum_func, const void *obj) +{ + unsigned int i, j, n, m; + Bucket *bucket; + Pair *pair; + + if (map == NULL) { + return 0; + } + if (enum_func == NULL) { + return 0; + } + bucket = map->buckets; + n = map->count; + i = 0; + while (i < n) { + pair = bucket->pairs; + m = bucket->count; + j = 0; + while (j < m) { + enum_func(pair->key, pair->value, obj); + pair++; + j++; + } + bucket++; + i++; + } + return 1; +} + +/* + * Returns a pair from the bucket that matches the provided key, + * or null if no such pair exist. + */ +static Pair * get_pair(Bucket *bucket, const char *key) +{ + unsigned int i, n; + Pair *pair; + + n = bucket->count; + if (n == 0) { + return NULL; + } + pair = bucket->pairs; + i = 0; + while (i < n) { + if (pair->key != NULL && pair->value != NULL) { + if (strcmp(pair->key, key) == 0) { + return pair; + } + } + pair++; + i++; + } + return NULL; +} + +/* + * Returns a hash code for the provided string. + */ +static unsigned long hash(const char *str) +{ + unsigned long hash = 5381; + int c; + c = 0; + + while (c == *str++) { + hash = ((hash << 5) + hash) + c; + } + return hash; +} + +/* + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + +*/ diff --git a/adk/tools/strmap.h b/adk/tools/strmap.h new file mode 100644 index 000000000..99687b236 --- /dev/null +++ b/adk/tools/strmap.h @@ -0,0 +1,350 @@ +/* + * strmap version 1.0.0 + * + * ANSI C hash table for strings. + * + * strmap.h + * + * Copyright (c) 2009 Per Ola Kristensson. + * + * Per Ola Kristensson + * Inference Group, Department of Physics + * University of Cambridge + * Cavendish Laboratory + * JJ Thomson Avenue + * CB3 0HE Cambridge + * United Kingdom + * + * strmap is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * strmap is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with strmap. If not, see . + */ +#ifndef _STRMAP_H_ +#define _STRMAP_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +typedef struct StrMap StrMap; + +/* + * This callback function is called once per key-value when enumerating + * all keys associated to values. + * + * Parameters: + * + * key: A pointer to a null-terminated C string. The string must not + * be modified by the client. + * + * value: A pointer to a null-terminated C string. The string must + * not be modified by the client. + * + * obj: A pointer to a client-specific object. This parameter may be + * null. + * + * Return value: None. + */ +typedef void(*strmap_enum_func)(const char *key, const char *value, const void *obj); + +/* + * Creates a string map. + * + * Parameters: + * + * capacity: The number of top-level slots this string map + * should allocate. This parameter must be > 0. + * + * Return value: A pointer to a string map object, + * or null if a new string map could not be allocated. + */ +StrMap * strmap_new(unsigned int capacity); + +/* + * Releases all memory held by a string map object. + * + * Parameters: + * + * map: A pointer to a string map. This parameter cannot be null. + * If the supplied string map has been previously released, the + * behaviour of this function is undefined. + * + * Return value: None. + */ +void strmap_delete(StrMap *map); + +/* + * Returns the value associated with the supplied key. + * + * Parameters: + * + * map: A pointer to a string map. This parameter cannot be null. + * + * key: A pointer to a null-terminated C string. This parameter cannot + * be null. + * + * out_buf: A pointer to an output buffer which will contain the value, + * if it exists and fits into the buffer. + * + * n_out_buf: The size of the output buffer in bytes. + * + * Return value: If out_buf is set to null and n_out_buf is set to 0 the return + * value will be the number of bytes required to store the value (if it exists) + * and its null-terminator. For all other parameter configurations the return value + * is 1 if an associated value was found and completely copied into the output buffer, + * 0 otherwise. + */ +int strmap_get(const StrMap *map, const char *key, char *out_buf, unsigned int n_out_buf); + +/* + * Queries the existence of a key. + * + * Parameters: + * + * map: A pointer to a string map. This parameter cannot be null. + * + * key: A pointer to a null-terminated C string. This parameter cannot + * be null. + * + * Return value: 1 if the key exists, 0 otherwise. + */ +int strmap_exists(const StrMap *map, const char *key); + +/* + * Associates a value with the supplied key. If the key is already + * associated with a value, the previous value is replaced. + * + * Parameters: + * + * map: A pointer to a string map. This parameter cannot be null. + * + * key: A pointer to a null-terminated C string. This parameter + * cannot be null. The string must have a string length > 0. The + * string will be copied. + * + * value: A pointer to a null-terminated C string. This parameter + * cannot be null. The string must have a string length > 0. The + * string will be copied. + * + * Return value: 1 if the association succeeded, 0 otherwise. + */ +int strmap_put(StrMap *map, const char *key, const char *value); + +/* + * Returns the number of associations between keys and values. + * + * Parameters: + * + * map: A pointer to a string map. This parameter cannot be null. + * + * Return value: The number of associations between keys and values. + */ +int strmap_get_count(const StrMap *map); + +/* + * Enumerates all associations between keys and values. + * + * Parameters: + * + * map: A pointer to a string map. This parameter cannot be null. + * + * enum_func: A pointer to a callback function that will be + * called by this procedure once for every key associated + * with a value. This parameter cannot be null. + * + * obj: A pointer to a client-specific object. This parameter will be + * passed back to the client's callback function. This parameter can + * be null. + * + * Return value: 1 if enumeration completed, 0 otherwise. + */ +int strmap_enum(const StrMap *map, strmap_enum_func enum_func, const void *obj); + +#ifdef __cplusplus +} +#endif + +#endif + +/* + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + +*/ diff --git a/config/Config.in b/config/Config.in deleted file mode 100644 index 9a7778310..000000000 --- a/config/Config.in +++ /dev/null @@ -1,8 +0,0 @@ -# - -config ADK_PACKAGE_CONFIG - bool"config" - default n - help - Add help text here. - diff --git a/config/Kconfig-language.txt b/config/Kconfig-language.txt deleted file mode 100644 index c412c2458..000000000 --- a/config/Kconfig-language.txt +++ /dev/null @@ -1,379 +0,0 @@ -Introduction ------------- - -The configuration database is a collection of configuration options -organized in a tree structure: - - +- Code maturity level options - | +- Prompt for development and/or incomplete code/drivers - +- General setup - | +- Networking support - | +- System V IPC - | +- BSD Process Accounting - | +- Sysctl support - +- Loadable module support - | +- Enable loadable module support - | +- Set version information on all module symbols - | +- Kernel module loader - +- ... - -Every entry has its own dependencies. These dependencies are used -to determine the visibility of an entry. Any child entry is only -visible if its parent entry is also visible. - -Menu entries ------------- - -Most entries define a config option; all other entries help to organize -them. A single configuration option is defined like this: - -config MODVERSIONS - bool "Set version information on all module symbols" - depends on MODULES - help - Usually, modules have to be recompiled whenever you switch to a new - kernel. ... - -Every line starts with a key word and can be followed by multiple -arguments. "config" starts a new config entry. The following lines -define attributes for this config option. Attributes can be the type of -the config option, input prompt, dependencies, help text and default -values. A config option can be defined multiple times with the same -name, but every definition can have only a single input prompt and the -type must not conflict. - -Menu attributes ---------------- - -A menu entry can have a number of attributes. Not all of them are -applicable everywhere (see syntax). - -- type definition: "bool"/"tristate"/"string"/"hex"/"int" - Every config option must have a type. There are only two basic types: - tristate and string; the other types are based on these two. The type - definition optionally accepts an input prompt, so these two examples - are equivalent: - - bool "Networking support" - and - bool - prompt "Networking support" - -- input prompt: "prompt" ["if" ] - Every menu entry can have at most one prompt, which is used to display - to the user. Optionally dependencies only for this prompt can be added - with "if". - -- default value: "default" ["if" ] - A config option can have any number of default values. If multiple - default values are visible, only the first defined one is active. - Default values are not limited to the menu entry where they are - defined. This means the default can be defined somewhere else or be - overridden by an earlier definition. - The default value is only assigned to the config symbol if no other - value was set by the user (via the input prompt above). If an input - prompt is visible the default value is presented to the user and can - be overridden by him. - Optionally, dependencies only for this default value can be added with - "if". - -- type definition + default value: - "def_bool"/"def_tristate" ["if" ] - This is a shorthand notation for a type definition plus a value. - Optionally dependencies for this default value can be added with "if". - -- dependencies: "depends on" - This defines a dependency for this menu entry. If multiple - dependencies are defined, they are connected with '&&'. Dependencies - are applied to all other options within this menu entry (which also - accept an "if" expression), so these two examples are equivalent: - - bool "foo" if BAR - default y if BAR - and - depends on BAR - bool "foo" - default y - -- reverse dependencies: "select" ["if" ] - While normal dependencies reduce the upper limit of a symbol (see - below), reverse dependencies can be used to force a lower limit of - another symbol. The value of the current menu symbol is used as the - minimal value can be set to. If is selected multiple - times, the limit is set to the largest selection. - Reverse dependencies can only be used with boolean or tristate - symbols. - Note: - select should be used with care. select will force - a symbol to a value without visiting the dependencies. - By abusing select you are able to select a symbol FOO even - if FOO depends on BAR that is not set. - In general use select only for non-visible symbols - (no prompts anywhere) and for symbols with no dependencies. - That will limit the usefulness but on the other hand avoid - the illegal configurations all over. - kconfig should one day warn about such things. - -- numerical ranges: "range" ["if" ] - This allows to limit the range of possible input values for int - and hex symbols. The user can only input a value which is larger than - or equal to the first symbol and smaller than or equal to the second - symbol. - -- help text: "help" or "---help---" - This defines a help text. The end of the help text is determined by - the indentation level, this means it ends at the first line which has - a smaller indentation than the first line of the help text. - "---help---" and "help" do not differ in behaviour, "---help---" is - used to help visually separate configuration logic from help within - the file as an aid to developers. - -- misc options: "option" [=] - Various less common options can be defined via this option syntax, - which can modify the behaviour of the menu entry and its config - symbol. These options are currently possible: - - - "defconfig_list" - This declares a list of default entries which can be used when - looking for the default configuration (which is used when the main - .config doesn't exists yet.) - - - "modules" - This declares the symbol to be used as the MODULES symbol, which - enables the third modular state for all config symbols. - - - "env"= - This imports the environment variable into Kconfig. It behaves like - a default, except that the value comes from the environment, this - also means that the behaviour when mixing it with normal defaults is - undefined at this point. The symbol is currently not exported back - to the build environment (if this is desired, it can be done via - another symbol). - -Menu dependencies ------------------ - -Dependencies define the visibility of a menu entry and can also reduce -the input range of tristate symbols. The tristate logic used in the -expressions uses one more state than normal boolean logic to express the -module state. Dependency expressions have the following syntax: - - ::= (1) - '=' (2) - '!=' (3) - '(' ')' (4) - '!' (5) - '&&' (6) - '||' (7) - -Expressions are listed in decreasing order of precedence. - -(1) Convert the symbol into an expression. Boolean and tristate symbols - are simply converted into the respective expression values. All - other symbol types result in 'n'. -(2) If the values of both symbols are equal, it returns 'y', - otherwise 'n'. -(3) If the values of both symbols are equal, it returns 'n', - otherwise 'y'. -(4) Returns the value of the expression. Used to override precedence. -(5) Returns the result of (2-/expr/). -(6) Returns the result of min(/expr/, /expr/). -(7) Returns the result of max(/expr/, /expr/). - -An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 -respectively for calculations). A menu entry becomes visible when it's -expression evaluates to 'm' or 'y'. - -There are two types of symbols: constant and non-constant symbols. -Non-constant symbols are the most common ones and are defined with the -'config' statement. Non-constant symbols consist entirely of alphanumeric -characters or underscores. -Constant symbols are only part of expressions. Constant symbols are -always surrounded by single or double quotes. Within the quote, any -other character is allowed and the quotes can be escaped using '\'. - -Menu structure --------------- - -The position of a menu entry in the tree is determined in two ways. First -it can be specified explicitly: - -menu "Network device support" - depends on NET - -config NETDEVICES - ... - -endmenu - -All entries within the "menu" ... "endmenu" block become a submenu of -"Network device support". All subentries inherit the dependencies from -the menu entry, e.g. this means the dependency "NET" is added to the -dependency list of the config option NETDEVICES. - -The other way to generate the menu structure is done by analyzing the -dependencies. If a menu entry somehow depends on the previous entry, it -can be made a submenu of it. First, the previous (parent) symbol must -be part of the dependency list and then one of these two conditions -must be true: -- the child entry must become invisible, if the parent is set to 'n' -- the child entry must only be visible, if the parent is visible - -config MODULES - bool "Enable loadable module support" - -config MODVERSIONS - bool "Set version information on all module symbols" - depends on MODULES - -comment "module support disabled" - depends on !MODULES - -MODVERSIONS directly depends on MODULES, this means it's only visible if -MODULES is different from 'n'. The comment on the other hand is always -visible when MODULES is visible (the (empty) dependency of MODULES is -also part of the comment dependencies). - - -Kconfig syntax --------------- - -The configuration file describes a series of menu entries, where every -line starts with a keyword (except help texts). The following keywords -end a menu entry: -- config -- menuconfig -- choice/endchoice -- comment -- menu/endmenu -- if/endif -- source -The first five also start the definition of a menu entry. - -config: - - "config" - - -This defines a config symbol and accepts any of above -attributes as options. - -menuconfig: - "menuconfig" - - -This is similar to the simple config entry above, but it also gives a -hint to front ends, that all suboptions should be displayed as a -separate list of options. - -choices: - - "choice" - - - "endchoice" - -This defines a choice group and accepts any of the above attributes as -options. A choice can only be of type bool or tristate, while a boolean -choice only allows a single config entry to be selected, a tristate -choice also allows any number of config entries to be set to 'm'. This -can be used if multiple drivers for a single hardware exists and only a -single driver can be compiled/loaded into the kernel, but all drivers -can be compiled as modules. -A choice accepts another option "optional", which allows to set the -choice to 'n' and no entry needs to be selected. - -comment: - - "comment" - - -This defines a comment which is displayed to the user during the -configuration process and is also echoed to the output files. The only -possible options are dependencies. - -menu: - - "menu" - - - "endmenu" - -This defines a menu block, see "Menu structure" above for more -information. The only possible options are dependencies. - -if: - - "if" - - "endif" - -This defines an if block. The dependency expression is appended -to all enclosed menu entries. - -source: - - "source" - -This reads the specified configuration file. This file is always parsed. - -mainmenu: - - "mainmenu" - -This sets the config program's title bar if the config program chooses -to use it. - - -Kconfig hints -------------- -This is a collection of Kconfig tips, most of which aren't obvious at -first glance and most of which have become idioms in several Kconfig -files. - -Adding common features and make the usage configurable -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -It is a common idiom to implement a feature/functionality that are -relevant for some architectures but not all. -The recommended way to do so is to use a config variable named HAVE_* -that is defined in a common Kconfig file and selected by the relevant -architectures. -An example is the generic IOMAP functionality. - -We would in lib/Kconfig see: - -# Generic IOMAP is used to ... -config HAVE_GENERIC_IOMAP - -config GENERIC_IOMAP - depends on HAVE_GENERIC_IOMAP && FOO - -And in lib/Makefile we would see: -obj-$(CONFIG_GENERIC_IOMAP) += iomap.o - -For each architecture using the generic IOMAP functionality we would see: - -config X86 - select ... - select HAVE_GENERIC_IOMAP - select ... - -Note: we use the existing config option and avoid creating a new -config variable to select HAVE_GENERIC_IOMAP. - -Note: the use of the internal config variable HAVE_GENERIC_IOMAP, it is -introduced to overcome the limitation of select which will force a -config option to 'y' no matter the dependencies. -The dependencies are moved to the symbol GENERIC_IOMAP and we avoid the -situation where select forces a symbol equals to 'y'. - -Build as module only -~~~~~~~~~~~~~~~~~~~~ -To restrict a component build to module-only, qualify its config symbol -with "depends on m". E.g.: - -config FOO - depends on BAR && m - -limits FOO to module (=m) or disabled (=n). - diff --git a/config/Makefile b/config/Makefile deleted file mode 100644 index 9dc08d3ac..000000000 --- a/config/Makefile +++ /dev/null @@ -1,131 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -ifneq ($(filter-out clean,${MAKECMDGOALS}),) -include ${TOPDIR}/rules.mk -endif - -CP=cp -fpR -CFLAGS_FOR_BUILD:=-DKBUILD_NO_NLS -O2 -w - -all: ncurses conf mconf - -LIBS= -lncurses -ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h)) -CFLAGS_FOR_BUILD+= -I/usr/include/ncurses -DCURSES_LOC="" -else -ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h)) -CFLAGS_FOR_BUILD+= -I/usr/include/ncurses -DCURSES_LOC="" -else -ifeq (/usr/local/include/ncurses/ncurses.h, $(wildcard /usr/local/include/ncurses/ncurses.h)) -CFLAGS_FOR_BUILD+= -I/usr/local/include/ncurses -DCURSES_LOC="" -else -ifeq (/usr/local/include/ncurses/curses.h, $(wildcard /usr/local/include/ncurses/curses.h)) -CFLAGS_FOR_BUILD+= -I/usr/local/include/ncurses -DCURSES_LOC="" -else -ifeq (/usr/pkg/include/ncurses.h, $(wildcard /usr/pkg/include/ncurses.h)) -CFLAGS_FOR_BUILD+= -I/usr/pkg/include -DCURSES_LOC="" -LIBS+= -L/usr/pkg/lib -Wl,-rpath -Wl,/usr/pkg/lib -else -ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h)) -CFLAGS_FOR_BUILD+= -DCURSES_LOC="" -else -CFLAGS_FOR_BUILD+= -DCURSES_LOC="" -LIBS= -lcurses -endif -endif -endif -endif -endif -endif - -CONF_SRC =conf.c -MCONF_SRC =mconf.c $(wildcard lxdialog/*.c) -SHARED_SRC=zconf.tab.c -SHARED_DEPS:=lkc.h lkc_proto.h lkc_defs.h expr.h zconf.tab.h -CONF_OBJS =$(patsubst %.c,%.o, $(CONF_SRC)) -MCONF_OBJS=$(patsubst %.c,%.o, $(MCONF_SRC)) -SHARED_OBJS=$(patsubst %.c,%.o, $(SHARED_SRC)) - -conf: $(CONF_OBJS) $(SHARED_OBJS) - @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $^ -o $@ - -mconf: $(MCONF_OBJS) $(SHARED_OBJS) - @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $^ -o $@ $(LIBS) - -$(CONF_OBJS): %.o : %.c $(SHARED_DEPS) - @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c $< -o $@ - -$(MCONF_OBJS): %.o : %.c $(SHARED_DEPS) - @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c $< -o $@ - -glob.o: glob.c $(SHARED_DEPS) - @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c glob.c -o $@ - -lkc_defs.h: lkc_proto.h - @sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' - -### -# The following requires flex/bison -# By default we use the _shipped versions, uncomment the -# following line if you are modifying the flex/bison src. -#LKC_GENPARSER:= 1 - -ifdef LKC_GENPARSER - -%.tab.c %.tab.h: %.y - bison -t -d -v -b $* -p $(notdir $*) $< - -%.hash.c: %.gperf - gperf < $< > $@ - -lex.%.c: %.l - flex -P$(notdir $*) -o$@ $< - -lex.zconf.o: lex.zconf.c $(SHARED_DEPS) - @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c $< -o $@ - -zconf.tab.o: zconf.tab.c zconf.hash.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(SHARED_DEPS) - @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c $< -o $@ - -else - -lex.zconf.o: lex.zconf.c $(SHARED_DEPS) - @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c $< -o $@ - -lex.zconf.c: lex.zconf.c_shipped - @$(CP) lex.zconf.c_shipped lex.zconf.c - -zconf.hash.c: zconf.hash.c_shipped - @$(CP) zconf.hash.c_shipped zconf.hash.c - -zconf.tab.o: zconf.tab.c zconf.hash.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(SHARED_DEPS) - @$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I. -c $< -o $@ - -zconf.tab.c: zconf.tab.c_shipped - @$(CP) zconf.tab.c_shipped zconf.tab.c - -zconf.tab.h: zconf.tab.h_shipped - @$(CP) zconf.tab.h_shipped zconf.tab.h -endif - -.PHONY: ncurses - -ncurses: - @echo "int main(void) { return -1; }" > lxtemp.c - @if $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) lxtemp.c $(LIBS) ; then \ - rm -f lxtemp.c a.out; \ - else \ - rm -f lxtemp.c; \ - printf '\007'; \ - echo ">> Unable to find the Ncurses libraries." ;\ - echo ">>" ;\ - echo ">> You must have Ncurses installed in order" ;\ - echo ">> to use 'make menuconfig'" ;\ - echo ;\ - exit 1 ;\ - fi - -clean: - @rm -f *.o *~ core $(TARGETS) $(MCONF_OBJS) $(CONF_OBJS) zconf.hash.c \ - conf mconf zconf.tab.c zconf.tab.h lex.zconf.c lkc_defs.h diff --git a/config/Makefile.in b/config/Makefile.in deleted file mode 100644 index 0b3ac40a9..000000000 --- a/config/Makefile.in +++ /dev/null @@ -1,5 +0,0 @@ -ifeq ($(strip $(ADK_PACKAGE_CONFIG)),y) -TARGETS+=config -endif - -include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/config/check.sh b/config/check.sh deleted file mode 100755 index fa59cbf9d..000000000 --- a/config/check.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# Needed for systems without gettext -$* -xc -o /dev/null - > /dev/null 2>&1 << EOF -#include -int main() -{ - gettext(""); - return 0; -} -EOF -if [ ! "$?" -eq "0" ]; then - echo -DKBUILD_NO_NLS; -fi - diff --git a/config/conf.c b/config/conf.c deleted file mode 100644 index 412656fec..000000000 --- a/config/conf.c +++ /dev/null @@ -1,619 +0,0 @@ -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LKC_DIRECT_LINK -#include "lkc.h" - -static void conf(struct menu *menu); -static void check_conf(struct menu *menu); - -enum { - ask_all, - ask_new, - ask_silent, - set_default, - set_yes, - set_mod, - set_no, - set_random -} input_mode = ask_all; -char *defconfig_file; - -static int indent = 1; -static int valid_stdin = 1; -static int sync_kconfig; -static int conf_cnt; -static char line[128]; -static struct menu *rootEntry; - -static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n"); - -static const char *get_help(struct menu *menu) -{ - if (menu_has_help(menu)) - return _(menu_get_help(menu)); - else - return nohelp_text; -} - -static void strip(char *str) -{ - char *p = str; - int l; - - while ((isspace(*p))) - p++; - l = strlen(p); - if (p != str) - memmove(str, p, l + 1); - if (!l) - return; - p = str + l - 1; - while ((isspace(*p))) - *p-- = 0; -} - -static void check_stdin(void) -{ - if (!valid_stdin) { - printf("aborted!\n\n"); - printf("Console input/output is redirected. "); - printf("Run 'make oldconfig' to update configuration.\n\n"); - exit(1); - } -} - -static int conf_askvalue(struct symbol *sym, const char *def) -{ - enum symbol_type type = sym_get_type(sym); - - if (!sym_has_value(sym)) - printf("(NEW) "); - - line[0] = '\n'; - line[1] = 0; - - if (!sym_is_changable(sym)) { - printf("%s\n", def); - line[0] = '\n'; - line[1] = 0; - return 0; - } - - switch (input_mode) { - case ask_new: - case ask_silent: - if (sym_has_value(sym)) { - printf("%s\n", def); - return 0; - } - check_stdin(); - case ask_all: - fflush(stdout); - if (fgets(line, 128, stdin) != NULL) - return 1; - default: - break; - } - - switch (type) { - case S_INT: - case S_HEX: - case S_STRING: - printf("%s\n", def); - return 1; - default: - ; - } - printf("%s", line); - return 1; -} - -int conf_string(struct menu *menu) -{ - struct symbol *sym = menu->sym; - const char *def; - - while (1) { - printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); - printf("(%s) ", sym->name); - def = sym_get_string_value(sym); - if (sym_get_string_value(sym)) - printf("[%s] ", def); - if (!conf_askvalue(sym, def)) - return 0; - switch (line[0]) { - case '\n': - break; - case '?': - /* print help */ - if (line[1] == '\n') { - printf("\n%s\n", get_help(menu)); - def = NULL; - break; - } - default: - line[strlen(line)-1] = 0; - def = line; - } - if (def && sym_set_string_value(sym, def)) - return 0; - } -} - -static int conf_sym(struct menu *menu) -{ - struct symbol *sym = menu->sym; - int type; - tristate oldval, newval; - - while (1) { - printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); - if (sym->name) - printf("(%s) ", sym->name); - type = sym_get_type(sym); - putchar('['); - oldval = sym_get_tristate_value(sym); - switch (oldval) { - case no: - putchar('N'); - break; - case mod: - putchar('M'); - break; - case yes: - putchar('Y'); - break; - } - if (oldval != no && sym_tristate_within_range(sym, no)) - printf("/n"); - if (oldval != mod && sym_tristate_within_range(sym, mod)) - printf("/m"); - if (oldval != yes && sym_tristate_within_range(sym, yes)) - printf("/y"); - if (menu_has_help(menu)) - printf("/?"); - printf("] "); - if (!conf_askvalue(sym, sym_get_string_value(sym))) - return 0; - strip(line); - - switch (line[0]) { - case 'n': - case 'N': - newval = no; - if (!line[1] || !strcmp(&line[1], "o")) - break; - continue; - case 'm': - case 'M': - newval = mod; - if (!line[1]) - break; - continue; - case 'y': - case 'Y': - newval = yes; - if (!line[1] || !strcmp(&line[1], "es")) - break; - continue; - case 0: - newval = oldval; - break; - case '?': - goto help; - default: - continue; - } - if (sym_set_tristate_value(sym, newval)) - return 0; -help: - printf("\n%s\n", get_help(menu)); - } -} - -static int conf_choice(struct menu *menu) -{ - struct symbol *sym, *def_sym; - struct menu *child; - int type; - bool is_new; - - sym = menu->sym; - type = sym_get_type(sym); - is_new = !sym_has_value(sym); - if (sym_is_changable(sym)) { - conf_sym(menu); - sym_calc_value(sym); - switch (sym_get_tristate_value(sym)) { - case no: - return 1; - case mod: - return 0; - case yes: - break; - } - } else { - switch (sym_get_tristate_value(sym)) { - case no: - return 1; - case mod: - printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); - return 0; - case yes: - break; - } - } - - while (1) { - int cnt, def; - - printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); - def_sym = sym_get_choice_value(sym); - cnt = def = 0; - line[0] = 0; - for (child = menu->list; child; child = child->next) { - if (!menu_is_visible(child)) - continue; - if (!child->sym) { - printf("%*c %s\n", indent, '*', _(menu_get_prompt(child))); - continue; - } - cnt++; - if (child->sym == def_sym) { - def = cnt; - printf("%*c", indent, '>'); - } else - printf("%*c", indent, ' '); - printf(" %d. %s", cnt, _(menu_get_prompt(child))); - if (child->sym->name) - printf(" (%s)", child->sym->name); - if (!sym_has_value(child->sym)) - printf(" (NEW)"); - printf("\n"); - } - printf(_("%*schoice"), indent - 1, ""); - if (cnt == 1) { - printf("[1]: 1\n"); - goto conf_childs; - } - printf("[1-%d", cnt); - if (menu_has_help(menu)) - printf("?"); - printf("]: "); - switch (input_mode) { - case ask_new: - case ask_silent: - if (!is_new) { - cnt = def; - printf("%d\n", cnt); - break; - } - check_stdin(); - case ask_all: - fflush(stdout); - if (fgets(line, 128, stdin) != NULL) - strip(line); - if (line[0] == '?') { - printf("\n%s\n", get_help(menu)); - continue; - } - if (!line[0]) - cnt = def; - else if (isdigit(line[0])) - cnt = atoi(line); - else - continue; - break; - default: - break; - } - - conf_childs: - for (child = menu->list; child; child = child->next) { - if (!child->sym || !menu_is_visible(child)) - continue; - if (!--cnt) - break; - } - if (!child) - continue; - if (line[strlen(line) - 1] == '?') { - printf("\n%s\n", get_help(child)); - continue; - } - sym_set_choice_value(sym, child->sym); - for (child = child->list; child; child = child->next) { - indent += 2; - conf(child); - indent -= 2; - } - return 1; - } -} - -static void conf(struct menu *menu) -{ - struct symbol *sym; - struct property *prop; - struct menu *child; - - if (!menu_is_visible(menu)) - return; - - sym = menu->sym; - prop = menu->prompt; - if (prop) { - const char *prompt; - - switch (prop->type) { - case P_MENU: - if (input_mode == ask_silent && rootEntry != menu) { - check_conf(menu); - return; - } - case P_COMMENT: - prompt = menu_get_prompt(menu); - if (prompt) - printf("%*c\n%*c %s\n%*c\n", - indent, '*', - indent, '*', _(prompt), - indent, '*'); - default: - ; - } - } - - if (!sym) - goto conf_childs; - - if (sym_is_choice(sym)) { - conf_choice(menu); - if (sym->curr.tri != mod) - return; - goto conf_childs; - } - - switch (sym->type) { - case S_INT: - case S_HEX: - case S_STRING: - conf_string(menu); - break; - default: - conf_sym(menu); - break; - } - -conf_childs: - if (sym) - indent += 2; - for (child = menu->list; child; child = child->next) - conf(child); - if (sym) - indent -= 2; -} - -static void check_conf(struct menu *menu) -{ - struct symbol *sym; - struct menu *child; - - if (!menu_is_visible(menu)) - return; - - sym = menu->sym; - if (sym && !sym_has_value(sym)) { - if (sym_is_changable(sym) || - (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { - if (!conf_cnt++) - printf("*\n* Restart config...\n*\n"); - rootEntry = menu_get_parent_menu(menu); - conf(rootEntry); - } - } - - for (child = menu->list; child; child = child->next) - check_conf(child); -} - -int main(int ac, char **av) -{ - int opt; - const char *name; - struct stat tmpstat; - -#ifndef KBUILD_NO_NLS - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); -#endif - - while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) { - switch (opt) { - case 'o': - input_mode = ask_silent; - break; - case 's': - input_mode = ask_silent; - sync_kconfig = 1; - break; - case 'd': - input_mode = set_default; - break; - case 'D': - input_mode = set_default; - defconfig_file = optarg; - break; - case 'n': - input_mode = set_no; - break; - case 'm': - input_mode = set_mod; - break; - case 'y': - input_mode = set_yes; - break; - case 'r': - { - struct timeval now; - unsigned int seed; - - /* - * Use microseconds derived seed, - * compensate for systems where it may be zero - */ - gettimeofday(&now, NULL); - - seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); - srand(seed); - - input_mode = set_random; - break; - } - case 'h': - printf("See README for usage info\n"); - exit(0); - break; - default: - fprintf(stderr, "See README for usage info\n"); - exit(1); - } - } - if (ac == optind) { - printf(_("%s: Kconfig file missing\n"), av[0]); - exit(1); - } - name = av[optind]; - conf_parse(name); - //zconfdump(stdout); - if (sync_kconfig) { - name = conf_get_configname(); - if (stat(name, &tmpstat)) { - fprintf(stderr, _("***\n" - "*** You have not yet configured your kernel!\n" - "*** (missing kernel config file \"%s\")\n" - "***\n" - "*** Please run some configurator (e.g. \"make oldconfig\" or\n" - "*** \"make menuconfig\" or \"make xconfig\").\n" - "***\n"), name); - exit(1); - } - } - - switch (input_mode) { - case set_default: - if (!defconfig_file) - defconfig_file = conf_get_default_confname(); - if (conf_read(defconfig_file)) { - printf(_("***\n" - "*** Can't find default configuration \"%s\"!\n" - "***\n"), defconfig_file); - exit(1); - } - break; - case ask_silent: - case ask_all: - case ask_new: - conf_read(NULL); - break; - case set_no: - case set_mod: - case set_yes: - case set_random: - name = getenv("KCONFIG_ALLCONFIG"); - if (name && !stat(name, &tmpstat)) { - conf_read_simple(name, S_DEF_USER); - break; - } - switch (input_mode) { - case set_no: name = "allno.config"; break; - case set_mod: name = "allmod.config"; break; - case set_yes: name = "allyes.config"; break; - case set_random: name = "allrandom.config"; break; - default: break; - } - if (!stat(name, &tmpstat)) - conf_read_simple(name, S_DEF_USER); - else if (!stat("all.config", &tmpstat)) - conf_read_simple("all.config", S_DEF_USER); - break; - default: - break; - } - - if (sync_kconfig) { - if (conf_get_changed()) { - name = getenv("KCONFIG_NOSILENTUPDATE"); - if (name && *name) { - fprintf(stderr, - "\n*** Kernel configuration requires explicit update.\n\n"); - return 1; - } - } - valid_stdin = isatty(0) && isatty(1) && isatty(2); - } - - switch (input_mode) { - case set_no: - conf_set_all_new_symbols(def_no); - break; - case set_yes: - conf_set_all_new_symbols(def_yes); - break; - case set_mod: - conf_set_all_new_symbols(def_mod); - break; - case set_random: - conf_set_all_new_symbols(def_random); - break; - case set_default: - conf_set_all_new_symbols(def_default); - break; - case ask_new: - case ask_all: - rootEntry = &rootmenu; - conf(&rootmenu); - input_mode = ask_silent; - /* fall through */ - case ask_silent: - /* Update until a loop caused no more changes */ - do { - conf_cnt = 0; - check_conf(&rootmenu); - } while (conf_cnt); - break; - } - - if (sync_kconfig) { - /* silentoldconfig is used during the build so we shall update autoconf. - * All other commands are only used to generate a config. - */ - if (conf_get_changed() && conf_write(NULL)) { - fprintf(stderr, "\n*** Error during writing of the kernel configuration.\n\n"); - exit(1); - } - if (conf_write_autoconf()) { - fprintf(stderr, "\n*** Error during update of the kernel configuration.\n\n"); - return 1; - } - } else { - if (conf_write(NULL)) { - fprintf(stderr, "\n*** Error during writing of the kernel configuration.\n\n"); - exit(1); - } - } - return 0; -} diff --git a/config/confdata.c b/config/confdata.c deleted file mode 100644 index 4a79c72bb..000000000 --- a/config/confdata.c +++ /dev/null @@ -1,899 +0,0 @@ -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define LKC_DIRECT_LINK -#include "lkc.h" - -static void conf_warning(const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); - -static const char *conf_filename; -static int conf_lineno, conf_warnings, conf_unsaved; - -const char conf_defname[] = "arch/$ARCH/defconfig"; - -static void conf_warning(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - conf_warnings++; -} - -const char *conf_get_configname(void) -{ - char *name = getenv("KCONFIG_CONFIG"); - - return name ? name : ".config"; -} - -const char *conf_get_autoconfig_name(void) -{ - char *name = getenv("KCONFIG_AUTOCONFIG"); - - return name ? name : "include/config/auto.conf"; -} - -static char *conf_expand_value(const char *in) -{ - struct symbol *sym; - const char *src; - static char res_value[SYMBOL_MAXLENGTH]; - char *dst, name[SYMBOL_MAXLENGTH]; - - res_value[0] = 0; - dst = name; - while ((src = strchr(in, '$'))) { - strncat(res_value, in, src - in); - src++; - dst = name; - while (isalnum(*src) || *src == '_') - *dst++ = *src++; - *dst = 0; - sym = sym_lookup(name, 0); - sym_calc_value(sym); - strcat(res_value, sym_get_string_value(sym)); - in = src; - } - strcat(res_value, in); - - return res_value; -} - -char *conf_get_default_confname(void) -{ - struct stat buf; - static char fullname[PATH_MAX+1]; - char *env, *name; - - name = conf_expand_value(conf_defname); - env = getenv(SRCTREE); - if (env) { - sprintf(fullname, "%s/%s", env, name); - if (!stat(fullname, &buf)) - return fullname; - } - return name; -} - -static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) -{ - char *p2; - - switch (sym->type) { - case S_TRISTATE: - if (p[0] == 'm') { - sym->def[def].tri = mod; - sym->flags |= def_flags; - break; - } - case S_BOOLEAN: - if (p[0] == 'y') { - sym->def[def].tri = yes; - sym->flags |= def_flags; - break; - } - if (p[0] == 'n') { - sym->def[def].tri = no; - sym->flags |= def_flags; - break; - } - conf_warning("symbol value '%s' invalid for %s", p, sym->name); - break; - case S_OTHER: - if (*p != '"') { - for (p2 = p; *p2 && !isspace(*p2); p2++) - ; - sym->type = S_STRING; - goto done; - } - case S_STRING: - if (*p++ != '"') - break; - for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { - if (*p2 == '"') { - *p2 = 0; - break; - } - memmove(p2, p2 + 1, strlen(p2)); - } - if (!p2) { - conf_warning("invalid string found"); - return 1; - } - case S_INT: - case S_HEX: - done: - if (sym_string_valid(sym, p)) { - sym->def[def].val = strdup(p); - sym->flags |= def_flags; - } else { - conf_warning("symbol value '%s' invalid for %s", p, sym->name); - return 1; - } - break; - default: - ; - } - return 0; -} - -int conf_read_simple(const char *name, int def) -{ - FILE *in = NULL; - char line[1024]; - char *p, *p2; - struct symbol *sym; - int i, def_flags; - - if (name) { - in = zconf_fopen(name); - } else { - struct property *prop; - - name = conf_get_configname(); - in = zconf_fopen(name); - if (in) - goto load; - sym_add_change_count(1); - if (!sym_defconfig_list) - return 1; - - for_all_defaults(sym_defconfig_list, prop) { - if (expr_calc_value(prop->visible.expr) == no || - prop->expr->type != E_SYMBOL) - continue; - name = conf_expand_value(prop->expr->left.sym->name); - in = zconf_fopen(name); - if (in) { - printf(_("#\n" - "# using defaults found in %s\n" - "#\n"), name); - goto load; - } - } - } - if (!in) - return 1; - -load: - conf_filename = name; - conf_lineno = 0; - conf_warnings = 0; - conf_unsaved = 0; - - def_flags = SYMBOL_DEF << def; - for_all_symbols(i, sym) { - sym->flags |= SYMBOL_CHANGED; - sym->flags &= ~(def_flags|SYMBOL_VALID); - if (sym_is_choice(sym)) - sym->flags |= def_flags; - switch (sym->type) { - case S_INT: - case S_HEX: - case S_STRING: - if (sym->def[def].val) - free(sym->def[def].val); - default: - sym->def[def].val = NULL; - sym->def[def].tri = no; - } - } - - while (fgets(line, sizeof(line), in)) { - conf_lineno++; - sym = NULL; - switch (line[0]) { - case '#': - p = strchr(line + 2, ' '); - if (!p) - continue; - *p++ = 0; - if (strncmp(p, "is not set", 10)) - continue; - if (def == S_DEF_USER) { - sym = sym_find(line + 2); - if (!sym) { - sym_add_change_count(1); - break; - } - } else { - sym = sym_lookup(line + 2, 0); - if (sym->type == S_UNKNOWN) - sym->type = S_BOOLEAN; - } - if (sym->flags & def_flags) { - conf_warning("override: reassigning to symbol %s", sym->name); - } - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - sym->def[def].tri = no; - sym->flags |= def_flags; - break; - default: - ; - } - break; - default: - p = strchr(line, '='); - if (!p) - continue; - *p++ = 0; - p2 = strchr(p, '\n'); - if (p2) { - *p2-- = 0; - if (*p2 == '\r') - *p2 = 0; - } - if (def == S_DEF_USER) { - sym = sym_find(line); - if (!sym) { - sym_add_change_count(1); - break; - } - } else { - sym = sym_lookup(line, 0); - if (sym->type == S_UNKNOWN) - sym->type = S_OTHER; - } - if (sym->flags & def_flags) { - conf_warning("override: reassigning to symbol %s", sym->name); - } - if (conf_set_sym_val(sym, def, def_flags, p)) - continue; - break; - case '\r': - case '\n': - break; - } - if (sym && sym_is_choice_value(sym)) { - struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); - switch (sym->def[def].tri) { - case no: - break; - case mod: - if (cs->def[def].tri == yes) { - conf_warning("%s creates inconsistent choice state", sym->name); - cs->flags &= ~def_flags; - } - break; - case yes: - if (cs->def[def].tri != no) - conf_warning("override: %s changes choice state", sym->name); - cs->def[def].val = sym; - break; - } - cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri); - } - } - fclose(in); - - if (modules_sym) - sym_calc_value(modules_sym); - return 0; -} - -int conf_read(const char *name) -{ - struct symbol *sym, *choice_sym; - struct property *prop; - struct expr *e; - int i, flags; - - sym_set_change_count(0); - - if (conf_read_simple(name, S_DEF_USER)) - return 1; - - for_all_symbols(i, sym) { - sym_calc_value(sym); - if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) - goto sym_ok; - if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { - /* check that calculated value agrees with saved value */ - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) - break; - if (!sym_is_choice(sym)) - goto sym_ok; - default: - if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) - goto sym_ok; - break; - } - } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) - /* no previous value and not saved */ - goto sym_ok; - conf_unsaved++; - /* maybe print value in verbose mode... */ - sym_ok: - if (!sym_is_choice(sym)) - continue; - /* The choice symbol only has a set value (and thus is not new) - * if all its visible childs have values. - */ - prop = sym_get_choice_prop(sym); - flags = sym->flags; - expr_list_for_each_sym(prop->expr, e, choice_sym) - if (choice_sym->visible != no) - flags &= choice_sym->flags; - sym->flags &= flags | ~SYMBOL_DEF_USER; - } - - for_all_symbols(i, sym) { - if (sym_has_value(sym) && !sym_is_choice_value(sym)) { - /* Reset values of generates values, so they'll appear - * as new, if they should become visible, but that - * doesn't quite work if the Kconfig and the saved - * configuration disagree. - */ - if (sym->visible == no && !conf_unsaved) - sym->flags &= ~SYMBOL_DEF_USER; - switch (sym->type) { - case S_STRING: - case S_INT: - case S_HEX: - /* Reset a string value if it's out of range */ - if (sym_string_within_range(sym, sym->def[S_DEF_USER].val)) - break; - sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER); - conf_unsaved++; - break; - default: - break; - } - } - } - - sym_add_change_count(conf_warnings || conf_unsaved); - - return 0; -} - -int conf_write(const char *name) -{ - FILE *out; - struct symbol *sym; - struct menu *menu; - const char *basename; - char dirname[128], tmpname[128], newname[128]; - int type, l; - const char *str; - time_t now; - int use_timestamp = 1; - char *env; - - dirname[0] = 0; - if (name && name[0]) { - struct stat st; - char *slash; - - if (!stat(name, &st) && S_ISDIR(st.st_mode)) { - strcpy(dirname, name); - strcat(dirname, "/"); - basename = conf_get_configname(); - } else if ((slash = strrchr(name, '/'))) { - int size = slash - name + 1; - memcpy(dirname, name, size); - dirname[size] = 0; - if (slash[1]) - basename = slash + 1; - else - basename = conf_get_configname(); - } else - basename = name; - } else - basename = conf_get_configname(); - - sprintf(newname, "%s%s", dirname, basename); - env = getenv("KCONFIG_OVERWRITECONFIG"); - if (!env || !*env) { - sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); - out = fopen(tmpname, "w"); - } else { - *tmpname = 0; - out = fopen(newname, "w"); - } - if (!out) - return 1; - - sym = sym_lookup("ADKVERSION", 0); - sym_calc_value(sym); - time(&now); - env = getenv("KCONFIG_NOTIMESTAMP"); - if (env && *env) - use_timestamp = 0; - - fprintf(out, _("#\n" - "# Automatically generated make config: don't edit\n" - "# OpenADK version: %s\n" - "%s%s" - "#\n"), - sym_get_string_value(sym), - use_timestamp ? "# " : "", - use_timestamp ? ctime(&now) : ""); - - if (!conf_get_changed()) - sym_clear_all_valid(); - - menu = rootmenu.list; - while (menu) { - sym = menu->sym; - if (!sym) { - if (!menu_is_visible(menu)) - goto next; - str = menu_get_prompt(menu); - fprintf(out, "\n" - "#\n" - "# %s\n" - "#\n", str); - } else if (!(sym->flags & SYMBOL_CHOICE)) { - sym_calc_value(sym); - if (!(sym->flags & SYMBOL_WRITE)) - goto next; - sym->flags &= ~SYMBOL_WRITE; - type = sym->type; - if (type == S_TRISTATE) { - sym_calc_value(modules_sym); - if (modules_sym->curr.tri == no) - type = S_BOOLEAN; - } - switch (type) { - case S_BOOLEAN: - case S_TRISTATE: - switch (sym_get_tristate_value(sym)) { - case no: - fprintf(out, "# %s is not set\n", sym->name); - break; - case mod: - fprintf(out, "%s=m\n", sym->name); - break; - case yes: - fprintf(out, "%s=y\n", sym->name); - break; - } - break; - case S_STRING: - str = sym_get_string_value(sym); - fprintf(out, "%s=\"", sym->name); - while (1) { - l = strcspn(str, "\"\\"); - if (l) { - fwrite(str, l, 1, out); - str += l; - } - if (!*str) - break; - fprintf(out, "\\%c", *str++); - } - fputs("\"\n", out); - break; - case S_HEX: - str = sym_get_string_value(sym); - if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { - fprintf(out, "%s=%s\n", sym->name, str); - break; - } - case S_INT: - str = sym_get_string_value(sym); - fprintf(out, "%s=%s\n", sym->name, str); - break; - } - } - - next: - if (menu->list) { - menu = menu->list; - continue; - } - if (menu->next) - menu = menu->next; - else while ((menu = menu->parent)) { - if (menu->next) { - menu = menu->next; - break; - } - } - } - fclose(out); - - if (*tmpname) { - strcat(dirname, basename); - strcat(dirname, ".old"); - rename(newname, dirname); - if (rename(tmpname, newname)) - return 1; - } - - printf(_("#\n" - "# configuration written to %s\n" - "#\n"), newname); - - sym_set_change_count(0); - - return 0; -} - -int conf_split_config(void) -{ - const char *name; - char path[128]; - char *s, *d, c; - struct symbol *sym; - struct stat sb; - int res, i, fd; - - name = conf_get_autoconfig_name(); - conf_read_simple(name, S_DEF_AUTO); - - if (chdir("include/config")) - return 1; - - res = 0; - for_all_symbols(i, sym) { - sym_calc_value(sym); - if ((sym->flags & SYMBOL_AUTO) || !sym->name) - continue; - if (sym->flags & SYMBOL_WRITE) { - if (sym->flags & SYMBOL_DEF_AUTO) { - /* - * symbol has old and new value, - * so compare them... - */ - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - if (sym_get_tristate_value(sym) == - sym->def[S_DEF_AUTO].tri) - continue; - break; - case S_STRING: - case S_HEX: - case S_INT: - if (!strcmp(sym_get_string_value(sym), - sym->def[S_DEF_AUTO].val)) - continue; - break; - default: - break; - } - } else { - /* - * If there is no old value, only 'no' (unset) - * is allowed as new value. - */ - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - if (sym_get_tristate_value(sym) == no) - continue; - break; - default: - break; - } - } - } else if (!(sym->flags & SYMBOL_DEF_AUTO)) - /* There is neither an old nor a new value. */ - continue; - /* else - * There is an old value, but no new value ('no' (unset) - * isn't saved in auto.conf, so the old value is always - * different from 'no'). - */ - - /* Replace all '_' and append ".h" */ - s = sym->name; - d = path; - while ((c = *s++)) { - c = tolower(c); - *d++ = (c == '_') ? '/' : c; - } - strcpy(d, ".h"); - - /* Assume directory path already exists. */ - fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) { - if (errno != ENOENT) { - res = 1; - break; - } - /* - * Create directory components, - * unless they exist already. - */ - d = path; - while ((d = strchr(d, '/'))) { - *d = 0; - if (stat(path, &sb) && mkdir(path, 0755)) { - res = 1; - goto out; - } - *d++ = '/'; - } - /* Try it again. */ - fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) { - res = 1; - break; - } - } - close(fd); - } -out: - if (chdir("../..")) - return 1; - - return res; -} - -int conf_write_autoconf(void) -{ - struct symbol *sym; - const char *str; - const char *name; - FILE *out, *out_h; - time_t now; - int i, l; - - sym_clear_all_valid(); - - file_write_dep("include/config/auto.conf.cmd"); - - if (conf_split_config()) - return 1; - - out = fopen(".tmpconfig", "w"); - if (!out) - return 1; - - out_h = fopen(".tmpconfig.h", "w"); - if (!out_h) { - fclose(out); - return 1; - } - - sym = sym_lookup("ADKVERSION", 0); - sym_calc_value(sym); - time(&now); - fprintf(out, "#\n" - "# Automatically generated make config: don't edit\n" - "# OpenADK version: %s\n" - "# %s" - "#\n", - sym_get_string_value(sym), ctime(&now)); - fprintf(out_h, "/*\n" - " * Automatically generated C config: don't edit\n" - " * OpenADK version: %s\n" - " * %s" - " */\n" - "#define AUTOCONF_INCLUDED\n", - sym_get_string_value(sym), ctime(&now)); - - for_all_symbols(i, sym) { - sym_calc_value(sym); - if (!(sym->flags & SYMBOL_WRITE) || !sym->name) - continue; - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - switch (sym_get_tristate_value(sym)) { - case no: - break; - case mod: - fprintf(out, "%s=m\n", sym->name); - fprintf(out_h, "#define %s_MODULE 1\n", sym->name); - break; - case yes: - fprintf(out, "%s=y\n", sym->name); - fprintf(out_h, "#define %s 1\n", sym->name); - break; - } - break; - case S_STRING: - str = sym_get_string_value(sym); - fprintf(out, "%s=\"", sym->name); - fprintf(out_h, "#define %s \"", sym->name); - while (1) { - l = strcspn(str, "\"\\"); - if (l) { - fwrite(str, l, 1, out); - fwrite(str, l, 1, out_h); - str += l; - } - if (!*str) - break; - fprintf(out, "\\%c", *str); - fprintf(out_h, "\\%c", *str); - str++; - } - fputs("\"\n", out); - fputs("\"\n", out_h); - break; - case S_HEX: - str = sym_get_string_value(sym); - if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { - fprintf(out, "%s=%s\n", sym->name, str); - fprintf(out_h, "#define %s 0x%s\n", sym->name, str); - break; - } - case S_INT: - str = sym_get_string_value(sym); - fprintf(out, "%s=%s\n", sym->name, str); - fprintf(out_h, "#define %s %s\n", sym->name, str); - break; - default: - break; - } - } - fclose(out); - fclose(out_h); - - name = getenv("KCONFIG_AUTOHEADER"); - if (!name) - name = "include/linux/autoconf.h"; - if (rename(".tmpconfig.h", name)) - return 1; - name = conf_get_autoconfig_name(); - /* - * This must be the last step, kbuild has a dependency on auto.conf - * and this marks the successful completion of the previous steps. - */ - if (rename(".tmpconfig", name)) - return 1; - - return 0; -} - -static int sym_change_count; -static void (*conf_changed_callback)(void); - -void sym_set_change_count(int count) -{ - int _sym_change_count = sym_change_count; - sym_change_count = count; - if (conf_changed_callback && - (bool)_sym_change_count != (bool)count) - conf_changed_callback(); -} - -void sym_add_change_count(int count) -{ - sym_set_change_count(count + sym_change_count); -} - -bool conf_get_changed(void) -{ - return sym_change_count; -} - -void conf_set_changed_callback(void (*fn)(void)) -{ - conf_changed_callback = fn; -} - - -void conf_set_all_new_symbols(enum conf_def_mode mode) -{ - struct symbol *sym, *csym; - struct property *prop; - struct expr *e; - int i, cnt, def; - - for_all_symbols(i, sym) { - if (sym_has_value(sym)) - continue; - switch (sym_get_type(sym)) { - case S_BOOLEAN: - case S_TRISTATE: - switch (mode) { - case def_yes: - sym->def[S_DEF_USER].tri = yes; - break; - case def_mod: - sym->def[S_DEF_USER].tri = mod; - break; - case def_no: - sym->def[S_DEF_USER].tri = no; - break; - case def_random: - sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); - break; - default: - continue; - } - if (!(sym_is_choice(sym) && mode == def_random)) - sym->flags |= SYMBOL_DEF_USER; - break; - default: - break; - } - - } - - sym_clear_all_valid(); - - if (mode != def_random) - return; - /* - * We have different type of choice blocks. - * If curr.tri equal to mod then we can select several - * choice symbols in one block. - * In this case we do nothing. - * If curr.tri equal yes then only one symbol can be - * selected in a choice block and we set it to yes, - * and the rest to no. - */ - for_all_symbols(i, csym) { - if (sym_has_value(csym) || !sym_is_choice(csym)) - continue; - - sym_calc_value(csym); - - if (csym->curr.tri != yes) - continue; - - prop = sym_get_choice_prop(csym); - - /* count entries in choice block */ - cnt = 0; - expr_list_for_each_sym(prop->expr, e, sym) - cnt++; - - /* - * find a random value and set it to yes, - * set the rest to no so we have only one set - */ - def = (rand() % cnt); - - cnt = 0; - expr_list_for_each_sym(prop->expr, e, sym) { - if (def == cnt++) { - sym->def[S_DEF_USER].tri = yes; - csym->def[S_DEF_USER].val = sym; - } - else { - sym->def[S_DEF_USER].tri = no; - } - } - csym->flags |= SYMBOL_DEF_USER; - /* clear VALID to get value calculated */ - csym->flags &= ~(SYMBOL_VALID); - } -} diff --git a/config/expr.c b/config/expr.c deleted file mode 100644 index 579ece4fa..000000000 --- a/config/expr.c +++ /dev/null @@ -1,1106 +0,0 @@ -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - */ - -#include -#include -#include - -#define LKC_DIRECT_LINK -#include "lkc.h" - -#define DEBUG_EXPR 0 - -struct expr *expr_alloc_symbol(struct symbol *sym) -{ - struct expr *e = malloc(sizeof(*e)); - memset(e, 0, sizeof(*e)); - e->type = E_SYMBOL; - e->left.sym = sym; - return e; -} - -struct expr *expr_alloc_one(enum expr_type type, struct expr *ce) -{ - struct expr *e = malloc(sizeof(*e)); - memset(e, 0, sizeof(*e)); - e->type = type; - e->left.expr = ce; - return e; -} - -struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2) -{ - struct expr *e = malloc(sizeof(*e)); - memset(e, 0, sizeof(*e)); - e->type = type; - e->left.expr = e1; - e->right.expr = e2; - return e; -} - -struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2) -{ - struct expr *e = malloc(sizeof(*e)); - memset(e, 0, sizeof(*e)); - e->type = type; - e->left.sym = s1; - e->right.sym = s2; - return e; -} - -struct expr *expr_alloc_and(struct expr *e1, struct expr *e2) -{ - if (!e1) - return e2; - return e2 ? expr_alloc_two(E_AND, e1, e2) : e1; -} - -struct expr *expr_alloc_or(struct expr *e1, struct expr *e2) -{ - if (!e1) - return e2; - return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; -} - -struct expr *expr_copy(struct expr *org) -{ - struct expr *e; - - if (!org) - return NULL; - - e = malloc(sizeof(*org)); - memcpy(e, org, sizeof(*org)); - switch (org->type) { - case E_SYMBOL: - e->left = org->left; - break; - case E_NOT: - e->left.expr = expr_copy(org->left.expr); - break; - case E_EQUAL: - case E_UNEQUAL: - e->left.sym = org->left.sym; - e->right.sym = org->right.sym; - break; - case E_AND: - case E_OR: - case E_LIST: - e->left.expr = expr_copy(org->left.expr); - e->right.expr = expr_copy(org->right.expr); - break; - default: - printf("can't copy type %d\n", e->type); - free(e); - e = NULL; - break; - } - - return e; -} - -void expr_free(struct expr *e) -{ - if (!e) - return; - - switch (e->type) { - case E_SYMBOL: - break; - case E_NOT: - expr_free(e->left.expr); - return; - case E_EQUAL: - case E_UNEQUAL: - break; - case E_OR: - case E_AND: - expr_free(e->left.expr); - expr_free(e->right.expr); - break; - default: - printf("how to free type %d?\n", e->type); - break; - } - free(e); -} - -static int trans_count; - -#define e1 (*ep1) -#define e2 (*ep2) - -static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2) -{ - if (e1->type == type) { - __expr_eliminate_eq(type, &e1->left.expr, &e2); - __expr_eliminate_eq(type, &e1->right.expr, &e2); - return; - } - if (e2->type == type) { - __expr_eliminate_eq(type, &e1, &e2->left.expr); - __expr_eliminate_eq(type, &e1, &e2->right.expr); - return; - } - if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && - e1->left.sym == e2->left.sym && - (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no)) - return; - if (!expr_eq(e1, e2)) - return; - trans_count++; - expr_free(e1); expr_free(e2); - switch (type) { - case E_OR: - e1 = expr_alloc_symbol(&symbol_no); - e2 = expr_alloc_symbol(&symbol_no); - break; - case E_AND: - e1 = expr_alloc_symbol(&symbol_yes); - e2 = expr_alloc_symbol(&symbol_yes); - break; - default: - ; - } -} - -void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) -{ - if (!e1 || !e2) - return; - switch (e1->type) { - case E_OR: - case E_AND: - __expr_eliminate_eq(e1->type, ep1, ep2); - default: - ; - } - if (e1->type != e2->type) switch (e2->type) { - case E_OR: - case E_AND: - __expr_eliminate_eq(e2->type, ep1, ep2); - default: - ; - } - e1 = expr_eliminate_yn(e1); - e2 = expr_eliminate_yn(e2); -} - -#undef e1 -#undef e2 - -int expr_eq(struct expr *e1, struct expr *e2) -{ - int res, old_count; - - if (e1->type != e2->type) - return 0; - switch (e1->type) { - case E_EQUAL: - case E_UNEQUAL: - return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym; - case E_SYMBOL: - return e1->left.sym == e2->left.sym; - case E_NOT: - return expr_eq(e1->left.expr, e2->left.expr); - case E_AND: - case E_OR: - e1 = expr_copy(e1); - e2 = expr_copy(e2); - old_count = trans_count; - expr_eliminate_eq(&e1, &e2); - res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL && - e1->left.sym == e2->left.sym); - expr_free(e1); - expr_free(e2); - trans_count = old_count; - return res; - case E_LIST: - case E_RANGE: - case E_NONE: - /* panic */; - } - - if (DEBUG_EXPR) { - expr_fprint(e1, stdout); - printf(" = "); - expr_fprint(e2, stdout); - printf(" ?\n"); - } - - return 0; -} - -struct expr *expr_eliminate_yn(struct expr *e) -{ - struct expr *tmp; - - if (e) switch (e->type) { - case E_AND: - e->left.expr = expr_eliminate_yn(e->left.expr); - e->right.expr = expr_eliminate_yn(e->right.expr); - if (e->left.expr->type == E_SYMBOL) { - if (e->left.expr->left.sym == &symbol_no) { - expr_free(e->left.expr); - expr_free(e->right.expr); - e->type = E_SYMBOL; - e->left.sym = &symbol_no; - e->right.expr = NULL; - return e; - } else if (e->left.expr->left.sym == &symbol_yes) { - free(e->left.expr); - tmp = e->right.expr; - *e = *(e->right.expr); - free(tmp); - return e; - } - } - if (e->right.expr->type == E_SYMBOL) { - if (e->right.expr->left.sym == &symbol_no) { - expr_free(e->left.expr); - expr_free(e->right.expr); - e->type = E_SYMBOL; - e->left.sym = &symbol_no; - e->right.expr = NULL; - return e; - } else if (e->right.expr->left.sym == &symbol_yes) { - free(e->right.expr); - tmp = e->left.expr; - *e = *(e->left.expr); - free(tmp); - return e; - } - } - break; - case E_OR: - e->left.expr = expr_eliminate_yn(e->left.expr); - e->right.expr = expr_eliminate_yn(e->right.expr); - if (e->left.expr->type == E_SYMBOL) { - if (e->left.expr->left.sym == &symbol_no) { - free(e->left.expr); - tmp = e->right.expr; - *e = *(e->right.expr); - free(tmp); - return e; - } else if (e->left.expr->left.sym == &symbol_yes) { - expr_free(e->left.expr); - expr_free(e->right.expr); - e->type = E_SYMBOL; - e->left.sym = &symbol_yes; - e->right.expr = NULL; - return e; - } - } - if (e->right.expr->type == E_SYMBOL) { - if (e->right.expr->left.sym == &symbol_no) { - free(e->right.expr); - tmp = e->left.expr; - *e = *(e->left.expr); - free(tmp); - return e; - } else if (e->right.expr->left.sym == &symbol_yes) { - expr_free(e->left.expr); - expr_free(e->right.expr); - e->type = E_SYMBOL; - e->left.sym = &symbol_yes; - e->right.expr = NULL; - return e; - } - } - break; - default: - ; - } - return e; -} - -/* - * bool FOO!=n => FOO - */ -struct expr *expr_trans_bool(struct expr *e) -{ - if (!e) - return NULL; - switch (e->type) { - case E_AND: - case E_OR: - case E_NOT: - e->left.expr = expr_trans_bool(e->left.expr); - e->right.expr = expr_trans_bool(e->right.expr); - break; - case E_UNEQUAL: - // FOO!=n -> FOO - if (e->left.sym->type == S_TRISTATE) { - if (e->right.sym == &symbol_no) { - e->type = E_SYMBOL; - e->right.sym = NULL; - } - } - break; - default: - ; - } - return e; -} - -/* - * e1 || e2 -> ? - */ -struct expr *expr_join_or(struct expr *e1, struct expr *e2) -{ - struct expr *tmp; - struct symbol *sym1, *sym2; - - if (expr_eq(e1, e2)) - return expr_copy(e1); - if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) - return NULL; - if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) - return NULL; - if (e1->type == E_NOT) { - tmp = e1->left.expr; - if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) - return NULL; - sym1 = tmp->left.sym; - } else - sym1 = e1->left.sym; - if (e2->type == E_NOT) { - if (e2->left.expr->type != E_SYMBOL) - return NULL; - sym2 = e2->left.expr->left.sym; - } else - sym2 = e2->left.sym; - if (sym1 != sym2) - return NULL; - if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) - return NULL; - if (sym1->type == S_TRISTATE) { - if (e1->type == E_EQUAL && e2->type == E_EQUAL && - ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || - (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) { - // (a='y') || (a='m') -> (a!='n') - return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no); - } - if (e1->type == E_EQUAL && e2->type == E_EQUAL && - ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || - (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) { - // (a='y') || (a='n') -> (a!='m') - return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod); - } - if (e1->type == E_EQUAL && e2->type == E_EQUAL && - ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || - (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) { - // (a='m') || (a='n') -> (a!='y') - return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes); - } - } - if (sym1->type == S_BOOLEAN && sym1 == sym2) { - if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) || - (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL)) - return expr_alloc_symbol(&symbol_yes); - } - - if (DEBUG_EXPR) { - printf("optimize ("); - expr_fprint(e1, stdout); - printf(") || ("); - expr_fprint(e2, stdout); - printf(")?\n"); - } - return NULL; -} - -struct expr *expr_join_and(struct expr *e1, struct expr *e2) -{ - struct expr *tmp; - struct symbol *sym1, *sym2; - - if (expr_eq(e1, e2)) - return expr_copy(e1); - if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) - return NULL; - if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) - return NULL; - if (e1->type == E_NOT) { - tmp = e1->left.expr; - if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) - return NULL; - sym1 = tmp->left.sym; - } else - sym1 = e1->left.sym; - if (e2->type == E_NOT) { - if (e2->left.expr->type != E_SYMBOL) - return NULL; - sym2 = e2->left.expr->left.sym; - } else - sym2 = e2->left.sym; - if (sym1 != sym2) - return NULL; - if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) - return NULL; - - if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) || - (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes)) - // (a) && (a='y') -> (a='y') - return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); - - if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) || - (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no)) - // (a) && (a!='n') -> (a) - return expr_alloc_symbol(sym1); - - if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) || - (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod)) - // (a) && (a!='m') -> (a='y') - return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); - - if (sym1->type == S_TRISTATE) { - if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) { - // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' - sym2 = e1->right.sym; - if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) - return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) - : expr_alloc_symbol(&symbol_no); - } - if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) { - // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' - sym2 = e2->right.sym; - if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) - return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) - : expr_alloc_symbol(&symbol_no); - } - if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && - ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || - (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) - // (a!='y') && (a!='n') -> (a='m') - return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod); - - if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && - ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || - (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) - // (a!='y') && (a!='m') -> (a='n') - return expr_alloc_comp(E_EQUAL, sym1, &symbol_no); - - if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && - ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || - (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) - // (a!='m') && (a!='n') -> (a='m') - return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); - - if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) || - (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) || - (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) || - (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes)) - return NULL; - } - - if (DEBUG_EXPR) { - printf("optimize ("); - expr_fprint(e1, stdout); - printf(") && ("); - expr_fprint(e2, stdout); - printf(")?\n"); - } - return NULL; -} - -static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) -{ -#define e1 (*ep1) -#define e2 (*ep2) - struct expr *tmp; - - if (e1->type == type) { - expr_eliminate_dups1(type, &e1->left.expr, &e2); - expr_eliminate_dups1(type, &e1->right.expr, &e2); - return; - } - if (e2->type == type) { - expr_eliminate_dups1(type, &e1, &e2->left.expr); - expr_eliminate_dups1(type, &e1, &e2->right.expr); - return; - } - if (e1 == e2) - return; - - switch (e1->type) { - case E_OR: case E_AND: - expr_eliminate_dups1(e1->type, &e1, &e1); - default: - ; - } - - switch (type) { - case E_OR: - tmp = expr_join_or(e1, e2); - if (tmp) { - expr_free(e1); expr_free(e2); - e1 = expr_alloc_symbol(&symbol_no); - e2 = tmp; - trans_count++; - } - break; - case E_AND: - tmp = expr_join_and(e1, e2); - if (tmp) { - expr_free(e1); expr_free(e2); - e1 = expr_alloc_symbol(&symbol_yes); - e2 = tmp; - trans_count++; - } - break; - default: - ; - } -#undef e1 -#undef e2 -} - -static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2) -{ -#define e1 (*ep1) -#define e2 (*ep2) - struct expr *tmp, *tmp1, *tmp2; - - if (e1->type == type) { - expr_eliminate_dups2(type, &e1->left.expr, &e2); - expr_eliminate_dups2(type, &e1->right.expr, &e2); - return; - } - if (e2->type == type) { - expr_eliminate_dups2(type, &e1, &e2->left.expr); - expr_eliminate_dups2(type, &e1, &e2->right.expr); - } - if (e1 == e2) - return; - - switch (e1->type) { - case E_OR: - expr_eliminate_dups2(e1->type, &e1, &e1); - // (FOO || BAR) && (!FOO && !BAR) -> n - tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); - tmp2 = expr_copy(e2); - tmp = expr_extract_eq_and(&tmp1, &tmp2); - if (expr_is_yes(tmp1)) { - expr_free(e1); - e1 = expr_alloc_symbol(&symbol_no); - trans_count++; - } - expr_free(tmp2); - expr_free(tmp1); - expr_free(tmp); - break; - case E_AND: - expr_eliminate_dups2(e1->type, &e1, &e1); - // (FOO && BAR) || (!FOO || !BAR) -> y - tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); - tmp2 = expr_copy(e2); - tmp = expr_extract_eq_or(&tmp1, &tmp2); - if (expr_is_no(tmp1)) { - expr_free(e1); - e1 = expr_alloc_symbol(&symbol_yes); - trans_count++; - } - expr_free(tmp2); - expr_free(tmp1); - expr_free(tmp); - break; - default: - ; - } -#undef e1 -#undef e2 -} - -struct expr *expr_eliminate_dups(struct expr *e) -{ - int oldcount; - if (!e) - return e; - - oldcount = trans_count; - while (1) { - trans_count = 0; - switch (e->type) { - case E_OR: case E_AND: - expr_eliminate_dups1(e->type, &e, &e); - expr_eliminate_dups2(e->type, &e, &e); - default: - ; - } - if (!trans_count) - break; - e = expr_eliminate_yn(e); - } - trans_count = oldcount; - return e; -} - -struct expr *expr_transform(struct expr *e) -{ - struct expr *tmp; - - if (!e) - return NULL; - switch (e->type) { - case E_EQUAL: - case E_UNEQUAL: - case E_SYMBOL: - case E_LIST: - break; - default: - e->left.expr = expr_transform(e->left.expr); - e->right.expr = expr_transform(e->right.expr); - } - - switch (e->type) { - case E_EQUAL: - if (e->left.sym->type != S_BOOLEAN) - break; - if (e->right.sym == &symbol_no) { - e->type = E_NOT; - e->left.expr = expr_alloc_symbol(e->left.sym); - e->right.sym = NULL; - break; - } - if (e->right.sym == &symbol_mod) { - printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name); - e->type = E_SYMBOL; - e->left.sym = &symbol_no; - e->right.sym = NULL; - break; - } - if (e->right.sym == &symbol_yes) { - e->type = E_SYMBOL; - e->right.sym = NULL; - break; - } - break; - case E_UNEQUAL: - if (e->left.sym->type != S_BOOLEAN) - break; - if (e->right.sym == &symbol_no) { - e->type = E_SYMBOL; - e->right.sym = NULL; - break; - } - if (e->right.sym == &symbol_mod) { - printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name); - e->type = E_SYMBOL; - e->left.sym = &symbol_yes; - e->right.sym = NULL; - break; - } - if (e->right.sym == &symbol_yes) { - e->type = E_NOT; - e->left.expr = expr_alloc_symbol(e->left.sym); - e->right.sym = NULL; - break; - } - break; - case E_NOT: - switch (e->left.expr->type) { - case E_NOT: - // !!a -> a - tmp = e->left.expr->left.expr; - free(e->left.expr); - free(e); - e = tmp; - e = expr_transform(e); - break; - case E_EQUAL: - case E_UNEQUAL: - // !a='x' -> a!='x' - tmp = e->left.expr; - free(e); - e = tmp; - e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; - break; - case E_OR: - // !(a || b) -> !a && !b - tmp = e->left.expr; - e->type = E_AND; - e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); - tmp->type = E_NOT; - tmp->right.expr = NULL; - e = expr_transform(e); - break; - case E_AND: - // !(a && b) -> !a || !b - tmp = e->left.expr; - e->type = E_OR; - e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); - tmp->type = E_NOT; - tmp->right.expr = NULL; - e = expr_transform(e); - break; - case E_SYMBOL: - if (e->left.expr->left.sym == &symbol_yes) { - // !'y' -> 'n' - tmp = e->left.expr; - free(e); - e = tmp; - e->type = E_SYMBOL; - e->left.sym = &symbol_no; - break; - } - if (e->left.expr->left.sym == &symbol_mod) { - // !'m' -> 'm' - tmp = e->left.expr; - free(e); - e = tmp; - e->type = E_SYMBOL; - e->left.sym = &symbol_mod; - break; - } - if (e->left.expr->left.sym == &symbol_no) { - // !'n' -> 'y' - tmp = e->left.expr; - free(e); - e = tmp; - e->type = E_SYMBOL; - e->left.sym = &symbol_yes; - break; - } - break; - default: - ; - } - break; - default: - ; - } - return e; -} - -int expr_contains_symbol(struct expr *dep, struct symbol *sym) -{ - if (!dep) - return 0; - - switch (dep->type) { - case E_AND: - case E_OR: - return expr_contains_symbol(dep->left.expr, sym) || - expr_contains_symbol(dep->right.expr, sym); - case E_SYMBOL: - return dep->left.sym == sym; - case E_EQUAL: - case E_UNEQUAL: - return dep->left.sym == sym || - dep->right.sym == sym; - case E_NOT: - return expr_contains_symbol(dep->left.expr, sym); - default: - ; - } - return 0; -} - -bool expr_depends_symbol(struct expr *dep, struct symbol *sym) -{ - if (!dep) - return false; - - switch (dep->type) { - case E_AND: - return expr_depends_symbol(dep->left.expr, sym) || - expr_depends_symbol(dep->right.expr, sym); - case E_SYMBOL: - return dep->left.sym == sym; - case E_EQUAL: - if (dep->left.sym == sym) { - if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod) - return true; - } - break; - case E_UNEQUAL: - if (dep->left.sym == sym) { - if (dep->right.sym == &symbol_no) - return true; - } - break; - default: - ; - } - return false; -} - -struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) -{ - struct expr *tmp = NULL; - expr_extract_eq(E_AND, &tmp, ep1, ep2); - if (tmp) { - *ep1 = expr_eliminate_yn(*ep1); - *ep2 = expr_eliminate_yn(*ep2); - } - return tmp; -} - -struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) -{ - struct expr *tmp = NULL; - expr_extract_eq(E_OR, &tmp, ep1, ep2); - if (tmp) { - *ep1 = expr_eliminate_yn(*ep1); - *ep2 = expr_eliminate_yn(*ep2); - } - return tmp; -} - -void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2) -{ -#define e1 (*ep1) -#define e2 (*ep2) - if (e1->type == type) { - expr_extract_eq(type, ep, &e1->left.expr, &e2); - expr_extract_eq(type, ep, &e1->right.expr, &e2); - return; - } - if (e2->type == type) { - expr_extract_eq(type, ep, ep1, &e2->left.expr); - expr_extract_eq(type, ep, ep1, &e2->right.expr); - return; - } - if (expr_eq(e1, e2)) { - *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1; - expr_free(e2); - if (type == E_AND) { - e1 = expr_alloc_symbol(&symbol_yes); - e2 = expr_alloc_symbol(&symbol_yes); - } else if (type == E_OR) { - e1 = expr_alloc_symbol(&symbol_no); - e2 = expr_alloc_symbol(&symbol_no); - } - } -#undef e1 -#undef e2 -} - -struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) -{ - struct expr *e1, *e2; - - if (!e) { - e = expr_alloc_symbol(sym); - if (type == E_UNEQUAL) - e = expr_alloc_one(E_NOT, e); - return e; - } - switch (e->type) { - case E_AND: - e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); - e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); - if (sym == &symbol_yes) - e = expr_alloc_two(E_AND, e1, e2); - if (sym == &symbol_no) - e = expr_alloc_two(E_OR, e1, e2); - if (type == E_UNEQUAL) - e = expr_alloc_one(E_NOT, e); - return e; - case E_OR: - e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); - e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); - if (sym == &symbol_yes) - e = expr_alloc_two(E_OR, e1, e2); - if (sym == &symbol_no) - e = expr_alloc_two(E_AND, e1, e2); - if (type == E_UNEQUAL) - e = expr_alloc_one(E_NOT, e); - return e; - case E_NOT: - return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); - case E_UNEQUAL: - case E_EQUAL: - if (type == E_EQUAL) { - if (sym == &symbol_yes) - return expr_copy(e); - if (sym == &symbol_mod) - return expr_alloc_symbol(&symbol_no); - if (sym == &symbol_no) - return expr_alloc_one(E_NOT, expr_copy(e)); - } else { - if (sym == &symbol_yes) - return expr_alloc_one(E_NOT, expr_copy(e)); - if (sym == &symbol_mod) - return expr_alloc_symbol(&symbol_yes); - if (sym == &symbol_no) - return expr_copy(e); - } - break; - case E_SYMBOL: - return expr_alloc_comp(type, e->left.sym, sym); - case E_LIST: - case E_RANGE: - case E_NONE: - /* panic */; - } - return NULL; -} - -tristate expr_calc_value(struct expr *e) -{ - tristate val1, val2; - const char *str1, *str2; - - if (!e) - return yes; - - switch (e->type) { - case E_SYMBOL: - sym_calc_value(e->left.sym); - return e->left.sym->curr.tri; - case E_AND: - val1 = expr_calc_value(e->left.expr); - val2 = expr_calc_value(e->right.expr); - return EXPR_AND(val1, val2); - case E_OR: - val1 = expr_calc_value(e->left.expr); - val2 = expr_calc_value(e->right.expr); - return EXPR_OR(val1, val2); - case E_NOT: - val1 = expr_calc_value(e->left.expr); - return EXPR_NOT(val1); - case E_EQUAL: - sym_calc_value(e->left.sym); - sym_calc_value(e->right.sym); - str1 = sym_get_string_value(e->left.sym); - str2 = sym_get_string_value(e->right.sym); - return !strcmp(str1, str2) ? yes : no; - case E_UNEQUAL: - sym_calc_value(e->left.sym); - sym_calc_value(e->right.sym); - str1 = sym_get_string_value(e->left.sym); - str2 = sym_get_string_value(e->right.sym); - return !strcmp(str1, str2) ? no : yes; - default: - printf("expr_calc_value: %d?\n", e->type); - return no; - } -} - -int expr_compare_type(enum expr_type t1, enum expr_type t2) -{ -#if 0 - return 1; -#else - if (t1 == t2) - return 0; - switch (t1) { - case E_EQUAL: - case E_UNEQUAL: - if (t2 == E_NOT) - return 1; - case E_NOT: - if (t2 == E_AND) - return 1; - case E_AND: - if (t2 == E_OR) - return 1; - case E_OR: - if (t2 == E_LIST) - return 1; - case E_LIST: - if (t2 == 0) - return 1; - default: - return -1; - } - printf("[%dgt%d?]", t1, t2); - return 0; -#endif -} - -void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken) -{ - if (!e) { - fn(data, NULL, "y"); - return; - } - - if (expr_compare_type(prevtoken, e->type) > 0) - fn(data, NULL, "("); - switch (e->type) { - case E_SYMBOL: - if (e->left.sym->name) - fn(data, e->left.sym, e->left.sym->name); - else - fn(data, NULL, ""); - break; - case E_NOT: - fn(data, NULL, "!"); - expr_print(e->left.expr, fn, data, E_NOT); - break; - case E_EQUAL: - if (e->left.sym->name) - fn(data, e->left.sym, e->left.sym->name); - else - fn(data, NULL, ""); - fn(data, NULL, "="); - fn(data, e->right.sym, e->right.sym->name); - break; - case E_UNEQUAL: - if (e->left.sym->name) - fn(data, e->left.sym, e->left.sym->name); - else - fn(data, NULL, ""); - fn(data, NULL, "!="); - fn(data, e->right.sym, e->right.sym->name); - break; - case E_OR: - expr_print(e->left.expr, fn, data, E_OR); - fn(data, NULL, " || "); - expr_print(e->right.expr, fn, data, E_OR); - break; - case E_AND: - expr_print(e->left.expr, fn, data, E_AND); - fn(data, NULL, " && "); - expr_print(e->right.expr, fn, data, E_AND); - break; - case E_LIST: - fn(data, e->right.sym, e->right.sym->name); - if (e->left.expr) { - fn(data, NULL, " ^ "); - expr_print(e->left.expr, fn, data, E_LIST); - } - break; - case E_RANGE: - fn(data, NULL, "["); - fn(data, e->left.sym, e->left.sym->name); - fn(data, NULL, " "); - fn(data, e->right.sym, e->right.sym->name); - fn(data, NULL, "]"); - break; - default: - { - char buf[32]; - sprintf(buf, "", e->type); - fn(data, NULL, buf); - break; - } - } - if (expr_compare_type(prevtoken, e->type) > 0) - fn(data, NULL, ")"); -} - -static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) -{ - fwrite(str, strlen(str), 1, data); -} - -void expr_fprint(struct expr *e, FILE *out) -{ - expr_print(e, expr_print_file_helper, out, E_NONE); -} - -static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) -{ - str_append((struct gstr*)data, str); -} - -void expr_gstr_print(struct expr *e, struct gstr *gs) -{ - expr_print(e, expr_print_gstr_helper, gs, E_NONE); -} diff --git a/config/expr.h b/config/expr.h deleted file mode 100644 index 6408fefae..000000000 --- a/config/expr.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - */ - -#ifndef EXPR_H -#define EXPR_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#ifndef __cplusplus -#include -#endif - -struct file { - struct file *next; - struct file *parent; - char *name; - int lineno; - int flags; -}; - -#define FILE_BUSY 0x0001 -#define FILE_SCANNED 0x0002 - -typedef enum tristate { - no, mod, yes -} tristate; - -enum expr_type { - E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE -}; - -union expr_data { - struct expr *expr; - struct symbol *sym; -}; - -struct expr { - enum expr_type type; - union expr_data left, right; -}; - -#define EXPR_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2)) -#define EXPR_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2)) -#define EXPR_NOT(dep) (2-(dep)) - -#define expr_list_for_each_sym(l, e, s) \ - for (e = (l); e && (s = e->right.sym); e = e->left.expr) - -struct expr_value { - struct expr *expr; - tristate tri; -}; - -struct symbol_value { - void *val; - tristate tri; -}; - -enum symbol_type { - S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER -}; - -/* enum values are used as index to symbol.def[] */ -enum { - S_DEF_USER, /* main user value */ - S_DEF_AUTO, /* values read from auto.conf */ - S_DEF_DEF3, /* Reserved for UI usage */ - S_DEF_DEF4, /* Reserved for UI usage */ - S_DEF_COUNT -}; - -struct symbol { - struct symbol *next; - char *name; - enum symbol_type type; - struct symbol_value curr; - struct symbol_value def[S_DEF_COUNT]; - tristate visible; - int flags; - struct property *prop; - struct expr_value rev_dep; -}; - -#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) - -#define SYMBOL_CONST 0x0001 /* symbol is const */ -#define SYMBOL_CHECK 0x0008 /* used during dependency checking */ -#define SYMBOL_CHOICE 0x0010 /* start of a choice block (null name) */ -#define SYMBOL_CHOICEVAL 0x0020 /* used as a value in a choice block */ -#define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */ -#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ -#define SYMBOL_WRITE 0x0200 /* ? */ -#define SYMBOL_CHANGED 0x0400 /* ? */ -#define SYMBOL_AUTO 0x1000 /* value from environment variable */ -#define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ -#define SYMBOL_WARNED 0x8000 /* warning has been issued */ - -/* Set when symbol.def[] is used */ -#define SYMBOL_DEF 0x10000 /* First bit of SYMBOL_DEF */ -#define SYMBOL_DEF_USER 0x10000 /* symbol.def[S_DEF_USER] is valid */ -#define SYMBOL_DEF_AUTO 0x20000 /* symbol.def[S_DEF_AUTO] is valid */ -#define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */ -#define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ - -#define SYMBOL_MAXLENGTH 256 -#define SYMBOL_HASHSIZE 257 -#define SYMBOL_HASHMASK 0xff - -/* A property represent the config options that can be associated - * with a config "symbol". - * Sample: - * config FOO - * default y - * prompt "foo prompt" - * select BAR - * config BAZ - * int "BAZ Value" - * range 1..255 - */ -enum prop_type { - P_UNKNOWN, - P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */ - P_COMMENT, /* text associated with a comment */ - P_MENU, /* prompt associated with a menuconfig option */ - P_DEFAULT, /* default y */ - P_CHOICE, /* choice value */ - P_SELECT, /* select BAR */ - P_RANGE, /* range 7..100 (for a symbol) */ - P_ENV, /* value from environment variable */ -}; - -struct property { - struct property *next; /* next property - null if last */ - struct symbol *sym; /* the symbol for which the property is associated */ - enum prop_type type; /* type of property */ - const char *text; /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */ - struct expr_value visible; - struct expr *expr; /* the optional conditional part of the property */ - struct menu *menu; /* the menu the property are associated with - * valid for: P_SELECT, P_RANGE, P_CHOICE, - * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */ - struct file *file; /* what file was this property defined */ - int lineno; /* what lineno was this property defined */ -}; - -#define for_all_properties(sym, st, tok) \ - for (st = sym->prop; st; st = st->next) \ - if (st->type == (tok)) -#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT) -#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE) -#define for_all_prompts(sym, st) \ - for (st = sym->prop; st; st = st->next) \ - if (st->text) - -struct menu { - struct menu *next; - struct menu *parent; - struct menu *list; - struct symbol *sym; - struct property *prompt; - struct expr *dep; - unsigned int flags; - char *help; - struct file *file; - int lineno; - void *data; -}; - -#define MENU_CHANGED 0x0001 -#define MENU_ROOT 0x0002 - -#ifndef SWIG - -extern struct file *file_list; -extern struct file *current_file; -struct file *lookup_file(const char *name); - -extern struct symbol symbol_yes, symbol_no, symbol_mod; -extern struct symbol *modules_sym; -extern struct symbol *sym_defconfig_list; -extern int cdebug; -struct expr *expr_alloc_symbol(struct symbol *sym); -struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); -struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2); -struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); -struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); -struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); -struct expr *expr_copy(struct expr *org); -void expr_free(struct expr *e); -int expr_eq(struct expr *e1, struct expr *e2); -void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); -tristate expr_calc_value(struct expr *e); -struct expr *expr_eliminate_yn(struct expr *e); -struct expr *expr_trans_bool(struct expr *e); -struct expr *expr_eliminate_dups(struct expr *e); -struct expr *expr_transform(struct expr *e); -int expr_contains_symbol(struct expr *dep, struct symbol *sym); -bool expr_depends_symbol(struct expr *dep, struct symbol *sym); -struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); -struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); -void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); -struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); - -void expr_fprint(struct expr *e, FILE *out); -struct gstr; /* forward */ -void expr_gstr_print(struct expr *e, struct gstr *gs); - -static inline int expr_is_yes(struct expr *e) -{ - return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes); -} - -static inline int expr_is_no(struct expr *e) -{ - return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no); -} -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* EXPR_H */ diff --git a/config/gconf.c b/config/gconf.c deleted file mode 100644 index 681125e11..000000000 --- a/config/gconf.c +++ /dev/null @@ -1,1618 +0,0 @@ -/* Hey EMACS -*- linux-c -*- */ -/* - * - * Copyright (C) 2002-2003 Romain Lievin - * Released under the terms of the GNU GPL v2.0. - * - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "lkc.h" -#include "images.c" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -//#define DEBUG - -enum { - SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW -}; - -static gint view_mode = FULL_VIEW; -static gboolean show_name = TRUE; -static gboolean show_range = TRUE; -static gboolean show_value = TRUE; -static gboolean show_all = FALSE; -static gboolean show_debug = FALSE; -static gboolean resizeable = FALSE; - -GtkWidget *main_wnd = NULL; -GtkWidget *tree1_w = NULL; // left frame -GtkWidget *tree2_w = NULL; // right frame -GtkWidget *text_w = NULL; -GtkWidget *hpaned = NULL; -GtkWidget *vpaned = NULL; -GtkWidget *back_btn = NULL; -GtkWidget *save_btn = NULL; -GtkWidget *save_menu_item = NULL; - -GtkTextTag *tag1, *tag2; -GdkColor color; - -GtkTreeStore *tree1, *tree2, *tree; -GtkTreeModel *model1, *model2; -static GtkTreeIter *parents[256]; -static gint indent; - -static struct menu *current; // current node for SINGLE view -static struct menu *browsed; // browsed node for SPLIT view - -enum { - COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE, - COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF, - COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD, - COL_NUMBER -}; - -static void display_list(void); -static void display_tree(struct menu *menu); -static void display_tree_part(void); -static void update_tree(struct menu *src, GtkTreeIter * dst); -static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row); -static gchar **fill_row(struct menu *menu); -static void conf_changed(void); - -/* Helping/Debugging Functions */ - - -const char *dbg_print_stype(int val) -{ - static char buf[256]; - - bzero(buf, 256); - - if (val == S_UNKNOWN) - strcpy(buf, "unknown"); - if (val == S_BOOLEAN) - strcpy(buf, "boolean"); - if (val == S_TRISTATE) - strcpy(buf, "tristate"); - if (val == S_INT) - strcpy(buf, "int"); - if (val == S_HEX) - strcpy(buf, "hex"); - if (val == S_STRING) - strcpy(buf, "string"); - if (val == S_OTHER) - strcpy(buf, "other"); - -#ifdef DEBUG - printf("%s", buf); -#endif - - return buf; -} - -const char *dbg_print_flags(int val) -{ - static char buf[256]; - - bzero(buf, 256); - - if (val & SYMBOL_CONST) - strcat(buf, "const/"); - if (val & SYMBOL_CHECK) - strcat(buf, "check/"); - if (val & SYMBOL_CHOICE) - strcat(buf, "choice/"); - if (val & SYMBOL_CHOICEVAL) - strcat(buf, "choiceval/"); - if (val & SYMBOL_VALID) - strcat(buf, "valid/"); - if (val & SYMBOL_OPTIONAL) - strcat(buf, "optional/"); - if (val & SYMBOL_WRITE) - strcat(buf, "write/"); - if (val & SYMBOL_CHANGED) - strcat(buf, "changed/"); - if (val & SYMBOL_AUTO) - strcat(buf, "auto/"); - - buf[strlen(buf) - 1] = '\0'; -#ifdef DEBUG - printf("%s", buf); -#endif - - return buf; -} - -const char *dbg_print_ptype(int val) -{ - static char buf[256]; - - bzero(buf, 256); - - if (val == P_UNKNOWN) - strcpy(buf, "unknown"); - if (val == P_PROMPT) - strcpy(buf, "prompt"); - if (val == P_COMMENT) - strcpy(buf, "comment"); - if (val == P_MENU) - strcpy(buf, "menu"); - if (val == P_DEFAULT) - strcpy(buf, "default"); - if (val == P_CHOICE) - strcpy(buf, "choice"); - -#ifdef DEBUG - printf("%s", buf); -#endif - - return buf; -} - - -void replace_button_icon(GladeXML * xml, GdkDrawable * window, - GtkStyle * style, gchar * btn_name, gchar ** xpm) -{ - GdkPixmap *pixmap; - GdkBitmap *mask; - GtkToolButton *button; - GtkWidget *image; - - pixmap = gdk_pixmap_create_from_xpm_d(window, &mask, - &style->bg[GTK_STATE_NORMAL], - xpm); - - button = GTK_TOOL_BUTTON(glade_xml_get_widget(xml, btn_name)); - image = gtk_image_new_from_pixmap(pixmap, mask); - gtk_widget_show(image); - gtk_tool_button_set_icon_widget(button, image); -} - -/* Main Window Initialization */ -void init_main_window(const gchar * glade_file) -{ - GladeXML *xml; - GtkWidget *widget; - GtkTextBuffer *txtbuf; - char title[256]; - GtkStyle *style; - - xml = glade_xml_new(glade_file, "window1", NULL); - if (!xml) - g_error(_("GUI loading failed !\n")); - glade_xml_signal_autoconnect(xml); - - main_wnd = glade_xml_get_widget(xml, "window1"); - hpaned = glade_xml_get_widget(xml, "hpaned1"); - vpaned = glade_xml_get_widget(xml, "vpaned1"); - tree1_w = glade_xml_get_widget(xml, "treeview1"); - tree2_w = glade_xml_get_widget(xml, "treeview2"); - text_w = glade_xml_get_widget(xml, "textview3"); - - back_btn = glade_xml_get_widget(xml, "button1"); - gtk_widget_set_sensitive(back_btn, FALSE); - - widget = glade_xml_get_widget(xml, "show_name1"); - gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, - show_name); - - widget = glade_xml_get_widget(xml, "show_range1"); - gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, - show_range); - - widget = glade_xml_get_widget(xml, "show_data1"); - gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, - show_value); - - save_btn = glade_xml_get_widget(xml, "button3"); - save_menu_item = glade_xml_get_widget(xml, "save1"); - conf_set_changed_callback(conf_changed); - - style = gtk_widget_get_style(main_wnd); - widget = glade_xml_get_widget(xml, "toolbar1"); - -#if 0 /* Use stock Gtk icons instead */ - replace_button_icon(xml, main_wnd->window, style, - "button1", (gchar **) xpm_back); - replace_button_icon(xml, main_wnd->window, style, - "button2", (gchar **) xpm_load); - replace_button_icon(xml, main_wnd->window, style, - "button3", (gchar **) xpm_save); -#endif - replace_button_icon(xml, main_wnd->window, style, - "button4", (gchar **) xpm_single_view); - replace_button_icon(xml, main_wnd->window, style, - "button5", (gchar **) xpm_split_view); - replace_button_icon(xml, main_wnd->window, style, - "button6", (gchar **) xpm_tree_view); - -#if 0 - switch (view_mode) { - case SINGLE_VIEW: - widget = glade_xml_get_widget(xml, "button4"); - g_signal_emit_by_name(widget, "clicked"); - break; - case SPLIT_VIEW: - widget = glade_xml_get_widget(xml, "button5"); - g_signal_emit_by_name(widget, "clicked"); - break; - case FULL_VIEW: - widget = glade_xml_get_widget(xml, "button6"); - g_signal_emit_by_name(widget, "clicked"); - break; - } -#endif - txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); - tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1", - "foreground", "red", - "weight", PANGO_WEIGHT_BOLD, - NULL); - tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2", - /*"style", PANGO_STYLE_OBLIQUE, */ - NULL); - - sprintf(title, _("OpenADK Configuration")); - gtk_window_set_title(GTK_WINDOW(main_wnd), title); - - gtk_widget_show(main_wnd); -} - -void init_tree_model(void) -{ - gint i; - - tree = tree2 = gtk_tree_store_new(COL_NUMBER, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_POINTER, GDK_TYPE_COLOR, - G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, - G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN); - model2 = GTK_TREE_MODEL(tree2); - - for (parents[0] = NULL, i = 1; i < 256; i++) - parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter)); - - tree1 = gtk_tree_store_new(COL_NUMBER, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_POINTER, GDK_TYPE_COLOR, - G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, - G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN); - model1 = GTK_TREE_MODEL(tree1); -} - -void init_left_tree(void) -{ - GtkTreeView *view = GTK_TREE_VIEW(tree1_w); - GtkCellRenderer *renderer; - GtkTreeSelection *sel; - GtkTreeViewColumn *column; - - gtk_tree_view_set_model(view, model1); - gtk_tree_view_set_headers_visible(view, TRUE); - gtk_tree_view_set_rules_hint(view, FALSE); - - column = gtk_tree_view_column_new(); - gtk_tree_view_append_column(view, column); - gtk_tree_view_column_set_title(column, _("Options")); - - renderer = gtk_cell_renderer_toggle_new(); - gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), - renderer, FALSE); - gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), - renderer, - "active", COL_BTNACT, - "inconsistent", COL_BTNINC, - "visible", COL_BTNVIS, - "radio", COL_BTNRAD, NULL); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), - renderer, FALSE); - gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), - renderer, - "text", COL_OPTION, - "foreground-gdk", - COL_COLOR, NULL); - - sel = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); - gtk_widget_realize(tree1_w); -} - -static void renderer_edited(GtkCellRendererText * cell, - const gchar * path_string, - const gchar * new_text, gpointer user_data); -static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle, - gchar * arg1, gpointer user_data); - -void init_right_tree(void) -{ - GtkTreeView *view = GTK_TREE_VIEW(tree2_w); - GtkCellRenderer *renderer; - GtkTreeSelection *sel; - GtkTreeViewColumn *column; - gint i; - - gtk_tree_view_set_model(view, model2); - gtk_tree_view_set_headers_visible(view, TRUE); - gtk_tree_view_set_rules_hint(view, FALSE); - - column = gtk_tree_view_column_new(); - gtk_tree_view_append_column(view, column); - gtk_tree_view_column_set_title(column, _("Options")); - - renderer = gtk_cell_renderer_pixbuf_new(); - gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), - renderer, FALSE); - gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), - renderer, - "pixbuf", COL_PIXBUF, - "visible", COL_PIXVIS, NULL); - renderer = gtk_cell_renderer_toggle_new(); - gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), - renderer, FALSE); - gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), - renderer, - "active", COL_BTNACT, - "inconsistent", COL_BTNINC, - "visible", COL_BTNVIS, - "radio", COL_BTNRAD, NULL); - /*g_signal_connect(G_OBJECT(renderer), "toggled", - G_CALLBACK(renderer_toggled), NULL); */ - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), - renderer, FALSE); - gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), - renderer, - "text", COL_OPTION, - "foreground-gdk", - COL_COLOR, NULL); - - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_insert_column_with_attributes(view, -1, - _("Name"), renderer, - "text", COL_NAME, - "foreground-gdk", - COL_COLOR, NULL); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_insert_column_with_attributes(view, -1, - "N", renderer, - "text", COL_NO, - "foreground-gdk", - COL_COLOR, NULL); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_insert_column_with_attributes(view, -1, - "M", renderer, - "text", COL_MOD, - "foreground-gdk", - COL_COLOR, NULL); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_insert_column_with_attributes(view, -1, - "Y", renderer, - "text", COL_YES, - "foreground-gdk", - COL_COLOR, NULL); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_insert_column_with_attributes(view, -1, - _("Value"), renderer, - "text", COL_VALUE, - "editable", - COL_EDIT, - "foreground-gdk", - COL_COLOR, NULL); - g_signal_connect(G_OBJECT(renderer), "edited", - G_CALLBACK(renderer_edited), NULL); - - column = gtk_tree_view_get_column(view, COL_NAME); - gtk_tree_view_column_set_visible(column, show_name); - column = gtk_tree_view_get_column(view, COL_NO); - gtk_tree_view_column_set_visible(column, show_range); - column = gtk_tree_view_get_column(view, COL_MOD); - gtk_tree_view_column_set_visible(column, show_range); - column = gtk_tree_view_get_column(view, COL_YES); - gtk_tree_view_column_set_visible(column, show_range); - column = gtk_tree_view_get_column(view, COL_VALUE); - gtk_tree_view_column_set_visible(column, show_value); - - if (resizeable) { - for (i = 0; i < COL_VALUE; i++) { - column = gtk_tree_view_get_column(view, i); - gtk_tree_view_column_set_resizable(column, TRUE); - } - } - - sel = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); -} - - -/* Utility Functions */ - - -static void text_insert_help(struct menu *menu) -{ - GtkTextBuffer *buffer; - GtkTextIter start, end; - const char *prompt = _(menu_get_prompt(menu)); - struct gstr help = str_new(); - - menu_get_ext_help(menu, &help); - - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); - gtk_text_buffer_get_bounds(buffer, &start, &end); - gtk_text_buffer_delete(buffer, &start, &end); - gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15); - - gtk_text_buffer_get_end_iter(buffer, &end); - gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1, - NULL); - gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2); - gtk_text_buffer_get_end_iter(buffer, &end); - gtk_text_buffer_insert_with_tags(buffer, &end, str_get(&help), -1, tag2, - NULL); - str_free(&help); -} - - -static void text_insert_msg(const char *title, const char *message) -{ - GtkTextBuffer *buffer; - GtkTextIter start, end; - const char *msg = message; - - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); - gtk_text_buffer_get_bounds(buffer, &start, &end); - gtk_text_buffer_delete(buffer, &start, &end); - gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15); - - gtk_text_buffer_get_end_iter(buffer, &end); - gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1, - NULL); - gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2); - gtk_text_buffer_get_end_iter(buffer, &end); - gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2, - NULL); -} - - -/* Main Windows Callbacks */ - -void on_save_activate(GtkMenuItem * menuitem, gpointer user_data); -gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event, - gpointer user_data) -{ - GtkWidget *dialog, *label; - gint result; - - if (!conf_get_changed()) - return FALSE; - - dialog = gtk_dialog_new_with_buttons(_("Warning !"), - GTK_WINDOW(main_wnd), - (GtkDialogFlags) - (GTK_DIALOG_MODAL | - GTK_DIALOG_DESTROY_WITH_PARENT), - GTK_STOCK_OK, - GTK_RESPONSE_YES, - GTK_STOCK_NO, - GTK_RESPONSE_NO, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, NULL); - gtk_dialog_set_default_response(GTK_DIALOG(dialog), - GTK_RESPONSE_CANCEL); - - label = gtk_label_new(_("\nSave configuration ?\n")); - gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label); - gtk_widget_show(label); - - result = gtk_dialog_run(GTK_DIALOG(dialog)); - switch (result) { - case GTK_RESPONSE_YES: - on_save_activate(NULL, NULL); - return FALSE; - case GTK_RESPONSE_NO: - return FALSE; - case GTK_RESPONSE_CANCEL: - case GTK_RESPONSE_DELETE_EVENT: - default: - gtk_widget_destroy(dialog); - return TRUE; - } - - return FALSE; -} - - -void on_window1_destroy(GtkObject * object, gpointer user_data) -{ - gtk_main_quit(); -} - - -void -on_window1_size_request(GtkWidget * widget, - GtkRequisition * requisition, gpointer user_data) -{ - static gint old_h; - gint w, h; - - if (widget->window == NULL) - gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h); - else - gdk_window_get_size(widget->window, &w, &h); - - if (h == old_h) - return; - old_h = h; - - gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3); -} - - -/* Menu & Toolbar Callbacks */ - - -static void -load_filename(GtkFileSelection * file_selector, gpointer user_data) -{ - const gchar *fn; - - fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION - (user_data)); - - if (conf_read(fn)) - text_insert_msg(_("Error"), _("Unable to load configuration !")); - else - display_tree(&rootmenu); -} - -void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data) -{ - GtkWidget *fs; - - fs = gtk_file_selection_new(_("Load file...")); - g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), - "clicked", - G_CALLBACK(load_filename), (gpointer) fs); - g_signal_connect_swapped(GTK_OBJECT - (GTK_FILE_SELECTION(fs)->ok_button), - "clicked", G_CALLBACK(gtk_widget_destroy), - (gpointer) fs); - g_signal_connect_swapped(GTK_OBJECT - (GTK_FILE_SELECTION(fs)->cancel_button), - "clicked", G_CALLBACK(gtk_widget_destroy), - (gpointer) fs); - gtk_widget_show(fs); -} - - -void on_save_activate(GtkMenuItem * menuitem, gpointer user_data) -{ - if (conf_write(NULL)) - text_insert_msg(_("Error"), _("Unable to save configuration !")); -} - - -static void -store_filename(GtkFileSelection * file_selector, gpointer user_data) -{ - const gchar *fn; - - fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION - (user_data)); - - if (conf_write(fn)) - text_insert_msg(_("Error"), _("Unable to save configuration !")); - - gtk_widget_destroy(GTK_WIDGET(user_data)); -} - -void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data) -{ - GtkWidget *fs; - - fs = gtk_file_selection_new(_("Save file as...")); - g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), - "clicked", - G_CALLBACK(store_filename), (gpointer) fs); - g_signal_connect_swapped(GTK_OBJECT - (GTK_FILE_SELECTION(fs)->ok_button), - "clicked", G_CALLBACK(gtk_widget_destroy), - (gpointer) fs); - g_signal_connect_swapped(GTK_OBJECT - (GTK_FILE_SELECTION(fs)->cancel_button), - "clicked", G_CALLBACK(gtk_widget_destroy), - (gpointer) fs); - gtk_widget_show(fs); -} - - -void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data) -{ - if (!on_window1_delete_event(NULL, NULL, NULL)) - gtk_widget_destroy(GTK_WIDGET(main_wnd)); -} - - -void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data) -{ - GtkTreeViewColumn *col; - - show_name = GTK_CHECK_MENU_ITEM(menuitem)->active; - col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME); - if (col) - gtk_tree_view_column_set_visible(col, show_name); -} - - -void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data) -{ - GtkTreeViewColumn *col; - - show_range = GTK_CHECK_MENU_ITEM(menuitem)->active; - col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO); - if (col) - gtk_tree_view_column_set_visible(col, show_range); - col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_MOD); - if (col) - gtk_tree_view_column_set_visible(col, show_range); - col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_YES); - if (col) - gtk_tree_view_column_set_visible(col, show_range); - -} - - -void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data) -{ - GtkTreeViewColumn *col; - - show_value = GTK_CHECK_MENU_ITEM(menuitem)->active; - col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE); - if (col) - gtk_tree_view_column_set_visible(col, show_value); -} - - -void -on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data) -{ - show_all = GTK_CHECK_MENU_ITEM(menuitem)->active; - - gtk_tree_store_clear(tree2); - display_tree(&rootmenu); // instead of update_tree to speed-up -} - - -void -on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data) -{ - show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active; - update_tree(&rootmenu, NULL); -} - - -void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) -{ - GtkWidget *dialog; - const gchar *intro_text = _( - "Welcome to gkc, the GTK+ graphical kernel configuration tool\n" - "for Linux.\n" - "For each option, a blank box indicates the feature is disabled, a\n" - "check indicates it is enabled, and a dot indicates that it is to\n" - "be compiled as a module. Clicking on the box will cycle through the three states.\n" - "\n" - "If you do not see an option (e.g., a device driver) that you\n" - "believe should be present, try turning on Show All Options\n" - "under the Options menu.\n" - "Although there is no cross reference yet to help you figure out\n" - "what other options must be enabled to support the option you\n" - "are interested in, you can still view the help of a grayed-out\n" - "option.\n" - "\n" - "Toggling Show Debug Info under the Options menu will show \n" - "the dependencies, which you can then match by examining other options."); - - dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_CLOSE, intro_text); - g_signal_connect_swapped(GTK_OBJECT(dialog), "response", - G_CALLBACK(gtk_widget_destroy), - GTK_OBJECT(dialog)); - gtk_widget_show_all(dialog); -} - - -void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) -{ - GtkWidget *dialog; - const gchar *about_text = - _("gkc is copyright (c) 2002 Romain Lievin .\n" - "Based on the source code from Roman Zippel.\n"); - - dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_CLOSE, about_text); - g_signal_connect_swapped(GTK_OBJECT(dialog), "response", - G_CALLBACK(gtk_widget_destroy), - GTK_OBJECT(dialog)); - gtk_widget_show_all(dialog); -} - - -void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) -{ - GtkWidget *dialog; - const gchar *license_text = - _("gkc is released under the terms of the GNU GPL v2.\n" - "For more information, please see the source code or\n" - "visit http://www.fsf.org/licenses/licenses.html\n"); - - dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_CLOSE, license_text); - g_signal_connect_swapped(GTK_OBJECT(dialog), "response", - G_CALLBACK(gtk_widget_destroy), - GTK_OBJECT(dialog)); - gtk_widget_show_all(dialog); -} - - -void on_back_clicked(GtkButton * button, gpointer user_data) -{ - enum prop_type ptype; - - current = current->parent; - ptype = current->prompt ? current->prompt->type : P_UNKNOWN; - if (ptype != P_MENU) - current = current->parent; - display_tree_part(); - - if (current == &rootmenu) - gtk_widget_set_sensitive(back_btn, FALSE); -} - - -void on_load_clicked(GtkButton * button, gpointer user_data) -{ - on_load1_activate(NULL, user_data); -} - - -void on_single_clicked(GtkButton * button, gpointer user_data) -{ - view_mode = SINGLE_VIEW; - gtk_paned_set_position(GTK_PANED(hpaned), 0); - gtk_widget_hide(tree1_w); - current = &rootmenu; - display_tree_part(); -} - - -void on_split_clicked(GtkButton * button, gpointer user_data) -{ - gint w, h; - view_mode = SPLIT_VIEW; - gtk_widget_show(tree1_w); - gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h); - gtk_paned_set_position(GTK_PANED(hpaned), w / 2); - if (tree2) - gtk_tree_store_clear(tree2); - display_list(); - - /* Disable back btn, like in full mode. */ - gtk_widget_set_sensitive(back_btn, FALSE); -} - - -void on_full_clicked(GtkButton * button, gpointer user_data) -{ - view_mode = FULL_VIEW; - gtk_paned_set_position(GTK_PANED(hpaned), 0); - gtk_widget_hide(tree1_w); - if (tree2) - gtk_tree_store_clear(tree2); - display_tree(&rootmenu); - gtk_widget_set_sensitive(back_btn, FALSE); -} - - -void on_collapse_clicked(GtkButton * button, gpointer user_data) -{ - gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w)); -} - - -void on_expand_clicked(GtkButton * button, gpointer user_data) -{ - gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); -} - - -/* CTree Callbacks */ - -/* Change hex/int/string value in the cell */ -static void renderer_edited(GtkCellRendererText * cell, - const gchar * path_string, - const gchar * new_text, gpointer user_data) -{ - GtkTreePath *path = gtk_tree_path_new_from_string(path_string); - GtkTreeIter iter; - const char *old_def, *new_def; - struct menu *menu; - struct symbol *sym; - - if (!gtk_tree_model_get_iter(model2, &iter, path)) - return; - - gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); - sym = menu->sym; - - gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1); - new_def = new_text; - - sym_set_string_value(sym, new_def); - - update_tree(&rootmenu, NULL); - - gtk_tree_path_free(path); -} - -/* Change the value of a symbol and update the tree */ -static void change_sym_value(struct menu *menu, gint col) -{ - struct symbol *sym = menu->sym; - tristate oldval, newval; - - if (!sym) - return; - - if (col == COL_NO) - newval = no; - else if (col == COL_MOD) - newval = mod; - else if (col == COL_YES) - newval = yes; - else - return; - - switch (sym_get_type(sym)) { - case S_BOOLEAN: - case S_TRISTATE: - oldval = sym_get_tristate_value(sym); - if (!sym_tristate_within_range(sym, newval)) - newval = yes; - sym_set_tristate_value(sym, newval); - if (view_mode == FULL_VIEW) - update_tree(&rootmenu, NULL); - else if (view_mode == SPLIT_VIEW) { - update_tree(browsed, NULL); - display_list(); - } - else if (view_mode == SINGLE_VIEW) - display_tree_part(); //fixme: keep exp/coll - break; - case S_INT: - case S_HEX: - case S_STRING: - default: - break; - } -} - -static void toggle_sym_value(struct menu *menu) -{ - if (!menu->sym) - return; - - sym_toggle_tristate_value(menu->sym); - if (view_mode == FULL_VIEW) - update_tree(&rootmenu, NULL); - else if (view_mode == SPLIT_VIEW) { - update_tree(browsed, NULL); - display_list(); - } - else if (view_mode == SINGLE_VIEW) - display_tree_part(); //fixme: keep exp/coll -} - -static void renderer_toggled(GtkCellRendererToggle * cell, - gchar * path_string, gpointer user_data) -{ - GtkTreePath *path, *sel_path = NULL; - GtkTreeIter iter, sel_iter; - GtkTreeSelection *sel; - struct menu *menu; - - path = gtk_tree_path_new_from_string(path_string); - if (!gtk_tree_model_get_iter(model2, &iter, path)) - return; - - sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree2_w)); - if (gtk_tree_selection_get_selected(sel, NULL, &sel_iter)) - sel_path = gtk_tree_model_get_path(model2, &sel_iter); - if (!sel_path) - goto out1; - if (gtk_tree_path_compare(path, sel_path)) - goto out2; - - gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); - toggle_sym_value(menu); - - out2: - gtk_tree_path_free(sel_path); - out1: - gtk_tree_path_free(path); -} - -static gint column2index(GtkTreeViewColumn * column) -{ - gint i; - - for (i = 0; i < COL_NUMBER; i++) { - GtkTreeViewColumn *col; - - col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), i); - if (col == column) - return i; - } - - return -1; -} - - -/* User click: update choice (full) or goes down (single) */ -gboolean -on_treeview2_button_press_event(GtkWidget * widget, - GdkEventButton * event, gpointer user_data) -{ - GtkTreeView *view = GTK_TREE_VIEW(widget); - GtkTreePath *path; - GtkTreeViewColumn *column; - GtkTreeIter iter; - struct menu *menu; - gint col; - -#if GTK_CHECK_VERSION(2,1,4) // bug in ctree with earlier version of GTK - gint tx = (gint) event->x; - gint ty = (gint) event->y; - gint cx, cy; - - gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx, - &cy); -#else - gtk_tree_view_get_cursor(view, &path, &column); -#endif - if (path == NULL) - return FALSE; - - if (!gtk_tree_model_get_iter(model2, &iter, path)) - return FALSE; - gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); - - col = column2index(column); - if (event->type == GDK_2BUTTON_PRESS) { - enum prop_type ptype; - ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; - - if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) { - // goes down into menu - current = menu; - display_tree_part(); - gtk_widget_set_sensitive(back_btn, TRUE); - } else if ((col == COL_OPTION)) { - toggle_sym_value(menu); - gtk_tree_view_expand_row(view, path, TRUE); - } - } else { - if (col == COL_VALUE) { - toggle_sym_value(menu); - gtk_tree_view_expand_row(view, path, TRUE); - } else if (col == COL_NO || col == COL_MOD - || col == COL_YES) { - change_sym_value(menu, col); - gtk_tree_view_expand_row(view, path, TRUE); - } - } - - return FALSE; -} - -/* Key pressed: update choice */ -gboolean -on_treeview2_key_press_event(GtkWidget * widget, - GdkEventKey * event, gpointer user_data) -{ - GtkTreeView *view = GTK_TREE_VIEW(widget); - GtkTreePath *path; - GtkTreeViewColumn *column; - GtkTreeIter iter; - struct menu *menu; - gint col; - - gtk_tree_view_get_cursor(view, &path, &column); - if (path == NULL) - return FALSE; - - if (event->keyval == GDK_space) { - if (gtk_tree_view_row_expanded(view, path)) - gtk_tree_view_collapse_row(view, path); - else - gtk_tree_view_expand_row(view, path, FALSE); - return TRUE; - } - if (event->keyval == GDK_KP_Enter) { - } - if (widget == tree1_w) - return FALSE; - - gtk_tree_model_get_iter(model2, &iter, path); - gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); - - if (!strcasecmp(event->string, "n")) - col = COL_NO; - else if (!strcasecmp(event->string, "m")) - col = COL_MOD; - else if (!strcasecmp(event->string, "y")) - col = COL_YES; - else - col = -1; - change_sym_value(menu, col); - - return FALSE; -} - - -/* Row selection changed: update help */ -void -on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data) -{ - GtkTreeSelection *selection; - GtkTreeIter iter; - struct menu *menu; - - selection = gtk_tree_view_get_selection(treeview); - if (gtk_tree_selection_get_selected(selection, &model2, &iter)) { - gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); - text_insert_help(menu); - } -} - - -/* User click: display sub-tree in the right frame. */ -gboolean -on_treeview1_button_press_event(GtkWidget * widget, - GdkEventButton * event, gpointer user_data) -{ - GtkTreeView *view = GTK_TREE_VIEW(widget); - GtkTreePath *path; - GtkTreeViewColumn *column; - GtkTreeIter iter; - struct menu *menu; - - gint tx = (gint) event->x; - gint ty = (gint) event->y; - gint cx, cy; - - gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx, - &cy); - if (path == NULL) - return FALSE; - - gtk_tree_model_get_iter(model1, &iter, path); - gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1); - - if (event->type == GDK_2BUTTON_PRESS) { - toggle_sym_value(menu); - current = menu; - display_tree_part(); - } else { - browsed = menu; - display_tree_part(); - } - - gtk_widget_realize(tree2_w); - gtk_tree_view_set_cursor(view, path, NULL, FALSE); - gtk_widget_grab_focus(tree2_w); - - return FALSE; -} - - -/* Fill a row of strings */ -static gchar **fill_row(struct menu *menu) -{ - static gchar *row[COL_NUMBER]; - struct symbol *sym = menu->sym; - const char *def; - int stype; - tristate val; - enum prop_type ptype; - int i; - - for (i = COL_OPTION; i <= COL_COLOR; i++) - g_free(row[i]); - bzero(row, sizeof(row)); - - row[COL_OPTION] = - g_strdup_printf("%s %s", _(menu_get_prompt(menu)), - sym && sym_has_value(sym) ? "(NEW)" : ""); - - if (show_all && !menu_is_visible(menu)) - row[COL_COLOR] = g_strdup("DarkGray"); - else - row[COL_COLOR] = g_strdup("Black"); - - ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; - switch (ptype) { - case P_MENU: - row[COL_PIXBUF] = (gchar *) xpm_menu; - if (view_mode == SINGLE_VIEW) - row[COL_PIXVIS] = GINT_TO_POINTER(TRUE); - row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); - break; - case P_COMMENT: - row[COL_PIXBUF] = (gchar *) xpm_void; - row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); - row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); - break; - default: - row[COL_PIXBUF] = (gchar *) xpm_void; - row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); - row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); - break; - } - - if (!sym) - return row; - row[COL_NAME] = g_strdup(sym->name); - - sym_calc_value(sym); - sym->flags &= ~SYMBOL_CHANGED; - - if (sym_is_choice(sym)) { // parse childs for getting final value - struct menu *child; - struct symbol *def_sym = sym_get_choice_value(sym); - struct menu *def_menu = NULL; - - row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); - - for (child = menu->list; child; child = child->next) { - if (menu_is_visible(child) - && child->sym == def_sym) - def_menu = child; - } - - if (def_menu) - row[COL_VALUE] = - g_strdup(_(menu_get_prompt(def_menu))); - } - if (sym->flags & SYMBOL_CHOICEVAL) - row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); - - stype = sym_get_type(sym); - switch (stype) { - case S_BOOLEAN: - if (GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE) - row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); - if (sym_is_choice(sym)) - break; - case S_TRISTATE: - val = sym_get_tristate_value(sym); - switch (val) { - case no: - row[COL_NO] = g_strdup("N"); - row[COL_VALUE] = g_strdup("N"); - row[COL_BTNACT] = GINT_TO_POINTER(FALSE); - row[COL_BTNINC] = GINT_TO_POINTER(FALSE); - break; - case mod: - row[COL_MOD] = g_strdup("M"); - row[COL_VALUE] = g_strdup("M"); - row[COL_BTNINC] = GINT_TO_POINTER(TRUE); - break; - case yes: - row[COL_YES] = g_strdup("Y"); - row[COL_VALUE] = g_strdup("Y"); - row[COL_BTNACT] = GINT_TO_POINTER(TRUE); - row[COL_BTNINC] = GINT_TO_POINTER(FALSE); - break; - } - - if (val != no && sym_tristate_within_range(sym, no)) - row[COL_NO] = g_strdup("_"); - if (val != mod && sym_tristate_within_range(sym, mod)) - row[COL_MOD] = g_strdup("_"); - if (val != yes && sym_tristate_within_range(sym, yes)) - row[COL_YES] = g_strdup("_"); - break; - case S_INT: - case S_HEX: - case S_STRING: - def = sym_get_string_value(sym); - row[COL_VALUE] = g_strdup(def); - row[COL_EDIT] = GINT_TO_POINTER(TRUE); - row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); - break; - } - - return row; -} - - -/* Set the node content with a row of strings */ -static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row) -{ - GdkColor color; - gboolean success; - GdkPixbuf *pix; - - pix = gdk_pixbuf_new_from_xpm_data((const char **) - row[COL_PIXBUF]); - - gdk_color_parse(row[COL_COLOR], &color); - gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1, - FALSE, FALSE, &success); - - gtk_tree_store_set(tree, node, - COL_OPTION, row[COL_OPTION], - COL_NAME, row[COL_NAME], - COL_NO, row[COL_NO], - COL_MOD, row[COL_MOD], - COL_YES, row[COL_YES], - COL_VALUE, row[COL_VALUE], - COL_MENU, (gpointer) menu, - COL_COLOR, &color, - COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]), - COL_PIXBUF, pix, - COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]), - COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]), - COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]), - COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]), - COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]), - -1); - - g_object_unref(pix); -} - - -/* Add a node to the tree */ -static void place_node(struct menu *menu, char **row) -{ - GtkTreeIter *parent = parents[indent - 1]; - GtkTreeIter *node = parents[indent]; - - gtk_tree_store_append(tree, node, parent); - set_node(node, menu, row); -} - - -/* Find a node in the GTK+ tree */ -static GtkTreeIter found; - -/* - * Find a menu in the GtkTree starting at parent. - */ -GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent, - struct menu *tofind) -{ - GtkTreeIter iter; - GtkTreeIter *child = &iter; - gboolean valid; - GtkTreeIter *ret; - - valid = gtk_tree_model_iter_children(model2, child, parent); - while (valid) { - struct menu *menu; - - gtk_tree_model_get(model2, child, 6, &menu, -1); - - if (menu == tofind) { - memcpy(&found, child, sizeof(GtkTreeIter)); - return &found; - } - - ret = gtktree_iter_find_node(child, tofind); - if (ret) - return ret; - - valid = gtk_tree_model_iter_next(model2, child); - } - - return NULL; -} - - -/* - * Update the tree by adding/removing entries - * Does not change other nodes - */ -static void update_tree(struct menu *src, GtkTreeIter * dst) -{ - struct menu *child1; - GtkTreeIter iter, tmp; - GtkTreeIter *child2 = &iter; - gboolean valid; - GtkTreeIter *sibling; - struct symbol *sym; - struct property *prop; - struct menu *menu1, *menu2; - - if (src == &rootmenu) - indent = 1; - - valid = gtk_tree_model_iter_children(model2, child2, dst); - for (child1 = src->list; child1; child1 = child1->next) { - - prop = child1->prompt; - sym = child1->sym; - - reparse: - menu1 = child1; - if (valid) - gtk_tree_model_get(model2, child2, COL_MENU, - &menu2, -1); - else - menu2 = NULL; // force adding of a first child - -#ifdef DEBUG - printf("%*c%s | %s\n", indent, ' ', - menu1 ? menu_get_prompt(menu1) : "nil", - menu2 ? menu_get_prompt(menu2) : "nil"); -#endif - - if (!menu_is_visible(child1) && !show_all) { // remove node - if (gtktree_iter_find_node(dst, menu1) != NULL) { - memcpy(&tmp, child2, sizeof(GtkTreeIter)); - valid = gtk_tree_model_iter_next(model2, - child2); - gtk_tree_store_remove(tree2, &tmp); - if (!valid) - return; // next parent - else - goto reparse; // next child - } else - continue; - } - - if (menu1 != menu2) { - if (gtktree_iter_find_node(dst, menu1) == NULL) { // add node - if (!valid && !menu2) - sibling = NULL; - else - sibling = child2; - gtk_tree_store_insert_before(tree2, - child2, - dst, sibling); - set_node(child2, menu1, fill_row(menu1)); - if (menu2 == NULL) - valid = TRUE; - } else { // remove node - memcpy(&tmp, child2, sizeof(GtkTreeIter)); - valid = gtk_tree_model_iter_next(model2, - child2); - gtk_tree_store_remove(tree2, &tmp); - if (!valid) - return; // next parent - else - goto reparse; // next child - } - } else if (sym && (sym->flags & SYMBOL_CHANGED)) { - set_node(child2, menu1, fill_row(menu1)); - } - - indent++; - update_tree(child1, child2); - indent--; - - valid = gtk_tree_model_iter_next(model2, child2); - } -} - - -/* Display the whole tree (single/split/full view) */ -static void display_tree(struct menu *menu) -{ - struct symbol *sym; - struct property *prop; - struct menu *child; - enum prop_type ptype; - - if (menu == &rootmenu) { - indent = 1; - current = &rootmenu; - } - - for (child = menu->list; child; child = child->next) { - prop = child->prompt; - sym = child->sym; - ptype = prop ? prop->type : P_UNKNOWN; - - if (sym) - sym->flags &= ~SYMBOL_CHANGED; - - if ((view_mode == SPLIT_VIEW) - && !(child->flags & MENU_ROOT) && (tree == tree1)) - continue; - - if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) - && (tree == tree2)) - continue; - - if (menu_is_visible(child) || show_all) - place_node(child, fill_row(child)); -#ifdef DEBUG - printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); - printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : ""); - dbg_print_ptype(ptype); - printf(" | "); - if (sym) { - dbg_print_stype(sym->type); - printf(" | "); - dbg_print_flags(sym->flags); - printf("\n"); - } else - printf("\n"); -#endif - if ((view_mode != FULL_VIEW) && (ptype == P_MENU) - && (tree == tree2)) - continue; -/* - if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) - || (view_mode == FULL_VIEW) - || (view_mode == SPLIT_VIEW))*/ - if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT)) - || (view_mode == FULL_VIEW) - || (view_mode == SPLIT_VIEW)) { - indent++; - display_tree(child); - indent--; - } - } -} - -/* Display a part of the tree starting at current node (single/split view) */ -static void display_tree_part(void) -{ - if (tree2) - gtk_tree_store_clear(tree2); - if (view_mode == SINGLE_VIEW) - display_tree(current); - else if (view_mode == SPLIT_VIEW) - display_tree(browsed); - gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); -} - -/* Display the list in the left frame (split view) */ -static void display_list(void) -{ - if (tree1) - gtk_tree_store_clear(tree1); - - tree = tree1; - display_tree(&rootmenu); - gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w)); - tree = tree2; -} - -void fixup_rootmenu(struct menu *menu) -{ - struct menu *child; - static int menu_cnt = 0; - - menu->flags |= MENU_ROOT; - for (child = menu->list; child; child = child->next) { - if (child->prompt && child->prompt->type == P_MENU) { - menu_cnt++; - fixup_rootmenu(child); - menu_cnt--; - } else if (!menu_cnt) - fixup_rootmenu(child); - } -} - - -/* Main */ -int main(int ac, char *av[]) -{ - const char *name; - char *env; - gchar *glade_file; - -#ifndef LKC_DIRECT_LINK - kconfig_load(); -#endif - - bindtextdomain(PACKAGE, LOCALEDIR); - bind_textdomain_codeset(PACKAGE, "UTF-8"); - textdomain(PACKAGE); - - /* GTK stuffs */ - gtk_set_locale(); - gtk_init(&ac, &av); - glade_init(); - - //add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps"); - //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps"); - - /* Determine GUI path */ - env = getenv(SRCTREE); - if (env) - glade_file = g_strconcat(env, "/scripts/kconfig/gconf.glade", NULL); - else if (av[0][0] == '/') - glade_file = g_strconcat(av[0], ".glade", NULL); - else - glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL); - - /* Load the interface and connect signals */ - init_main_window(glade_file); - init_tree_model(); - init_left_tree(); - init_right_tree(); - - /* Conf stuffs */ - if (ac > 1 && av[1][0] == '-') { - switch (av[1][1]) { - case 'a': - //showAll = 1; - break; - case 'h': - case '?': - printf("%s \n", av[0]); - exit(0); - } - name = av[2]; - } else - name = av[1]; - - conf_parse(name); - fixup_rootmenu(&rootmenu); - conf_read(NULL); - - switch (view_mode) { - case SINGLE_VIEW: - display_tree_part(); - break; - case SPLIT_VIEW: - display_list(); - break; - case FULL_VIEW: - display_tree(&rootmenu); - break; - } - - gtk_main(); - - return 0; -} - -static void conf_changed(void) -{ - bool changed = conf_get_changed(); - gtk_widget_set_sensitive(save_btn, changed); - gtk_widget_set_sensitive(save_menu_item, changed); -} diff --git a/config/gconf.glade b/config/gconf.glade deleted file mode 100644 index b1c86c192..000000000 --- a/config/gconf.glade +++ /dev/null @@ -1,648 +0,0 @@ - - - - - - - True - Gtk Kernel Configurator - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - 640 - 480 - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - - - - - - - True - False - 0 - - - - True - - - - True - _File - True - - - - - - - True - Load a config file - _Load - True - - - - - - True - gtk-open - 1 - 0.5 - 0.5 - 0 - 0 - - - - - - - - True - Save the config in .config - _Save - True - - - - - - True - gtk-save - 1 - 0.5 - 0.5 - 0 - 0 - - - - - - - - True - Save the config in a file - Save _as - True - - - - - True - gtk-save-as - 1 - 0.5 - 0.5 - 0 - 0 - - - - - - - - True - - - - - - True - _Quit - True - - - - - - True - gtk-quit - 1 - 0.5 - 0.5 - 0 - 0 - - - - - - - - - - - - True - _Options - True - - - - - - - True - Show name - Show _name - True - False - - - - - - - True - Show range (Y/M/N) - Show _range - True - False - - - - - - - True - Show value of the option - Show _data - True - False - - - - - - - True - - - - - - True - Show all options - Show all _options - True - False - - - - - - - True - Show masked options - Show _debug info - True - False - - - - - - - - - - - True - _Help - True - - - - - - - True - _Introduction - True - - - - - - True - gtk-dialog-question - 1 - 0.5 - 0.5 - 0 - 0 - - - - - - - - True - _About - True - - - - - - True - gtk-properties - 1 - 0.5 - 0.5 - 0 - 0 - - - - - - - - True - _License - True - - - - - True - gtk-justify-fill - 1 - 0.5 - 0.5 - 0 - 0 - - - - - - - - - - - 0 - False - False - - - - - - True - GTK_SHADOW_OUT - GTK_POS_LEFT - GTK_POS_TOP - - - - True - GTK_ORIENTATION_HORIZONTAL - GTK_TOOLBAR_BOTH - True - True - - - - True - Goes up of one level (single view) - Back - True - gtk-undo - True - True - False - - - - False - True - - - - - - True - True - True - False - - - - True - - - - - False - False - - - - - - True - Load a config file - Load - True - gtk-open - True - True - False - - - - False - True - - - - - - True - Save a config file - Save - True - gtk-save - True - True - False - - - - False - True - - - - - - True - True - True - False - - - - True - - - - - False - False - - - - - - True - Single view - Single - True - gtk-missing-image - True - True - False - - - - False - True - - - - - - True - Split view - Split - True - gtk-missing-image - True - True - False - - - - False - True - - - - - - True - Full view - Full - True - gtk-missing-image - True - True - False - - - - False - True - - - - - - True - True - True - False - - - - True - - - - - False - False - - - - - - True - Collapse the whole tree in the right frame - Collapse - True - gtk-remove - True - True - False - - - - False - True - - - - - - True - Expand the whole tree in the right frame - Expand - True - gtk-add - True - True - False - - - - False - True - - - - - - - 0 - False - False - - - - - - 1 - True - True - 0 - - - - True - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - GTK_CORNER_TOP_LEFT - - - - True - True - True - False - False - False - - - - - - - - True - False - - - - - - True - True - 0 - - - - True - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - GTK_CORNER_TOP_LEFT - - - - True - True - True - True - False - False - False - - - - - - - - True - False - - - - - - True - GTK_POLICY_NEVER - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - GTK_CORNER_TOP_LEFT - - - - True - True - False - False - True - GTK_JUSTIFY_LEFT - GTK_WRAP_WORD - True - 0 - 0 - 0 - 0 - 0 - 0 - Sorry, no help available for this option yet. - - - - - True - True - - - - - True - True - - - - - 0 - True - True - - - - - - - diff --git a/config/images.c b/config/images.c deleted file mode 100644 index d4f84bd4a..000000000 --- a/config/images.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - */ - -static const char *xpm_load[] = { -"22 22 5 1", -". c None", -"# c #000000", -"c c #838100", -"a c #ffff00", -"b c #ffffff", -"......................", -"......................", -"......................", -"............####....#.", -"...........#....##.##.", -"..................###.", -".................####.", -".####...........#####.", -"#abab##########.......", -"#babababababab#.......", -"#ababababababa#.......", -"#babababababab#.......", -"#ababab###############", -"#babab##cccccccccccc##", -"#abab##cccccccccccc##.", -"#bab##cccccccccccc##..", -"#ab##cccccccccccc##...", -"#b##cccccccccccc##....", -"###cccccccccccc##.....", -"##cccccccccccc##......", -"###############.......", -"......................"}; - -static const char *xpm_save[] = { -"22 22 5 1", -". c None", -"# c #000000", -"a c #838100", -"b c #c5c2c5", -"c c #cdb6d5", -"......................", -".####################.", -".#aa#bbbbbbbbbbbb#bb#.", -".#aa#bbbbbbbbbbbb#bb#.", -".#aa#bbbbbbbbbcbb####.", -".#aa#bbbccbbbbbbb#aa#.", -".#aa#bbbccbbbbbbb#aa#.", -".#aa#bbbbbbbbbbbb#aa#.", -".#aa#bbbbbbbbbbbb#aa#.", -".#aa#bbbbbbbbbbbb#aa#.", -".#aa#bbbbbbbbbbbb#aa#.", -".#aaa############aaa#.", -".#aaaaaaaaaaaaaaaaaa#.", -".#aaaaaaaaaaaaaaaaaa#.", -".#aaa#############aa#.", -".#aaa#########bbb#aa#.", -".#aaa#########bbb#aa#.", -".#aaa#########bbb#aa#.", -".#aaa#########bbb#aa#.", -".#aaa#########bbb#aa#.", -"..##################..", -"......................"}; - -static const char *xpm_back[] = { -"22 22 3 1", -". c None", -"# c #000083", -"a c #838183", -"......................", -"......................", -"......................", -"......................", -"......................", -"...........######a....", -"..#......##########...", -"..##...####......##a..", -"..###.###.........##..", -"..######..........##..", -"..#####...........##..", -"..######..........##..", -"..#######.........##..", -"..########.......##a..", -"...............a###...", -"...............###....", -"......................", -"......................", -"......................", -"......................", -"......................", -"......................"}; - -static const char *xpm_tree_view[] = { -"22 22 2 1", -". c None", -"# c #000000", -"......................", -"......................", -"......#...............", -"......#...............", -"......#...............", -"......#...............", -"......#...............", -"......########........", -"......#...............", -"......#...............", -"......#...............", -"......#...............", -"......#...............", -"......########........", -"......#...............", -"......#...............", -"......#...............", -"......#...............", -"......#...............", -"......########........", -"......................", -"......................"}; - -static const char *xpm_single_view[] = { -"22 22 2 1", -". c None", -"# c #000000", -"......................", -"......................", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"......................", -"......................"}; - -static const char *xpm_split_view[] = { -"22 22 2 1", -". c None", -"# c #000000", -"......................", -"......................", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......................", -"......................"}; - -static const char *xpm_symbol_no[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .......... ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" .......... ", -" "}; - -static const char *xpm_symbol_mod[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .......... ", -" . . ", -" . . ", -" . .. . ", -" . .... . ", -" . .... . ", -" . .. . ", -" . . ", -" . . ", -" .......... ", -" "}; - -static const char *xpm_symbol_yes[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .......... ", -" . . ", -" . . ", -" . . . ", -" . .. . ", -" . . .. . ", -" . .... . ", -" . .. . ", -" . . ", -" .......... ", -" "}; - -static const char *xpm_choice_no[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .... ", -" .. .. ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" .. .. ", -" .... ", -" "}; - -static const char *xpm_choice_yes[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .... ", -" .. .. ", -" . . ", -" . .. . ", -" . .... . ", -" . .... . ", -" . .. . ", -" . . ", -" .. .. ", -" .... ", -" "}; - -static const char *xpm_menu[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .......... ", -" . . ", -" . .. . ", -" . .... . ", -" . ...... . ", -" . ...... . ", -" . .... . ", -" . .. . ", -" . . ", -" .......... ", -" "}; - -static const char *xpm_menu_inv[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .......... ", -" .......... ", -" .. ...... ", -" .. .... ", -" .. .. ", -" .. .. ", -" .. .... ", -" .. ...... ", -" .......... ", -" .......... ", -" "}; - -static const char *xpm_menuback[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .......... ", -" . . ", -" . .. . ", -" . .... . ", -" . ...... . ", -" . ...... . ", -" . .... . ", -" . .. . ", -" . . ", -" .......... ", -" "}; - -static const char *xpm_void[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" "}; diff --git a/config/kconfig_load.c b/config/kconfig_load.c deleted file mode 100644 index dbdcaad82..000000000 --- a/config/kconfig_load.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include - -#include "lkc.h" - -#define P(name,type,arg) type (*name ## _p) arg -#include "lkc_proto.h" -#undef P - -void kconfig_load(void) -{ - void *handle; - char *error; - - handle = dlopen("./libkconfig.so", RTLD_LAZY); - if (!handle) { - handle = dlopen("./scripts/kconfig/libkconfig.so", RTLD_LAZY); - if (!handle) { - fprintf(stderr, "%s\n", dlerror()); - exit(1); - } - } - -#define P(name,type,arg) \ -{ \ - name ## _p = dlsym(handle, #name); \ - if ((error = dlerror())) { \ - fprintf(stderr, "%s\n", error); \ - exit(1); \ - } \ -} -#include "lkc_proto.h" -#undef P -} diff --git a/config/kxgettext.c b/config/kxgettext.c deleted file mode 100644 index 8d9ce22b0..000000000 --- a/config/kxgettext.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Arnaldo Carvalho de Melo , 2005 - * - * Released under the terms of the GNU GPL v2.0 - */ - -#include -#include - -#define LKC_DIRECT_LINK -#include "lkc.h" - -static char *escape(const char* text, char *bf, int len) -{ - char *bfp = bf; - int multiline = strchr(text, '\n') != NULL; - int eol = 0; - int textlen = strlen(text); - - if ((textlen > 0) && (text[textlen-1] == '\n')) - eol = 1; - - *bfp++ = '"'; - --len; - - if (multiline) { - *bfp++ = '"'; - *bfp++ = '\n'; - *bfp++ = '"'; - len -= 3; - } - - while (*text != '\0' && len > 1) { - if (*text == '"') - *bfp++ = '\\'; - else if (*text == '\n') { - *bfp++ = '\\'; - *bfp++ = 'n'; - *bfp++ = '"'; - *bfp++ = '\n'; - *bfp++ = '"'; - len -= 5; - ++text; - goto next; - } - else if (*text == '\\') { - *bfp++ = '\\'; - len--; - } - *bfp++ = *text++; -next: - --len; - } - - if (multiline && eol) - bfp -= 3; - - *bfp++ = '"'; - *bfp = '\0'; - - return bf; -} - -struct file_line { - struct file_line *next; - char* file; - int lineno; -}; - -static struct file_line *file_line__new(char *file, int lineno) -{ - struct file_line *self = malloc(sizeof(*self)); - - if (self == NULL) - goto out; - - self->file = file; - self->lineno = lineno; - self->next = NULL; -out: - return self; -} - -struct message { - const char *msg; - const char *option; - struct message *next; - struct file_line *files; -}; - -static struct message *message__list; - -static struct message *message__new(const char *msg, char *option, char *file, int lineno) -{ - struct message *self = malloc(sizeof(*self)); - - if (self == NULL) - goto out; - - self->files = file_line__new(file, lineno); - if (self->files == NULL) - goto out_fail; - - self->msg = strdup(msg); - if (self->msg == NULL) - goto out_fail_msg; - - self->option = option; - self->next = NULL; -out: - return self; -out_fail_msg: - free(self->files); -out_fail: - free(self); - self = NULL; - goto out; -} - -static struct message *mesage__find(const char *msg) -{ - struct message *m = message__list; - - while (m != NULL) { - if (strcmp(m->msg, msg) == 0) - break; - m = m->next; - } - - return m; -} - -static int message__add_file_line(struct message *self, char *file, int lineno) -{ - int rc = -1; - struct file_line *fl = file_line__new(file, lineno); - - if (fl == NULL) - goto out; - - fl->next = self->files; - self->files = fl; - rc = 0; -out: - return rc; -} - -static int message__add(const char *msg, char *option, char *file, int lineno) -{ - int rc = 0; - char bf[16384]; - char *escaped = escape(msg, bf, sizeof(bf)); - struct message *m = mesage__find(escaped); - - if (m != NULL) - rc = message__add_file_line(m, file, lineno); - else { - m = message__new(escaped, option, file, lineno); - - if (m != NULL) { - m->next = message__list; - message__list = m; - } else - rc = -1; - } - return rc; -} - -void menu_build_message_list(struct menu *menu) -{ - struct menu *child; - - message__add(menu_get_prompt(menu), NULL, - menu->file == NULL ? "Root Menu" : menu->file->name, - menu->lineno); - - if (menu->sym != NULL && menu_has_help(menu)) - message__add(menu_get_help(menu), menu->sym->name, - menu->file == NULL ? "Root Menu" : menu->file->name, - menu->lineno); - - for (child = menu->list; child != NULL; child = child->next) - if (child->prompt != NULL) - menu_build_message_list(child); -} - -static void message__print_file_lineno(struct message *self) -{ - struct file_line *fl = self->files; - - putchar('\n'); - if (self->option != NULL) - printf("# %s:00000\n", self->option); - - printf("#: %s:%d", fl->file, fl->lineno); - fl = fl->next; - - while (fl != NULL) { - printf(", %s:%d", fl->file, fl->lineno); - fl = fl->next; - } - - putchar('\n'); -} - -static void message__print_gettext_msgid_msgstr(struct message *self) -{ - message__print_file_lineno(self); - - printf("msgid %s\n" - "msgstr \"\"\n", self->msg); -} - -void menu__xgettext(void) -{ - struct message *m = message__list; - - while (m != NULL) { - /* skip empty lines ("") */ - if (strlen(m->msg) > sizeof("\"\"")) - message__print_gettext_msgid_msgstr(m); - m = m->next; - } -} - -int main(int ac, char **av) -{ - conf_parse(av[1]); - - menu_build_message_list(menu_get_root_menu(NULL)); - menu__xgettext(); - return 0; -} diff --git a/config/lex.zconf.c_shipped b/config/lex.zconf.c_shipped deleted file mode 100644 index dc3e81807..000000000 --- a/config/lex.zconf.c_shipped +++ /dev/null @@ -1,2416 +0,0 @@ - -#line 3 "scripts/kconfig/lex.zconf.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define yy_create_buffer zconf_create_buffer -#define yy_delete_buffer zconf_delete_buffer -#define yy_flex_debug zconf_flex_debug -#define yy_init_buffer zconf_init_buffer -#define yy_flush_buffer zconf_flush_buffer -#define yy_load_buffer_state zconf_load_buffer_state -#define yy_switch_to_buffer zconf_switch_to_buffer -#define yyin zconfin -#define yyleng zconfleng -#define yylex zconflex -#define yylineno zconflineno -#define yyout zconfout -#define yyrestart zconfrestart -#define yytext zconftext -#define yywrap zconfwrap -#define yyalloc zconfalloc -#define yyrealloc zconfrealloc -#define yyfree zconffree - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN (yy_start) = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START (((yy_start) - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE zconfrestart(zconfin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -extern int zconfleng; - -extern FILE *zconfin, *zconfout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up zconftext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = (yy_hold_char); \ - YY_RESTORE_YY_MORE_OFFSET \ - (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up zconftext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, (yytext_ptr) ) - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via zconfrestart()), so that the user can continue scanning by - * just pointing zconfin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* Stack of input buffers. */ -static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ -static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ - ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] - -/* yy_hold_char holds the character lost when zconftext is formed. */ -static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ -int zconfleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 0; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow zconfwrap()'s to do buffer switches - * instead of setting up a fresh zconfin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void zconfrestart (FILE *input_file ); -void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE zconf_create_buffer (FILE *file,int size ); -void zconf_delete_buffer (YY_BUFFER_STATE b ); -void zconf_flush_buffer (YY_BUFFER_STATE b ); -void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer ); -void zconfpop_buffer_state (void ); - -static void zconfensure_buffer_stack (void ); -static void zconf_load_buffer_state (void ); -static void zconf_init_buffer (YY_BUFFER_STATE b,FILE *file ); - -#define YY_FLUSH_BUFFER zconf_flush_buffer(YY_CURRENT_BUFFER ) - -YY_BUFFER_STATE zconf_scan_buffer (char *base,yy_size_t size ); -YY_BUFFER_STATE zconf_scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE zconf_scan_bytes (yyconst char *bytes,int len ); - -void *zconfalloc (yy_size_t ); -void *zconfrealloc (void *,yy_size_t ); -void zconffree (void * ); - -#define yy_new_buffer zconf_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - zconfensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - zconf_create_buffer(zconfin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - zconfensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - zconf_create_buffer(zconfin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define zconfwrap(n) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -FILE *zconfin = (FILE *) 0, *zconfout = (FILE *) 0; - -typedef int yy_state_type; - -extern int zconflineno; - -int zconflineno = 1; - -extern char *zconftext; -#define yytext_ptr zconftext -static yyconst flex_int16_t yy_nxt[][17] = - { - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 - }, - - { - 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12 - }, - - { - 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12 - }, - - { - 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 18, 16, 16, 16 - }, - - { - 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 18, 16, 16, 16 - - }, - - { - 11, 19, 20, 21, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19 - }, - - { - 11, 19, 20, 21, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19 - }, - - { - 11, 22, 22, 23, 22, 24, 22, 22, 24, 22, - 22, 22, 22, 22, 22, 25, 22 - }, - - { - 11, 22, 22, 23, 22, 24, 22, 22, 24, 22, - 22, 22, 22, 22, 22, 25, 22 - }, - - { - 11, 26, 26, 27, 28, 29, 30, 31, 29, 32, - 33, 34, 35, 35, 36, 37, 38 - - }, - - { - 11, 26, 26, 27, 28, 29, 30, 31, 29, 32, - 33, 34, 35, 35, 36, 37, 38 - }, - - { - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11 - }, - - { - 11, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12 - }, - - { - 11, -13, 39, 40, -13, -13, 41, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13 - }, - - { - 11, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14 - - }, - - { - 11, 42, 42, 43, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42 - }, - - { - 11, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16 - }, - - { - 11, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17 - }, - - { - 11, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, 44, -18, -18, -18 - }, - - { - 11, 45, 45, -19, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45 - - }, - - { - 11, -20, 46, 47, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20 - }, - - { - 11, 48, -21, -21, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48 - }, - - { - 11, 49, 49, 50, 49, -22, 49, 49, -22, 49, - 49, 49, 49, 49, 49, -22, 49 - }, - - { - 11, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23 - }, - - { - 11, -24, -24, -24, -24, -24, -24, -24, -24, -24, - -24, -24, -24, -24, -24, -24, -24 - - }, - - { - 11, 51, 51, 52, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51 - }, - - { - 11, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26 - }, - - { - 11, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27 - }, - - { - 11, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, 53, -28, -28 - }, - - { - 11, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29 - - }, - - { - 11, 54, 54, -30, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54 - }, - - { - 11, -31, -31, -31, -31, -31, -31, 55, -31, -31, - -31, -31, -31, -31, -31, -31, -31 - }, - - { - 11, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32 - }, - - { - 11, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33 - }, - - { - 11, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, 56, 57, 57, -34, -34, -34 - - }, - - { - 11, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, 57, 57, 57, -35, -35, -35 - }, - - { - 11, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36 - }, - - { - 11, -37, -37, 58, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37 - }, - - { - 11, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, 59 - }, - - { - 11, -39, 39, 40, -39, -39, 41, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39 - - }, - - { - 11, -40, -40, -40, -40, -40, -40, -40, -40, -40, - -40, -40, -40, -40, -40, -40, -40 - }, - - { - 11, 42, 42, 43, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42 - }, - - { - 11, 42, 42, 43, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42 - }, - - { - 11, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43 - }, - - { - 11, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, 44, -44, -44, -44 - - }, - - { - 11, 45, 45, -45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45 - }, - - { - 11, -46, 46, 47, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46 - }, - - { - 11, 48, -47, -47, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48 - }, - - { - 11, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48 - }, - - { - 11, 49, 49, 50, 49, -49, 49, 49, -49, 49, - 49, 49, 49, 49, 49, -49, 49 - - }, - - { - 11, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50 - }, - - { - 11, -51, -51, 52, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51 - }, - - { - 11, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52 - }, - - { - 11, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53 - }, - - { - 11, 54, 54, -54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54 - - }, - - { - 11, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55 - }, - - { - 11, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, 60, 57, 57, -56, -56, -56 - }, - - { - 11, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, 57, 57, 57, -57, -57, -57 - }, - - { - 11, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58 - }, - - { - 11, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59 - - }, - - { - 11, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, 57, 57, 57, -60, -60, -60 - }, - - } ; - -static yy_state_type yy_get_previous_state (void ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); -static int yy_get_next_buffer (void ); -static void yy_fatal_error (yyconst char msg[] ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up zconftext. - */ -#define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ - zconfleng = (size_t) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - -#define YY_NUM_RULES 33 -#define YY_END_OF_BUFFER 34 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[61] = - { 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 34, 5, 4, 2, 3, 7, 8, 6, 32, 29, - 31, 24, 28, 27, 26, 22, 17, 13, 16, 20, - 22, 11, 12, 19, 19, 14, 22, 22, 4, 2, - 3, 3, 1, 6, 32, 29, 31, 30, 24, 23, - 26, 25, 15, 20, 9, 19, 19, 21, 10, 18 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 5, 6, 1, 1, 7, 8, 9, - 10, 1, 1, 1, 11, 12, 12, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, - 14, 1, 1, 1, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 1, 15, 1, 1, 13, 1, 13, 13, 13, 13, - - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 1, 16, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -extern int zconf_flex_debug; -int zconf_flex_debug = 0; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *zconftext; -#define YY_NO_INPUT 1 - -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - */ - -#include -#include -#include -#include -#include - -#define LKC_DIRECT_LINK -#include "lkc.h" - -#define START_STRSIZE 16 - -static struct { - struct file *file; - int lineno; -} current_pos; - -static char *text; -static int text_size, text_asize; - -struct buffer { - struct buffer *parent; - YY_BUFFER_STATE state; -}; - -struct buffer *current_buf; - -static int last_ts, first_ts; - -static void zconf_endhelp(void); -static void zconf_endfile(void); - -void new_string(void) -{ - text = malloc(START_STRSIZE); - text_asize = START_STRSIZE; - text_size = 0; - *text = 0; -} - -void append_string(const char *str, int size) -{ - int new_size = text_size + size + 1; - if (new_size > text_asize) { - new_size += START_STRSIZE - 1; - new_size &= -START_STRSIZE; - text = realloc(text, new_size); - text_asize = new_size; - } - memcpy(text + text_size, str, size); - text_size += size; - text[text_size] = 0; -} - -void alloc_string(const char *str, int size) -{ - text = malloc(size + 1); - memcpy(text, str, size); - text[size] = 0; -} - -#define INITIAL 0 -#define COMMAND 1 -#define HELP 2 -#define STRING 3 -#define PARAM 4 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -static int yy_init_globals (void ); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int zconflex_destroy (void ); - -int zconfget_debug (void ); - -void zconfset_debug (int debug_flag ); - -YY_EXTRA_TYPE zconfget_extra (void ); - -void zconfset_extra (YY_EXTRA_TYPE user_defined ); - -FILE *zconfget_in (void ); - -void zconfset_in (FILE * in_str ); - -FILE *zconfget_out (void ); - -void zconfset_out (FILE * out_str ); - -int zconfget_leng (void ); - -char *zconfget_text (void ); - -int zconfget_lineno (void ); - -void zconfset_lineno (int line_number ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int zconfwrap (void ); -#else -extern int zconfwrap (void ); -#endif -#endif - - static void yyunput (int c,char *buf_ptr ); - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (void ); -#else -static int input (void ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO fwrite( zconftext, zconfleng, 1, zconfout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - errno=0; \ - while ( (result = read( fileno(zconfin), (char *) buf, max_size )) < 0 ) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(zconfin); \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int zconflex (void); - -#define YY_DECL int zconflex (void) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after zconftext and zconfleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - - int str = 0; - int ts, i; - - if ( !(yy_init) ) - { - (yy_init) = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! (yy_start) ) - (yy_start) = 1; /* first start state */ - - if ( ! zconfin ) - zconfin = stdin; - - if ( ! zconfout ) - zconfout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - zconfensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - zconf_create_buffer(zconfin,YY_BUF_SIZE ); - } - - zconf_load_buffer_state( ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - - /* Support of zconftext. */ - *yy_cp = (yy_hold_char); - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = (yy_start); -yy_match: - while ( (yy_current_state = yy_nxt[yy_current_state][ yy_ec[YY_SC_TO_UI(*yy_cp)] ]) > 0 ) - ++yy_cp; - - yy_current_state = -yy_current_state; - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ -case 1: -/* rule 1 can match eol */ -case 2: -/* rule 2 can match eol */ -YY_RULE_SETUP -{ - current_file->lineno++; - return T_EOL; -} - YY_BREAK -case 3: -YY_RULE_SETUP - - YY_BREAK -case 4: -YY_RULE_SETUP -{ - BEGIN(COMMAND); -} - YY_BREAK -case 5: -YY_RULE_SETUP -{ - unput(zconftext[0]); - BEGIN(COMMAND); -} - YY_BREAK - -case 6: -YY_RULE_SETUP -{ - struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng); - BEGIN(PARAM); - current_pos.file = current_file; - current_pos.lineno = current_file->lineno; - if (id && id->flags & TF_COMMAND) { - zconflval.id = id; - return id->token; - } - alloc_string(zconftext, zconfleng); - zconflval.string = text; - return T_WORD; - } - YY_BREAK -case 7: -YY_RULE_SETUP - - YY_BREAK -case 8: -/* rule 8 can match eol */ -YY_RULE_SETUP -{ - BEGIN(INITIAL); - current_file->lineno++; - return T_EOL; - } - YY_BREAK - -case 9: -YY_RULE_SETUP -return T_AND; - YY_BREAK -case 10: -YY_RULE_SETUP -return T_OR; - YY_BREAK -case 11: -YY_RULE_SETUP -return T_OPEN_PAREN; - YY_BREAK -case 12: -YY_RULE_SETUP -return T_CLOSE_PAREN; - YY_BREAK -case 13: -YY_RULE_SETUP -return T_NOT; - YY_BREAK -case 14: -YY_RULE_SETUP -return T_EQUAL; - YY_BREAK -case 15: -YY_RULE_SETUP -return T_UNEQUAL; - YY_BREAK -case 16: -YY_RULE_SETUP -{ - str = zconftext[0]; - new_string(); - BEGIN(STRING); - } - YY_BREAK -case 17: -/* rule 17 can match eol */ -YY_RULE_SETUP -BEGIN(INITIAL); current_file->lineno++; return T_EOL; - YY_BREAK -case 18: -YY_RULE_SETUP -/* ignore */ - YY_BREAK -case 19: -YY_RULE_SETUP -{ - struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng); - if (id && id->flags & TF_PARAM) { - zconflval.id = id; - return id->token; - } - alloc_string(zconftext, zconfleng); - zconflval.string = text; - return T_WORD; - } - YY_BREAK -case 20: -YY_RULE_SETUP -/* comment */ - YY_BREAK -case 21: -/* rule 21 can match eol */ -YY_RULE_SETUP -current_file->lineno++; - YY_BREAK -case 22: -YY_RULE_SETUP - - YY_BREAK -case YY_STATE_EOF(PARAM): -{ - BEGIN(INITIAL); - } - YY_BREAK - -case 23: -/* rule 23 can match eol */ -*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ -(yy_c_buf_p) = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up zconftext again */ -YY_RULE_SETUP -{ - append_string(zconftext, zconfleng); - zconflval.string = text; - return T_WORD_QUOTE; - } - YY_BREAK -case 24: -YY_RULE_SETUP -{ - append_string(zconftext, zconfleng); - } - YY_BREAK -case 25: -/* rule 25 can match eol */ -*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ -(yy_c_buf_p) = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up zconftext again */ -YY_RULE_SETUP -{ - append_string(zconftext + 1, zconfleng - 1); - zconflval.string = text; - return T_WORD_QUOTE; - } - YY_BREAK -case 26: -YY_RULE_SETUP -{ - append_string(zconftext + 1, zconfleng - 1); - } - YY_BREAK -case 27: -YY_RULE_SETUP -{ - if (str == zconftext[0]) { - BEGIN(PARAM); - zconflval.string = text; - return T_WORD_QUOTE; - } else - append_string(zconftext, 1); - } - YY_BREAK -case 28: -/* rule 28 can match eol */ -YY_RULE_SETUP -{ - printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); - current_file->lineno++; - BEGIN(INITIAL); - return T_EOL; - } - YY_BREAK -case YY_STATE_EOF(STRING): -{ - BEGIN(INITIAL); - } - YY_BREAK - -case 29: -YY_RULE_SETUP -{ - ts = 0; - for (i = 0; i < zconfleng; i++) { - if (zconftext[i] == '\t') - ts = (ts & ~7) + 8; - else - ts++; - } - last_ts = ts; - if (first_ts) { - if (ts < first_ts) { - zconf_endhelp(); - return T_HELPTEXT; - } - ts -= first_ts; - while (ts > 8) { - append_string(" ", 8); - ts -= 8; - } - append_string(" ", ts); - } - } - YY_BREAK -case 30: -/* rule 30 can match eol */ -*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ -(yy_c_buf_p) = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up zconftext again */ -YY_RULE_SETUP -{ - current_file->lineno++; - zconf_endhelp(); - return T_HELPTEXT; - } - YY_BREAK -case 31: -/* rule 31 can match eol */ -YY_RULE_SETUP -{ - current_file->lineno++; - append_string("\n", 1); - } - YY_BREAK -case 32: -YY_RULE_SETUP -{ - while (zconfleng) { - if ((zconftext[zconfleng-1] != ' ') && (zconftext[zconfleng-1] != '\t')) - break; - zconfleng--; - } - append_string(zconftext, zconfleng); - if (!first_ts) - first_ts = last_ts; - } - YY_BREAK -case YY_STATE_EOF(HELP): -{ - zconf_endhelp(); - return T_HELPTEXT; - } - YY_BREAK - -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(COMMAND): -{ - if (current_file) { - zconf_endfile(); - return T_EOL; - } - fclose(zconfin); - yyterminate(); -} - YY_BREAK -case 33: -YY_RULE_SETUP -YY_FATAL_ERROR( "flex scanner jammed" ); - YY_BREAK - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = (yy_hold_char); - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed zconfin at a new source and called - * zconflex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = zconfin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++(yy_c_buf_p); - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = (yy_c_buf_p); - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_END_OF_FILE: - { - (yy_did_buffer_switch_on_eof) = 0; - - if ( zconfwrap( ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * zconftext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = - (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - (yy_c_buf_p) = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of zconflex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (void) -{ - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = (yytext_ptr); - register int number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - zconfrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - if ( (yy_n_chars) == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - zconfrestart(zconfin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) zconfrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - (yy_n_chars) += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - - (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (void) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = (yy_start); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { - yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) -{ - register int yy_is_jam; - - yy_current_state = yy_nxt[yy_current_state][1]; - yy_is_jam = (yy_current_state <= 0); - - return yy_is_jam ? 0 : yy_current_state; -} - - static void yyunput (int c, register char * yy_bp ) -{ - register char *yy_cp; - - yy_cp = (yy_c_buf_p); - - /* undo effects of setting up zconftext */ - *yy_cp = (yy_hold_char); - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = (yy_n_chars) + 2; - register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - register char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - (yytext_ptr) = yy_bp; - (yy_hold_char) = *yy_cp; - (yy_c_buf_p) = yy_cp; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (void) -#else - static int input (void) -#endif - -{ - int c; - - *(yy_c_buf_p) = (yy_hold_char); - - if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - /* This was really a NUL. */ - *(yy_c_buf_p) = '\0'; - - else - { /* need more input */ - int offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - zconfrestart(zconfin ); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( zconfwrap( ) ) - return EOF; - - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = (yytext_ptr) + offset; - break; - } - } - } - - c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ - *(yy_c_buf_p) = '\0'; /* preserve zconftext */ - (yy_hold_char) = *++(yy_c_buf_p); - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * - * @note This function does not reset the start condition to @c INITIAL . - */ - void zconfrestart (FILE * input_file ) -{ - - if ( ! YY_CURRENT_BUFFER ){ - zconfensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - zconf_create_buffer(zconfin,YY_BUF_SIZE ); - } - - zconf_init_buffer(YY_CURRENT_BUFFER,input_file ); - zconf_load_buffer_state( ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * - */ - void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer ) -{ - - /* TODO. We should be able to replace this entire function body - * with - * zconfpop_buffer_state(); - * zconfpush_buffer_state(new_buffer); - */ - zconfensure_buffer_stack (); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - zconf_load_buffer_state( ); - - /* We don't actually know whether we did this switch during - * EOF (zconfwrap()) processing, but the only time this flag - * is looked at is after zconfwrap() is called, so it's safe - * to go ahead and always set it. - */ - (yy_did_buffer_switch_on_eof) = 1; -} - -static void zconf_load_buffer_state (void) -{ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - zconfin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - (yy_hold_char) = *(yy_c_buf_p); -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * - * @return the allocated buffer state. - */ - YY_BUFFER_STATE zconf_create_buffer (FILE * file, int size ) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) zconfalloc(b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - zconf_init_buffer(b,file ); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with zconf_create_buffer() - * - */ - void zconf_delete_buffer (YY_BUFFER_STATE b ) -{ - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - zconffree((void *) b->yy_ch_buf ); - - zconffree((void *) b ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a zconfrestart() or at EOF. - */ - static void zconf_init_buffer (YY_BUFFER_STATE b, FILE * file ) - -{ - int oerrno = errno; - - zconf_flush_buffer(b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then zconf_init_buffer was _probably_ - * called from zconfrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * - */ - void zconf_flush_buffer (YY_BUFFER_STATE b ) -{ - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - zconf_load_buffer_state( ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * - */ -void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer ) -{ - if (new_buffer == NULL) - return; - - zconfensure_buffer_stack(); - - /* This block is copied from zconf_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - (yy_buffer_stack_top)++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from zconf_switch_to_buffer. */ - zconf_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * - */ -void zconfpop_buffer_state (void) -{ - if (!YY_CURRENT_BUFFER) - return; - - zconf_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - if ((yy_buffer_stack_top) > 0) - --(yy_buffer_stack_top); - - if (YY_CURRENT_BUFFER) { - zconf_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void zconfensure_buffer_stack (void) -{ - int num_to_alloc; - - if (!(yy_buffer_stack)) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - (yy_buffer_stack) = (struct yy_buffer_state**)zconfalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in zconfensure_buffer_stack()" ); - - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; - } - - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)zconfrealloc - ((yy_buffer_stack), - num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in zconfensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); - (yy_buffer_stack_max) = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size ) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - zconf_switch_to_buffer(b ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to zconflex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * zconf_scan_bytes() instead. - */ -YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr ) -{ - - return zconf_scan_bytes(yystr,strlen(yystr) ); -} - -/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will - * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE zconf_scan_bytes (yyconst char * yybytes, int _yybytes_len ) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) zconfalloc(n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = zconf_scan_buffer(buf,n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in zconf_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg ) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up zconftext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - zconftext[zconfleng] = (yy_hold_char); \ - (yy_c_buf_p) = zconftext + yyless_macro_arg; \ - (yy_hold_char) = *(yy_c_buf_p); \ - *(yy_c_buf_p) = '\0'; \ - zconfleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the current line number. - * - */ -int zconfget_lineno (void) -{ - - return zconflineno; -} - -/** Get the input stream. - * - */ -FILE *zconfget_in (void) -{ - return zconfin; -} - -/** Get the output stream. - * - */ -FILE *zconfget_out (void) -{ - return zconfout; -} - -/** Get the length of the current token. - * - */ -int zconfget_leng (void) -{ - return zconfleng; -} - -/** Get the current token. - * - */ - -char *zconfget_text (void) -{ - return zconftext; -} - -/** Set the current line number. - * @param line_number - * - */ -void zconfset_lineno (int line_number ) -{ - - zconflineno = line_number; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * - * @see zconf_switch_to_buffer - */ -void zconfset_in (FILE * in_str ) -{ - zconfin = in_str ; -} - -void zconfset_out (FILE * out_str ) -{ - zconfout = out_str ; -} - -int zconfget_debug (void) -{ - return zconf_flex_debug; -} - -void zconfset_debug (int bdebug ) -{ - zconf_flex_debug = bdebug ; -} - -static int yy_init_globals (void) -{ - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from zconflex_destroy(), so don't allocate here. - */ - - (yy_buffer_stack) = 0; - (yy_buffer_stack_top) = 0; - (yy_buffer_stack_max) = 0; - (yy_c_buf_p) = (char *) 0; - (yy_init) = 0; - (yy_start) = 0; - -/* Defined in main.c */ -#ifdef YY_STDINIT - zconfin = stdin; - zconfout = stdout; -#else - zconfin = (FILE *) 0; - zconfout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * zconflex_init() - */ - return 0; -} - -/* zconflex_destroy is for both reentrant and non-reentrant scanners. */ -int zconflex_destroy (void) -{ - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - zconf_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - zconfpop_buffer_state(); - } - - /* Destroy the stack itself. */ - zconffree((yy_buffer_stack) ); - (yy_buffer_stack) = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * zconflex() is called, initialization will occur. */ - yy_init_globals( ); - - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s ) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *zconfalloc (yy_size_t size ) -{ - return (void *) malloc( size ); -} - -void *zconfrealloc (void * ptr, yy_size_t size ) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void zconffree (void * ptr ) -{ - free( (char *) ptr ); /* see zconfrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -void zconf_starthelp(void) -{ - new_string(); - last_ts = first_ts = 0; - BEGIN(HELP); -} - -static void zconf_endhelp(void) -{ - zconflval.string = text; - BEGIN(INITIAL); -} - -/* - * Try to open specified file with following names: - * ./name - * $(srctree)/name - * The latter is used when srctree is separate from objtree - * when compiling the kernel. - * Return NULL if file is not found. - */ -FILE *zconf_fopen(const char *name) -{ - char *env, fullname[PATH_MAX+1]; - FILE *f; - - f = fopen(name, "r"); - if (!f && name != NULL && name[0] != '/') { - env = getenv(SRCTREE); - if (env) { - sprintf(fullname, "%s/%s", env, name); - f = fopen(fullname, "r"); - } - } - return f; -} - -void zconf_initscan(const char *name) -{ - zconfin = zconf_fopen(name); - if (!zconfin) { - printf("can't find file %s\n", name); - exit(1); - } - - current_buf = malloc(sizeof(*current_buf)); - memset(current_buf, 0, sizeof(*current_buf)); - - current_file = file_lookup(name); - current_file->lineno = 1; - current_file->flags = FILE_BUSY; -} - -void zconf_nextfile(const char *name) -{ - struct file *file = file_lookup(name); - struct buffer *buf = malloc(sizeof(*buf)); - memset(buf, 0, sizeof(*buf)); - - current_buf->state = YY_CURRENT_BUFFER; - zconfin = zconf_fopen(name); - if (!zconfin) { - printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); - exit(1); - } - zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE)); - buf->parent = current_buf; - current_buf = buf; - - if (file->flags & FILE_BUSY) { - printf("%s:%d: do not source '%s' from itself\n", - zconf_curname(), zconf_lineno(), name); - exit(1); - } - if (file->flags & FILE_SCANNED) { - printf("%s:%d: file '%s' is already sourced from '%s'\n", - zconf_curname(), zconf_lineno(), name, - file->parent->name); - exit(1); - } - file->flags |= FILE_BUSY; - file->lineno = 1; - file->parent = current_file; - current_file = file; -} - -static void zconf_endfile(void) -{ - struct buffer *parent; - - current_file->flags |= FILE_SCANNED; - current_file->flags &= ~FILE_BUSY; - current_file = current_file->parent; - - parent = current_buf->parent; - if (parent) { - fclose(zconfin); - zconf_delete_buffer(YY_CURRENT_BUFFER); - zconf_switch_to_buffer(parent->state); - } - free(current_buf); - current_buf = parent; -} - -int zconf_lineno(void) -{ - return current_pos.lineno; -} - -char *zconf_curname(void) -{ - return current_pos.file ? current_pos.file->name : ""; -} - diff --git a/config/lkc.h b/config/lkc.h deleted file mode 100644 index f379b0bf8..000000000 --- a/config/lkc.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - */ - -#ifndef LKC_H -#define LKC_H - -#include "expr.h" - -#ifndef KBUILD_NO_NLS -# include -#else -static inline const char *gettext(const char *txt) { return txt; } -static inline void textdomain(const char *domainname) {} -static inline void bindtextdomain(const char *name, const char *dir) {} -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef LKC_DIRECT_LINK -#define P(name,type,arg) extern type name arg -#else -#include "lkc_defs.h" -#define P(name,type,arg) extern type (*name ## _p) arg -#endif -#include "lkc_proto.h" -#undef P - -#define SRCTREE "srctree" - -#define PACKAGE "linux" -#define LOCALEDIR "/usr/share/locale" - -#define _(text) gettext(text) -#define N_(text) (text) - - -#define TF_COMMAND 0x0001 -#define TF_PARAM 0x0002 -#define TF_OPTION 0x0004 - -enum conf_def_mode { - def_default, - def_yes, - def_mod, - def_no, - def_random -}; - -#define T_OPT_MODULES 1 -#define T_OPT_DEFCONFIG_LIST 2 -#define T_OPT_ENV 3 - -struct kconf_id { - int name; - int token; - unsigned int flags; - enum symbol_type stype; -}; - -int zconfparse(void); -void zconfdump(FILE *out); - -extern int zconfdebug; -void zconf_starthelp(void); -FILE *zconf_fopen(const char *name); -void zconf_initscan(const char *name); -void zconf_nextfile(const char *name); -int zconf_lineno(void); -char *zconf_curname(void); - -/* confdata.c */ -const char *conf_get_configname(void); -const char *conf_get_autoconfig_name(void); -char *conf_get_default_confname(void); -void sym_set_change_count(int count); -void sym_add_change_count(int count); -void conf_set_all_new_symbols(enum conf_def_mode mode); - -/* kconfig_load.c */ -void kconfig_load(void); - -/* menu.c */ -void menu_init(void); -void menu_warn(struct menu *menu, const char *fmt, ...); -struct menu *menu_add_menu(void); -void menu_end_menu(void); -void menu_add_entry(struct symbol *sym); -void menu_end_entry(void); -void menu_add_dep(struct expr *dep); -struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep); -struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); -void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); -void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); -void menu_add_option(int token, char *arg); -void menu_finalize(struct menu *parent); -void menu_set_type(int type); - -/* util.c */ -struct file *file_lookup(const char *name); -int file_write_dep(const char *name); - -struct gstr { - size_t len; - char *s; -}; -struct gstr str_new(void); -struct gstr str_assign(const char *s); -void str_free(struct gstr *gs); -void str_append(struct gstr *gs, const char *s); -void str_printf(struct gstr *gs, const char *fmt, ...); -const char *str_get(struct gstr *gs); - -/* symbol.c */ -extern struct expr *sym_env_list; - -void sym_init(void); -void sym_clear_all_valid(void); -void sym_set_all_changed(void); -void sym_set_changed(struct symbol *sym); -struct symbol *sym_check_deps(struct symbol *sym); -struct property *prop_alloc(enum prop_type type, struct symbol *sym); -struct symbol *prop_get_symbol(struct property *prop); -struct property *sym_get_env_prop(struct symbol *sym); - -static inline tristate sym_get_tristate_value(struct symbol *sym) -{ - return sym->curr.tri; -} - - -static inline struct symbol *sym_get_choice_value(struct symbol *sym) -{ - return (struct symbol *)sym->curr.val; -} - -static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval) -{ - return sym_set_tristate_value(chval, yes); -} - -static inline bool sym_is_choice(struct symbol *sym) -{ - return sym->flags & SYMBOL_CHOICE ? true : false; -} - -static inline bool sym_is_choice_value(struct symbol *sym) -{ - return sym->flags & SYMBOL_CHOICEVAL ? true : false; -} - -static inline bool sym_is_optional(struct symbol *sym) -{ - return sym->flags & SYMBOL_OPTIONAL ? true : false; -} - -static inline bool sym_has_value(struct symbol *sym) -{ - return sym->flags & SYMBOL_DEF_USER ? true : false; -} - -#ifdef __cplusplus -} -#endif - -#endif /* LKC_H */ diff --git a/config/lkc_proto.h b/config/lkc_proto.h deleted file mode 100644 index 8e6946131..000000000 --- a/config/lkc_proto.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* confdata.c */ -P(conf_parse,void,(const char *name)); -P(conf_read,int,(const char *name)); -P(conf_read_simple,int,(const char *name, int)); -P(conf_write,int,(const char *name)); -P(conf_write_autoconf,int,(void)); -P(conf_get_changed,bool,(void)); -P(conf_set_changed_callback, void,(void (*fn)(void))); - -/* menu.c */ -P(rootmenu,struct menu,); - -P(menu_is_visible,bool,(struct menu *menu)); -P(menu_get_prompt,const char *,(struct menu *menu)); -P(menu_get_root_menu,struct menu *,(struct menu *menu)); -P(menu_get_parent_menu,struct menu *,(struct menu *menu)); -P(menu_has_help,bool,(struct menu *menu)); -P(menu_get_help,const char *,(struct menu *menu)); - -/* symbol.c */ -P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); - -P(sym_lookup,struct symbol *,(const char *name, int flags)); -P(sym_find,struct symbol *,(const char *name)); -P(sym_re_search,struct symbol **,(const char *pattern)); -P(sym_type_name,const char *,(enum symbol_type type)); -P(sym_calc_value,void,(struct symbol *sym)); -P(sym_get_type,enum symbol_type,(struct symbol *sym)); -P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); -P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri)); -P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); -P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); -P(sym_string_within_range,bool,(struct symbol *sym, const char *str)); -P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); -P(sym_is_changable,bool,(struct symbol *sym)); -P(sym_get_choice_prop,struct property *,(struct symbol *sym)); -P(sym_get_default_prop,struct property *,(struct symbol *sym)); -P(sym_get_string_value,const char *,(struct symbol *sym)); - -P(prop_get_type_name,const char *,(enum prop_type type)); - -/* expr.c */ -P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); -P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)); diff --git a/config/lxdialog/.gitignore b/config/lxdialog/.gitignore deleted file mode 100644 index 90b08ff02..000000000 --- a/config/lxdialog/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# -# Generated files -# -lxdialog diff --git a/config/lxdialog/BIG.FAT.WARNING b/config/lxdialog/BIG.FAT.WARNING deleted file mode 100644 index a8999d82b..000000000 --- a/config/lxdialog/BIG.FAT.WARNING +++ /dev/null @@ -1,4 +0,0 @@ -This is NOT the official version of dialog. This version has been -significantly modified from the original. It is for use by the Linux -kernel configuration script. Please do not bother Savio Lam with -questions about this program. diff --git a/config/lxdialog/check-lxdialog.sh b/config/lxdialog/check-lxdialog.sh deleted file mode 100644 index fcef0f59d..000000000 --- a/config/lxdialog/check-lxdialog.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/sh -# Check ncurses compatibility - -# What library to link -ldflags() -{ - for ext in so a dylib ; do - for lib in ncursesw ncurses curses ; do - $cc -print-file-name=lib${lib}.${ext} | grep -q / - if [ $? -eq 0 ]; then - echo "-l${lib}" - exit - fi - done - done - exit 1 -} - -# Where is ncurses.h? -ccflags() -{ - if [ -f /usr/include/ncurses/ncurses.h ]; then - echo '-I/usr/include/ncurses -DCURSES_LOC=""' - elif [ -f /usr/include/ncurses/curses.h ]; then - echo '-I/usr/include/ncurses -DCURSES_LOC=""' - elif [ -f /usr/include/ncurses.h ]; then - echo '-DCURSES_LOC=""' - else - echo '-DCURSES_LOC=""' - fi -} - -# Temp file, try to clean up after us -tmp=.lxdialog.tmp -trap "rm -f $tmp" 0 1 2 3 15 - -# Check if we can link to ncurses -check() { - $cc -xc - -o $tmp 2>/dev/null <<'EOF' -#include CURSES_LOC -main() {} -EOF - if [ $? != 0 ]; then - echo " *** Unable to find the ncurses libraries or the" 1>&2 - echo " *** required header files." 1>&2 - echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2 - echo " *** " 1>&2 - echo " *** Install ncurses (ncurses-devel) and try again." 1>&2 - echo " *** " 1>&2 - exit 1 - fi -} - -usage() { - printf "Usage: $0 [-check compiler options|-ccflags|-ldflags compiler options]\n" -} - -if [ $# -eq 0 ]; then - usage - exit 1 -fi - -cc="" -case "$1" in - "-check") - shift - cc="$@" - check - ;; - "-ccflags") - ccflags - ;; - "-ldflags") - shift - cc="$@" - ldflags - ;; - "*") - usage - exit 1 - ;; -esac diff --git a/config/lxdialog/checklist.c b/config/lxdialog/checklist.c deleted file mode 100644 index bcc6f19c3..000000000 --- a/config/lxdialog/checklist.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * checklist.c -- implements the checklist box - * - * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) - * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension - * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two - * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "dialog.h" - -static int list_width, check_x, item_x; - -/* - * Print list item - */ -static void print_item(WINDOW * win, int choice, int selected) -{ - int i; - - /* Clear 'residue' of last item */ - wattrset(win, dlg.menubox.atr); - wmove(win, choice, 0); - for (i = 0; i < list_width; i++) - waddch(win, ' '); - - wmove(win, choice, check_x); - wattrset(win, selected ? dlg.check_selected.atr - : dlg.check.atr); - if (!item_is_tag(':')) - wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); - - wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); - mvwaddch(win, choice, item_x, item_str()[0]); - wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); - waddstr(win, (char *)item_str() + 1); - if (selected) { - wmove(win, choice, check_x + 1); - wrefresh(win); - } -} - -/* - * Print the scroll indicators. - */ -static void print_arrows(WINDOW * win, int choice, int item_no, int scroll, - int y, int x, int height) -{ - wmove(win, y, x); - - if (scroll > 0) { - wattrset(win, dlg.uarrow.atr); - waddch(win, ACS_UARROW); - waddstr(win, "(-)"); - } else { - wattrset(win, dlg.menubox.atr); - waddch(win, ACS_HLINE); - waddch(win, ACS_HLINE); - waddch(win, ACS_HLINE); - waddch(win, ACS_HLINE); - } - - y = y + height + 1; - wmove(win, y, x); - - if ((height < item_no) && (scroll + choice < item_no - 1)) { - wattrset(win, dlg.darrow.atr); - waddch(win, ACS_DARROW); - waddstr(win, "(+)"); - } else { - wattrset(win, dlg.menubox_border.atr); - waddch(win, ACS_HLINE); - waddch(win, ACS_HLINE); - waddch(win, ACS_HLINE); - waddch(win, ACS_HLINE); - } -} - -/* - * Display the termination buttons - */ -static void print_buttons(WINDOW * dialog, int height, int width, int selected) -{ - int x = width / 2 - 11; - int y = height - 2; - - print_button(dialog, gettext("Select"), y, x, selected == 0); - print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); - - wmove(dialog, y, x + 1 + 14 * selected); - wrefresh(dialog); -} - -/* - * Display a dialog box with a list of options that can be turned on or off - * in the style of radiolist (only one option turned on at a time). - */ -int dialog_checklist(const char *title, const char *prompt, int height, - int width, int list_height) -{ - int i, x, y, box_x, box_y; - int key = 0, button = 0, choice = 0, scroll = 0, max_choice; - WINDOW *dialog, *list; - - /* which item to highlight */ - item_foreach() { - if (item_is_tag('X')) - choice = item_n(); - if (item_is_selected()) { - choice = item_n(); - break; - } - } - -do_resize: - if (getmaxy(stdscr) < (height + 6)) - return -ERRDISPLAYTOOSMALL; - if (getmaxx(stdscr) < (width + 6)) - return -ERRDISPLAYTOOSMALL; - - max_choice = MIN(list_height, item_count()); - - /* center dialog box on screen */ - x = (COLS - width) / 2; - y = (LINES - height) / 2; - - draw_shadow(stdscr, y, x, height, width); - - dialog = newwin(height, width, y, x); - keypad(dialog, TRUE); - - draw_box(dialog, 0, 0, height, width, - dlg.dialog.atr, dlg.border.atr); - wattrset(dialog, dlg.border.atr); - mvwaddch(dialog, height - 3, 0, ACS_LTEE); - for (i = 0; i < width - 2; i++) - waddch(dialog, ACS_HLINE); - wattrset(dialog, dlg.dialog.atr); - waddch(dialog, ACS_RTEE); - - print_title(dialog, title, width); - - wattrset(dialog, dlg.dialog.atr); - print_autowrap(dialog, prompt, width - 2, 1, 3); - - list_width = width - 6; - box_y = height - list_height - 5; - box_x = (width - list_width) / 2 - 1; - - /* create new window for the list */ - list = subwin(dialog, list_height, list_width, y + box_y + 1, - x + box_x + 1); - - keypad(list, TRUE); - - /* draw a box around the list items */ - draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, - dlg.menubox_border.atr, dlg.menubox.atr); - - /* Find length of longest item in order to center checklist */ - check_x = 0; - item_foreach() - check_x = MAX(check_x, strlen(item_str()) + 4); - - check_x = (list_width - check_x) / 2; - item_x = check_x + 4; - - if (choice >= list_height) { - scroll = choice - list_height + 1; - choice -= scroll; - } - - /* Print the list */ - for (i = 0; i < max_choice; i++) { - item_set(scroll + i); - print_item(list, i, i == choice); - } - - print_arrows(dialog, choice, item_count(), scroll, - box_y, box_x + check_x + 5, list_height); - - print_buttons(dialog, height, width, 0); - - wnoutrefresh(dialog); - wnoutrefresh(list); - doupdate(); - - while (key != KEY_ESC) { - key = wgetch(dialog); - - for (i = 0; i < max_choice; i++) { - item_set(i + scroll); - if (toupper(key) == toupper(item_str()[0])) - break; - } - - if (i < max_choice || key == KEY_UP || key == KEY_DOWN || - key == '+' || key == '-') { - if (key == KEY_UP || key == '-') { - if (!choice) { - if (!scroll) - continue; - /* Scroll list down */ - if (list_height > 1) { - /* De-highlight current first item */ - item_set(scroll); - print_item(list, 0, FALSE); - scrollok(list, TRUE); - wscrl(list, -1); - scrollok(list, FALSE); - } - scroll--; - item_set(scroll); - print_item(list, 0, TRUE); - print_arrows(dialog, choice, item_count(), - scroll, box_y, box_x + check_x + 5, list_height); - - wnoutrefresh(dialog); - wrefresh(list); - - continue; /* wait for another key press */ - } else - i = choice - 1; - } else if (key == KEY_DOWN || key == '+') { - if (choice == max_choice - 1) { - if (scroll + choice >= item_count() - 1) - continue; - /* Scroll list up */ - if (list_height > 1) { - /* De-highlight current last item before scrolling up */ - item_set(scroll + max_choice - 1); - print_item(list, - max_choice - 1, - FALSE); - scrollok(list, TRUE); - wscrl(list, 1); - scrollok(list, FALSE); - } - scroll++; - item_set(scroll + max_choice - 1); - print_item(list, max_choice - 1, TRUE); - - print_arrows(dialog, choice, item_count(), - scroll, box_y, box_x + check_x + 5, list_height); - - wnoutrefresh(dialog); - wrefresh(list); - - continue; /* wait for another key press */ - } else - i = choice + 1; - } - if (i != choice) { - /* De-highlight current item */ - item_set(scroll + choice); - print_item(list, choice, FALSE); - /* Highlight new item */ - choice = i; - item_set(scroll + choice); - print_item(list, choice, TRUE); - wnoutrefresh(dialog); - wrefresh(list); - } - continue; /* wait for another key press */ - } - switch (key) { - case 'H': - case 'h': - case '?': - button = 1; - /* fall-through */ - case 'S': - case 's': - case ' ': - case '\n': - item_foreach() - item_set_selected(0); - item_set(scroll + choice); - item_set_selected(1); - delwin(list); - delwin(dialog); - return button; - case TAB: - case KEY_LEFT: - case KEY_RIGHT: - button = ((key == KEY_LEFT ? --button : ++button) < 0) - ? 1 : (button > 1 ? 0 : button); - - print_buttons(dialog, height, width, button); - wrefresh(dialog); - break; - case 'X': - case 'x': - key = KEY_ESC; - break; - case KEY_ESC: - key = on_key_esc(dialog); - break; - case KEY_RESIZE: - delwin(list); - delwin(dialog); - on_key_resize(); - goto do_resize; - } - - /* Now, update everything... */ - doupdate(); - } - delwin(list); - delwin(dialog); - return key; /* ESC pressed */ -} diff --git a/config/lxdialog/dialog.h b/config/lxdialog/dialog.h deleted file mode 100644 index b5211fce0..000000000 --- a/config/lxdialog/dialog.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * dialog.h -- common declarations for all dialog modules - * - * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -#ifndef KBUILD_NO_NLS -# include -#else -# define gettext(Msgid) ((const char *) (Msgid)) -#endif - -#ifdef __sun__ -#define CURS_MACROS -#endif -#include CURSES_LOC - -/* - * Colors in ncurses 1.9.9e do not work properly since foreground and - * background colors are OR'd rather than separately masked. This version - * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible - * with standard curses. The simplest fix (to make this work with standard - * curses) uses the wbkgdset() function, not used in the original hack. - * Turn it off if we're building with 1.9.9e, since it just confuses things. - */ -#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE) -#define OLD_NCURSES 1 -#undef wbkgdset -#define wbkgdset(w,p) /*nothing */ -#else -#define OLD_NCURSES 0 -#endif - -#define TR(params) _tracef params - -#define KEY_ESC 27 -#define TAB 9 -#define MAX_LEN 2048 -#define BUF_SIZE (10*1024) -#define MIN(x,y) (x < y ? x : y) -#define MAX(x,y) (x > y ? x : y) - -#ifndef ACS_ULCORNER -#define ACS_ULCORNER '+' -#endif -#ifndef ACS_LLCORNER -#define ACS_LLCORNER '+' -#endif -#ifndef ACS_URCORNER -#define ACS_URCORNER '+' -#endif -#ifndef ACS_LRCORNER -#define ACS_LRCORNER '+' -#endif -#ifndef ACS_HLINE -#define ACS_HLINE '-' -#endif -#ifndef ACS_VLINE -#define ACS_VLINE '|' -#endif -#ifndef ACS_LTEE -#define ACS_LTEE '+' -#endif -#ifndef ACS_RTEE -#define ACS_RTEE '+' -#endif -#ifndef ACS_UARROW -#define ACS_UARROW '^' -#endif -#ifndef ACS_DARROW -#define ACS_DARROW 'v' -#endif - -/* error return codes */ -#define ERRDISPLAYTOOSMALL (KEY_MAX + 1) - -/* - * Color definitions - */ -struct dialog_color { - chtype atr; /* Color attribute */ - int fg; /* foreground */ - int bg; /* background */ - int hl; /* highlight this item */ -}; - -struct dialog_info { - const char *backtitle; - struct dialog_color screen; - struct dialog_color shadow; - struct dialog_color dialog; - struct dialog_color title; - struct dialog_color border; - struct dialog_color button_active; - struct dialog_color button_inactive; - struct dialog_color button_key_active; - struct dialog_color button_key_inactive; - struct dialog_color button_label_active; - struct dialog_color button_label_inactive; - struct dialog_color inputbox; - struct dialog_color inputbox_border; - struct dialog_color searchbox; - struct dialog_color searchbox_title; - struct dialog_color searchbox_border; - struct dialog_color position_indicator; - struct dialog_color menubox; - struct dialog_color menubox_border; - struct dialog_color item; - struct dialog_color item_selected; - struct dialog_color tag; - struct dialog_color tag_selected; - struct dialog_color tag_key; - struct dialog_color tag_key_selected; - struct dialog_color check; - struct dialog_color check_selected; - struct dialog_color uarrow; - struct dialog_color darrow; -}; - -/* - * Global variables - */ -extern struct dialog_info dlg; -extern char dialog_input_result[]; - -/* - * Function prototypes - */ - -/* item list as used by checklist and menubox */ -void item_reset(void); -void item_make(const char *fmt, ...); -void item_add_str(const char *fmt, ...); -void item_set_tag(char tag); -void item_set_data(void *p); -void item_set_selected(int val); -int item_activate_selected(void); -void *item_data(void); -char item_tag(void); - -/* item list manipulation for lxdialog use */ -#define MAXITEMSTR 200 -struct dialog_item { - char str[MAXITEMSTR]; /* promtp displayed */ - char tag; - void *data; /* pointer to menu item - used by menubox+checklist */ - int selected; /* Set to 1 by dialog_*() function if selected. */ -}; - -/* list of lialog_items */ -struct dialog_list { - struct dialog_item node; - struct dialog_list *next; -}; - -extern struct dialog_list *item_cur; -extern struct dialog_list item_nil; -extern struct dialog_list *item_head; - -int item_count(void); -void item_set(int n); -int item_n(void); -const char *item_str(void); -int item_is_selected(void); -int item_is_tag(char tag); -#define item_foreach() \ - for (item_cur = item_head ? item_head: item_cur; \ - item_cur && (item_cur != &item_nil); item_cur = item_cur->next) - -/* generic key handlers */ -int on_key_esc(WINDOW *win); -int on_key_resize(void); - -int init_dialog(const char *backtitle); -void set_dialog_backtitle(const char *backtitle); -void end_dialog(int x, int y); -void attr_clear(WINDOW * win, int height, int width, chtype attr); -void dialog_clear(void); -void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x); -void print_button(WINDOW * win, const char *label, int y, int x, int selected); -void print_title(WINDOW *dialog, const char *title, int width); -void draw_box(WINDOW * win, int y, int x, int height, int width, chtype box, - chtype border); -void draw_shadow(WINDOW * win, int y, int x, int height, int width); - -int first_alpha(const char *string, const char *exempt); -int dialog_yesno(const char *title, const char *prompt, int height, int width); -int dialog_msgbox(const char *title, const char *prompt, int height, - int width, int pause); -int dialog_textbox(const char *title, const char *file, int height, int width); -int dialog_menu(const char *title, const char *prompt, - const void *selected, int *s_scroll); -int dialog_checklist(const char *title, const char *prompt, int height, - int width, int list_height); -extern char dialog_input_result[]; -int dialog_inputbox(const char *title, const char *prompt, int height, - int width, const char *init); - -/* - * This is the base for fictitious keys, which activate - * the buttons. - * - * Mouse-generated keys are the following: - * -- the first 32 are used as numbers, in addition to '0'-'9' - * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o') - * -- uppercase chars are used to invoke the button (M_EVENT + 'O') - */ -#define M_EVENT (KEY_MAX+1) diff --git a/config/lxdialog/inputbox.c b/config/lxdialog/inputbox.c deleted file mode 100644 index 616c60138..000000000 --- a/config/lxdialog/inputbox.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * inputbox.c -- implements the input box - * - * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) - * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "dialog.h" - -char dialog_input_result[MAX_LEN + 1]; - -/* - * Print the termination buttons - */ -static void print_buttons(WINDOW * dialog, int height, int width, int selected) -{ - int x = width / 2 - 11; - int y = height - 2; - - print_button(dialog, gettext(" Ok "), y, x, selected == 0); - print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); - - wmove(dialog, y, x + 1 + 14 * selected); - wrefresh(dialog); -} - -/* - * Display a dialog box for inputing a string - */ -int dialog_inputbox(const char *title, const char *prompt, int height, int width, - const char *init) -{ - int i, x, y, box_y, box_x, box_width; - int input_x = 0, scroll = 0, key = 0, button = -1; - char *instr = dialog_input_result; - WINDOW *dialog; - - if (!init) - instr[0] = '\0'; - else - strcpy(instr, init); - -do_resize: - if (getmaxy(stdscr) <= (height - 2)) - return -ERRDISPLAYTOOSMALL; - if (getmaxx(stdscr) <= (width - 2)) - return -ERRDISPLAYTOOSMALL; - - /* center dialog box on screen */ - x = (COLS - width) / 2; - y = (LINES - height) / 2; - - draw_shadow(stdscr, y, x, height, width); - - dialog = newwin(height, width, y, x); - keypad(dialog, TRUE); - - draw_box(dialog, 0, 0, height, width, - dlg.dialog.atr, dlg.border.atr); - wattrset(dialog, dlg.border.atr); - mvwaddch(dialog, height - 3, 0, ACS_LTEE); - for (i = 0; i < width - 2; i++) - waddch(dialog, ACS_HLINE); - wattrset(dialog, dlg.dialog.atr); - waddch(dialog, ACS_RTEE); - - print_title(dialog, title, width); - - wattrset(dialog, dlg.dialog.atr); - print_autowrap(dialog, prompt, width - 2, 1, 3); - - /* Draw the input field box */ - box_width = width - 6; - getyx(dialog, y, x); - box_y = y + 2; - box_x = (width - box_width) / 2; - draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, - dlg.dialog.atr, dlg.border.atr); - - print_buttons(dialog, height, width, 0); - - /* Set up the initial value */ - wmove(dialog, box_y, box_x); - wattrset(dialog, dlg.inputbox.atr); - - input_x = strlen(instr); - - if (input_x >= box_width) { - scroll = input_x - box_width + 1; - input_x = box_width - 1; - for (i = 0; i < box_width - 1; i++) - waddch(dialog, instr[scroll + i]); - } else { - waddstr(dialog, instr); - } - - wmove(dialog, box_y, box_x + input_x); - - wrefresh(dialog); - - while (key != KEY_ESC) { - key = wgetch(dialog); - - if (button == -1) { /* Input box selected */ - switch (key) { - case TAB: - case KEY_UP: - case KEY_DOWN: - break; - case KEY_LEFT: - continue; - case KEY_RIGHT: - continue; - case KEY_BACKSPACE: - case 127: - if (input_x || scroll) { - wattrset(dialog, dlg.inputbox.atr); - if (!input_x) { - scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1); - wmove(dialog, box_y, box_x); - for (i = 0; i < box_width; i++) - waddch(dialog, - instr[scroll + input_x + i] ? - instr[scroll + input_x + i] : ' '); - input_x = strlen(instr) - scroll; - } else - input_x--; - instr[scroll + input_x] = '\0'; - mvwaddch(dialog, box_y, input_x + box_x, ' '); - wmove(dialog, box_y, input_x + box_x); - wrefresh(dialog); - } - continue; - default: - if (key < 0x100 && isprint(key)) { - if (scroll + input_x < MAX_LEN) { - wattrset(dialog, dlg.inputbox.atr); - instr[scroll + input_x] = key; - instr[scroll + input_x + 1] = '\0'; - if (input_x == box_width - 1) { - scroll++; - wmove(dialog, box_y, box_x); - for (i = 0; i < box_width - 1; i++) - waddch(dialog, instr [scroll + i]); - } else { - wmove(dialog, box_y, input_x++ + box_x); - waddch(dialog, key); - } - wrefresh(dialog); - } else - flash(); /* Alarm user about overflow */ - continue; - } - } - } - switch (key) { - case 'O': - case 'o': - delwin(dialog); - return 0; - case 'H': - case 'h': - delwin(dialog); - return 1; - case KEY_UP: - case KEY_LEFT: - switch (button) { - case -1: - button = 1; /* Indicates "Cancel" button is selected */ - print_buttons(dialog, height, width, 1); - break; - case 0: - button = -1; /* Indicates input box is selected */ - print_buttons(dialog, height, width, 0); - wmove(dialog, box_y, box_x + input_x); - wrefresh(dialog); - break; - case 1: - button = 0; /* Indicates "OK" button is selected */ - print_buttons(dialog, height, width, 0); - break; - } - break; - case TAB: - case KEY_DOWN: - case KEY_RIGHT: - switch (button) { - case -1: - button = 0; /* Indicates "OK" button is selected */ - print_buttons(dialog, height, width, 0); - break; - case 0: - button = 1; /* Indicates "Cancel" button is selected */ - print_buttons(dialog, height, width, 1); - break; - case 1: - button = -1; /* Indicates input box is selected */ - print_buttons(dialog, height, width, 0); - wmove(dialog, box_y, box_x + input_x); - wrefresh(dialog); - break; - } - break; - case ' ': - case '\n': - delwin(dialog); - return (button == -1 ? 0 : button); - case 'X': - case 'x': - key = KEY_ESC; - break; - case KEY_ESC: - key = on_key_esc(dialog); - break; - case KEY_RESIZE: - delwin(dialog); - on_key_resize(); - goto do_resize; - } - } - - delwin(dialog); - return KEY_ESC; /* ESC pressed */ -} diff --git a/config/lxdialog/menubox.c b/config/lxdialog/menubox.c deleted file mode 100644 index fa9d633f2..000000000 --- a/config/lxdialog/menubox.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * menubox.c -- implements the menu box - * - * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) - * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * Changes by Clifford Wolf (god@clifford.at) - * - * [ 1998-06-13 ] - * - * *) A bugfix for the Page-Down problem - * - * *) Formerly when I used Page Down and Page Up, the cursor would be set - * to the first position in the menu box. Now lxdialog is a bit - * smarter and works more like other menu systems (just have a look at - * it). - * - * *) Formerly if I selected something my scrolling would be broken because - * lxdialog is re-invoked by the Menuconfig shell script, can't - * remember the last scrolling position, and just sets it so that the - * cursor is at the bottom of the box. Now it writes the temporary file - * lxdialog.scrltmp which contains this information. The file is - * deleted by lxdialog if the user leaves a submenu or enters a new - * one, but it would be nice if Menuconfig could make another "rm -f" - * just to be sure. Just try it out - you will recognise a difference! - * - * [ 1998-06-14 ] - * - * *) Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files - * and menus change their size on the fly. - * - * *) If for some reason the last scrolling position is not saved by - * lxdialog, it sets the scrolling so that the selected item is in the - * middle of the menu box, not at the bottom. - * - * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net) - * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus. - * This fixes a bug in Menuconfig where using ' ' to descend into menus - * would leave mis-synchronized lxdialog.scrltmp files lying around, - * fscanf would read in 'scroll', and eventually that value would get used. - */ - -#include "dialog.h" - -static int menu_width, item_x; - -/* - * Print menu item - */ -static void do_print_item(WINDOW * win, const char *item, int line_y, - int selected, int hotkey) -{ - int j; - char *menu_item = malloc(menu_width + 1); - - strncpy(menu_item, item, menu_width - item_x); - menu_item[menu_width - item_x] = '\0'; - j = first_alpha(menu_item, "YyNnMmHh"); - - /* Clear 'residue' of last item */ - wattrset(win, dlg.menubox.atr); - wmove(win, line_y, 0); -#if OLD_NCURSES - { - int i; - for (i = 0; i < menu_width; i++) - waddch(win, ' '); - } -#else - wclrtoeol(win); -#endif - wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); - mvwaddstr(win, line_y, item_x, menu_item); - if (hotkey) { - wattrset(win, selected ? dlg.tag_key_selected.atr - : dlg.tag_key.atr); - mvwaddch(win, line_y, item_x + j, menu_item[j]); - } - if (selected) { - wmove(win, line_y, item_x + 1); - } - free(menu_item); - wrefresh(win); -} - -#define print_item(index, choice, selected) \ -do { \ - item_set(index); \ - do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \ -} while (0) - -/* - * Print the scroll indicators. - */ -static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x, - int height) -{ - int cur_y, cur_x; - - getyx(win, cur_y, cur_x); - - wmove(win, y, x); - - if (scroll > 0) { - wattrset(win, dlg.uarrow.atr); - waddch(win, ACS_UARROW); - waddstr(win, "(-)"); - } else { - wattrset(win, dlg.menubox.atr); - waddch(win, ACS_HLINE); - waddch(win, ACS_HLINE); - waddch(win, ACS_HLINE); - waddch(win, ACS_HLINE); - } - - y = y + height + 1; - wmove(win, y, x); - wrefresh(win); - - if ((height < item_no) && (scroll + height < item_no)) { - wattrset(win, dlg.darrow.atr); - waddch(win, ACS_DARROW); - waddstr(win, "(+)"); - } else { - wattrset(win, dlg.menubox_border.atr); - waddch(win, ACS_HLINE); - waddch(win, ACS_HLINE); - waddch(win, ACS_HLINE); - waddch(win, ACS_HLINE); - } - - wmove(win, cur_y, cur_x); - wrefresh(win); -} - -/* - * Display the termination buttons. - */ -static void print_buttons(WINDOW * win, int height, int width, int selected) -{ - int x = width / 2 - 16; - int y = height - 2; - - print_button(win, gettext("Select"), y, x, selected == 0); - print_button(win, gettext(" Exit "), y, x + 12, selected == 1); - print_button(win, gettext(" Help "), y, x + 24, selected == 2); - - wmove(win, y, x + 1 + 12 * selected); - wrefresh(win); -} - -/* scroll up n lines (n may be negative) */ -static void do_scroll(WINDOW *win, int *scroll, int n) -{ - /* Scroll menu up */ - scrollok(win, TRUE); - wscrl(win, n); - scrollok(win, FALSE); - *scroll = *scroll + n; - wrefresh(win); -} - -/* - * Display a menu for choosing among a number of options - */ -int dialog_menu(const char *title, const char *prompt, - const void *selected, int *s_scroll) -{ - int i, j, x, y, box_x, box_y; - int height, width, menu_height; - int key = 0, button = 0, scroll = 0, choice = 0; - int first_item = 0, max_choice; - WINDOW *dialog, *menu; - -do_resize: - height = getmaxy(stdscr); - width = getmaxx(stdscr); - if (height < 15 || width < 65) - return -ERRDISPLAYTOOSMALL; - - height -= 4; - width -= 5; - menu_height = height - 10; - - max_choice = MIN(menu_height, item_count()); - - /* center dialog box on screen */ - x = (COLS - width) / 2; - y = (LINES - height) / 2; - - draw_shadow(stdscr, y, x, height, width); - - dialog = newwin(height, width, y, x); - keypad(dialog, TRUE); - - draw_box(dialog, 0, 0, height, width, - dlg.dialog.atr, dlg.border.atr); - wattrset(dialog, dlg.border.atr); - mvwaddch(dialog, height - 3, 0, ACS_LTEE); - for (i = 0; i < width - 2; i++) - waddch(dialog, ACS_HLINE); - wattrset(dialog, dlg.dialog.atr); - wbkgdset(dialog, dlg.dialog.atr & A_COLOR); - waddch(dialog, ACS_RTEE); - - print_title(dialog, title, width); - - wattrset(dialog, dlg.dialog.atr); - print_autowrap(dialog, prompt, width - 2, 1, 3); - - menu_width = width - 6; - box_y = height - menu_height - 5; - box_x = (width - menu_width) / 2 - 1; - - /* create new window for the menu */ - menu = subwin(dialog, menu_height, menu_width, - y + box_y + 1, x + box_x + 1); - keypad(menu, TRUE); - - /* draw a box around the menu items */ - draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2, - dlg.menubox_border.atr, dlg.menubox.atr); - - if (menu_width >= 80) - item_x = (menu_width - 70) / 2; - else - item_x = 4; - - /* Set choice to default item */ - item_foreach() - if (selected && (selected == item_data())) - choice = item_n(); - /* get the saved scroll info */ - scroll = *s_scroll; - if ((scroll <= choice) && (scroll + max_choice > choice) && - (scroll >= 0) && (scroll + max_choice <= item_count())) { - first_item = scroll; - choice = choice - scroll; - } else { - scroll = 0; - } - if ((choice >= max_choice)) { - if (choice >= item_count() - max_choice / 2) - scroll = first_item = item_count() - max_choice; - else - scroll = first_item = choice - max_choice / 2; - choice = choice - scroll; - } - - /* Print the menu */ - for (i = 0; i < max_choice; i++) { - print_item(first_item + i, i, i == choice); - } - - wnoutrefresh(menu); - - print_arrows(dialog, item_count(), scroll, - box_y, box_x + item_x + 1, menu_height); - - print_buttons(dialog, height, width, 0); - wmove(menu, choice, item_x + 1); - wrefresh(menu); - - while (key != KEY_ESC) { - key = wgetch(menu); - - if (key < 256 && isalpha(key)) - key = tolower(key); - - if (strchr("ynmh", key)) - i = max_choice; - else { - for (i = choice + 1; i < max_choice; i++) { - item_set(scroll + i); - j = first_alpha(item_str(), "YyNnMmHh"); - if (key == tolower(item_str()[j])) - break; - } - if (i == max_choice) - for (i = 0; i < max_choice; i++) { - item_set(scroll + i); - j = first_alpha(item_str(), "YyNnMmHh"); - if (key == tolower(item_str()[j])) - break; - } - } - - if (i < max_choice || - key == KEY_UP || key == KEY_DOWN || - key == '-' || key == '+' || - key == KEY_PPAGE || key == KEY_NPAGE) { - /* Remove highligt of current item */ - print_item(scroll + choice, choice, FALSE); - - if (key == KEY_UP || key == '-') { - if (choice < 2 && scroll) { - /* Scroll menu down */ - do_scroll(menu, &scroll, -1); - - print_item(scroll, 0, FALSE); - } else - choice = MAX(choice - 1, 0); - - } else if (key == KEY_DOWN || key == '+') { - print_item(scroll+choice, choice, FALSE); - - if ((choice > max_choice - 3) && - (scroll + max_choice < item_count())) { - /* Scroll menu up */ - do_scroll(menu, &scroll, 1); - - print_item(scroll+max_choice - 1, - max_choice - 1, FALSE); - } else - choice = MIN(choice + 1, max_choice - 1); - - } else if (key == KEY_PPAGE) { - scrollok(menu, TRUE); - for (i = 0; (i < max_choice); i++) { - if (scroll > 0) { - do_scroll(menu, &scroll, -1); - print_item(scroll, 0, FALSE); - } else { - if (choice > 0) - choice--; - } - } - - } else if (key == KEY_NPAGE) { - for (i = 0; (i < max_choice); i++) { - if (scroll + max_choice < item_count()) { - do_scroll(menu, &scroll, 1); - print_item(scroll+max_choice-1, - max_choice - 1, FALSE); - } else { - if (choice + 1 < max_choice) - choice++; - } - } - } else - choice = i; - - print_item(scroll + choice, choice, TRUE); - - print_arrows(dialog, item_count(), scroll, - box_y, box_x + item_x + 1, menu_height); - - wnoutrefresh(dialog); - wrefresh(menu); - - continue; /* wait for another key press */ - } - - switch (key) { - case KEY_LEFT: - case TAB: - case KEY_RIGHT: - button = ((key == KEY_LEFT ? --button : ++button) < 0) - ? 2 : (button > 2 ? 0 : button); - - print_buttons(dialog, height, width, button); - wrefresh(menu); - break; - case ' ': - case 's': - case 'y': - case 'n': - case 'm': - case '/': - /* save scroll info */ - *s_scroll = scroll; - delwin(menu); - delwin(dialog); - item_set(scroll + choice); - item_set_selected(1); - switch (key) { - case 's': - return 3; - case 'y': - return 3; - case 'n': - return 4; - case 'm': - return 5; - case ' ': - return 6; - case '/': - return 7; - } - return 0; - case 'h': - case '?': - button = 2; - case '\n': - *s_scroll = scroll; - delwin(menu); - delwin(dialog); - item_set(scroll + choice); - item_set_selected(1); - return button; - case 'e': - case 'x': - key = KEY_ESC; - break; - case KEY_ESC: - key = on_key_esc(menu); - break; - case KEY_RESIZE: - on_key_resize(); - delwin(menu); - delwin(dialog); - goto do_resize; - } - } - delwin(menu); - delwin(dialog); - return key; /* ESC pressed */ -} diff --git a/config/lxdialog/textbox.c b/config/lxdialog/textbox.c deleted file mode 100644 index c704712d0..000000000 --- a/config/lxdialog/textbox.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * textbox.c -- implements the text box - * - * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) - * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "dialog.h" - -static void back_lines(int n); -static void print_page(WINDOW * win, int height, int width); -static void print_line(WINDOW * win, int row, int width); -static char *get_line(void); -static void print_position(WINDOW * win); - -static int hscroll; -static int begin_reached, end_reached, page_length; -static const char *buf; -static const char *page; - -/* - * refresh window content - */ -static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, - int cur_y, int cur_x) -{ - print_page(box, boxh, boxw); - print_position(dialog); - wmove(dialog, cur_y, cur_x); /* Restore cursor position */ - wrefresh(dialog); -} - - -/* - * Display text from a file in a dialog box. - */ -int dialog_textbox(const char *title, const char *tbuf, - int initial_height, int initial_width) -{ - int i, x, y, cur_x, cur_y, key = 0; - int height, width, boxh, boxw; - int passed_end; - WINDOW *dialog, *box; - - begin_reached = 1; - end_reached = 0; - page_length = 0; - hscroll = 0; - buf = tbuf; - page = buf; /* page is pointer to start of page to be displayed */ - -do_resize: - getmaxyx(stdscr, height, width); - if (height < 8 || width < 8) - return -ERRDISPLAYTOOSMALL; - if (initial_height != 0) - height = initial_height; - else - if (height > 4) - height -= 4; - else - height = 0; - if (initial_width != 0) - width = initial_width; - else - if (width > 5) - width -= 5; - else - width = 0; - - /* center dialog box on screen */ - x = (COLS - width) / 2; - y = (LINES - height) / 2; - - draw_shadow(stdscr, y, x, height, width); - - dialog = newwin(height, width, y, x); - keypad(dialog, TRUE); - - /* Create window for box region, used for scrolling text */ - boxh = height - 4; - boxw = width - 2; - box = subwin(dialog, boxh, boxw, y + 1, x + 1); - wattrset(box, dlg.dialog.atr); - wbkgdset(box, dlg.dialog.atr & A_COLOR); - - keypad(box, TRUE); - - /* register the new window, along with its borders */ - draw_box(dialog, 0, 0, height, width, - dlg.dialog.atr, dlg.border.atr); - - wattrset(dialog, dlg.border.atr); - mvwaddch(dialog, height - 3, 0, ACS_LTEE); - for (i = 0; i < width - 2; i++) - waddch(dialog, ACS_HLINE); - wattrset(dialog, dlg.dialog.atr); - wbkgdset(dialog, dlg.dialog.atr & A_COLOR); - waddch(dialog, ACS_RTEE); - - print_title(dialog, title, width); - - print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE); - wnoutrefresh(dialog); - getyx(dialog, cur_y, cur_x); /* Save cursor position */ - - /* Print first page of text */ - attr_clear(box, boxh, boxw, dlg.dialog.atr); - refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); - - while ((key != KEY_ESC) && (key != '\n')) { - key = wgetch(dialog); - switch (key) { - case 'E': /* Exit */ - case 'e': - case 'X': - case 'x': - delwin(box); - delwin(dialog); - return 0; - case 'g': /* First page */ - case KEY_HOME: - if (!begin_reached) { - begin_reached = 1; - page = buf; - refresh_text_box(dialog, box, boxh, boxw, - cur_y, cur_x); - } - break; - case 'G': /* Last page */ - case KEY_END: - - end_reached = 1; - /* point to last char in buf */ - page = buf + strlen(buf); - back_lines(boxh); - refresh_text_box(dialog, box, boxh, boxw, - cur_y, cur_x); - break; - case 'K': /* Previous line */ - case 'k': - case KEY_UP: - if (!begin_reached) { - back_lines(page_length + 1); - - /* We don't call print_page() here but use - * scrolling to ensure faster screen update. - * However, 'end_reached' and 'page_length' - * should still be updated, and 'page' should - * point to start of next page. This is done - * by calling get_line() in the following - * 'for' loop. */ - scrollok(box, TRUE); - wscrl(box, -1); /* Scroll box region down one line */ - scrollok(box, FALSE); - page_length = 0; - passed_end = 0; - for (i = 0; i < boxh; i++) { - if (!i) { - /* print first line of page */ - print_line(box, 0, boxw); - wnoutrefresh(box); - } else - /* Called to update 'end_reached' and 'page' */ - get_line(); - if (!passed_end) - page_length++; - if (end_reached && !passed_end) - passed_end = 1; - } - - print_position(dialog); - wmove(dialog, cur_y, cur_x); /* Restore cursor position */ - wrefresh(dialog); - } - break; - case 'B': /* Previous page */ - case 'b': - case KEY_PPAGE: - if (begin_reached) - break; - back_lines(page_length + boxh); - refresh_text_box(dialog, box, boxh, boxw, - cur_y, cur_x); - break; - case 'J': /* Next line */ - case 'j': - case KEY_DOWN: - if (!end_reached) { - begin_reached = 0; - scrollok(box, TRUE); - scroll(box); /* Scroll box region up one line */ - scrollok(box, FALSE); - print_line(box, boxh - 1, boxw); - wnoutrefresh(box); - print_position(dialog); - wmove(dialog, cur_y, cur_x); /* Restore cursor position */ - wrefresh(dialog); - } - break; - case KEY_NPAGE: /* Next page */ - case ' ': - if (end_reached) - break; - - begin_reached = 0; - refresh_text_box(dialog, box, boxh, boxw, - cur_y, cur_x); - break; - case '0': /* Beginning of line */ - case 'H': /* Scroll left */ - case 'h': - case KEY_LEFT: - if (hscroll <= 0) - break; - - if (key == '0') - hscroll = 0; - else - hscroll--; - /* Reprint current page to scroll horizontally */ - back_lines(page_length); - refresh_text_box(dialog, box, boxh, boxw, - cur_y, cur_x); - break; - case 'L': /* Scroll right */ - case 'l': - case KEY_RIGHT: - if (hscroll >= MAX_LEN) - break; - hscroll++; - /* Reprint current page to scroll horizontally */ - back_lines(page_length); - refresh_text_box(dialog, box, boxh, boxw, - cur_y, cur_x); - break; - case KEY_ESC: - key = on_key_esc(dialog); - break; - case KEY_RESIZE: - back_lines(height); - delwin(box); - delwin(dialog); - on_key_resize(); - goto do_resize; - } - } - delwin(box); - delwin(dialog); - return key; /* ESC pressed */ -} - -/* - * Go back 'n' lines in text. Called by dialog_textbox(). - * 'page' will be updated to point to the desired line in 'buf'. - */ -static void back_lines(int n) -{ - int i; - - begin_reached = 0; - /* Go back 'n' lines */ - for (i = 0; i < n; i++) { - if (*page == '\0') { - if (end_reached) { - end_reached = 0; - continue; - } - } - if (page == buf) { - begin_reached = 1; - return; - } - page--; - do { - if (page == buf) { - begin_reached = 1; - return; - } - page--; - } while (*page != '\n'); - page++; - } -} - -/* - * Print a new page of text. Called by dialog_textbox(). - */ -static void print_page(WINDOW * win, int height, int width) -{ - int i, passed_end = 0; - - page_length = 0; - for (i = 0; i < height; i++) { - print_line(win, i, width); - if (!passed_end) - page_length++; - if (end_reached && !passed_end) - passed_end = 1; - } - wnoutrefresh(win); -} - -/* - * Print a new line of text. Called by dialog_textbox() and print_page(). - */ -static void print_line(WINDOW * win, int row, int width) -{ - int y, x; - char *line; - - line = get_line(); - line += MIN(strlen(line), hscroll); /* Scroll horizontally */ - wmove(win, row, 0); /* move cursor to correct line */ - waddch(win, ' '); - waddnstr(win, line, MIN(strlen(line), width - 2)); - - getyx(win, y, x); - /* Clear 'residue' of previous line */ -#if OLD_NCURSES - { - int i; - for (i = 0; i < width - x; i++) - waddch(win, ' '); - } -#else - wclrtoeol(win); -#endif -} - -/* - * Return current line of text. Called by dialog_textbox() and print_line(). - * 'page' should point to start of current line before calling, and will be - * updated to point to start of next line. - */ -static char *get_line(void) -{ - int i = 0; - static char line[MAX_LEN + 1]; - - end_reached = 0; - while (*page != '\n') { - if (*page == '\0') { - if (!end_reached) { - end_reached = 1; - break; - } - } else if (i < MAX_LEN) - line[i++] = *(page++); - else { - /* Truncate lines longer than MAX_LEN characters */ - if (i == MAX_LEN) - line[i++] = '\0'; - page++; - } - } - if (i <= MAX_LEN) - line[i] = '\0'; - if (!end_reached) - page++; /* move pass '\n' */ - - return line; -} - -/* - * Print current position - */ -static void print_position(WINDOW * win) -{ - int percent; - - wattrset(win, dlg.position_indicator.atr); - wbkgdset(win, dlg.position_indicator.atr & A_COLOR); - percent = (page - buf) * 100 / strlen(buf); - wmove(win, getmaxy(win) - 3, getmaxx(win) - 9); - wprintw(win, "(%3d%%)", percent); -} diff --git a/config/lxdialog/util.c b/config/lxdialog/util.c deleted file mode 100644 index f2375ad7e..000000000 --- a/config/lxdialog/util.c +++ /dev/null @@ -1,657 +0,0 @@ -/* - * util.c - * - * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) - * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include "dialog.h" - -struct dialog_info dlg; - -static void set_mono_theme(void) -{ - dlg.screen.atr = A_NORMAL; - dlg.shadow.atr = A_NORMAL; - dlg.dialog.atr = A_NORMAL; - dlg.title.atr = A_BOLD; - dlg.border.atr = A_NORMAL; - dlg.button_active.atr = A_REVERSE; - dlg.button_inactive.atr = A_DIM; - dlg.button_key_active.atr = A_REVERSE; - dlg.button_key_inactive.atr = A_BOLD; - dlg.button_label_active.atr = A_REVERSE; - dlg.button_label_inactive.atr = A_NORMAL; - dlg.inputbox.atr = A_NORMAL; - dlg.inputbox_border.atr = A_NORMAL; - dlg.searchbox.atr = A_NORMAL; - dlg.searchbox_title.atr = A_BOLD; - dlg.searchbox_border.atr = A_NORMAL; - dlg.position_indicator.atr = A_BOLD; - dlg.menubox.atr = A_NORMAL; - dlg.menubox_border.atr = A_NORMAL; - dlg.item.atr = A_NORMAL; - dlg.item_selected.atr = A_REVERSE; - dlg.tag.atr = A_BOLD; - dlg.tag_selected.atr = A_REVERSE; - dlg.tag_key.atr = A_BOLD; - dlg.tag_key_selected.atr = A_REVERSE; - dlg.check.atr = A_BOLD; - dlg.check_selected.atr = A_REVERSE; - dlg.uarrow.atr = A_BOLD; - dlg.darrow.atr = A_BOLD; -} - -#define DLG_COLOR(dialog, f, b, h) \ -do { \ - dlg.dialog.fg = (f); \ - dlg.dialog.bg = (b); \ - dlg.dialog.hl = (h); \ -} while (0) - -static void set_classic_theme(void) -{ - DLG_COLOR(screen, COLOR_CYAN, COLOR_BLUE, true); - DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, true); - DLG_COLOR(dialog, COLOR_BLACK, COLOR_WHITE, false); - DLG_COLOR(title, COLOR_YELLOW, COLOR_WHITE, true); - DLG_COLOR(border, COLOR_WHITE, COLOR_WHITE, true); - DLG_COLOR(button_active, COLOR_WHITE, COLOR_BLUE, true); - DLG_COLOR(button_inactive, COLOR_BLACK, COLOR_WHITE, false); - DLG_COLOR(button_key_active, COLOR_WHITE, COLOR_BLUE, true); - DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_WHITE, false); - DLG_COLOR(button_label_active, COLOR_YELLOW, COLOR_BLUE, true); - DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_WHITE, true); - DLG_COLOR(inputbox, COLOR_BLACK, COLOR_WHITE, false); - DLG_COLOR(inputbox_border, COLOR_BLACK, COLOR_WHITE, false); - DLG_COLOR(searchbox, COLOR_BLACK, COLOR_WHITE, false); - DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_WHITE, true); - DLG_COLOR(searchbox_border, COLOR_WHITE, COLOR_WHITE, true); - DLG_COLOR(position_indicator, COLOR_YELLOW, COLOR_WHITE, true); - DLG_COLOR(menubox, COLOR_BLACK, COLOR_WHITE, false); - DLG_COLOR(menubox_border, COLOR_WHITE, COLOR_WHITE, true); - DLG_COLOR(item, COLOR_BLACK, COLOR_WHITE, false); - DLG_COLOR(item_selected, COLOR_WHITE, COLOR_BLUE, true); - DLG_COLOR(tag, COLOR_YELLOW, COLOR_WHITE, true); - DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_BLUE, true); - DLG_COLOR(tag_key, COLOR_YELLOW, COLOR_WHITE, true); - DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_BLUE, true); - DLG_COLOR(check, COLOR_BLACK, COLOR_WHITE, false); - DLG_COLOR(check_selected, COLOR_WHITE, COLOR_BLUE, true); - DLG_COLOR(uarrow, COLOR_GREEN, COLOR_WHITE, true); - DLG_COLOR(darrow, COLOR_GREEN, COLOR_WHITE, true); -} - -static void set_blackbg_theme(void) -{ - DLG_COLOR(screen, COLOR_RED, COLOR_BLACK, true); - DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false); - DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false); - DLG_COLOR(title, COLOR_RED, COLOR_BLACK, false); - DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true); - - DLG_COLOR(button_active, COLOR_YELLOW, COLOR_RED, false); - DLG_COLOR(button_inactive, COLOR_YELLOW, COLOR_BLACK, false); - DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_RED, true); - DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_BLACK, false); - DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_RED, false); - DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_BLACK, true); - - DLG_COLOR(inputbox, COLOR_YELLOW, COLOR_BLACK, false); - DLG_COLOR(inputbox_border, COLOR_YELLOW, COLOR_BLACK, false); - - DLG_COLOR(searchbox, COLOR_YELLOW, COLOR_BLACK, false); - DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_BLACK, true); - DLG_COLOR(searchbox_border, COLOR_BLACK, COLOR_BLACK, true); - - DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK, false); - - DLG_COLOR(menubox, COLOR_YELLOW, COLOR_BLACK, false); - DLG_COLOR(menubox_border, COLOR_BLACK, COLOR_BLACK, true); - - DLG_COLOR(item, COLOR_WHITE, COLOR_BLACK, false); - DLG_COLOR(item_selected, COLOR_WHITE, COLOR_RED, false); - - DLG_COLOR(tag, COLOR_RED, COLOR_BLACK, false); - DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_RED, true); - DLG_COLOR(tag_key, COLOR_RED, COLOR_BLACK, false); - DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED, true); - - DLG_COLOR(check, COLOR_YELLOW, COLOR_BLACK, false); - DLG_COLOR(check_selected, COLOR_YELLOW, COLOR_RED, true); - - DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false); - DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false); -} - -static void set_bluetitle_theme(void) -{ - set_classic_theme(); - DLG_COLOR(title, COLOR_BLUE, COLOR_WHITE, true); - DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_BLUE, true); - DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_BLUE, true); - DLG_COLOR(searchbox_title, COLOR_BLUE, COLOR_WHITE, true); - DLG_COLOR(position_indicator, COLOR_BLUE, COLOR_WHITE, true); - DLG_COLOR(tag, COLOR_BLUE, COLOR_WHITE, true); - DLG_COLOR(tag_key, COLOR_BLUE, COLOR_WHITE, true); - -} - -/* - * Select color theme - */ -static int set_theme(const char *theme) -{ - int use_color = 1; - if (!theme) - set_bluetitle_theme(); - else if (strcmp(theme, "classic") == 0) - set_classic_theme(); - else if (strcmp(theme, "bluetitle") == 0) - set_bluetitle_theme(); - else if (strcmp(theme, "blackbg") == 0) - set_blackbg_theme(); - else if (strcmp(theme, "mono") == 0) - use_color = 0; - - return use_color; -} - -static void init_one_color(struct dialog_color *color) -{ - static int pair = 0; - - pair++; - init_pair(pair, color->fg, color->bg); - if (color->hl) - color->atr = A_BOLD | COLOR_PAIR(pair); - else - color->atr = COLOR_PAIR(pair); -} - -static void init_dialog_colors(void) -{ - init_one_color(&dlg.screen); - init_one_color(&dlg.shadow); - init_one_color(&dlg.dialog); - init_one_color(&dlg.title); - init_one_color(&dlg.border); - init_one_color(&dlg.button_active); - init_one_color(&dlg.button_inactive); - init_one_color(&dlg.button_key_active); - init_one_color(&dlg.button_key_inactive); - init_one_color(&dlg.button_label_active); - init_one_color(&dlg.button_label_inactive); - init_one_color(&dlg.inputbox); - init_one_color(&dlg.inputbox_border); - init_one_color(&dlg.searchbox); - init_one_color(&dlg.searchbox_title); - init_one_color(&dlg.searchbox_border); - init_one_color(&dlg.position_indicator); - init_one_color(&dlg.menubox); - init_one_color(&dlg.menubox_border); - init_one_color(&dlg.item); - init_one_color(&dlg.item_selected); - init_one_color(&dlg.tag); - init_one_color(&dlg.tag_selected); - init_one_color(&dlg.tag_key); - init_one_color(&dlg.tag_key_selected); - init_one_color(&dlg.check); - init_one_color(&dlg.check_selected); - init_one_color(&dlg.uarrow); - init_one_color(&dlg.darrow); -} - -/* - * Setup for color display - */ -static void color_setup(const char *theme) -{ - int use_color; - - use_color = set_theme(theme); - if (use_color && has_colors()) { - start_color(); - init_dialog_colors(); - } else - set_mono_theme(); -} - -/* - * Set window to attribute 'attr' - */ -void attr_clear(WINDOW * win, int height, int width, chtype attr) -{ - int i, j; - - wattrset(win, attr); - for (i = 0; i < height; i++) { - wmove(win, i, 0); - for (j = 0; j < width; j++) - waddch(win, ' '); - } - touchwin(win); -} - -void dialog_clear(void) -{ - attr_clear(stdscr, LINES, COLS, dlg.screen.atr); - /* Display background title if it exists ... - SLH */ - if (dlg.backtitle != NULL) { - int i; - - wattrset(stdscr, dlg.screen.atr); - mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle); - wmove(stdscr, 1, 1); - for (i = 1; i < COLS - 1; i++) - waddch(stdscr, ACS_HLINE); - } - wnoutrefresh(stdscr); -} - -/* - * Do some initialization for dialog - */ -int init_dialog(const char *backtitle) -{ - int height, width; - - initscr(); /* Init curses */ - getmaxyx(stdscr, height, width); - if (height < 19 || width < 80) { - endwin(); - return -ERRDISPLAYTOOSMALL; - } - - dlg.backtitle = backtitle; - color_setup(getenv("MENUCONFIG_COLOR")); - - keypad(stdscr, TRUE); - cbreak(); - noecho(); - dialog_clear(); - - return 0; -} - -void set_dialog_backtitle(const char *backtitle) -{ - dlg.backtitle = backtitle; -} - -/* - * End using dialog functions. - */ -void end_dialog(int x, int y) -{ - /* move cursor back to original position */ - move(y, x); - refresh(); - endwin(); -} - -/* Print the title of the dialog. Center the title and truncate - * tile if wider than dialog (- 2 chars). - **/ -void print_title(WINDOW *dialog, const char *title, int width) -{ - if (title) { - int tlen = MIN(width - 2, strlen(title)); - wattrset(dialog, dlg.title.atr); - mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' '); - mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen); - waddch(dialog, ' '); - } -} - -/* - * Print a string of text in a window, automatically wrap around to the - * next line if the string is too long to fit on one line. Newline - * characters '\n' are replaced by spaces. We start on a new line - * if there is no room for at least 4 nonblanks following a double-space. - */ -void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) -{ - int newl, cur_x, cur_y; - int i, prompt_len, room, wlen; - char tempstr[MAX_LEN + 1], *word, *sp, *sp2; - - strcpy(tempstr, prompt); - - prompt_len = strlen(tempstr); - - /* - * Remove newlines - */ - for (i = 0; i < prompt_len; i++) { - if (tempstr[i] == '\n') - tempstr[i] = ' '; - } - - if (prompt_len <= width - x * 2) { /* If prompt is short */ - wmove(win, y, (width - prompt_len) / 2); - waddstr(win, tempstr); - } else { - cur_x = x; - cur_y = y; - newl = 1; - word = tempstr; - while (word && *word) { - sp = strchr(word, ' '); - if (sp) - *sp++ = 0; - - /* Wrap to next line if either the word does not fit, - or it is the first word of a new sentence, and it is - short, and the next word does not fit. */ - room = width - cur_x; - wlen = strlen(word); - if (wlen > room || - (newl && wlen < 4 && sp - && wlen + 1 + strlen(sp) > room - && (!(sp2 = strchr(sp, ' ')) - || wlen + 1 + (sp2 - sp) > room))) { - cur_y++; - cur_x = x; - } - wmove(win, cur_y, cur_x); - waddstr(win, word); - getyx(win, cur_y, cur_x); - cur_x++; - if (sp && *sp == ' ') { - cur_x++; /* double space */ - while (*++sp == ' ') ; - newl = 1; - } else - newl = 0; - word = sp; - } - } -} - -/* - * Print a button - */ -void print_button(WINDOW * win, const char *label, int y, int x, int selected) -{ - int i, temp; - - wmove(win, y, x); - wattrset(win, selected ? dlg.button_active.atr - : dlg.button_inactive.atr); - waddstr(win, "<"); - temp = strspn(label, " "); - label += temp; - wattrset(win, selected ? dlg.button_label_active.atr - : dlg.button_label_inactive.atr); - for (i = 0; i < temp; i++) - waddch(win, ' '); - wattrset(win, selected ? dlg.button_key_active.atr - : dlg.button_key_inactive.atr); - waddch(win, label[0]); - wattrset(win, selected ? dlg.button_label_active.atr - : dlg.button_label_inactive.atr); - waddstr(win, (char *)label + 1); - wattrset(win, selected ? dlg.button_active.atr - : dlg.button_inactive.atr); - waddstr(win, ">"); - wmove(win, y, x + temp + 1); -} - -/* - * Draw a rectangular box with line drawing characters - */ -void -draw_box(WINDOW * win, int y, int x, int height, int width, - chtype box, chtype border) -{ - int i, j; - - wattrset(win, 0); - for (i = 0; i < height; i++) { - wmove(win, y + i, x); - for (j = 0; j < width; j++) - if (!i && !j) - waddch(win, border | ACS_ULCORNER); - else if (i == height - 1 && !j) - waddch(win, border | ACS_LLCORNER); - else if (!i && j == width - 1) - waddch(win, box | ACS_URCORNER); - else if (i == height - 1 && j == width - 1) - waddch(win, box | ACS_LRCORNER); - else if (!i) - waddch(win, border | ACS_HLINE); - else if (i == height - 1) - waddch(win, box | ACS_HLINE); - else if (!j) - waddch(win, border | ACS_VLINE); - else if (j == width - 1) - waddch(win, box | ACS_VLINE); - else - waddch(win, box | ' '); - } -} - -/* - * Draw shadows along the right and bottom edge to give a more 3D look - * to the boxes - */ -void draw_shadow(WINDOW * win, int y, int x, int height, int width) -{ - int i; - - if (has_colors()) { /* Whether terminal supports color? */ - wattrset(win, dlg.shadow.atr); - wmove(win, y + height, x + 2); - for (i = 0; i < width; i++) - waddch(win, winch(win) & A_CHARTEXT); - for (i = y + 1; i < y + height + 1; i++) { - wmove(win, i, x + width); - waddch(win, winch(win) & A_CHARTEXT); - waddch(win, winch(win) & A_CHARTEXT); - } - wnoutrefresh(win); - } -} - -/* - * Return the position of the first alphabetic character in a string. - */ -int first_alpha(const char *string, const char *exempt) -{ - int i, in_paren = 0, c; - - for (i = 0; i < strlen(string); i++) { - c = tolower(string[i]); - - if (strchr("<[(", c)) - ++in_paren; - if (strchr(">])", c) && in_paren > 0) - --in_paren; - - if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0) - return i; - } - - return 0; -} - -/* - * ncurses uses ESC to detect escaped char sequences. This resutl in - * a small timeout before ESC is actually delivered to the application. - * lxdialog suggest which is correctly translated to two - * times esc. But then we need to ignore the second esc to avoid stepping - * out one menu too much. Filter away all escaped key sequences since - * keypad(FALSE) turn off ncurses support for escape sequences - and thats - * needed to make notimeout() do as expected. - */ -int on_key_esc(WINDOW *win) -{ - int key; - int key2; - int key3; - - nodelay(win, TRUE); - keypad(win, FALSE); - key = wgetch(win); - key2 = wgetch(win); - do { - key3 = wgetch(win); - } while (key3 != ERR); - nodelay(win, FALSE); - keypad(win, TRUE); - if (key == KEY_ESC && key2 == ERR) - return KEY_ESC; - else if (key != ERR && key != KEY_ESC && key2 == ERR) - ungetch(key); - - return -1; -} - -/* redraw screen in new size */ -int on_key_resize(void) -{ - dialog_clear(); - return KEY_RESIZE; -} - -struct dialog_list *item_cur; -struct dialog_list item_nil; -struct dialog_list *item_head; - -void item_reset(void) -{ - struct dialog_list *p, *next; - - for (p = item_head; p; p = next) { - next = p->next; - free(p); - } - item_head = NULL; - item_cur = &item_nil; -} - -void item_make(const char *fmt, ...) -{ - va_list ap; - struct dialog_list *p = malloc(sizeof(*p)); - - if (item_head) - item_cur->next = p; - else - item_head = p; - item_cur = p; - memset(p, 0, sizeof(*p)); - - va_start(ap, fmt); - vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap); - va_end(ap); -} - -void item_add_str(const char *fmt, ...) -{ - va_list ap; - size_t avail; - - avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str); - - va_start(ap, fmt); - vsnprintf(item_cur->node.str + strlen(item_cur->node.str), - avail, fmt, ap); - item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0'; - va_end(ap); -} - -void item_set_tag(char tag) -{ - item_cur->node.tag = tag; -} -void item_set_data(void *ptr) -{ - item_cur->node.data = ptr; -} - -void item_set_selected(int val) -{ - item_cur->node.selected = val; -} - -int item_activate_selected(void) -{ - item_foreach() - if (item_is_selected()) - return 1; - return 0; -} - -void *item_data(void) -{ - return item_cur->node.data; -} - -char item_tag(void) -{ - return item_cur->node.tag; -} - -int item_count(void) -{ - int n = 0; - struct dialog_list *p; - - for (p = item_head; p; p = p->next) - n++; - return n; -} - -void item_set(int n) -{ - int i = 0; - item_foreach() - if (i++ == n) - return; -} - -int item_n(void) -{ - int n = 0; - struct dialog_list *p; - - for (p = item_head; p; p = p->next) { - if (p == item_cur) - return n; - n++; - } - return 0; -} - -const char *item_str(void) -{ - return item_cur->node.str; -} - -int item_is_selected(void) -{ - return (item_cur->node.selected != 0); -} - -int item_is_tag(char tag) -{ - return (item_cur->node.tag == tag); -} diff --git a/config/lxdialog/yesno.c b/config/lxdialog/yesno.c deleted file mode 100644 index 4e6e8090c..000000000 --- a/config/lxdialog/yesno.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * yesno.c -- implements the yes/no box - * - * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) - * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "dialog.h" - -/* - * Display termination buttons - */ -static void print_buttons(WINDOW * dialog, int height, int width, int selected) -{ - int x = width / 2 - 10; - int y = height - 2; - - print_button(dialog, gettext(" Yes "), y, x, selected == 0); - print_button(dialog, gettext(" No "), y, x + 13, selected == 1); - - wmove(dialog, y, x + 1 + 13 * selected); - wrefresh(dialog); -} - -/* - * Display a dialog box with two buttons - Yes and No - */ -int dialog_yesno(const char *title, const char *prompt, int height, int width) -{ - int i, x, y, key = 0, button = 0; - WINDOW *dialog; - -do_resize: - if (getmaxy(stdscr) < (height + 4)) - return -ERRDISPLAYTOOSMALL; - if (getmaxx(stdscr) < (width + 4)) - return -ERRDISPLAYTOOSMALL; - - /* center dialog box on screen */ - x = (COLS - width) / 2; - y = (LINES - height) / 2; - - draw_shadow(stdscr, y, x, height, width); - - dialog = newwin(height, width, y, x); - keypad(dialog, TRUE); - - draw_box(dialog, 0, 0, height, width, - dlg.dialog.atr, dlg.border.atr); - wattrset(dialog, dlg.border.atr); - mvwaddch(dialog, height - 3, 0, ACS_LTEE); - for (i = 0; i < width - 2; i++) - waddch(dialog, ACS_HLINE); - wattrset(dialog, dlg.dialog.atr); - waddch(dialog, ACS_RTEE); - - print_title(dialog, title, width); - - wattrset(dialog, dlg.dialog.atr); - print_autowrap(dialog, prompt, width - 2, 1, 3); - - print_buttons(dialog, height, width, 0); - - while (key != KEY_ESC) { - key = wgetch(dialog); - switch (key) { - case 'Y': - case 'y': - delwin(dialog); - return 0; - case 'N': - case 'n': - delwin(dialog); - return 1; - - case TAB: - case KEY_LEFT: - case KEY_RIGHT: - button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button); - - print_buttons(dialog, height, width, button); - wrefresh(dialog); - break; - case ' ': - case '\n': - delwin(dialog); - return button; - case KEY_ESC: - key = on_key_esc(dialog); - break; - case KEY_RESIZE: - delwin(dialog); - on_key_resize(); - goto do_resize; - } - } - - delwin(dialog); - return key; /* ESC pressed */ -} diff --git a/config/mconf.c b/config/mconf.c deleted file mode 100644 index 6aa2c0d88..000000000 --- a/config/mconf.c +++ /dev/null @@ -1,940 +0,0 @@ -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - * - * Introduced single menu mode (show all sub-menus in one large tree). - * 2002-11-06 Petr Baudis - * - * i18n, 2005, Arnaldo Carvalho de Melo - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LKC_DIRECT_LINK -#include "lkc.h" -#include "lxdialog/dialog.h" - -static const char mconf_readme[] = N_( -"Overview\n" -"--------\n" -"Some kernel features may be built directly into the kernel.\n" -"Some may be made into loadable runtime modules. Some features\n" -"may be completely removed altogether. There are also certain\n" -"kernel parameters which are not really features, but must be\n" -"entered in as decimal or hexadecimal numbers or possibly text.\n" -"\n" -"Menu items beginning with following braces represent features that\n" -" [ ] can be built in or removed\n" -" < > can be built in, modularized or removed\n" -" { } can be built in or modularized (selected by other feature)\n" -" - - are selected by other feature,\n" -"while *, M or whitespace inside braces means to build in, build as\n" -"a module or to exclude the feature respectively.\n" -"\n" -"To change any of these features, highlight it with the cursor\n" -"keys and press to build it in, to make it a module or\n" -" to removed it. You may also press the to cycle\n" -"through the available options (ie. Y->N->M->Y).\n" -"\n" -"Some additional keyboard hints:\n" -"\n" -"Menus\n" -"----------\n" -"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n" -" you wish to change or submenu wish to select and press .\n" -" Submenus are designated by \"--->\".\n" -"\n" -" Shortcut: Press the option's highlighted letter (hotkey).\n" -" Pressing a hotkey more than once will sequence\n" -" through all visible items which use that hotkey.\n" -"\n" -" You may also use the and keys to scroll\n" -" unseen options into view.\n" -"\n" -"o To exit a menu use the cursor keys to highlight the button\n" -" and press .\n" -"\n" -" Shortcut: Press or or if there is no hotkey\n" -" using those letters. You may press a single , but\n" -" there is a delayed response which you may find annoying.\n" -"\n" -" Also, the and cursor keys will cycle between and\n" -" \n" -"\n" -"\n" -"Data Entry\n" -"-----------\n" -"o Enter the requested information and press \n" -" If you are entering hexadecimal values, it is not necessary to\n" -" add the '0x' prefix to the entry.\n" -"\n" -"o For help, use the or cursor keys to highlight the help option\n" -" and press . You can try as well.\n" -"\n" -"\n" -"Text Box (Help Window)\n" -"--------\n" -"o Use the cursor keys to scroll up/down/left/right. The VI editor\n" -" keys h,j,k,l function here as do and for those\n" -" who are familiar with less and lynx.\n" -"\n" -"o Press , , or to exit.\n" -"\n" -"\n" -"Alternate Configuration Files\n" -"-----------------------------\n" -"Menuconfig supports the use of alternate configuration files for\n" -"those who, for various reasons, find it necessary to switch\n" -"between different kernel configurations.\n" -"\n" -"At the end of the main menu you will find two options. One is\n" -"for saving the current configuration to a file of your choosing.\n" -"The other option is for loading a previously saved alternate\n" -"configuration.\n" -"\n" -"Even if you don't use alternate configuration files, but you\n" -"find during a Menuconfig session that you have completely messed\n" -"up your settings, you may use the \"Load Alternate...\" option to\n" -"restore your previously saved settings from \".config\" without\n" -"restarting Menuconfig.\n" -"\n" -"Other information\n" -"-----------------\n" -"If you use Menuconfig in an XTERM window make sure you have your\n" -"$TERM variable set to point to a xterm definition which supports color.\n" -"Otherwise, Menuconfig will look rather bad. Menuconfig will not\n" -"display correctly in a RXVT window because rxvt displays only one\n" -"intensity of color, bright.\n" -"\n" -"Menuconfig will display larger menus on screens or xterms which are\n" -"set to display more than the standard 25 row by 80 column geometry.\n" -"In order for this to work, the \"stty size\" command must be able to\n" -"display the screen's current row and column geometry. I STRONGLY\n" -"RECOMMEND that you make sure you do NOT have the shell variables\n" -"LINES and COLUMNS exported into your environment. Some distributions\n" -"export those variables via /etc/profile. Some ncurses programs can\n" -"become confused when those variables (LINES & COLUMNS) don't reflect\n" -"the true screen size.\n" -"\n" -"Optional personality available\n" -"------------------------------\n" -"If you prefer to have all of the kernel options listed in a single\n" -"menu, rather than the default multimenu hierarchy, run the menuconfig\n" -"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n" -"\n" -"make MENUCONFIG_MODE=single_menu menuconfig\n" -"\n" -" will then unroll the appropriate category, or enfold it if it\n" -"is already unrolled.\n" -"\n" -"Note that this mode can eventually be a little more CPU expensive\n" -"(especially with a larger number of unrolled categories) than the\n" -"default mode.\n" -"\n" -"Different color themes available\n" -"--------------------------------\n" -"It is possible to select different color themes using the variable\n" -"MENUCONFIG_COLOR. To select a theme use:\n" -"\n" -"make MENUCONFIG_COLOR= menuconfig\n" -"\n" -"Available themes are\n" -" mono => selects colors suitable for monochrome displays\n" -" blackbg => selects a color scheme with black background\n" -" classic => theme with blue background. The classic look\n" -" bluetitle => a LCD friendly version of classic. (default)\n" -"\n"), -menu_instructions[] = N_( - "Arrow keys navigate the menu. " - " selects submenus --->. " - "Highlighted letters are hotkeys. " - "Pressing includes, excludes, modularizes features. " - "Press to exit, for Help, for Search. " - "Legend: [*] built-in [ ] excluded module < > module capable"), -radiolist_instructions[] = N_( - "Use the arrow keys to navigate this window or " - "press the hotkey of the item you wish to select " - "followed by the . " - "Press for additional information about this option."), -inputbox_instructions_int[] = N_( - "Please enter a decimal value. " - "Fractions will not be accepted. " - "Use the key to move from the input field to the buttons below it."), -inputbox_instructions_hex[] = N_( - "Please enter a hexadecimal value. " - "Use the key to move from the input field to the buttons below it."), -inputbox_instructions_string[] = N_( - "Please enter a string value. " - "Use the key to move from the input field to the buttons below it."), -setmod_text[] = N_( - "This feature depends on another which has been configured as a module.\n" - "As a result, this feature will be built as a module."), -nohelp_text[] = N_( - "There is no help available for this kernel option.\n"), -load_config_text[] = N_( - "Enter the name of the configuration file you wish to load. " - "Accept the name shown to restore the configuration you " - "last retrieved. Leave blank to abort."), -load_config_help[] = N_( - "\n" - "For various reasons, one may wish to keep several different kernel\n" - "configurations available on a single machine.\n" - "\n" - "If you have saved a previous configuration in a file other than the\n" - "kernel's default, entering the name of the file here will allow you\n" - "to modify that configuration.\n" - "\n" - "If you are uncertain, then you have probably never used alternate\n" - "configuration files. You should therefor leave this blank to abort.\n"), -save_config_text[] = N_( - "Enter a filename to which this configuration should be saved " - "as an alternate. Leave blank to abort."), -save_config_help[] = N_( - "\n" - "For various reasons, one may wish to keep different kernel\n" - "configurations available on a single machine.\n" - "\n" - "Entering a file name here will allow you to later retrieve, modify\n" - "and use the current configuration as an alternate to whatever\n" - "configuration options you have selected at that time.\n" - "\n" - "If you are uncertain what all this means then you should probably\n" - "leave this blank.\n"), -search_help[] = N_( - "\n" - "Search for CONFIG_ symbols and display their relations.\n" - "Regular expressions are allowed.\n" - "Example: search for \"^FOO\"\n" - "Result:\n" - "-----------------------------------------------------------------\n" - "Symbol: FOO [=m]\n" - "Prompt: Foo bus is used to drive the bar HW\n" - "Defined at drivers/pci/Kconfig:47\n" - "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" - "Location:\n" - " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" - " -> PCI support (PCI [=y])\n" - " -> PCI access mode ( [=y])\n" - "Selects: LIBCRC32\n" - "Selected by: BAR\n" - "-----------------------------------------------------------------\n" - "o The line 'Prompt:' shows the text used in the menu structure for\n" - " this CONFIG_ symbol\n" - "o The 'Defined at' line tell at what file / line number the symbol\n" - " is defined\n" - "o The 'Depends on:' line tell what symbols needs to be defined for\n" - " this symbol to be visible in the menu (selectable)\n" - "o The 'Location:' lines tell where in the menu structure this symbol\n" - " is located\n" - " A location followed by a [=y] indicate that this is a selectable\n" - " menu item - and current value is displayed inside brackets.\n" - "o The 'Selects:' line tell what symbol will be automatically\n" - " selected if this symbol is selected (y or m)\n" - "o The 'Selected by' line tell what symbol has selected this symbol\n" - "\n" - "Only relevant lines are shown.\n" - "\n\n" - "Search examples:\n" - "Examples: USB => find all CONFIG_ symbols containing USB\n" - " ^USB => find all CONFIG_ symbols starting with USB\n" - " USB$ => find all CONFIG_ symbols ending with USB\n" - "\n"); - -static int indent; -static struct menu *current_menu; -static int child_count; -static int single_menu_mode; - -static void conf(struct menu *menu); -static void conf_choice(struct menu *menu); -static void conf_string(struct menu *menu); -static void conf_load(void); -static void conf_save(void); -static void show_textbox(const char *title, const char *text, int r, int c); -static void show_helptext(const char *title, const char *text); -static void show_help(struct menu *menu); - -static void get_prompt_str(struct gstr *r, struct property *prop) -{ - int i, j; - struct menu *submenu[8], *menu; - - str_printf(r, _("Prompt: %s\n"), _(prop->text)); - str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, - prop->menu->lineno); - if (!expr_is_yes(prop->visible.expr)) { - str_append(r, _(" Depends on: ")); - expr_gstr_print(prop->visible.expr, r); - str_append(r, "\n"); - } - menu = prop->menu->parent; - for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) - submenu[i++] = menu; - if (i > 0) { - str_printf(r, _(" Location:\n")); - for (j = 4; --i >= 0; j += 2) { - menu = submenu[i]; - str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); - if (menu->sym) { - str_printf(r, " (%s [=%s])", menu->sym->name ? - menu->sym->name : _(""), - sym_get_string_value(menu->sym)); - } - str_append(r, "\n"); - } - } -} - -static void get_symbol_str(struct gstr *r, struct symbol *sym) -{ - bool hit; - struct property *prop; - - if (sym && sym->name) - str_printf(r, "Symbol: %s [=%s]\n", sym->name, - sym_get_string_value(sym)); - for_all_prompts(sym, prop) - get_prompt_str(r, prop); - hit = false; - for_all_properties(sym, prop, P_SELECT) { - if (!hit) { - str_append(r, " Selects: "); - hit = true; - } else - str_printf(r, " && "); - expr_gstr_print(prop->expr, r); - } - if (hit) - str_append(r, "\n"); - if (sym->rev_dep.expr) { - str_append(r, _(" Selected by: ")); - expr_gstr_print(sym->rev_dep.expr, r); - str_append(r, "\n"); - } - str_append(r, "\n\n"); -} - -static struct gstr get_relations_str(struct symbol **sym_arr) -{ - struct symbol *sym; - struct gstr res = str_new(); - int i; - - for (i = 0; sym_arr && (sym = sym_arr[i]); i++) - get_symbol_str(&res, sym); - if (!i) - str_append(&res, _("No matches found.\n")); - return res; -} - -static char filename[PATH_MAX+1]; -static void set_config_filename(const char *config_filename) -{ - static char menu_backtitle[PATH_MAX+128]; - int size; - struct symbol *sym; - - sym = sym_lookup("ADKVERSION", 0); - sym_calc_value(sym); - size = snprintf(menu_backtitle, sizeof(menu_backtitle), - _("%s - OpenADK v%s Configuration"), - config_filename, sym_get_string_value(sym)); - if (size >= sizeof(menu_backtitle)) - menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; - set_dialog_backtitle(menu_backtitle); - - size = snprintf(filename, sizeof(filename), "%s", config_filename); - if (size >= sizeof(filename)) - filename[sizeof(filename)-1] = '\0'; -} - - -static void search_conf(void) -{ - struct symbol **sym_arr; - struct gstr res; - char *dialog_input; - int dres; -again: - dialog_clear(); - dres = dialog_inputbox(_("Search Configuration Parameter"), - _("Enter CONFIG_ (sub)string to search for " - "(with or without \"CONFIG\")"), - 10, 75, ""); - switch (dres) { - case 0: - break; - case 1: - show_helptext(_("Search Configuration"), search_help); - goto again; - default: - return; - } - - /* strip CONFIG_ if necessary */ - dialog_input = dialog_input_result; - if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) - dialog_input += 7; - - sym_arr = sym_re_search(dialog_input); - res = get_relations_str(sym_arr); - free(sym_arr); - show_textbox(_("Search Results"), str_get(&res), 0, 0); - str_free(&res); -} - -static void build_conf(struct menu *menu) -{ - struct symbol *sym; - struct property *prop; - struct menu *child; - int type, tmp, doint = 2; - tristate val; - char ch; - - if (!menu_is_visible(menu)) - return; - - sym = menu->sym; - prop = menu->prompt; - if (!sym) { - if (prop && menu != current_menu) { - const char *prompt = menu_get_prompt(menu); - switch (prop->type) { - case P_MENU: - child_count++; - prompt = _(prompt); - if (single_menu_mode) { - item_make("%s%*c%s", - menu->data ? "-->" : "++>", - indent + 1, ' ', prompt); - } else - item_make(" %*c%s --->", indent + 1, ' ', prompt); - - item_set_tag('m'); - item_set_data(menu); - if (single_menu_mode && menu->data) - goto conf_childs; - return; - case P_COMMENT: - if (prompt) { - child_count++; - item_make(" %*c*** %s ***", indent + 1, ' ', _(prompt)); - item_set_tag(':'); - item_set_data(menu); - } - break; - default: - if (prompt) { - child_count++; - item_make("---%*c%s", indent + 1, ' ', _(prompt)); - item_set_tag(':'); - item_set_data(menu); - } - } - } else - doint = 0; - goto conf_childs; - } - - type = sym_get_type(sym); - if (sym_is_choice(sym)) { - struct symbol *def_sym = sym_get_choice_value(sym); - struct menu *def_menu = NULL; - - child_count++; - for (child = menu->list; child; child = child->next) { - if (menu_is_visible(child) && child->sym == def_sym) - def_menu = child; - } - - val = sym_get_tristate_value(sym); - if (sym_is_changable(sym)) { - switch (type) { - case S_BOOLEAN: - item_make("[%c]", val == no ? ' ' : '*'); - break; - case S_TRISTATE: - switch (val) { - case yes: ch = '*'; break; - case mod: ch = 'M'; break; - default: ch = ' '; break; - } - item_make("<%c>", ch); - break; - } - item_set_tag('t'); - item_set_data(menu); - } else { - item_make(" "); - item_set_tag(def_menu ? 't' : ':'); - item_set_data(menu); - } - - item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); - if (val == yes) { - if (def_menu) { - item_add_str(" (%s)", _(menu_get_prompt(def_menu))); - item_add_str(" --->"); - if (def_menu->list) { - indent += 2; - build_conf(def_menu); - indent -= 2; - } - } - return; - } - } else { - if (menu == current_menu) { - item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); - item_set_tag(':'); - item_set_data(menu); - goto conf_childs; - } - child_count++; - val = sym_get_tristate_value(sym); - if (sym_is_choice_value(sym) && val == yes) { - item_make(" "); - item_set_tag(':'); - item_set_data(menu); - } else { - switch (type) { - case S_BOOLEAN: - if (sym_is_changable(sym)) - item_make("[%c]", val == no ? ' ' : '*'); - else - item_make("-%c-", val == no ? ' ' : '*'); - item_set_tag('t'); - item_set_data(menu); - break; - case S_TRISTATE: - switch (val) { - case yes: ch = '*'; break; - case mod: ch = 'M'; break; - default: ch = ' '; break; - } - if (sym_is_changable(sym)) { - if (sym->rev_dep.tri == mod) - item_make("{%c}", ch); - else - item_make("<%c>", ch); - } else - item_make("-%c-", ch); - item_set_tag('t'); - item_set_data(menu); - break; - default: - tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */ - item_make("(%s)", sym_get_string_value(sym)); - tmp = indent - tmp + 4; - if (tmp < 0) - tmp = 0; - item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)), - (sym_has_value(sym) || !sym_is_changable(sym)) ? - "" : _(" (NEW)")); - item_set_tag('s'); - item_set_data(menu); - goto conf_childs; - } - } - item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)), - (sym_has_value(sym) || !sym_is_changable(sym)) ? - "" : _(" (NEW)")); - if (menu->prompt->type == P_MENU) { - item_add_str(" --->"); - return; - } - } - -conf_childs: - indent += doint; - for (child = menu->list; child; child = child->next) - build_conf(child); - indent -= doint; -} - -static void conf(struct menu *menu) -{ - struct menu *submenu; - const char *prompt = menu_get_prompt(menu); - struct symbol *sym; - struct menu *active_menu = NULL; - int res; - int s_scroll = 0; - - while (1) { - item_reset(); - current_menu = menu; - build_conf(menu); - if (!child_count) - break; - if (menu == &rootmenu) { - item_make("--- "); - item_set_tag(':'); - item_make(_(" Load an Alternate Configuration File")); - item_set_tag('L'); - item_make(_(" Save an Alternate Configuration File")); - item_set_tag('S'); - } - dialog_clear(); - res = dialog_menu(prompt ? _(prompt) : _("Main Menu"), - _(menu_instructions), - active_menu, &s_scroll); - if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) - break; - if (!item_activate_selected()) - continue; - if (!item_tag()) - continue; - - submenu = item_data(); - active_menu = item_data(); - if (submenu) - sym = submenu->sym; - else - sym = NULL; - - switch (res) { - case 0: - switch (item_tag()) { - case 'm': - if (single_menu_mode) - submenu->data = (void *) (long) !submenu->data; - else - conf(submenu); - break; - case 't': - if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) - conf_choice(submenu); - else if (submenu->prompt->type == P_MENU) - conf(submenu); - break; - case 's': - conf_string(submenu); - break; - case 'L': - conf_load(); - break; - case 'S': - conf_save(); - break; - } - break; - case 2: - if (sym) - show_help(submenu); - else - show_helptext(_("README"), _(mconf_readme)); - break; - case 3: - if (item_is_tag('t')) { - if (sym_set_tristate_value(sym, yes)) - break; - if (sym_set_tristate_value(sym, mod)) - show_textbox(NULL, setmod_text, 6, 74); - } - break; - case 4: - if (item_is_tag('t')) - sym_set_tristate_value(sym, no); - break; - case 5: - if (item_is_tag('t')) - sym_set_tristate_value(sym, mod); - break; - case 6: - if (item_is_tag('t')) - sym_toggle_tristate_value(sym); - else if (item_is_tag('m')) - conf(submenu); - break; - case 7: - search_conf(); - break; - } - } -} - -static void show_textbox(const char *title, const char *text, int r, int c) -{ - dialog_clear(); - dialog_textbox(title, text, r, c); -} - -static void show_helptext(const char *title, const char *text) -{ - show_textbox(title, text, 0, 0); -} - -static void show_help(struct menu *menu) -{ - struct gstr help = str_new(); - struct symbol *sym = menu->sym; - - if (menu_has_help(menu)) - { - if (sym->name) { - str_printf(&help, "CONFIG_%s:\n\n", sym->name); - str_append(&help, _(menu_get_help(menu))); - str_append(&help, "\n"); - } - } else { - str_append(&help, nohelp_text); - } - get_symbol_str(&help, sym); - show_helptext(_(menu_get_prompt(menu)), str_get(&help)); - str_free(&help); -} - -static void conf_choice(struct menu *menu) -{ - const char *prompt = _(menu_get_prompt(menu)); - struct menu *child; - struct symbol *active; - - active = sym_get_choice_value(menu->sym); - while (1) { - int res; - int selected; - item_reset(); - - current_menu = menu; - for (child = menu->list; child; child = child->next) { - if (!menu_is_visible(child)) - continue; - if (child->sym) - item_make("%s", _(menu_get_prompt(child))); - else { - item_make("*** %s ***", _(menu_get_prompt(child))); - item_set_tag(':'); - } - item_set_data(child); - if (child->sym == active) - item_set_selected(1); - if (child->sym == sym_get_choice_value(menu->sym)) - item_set_tag('X'); - } - dialog_clear(); - res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"), - _(radiolist_instructions), - 15, 70, 6); - selected = item_activate_selected(); - switch (res) { - case 0: - if (selected) { - child = item_data(); - if (!child->sym) - break; - - sym_set_tristate_value(child->sym, yes); - } - return; - case 1: - if (selected) { - child = item_data(); - show_help(child); - active = child->sym; - } else - show_help(menu); - break; - case KEY_ESC: - return; - case -ERRDISPLAYTOOSMALL: - return; - } - } -} - -static void conf_string(struct menu *menu) -{ - const char *prompt = menu_get_prompt(menu); - - while (1) { - int res; - const char *heading; - - switch (sym_get_type(menu->sym)) { - case S_INT: - heading = _(inputbox_instructions_int); - break; - case S_HEX: - heading = _(inputbox_instructions_hex); - break; - case S_STRING: - heading = _(inputbox_instructions_string); - break; - default: - heading = _("Internal mconf error!"); - } - dialog_clear(); - res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"), - heading, 10, 75, - sym_get_string_value(menu->sym)); - switch (res) { - case 0: - if (sym_set_string_value(menu->sym, dialog_input_result)) - return; - show_textbox(NULL, _("You have made an invalid entry."), 5, 43); - break; - case 1: - show_help(menu); - break; - case KEY_ESC: - return; - } - } -} - -static void conf_load(void) -{ - - while (1) { - int res; - dialog_clear(); - res = dialog_inputbox(NULL, load_config_text, - 11, 55, filename); - switch(res) { - case 0: - if (!dialog_input_result[0]) - return; - if (!conf_read(dialog_input_result)) { - set_config_filename(dialog_input_result); - sym_set_change_count(1); - return; - } - show_textbox(NULL, _("File does not exist!"), 5, 38); - break; - case 1: - show_helptext(_("Load Alternate Configuration"), load_config_help); - break; - case KEY_ESC: - return; - } - } -} - -static void conf_save(void) -{ - while (1) { - int res; - dialog_clear(); - res = dialog_inputbox(NULL, save_config_text, - 11, 55, filename); - switch(res) { - case 0: - if (!dialog_input_result[0]) - return; - if (!conf_write(dialog_input_result)) { - set_config_filename(dialog_input_result); - return; - } - show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60); - break; - case 1: - show_helptext(_("Save Alternate Configuration"), save_config_help); - break; - case KEY_ESC: - return; - } - } -} - -int main(int ac, char **av) -{ - int saved_x, saved_y; - char *mode; - int res; - -#ifndef KBUILD_NO_NLS - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); -#endif - - conf_parse(av[1]); - conf_read(NULL); - - mode = getenv("MENUCONFIG_MODE"); - if (mode) { - if (!strcasecmp(mode, "single_menu")) - single_menu_mode = 1; - } - - initscr(); - - getyx(stdscr, saved_y, saved_x); - if (init_dialog(NULL)) { - fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); - fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n")); - return 1; - } - - set_config_filename(conf_get_configname()); - do { - conf(&rootmenu); - dialog_clear(); - if (conf_get_changed()) - res = dialog_yesno(NULL, - _("Do you wish to save your " - "new OpenADK configuration?\n" - " to continue."), - 6, 60); - else - res = -1; - } while (res == KEY_ESC); - end_dialog(saved_x, saved_y); - - switch (res) { - case 0: - if (conf_write(filename)) { - fprintf(stderr, _("\n\n" - "Error during writing of the OpenADK configuration.\n" - "Your OpenADK configuration changes were NOT saved." - "\n\n")); - return 1; - } - case -1: - printf(_("\n\n" - "*** End of OpenADK configuration.\n" - "*** Execute 'make' to build the firmware or try 'make help'." - "\n\n")); - break; - default: - fprintf(stderr, _("\n\n" - "Your OpenADK configuration changes were NOT saved." - "\n\n")); - } - - return 0; -} - diff --git a/config/menu.c b/config/menu.c deleted file mode 100644 index 3e6405ac2..000000000 --- a/config/menu.c +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - */ - -#include -#include - -#define LKC_DIRECT_LINK -#include "lkc.h" - -static const char nohelp_text[] = N_( - "There is no help available for this OpenADK option.\n"); - -struct menu rootmenu; -static struct menu **last_entry_ptr; - -struct file *file_list; -struct file *current_file; - -void menu_warn(struct menu *menu, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); -} - -static void prop_warn(struct property *prop, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); -} - -void menu_init(void) -{ - current_entry = current_menu = &rootmenu; - last_entry_ptr = &rootmenu.list; -} - -void menu_add_entry(struct symbol *sym) -{ - struct menu *menu; - - menu = malloc(sizeof(*menu)); - memset(menu, 0, sizeof(*menu)); - menu->sym = sym; - menu->parent = current_menu; - menu->file = current_file; - menu->lineno = zconf_lineno(); - - *last_entry_ptr = menu; - last_entry_ptr = &menu->next; - current_entry = menu; -} - -void menu_end_entry(void) -{ -} - -struct menu *menu_add_menu(void) -{ - menu_end_entry(); - last_entry_ptr = ¤t_entry->list; - return current_menu = current_entry; -} - -void menu_end_menu(void) -{ - last_entry_ptr = ¤t_menu->next; - current_menu = current_menu->parent; -} - -static struct expr *menu_check_dep(struct expr *e) -{ - if (!e) - return e; - - switch (e->type) { - case E_NOT: - e->left.expr = menu_check_dep(e->left.expr); - break; - case E_OR: - case E_AND: - e->left.expr = menu_check_dep(e->left.expr); - e->right.expr = menu_check_dep(e->right.expr); - break; - case E_SYMBOL: - /* change 'm' into 'm' && MODULES */ - if (e->left.sym == &symbol_mod) - return expr_alloc_and(e, expr_alloc_symbol(modules_sym)); - break; - default: - break; - } - return e; -} - -void menu_add_dep(struct expr *dep) -{ - current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); -} - -void menu_set_type(int type) -{ - struct symbol *sym = current_entry->sym; - - if (sym->type == type) - return; - if (sym->type == S_UNKNOWN) { - sym->type = type; - return; - } - menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'", - sym->name ? sym->name : "", - sym_type_name(sym->type), sym_type_name(type)); -} - -struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) -{ - struct property *prop = prop_alloc(type, current_entry->sym); - - prop->menu = current_entry; - prop->expr = expr; - prop->visible.expr = menu_check_dep(dep); - - if (prompt) { - if (isspace(*prompt)) { - prop_warn(prop, "leading whitespace ignored"); - while (isspace(*prompt)) - prompt++; - } - if (current_entry->prompt) - prop_warn(prop, "prompt redefined"); - current_entry->prompt = prop; - } - prop->text = prompt; - - return prop; -} - -struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep) -{ - return menu_add_prop(type, prompt, NULL, dep); -} - -void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) -{ - menu_add_prop(type, NULL, expr, dep); -} - -void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) -{ - menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); -} - -void menu_add_option(int token, char *arg) -{ - struct property *prop; - - switch (token) { - case T_OPT_MODULES: - prop = prop_alloc(P_DEFAULT, modules_sym); - prop->expr = expr_alloc_symbol(current_entry->sym); - break; - case T_OPT_DEFCONFIG_LIST: - if (!sym_defconfig_list) - sym_defconfig_list = current_entry->sym; - else if (sym_defconfig_list != current_entry->sym) - zconf_error("trying to redefine defconfig symbol"); - break; - case T_OPT_ENV: - prop_add_env(arg); - break; - } -} - -static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) -{ - return sym2->type == S_INT || sym2->type == S_HEX || - (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); -} - -static void sym_check_prop(struct symbol *sym) -{ - struct property *prop; - struct symbol *sym2; - for (prop = sym->prop; prop; prop = prop->next) { - switch (prop->type) { - case P_DEFAULT: - if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) && - prop->expr->type != E_SYMBOL) - prop_warn(prop, - "default for config symbol '%'" - " must be a single symbol", sym->name); - break; - case P_SELECT: - sym2 = prop_get_symbol(prop); - if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) - prop_warn(prop, - "config symbol '%s' uses select, but is " - "not boolean or tristate", sym->name); - else if (sym2->type != S_UNKNOWN && - sym2->type != S_BOOLEAN && - sym2->type != S_TRISTATE) - prop_warn(prop, - "'%s' has wrong type. 'select' only " - "accept arguments of boolean and " - "tristate type", sym2->name); - break; - case P_RANGE: - if (sym->type != S_INT && sym->type != S_HEX) - prop_warn(prop, "range is only allowed " - "for int or hex symbols"); - if (!menu_range_valid_sym(sym, prop->expr->left.sym) || - !menu_range_valid_sym(sym, prop->expr->right.sym)) - prop_warn(prop, "range is invalid"); - break; - default: - ; - } - } -} - -void menu_finalize(struct menu *parent) -{ - struct menu *menu, *last_menu; - struct symbol *sym; - struct property *prop; - struct expr *parentdep, *basedep, *dep, *dep2, **ep; - - sym = parent->sym; - if (parent->list) { - if (sym && sym_is_choice(sym)) { - if (sym->type == S_UNKNOWN) { - /* find the first choice value to find out choice type */ - current_entry = parent; - for (menu = parent->list; menu; menu = menu->next) { - if (menu->sym && menu->sym->type != S_UNKNOWN) { - menu_set_type(menu->sym->type); - break; - } - } - } - /* set the type of the remaining choice values */ - for (menu = parent->list; menu; menu = menu->next) { - current_entry = menu; - if (menu->sym && menu->sym->type == S_UNKNOWN) - menu_set_type(sym->type); - } - parentdep = expr_alloc_symbol(sym); - } else if (parent->prompt) - parentdep = parent->prompt->visible.expr; - else - parentdep = parent->dep; - - for (menu = parent->list; menu; menu = menu->next) { - basedep = expr_transform(menu->dep); - basedep = expr_alloc_and(expr_copy(parentdep), basedep); - basedep = expr_eliminate_dups(basedep); - menu->dep = basedep; - if (menu->sym) - prop = menu->sym->prop; - else - prop = menu->prompt; - for (; prop; prop = prop->next) { - if (prop->menu != menu) - continue; - dep = expr_transform(prop->visible.expr); - dep = expr_alloc_and(expr_copy(basedep), dep); - dep = expr_eliminate_dups(dep); - if (menu->sym && menu->sym->type != S_TRISTATE) - dep = expr_trans_bool(dep); - prop->visible.expr = dep; - if (prop->type == P_SELECT) { - struct symbol *es = prop_get_symbol(prop); - es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, - expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); - } - } - } - for (menu = parent->list; menu; menu = menu->next) - menu_finalize(menu); - } else if (sym) { - basedep = parent->prompt ? parent->prompt->visible.expr : NULL; - basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); - basedep = expr_eliminate_dups(expr_transform(basedep)); - last_menu = NULL; - for (menu = parent->next; menu; menu = menu->next) { - dep = menu->prompt ? menu->prompt->visible.expr : menu->dep; - if (!expr_contains_symbol(dep, sym)) - break; - if (expr_depends_symbol(dep, sym)) - goto next; - dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no); - dep = expr_eliminate_dups(expr_transform(dep)); - dep2 = expr_copy(basedep); - expr_eliminate_eq(&dep, &dep2); - expr_free(dep); - if (!expr_is_yes(dep2)) { - expr_free(dep2); - break; - } - expr_free(dep2); - next: - menu_finalize(menu); - menu->parent = parent; - last_menu = menu; - } - if (last_menu) { - parent->list = parent->next; - parent->next = last_menu->next; - last_menu->next = NULL; - } - } - for (menu = parent->list; menu; menu = menu->next) { - if (sym && sym_is_choice(sym) && - menu->sym && !sym_is_choice_value(menu->sym)) { - current_entry = menu; - menu->sym->flags |= SYMBOL_CHOICEVAL; - if (!menu->prompt) - menu_warn(menu, "choice value must have a prompt"); - for (prop = menu->sym->prop; prop; prop = prop->next) { - if (prop->type == P_DEFAULT) - prop_warn(prop, "defaults for choice " - "values not supported"); - if (prop->menu == menu) - continue; - if (prop->type == P_PROMPT && - prop->menu->parent->sym != sym) - prop_warn(prop, "choice value used outside its choice group"); - } - /* Non-tristate choice values of tristate choices must - * depend on the choice being set to Y. The choice - * values' dependencies were propagated to their - * properties above, so the change here must be re- - * propagated. - */ - if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) { - basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes); - menu->dep = expr_alloc_and(basedep, menu->dep); - for (prop = menu->sym->prop; prop; prop = prop->next) { - if (prop->menu != menu) - continue; - prop->visible.expr = expr_alloc_and(expr_copy(basedep), - prop->visible.expr); - } - } - menu_add_symbol(P_CHOICE, sym, NULL); - prop = sym_get_choice_prop(sym); - for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr) - ; - *ep = expr_alloc_one(E_LIST, NULL); - (*ep)->right.sym = menu->sym; - } - if (menu->list && (!menu->prompt || !menu->prompt->text)) { - for (last_menu = menu->list; ; last_menu = last_menu->next) { - last_menu->parent = parent; - if (!last_menu->next) - break; - } - last_menu->next = menu->next; - menu->next = menu->list; - menu->list = NULL; - } - } - - if (sym && !(sym->flags & SYMBOL_WARNED)) { - if (sym->type == S_UNKNOWN) - menu_warn(parent, "config symbol defined without type"); - - if (sym_is_choice(sym) && !parent->prompt) - menu_warn(parent, "choice must have a prompt"); - - /* Check properties connected to this symbol */ - sym_check_prop(sym); - sym->flags |= SYMBOL_WARNED; - } - - if (sym && !sym_is_optional(sym) && parent->prompt) { - sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr, - expr_alloc_and(parent->prompt->visible.expr, - expr_alloc_symbol(&symbol_mod))); - } -} - -bool menu_is_visible(struct menu *menu) -{ - struct menu *child; - struct symbol *sym; - tristate visible; - - if (!menu->prompt) - return false; - sym = menu->sym; - if (sym) { - sym_calc_value(sym); - visible = menu->prompt->visible.tri; - } else - visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr); - - if (visible != no) - return true; - if (!sym || sym_get_tristate_value(menu->sym) == no) - return false; - - for (child = menu->list; child; child = child->next) - if (menu_is_visible(child)) - return true; - return false; -} - -const char *menu_get_prompt(struct menu *menu) -{ - if (menu->prompt) - return menu->prompt->text; - else if (menu->sym) - return menu->sym->name; - return NULL; -} - -struct menu *menu_get_root_menu(struct menu *menu) -{ - return &rootmenu; -} - -struct menu *menu_get_parent_menu(struct menu *menu) -{ - enum prop_type type; - - for (; menu != &rootmenu; menu = menu->parent) { - type = menu->prompt ? menu->prompt->type : 0; - if (type == P_MENU) - break; - } - return menu; -} - -bool menu_has_help(struct menu *menu) -{ - return menu->help != NULL; -} - -const char *menu_get_help(struct menu *menu) -{ - if (menu->help) - return menu->help; - else - return ""; -} - -static void get_prompt_str(struct gstr *r, struct property *prop) -{ - int i, j; - struct menu *submenu[8], *menu; - - str_printf(r, _("Prompt: %s\n"), _(prop->text)); - str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, - prop->menu->lineno); - if (!expr_is_yes(prop->visible.expr)) { - str_append(r, _(" Depends on: ")); - expr_gstr_print(prop->visible.expr, r); - str_append(r, "\n"); - } - menu = prop->menu->parent; - for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) - submenu[i++] = menu; - if (i > 0) { - str_printf(r, _(" Location:\n")); - for (j = 4; --i >= 0; j += 2) { - menu = submenu[i]; - str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); - if (menu->sym) { - str_printf(r, " (%s [=%s])", menu->sym->name ? - menu->sym->name : _(""), - sym_get_string_value(menu->sym)); - } - str_append(r, "\n"); - } - } -} - -void get_symbol_str(struct gstr *r, struct symbol *sym) -{ - bool hit; - struct property *prop; - - if (sym && sym->name) - str_printf(r, "Symbol: %s [=%s]\n", sym->name, - sym_get_string_value(sym)); - for_all_prompts(sym, prop) - get_prompt_str(r, prop); - hit = false; - for_all_properties(sym, prop, P_SELECT) { - if (!hit) { - str_append(r, " Selects: "); - hit = true; - } else - str_printf(r, " && "); - expr_gstr_print(prop->expr, r); - } - if (hit) - str_append(r, "\n"); - if (sym->rev_dep.expr) { - str_append(r, _(" Selected by: ")); - expr_gstr_print(sym->rev_dep.expr, r); - str_append(r, "\n"); - } - str_append(r, "\n\n"); -} - -void menu_get_ext_help(struct menu *menu, struct gstr *help) -{ - struct symbol *sym = menu->sym; - - if (menu_has_help(menu)) { - if (sym->name) { - str_printf(help, "CONFIG_%s:\n\n", sym->name); - str_append(help, _(menu_get_help(menu))); - str_append(help, "\n"); - } - } else { - str_append(help, nohelp_text); - } - if (sym) - get_symbol_str(help, sym); -} diff --git a/config/symbol.c b/config/symbol.c deleted file mode 100644 index 18f3e5c33..000000000 --- a/config/symbol.c +++ /dev/null @@ -1,973 +0,0 @@ -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - */ - -#include -#include -#include -#include -#include - -#define LKC_DIRECT_LINK -#include "lkc.h" - -struct symbol symbol_yes = { - .name = "y", - .curr = { "y", yes }, - .flags = SYMBOL_CONST|SYMBOL_VALID, -}, symbol_mod = { - .name = "m", - .curr = { "m", mod }, - .flags = SYMBOL_CONST|SYMBOL_VALID, -}, symbol_no = { - .name = "n", - .curr = { "n", no }, - .flags = SYMBOL_CONST|SYMBOL_VALID, -}, symbol_empty = { - .name = "", - .curr = { "", no }, - .flags = SYMBOL_VALID, -}; - -struct symbol *sym_defconfig_list; -struct symbol *modules_sym; -tristate modules_val; - -struct expr *sym_env_list; - -void sym_add_default(struct symbol *sym, const char *def) -{ - struct property *prop = prop_alloc(P_DEFAULT, sym); - - prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST)); -} - -void sym_init(void) -{ - struct symbol *sym; - struct utsname uts; - static bool inited = false; - - if (inited) - return; - inited = true; - - uname(&uts); - - sym = sym_lookup("UNAME_RELEASE", 0); - sym->type = S_STRING; - sym->flags |= SYMBOL_AUTO; - sym_add_default(sym, uts.release); -} - -enum symbol_type sym_get_type(struct symbol *sym) -{ - enum symbol_type type = sym->type; - - if (type == S_TRISTATE) { - if (sym_is_choice_value(sym) && sym->visible == yes) - type = S_BOOLEAN; - else if (modules_val == no) - type = S_BOOLEAN; - } - return type; -} - -const char *sym_type_name(enum symbol_type type) -{ - switch (type) { - case S_BOOLEAN: - return "boolean"; - case S_TRISTATE: - return "tristate"; - case S_INT: - return "integer"; - case S_HEX: - return "hex"; - case S_STRING: - return "string"; - case S_UNKNOWN: - return "unknown"; - case S_OTHER: - break; - } - return "???"; -} - -struct property *sym_get_choice_prop(struct symbol *sym) -{ - struct property *prop; - - for_all_choices(sym, prop) - return prop; - return NULL; -} - -struct property *sym_get_env_prop(struct symbol *sym) -{ - struct property *prop; - - for_all_properties(sym, prop, P_ENV) - return prop; - return NULL; -} - -struct property *sym_get_default_prop(struct symbol *sym) -{ - struct property *prop; - - for_all_defaults(sym, prop) { - prop->visible.tri = expr_calc_value(prop->visible.expr); - if (prop->visible.tri != no) - return prop; - } - return NULL; -} - -struct property *sym_get_range_prop(struct symbol *sym) -{ - struct property *prop; - - for_all_properties(sym, prop, P_RANGE) { - prop->visible.tri = expr_calc_value(prop->visible.expr); - if (prop->visible.tri != no) - return prop; - } - return NULL; -} - -static int sym_get_range_val(struct symbol *sym, int base) -{ - sym_calc_value(sym); - switch (sym->type) { - case S_INT: - base = 10; - break; - case S_HEX: - base = 16; - break; - default: - break; - } - return strtol(sym->curr.val, NULL, base); -} - -static void sym_validate_range(struct symbol *sym) -{ - struct property *prop; - int base, val, val2; - char str[64]; - - switch (sym->type) { - case S_INT: - base = 10; - break; - case S_HEX: - base = 16; - break; - default: - return; - } - prop = sym_get_range_prop(sym); - if (!prop) - return; - val = strtol(sym->curr.val, NULL, base); - val2 = sym_get_range_val(prop->expr->left.sym, base); - if (val >= val2) { - val2 = sym_get_range_val(prop->expr->right.sym, base); - if (val <= val2) - return; - } - if (sym->type == S_INT) - sprintf(str, "%d", val2); - else - sprintf(str, "0x%x", val2); - sym->curr.val = strdup(str); -} - -static void sym_calc_visibility(struct symbol *sym) -{ - struct property *prop; - tristate tri; - - /* any prompt visible? */ - tri = no; - for_all_prompts(sym, prop) { - prop->visible.tri = expr_calc_value(prop->visible.expr); - tri = EXPR_OR(tri, prop->visible.tri); - } - if (tri == mod && (sym->type != S_TRISTATE || modules_val == no)) - tri = yes; - if (sym->visible != tri) { - sym->visible = tri; - sym_set_changed(sym); - } - if (sym_is_choice_value(sym)) - return; - tri = no; - if (sym->rev_dep.expr) - tri = expr_calc_value(sym->rev_dep.expr); - if (tri == mod && sym_get_type(sym) == S_BOOLEAN) - tri = yes; - if (sym->rev_dep.tri != tri) { - sym->rev_dep.tri = tri; - sym_set_changed(sym); - } -} - -static struct symbol *sym_calc_choice(struct symbol *sym) -{ - struct symbol *def_sym; - struct property *prop; - struct expr *e; - - /* is the user choice visible? */ - def_sym = sym->def[S_DEF_USER].val; - if (def_sym) { - sym_calc_visibility(def_sym); - if (def_sym->visible != no) - return def_sym; - } - - /* any of the defaults visible? */ - for_all_defaults(sym, prop) { - prop->visible.tri = expr_calc_value(prop->visible.expr); - if (prop->visible.tri == no) - continue; - def_sym = prop_get_symbol(prop); - sym_calc_visibility(def_sym); - if (def_sym->visible != no) - return def_sym; - } - - /* just get the first visible value */ - prop = sym_get_choice_prop(sym); - expr_list_for_each_sym(prop->expr, e, def_sym) { - sym_calc_visibility(def_sym); - if (def_sym->visible != no) - return def_sym; - } - - /* no choice? reset tristate value */ - sym->curr.tri = no; - return NULL; -} - -void sym_calc_value(struct symbol *sym) -{ - struct symbol_value newval, oldval; - struct property *prop; - struct expr *e; - - if (!sym) - return; - - if (sym->flags & SYMBOL_VALID) - return; - sym->flags |= SYMBOL_VALID; - - oldval = sym->curr; - - switch (sym->type) { - case S_INT: - case S_HEX: - case S_STRING: - newval = symbol_empty.curr; - break; - case S_BOOLEAN: - case S_TRISTATE: - newval = symbol_no.curr; - break; - default: - sym->curr.val = sym->name; - sym->curr.tri = no; - return; - } - if (!sym_is_choice_value(sym)) - sym->flags &= ~SYMBOL_WRITE; - - sym_calc_visibility(sym); - - /* set default if recursively called */ - sym->curr = newval; - - switch (sym_get_type(sym)) { - case S_BOOLEAN: - case S_TRISTATE: - if (sym_is_choice_value(sym) && sym->visible == yes) { - prop = sym_get_choice_prop(sym); - newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no; - } else { - if (sym->visible != no) { - /* if the symbol is visible use the user value - * if available, otherwise try the default value - */ - sym->flags |= SYMBOL_WRITE; - if (sym_has_value(sym)) { - newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri, - sym->visible); - goto calc_newval; - } - } - if (sym->rev_dep.tri != no) - sym->flags |= SYMBOL_WRITE; - if (!sym_is_choice(sym)) { - prop = sym_get_default_prop(sym); - if (prop) { - sym->flags |= SYMBOL_WRITE; - newval.tri = EXPR_AND(expr_calc_value(prop->expr), - prop->visible.tri); - } - } - calc_newval: - newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); - } - if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) - newval.tri = yes; - break; - case S_STRING: - case S_HEX: - case S_INT: - if (sym->visible != no) { - sym->flags |= SYMBOL_WRITE; - if (sym_has_value(sym)) { - newval.val = sym->def[S_DEF_USER].val; - break; - } - } - prop = sym_get_default_prop(sym); - if (prop) { - struct symbol *ds = prop_get_symbol(prop); - if (ds) { - sym->flags |= SYMBOL_WRITE; - sym_calc_value(ds); - newval.val = ds->curr.val; - } - } - break; - default: - ; - } - - sym->curr = newval; - if (sym_is_choice(sym) && newval.tri == yes) - sym->curr.val = sym_calc_choice(sym); - sym_validate_range(sym); - - if (memcmp(&oldval, &sym->curr, sizeof(oldval))) { - sym_set_changed(sym); - if (modules_sym == sym) { - sym_set_all_changed(); - modules_val = modules_sym->curr.tri; - } - } - - if (sym_is_choice(sym)) { - struct symbol *choice_sym; - int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); - - prop = sym_get_choice_prop(sym); - expr_list_for_each_sym(prop->expr, e, choice_sym) { - choice_sym->flags |= flags; - if (flags & SYMBOL_CHANGED) - sym_set_changed(choice_sym); - } - } - - if (sym->flags & SYMBOL_AUTO) - sym->flags &= ~SYMBOL_WRITE; -} - -void sym_clear_all_valid(void) -{ - struct symbol *sym; - int i; - - for_all_symbols(i, sym) - sym->flags &= ~SYMBOL_VALID; - sym_add_change_count(1); - if (modules_sym) - sym_calc_value(modules_sym); -} - -void sym_set_changed(struct symbol *sym) -{ - struct property *prop; - - sym->flags |= SYMBOL_CHANGED; - for (prop = sym->prop; prop; prop = prop->next) { - if (prop->menu) - prop->menu->flags |= MENU_CHANGED; - } -} - -void sym_set_all_changed(void) -{ - struct symbol *sym; - int i; - - for_all_symbols(i, sym) - sym_set_changed(sym); -} - -bool sym_tristate_within_range(struct symbol *sym, tristate val) -{ - int type = sym_get_type(sym); - - if (sym->visible == no) - return false; - - if (type != S_BOOLEAN && type != S_TRISTATE) - return false; - - if (type == S_BOOLEAN && val == mod) - return false; - if (sym->visible <= sym->rev_dep.tri) - return false; - if (sym_is_choice_value(sym) && sym->visible == yes) - return val == yes; - return val >= sym->rev_dep.tri && val <= sym->visible; -} - -bool sym_set_tristate_value(struct symbol *sym, tristate val) -{ - tristate oldval = sym_get_tristate_value(sym); - - if (oldval != val && !sym_tristate_within_range(sym, val)) - return false; - - if (!(sym->flags & SYMBOL_DEF_USER)) { - sym->flags |= SYMBOL_DEF_USER; - sym_set_changed(sym); - } - /* - * setting a choice value also resets the new flag of the choice - * symbol and all other choice values. - */ - if (sym_is_choice_value(sym) && val == yes) { - struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); - struct property *prop; - struct expr *e; - - cs->def[S_DEF_USER].val = sym; - cs->flags |= SYMBOL_DEF_USER; - prop = sym_get_choice_prop(cs); - for (e = prop->expr; e; e = e->left.expr) { - if (e->right.sym->visible != no) - e->right.sym->flags |= SYMBOL_DEF_USER; - } - } - - sym->def[S_DEF_USER].tri = val; - if (oldval != val) - sym_clear_all_valid(); - - return true; -} - -tristate sym_toggle_tristate_value(struct symbol *sym) -{ - tristate oldval, newval; - - oldval = newval = sym_get_tristate_value(sym); - do { - switch (newval) { - case no: - newval = mod; - break; - case mod: - newval = yes; - break; - case yes: - newval = no; - break; - } - if (sym_set_tristate_value(sym, newval)) - break; - } while (oldval != newval); - return newval; -} - -bool sym_string_valid(struct symbol *sym, const char *str) -{ - signed char ch; - - switch (sym->type) { - case S_STRING: - return true; - case S_INT: - ch = *str++; - if (ch == '-') - ch = *str++; - if (!isdigit(ch)) - return false; - if (ch == '0' && *str != 0) - return false; - while ((ch = *str++)) { - if (!isdigit(ch)) - return false; - } - return true; - case S_HEX: - if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) - str += 2; - ch = *str++; - do { - if (!isxdigit(ch)) - return false; - } while ((ch = *str++)); - return true; - case S_BOOLEAN: - case S_TRISTATE: - switch (str[0]) { - case 'y': case 'Y': - case 'm': case 'M': - case 'n': case 'N': - return true; - } - return false; - default: - return false; - } -} - -bool sym_string_within_range(struct symbol *sym, const char *str) -{ - struct property *prop; - int val; - - switch (sym->type) { - case S_STRING: - return sym_string_valid(sym, str); - case S_INT: - if (!sym_string_valid(sym, str)) - return false; - prop = sym_get_range_prop(sym); - if (!prop) - return true; - val = strtol(str, NULL, 10); - return val >= sym_get_range_val(prop->expr->left.sym, 10) && - val <= sym_get_range_val(prop->expr->right.sym, 10); - case S_HEX: - if (!sym_string_valid(sym, str)) - return false; - prop = sym_get_range_prop(sym); - if (!prop) - return true; - val = strtol(str, NULL, 16); - return val >= sym_get_range_val(prop->expr->left.sym, 16) && - val <= sym_get_range_val(prop->expr->right.sym, 16); - case S_BOOLEAN: - case S_TRISTATE: - switch (str[0]) { - case 'y': case 'Y': - return sym_tristate_within_range(sym, yes); - case 'm': case 'M': - return sym_tristate_within_range(sym, mod); - case 'n': case 'N': - return sym_tristate_within_range(sym, no); - } - return false; - default: - return false; - } -} - -bool sym_set_string_value(struct symbol *sym, const char *newval) -{ - const char *oldval; - char *val; - int size; - - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - switch (newval[0]) { - case 'y': case 'Y': - return sym_set_tristate_value(sym, yes); - case 'm': case 'M': - return sym_set_tristate_value(sym, mod); - case 'n': case 'N': - return sym_set_tristate_value(sym, no); - } - return false; - default: - ; - } - - if (!sym_string_within_range(sym, newval)) - return false; - - if (!(sym->flags & SYMBOL_DEF_USER)) { - sym->flags |= SYMBOL_DEF_USER; - sym_set_changed(sym); - } - - oldval = sym->def[S_DEF_USER].val; - size = strlen(newval) + 1; - if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { - size += 2; - sym->def[S_DEF_USER].val = val = malloc(size); - *val++ = '0'; - *val++ = 'x'; - } else if (!oldval || strcmp(oldval, newval)) - sym->def[S_DEF_USER].val = val = malloc(size); - else - return true; - - strcpy(val, newval); - free((void *)oldval); - sym_clear_all_valid(); - - return true; -} - -const char *sym_get_string_value(struct symbol *sym) -{ - tristate val; - - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - val = sym_get_tristate_value(sym); - switch (val) { - case no: - return "n"; - case mod: - return "m"; - case yes: - return "y"; - } - break; - default: - ; - } - return (const char *)sym->curr.val; -} - -bool sym_is_changable(struct symbol *sym) -{ - return sym->visible > sym->rev_dep.tri; -} - -struct symbol *sym_lookup(const char *name, int flags) -{ - struct symbol *symbol; - const char *ptr; - char *new_name; - int hash = 0; - - if (name) { - if (name[0] && !name[1]) { - switch (name[0]) { - case 'y': return &symbol_yes; - case 'm': return &symbol_mod; - case 'n': return &symbol_no; - } - } - for (ptr = name; *ptr; ptr++) - hash += *ptr; - hash &= 0xff; - - for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { - if (!strcmp(symbol->name, name) && - (flags ? symbol->flags & flags - : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) - return symbol; - } - new_name = strdup(name); - } else { - new_name = NULL; - hash = 256; - } - - symbol = malloc(sizeof(*symbol)); - memset(symbol, 0, sizeof(*symbol)); - symbol->name = new_name; - symbol->type = S_UNKNOWN; - symbol->flags |= flags; - - symbol->next = symbol_hash[hash]; - symbol_hash[hash] = symbol; - - return symbol; -} - -struct symbol *sym_find(const char *name) -{ - struct symbol *symbol = NULL; - const char *ptr; - int hash = 0; - - if (!name) - return NULL; - - if (name[0] && !name[1]) { - switch (name[0]) { - case 'y': return &symbol_yes; - case 'm': return &symbol_mod; - case 'n': return &symbol_no; - } - } - for (ptr = name; *ptr; ptr++) - hash += *ptr; - hash &= 0xff; - - for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { - if (!strcmp(symbol->name, name) && - !(symbol->flags & SYMBOL_CONST)) - break; - } - - return symbol; -} - -struct symbol **sym_re_search(const char *pattern) -{ - struct symbol *sym, **sym_arr = NULL; - int i, cnt, size; - regex_t re; - - cnt = size = 0; - /* Skip if empty */ - if (strlen(pattern) == 0) - return NULL; - if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE)) - return NULL; - - for_all_symbols(i, sym) { - if (sym->flags & SYMBOL_CONST || !sym->name) - continue; - if (regexec(&re, sym->name, 0, NULL, 0)) - continue; - if (cnt + 1 >= size) { - void *tmp = sym_arr; - size += 16; - sym_arr = realloc(sym_arr, size * sizeof(struct symbol *)); - if (!sym_arr) { - free(tmp); - return NULL; - } - } - sym_arr[cnt++] = sym; - } - if (sym_arr) - sym_arr[cnt] = NULL; - regfree(&re); - - return sym_arr; -} - - -static struct symbol *sym_check_expr_deps(struct expr *e) -{ - struct symbol *sym; - - if (!e) - return NULL; - switch (e->type) { - case E_OR: - case E_AND: - sym = sym_check_expr_deps(e->left.expr); - if (sym) - return sym; - return sym_check_expr_deps(e->right.expr); - case E_NOT: - return sym_check_expr_deps(e->left.expr); - case E_EQUAL: - case E_UNEQUAL: - sym = sym_check_deps(e->left.sym); - if (sym) - return sym; - return sym_check_deps(e->right.sym); - case E_SYMBOL: - return sym_check_deps(e->left.sym); - default: - break; - } - printf("Oops! How to check %d?\n", e->type); - return NULL; -} - -/* return NULL when dependencies are OK */ -static struct symbol *sym_check_sym_deps(struct symbol *sym) -{ - struct symbol *sym2; - struct property *prop; - - sym2 = sym_check_expr_deps(sym->rev_dep.expr); - if (sym2) - return sym2; - - for (prop = sym->prop; prop; prop = prop->next) { - if (prop->type == P_CHOICE || prop->type == P_SELECT) - continue; - sym2 = sym_check_expr_deps(prop->visible.expr); - if (sym2) - break; - if (prop->type != P_DEFAULT || sym_is_choice(sym)) - continue; - sym2 = sym_check_expr_deps(prop->expr); - if (sym2) - break; - } - - return sym2; -} - -static struct symbol *sym_check_choice_deps(struct symbol *choice) -{ - struct symbol *sym, *sym2; - struct property *prop; - struct expr *e; - - prop = sym_get_choice_prop(choice); - expr_list_for_each_sym(prop->expr, e, sym) - sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); - - choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); - sym2 = sym_check_sym_deps(choice); - choice->flags &= ~SYMBOL_CHECK; - if (sym2) - goto out; - - expr_list_for_each_sym(prop->expr, e, sym) { - sym2 = sym_check_sym_deps(sym); - if (sym2) { - fprintf(stderr, " -> %s", sym->name); - break; - } - } -out: - expr_list_for_each_sym(prop->expr, e, sym) - sym->flags &= ~SYMBOL_CHECK; - - if (sym2 && sym_is_choice_value(sym2) && - prop_get_symbol(sym_get_choice_prop(sym2)) == choice) - sym2 = choice; - - return sym2; -} - -struct symbol *sym_check_deps(struct symbol *sym) -{ - struct symbol *sym2; - struct property *prop; - - if (sym->flags & SYMBOL_CHECK) { - fprintf(stderr, "%s:%d:error: found recursive dependency: %s", - sym->prop->file->name, sym->prop->lineno, - sym->name ? sym->name : ""); - return sym; - } - if (sym->flags & SYMBOL_CHECKED) - return NULL; - - if (sym_is_choice_value(sym)) { - /* for choice groups start the check with main choice symbol */ - prop = sym_get_choice_prop(sym); - sym2 = sym_check_deps(prop_get_symbol(prop)); - } else if (sym_is_choice(sym)) { - sym2 = sym_check_choice_deps(sym); - } else { - sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); - sym2 = sym_check_sym_deps(sym); - sym->flags &= ~SYMBOL_CHECK; - } - - if (sym2) { - fprintf(stderr, " -> %s", sym->name ? sym->name : ""); - if (sym2 == sym) { - fprintf(stderr, "\n"); - zconfnerrs++; - sym2 = NULL; - } - } - - return sym2; -} - -struct property *prop_alloc(enum prop_type type, struct symbol *sym) -{ - struct property *prop; - struct property **propp; - - prop = malloc(sizeof(*prop)); - memset(prop, 0, sizeof(*prop)); - prop->type = type; - prop->sym = sym; - prop->file = current_file; - prop->lineno = zconf_lineno(); - - /* append property to the prop list of symbol */ - if (sym) { - for (propp = &sym->prop; *propp; propp = &(*propp)->next) - ; - *propp = prop; - } - - return prop; -} - -struct symbol *prop_get_symbol(struct property *prop) -{ - if (prop->expr && (prop->expr->type == E_SYMBOL || - prop->expr->type == E_LIST)) - return prop->expr->left.sym; - return NULL; -} - -const char *prop_get_type_name(enum prop_type type) -{ - switch (type) { - case P_PROMPT: - return "prompt"; - case P_ENV: - return "env"; - case P_COMMENT: - return "comment"; - case P_MENU: - return "menu"; - case P_DEFAULT: - return "default"; - case P_CHOICE: - return "choice"; - case P_SELECT: - return "select"; - case P_RANGE: - return "range"; - case P_UNKNOWN: - break; - } - return "unknown"; -} - -void prop_add_env(const char *env) -{ - struct symbol *sym, *sym2; - struct property *prop; - char *p; - - sym = current_entry->sym; - sym->flags |= SYMBOL_AUTO; - for_all_properties(sym, prop, P_ENV) { - sym2 = prop_get_symbol(prop); - if (strcmp(sym2->name, env)) - menu_warn(current_entry, "redefining environment symbol from %s", - sym2->name); - return; - } - - prop = prop_alloc(P_ENV, sym); - prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST)); - - sym_env_list = expr_alloc_one(E_LIST, sym_env_list); - sym_env_list->right.sym = sym; - - p = getenv(env); - if (p) - sym_add_default(sym, p); - else - menu_warn(current_entry, "environment variable %s undefined", env); -} diff --git a/config/util.c b/config/util.c deleted file mode 100644 index b6b2a46af..000000000 --- a/config/util.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2002-2005 Roman Zippel - * Copyright (C) 2002-2005 Sam Ravnborg - * - * Released under the terms of the GNU GPL v2.0. - */ - -#include -#include "lkc.h" - -/* file already present in list? If not add it */ -struct file *file_lookup(const char *name) -{ - struct file *file; - - for (file = file_list; file; file = file->next) { - if (!strcmp(name, file->name)) - return file; - } - - file = malloc(sizeof(*file)); - memset(file, 0, sizeof(*file)); - file->name = strdup(name); - file->next = file_list; - file_list = file; - return file; -} - -/* write a dependency file as used by kbuild to track dependencies */ -int file_write_dep(const char *name) -{ - struct symbol *sym, *env_sym; - struct expr *e; - struct file *file; - FILE *out; - - if (!name) - name = ".kconfig.d"; - out = fopen("..config.tmp", "w"); - if (!out) - return 1; - fprintf(out, "deps_config := \\\n"); - for (file = file_list; file; file = file->next) { - if (file->next) - fprintf(out, "\t%s \\\n", file->name); - else - fprintf(out, "\t%s\n", file->name); - } - fprintf(out, "\n%s: \\\n" - "\t$(deps_config)\n\n", conf_get_autoconfig_name()); - - expr_list_for_each_sym(sym_env_list, e, sym) { - struct property *prop; - const char *value; - - prop = sym_get_env_prop(sym); - env_sym = prop_get_symbol(prop); - if (!env_sym) - continue; - value = getenv(env_sym->name); - if (!value) - value = ""; - fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value); - fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name()); - fprintf(out, "endif\n"); - } - - fprintf(out, "\n$(deps_config): ;\n"); - fclose(out); - rename("..config.tmp", name); - return 0; -} - - -/* Allocate initial growable sting */ -struct gstr str_new(void) -{ - struct gstr gs; - gs.s = malloc(sizeof(char) * 64); - gs.len = 64; - strcpy(gs.s, "\0"); - return gs; -} - -/* Allocate and assign growable string */ -struct gstr str_assign(const char *s) -{ - struct gstr gs; - gs.s = strdup(s); - gs.len = strlen(s) + 1; - return gs; -} - -/* Free storage for growable string */ -void str_free(struct gstr *gs) -{ - if (gs->s) - free(gs->s); - gs->s = NULL; - gs->len = 0; -} - -/* Append to growable string */ -void str_append(struct gstr *gs, const char *s) -{ - size_t l; - if (s) { - l = strlen(gs->s) + strlen(s) + 1; - if (l > gs->len) { - gs->s = realloc(gs->s, l); - gs->len = l; - } - strcat(gs->s, s); - } -} - -/* Append printf formatted string to growable string */ -void str_printf(struct gstr *gs, const char *fmt, ...) -{ - va_list ap; - char s[10000]; /* big enough... */ - va_start(ap, fmt); - vsnprintf(s, sizeof(s), fmt, ap); - str_append(gs, s); - va_end(ap); -} - -/* Retrieve value of growable string */ -const char *str_get(struct gstr *gs) -{ - return gs->s; -} - diff --git a/config/zconf.gperf b/config/zconf.gperf deleted file mode 100644 index 25ef5d01c..000000000 --- a/config/zconf.gperf +++ /dev/null @@ -1,44 +0,0 @@ -%language=ANSI-C -%define hash-function-name kconf_id_hash -%define lookup-function-name kconf_id_lookup -%define string-pool-name kconf_id_strings -%compare-strncmp -%enum -%pic -%struct-type - -struct kconf_id; - -%% -mainmenu, T_MAINMENU, TF_COMMAND -menu, T_MENU, TF_COMMAND -endmenu, T_ENDMENU, TF_COMMAND -source, T_SOURCE, TF_COMMAND -choice, T_CHOICE, TF_COMMAND -endchoice, T_ENDCHOICE, TF_COMMAND -comment, T_COMMENT, TF_COMMAND -config, T_CONFIG, TF_COMMAND -menuconfig, T_MENUCONFIG, TF_COMMAND -help, T_HELP, TF_COMMAND -if, T_IF, TF_COMMAND|TF_PARAM -endif, T_ENDIF, TF_COMMAND -depends, T_DEPENDS, TF_COMMAND -optional, T_OPTIONAL, TF_COMMAND -default, T_DEFAULT, TF_COMMAND, S_UNKNOWN -prompt, T_PROMPT, TF_COMMAND -tristate, T_TYPE, TF_COMMAND, S_TRISTATE -def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE -bool, T_TYPE, TF_COMMAND, S_BOOLEAN -boolean, T_TYPE, TF_COMMAND, S_BOOLEAN -def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN -int, T_TYPE, TF_COMMAND, S_INT -hex, T_TYPE, TF_COMMAND, S_HEX -string, T_TYPE, TF_COMMAND, S_STRING -select, T_SELECT, TF_COMMAND -range, T_RANGE, TF_COMMAND -option, T_OPTION, TF_COMMAND -on, T_ON, TF_PARAM -modules, T_OPT_MODULES, TF_OPTION -defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION -env, T_OPT_ENV, TF_OPTION -%% diff --git a/config/zconf.hash.c_shipped b/config/zconf.hash.c_shipped deleted file mode 100644 index 5c73d5133..000000000 --- a/config/zconf.hash.c_shipped +++ /dev/null @@ -1,237 +0,0 @@ -/* ANSI-C code produced by gperf version 3.0.3 */ -/* Command-line: gperf */ -/* Computed positions: -k'1,3' */ - -#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ - && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ - && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ - && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ - && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ - && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ - && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ - && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ - && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ - && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ - && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ - && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ - && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ - && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ - && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ - && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ - && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ - && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ - && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ - && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ - && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ - && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ - && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) -/* The character set is not based on ISO-646. */ -#error "gperf generated tables don't work with this execution character set. Please report a bug to ." -#endif - -struct kconf_id; -/* maximum key range = 47, duplicates = 0 */ - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int -kconf_id_hash (register const char *str, register unsigned int len) -{ - static unsigned char asso_values[] = - { - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 11, 5, - 0, 0, 5, 49, 5, 20, 49, 49, 5, 20, - 5, 0, 30, 49, 0, 15, 0, 10, 0, 49, - 25, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49 - }; - register int hval = len; - - switch (hval) - { - default: - hval += asso_values[(unsigned char)str[2]]; - /*FALLTHROUGH*/ - case 2: - case 1: - hval += asso_values[(unsigned char)str[0]]; - break; - } - return hval; -} - -struct kconf_id_strings_t - { - char kconf_id_strings_str2[sizeof("on")]; - char kconf_id_strings_str3[sizeof("env")]; - char kconf_id_strings_str5[sizeof("endif")]; - char kconf_id_strings_str6[sizeof("option")]; - char kconf_id_strings_str7[sizeof("endmenu")]; - char kconf_id_strings_str8[sizeof("optional")]; - char kconf_id_strings_str9[sizeof("endchoice")]; - char kconf_id_strings_str10[sizeof("range")]; - char kconf_id_strings_str11[sizeof("choice")]; - char kconf_id_strings_str12[sizeof("default")]; - char kconf_id_strings_str13[sizeof("def_bool")]; - char kconf_id_strings_str14[sizeof("help")]; - char kconf_id_strings_str15[sizeof("bool")]; - char kconf_id_strings_str16[sizeof("config")]; - char kconf_id_strings_str17[sizeof("def_tristate")]; - char kconf_id_strings_str18[sizeof("boolean")]; - char kconf_id_strings_str19[sizeof("defconfig_list")]; - char kconf_id_strings_str21[sizeof("string")]; - char kconf_id_strings_str22[sizeof("if")]; - char kconf_id_strings_str23[sizeof("int")]; - char kconf_id_strings_str26[sizeof("select")]; - char kconf_id_strings_str27[sizeof("modules")]; - char kconf_id_strings_str28[sizeof("tristate")]; - char kconf_id_strings_str29[sizeof("menu")]; - char kconf_id_strings_str31[sizeof("source")]; - char kconf_id_strings_str32[sizeof("comment")]; - char kconf_id_strings_str33[sizeof("hex")]; - char kconf_id_strings_str35[sizeof("menuconfig")]; - char kconf_id_strings_str36[sizeof("prompt")]; - char kconf_id_strings_str37[sizeof("depends")]; - char kconf_id_strings_str48[sizeof("mainmenu")]; - }; -static struct kconf_id_strings_t kconf_id_strings_contents = - { - "on", - "env", - "endif", - "option", - "endmenu", - "optional", - "endchoice", - "range", - "choice", - "default", - "def_bool", - "help", - "bool", - "config", - "def_tristate", - "boolean", - "defconfig_list", - "string", - "if", - "int", - "select", - "modules", - "tristate", - "menu", - "source", - "comment", - "hex", - "menuconfig", - "prompt", - "depends", - "mainmenu" - }; -#define kconf_id_strings ((const char *) &kconf_id_strings_contents) -#ifdef __GNUC__ -__inline -#ifdef __GNUC_STDC_INLINE__ -__attribute__ ((__gnu_inline__)) -#endif -#endif -struct kconf_id * -kconf_id_lookup (register const char *str, register unsigned int len) -{ - enum - { - TOTAL_KEYWORDS = 31, - MIN_WORD_LENGTH = 2, - MAX_WORD_LENGTH = 14, - MIN_HASH_VALUE = 2, - MAX_HASH_VALUE = 48 - }; - - static struct kconf_id wordlist[] = - { - {-1}, {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_ON, TF_PARAM}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_OPT_ENV, TF_OPTION}, - {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_OPTION, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_OPTIONAL, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_RANGE, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_CHOICE, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_HELP, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str15, T_TYPE, TF_COMMAND, S_BOOLEAN}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_CONFIG, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_BOOLEAN}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19, T_OPT_DEFCONFIG_LIST,TF_OPTION}, - {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_TYPE, TF_COMMAND, S_STRING}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT}, - {-1}, {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SELECT, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND}, - {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SOURCE, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_TYPE, TF_COMMAND, S_HEX}, - {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_PROMPT, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_DEPENDS, TF_COMMAND}, - {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, - {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = kconf_id_hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register int o = wordlist[key].name; - if (o >= 0) - { - register const char *s = o + kconf_id_strings; - - if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') - return &wordlist[key]; - } - } - } - return 0; -} - diff --git a/config/zconf.l b/config/zconf.l deleted file mode 100644 index 21ff69c9a..000000000 --- a/config/zconf.l +++ /dev/null @@ -1,359 +0,0 @@ -%option backup nostdinit noyywrap never-interactive full ecs -%option 8bit backup nodefault perf-report perf-report -%option noinput -%x COMMAND HELP STRING PARAM -%{ -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - */ - -#include -#include -#include -#include -#include - -#define LKC_DIRECT_LINK -#include "lkc.h" - -#define START_STRSIZE 16 - -static struct { - struct file *file; - int lineno; -} current_pos; - -static char *text; -static int text_size, text_asize; - -struct buffer { - struct buffer *parent; - YY_BUFFER_STATE state; -}; - -struct buffer *current_buf; - -static int last_ts, first_ts; - -static void zconf_endhelp(void); -static void zconf_endfile(void); - -void new_string(void) -{ - text = malloc(START_STRSIZE); - text_asize = START_STRSIZE; - text_size = 0; - *text = 0; -} - -void append_string(const char *str, int size) -{ - int new_size = text_size + size + 1; - if (new_size > text_asize) { - new_size += START_STRSIZE - 1; - new_size &= -START_STRSIZE; - text = realloc(text, new_size); - text_asize = new_size; - } - memcpy(text + text_size, str, size); - text_size += size; - text[text_size] = 0; -} - -void alloc_string(const char *str, int size) -{ - text = malloc(size + 1); - memcpy(text, str, size); - text[size] = 0; -} -%} - -ws [ \n\t] -n [A-Za-z0-9_] - -%% - int str = 0; - int ts, i; - -[ \t]*#.*\n | -[ \t]*\n { - current_file->lineno++; - return T_EOL; -} -[ \t]*#.* - - -[ \t]+ { - BEGIN(COMMAND); -} - -. { - unput(yytext[0]); - BEGIN(COMMAND); -} - - -{ - {n}+ { - struct kconf_id *id = kconf_id_lookup(yytext, yyleng); - BEGIN(PARAM); - current_pos.file = current_file; - current_pos.lineno = current_file->lineno; - if (id && id->flags & TF_COMMAND) { - zconflval.id = id; - return id->token; - } - alloc_string(yytext, yyleng); - zconflval.string = text; - return T_WORD; - } - . - \n { - BEGIN(INITIAL); - current_file->lineno++; - return T_EOL; - } -} - -{ - "&&" return T_AND; - "||" return T_OR; - "(" return T_OPEN_PAREN; - ")" return T_CLOSE_PAREN; - "!" return T_NOT; - "=" return T_EQUAL; - "!=" return T_UNEQUAL; - \"|\' { - str = yytext[0]; - new_string(); - BEGIN(STRING); - } - \n BEGIN(INITIAL); current_file->lineno++; return T_EOL; - --- /* ignore */ - ({n}|[-/.])+ { - struct kconf_id *id = kconf_id_lookup(yytext, yyleng); - if (id && id->flags & TF_PARAM) { - zconflval.id = id; - return id->token; - } - alloc_string(yytext, yyleng); - zconflval.string = text; - return T_WORD; - } - #.* /* comment */ - \\\n current_file->lineno++; - . - <> { - BEGIN(INITIAL); - } -} - -{ - [^'"\\\n]+/\n { - append_string(yytext, yyleng); - zconflval.string = text; - return T_WORD_QUOTE; - } - [^'"\\\n]+ { - append_string(yytext, yyleng); - } - \\.?/\n { - append_string(yytext + 1, yyleng - 1); - zconflval.string = text; - return T_WORD_QUOTE; - } - \\.? { - append_string(yytext + 1, yyleng - 1); - } - \'|\" { - if (str == yytext[0]) { - BEGIN(PARAM); - zconflval.string = text; - return T_WORD_QUOTE; - } else - append_string(yytext, 1); - } - \n { - printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); - current_file->lineno++; - BEGIN(INITIAL); - return T_EOL; - } - <> { - BEGIN(INITIAL); - } -} - -{ - [ \t]+ { - ts = 0; - for (i = 0; i < yyleng; i++) { - if (yytext[i] == '\t') - ts = (ts & ~7) + 8; - else - ts++; - } - last_ts = ts; - if (first_ts) { - if (ts < first_ts) { - zconf_endhelp(); - return T_HELPTEXT; - } - ts -= first_ts; - while (ts > 8) { - append_string(" ", 8); - ts -= 8; - } - append_string(" ", ts); - } - } - [ \t]*\n/[^ \t\n] { - current_file->lineno++; - zconf_endhelp(); - return T_HELPTEXT; - } - [ \t]*\n { - current_file->lineno++; - append_string("\n", 1); - } - [^ \t\n].* { - while (yyleng) { - if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t')) - break; - yyleng--; - } - append_string(yytext, yyleng); - if (!first_ts) - first_ts = last_ts; - } - <> { - zconf_endhelp(); - return T_HELPTEXT; - } -} - -<> { - if (current_file) { - zconf_endfile(); - return T_EOL; - } - fclose(yyin); - yyterminate(); -} - -%% -void zconf_starthelp(void) -{ - new_string(); - last_ts = first_ts = 0; - BEGIN(HELP); -} - -static void zconf_endhelp(void) -{ - zconflval.string = text; - BEGIN(INITIAL); -} - - -/* - * Try to open specified file with following names: - * ./name - * $(srctree)/name - * The latter is used when srctree is separate from objtree - * when compiling the kernel. - * Return NULL if file is not found. - */ -FILE *zconf_fopen(const char *name) -{ - char *env, fullname[PATH_MAX+1]; - FILE *f; - - f = fopen(name, "r"); - if (!f && name != NULL && name[0] != '/') { - env = getenv(SRCTREE); - if (env) { - sprintf(fullname, "%s/%s", env, name); - f = fopen(fullname, "r"); - } - } - return f; -} - -void zconf_initscan(const char *name) -{ - yyin = zconf_fopen(name); - if (!yyin) { - printf("can't find file %s\n", name); - exit(1); - } - - current_buf = malloc(sizeof(*current_buf)); - memset(current_buf, 0, sizeof(*current_buf)); - - current_file = file_lookup(name); - current_file->lineno = 1; - current_file->flags = FILE_BUSY; -} - -void zconf_nextfile(const char *name) -{ - struct file *file = file_lookup(name); - struct buffer *buf = malloc(sizeof(*buf)); - memset(buf, 0, sizeof(*buf)); - - current_buf->state = YY_CURRENT_BUFFER; - yyin = zconf_fopen(name); - if (!yyin) { - printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); - exit(1); - } - yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); - buf->parent = current_buf; - current_buf = buf; - - if (file->flags & FILE_BUSY) { - printf("%s:%d: do not source '%s' from itself\n", - zconf_curname(), zconf_lineno(), name); - exit(1); - } - if (file->flags & FILE_SCANNED) { - printf("%s:%d: file '%s' is already sourced from '%s'\n", - zconf_curname(), zconf_lineno(), name, - file->parent->name); - exit(1); - } - file->flags |= FILE_BUSY; - file->lineno = 1; - file->parent = current_file; - current_file = file; -} - -static void zconf_endfile(void) -{ - struct buffer *parent; - - current_file->flags |= FILE_SCANNED; - current_file->flags &= ~FILE_BUSY; - current_file = current_file->parent; - - parent = current_buf->parent; - if (parent) { - fclose(yyin); - yy_delete_buffer(YY_CURRENT_BUFFER); - yy_switch_to_buffer(parent->state); - } - free(current_buf); - current_buf = parent; -} - -int zconf_lineno(void) -{ - return current_pos.lineno; -} - -char *zconf_curname(void) -{ - return current_pos.file ? current_pos.file->name : ""; -} diff --git a/config/zconf.tab.c_shipped b/config/zconf.tab.c_shipped deleted file mode 100644 index 3bdcb3a97..000000000 --- a/config/zconf.tab.c_shipped +++ /dev/null @@ -1,2490 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.3. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.3" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - -/* Substitute the variable and function names. */ -#define yyparse zconfparse -#define yylex zconflex -#define yyerror zconferror -#define yylval zconflval -#define yychar zconfchar -#define yydebug zconfdebug -#define yynerrs zconfnerrs - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - T_MAINMENU = 258, - T_MENU = 259, - T_ENDMENU = 260, - T_SOURCE = 261, - T_CHOICE = 262, - T_ENDCHOICE = 263, - T_COMMENT = 264, - T_CONFIG = 265, - T_MENUCONFIG = 266, - T_HELP = 267, - T_HELPTEXT = 268, - T_IF = 269, - T_ENDIF = 270, - T_DEPENDS = 271, - T_OPTIONAL = 272, - T_PROMPT = 273, - T_TYPE = 274, - T_DEFAULT = 275, - T_SELECT = 276, - T_RANGE = 277, - T_OPTION = 278, - T_ON = 279, - T_WORD = 280, - T_WORD_QUOTE = 281, - T_UNEQUAL = 282, - T_CLOSE_PAREN = 283, - T_OPEN_PAREN = 284, - T_EOL = 285, - T_OR = 286, - T_AND = 287, - T_EQUAL = 288, - T_NOT = 289 - }; -#endif -/* Tokens. */ -#define T_MAINMENU 258 -#define T_MENU 259 -#define T_ENDMENU 260 -#define T_SOURCE 261 -#define T_CHOICE 262 -#define T_ENDCHOICE 263 -#define T_COMMENT 264 -#define T_CONFIG 265 -#define T_MENUCONFIG 266 -#define T_HELP 267 -#define T_HELPTEXT 268 -#define T_IF 269 -#define T_ENDIF 270 -#define T_DEPENDS 271 -#define T_OPTIONAL 272 -#define T_PROMPT 273 -#define T_TYPE 274 -#define T_DEFAULT 275 -#define T_SELECT 276 -#define T_RANGE 277 -#define T_OPTION 278 -#define T_ON 279 -#define T_WORD 280 -#define T_WORD_QUOTE 281 -#define T_UNEQUAL 282 -#define T_CLOSE_PAREN 283 -#define T_OPEN_PAREN 284 -#define T_EOL 285 -#define T_OR 286 -#define T_AND 287 -#define T_EQUAL 288 -#define T_NOT 289 - - - - -/* Copy the first part of user declarations. */ - - -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - */ - -#include -#include -#include -#include -#include -#include - -#define LKC_DIRECT_LINK -#include "lkc.h" - -#include "zconf.hash.c" - -#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) - -#define PRINTD 0x0001 -#define DEBUG_PARSE 0x0002 - -int cdebug = PRINTD; - -extern int zconflex(void); -static void zconfprint(const char *err, ...); -static void zconf_error(const char *err, ...); -static void zconferror(const char *err); -static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); - -struct symbol *symbol_hash[257]; - -static struct menu *current_menu, *current_entry; - -#define YYDEBUG 0 -#if YYDEBUG -#define YYERROR_VERBOSE -#endif - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE - -{ - char *string; - struct file *file; - struct symbol *symbol; - struct expr *expr; - struct menu *menu; - struct kconf_id *id; -} -/* Line 187 of yacc.c. */ - - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ - - -/* Line 216 of yacc.c. */ - - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int i) -#else -static int -YYID (i) - int i; -#endif -{ - return i; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 3 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 259 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 35 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 46 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 110 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 180 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 289 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 5, 6, 9, 12, 15, 20, 23, - 28, 33, 37, 39, 41, 43, 45, 47, 49, 51, - 53, 55, 57, 59, 61, 63, 67, 70, 74, 77, - 81, 84, 85, 88, 91, 94, 97, 100, 103, 107, - 112, 117, 122, 128, 132, 133, 137, 138, 141, 145, - 148, 150, 154, 155, 158, 161, 164, 167, 170, 175, - 179, 182, 187, 188, 191, 195, 197, 201, 202, 205, - 208, 211, 215, 218, 220, 224, 225, 228, 231, 234, - 238, 242, 245, 248, 251, 252, 255, 258, 261, 266, - 267, 270, 272, 274, 277, 280, 283, 285, 288, 289, - 292, 294, 298, 302, 306, 309, 313, 317, 319, 321, - 322 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 36, 0, -1, 37, -1, -1, 37, 39, -1, 37, - 53, -1, 37, 64, -1, 37, 3, 74, 76, -1, - 37, 75, -1, 37, 25, 1, 30, -1, 37, 38, - 1, 30, -1, 37, 1, 30, -1, 16, -1, 18, - -1, 19, -1, 21, -1, 17, -1, 22, -1, 20, - -1, 30, -1, 59, -1, 68, -1, 42, -1, 44, - -1, 66, -1, 25, 1, 30, -1, 1, 30, -1, - 10, 25, 30, -1, 41, 45, -1, 11, 25, 30, - -1, 43, 45, -1, -1, 45, 46, -1, 45, 47, - -1, 45, 72, -1, 45, 70, -1, 45, 40, -1, - 45, 30, -1, 19, 73, 30, -1, 18, 74, 77, - 30, -1, 20, 78, 77, 30, -1, 21, 25, 77, - 30, -1, 22, 79, 79, 77, 30, -1, 23, 48, - 30, -1, -1, 48, 25, 49, -1, -1, 33, 74, - -1, 7, 80, 30, -1, 50, 54, -1, 75, -1, - 51, 56, 52, -1, -1, 54, 55, -1, 54, 72, - -1, 54, 70, -1, 54, 30, -1, 54, 40, -1, - 18, 74, 77, 30, -1, 19, 73, 30, -1, 17, - 30, -1, 20, 25, 77, 30, -1, -1, 56, 39, - -1, 14, 78, 76, -1, 75, -1, 57, 60, 58, - -1, -1, 60, 39, -1, 60, 64, -1, 60, 53, - -1, 4, 74, 30, -1, 61, 71, -1, 75, -1, - 62, 65, 63, -1, -1, 65, 39, -1, 65, 64, - -1, 65, 53, -1, 6, 74, 30, -1, 9, 74, - 30, -1, 67, 71, -1, 12, 30, -1, 69, 13, - -1, -1, 71, 72, -1, 71, 30, -1, 71, 40, - -1, 16, 24, 78, 30, -1, -1, 74, 77, -1, - 25, -1, 26, -1, 5, 30, -1, 8, 30, -1, - 15, 30, -1, 30, -1, 76, 30, -1, -1, 14, - 78, -1, 79, -1, 79, 33, 79, -1, 79, 27, - 79, -1, 29, 78, 28, -1, 34, 78, -1, 78, - 31, 78, -1, 78, 32, 78, -1, 25, -1, 26, - -1, -1, 25, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 104, 104, 106, 108, 109, 110, 111, 112, 113, - 114, 118, 122, 122, 122, 122, 122, 122, 122, 126, - 127, 128, 129, 130, 131, 135, 136, 142, 150, 156, - 164, 174, 176, 177, 178, 179, 180, 181, 184, 192, - 198, 208, 214, 220, 223, 225, 236, 237, 242, 251, - 256, 264, 267, 269, 270, 271, 272, 273, 276, 282, - 293, 299, 309, 311, 316, 324, 332, 335, 337, 338, - 339, 344, 351, 356, 364, 367, 369, 370, 371, 374, - 382, 389, 396, 402, 409, 411, 412, 413, 416, 424, - 426, 431, 432, 435, 436, 437, 441, 442, 445, 446, - 449, 450, 451, 452, 453, 454, 455, 458, 459, 462, - 463 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU", - "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG", - "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", - "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE", - "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", - "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL", - "T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt", - "option_error", "config_entry_start", "config_stmt", - "menuconfig_entry_start", "menuconfig_stmt", "config_option_list", - "config_option", "symbol_option", "symbol_option_list", - "symbol_option_arg", "choice", "choice_entry", "choice_end", - "choice_stmt", "choice_option_list", "choice_option", "choice_block", - "if_entry", "if_end", "if_stmt", "if_block", "menu", "menu_entry", - "menu_end", "menu_stmt", "menu_block", "source_stmt", "comment", - "comment_stmt", "help_start", "help", "depends_list", "depends", - "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", "symbol", - "word_opt", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 35, 36, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 38, 38, 38, 38, 38, 38, 38, 39, - 39, 39, 39, 39, 39, 40, 40, 41, 42, 43, - 44, 45, 45, 45, 45, 45, 45, 45, 46, 46, - 46, 46, 46, 47, 48, 48, 49, 49, 50, 51, - 52, 53, 54, 54, 54, 54, 54, 54, 55, 55, - 55, 55, 56, 56, 57, 58, 59, 60, 60, 60, - 60, 61, 62, 63, 64, 65, 65, 65, 65, 66, - 67, 68, 69, 70, 71, 71, 71, 71, 72, 73, - 73, 74, 74, 75, 75, 75, 76, 76, 77, 77, - 78, 78, 78, 78, 78, 78, 78, 79, 79, 80, - 80 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 0, 2, 2, 2, 4, 2, 4, - 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 2, 3, 2, 3, - 2, 0, 2, 2, 2, 2, 2, 2, 3, 4, - 4, 4, 5, 3, 0, 3, 0, 2, 3, 2, - 1, 3, 0, 2, 2, 2, 2, 2, 4, 3, - 2, 4, 0, 2, 3, 1, 3, 0, 2, 2, - 2, 3, 2, 1, 3, 0, 2, 2, 2, 3, - 3, 2, 2, 2, 0, 2, 2, 2, 4, 0, - 2, 1, 1, 2, 2, 2, 1, 2, 0, 2, - 1, 3, 3, 3, 2, 3, 3, 1, 1, 0, - 1 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 3, 0, 0, 1, 0, 0, 0, 0, 0, 109, - 0, 0, 0, 0, 0, 0, 12, 16, 13, 14, - 18, 15, 17, 0, 19, 0, 4, 31, 22, 31, - 23, 52, 62, 5, 67, 20, 84, 75, 6, 24, - 84, 21, 8, 11, 91, 92, 0, 0, 93, 0, - 110, 0, 94, 0, 0, 0, 107, 108, 0, 0, - 0, 100, 95, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 96, 7, 71, 79, 48, 80, 27, - 29, 0, 104, 0, 0, 64, 0, 0, 9, 10, - 0, 0, 0, 0, 89, 0, 0, 0, 44, 0, - 37, 36, 32, 33, 0, 35, 34, 0, 0, 89, - 0, 56, 57, 53, 55, 54, 63, 51, 50, 68, - 70, 66, 69, 65, 86, 87, 85, 76, 78, 74, - 77, 73, 97, 103, 105, 106, 102, 101, 26, 82, - 0, 98, 0, 98, 98, 98, 0, 0, 0, 83, - 60, 98, 0, 98, 0, 0, 0, 38, 90, 0, - 0, 98, 46, 43, 25, 0, 59, 0, 88, 99, - 39, 40, 41, 0, 0, 45, 58, 61, 42, 47 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 1, 2, 25, 26, 101, 27, 28, 29, 30, - 65, 102, 103, 147, 175, 31, 32, 117, 33, 67, - 113, 68, 34, 121, 35, 69, 36, 37, 129, 38, - 71, 39, 40, 41, 104, 105, 70, 106, 142, 143, - 42, 74, 156, 60, 61, 51 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -80 -static const yytype_int16 yypact[] = -{ - -80, 2, 132, -80, -13, -1, -1, -2, -1, 9, - 33, -1, 27, 40, -3, 38, -80, -80, -80, -80, - -80, -80, -80, 71, -80, 77, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, 57, 61, -80, 63, - -80, 76, -80, 87, 101, 133, -80, -80, -3, -3, - 195, -6, -80, 136, 149, 39, 104, 65, 150, 5, - 194, 5, 167, -80, 176, -80, -80, -80, -80, -80, - -80, 68, -80, -3, -3, 176, 72, 72, -80, -80, - 177, 187, 78, -1, -1, -3, 196, 72, -80, 222, - -80, -80, -80, -80, 221, -80, -80, 205, -1, -1, - 211, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, 206, -80, -80, -80, -80, -80, - -3, 223, 209, 223, 197, 223, 72, 7, 210, -80, - -80, 223, 212, 223, 201, -3, 213, -80, -80, 214, - 215, 223, 208, -80, -80, 216, -80, 217, -80, 113, - -80, -80, -80, 218, -1, -80, -80, -80, -80, -80 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -80, -80, -80, -80, 122, -34, -80, -80, -80, -80, - 220, -80, -80, -80, -80, -80, -80, -80, 59, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, 125, - -80, -80, -80, -80, -80, 183, 219, 22, 142, -5, - 147, 192, 69, -54, -79, -80 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -82 -static const yytype_int16 yytable[] = -{ - 46, 47, 3, 49, 81, 82, 53, 136, 137, 6, - 7, 8, 9, 10, 11, 12, 13, 43, 146, 14, - 15, 86, 56, 57, 44, 45, 58, 87, 48, 134, - 135, 59, 162, 112, 50, 24, 125, 163, 125, -28, - 90, 144, -28, -28, -28, -28, -28, -28, -28, -28, - -28, 91, 54, -28, -28, 92, -28, 93, 94, 95, - 96, 97, 98, 52, 99, 55, 90, 161, 62, 100, - -49, -49, 63, -49, -49, -49, -49, 91, 64, -49, - -49, 92, 107, 108, 109, 110, 154, 73, 141, 115, - 99, 75, 126, 76, 126, 111, 133, 56, 57, 83, - 84, 169, 140, 151, -30, 90, 77, -30, -30, -30, - -30, -30, -30, -30, -30, -30, 91, 78, -30, -30, - 92, -30, 93, 94, 95, 96, 97, 98, 120, 99, - 128, 79, -2, 4, 100, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 83, 84, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 7, 8, 23, 10, 11, - 12, 13, 24, 80, 14, 15, 88, -81, 90, 179, - -81, -81, -81, -81, -81, -81, -81, -81, -81, 89, - 24, -81, -81, 92, -81, -81, -81, -81, -81, -81, - 116, 119, 99, 127, 122, 90, 130, 124, -72, -72, - -72, -72, -72, -72, -72, -72, 132, 138, -72, -72, - 92, 155, 158, 159, 160, 118, 123, 139, 131, 99, - 165, 145, 167, 148, 124, 73, 83, 84, 83, 84, - 173, 168, 83, 84, 149, 150, 153, 155, 84, 157, - 164, 174, 166, 170, 171, 172, 176, 177, 178, 66, - 114, 152, 85, 0, 0, 0, 0, 0, 0, 72 -}; - -static const yytype_int16 yycheck[] = -{ - 5, 6, 0, 8, 58, 59, 11, 86, 87, 4, - 5, 6, 7, 8, 9, 10, 11, 30, 97, 14, - 15, 27, 25, 26, 25, 26, 29, 33, 30, 83, - 84, 34, 25, 67, 25, 30, 70, 30, 72, 0, - 1, 95, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 25, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 30, 25, 25, 1, 146, 30, 30, - 5, 6, 1, 8, 9, 10, 11, 12, 1, 14, - 15, 16, 17, 18, 19, 20, 140, 30, 93, 67, - 25, 30, 70, 30, 72, 30, 28, 25, 26, 31, - 32, 155, 24, 108, 0, 1, 30, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 30, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 69, 25, - 71, 30, 0, 1, 30, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 31, 32, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 5, 6, 25, 8, 9, - 10, 11, 30, 30, 14, 15, 30, 0, 1, 174, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 30, - 30, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 68, 69, 25, 71, 69, 1, 71, 30, 4, 5, - 6, 7, 8, 9, 10, 11, 30, 30, 14, 15, - 16, 14, 143, 144, 145, 68, 69, 30, 71, 25, - 151, 25, 153, 1, 30, 30, 31, 32, 31, 32, - 161, 30, 31, 32, 13, 30, 25, 14, 32, 30, - 30, 33, 30, 30, 30, 30, 30, 30, 30, 29, - 67, 109, 60, -1, -1, -1, -1, -1, -1, 40 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 36, 37, 0, 1, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 25, 30, 38, 39, 41, 42, 43, - 44, 50, 51, 53, 57, 59, 61, 62, 64, 66, - 67, 68, 75, 30, 25, 26, 74, 74, 30, 74, - 25, 80, 30, 74, 25, 25, 25, 26, 29, 34, - 78, 79, 30, 1, 1, 45, 45, 54, 56, 60, - 71, 65, 71, 30, 76, 30, 30, 30, 30, 30, - 30, 78, 78, 31, 32, 76, 27, 33, 30, 30, - 1, 12, 16, 18, 19, 20, 21, 22, 23, 25, - 30, 40, 46, 47, 69, 70, 72, 17, 18, 19, - 20, 30, 40, 55, 70, 72, 39, 52, 75, 39, - 53, 58, 64, 75, 30, 40, 72, 39, 53, 63, - 64, 75, 30, 28, 78, 78, 79, 79, 30, 30, - 24, 74, 73, 74, 78, 25, 79, 48, 1, 13, - 30, 74, 73, 25, 78, 14, 77, 30, 77, 77, - 77, 79, 25, 30, 30, 77, 30, 77, 30, 78, - 30, 30, 30, 77, 33, 49, 30, 30, 30, 74 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) -#else -static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) -#else -static void -yy_reduce_print (yyvsp, yyrule) - YYSTYPE *yyvsp; - int yyrule; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - fprintf (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); - fprintf (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - YYUSE (yyvaluep); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - case 51: /* "choice_entry" */ - - { - fprintf(stderr, "%s:%d: missing end statement for this entry\n", - (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); - if (current_menu == (yyvaluep->menu)) - menu_end_menu(); -}; - - break; - case 57: /* "if_entry" */ - - { - fprintf(stderr, "%s:%d: missing end statement for this entry\n", - (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); - if (current_menu == (yyvaluep->menu)) - menu_end_menu(); -}; - - break; - case 62: /* "menu_entry" */ - - { - fprintf(stderr, "%s:%d: missing end statement for this entry\n", - (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); - if (current_menu == (yyvaluep->menu)) - menu_end_menu(); -}; - - break; - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - -/* The look-ahead symbol. */ -int yychar; - -/* The semantic value of the look-ahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void) -#else -int -yyparse () - -#endif -#endif -{ - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; - - - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to look-ahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a look-ahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - if (yyn == YYFINAL) - YYACCEPT; - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the look-ahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 8: - - { zconf_error("unexpected end statement"); ;} - break; - - case 9: - - { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); ;} - break; - - case 10: - - { - zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[(2) - (4)].id)->name); -;} - break; - - case 11: - - { zconf_error("invalid statement"); ;} - break; - - case 25: - - { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;} - break; - - case 26: - - { zconf_error("invalid option"); ;} - break; - - case 27: - - { - struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); - sym->flags |= SYMBOL_OPTIONAL; - menu_add_entry(sym); - printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); -;} - break; - - case 28: - - { - menu_end_entry(); - printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 29: - - { - struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); - sym->flags |= SYMBOL_OPTIONAL; - menu_add_entry(sym); - printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); -;} - break; - - case 30: - - { - if (current_entry->prompt) - current_entry->prompt->type = P_MENU; - else - zconfprint("warning: menuconfig statement without prompt"); - menu_end_entry(); - printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 38: - - { - menu_set_type((yyvsp[(1) - (3)].id)->stype); - printd(DEBUG_PARSE, "%s:%d:type(%u)\n", - zconf_curname(), zconf_lineno(), - (yyvsp[(1) - (3)].id)->stype); -;} - break; - - case 39: - - { - menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); - printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 40: - - { - menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr)); - if ((yyvsp[(1) - (4)].id)->stype != S_UNKNOWN) - menu_set_type((yyvsp[(1) - (4)].id)->stype); - printd(DEBUG_PARSE, "%s:%d:default(%u)\n", - zconf_curname(), zconf_lineno(), - (yyvsp[(1) - (4)].id)->stype); -;} - break; - - case 41: - - { - menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); - printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 42: - - { - menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr)); - printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 45: - - { - struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string))); - if (id && id->flags & TF_OPTION) - menu_add_option(id->token, (yyvsp[(3) - (3)].string)); - else - zconfprint("warning: ignoring unknown option %s", (yyvsp[(2) - (3)].string)); - free((yyvsp[(2) - (3)].string)); -;} - break; - - case 46: - - { (yyval.string) = NULL; ;} - break; - - case 47: - - { (yyval.string) = (yyvsp[(2) - (2)].string); ;} - break; - - case 48: - - { - struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE); - sym->flags |= SYMBOL_AUTO; - menu_add_entry(sym); - menu_add_expr(P_CHOICE, NULL, NULL); - printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 49: - - { - (yyval.menu) = menu_add_menu(); -;} - break; - - case 50: - - { - if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) { - menu_end_menu(); - printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); - } -;} - break; - - case 58: - - { - menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); - printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 59: - - { - if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) { - menu_set_type((yyvsp[(1) - (3)].id)->stype); - printd(DEBUG_PARSE, "%s:%d:type(%u)\n", - zconf_curname(), zconf_lineno(), - (yyvsp[(1) - (3)].id)->stype); - } else - YYERROR; -;} - break; - - case 60: - - { - current_entry->sym->flags |= SYMBOL_OPTIONAL; - printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 61: - - { - if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) { - menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); - printd(DEBUG_PARSE, "%s:%d:default\n", - zconf_curname(), zconf_lineno()); - } else - YYERROR; -;} - break; - - case 64: - - { - printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); - menu_add_entry(NULL); - menu_add_dep((yyvsp[(2) - (3)].expr)); - (yyval.menu) = menu_add_menu(); -;} - break; - - case 65: - - { - if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) { - menu_end_menu(); - printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); - } -;} - break; - - case 71: - - { - menu_add_entry(NULL); - menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL); - printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 72: - - { - (yyval.menu) = menu_add_menu(); -;} - break; - - case 73: - - { - if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) { - menu_end_menu(); - printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); - } -;} - break; - - case 79: - - { - printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); - zconf_nextfile((yyvsp[(2) - (3)].string)); -;} - break; - - case 80: - - { - menu_add_entry(NULL); - menu_add_prompt(P_COMMENT, (yyvsp[(2) - (3)].string), NULL); - printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 81: - - { - menu_end_entry(); -;} - break; - - case 82: - - { - printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); - zconf_starthelp(); -;} - break; - - case 83: - - { - current_entry->help = (yyvsp[(2) - (2)].string); -;} - break; - - case 88: - - { - menu_add_dep((yyvsp[(3) - (4)].expr)); - printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 90: - - { - menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr)); -;} - break; - - case 93: - - { (yyval.id) = (yyvsp[(1) - (2)].id); ;} - break; - - case 94: - - { (yyval.id) = (yyvsp[(1) - (2)].id); ;} - break; - - case 95: - - { (yyval.id) = (yyvsp[(1) - (2)].id); ;} - break; - - case 98: - - { (yyval.expr) = NULL; ;} - break; - - case 99: - - { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;} - break; - - case 100: - - { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;} - break; - - case 101: - - { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} - break; - - case 102: - - { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} - break; - - case 103: - - { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;} - break; - - case 104: - - { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;} - break; - - case 105: - - { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} - break; - - case 106: - - { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} - break; - - case 107: - - { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;} - break; - - case 108: - - { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;} - break; - - case 109: - - { (yyval.string) = NULL; ;} - break; - - -/* Line 1267 of yacc.c. */ - - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (yymsg); - } - else - { - yyerror (YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse look-ahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse look-ahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - if (yyn == YYFINAL) - YYACCEPT; - - *++yyvsp = yylval; - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - - - - -void conf_parse(const char *name) -{ - struct symbol *sym; - int i; - - zconf_initscan(name); - - sym_init(); - menu_init(); - modules_sym = sym_lookup(NULL, 0); - modules_sym->type = S_BOOLEAN; - modules_sym->flags |= SYMBOL_AUTO; - rootmenu.prompt = menu_add_prompt(P_MENU, "OpenADK Configuration", NULL); - -#if YYDEBUG - if (getenv("ZCONF_DEBUG")) - zconfdebug = 1; -#endif - zconfparse(); - if (zconfnerrs) - exit(1); - if (!modules_sym->prop) { - struct property *prop; - - prop = prop_alloc(P_DEFAULT, modules_sym); - prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); - } - menu_finalize(&rootmenu); - for_all_symbols(i, sym) { - if (sym_check_deps(sym)) - zconfnerrs++; - } - if (zconfnerrs) - exit(1); - sym_set_change_count(1); -} - -const char *zconf_tokenname(int token) -{ - switch (token) { - case T_MENU: return "menu"; - case T_ENDMENU: return "endmenu"; - case T_CHOICE: return "choice"; - case T_ENDCHOICE: return "endchoice"; - case T_IF: return "if"; - case T_ENDIF: return "endif"; - case T_DEPENDS: return "depends"; - } - return ""; -} - -static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken) -{ - if (id->token != endtoken) { - zconf_error("unexpected '%s' within %s block", - kconf_id_strings + id->name, zconf_tokenname(starttoken)); - zconfnerrs++; - return false; - } - if (current_menu->file != current_file) { - zconf_error("'%s' in different file than '%s'", - kconf_id_strings + id->name, zconf_tokenname(starttoken)); - fprintf(stderr, "%s:%d: location of the '%s'\n", - current_menu->file->name, current_menu->lineno, - zconf_tokenname(starttoken)); - zconfnerrs++; - return false; - } - return true; -} - -static void zconfprint(const char *err, ...) -{ - va_list ap; - - fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); - va_start(ap, err); - vfprintf(stderr, err, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - -static void zconf_error(const char *err, ...) -{ - va_list ap; - - zconfnerrs++; - fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); - va_start(ap, err); - vfprintf(stderr, err, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - -static void zconferror(const char *err) -{ -#if YYDEBUG - fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); -#endif -} - -void print_quoted_string(FILE *out, const char *str) -{ - const char *p; - int len; - - putc('"', out); - while ((p = strchr(str, '"'))) { - len = p - str; - if (len) - fprintf(out, "%.*s", len, str); - fputs("\\\"", out); - str = p + 1; - } - fputs(str, out); - putc('"', out); -} - -void print_symbol(FILE *out, struct menu *menu) -{ - struct symbol *sym = menu->sym; - struct property *prop; - - if (sym_is_choice(sym)) - fprintf(out, "choice\n"); - else - fprintf(out, "config %s\n", sym->name); - switch (sym->type) { - case S_BOOLEAN: - fputs(" boolean\n", out); - break; - case S_TRISTATE: - fputs(" tristate\n", out); - break; - case S_STRING: - fputs(" string\n", out); - break; - case S_INT: - fputs(" integer\n", out); - break; - case S_HEX: - fputs(" hex\n", out); - break; - default: - fputs(" ???\n", out); - break; - } - for (prop = sym->prop; prop; prop = prop->next) { - if (prop->menu != menu) - continue; - switch (prop->type) { - case P_PROMPT: - fputs(" prompt ", out); - print_quoted_string(out, prop->text); - if (!expr_is_yes(prop->visible.expr)) { - fputs(" if ", out); - expr_fprint(prop->visible.expr, out); - } - fputc('\n', out); - break; - case P_DEFAULT: - fputs( " default ", out); - expr_fprint(prop->expr, out); - if (!expr_is_yes(prop->visible.expr)) { - fputs(" if ", out); - expr_fprint(prop->visible.expr, out); - } - fputc('\n', out); - break; - case P_CHOICE: - fputs(" #choice value\n", out); - break; - default: - fprintf(out, " unknown prop %d!\n", prop->type); - break; - } - } - if (menu->help) { - int len = strlen(menu->help); - while (menu->help[--len] == '\n') - menu->help[len] = 0; - fprintf(out, " help\n%s\n", menu->help); - } - fputc('\n', out); -} - -void zconfdump(FILE *out) -{ - struct property *prop; - struct symbol *sym; - struct menu *menu; - - menu = rootmenu.list; - while (menu) { - if ((sym = menu->sym)) - print_symbol(out, menu); - else if ((prop = menu->prompt)) { - switch (prop->type) { - case P_COMMENT: - fputs("\ncomment ", out); - print_quoted_string(out, prop->text); - fputs("\n", out); - break; - case P_MENU: - fputs("\nmenu ", out); - print_quoted_string(out, prop->text); - fputs("\n", out); - break; - default: - ; - } - if (!expr_is_yes(prop->visible.expr)) { - fputs(" depends ", out); - expr_fprint(prop->visible.expr, out); - fputc('\n', out); - } - fputs("\n", out); - } - - if (menu->list) - menu = menu->list; - else if (menu->next) - menu = menu->next; - else while ((menu = menu->parent)) { - if (menu->prompt && menu->prompt->type == P_MENU) - fputs("\nendmenu\n", out); - if (menu->next) { - menu = menu->next; - break; - } - } - } -} - -#include "lex.zconf.c" -#include "util.c" -#include "confdata.c" -#include "expr.c" -#include "symbol.c" -#include "menu.c" - diff --git a/config/zconf.tab.h_shipped b/config/zconf.tab.h_shipped deleted file mode 100644 index 1b17df414..000000000 --- a/config/zconf.tab.h_shipped +++ /dev/null @@ -1,133 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.3. */ - -/* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - T_MAINMENU = 258, - T_MENU = 259, - T_ENDMENU = 260, - T_SOURCE = 261, - T_CHOICE = 262, - T_ENDCHOICE = 263, - T_COMMENT = 264, - T_CONFIG = 265, - T_MENUCONFIG = 266, - T_HELP = 267, - T_HELPTEXT = 268, - T_IF = 269, - T_ENDIF = 270, - T_DEPENDS = 271, - T_OPTIONAL = 272, - T_PROMPT = 273, - T_TYPE = 274, - T_DEFAULT = 275, - T_SELECT = 276, - T_RANGE = 277, - T_OPTION = 278, - T_ON = 279, - T_WORD = 280, - T_WORD_QUOTE = 281, - T_UNEQUAL = 282, - T_CLOSE_PAREN = 283, - T_OPEN_PAREN = 284, - T_EOL = 285, - T_OR = 286, - T_AND = 287, - T_EQUAL = 288, - T_NOT = 289 - }; -#endif -/* Tokens. */ -#define T_MAINMENU 258 -#define T_MENU 259 -#define T_ENDMENU 260 -#define T_SOURCE 261 -#define T_CHOICE 262 -#define T_ENDCHOICE 263 -#define T_COMMENT 264 -#define T_CONFIG 265 -#define T_MENUCONFIG 266 -#define T_HELP 267 -#define T_HELPTEXT 268 -#define T_IF 269 -#define T_ENDIF 270 -#define T_DEPENDS 271 -#define T_OPTIONAL 272 -#define T_PROMPT 273 -#define T_TYPE 274 -#define T_DEFAULT 275 -#define T_SELECT 276 -#define T_RANGE 277 -#define T_OPTION 278 -#define T_ON 279 -#define T_WORD 280 -#define T_WORD_QUOTE 281 -#define T_UNEQUAL 282 -#define T_CLOSE_PAREN 283 -#define T_OPEN_PAREN 284 -#define T_EOL 285 -#define T_OR 286 -#define T_AND 287 -#define T_EQUAL 288 -#define T_NOT 289 - - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -#line 44 "zconf.y" -{ - char *string; - struct file *file; - struct symbol *symbol; - struct expr *expr; - struct menu *menu; - struct kconf_id *id; -} -/* Line 1489 of yacc.c. */ -#line 126 "zconf.tab.h" - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE zconflval; - diff --git a/config/zconf.y b/config/zconf.y deleted file mode 100644 index b4240c846..000000000 --- a/config/zconf.y +++ /dev/null @@ -1,706 +0,0 @@ -%{ -/* - * Copyright (C) 2002 Roman Zippel - * Released under the terms of the GNU GPL v2.0. - */ - -#include -#include -#include -#include -#include -#include - -#define LKC_DIRECT_LINK -#include "lkc.h" - -#include "zconf.hash.c" - -#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) - -#define PRINTD 0x0001 -#define DEBUG_PARSE 0x0002 - -int cdebug = PRINTD; - -extern int zconflex(void); -static void zconfprint(const char *err, ...); -static void zconf_error(const char *err, ...); -static void zconferror(const char *err); -static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); - -struct symbol *symbol_hash[257]; - -static struct menu *current_menu, *current_entry; - -#define YYDEBUG 0 -#if YYDEBUG -#define YYERROR_VERBOSE -#endif -%} -%expect 26 - -%union -{ - char *string; - struct file *file; - struct symbol *symbol; - struct expr *expr; - struct menu *menu; - struct kconf_id *id; -} - -%token T_MAINMENU -%token T_MENU -%token T_ENDMENU -%token T_SOURCE -%token T_CHOICE -%token T_ENDCHOICE -%token T_COMMENT -%token T_CONFIG -%token T_MENUCONFIG -%token T_HELP -%token T_HELPTEXT -%token T_IF -%token T_ENDIF -%token T_DEPENDS -%token T_OPTIONAL -%token T_PROMPT -%token T_TYPE -%token T_DEFAULT -%token T_SELECT -%token T_RANGE -%token T_OPTION -%token T_ON -%token T_WORD -%token T_WORD_QUOTE -%token T_UNEQUAL -%token T_CLOSE_PAREN -%token T_OPEN_PAREN -%token T_EOL - -%left T_OR -%left T_AND -%left T_EQUAL T_UNEQUAL -%nonassoc T_NOT - -%type prompt -%type symbol -%type expr -%type if_expr -%type end -%type option_name -%type if_entry menu_entry choice_entry -%type symbol_option_arg word_opt - -%destructor { - fprintf(stderr, "%s:%d: missing end statement for this entry\n", - $$->file->name, $$->lineno); - if (current_menu == $$) - menu_end_menu(); -} if_entry menu_entry choice_entry - -%% -input: stmt_list; - -stmt_list: - /* empty */ - | stmt_list common_stmt - | stmt_list choice_stmt - | stmt_list menu_stmt - | stmt_list T_MAINMENU prompt nl - | stmt_list end { zconf_error("unexpected end statement"); } - | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } - | stmt_list option_name error T_EOL -{ - zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name); -} - | stmt_list error T_EOL { zconf_error("invalid statement"); } -; - -option_name: - T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT -; - -common_stmt: - T_EOL - | if_stmt - | comment_stmt - | config_stmt - | menuconfig_stmt - | source_stmt -; - -option_error: - T_WORD error T_EOL { zconf_error("unknown option \"%s\"", $1); } - | error T_EOL { zconf_error("invalid option"); } -; - - -/* config/menuconfig entry */ - -config_entry_start: T_CONFIG T_WORD T_EOL -{ - struct symbol *sym = sym_lookup($2, 0); - sym->flags |= SYMBOL_OPTIONAL; - menu_add_entry(sym); - printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2); -}; - -config_stmt: config_entry_start config_option_list -{ - menu_end_entry(); - printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); -}; - -menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL -{ - struct symbol *sym = sym_lookup($2, 0); - sym->flags |= SYMBOL_OPTIONAL; - menu_add_entry(sym); - printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2); -}; - -menuconfig_stmt: menuconfig_entry_start config_option_list -{ - if (current_entry->prompt) - current_entry->prompt->type = P_MENU; - else - zconfprint("warning: menuconfig statement without prompt"); - menu_end_entry(); - printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); -}; - -config_option_list: - /* empty */ - | config_option_list config_option - | config_option_list symbol_option - | config_option_list depends - | config_option_list help - | config_option_list option_error - | config_option_list T_EOL -; - -config_option: T_TYPE prompt_stmt_opt T_EOL -{ - menu_set_type($1->stype); - printd(DEBUG_PARSE, "%s:%d:type(%u)\n", - zconf_curname(), zconf_lineno(), - $1->stype); -}; - -config_option: T_PROMPT prompt if_expr T_EOL -{ - menu_add_prompt(P_PROMPT, $2, $3); - printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); -}; - -config_option: T_DEFAULT expr if_expr T_EOL -{ - menu_add_expr(P_DEFAULT, $2, $3); - if ($1->stype != S_UNKNOWN) - menu_set_type($1->stype); - printd(DEBUG_PARSE, "%s:%d:default(%u)\n", - zconf_curname(), zconf_lineno(), - $1->stype); -}; - -config_option: T_SELECT T_WORD if_expr T_EOL -{ - menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3); - printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); -}; - -config_option: T_RANGE symbol symbol if_expr T_EOL -{ - menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); - printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); -}; - -symbol_option: T_OPTION symbol_option_list T_EOL -; - -symbol_option_list: - /* empty */ - | symbol_option_list T_WORD symbol_option_arg -{ - struct kconf_id *id = kconf_id_lookup($2, strlen($2)); - if (id && id->flags & TF_OPTION) - menu_add_option(id->token, $3); - else - zconfprint("warning: ignoring unknown option %s", $2); - free($2); -}; - -symbol_option_arg: - /* empty */ { $$ = NULL; } - | T_EQUAL prompt { $$ = $2; } -; - -/* choice entry */ - -choice: T_CHOICE word_opt T_EOL -{ - struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE); - sym->flags |= SYMBOL_AUTO; - menu_add_entry(sym); - menu_add_expr(P_CHOICE, NULL, NULL); - printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); -}; - -choice_entry: choice choice_option_list -{ - $$ = menu_add_menu(); -}; - -choice_end: end -{ - if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) { - menu_end_menu(); - printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); - } -}; - -choice_stmt: choice_entry choice_block choice_end -; - -choice_option_list: - /* empty */ - | choice_option_list choice_option - | choice_option_list depends - | choice_option_list help - | choice_option_list T_EOL - | choice_option_list option_error -; - -choice_option: T_PROMPT prompt if_expr T_EOL -{ - menu_add_prompt(P_PROMPT, $2, $3); - printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); -}; - -choice_option: T_TYPE prompt_stmt_opt T_EOL -{ - if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) { - menu_set_type($1->stype); - printd(DEBUG_PARSE, "%s:%d:type(%u)\n", - zconf_curname(), zconf_lineno(), - $1->stype); - } else - YYERROR; -}; - -choice_option: T_OPTIONAL T_EOL -{ - current_entry->sym->flags |= SYMBOL_OPTIONAL; - printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); -}; - -choice_option: T_DEFAULT T_WORD if_expr T_EOL -{ - if ($1->stype == S_UNKNOWN) { - menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); - printd(DEBUG_PARSE, "%s:%d:default\n", - zconf_curname(), zconf_lineno()); - } else - YYERROR; -}; - -choice_block: - /* empty */ - | choice_block common_stmt -; - -/* if entry */ - -if_entry: T_IF expr nl -{ - printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); - menu_add_entry(NULL); - menu_add_dep($2); - $$ = menu_add_menu(); -}; - -if_end: end -{ - if (zconf_endtoken($1, T_IF, T_ENDIF)) { - menu_end_menu(); - printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); - } -}; - -if_stmt: if_entry if_block if_end -; - -if_block: - /* empty */ - | if_block common_stmt - | if_block menu_stmt - | if_block choice_stmt -; - -/* menu entry */ - -menu: T_MENU prompt T_EOL -{ - menu_add_entry(NULL); - menu_add_prompt(P_MENU, $2, NULL); - printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); -}; - -menu_entry: menu depends_list -{ - $$ = menu_add_menu(); -}; - -menu_end: end -{ - if (zconf_endtoken($1, T_MENU, T_ENDMENU)) { - menu_end_menu(); - printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); - } -}; - -menu_stmt: menu_entry menu_block menu_end -; - -menu_block: - /* empty */ - | menu_block common_stmt - | menu_block menu_stmt - | menu_block choice_stmt -; - -source_stmt: T_SOURCE prompt T_EOL -{ - printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); - zconf_nextfile($2); -}; - -/* comment entry */ - -comment: T_COMMENT prompt T_EOL -{ - menu_add_entry(NULL); - menu_add_prompt(P_COMMENT, $2, NULL); - printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); -}; - -comment_stmt: comment depends_list -{ - menu_end_entry(); -}; - -/* help option */ - -help_start: T_HELP T_EOL -{ - printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); - zconf_starthelp(); -}; - -help: help_start T_HELPTEXT -{ - current_entry->help = $2; -}; - -/* depends option */ - -depends_list: - /* empty */ - | depends_list depends - | depends_list T_EOL - | depends_list option_error -; - -depends: T_DEPENDS T_ON expr T_EOL -{ - menu_add_dep($3); - printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); -}; - -/* prompt statement */ - -prompt_stmt_opt: - /* empty */ - | prompt if_expr -{ - menu_add_prompt(P_PROMPT, $1, $2); -}; - -prompt: T_WORD - | T_WORD_QUOTE -; - -end: T_ENDMENU T_EOL { $$ = $1; } - | T_ENDCHOICE T_EOL { $$ = $1; } - | T_ENDIF T_EOL { $$ = $1; } -; - -nl: - T_EOL - | nl T_EOL -; - -if_expr: /* empty */ { $$ = NULL; } - | T_IF expr { $$ = $2; } -; - -expr: symbol { $$ = expr_alloc_symbol($1); } - | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); } - | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } - | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; } - | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); } - | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); } - | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); } -; - -symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); } - | T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); } -; - -word_opt: /* empty */ { $$ = NULL; } - | T_WORD - -%% - -void conf_parse(const char *name) -{ - struct symbol *sym; - int i; - - zconf_initscan(name); - - sym_init(); - menu_init(); - modules_sym = sym_lookup(NULL, 0); - modules_sym->type = S_BOOLEAN; - modules_sym->flags |= SYMBOL_AUTO; - rootmenu.prompt = menu_add_prompt(P_MENU, "OpenADK Configuration", NULL); - -#if YYDEBUG - if (getenv("ZCONF_DEBUG")) - zconfdebug = 1; -#endif - zconfparse(); - if (zconfnerrs) - exit(1); - if (!modules_sym->prop) { - struct property *prop; - - prop = prop_alloc(P_DEFAULT, modules_sym); - prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); - } - menu_finalize(&rootmenu); - for_all_symbols(i, sym) { - if (sym_check_deps(sym)) - zconfnerrs++; - } - if (zconfnerrs) - exit(1); - sym_set_change_count(1); -} - -const char *zconf_tokenname(int token) -{ - switch (token) { - case T_MENU: return "menu"; - case T_ENDMENU: return "endmenu"; - case T_CHOICE: return "choice"; - case T_ENDCHOICE: return "endchoice"; - case T_IF: return "if"; - case T_ENDIF: return "endif"; - case T_DEPENDS: return "depends"; - } - return ""; -} - -static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken) -{ - if (id->token != endtoken) { - zconf_error("unexpected '%s' within %s block", - kconf_id_strings + id->name, zconf_tokenname(starttoken)); - zconfnerrs++; - return false; - } - if (current_menu->file != current_file) { - zconf_error("'%s' in different file than '%s'", - kconf_id_strings + id->name, zconf_tokenname(starttoken)); - fprintf(stderr, "%s:%d: location of the '%s'\n", - current_menu->file->name, current_menu->lineno, - zconf_tokenname(starttoken)); - zconfnerrs++; - return false; - } - return true; -} - -static void zconfprint(const char *err, ...) -{ - va_list ap; - - fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); - va_start(ap, err); - vfprintf(stderr, err, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - -static void zconf_error(const char *err, ...) -{ - va_list ap; - - zconfnerrs++; - fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); - va_start(ap, err); - vfprintf(stderr, err, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - -static void zconferror(const char *err) -{ -#if YYDEBUG - fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); -#endif -} - -void print_quoted_string(FILE *out, const char *str) -{ - const char *p; - int len; - - putc('"', out); - while ((p = strchr(str, '"'))) { - len = p - str; - if (len) - fprintf(out, "%.*s", len, str); - fputs("\\\"", out); - str = p + 1; - } - fputs(str, out); - putc('"', out); -} - -void print_symbol(FILE *out, struct menu *menu) -{ - struct symbol *sym = menu->sym; - struct property *prop; - - if (sym_is_choice(sym)) - fprintf(out, "choice\n"); - else - fprintf(out, "config %s\n", sym->name); - switch (sym->type) { - case S_BOOLEAN: - fputs(" boolean\n", out); - break; - case S_TRISTATE: - fputs(" tristate\n", out); - break; - case S_STRING: - fputs(" string\n", out); - break; - case S_INT: - fputs(" integer\n", out); - break; - case S_HEX: - fputs(" hex\n", out); - break; - default: - fputs(" ???\n", out); - break; - } - for (prop = sym->prop; prop; prop = prop->next) { - if (prop->menu != menu) - continue; - switch (prop->type) { - case P_PROMPT: - fputs(" prompt ", out); - print_quoted_string(out, prop->text); - if (!expr_is_yes(prop->visible.expr)) { - fputs(" if ", out); - expr_fprint(prop->visible.expr, out); - } - fputc('\n', out); - break; - case P_DEFAULT: - fputs( " default ", out); - expr_fprint(prop->expr, out); - if (!expr_is_yes(prop->visible.expr)) { - fputs(" if ", out); - expr_fprint(prop->visible.expr, out); - } - fputc('\n', out); - break; - case P_CHOICE: - fputs(" #choice value\n", out); - break; - default: - fprintf(out, " unknown prop %d!\n", prop->type); - break; - } - } - if (menu->help) { - int len = strlen(menu->help); - while (menu->help[--len] == '\n') - menu->help[len] = 0; - fprintf(out, " help\n%s\n", menu->help); - } - fputc('\n', out); -} - -void zconfdump(FILE *out) -{ - struct property *prop; - struct symbol *sym; - struct menu *menu; - - menu = rootmenu.list; - while (menu) { - if ((sym = menu->sym)) - print_symbol(out, menu); - else if ((prop = menu->prompt)) { - switch (prop->type) { - case P_COMMENT: - fputs("\ncomment ", out); - print_quoted_string(out, prop->text); - fputs("\n", out); - break; - case P_MENU: - fputs("\nmenu ", out); - print_quoted_string(out, prop->text); - fputs("\n", out); - break; - default: - ; - } - if (!expr_is_yes(prop->visible.expr)) { - fputs(" depends ", out); - expr_fprint(prop->visible.expr, out); - fputc('\n', out); - } - fputs("\n", out); - } - - if (menu->list) - menu = menu->list; - else if (menu->next) - menu = menu->next; - else while ((menu = menu->parent)) { - if (menu->prompt && menu->prompt->type == P_MENU) - fputs("\nendmenu\n", out); - if (menu->next) { - menu = menu->next; - break; - } - } - } -} - -#include "lex.zconf.c" -#include "util.c" -#include "confdata.c" -#include "expr.c" -#include "symbol.c" -#include "menu.c" diff --git a/docs/how-openadk-works.txt b/docs/how-openadk-works.txt index a8634d8c3..e86251196 100644 --- a/docs/how-openadk-works.txt +++ b/docs/how-openadk-works.txt @@ -6,7 +6,7 @@ How OpenADK works As mentioned above, OpenADK is basically a set of Makefiles that download, configure, and compile software with the correct options. It -also includes patches for various software packages and the linux kernel. +also includes patches for various software packages and the Linux kernel. There is basically one Makefile per software package. Makefiles are split into many different parts. @@ -22,28 +22,20 @@ many different parts. the kernel patches * The +package/+ directory contains the Makefiles and - associated files for all user-space tools and libraries that OpenADK - can compile and add to the target root filesystem. There is one - sub-directory per package. + associated files for all user-space tools and libraries that OpenADK can + compile and add to the target root filesystem or to the host directory. There + is one sub-directory per package. * The +mk/+ directory contains some globally used Makefiles with the suffix +.mk+, these are used in all other Makefile via include -* The +tools/+ directory contains the Makefiles and +* The +adk/+ directory contains the Makefiles and associated files for software related to the generation of the - host tools needed for different tasks (compression tools, ..). - -There are three other directories in the top level directory of OpenADK: + host tools needed for +make menuconfig+ system * The +scripts/+ directory contains shell scripts for the creation of meta-data in OpenADK, install scripts and image creation scripts -* The +config/+ directory contains the application used for the - +make menuconfig+ system - -* The +tests/+ directory contains some data for the +make check+ target, - to run the gcc testsuite - The main Makefile performs the following steps before the configuration is done: @@ -69,12 +61,13 @@ configuration is done (it is mainly a wrapper for +mk/build.mk+): available systems and package collections * Generate the host tools required for different tasks (encrypting passwords, - compressing data, extracting archives, ..) + compressing data, extracting archives, creating images, ..) * Generate the cross-compilation toolchain (binutils, gcc, libc, gdb) -* Compile the linux kernel +* Compile the Linux kernel * Compile all the userspace packages, the boot loader and external kernel modules * Generate the firmware images or archives + diff --git a/docs/make-tips.txt b/docs/make-tips.txt index f508633e9..dcfbe22e0 100644 --- a/docs/make-tips.txt +++ b/docs/make-tips.txt @@ -43,7 +43,7 @@ and pkg trees, the firmware and the toolchain for all targets): -------------------- If you even want to clean any downloaded source and your -confiuration +.config+: +configuration +.config+: -------------------- $ make distclean @@ -60,7 +60,7 @@ This is automatically triggered if you change the kernel version in your configuration. If you just want to clean all packages and wants to rebuild the firmware, -(the tools/toolchain is not deleted) just use: +(the toolchain is not deleted) just use: -------------------- $ make clean diff --git a/docs/prerequisite.txt b/docs/prerequisite.txt index 8a9670066..d7ffcc544 100644 --- a/docs/prerequisite.txt +++ b/docs/prerequisite.txt @@ -23,8 +23,8 @@ package names may vary between host systems. ** +bash+ ** +binutils+ -** +gcc+ -** `g++` +** +C compiler (gcc or clang)+ +** `C++ compiler (g++ or clang++)` ** +GNU sed+ ** +GNU awk+ ** +GNU make+ @@ -33,10 +33,9 @@ package names may vary between host systems. ** +perl+ ** +tar+ ** +wget+ -** +findutils (find, xargs)+ -** +ncurses5 development+ -** +zlib development+ -** +libc development+ +** +ncurses5 development files+ +** +zlib development files+ +** +libc development files+ There is a check for the required versions of these tools in advance, though. To re-issue the checks, use +make prereq+. diff --git a/mk/build.mk b/mk/build.mk index 375ccfb0b..04a92c1d2 100644 --- a/mk/build.mk +++ b/mk/build.mk @@ -9,7 +9,7 @@ $(error your umask is not 022) endif CONFIG_CONFIG_IN = Config.in -CONFIG = config +CONFIG = adk/config DEFCONFIG= ADK_DEBUG=n \ ADK_STATIC=n \ ADK_WGET_TIMEOUT=180 \ @@ -93,7 +93,7 @@ POSTCONFIG= -@\ if [ -f .adkinit ];then rm .adkinit;\ else \ if [ -f .config.old ];then \ - $(TOPDIR)/host_$(GNU_HOST_NAME)/usr/bin/pkgrebuild;\ + $(TOPDIR)/adk/tools/pkgrebuild;\ rebuild=0; \ if [ "$$(grep ^BUSYBOX .config|md5sum)" != "$$(grep ^BUSYBOX .config.old|md5sum)" ];then \ touch .rebuild.busybox;\ @@ -139,27 +139,26 @@ include $(TOPDIR)/rules.mk all: world -${TOPDIR}/package/Depends.mk: ${TOPDIR}/.config $(wildcard ${TOPDIR}/package/*/Makefile) - $(STAGING_HOST_DIR)/usr/bin/depmaker > ${TOPDIR}/package/Depends.mk +${TOPDIR}/package/Depends.mk: ${TOPDIR}/.config $(wildcard ${TOPDIR}/package/*/Makefile) $(TOPDIR)/adk/tools/depmaker + $(TOPDIR)/adk/tools/depmaker > ${TOPDIR}/package/Depends.mk .NOTPARALLEL: .PHONY: all world clean cleandir cleantoolchain distclean image_clean world: mkdir -p $(DL_DIR) $(BUILD_DIR) $(TARGET_DIR) $(FW_DIR) \ - $(TOOLS_BUILD_DIR) $(STAGING_HOST_DIR)/usr/bin \ - $(TOOLCHAIN_BUILD_DIR) $(STAGING_PKG_DIR)/stamps + $(STAGING_HOST_DIR) $(TOOLCHAIN_BUILD_DIR) $(STAGING_PKG_DIR)/stamps ${BASH} ${TOPDIR}/scripts/scan-pkgs.sh ${BASH} ${TOPDIR}/scripts/update-sys ${BASH} ${TOPDIR}/scripts/update-pkg ifeq ($(ADK_TOOLCHAIN),y) ifeq ($(ADK_TOOLCHAIN_ONLY),y) - $(MAKE) -f mk/build.mk tools/install toolchain/fixup package/compile + $(MAKE) -f mk/build.mk package/hostcompile toolchain/fixup package/compile else - $(MAKE) -f mk/build.mk tools/install toolchain/fixup package/compile root_clean package/install + $(MAKE) -f mk/build.mk package/hostcompile toolchain/fixup package/compile root_clean package/install endif else - $(MAKE) -f mk/build.mk tools/install toolchain/fixup target/config-prepare target/compile package/compile root_clean package/install target/install package_index + $(MAKE) -f mk/build.mk package/hostcompile toolchain/fixup target/config-prepare target/compile package/compile root_clean package/install target/install package_index endif package_index: @@ -191,9 +190,6 @@ target/%: toolchain/%: ${STAGING_TARGET_DIR} $(MAKE) -C toolchain $(patsubst toolchain/%,%,$@) -tools/%: - $(MAKE) -C tools $(patsubst tools/%,%,$@) - image: $(MAKE) -C target image @@ -266,7 +262,7 @@ cleandir: @$(MAKE) -C $(CONFIG) clean $(MAKE_TRACE) rm -rf $(BUILD_DIR_PFX) $(FW_DIR_PFX) $(TARGET_DIR_PFX) \ ${TOPDIR}/package/pkglist.d ${TOPDIR}/package/pkgconfigs.d - rm -rf $(TOOLCHAIN_DIR_PFX) $(STAGING_HOST_DIR_PFX) $(TOOLS_BUILD_DIR) + rm -rf $(TOOLCHAIN_DIR_PFX) $(STAGING_HOST_DIR_PFX) rm -rf $(STAGING_TARGET_DIR_PFX) $(STAGING_PKG_DIR_PFX) rm -f .menu .tmpconfig.h .rebuild* ${TOPDIR}/package/Depends.mk ${TOPDIR}/prereq.mk @@ -274,7 +270,7 @@ cleantoolchain: @$(TRACE) cleantoolchain @rm -rf $(BUILD_DIR_PFX) $(TARGET_DIR_PFX) \ ${TOPDIR}/package/pkglist.d ${TOPDIR}/package/pkgconfigs.d - @rm -rf $(TOOLCHAIN_DIR_PFX) $(STAGING_HOST_DIR_PFX) $(TOOLS_BUILD_DIR) + @rm -rf $(TOOLCHAIN_DIR_PFX) $(STAGING_HOST_DIR_PFX) @rm -rf $(STAGING_TARGET_DIR_PFX) $(STAGING_PKG_DIR_PFX) @rm -f .menu .tmpconfig.h .rebuild* ${TOPDIR}/package/Depends.mk @@ -283,7 +279,7 @@ distclean: @$(MAKE) -C $(CONFIG) clean $(MAKE_TRACE) @rm -rf $(BUILD_DIR_PFX) $(FW_DIR_PFX) $(TARGET_DIR_PFX) $(DL_DIR) \ ${TOPDIR}/package/pkglist.d ${TOPDIR}/package/pkgconfigs.d - @rm -rf $(TOOLCHAIN_DIR_PFX) $(STAGING_HOST_DIR_PFX) $(TOOLS_BUILD_DIR) + @rm -rf $(TOOLCHAIN_DIR_PFX) $(STAGING_HOST_DIR_PFX) @rm -rf $(STAGING_TARGET_DIR_PFX) $(STAGING_PKG_DIR_PFX) @rm -f .adkinit .config* .defconfig .tmpconfig.h all.config ${TOPDIR}/prereq.mk \ .menu ${TOPDIR}/package/Depends.mk .ADK_HAVE_DOT_CONFIG .rebuild.* @@ -456,7 +452,7 @@ distclean: @$(MAKE) -C $(CONFIG) clean @rm -rf $(BUILD_DIR_PFX) $(FW_DIR_PFX) $(TARGET_DIR_PFX) $(DL_DIR) \ ${TOPDIR}/package/pkglist.d ${TOPDIR}/package/pkgconfigs.d - @rm -rf $(TOOLCHAIN_DIR_PFX) $(STAGING_TARGET_DIR_PFX) $(TOOLS_BUILD_DIR) + @rm -rf $(TOOLCHAIN_DIR_PFX) $(STAGING_TARGET_DIR_PFX) @rm -rf $(STAGING_HOST_DIR_PFX) $(STAGING_TARGET_DIR_PFX) $(STAGING_PKG_DIR_PFX) @rm -f .adkinit .config* .defconfig .tmpconfig.h all.config ${TOPDIR}/prereq.mk \ .menu .rebuild.* ${TOPDIR}/package/Depends.mk .ADK_HAVE_DOT_CONFIG @@ -601,45 +597,42 @@ bulkallmod: if [ -f .exit ];then echo "Bulk build failed!"; cat .exit;rm .exit; exit 1;fi \ done -$(TOPDIR)/host_$(GNU_HOST_NAME)/usr/bin/pkgmaker: $(TOPDIR)/tools/adk/pkgmaker.c $(TOPDIR)/tools/adk/sortfile.c $(TOPDIR)/tools/adk/strmap.c - @mkdir -p host_$(GNU_HOST_NAME)/usr/bin - @$(CC_FOR_BUILD) -g -o $@ tools/adk/pkgmaker.c tools/adk/sortfile.c tools/adk/strmap.c +$(TOPDIR)/adk/tools/pkgmaker: $(TOPDIR)/adk/tools/pkgmaker.c $(TOPDIR)/adk/tools/sortfile.c $(TOPDIR)/adk/tools/strmap.c + @$(CC_FOR_BUILD) -g -o $@ adk/tools/pkgmaker.c adk/tools/sortfile.c adk/tools/strmap.c -$(TOPDIR)/host_$(GNU_HOST_NAME)/usr/bin/pkgrebuild: $(TOPDIR)/tools/adk/pkgrebuild.c $(TOPDIR)/tools/adk/strmap.c - @$(CC_FOR_BUILD) -g -o $@ tools/adk/pkgrebuild.c tools/adk/strmap.c +$(TOPDIR)/adk/tools/pkgrebuild: $(TOPDIR)/adk/tools/pkgrebuild.c $(TOPDIR)/adk/tools/strmap.c + @$(CC_FOR_BUILD) -g -o $@ adk/tools/pkgrebuild.c adk/tools/strmap.c -package/Config.in.auto menu .menu: $(wildcard ${TOPDIR}/package/*/Makefile) $(TOPDIR)/host_$(GNU_HOST_NAME)/usr/bin/pkgmaker $(TOPDIR)/host_$(GNU_HOST_NAME)/usr/bin/pkgrebuild +package/Config.in.auto menu .menu: $(wildcard ${TOPDIR}/package/*/Makefile) $(TOPDIR)/adk/tools/pkgmaker $(TOPDIR)/adk/tools/pkgrebuild @echo "Generating menu structure ..." - @$(TOPDIR)/host_$(GNU_HOST_NAME)/usr/bin/pkgmaker + @$(TOPDIR)/adk/tools/pkgmaker @:>.menu -$(TOPDIR)/host_$(GNU_HOST_NAME)/usr/bin/depmaker: $(TOPDIR)/tools/adk/depmaker.c - @mkdir -p host_$(GNU_HOST_NAME)/usr/bin - $(CC_FOR_BUILD) -g -o $@ $(TOPDIR)/tools/adk/depmaker.c +$(TOPDIR)/adk/tools/depmaker: $(TOPDIR)/adk/tools/depmaker.c + $(CC_FOR_BUILD) -g -o $@ $(TOPDIR)/adk/tools/depmaker.c -dep: $(TOPDIR)/host_$(GNU_HOST_NAME)/usr/bin/depmaker +dep: $(TOPDIR)/adk/tools/depmaker @echo "Generating dependencies ..." - @$(TOPDIR)/host_$(GNU_HOST_NAME)/usr/bin/depmaker > ${TOPDIR}/package/Depends.mk + @$(TOPDIR)/adk/tools/depmaker > ${TOPDIR}/package/Depends.mk .PHONY: menu dep include $(TOPDIR)/toolchain/gcc/Makefile.inc check-dejagnu: - @-rm tests/adk.exp tests/master.exp >/dev/null 2>&1 - @sed -e "s#@ADK_TARGET_IP@#$(ADK_TARGET_IP)#" tests/adk.exp.in > \ - tests/adk.exp.in.tmp - @sed -e "s#@ADK_TARGET_PORT@#$(ADK_TARGET_PORT)#" tests/adk.exp.in.tmp > \ - tests/adk.exp - @sed -e "s#@TOPDIR@#$(TOPDIR)#" tests/master.exp.in > \ - tests/master.exp + @-rm adk/tests/adk.exp adk/tests/master.exp >/dev/null 2>&1 + @sed -e "s#@ADK_TARGET_IP@#$(ADK_TARGET_IP)#" \ + -e "s#@ADK_TARGET_PORT@#$(ADK_TARGET_PORT)#" \ + adk/tests/adk.exp.in > adk/tests/adk.exp + @sed -e "s#@TOPDIR@#$(TOPDIR)#" adk/tests/master.exp.in > \ + adk/tests/master.exp check-gcc: check-dejagnu - env DEJAGNU=$(TOPDIR)/tests/master.exp \ + env DEJAGNU=$(TOPDIR)/adk/tests/master.exp \ $(MAKE) -C $(TOOLCHAIN_BUILD_DIR)/w-$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE)/$(PKG_NAME)-$(PKG_VERSION)-final/gcc check-gcc check-g++: check-dejagnu - env DEJAGNU=$(TOPDIR)/tests/master.exp \ + env DEJAGNU=$(TOPDIR)/adk/tests/master.exp \ $(MAKE) -C $(TOOLCHAIN_BUILD_DIR)/w-$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE)/$(PKG_NAME)-$(PKG_VERSION)-final/gcc check-g++ check: check-gcc check-g++ diff --git a/mk/buildhlp.mk b/mk/buildhlp.mk index 701f0f4a2..5ce3ca4a0 100644 --- a/mk/buildhlp.mk +++ b/mk/buildhlp.mk @@ -81,7 +81,7 @@ ${WRKDIST}/.prepared: ${WRKDIST}/.extract_done touch $@ endif -update-patches: +update-patches host-update-patches: @test ! -d ${WRKDIR}.orig || rm -rf ${WRKDIR}.orig @test ! -d ${WRKDIR}.orig ifeq ($(strip ${_IN_PACKAGE})$(strip ${_IN_CVTC}),1) @@ -115,4 +115,4 @@ endif rm -rf ${WRKDIR}.orig; \ [[ $$toedit != FAIL ]] -.PHONY: update-patches +.PHONY: update-patches host-update-patches diff --git a/mk/fetch.mk b/mk/fetch.mk index 6382571b3..ee24f0b60 100644 --- a/mk/fetch.mk +++ b/mk/fetch.mk @@ -26,7 +26,6 @@ refetch: -rm -f ${FULLDISTFILES} ${MAKE} fetch -# XXX for now _CHECKSUM_COOKIE?= ${WRKDIR}/.checksum_done checksum: ${_CHECKSUM_COOKIE} ifeq ($(strip ${NO_CHECKSUM}),) diff --git a/mk/host.mk b/mk/host.mk index 5f9539aef..8d3e7d74e 100644 --- a/mk/host.mk +++ b/mk/host.mk @@ -10,6 +10,7 @@ HOST_CONFIGURE_ENV+= AUTOM4TE=${STAGING_HOST_DIR}/usr/bin/autom4te \ CONFIG_SHELL='$(strip ${SHELL})' \ PKG_CONFIG_LIBDIR='${STAGING_HOST_DIR}/usr/lib/pkgconfig' \ PATH='${HOST_PATH}' \ + CC='$(strip ${CC_FOR_BUILD})' \ CFLAGS='$(strip ${CFLAGS_FOR_BUILD})' \ CXXFLAGS='$(strip ${CXXFLAGS_FOR_BUILD})' \ CPPFLAGS='$(strip ${CPPFLAGS_FOR_BUILD})' \ @@ -28,6 +29,7 @@ HOST_INSTALL_TARGET?= install HOST_MAKE_ENV+= PATH='${HOST_PATH}' \ PKG_CONFIG_LIBDIR='${STAGING_HOST_DIR}/usr/lib/pkgconfig' \ + CC='$(strip ${CC_FOR_BUILD})' \ CFLAGS='$(strip ${CFLAGS_FOR_BUILD})' \ CXXFLAGS='$(strip ${CXXFLAGS_FOR_BUILD})' \ CPPFLAGS='$(strip ${CPPFLAGS_FOR_BUILD})' \ diff --git a/mk/image.mk b/mk/image.mk index 6a4d7863d..2ce1b3444 100644 --- a/mk/image.mk +++ b/mk/image.mk @@ -127,7 +127,7 @@ ROOTFSSQUASHFS= ${ADK_TARGET_SYSTEM}-$(CPU_ARCH)-${ADK_TARGET_LIBC}-${ADK_TARGE ROOTFSJFFS2= ${ADK_TARGET_SYSTEM}-$(CPU_ARCH)-${ADK_TARGET_LIBC}-jffs2.img ROOTFSTARBALL= ${ADK_TARGET_SYSTEM}-$(CPU_ARCH)-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}+kernel.tar.gz ROOTFSUSERTARBALL= ${ADK_TARGET_SYSTEM}-$(CPU_ARCH)-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}.tar.gz -ROOTFSISO= ${ADK_TARGET_SYSTEM}-$(CPU_ARCH)-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}.iso +ROOTFSISO= ${ADK_TARGET_SYSTEM}-$(CPU_ARCH)-${ADK_TARGET_LIBC}.iso else TARGET_KERNEL= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_FS}-kernel INITRAMFS= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_LIBC}-${ADK_TARGET_FS} @@ -135,7 +135,7 @@ ROOTFSSQUASHFS= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}.img ROOTFSJFFS2= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_LIBC}-jffs2.img ROOTFSTARBALL= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}+kernel.tar.gz ROOTFSUSERTARBALL= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}.tar.gz -ROOTFSISO= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_LIBC}-${ADK_TARGET_FS}.iso +ROOTFSISO= ${ADK_TARGET_SYSTEM}-${ADK_TARGET_LIBC}.iso endif ${FW_DIR}/${ROOTFSTARBALL}: ${TARGET_DIR} kernel-package @@ -236,7 +236,7 @@ ${FW_DIR}/${ROOTFSISO}: ${TARGET_DIR} kernel-package mkdir -p ${TARGET_DIR}/boot/syslinux cp ${STAGING_HOST_DIR}/usr/share/syslinux/{isolinux.bin,ldlinux.c32} \ ${TARGET_DIR}/boot/syslinux - echo 'DEFAULT /boot/kernel root=/dev/sr0 init=/init' > \ + echo 'DEFAULT /boot/kernel root=/dev/sr0' > \ ${TARGET_DIR}/boot/syslinux/isolinux.cfg ${STAGING_HOST_DIR}/usr/bin/mkisofs -R -uid 0 -gid 0 -o $@ \ -b boot/syslinux/isolinux.bin \ diff --git a/mk/pkg-bottom.mk b/mk/pkg-bottom.mk index 3e454ee5a..2cec6ac2c 100644 --- a/mk/pkg-bottom.mk +++ b/mk/pkg-bottom.mk @@ -125,6 +125,8 @@ do-install: post-install: spkg-install: ${ALL_POSTINST} ${_FAKE_COOKIE}: ${_BUILD_COOKIE} + echo FOO + echo $(HOST_WRKDIR) @-rm -f ${_ALL_CONTROLS} @mkdir -p '${STAGING_PKG_DIR}/stamps' ${WRKINST} '${STAGING_TARGET_DIR}/scripts' @${MAKE} ${_ALL_CONTROLS} $(MAKE_TRACE) diff --git a/mk/vars.mk b/mk/vars.mk index 9da5f3ad3..042f519d7 100644 --- a/mk/vars.mk +++ b/mk/vars.mk @@ -17,7 +17,6 @@ DL_DIR?= $(BASE_DIR)/dl else DL_DIR?= $(ADK_DL_DIR) endif -TOOLS_BUILD_DIR= $(BASE_DIR)/tools_build SCRIPT_DIR:= $(BASE_DIR)/scripts STAGING_HOST_DIR:= ${BASE_DIR}/host_${GNU_HOST_NAME} TOOLCHAIN_DIR:= ${BASE_DIR}/toolchain_${GNU_HOST_NAME} @@ -71,7 +70,7 @@ CONFIGURE_TRIPLE:= --build=${GNU_HOST_NAME} \ --target=${GNU_TARGET_NAME} ifneq ($(strip ${ADK_USE_CCACHE}),) -TARGET_COMPILER_PREFIX=ccache ${TARGET_CROSS} +TARGET_COMPILER_PREFIX=$(STAGING_HOST_DIR)/usr/bin/ccache ${TARGET_CROSS} endif # target tools diff --git a/package/Makefile b/package/Makefile index 1b8cc97f3..c2b7d5285 100644 --- a/package/Makefile +++ b/package/Makefile @@ -28,11 +28,13 @@ include $(TOPDIR)/package/Depends.mk DOWNLOAD:=$(patsubst %,%-download,$(package-y) $(package-m)) REBUILD_PACKAGES:=$(patsubst %,%-rebuild,$(package-y) $(package-m)) COMPILE_PACKAGES:=$(patsubst %,%-compile,$(package-y) $(package-m)) +HOST_COMPILE_PACKAGES:=$(patsubst %,%-host-compile,$(hostpackage-y)) INSTALL_PACKAGES:=$(patsubst %,%-install,$(package-y)) all: compile download: $(DOWNLOAD) clean: $(patsubst %,%-clean,$(package-) $(package-y) $(package-m) base-files) +hostcompile: $(HOST_COMPILE_PACKAGES) ifeq ($(ADK_TOOLCHAIN_ONLY),y) compile: $(REBUILD_PACKAGES) $(COMPILE_PACKAGES) install: $(INSTALL_PACKAGES) diff --git a/package/base-files/Makefile b/package/base-files/Makefile index 3711e7a00..3440390ab 100644 --- a/package/base-files/Makefile +++ b/package/base-files/Makefile @@ -9,7 +9,6 @@ PKG_VERSION:= 1.0 PKG_RELEASE:= 79 PKG_SECTION:= base PKG_DESCR:= basic files and scripts -PKG_BUILDDEP:= pkgconf-host file-host WRKDIST= ${WRKDIR}/base-files NO_DISTFILES:= 1 diff --git a/package/bc/Makefile b/package/bc/Makefile index 2a5c59900..d35659ed8 100644 --- a/package/bc/Makefile +++ b/package/bc/Makefile @@ -7,7 +7,7 @@ PKG_NAME:= bc PKG_VERSION:= 1.06 PKG_RELEASE:= 1 PKG_MD5SUM:= d44b5dddebd8a7a7309aea6c36fda117 -PKG_DESCR:= An arbitrary precision calculator language +PKG_DESCR:= arbitrary precision calculator language PKG_SECTION:= utils PKG_BUILDDEP:= m4-host flex-host PKG_URL:= http://www.gnu.org/software/bc/ @@ -15,11 +15,15 @@ PKG_SITES:= http://ftp.gnu.org/pub/gnu/bc/ PKG_SUBPKGS:= BC DC +include ${TOPDIR}/mk/host.mk include ${TOPDIR}/mk/package.mk +$(eval $(call HOST_template,BC,bc,${PKG_VERSION}-${PKG_RELEASE})) $(eval $(call PKG_template,BC,bc,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) $(eval $(call PKG_template,DC,dc,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) +HOST_STYLE:= auto + bc-install: ${INSTALL_DIR} ${IDIR_BC}/usr/bin ${INSTALL_BIN} ${WRKBUILD}/bc/bc ${IDIR_BC}/usr/bin/bc @@ -28,4 +32,5 @@ dc-install: ${INSTALL_DIR} ${IDIR_DC}/usr/bin ${INSTALL_BIN} ${WRKBUILD}/dc/dc ${IDIR_DC}/usr/bin/dc +include ${TOPDIR}/mk/host-bottom.mk include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/busybox/Makefile b/package/busybox/Makefile index c1923708e..fce16fa32 100644 --- a/package/busybox/Makefile +++ b/package/busybox/Makefile @@ -9,6 +9,7 @@ PKG_RELEASE:= 5 PKG_MD5SUM:= 795394f83903b5eec6567d51eebb417e PKG_DESCR:= core utilities for embedded systems PKG_SECTION:= base +PKG_BUILDDEP:= bzip2-host PKG_URL:= http://www.busybox.net/ PKG_SITES:= http://www.busybox.net/downloads/ diff --git a/package/bzip2/Makefile b/package/bzip2/Makefile index 5585ae0c1..b73fde65f 100644 --- a/package/bzip2/Makefile +++ b/package/bzip2/Makefile @@ -43,8 +43,10 @@ host-build: PREFIX=${HOST_WRKINST}/usr ${HOST_ALL_TARGET}) bzip2-hostinstall: + ${INSTALL_DIR} ${STAGING_HOST_DIR}/usr/bin ${INSTALL_DIR} ${STAGING_HOST_DIR}/usr/lib ${INSTALL_DIR} $(STAGING_HOST_DIR)/usr/include + $(INSTALL_BIN) ${WRKBUILD}/bzip2-shared ${STAGING_HOST_DIR}/usr/bin/bzip2 $(CP) ${WRKBUILD}/libbz2.so* \ ${STAGING_HOST_DIR}/usr/lib (cd ${STAGING_HOST_DIR}/usr/lib; ln -sf libbz2.so.1.0.6 libbz2.so) diff --git a/package/ccache/Makefile b/package/ccache/Makefile new file mode 100644 index 000000000..c61f1c4d9 --- /dev/null +++ b/package/ccache/Makefile @@ -0,0 +1,24 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include $(TOPDIR)/rules.mk + +PKG_NAME:= ccache +PKG_VERSION:= 3.1.9 +PKG_RELEASE:= 1 +PKG_MD5SUM:= 367916e4ecba4968f77f59a378e61458 +PKG_DESCR:= ccache utility +PKG_SECTION:= misc +PKG_SITES:= http://samba.org/ftp/ccache/ + +PKG_CFLINE_CCACHE:= depends on ADK_HOST_ONLY + +include $(TOPDIR)/mk/host.mk +include $(TOPDIR)/mk/package.mk + +$(eval $(call HOST_template,CCACHE,ccache,$(PKG_VERSION)-${PKG_RELEASE})) + +HOST_STYLE:= auto + +include ${TOPDIR}/mk/host-bottom.mk +include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/cdrtools/Makefile b/package/cdrtools/Makefile index 6bf16ab17..612a553bc 100644 --- a/package/cdrtools/Makefile +++ b/package/cdrtools/Makefile @@ -8,28 +8,27 @@ PKG_VERSION:= 3.01 PKG_RELEASE:= 1 PKG_MD5SUM:= afd4563e335a614a11e042c7b6734d66 PKG_DESCR:= cdrtools -PKG_SECTION:= misc +PKG_SECTION:= fs PKG_URL:= http://cdrecord.berlios.de/private/cdrecord.html -PKG_SITES:= http://openadk.org/ +PKG_SITES:= ftp://ftp.berlios.de/pub/cdrecord/ -PKG_CFLINE_CDRTOOLS:= depends on ADK_BROKEN +PKG_CFLINE_CDRTOOLS:= depends on ADK_HOST_ONLY +include $(TOPDIR)/mk/host.mk include $(TOPDIR)/mk/package.mk -$(eval $(call PKG_template,CDRTOOLS,cdrtools,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) +$(eval $(call HOST_template,CDRTOOLS,cdrtools,$(PKG_VERSION)-${PKG_RELEASE})) -CONFIG_STYLE:= manual -XAKE_FLAGS+= GCC_HONOUR_COPTS=s +HOST_STYLE:= manual -cdrtools-install: - $(INSTALL_DIR) $(IDIR_CDRTOOLS)/usr/bin - $(INSTALL_BIN) $(WRKINST)/opt/schily/bin/cdrecord \ - $(IDIR_CDRTOOLS)/usr/bin - $(INSTALL_BIN) $(WRKINST)/opt/schily/bin/readcd \ - $(IDIR_CDRTOOLS)/usr/bin - $(INSTALL_BIN) $(WRKINST)/opt/schily/bin/mkisofs \ - $(IDIR_CDRTOOLS)/usr/bin - $(INSTALL_BIN) $(WRKINST)/opt/schily/bin/cdda2wav \ - $(IDIR_CDRTOOLS)/usr/bin +host-build: + (cd ${WRKBUILD} && env ${HOST_MAKE_ENV} ${MAKE} -f ${MAKE_FILE} \ + ${HOST_MAKE_FLAGS} ${HOST_ALL_TARGET}) +cdrtools-hostinstall: + $(INSTALL_DIR) $(STAGING_HOST_DIR)/usr/bin + $(INSTALL_BIN) $(WRKBUILD)/mkisofs/OBJ/*/mkisofs \ + $(STAGING_HOST_DIR)/usr/bin + +include ${TOPDIR}/mk/host-bottom.mk include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/cfgfs/Makefile b/package/cfgfs/Makefile index 70b323a76..3d1d41410 100644 --- a/package/cfgfs/Makefile +++ b/package/cfgfs/Makefile @@ -15,7 +15,7 @@ PKG_CFLINE_CFGFS:= select BUSYBOX_DIFF@ PKG_CFLINE_CFGFS+= select BUSYBOX_MD5SUM@ PKG_CFLINE_CFGFS+= select BUSYBOX_XARGS@ PKG_CFLINE_CFGFS+= select BUSYBOX_FEATURE_SORT_BIG@ -PKG_CFLINE_CFGFS+= depends on !ADK_TARGET_ROOTFS_NFSROOT && !ADK_TARGET_ROOTFS_INITRAMFS_PIGGYBACK && !ADK_TARGET_ROOTFS_INITRAMFS && !ADK_TARGET_ROOTFS_JFFS2 && !ADK_TARGET_ROOTFS_SQUASHFS +PKG_CFLINE_CFGFS+= depends on !ADK_TARGET_ROOTFS_NFSROOT && !ADK_TARGET_ROOTFS_INITRAMFS_PIGGYBACK && !ADK_TARGET_ROOTFS_INITRAMFS && !ADK_TARGET_ROOTFS_JFFS2 && !ADK_TARGET_ROOTFS_SQUASHFS && !ADK_TARGET_ROOTFS_ISO PKG_DFLT_CFGFS:= y if !(ADK_TOOLCHAIN_ONLY || ADK_TOOLCHAIN_ARCHIVE || ADK_PKG_TEST) WRKDIST= ${WRKDIR}/${PKG_NAME}-${PKG_VERSION} diff --git a/package/genext2fs/Makefile b/package/genext2fs/Makefile new file mode 100644 index 000000000..4e8fea5bd --- /dev/null +++ b/package/genext2fs/Makefile @@ -0,0 +1,24 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include $(TOPDIR)/rules.mk + +PKG_NAME:= genext2fs +PKG_VERSION:= 1.4.1 +PKG_RELEASE:= 1 +PKG_MD5SUM:= b7b6361bcce2cedff1ae437fadafe53b +PKG_DESCR:= genext2fs utility +PKG_SECTION:= fs +PKG_SITES:= ${MASTER_SITE_SOURCEFORGE:=genext2fs/} + +PKG_CFLINE_GENEXT2FS:= depends on ADK_HOST_ONLY + +include $(TOPDIR)/mk/host.mk +include $(TOPDIR)/mk/package.mk + +$(eval $(call HOST_template,GENEXT2FS,genext2fs,$(PKG_VERSION)-${PKG_RELEASE})) + +HOST_STYLE:= auto + +include ${TOPDIR}/mk/host-bottom.mk +include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/heirloom-cpio/Makefile b/package/heirloom-cpio/Makefile new file mode 100644 index 000000000..a91b71ecf --- /dev/null +++ b/package/heirloom-cpio/Makefile @@ -0,0 +1,32 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include ${TOPDIR}/rules.mk + +PKG_NAME:= heirloom-cpio +PKG_VERSION:= 1.0 +PKG_RELEASE:= 1 +PKG_DESCR:= patched version of heirloom cpio +PKG_SECTION:= archive + +PKG_CFLINE_HEIRLOOM_CPIO:= depends on ADK_HOST_ONLY + +NO_DISTFILES:= 1 + +include ${TOPDIR}/mk/host.mk +include ${TOPDIR}/mk/package.mk + +$(eval $(call HOST_template,HEIRLOOM_CPIO,heirloom-cpio,${PKG_VERSION}-${PKG_RELEASE})) + +HOST_STYLE:= manual + +host-build: + (cd ${WRKBUILD} && env ${HOST_MAKE_ENV} ${MAKE} -f ${MAKE_FILE} \ + ${HOST_MAKE_FLAGS} ${HOST_ALL_TARGET}) + +heirloom-cpio-hostinstall: + ${INSTALL_DIR} ${STAGING_HOST_DIR}/usr/bin + ${INSTALL_BIN} ${WRKBUILD}/cpio ${STAGING_HOST_DIR}/usr/bin + +include ${TOPDIR}/mk/host-bottom.mk +include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/heirloom-cpio/src/Makefile b/package/heirloom-cpio/src/Makefile new file mode 100644 index 000000000..ecaf82243 --- /dev/null +++ b/package/heirloom-cpio/src/Makefile @@ -0,0 +1,28 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +all: cpio + +SRCS:= ib_open.c \ + ib_close.c \ + ib_read.c \ + ib_alloc.c \ + ib_free.c \ + ib_getlin.c \ + sfile.c \ + gmatch.c \ + sigset.c \ + memalign.c \ + version.c \ + blast.c \ + crc32.c \ + expand.c \ + explode.c \ + flags.c \ + inflate.c \ + unshrink.c \ + nonpax.c \ + cpio.c + +cpio: ${SRCS} + $(CC) $(CFLAGS_FOR_BUILD) -D_GNU_SOURCE -I. -o $@ $^ diff --git a/package/heirloom-cpio/src/_alloca.h b/package/heirloom-cpio/src/_alloca.h new file mode 100644 index 000000000..dc2afe5b4 --- /dev/null +++ b/package/heirloom-cpio/src/_alloca.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)_alloca.h 1.5 (gritter) 1/22/06 */ + +#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \ + defined (__DragonFly__) || defined (__APPLE__) +#include +#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ diff --git a/package/heirloom-cpio/src/_malloc.h b/package/heirloom-cpio/src/_malloc.h new file mode 100644 index 000000000..1693e3673 --- /dev/null +++ b/package/heirloom-cpio/src/_malloc.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)_malloc.h 1.2 (gritter) 5/1/04 */ + +#include + +extern void *memalign(size_t, size_t); diff --git a/package/heirloom-cpio/src/_utmpx.h b/package/heirloom-cpio/src/_utmpx.h new file mode 100644 index 000000000..c32bd9527 --- /dev/null +++ b/package/heirloom-cpio/src/_utmpx.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2004 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)_utmpx.h 1.9 (gritter) 1/22/06 */ + +#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ + defined (__UCLIBC__) || defined (__OpenBSD__) || \ + defined (__DragonFly__) || defined (__APPLE__) +#include +#include +#include + +#ifndef __dietlibc__ +struct utmpx { + char ut_user[UT_NAMESIZE]; + char ut_id[UT_LINESIZE]; + char ut_line[UT_LINESIZE]; + char ut_host[UT_HOSTSIZE]; + pid_t ut_pid; + short ut_type; + struct timeval ut_tv; + struct { + int e_termination; + int e_exit; + } ut_exit; +}; + +#ifndef EMPTY +#define EMPTY 0 +#endif +#ifndef BOOT_TIME +#define BOOT_TIME 1 +#endif +#ifndef OLD_TIME +#define OLD_TIME 2 +#endif +#ifndef NEW_TIME +#define NEW_TIME 3 +#endif +#ifndef USER_PROCESS +#define USER_PROCESS 4 +#endif +#ifndef INIT_PROCESS +#define INIT_PROCESS 5 +#endif +#ifndef LOGIN_PROCESS +#define LOGIN_PROCESS 6 +#endif +#ifndef DEAD_PROCESS +#define DEAD_PROCESS 7 +#endif +#ifndef RUN_LVL +#define RUN_LVL 8 +#endif +#ifndef ACCOUNTING +#define ACCOUNTING 9 +#endif +#else /* __dietlibc__ */ +#define utmpx utmp +#endif /* __dietlibc__ */ + +extern void endutxent(void); +extern struct utmpx *getutxent(void); +extern struct utmpx *getutxid(const struct utmpx *); +extern struct utmpx *getutxline(const struct utmpx *); +extern struct utmpx *pututxline(const struct utmpx *); +extern void setutxent(void); +extern int utmpxname(const char *); +extern void updwtmpx(const char *, const struct utmpx *); +#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __UCLIBC__ || + __OpenBSD__ || __DragonFly__ || __APPLE__ */ diff --git a/package/heirloom-cpio/src/asciitype.c b/package/heirloom-cpio/src/asciitype.c new file mode 100644 index 000000000..f7f322173 --- /dev/null +++ b/package/heirloom-cpio/src/asciitype.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)asciitype.c 1.4 (gritter) 4/17/03 */ + +#include "asciitype.h" + +const unsigned char class_char[] = { +/* 000 nul 001 soh 002 stx 003 etx 004 eot 005 enq 006 ack 007 bel */ + C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL, +/* 010 bs 011 ht 012 nl 013 vt 014 np 015 cr 016 so 017 si */ + C_CNTRL,C_BLANK,C_WHITE,C_SPACE,C_SPACE,C_SPACE,C_CNTRL,C_CNTRL, +/* 020 dle 021 dc1 022 dc2 023 dc3 024 dc4 025 nak 026 syn 027 etb */ + C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL, +/* 030 can 031 em 032 sub 033 esc 034 fs 035 gs 036 rs 037 us */ + C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL, +/* 040 sp 041 ! 042 " 043 # 044 $ 045 % 046 & 047 ' */ + C_BLANK,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT, +/* 050 ( 051 ) 052 * 053 + 054 , 055 - 056 . 057 / */ + C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT, +/* 060 0 061 1 062 2 063 3 064 4 065 5 066 6 067 7 */ + C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL, +/* 070 8 071 9 072 : 073 ; 074 < 075 = 076 > 077 ? */ + C_DIGIT,C_DIGIT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT, +/* 100 @ 101 A 102 B 103 C 104 D 105 E 106 F 107 G */ + C_PUNCT,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER, +/* 110 H 111 I 112 J 113 K 114 L 115 M 116 N 117 O */ + C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER, +/* 120 P 121 Q 122 R 123 S 124 T 125 U 126 V 127 W */ + C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER, +/* 130 X 131 Y 132 Z 133 [ 134 \ 135 ] 136 ^ 137 _ */ + C_UPPER,C_UPPER,C_UPPER,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT, +/* 140 ` 141 a 142 b 143 c 144 d 145 e 146 f 147 g */ + C_PUNCT,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER, +/* 150 h 151 i 152 j 153 k 154 l 155 m 156 n 157 o */ + C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER, +/* 160 p 161 q 162 r 163 s 164 t 165 u 166 v 167 w */ + C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER, +/* 170 x 171 y 172 z 173 { 174 | 175 } 176 ~ 177 del */ + C_LOWER,C_LOWER,C_LOWER,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_CNTRL +}; diff --git a/package/heirloom-cpio/src/asciitype.h b/package/heirloom-cpio/src/asciitype.h new file mode 100644 index 000000000..6ac1961a1 --- /dev/null +++ b/package/heirloom-cpio/src/asciitype.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)asciitype.h 1.6 (gritter) 9/9/05 */ + +/* + * Locale-independent character classes. + */ +enum { + C_CNTRL = 0000, + C_BLANK = 0001, + C_WHITE = 0002, + C_SPACE = 0004, + C_PUNCT = 0010, + C_OCTAL = 0020, + C_DIGIT = 0040, + C_UPPER = 0100, + C_LOWER = 0200 +}; + +extern const unsigned char class_char[]; + +#define asciichar(c) ((unsigned)(c) <= 0177) +#define alnumchar(c) (asciichar(c)&&(class_char[c]&\ + (C_DIGIT|C_OCTAL|C_UPPER|C_LOWER))) +#define alphachar(c) (asciichar(c)&&(class_char[c]&(C_UPPER|C_LOWER))) +#define blankchar(c) (asciichar(c)&&(class_char[c]&(C_BLANK))) +#define cntrlchar(c) (asciichar(c)&&(class_char[c]==C_CNTRL) +#define digitchar(c) (asciichar(c)&&(class_char[c]&(C_DIGIT|C_OCTAL))) +#define lowerchar(c) (asciichar(c)&&(class_char[c]&(C_LOWER))) +#define punctchar(c) (asciichar(c)&&(class_char[c]&(C_PUNCT))) +#define spacechar(c) (asciichar(c)&&(class_char[c]&(C_BLANK|C_SPACE|C_WHITE))) +#define upperchar(c) (asciichar(c)&&(class_char[c]&(C_UPPER))) +#define whitechar(c) (asciichar(c)&&(class_char[c]&(C_BLANK|C_WHITE))) +#define octalchar(c) (asciichar(c)&&(class_char[c]&(C_OCTAL))) +#define graphchar(c) (asciichar(c)&&(class_char[c]&\ + (C_UPPER|C_LOWER|C_DIGIT|C_OCTAL|C_PUNCT))) +#define printchar(c) ((c)==' ' || asciichar(c)&&(class_char[c]&\ + (C_UPPER|C_LOWER|C_DIGIT|C_OCTAL|C_PUNCT))) + +#define upperconv(c) (lowerchar(c) ? (c)-'a'+'A' : (c)) +#define lowerconv(c) (upperchar(c) ? (c)-'A'+'a' : (c)) diff --git a/package/heirloom-cpio/src/atoll.h b/package/heirloom-cpio/src/atoll.h new file mode 100644 index 000000000..8283aff64 --- /dev/null +++ b/package/heirloom-cpio/src/atoll.h @@ -0,0 +1,8 @@ +/* Sccsid @(#)atoll.h 1.4 (gritter) 7/18/04 */ + +#if defined (__hpux) || defined (_AIX) || \ + defined (__FreeBSD__) && (__FreeBSD__) < 5 +extern long long strtoll(const char *nptr, char **endptr, int base); +extern unsigned long long strtoull(const char *nptr, char **endptr, int base); +extern long long atoll(const char *nptr); +#endif /* __hpux || _AIX || __FreeBSD__ < 5 */ diff --git a/package/heirloom-cpio/src/blank.h b/package/heirloom-cpio/src/blank.h new file mode 100644 index 000000000..1ab3d57b8 --- /dev/null +++ b/package/heirloom-cpio/src/blank.h @@ -0,0 +1,38 @@ +/* + * isblank() and iswblank() are not available with many pre-XSH6 + * systems. Check whether isblank was defined, and assume it is + * not available if not. + */ +/* Sccsid @(#)blank.h 1.3 (gritter) 5/1/04 */ + +#ifndef __dietlibc__ +#ifndef LIBCOMMON_BLANK_H +#define LIBCOMMON_BLANK_H 1 + +#include +#include + +#ifndef isblank + +static +#ifdef __GNUC__ +__inline__ +#endif /* __GNUC__ */ +int +my_isblank(int c) +{ + return c == ' ' || c == '\t'; +} +#define isblank(c) my_isblank(c) + +static int +my_iswblank(wint_t c) +{ + return c == L' ' || c == L'\t'; +} +#undef iswblank +#define iswblank(c) my_iswblank(c) + +#endif /* !isblank */ +#endif /* !LIBCOMMON_BLANK_H */ +#endif /* !__dietlibc__ */ diff --git a/package/heirloom-cpio/src/blast.c b/package/heirloom-cpio/src/blast.c new file mode 100644 index 000000000..b62efd585 --- /dev/null +++ b/package/heirloom-cpio/src/blast.c @@ -0,0 +1,449 @@ +/* + * Changes by Gunnar Ritter, Freiburg i. Br., Germany, February 2004. + * + * Sccsid @(#)blast.c 1.2 (gritter) 2/17/04 + */ +/* blast.c + * Copyright (C) 2003 Mark Adler + * For conditions of distribution and use, see copyright notice in blast.h + * version 1.1, 16 Feb 2003 + * + * blast.c decompresses data compressed by the PKWare Compression Library. + * This function provides functionality similar to the explode() function of + * the PKWare library, hence the name "blast". + * + * This decompressor is based on the excellent format description provided by + * Ben Rudiak-Gould in comp.compression on August 13, 2001. Interestingly, the + * example Ben provided in the post is incorrect. The distance 110001 should + * instead be 111000. When corrected, the example byte stream becomes: + * + * 00 04 82 24 25 8f 80 7f + * + * which decompresses to "AIAIAIAIAIAIA" (without the quotes). + */ + +/* + * Change history: + * + * 1.0 12 Feb 2003 - First version + * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data + */ + +#include /* for setjmp(), longjmp(), and jmp_buf */ +#include "blast.h" /* prototype for blast() */ + +#define local static /* for local function definitions */ +#define MAXBITS 13 /* maximum code length */ +#define MAXWIN 4096 /* maximum window size */ + +/* input and output state */ +struct state { + /* input state */ + blast_in infun; /* input function provided by user */ + void *inhow; /* opaque information passed to infun() */ + unsigned char *in; /* next input location */ + unsigned left; /* available input at in */ + int bitbuf; /* bit buffer */ + int bitcnt; /* number of bits in bit buffer */ + + /* input limit error return state for bits() and decode() */ + jmp_buf env; + + /* output state */ + blast_out outfun; /* output function provided by user */ + void *outhow; /* opaque information passed to outfun() */ + unsigned next; /* index of next write location in out[] */ + int first; /* true to check distances (for first 4K) */ + unsigned char out[MAXWIN]; /* output buffer and sliding window */ +}; + +/* + * Return need bits from the input stream. This always leaves less than + * eight bits in the buffer. bits() works properly for need == 0. + * + * Format notes: + * + * - Bits are stored in bytes from the least significant bit to the most + * significant bit. Therefore bits are dropped from the bottom of the bit + * buffer, using shift right, and new bytes are appended to the top of the + * bit buffer, using shift left. + */ +local int bits(struct state *s, int need) +{ + int val; /* bit accumulator */ + + /* load at least need bits into val */ + val = s->bitbuf; + while (s->bitcnt < need) { + if (s->left == 0) { + s->left = s->infun(s->inhow, &(s->in)); + if (s->left == 0) longjmp(s->env, 1); /* out of input */ + } + val |= (int)(*(s->in)++) << s->bitcnt; /* load eight bits */ + s->left--; + s->bitcnt += 8; + } + + /* drop need bits and update buffer, always zero to seven bits left */ + s->bitbuf = val >> need; + s->bitcnt -= need; + + /* return need bits, zeroing the bits above that */ + return val & ((1 << need) - 1); +} + +/* + * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of + * each length, which for a canonical code are stepped through in order. + * symbol[] are the symbol values in canonical order, where the number of + * entries is the sum of the counts in count[]. The decoding process can be + * seen in the function decode() below. + */ +struct huffman { + short *count; /* number of symbols of each length */ + short *symbol; /* canonically ordered symbols */ +}; + +/* + * Decode a code from the stream s using huffman table h. Return the symbol or + * a negative value if there is an error. If all of the lengths are zero, i.e. + * an empty code, or if the code is incomplete and an invalid code is received, + * then -9 is returned after reading MAXBITS bits. + * + * Format notes: + * + * - The codes as stored in the compressed data are bit-reversed relative to + * a simple integer ordering of codes of the same lengths. Hence below the + * bits are pulled from the compressed data one at a time and used to + * build the code value reversed from what is in the stream in order to + * permit simple integer comparisons for decoding. + * + * - The first code for the shortest length is all ones. Subsequent codes of + * the same length are simply integer decrements of the previous code. When + * moving up a length, a one bit is appended to the code. For a complete + * code, the last code of the longest length will be all zeros. To support + * this ordering, the bits pulled during decoding are inverted to apply the + * more "natural" ordering starting with all zeros and incrementing. + */ +local int decode(struct state *s, struct huffman *h) +{ + int len; /* current number of bits in code */ + int code; /* len bits being decoded */ + int first; /* first code of length len */ + int count; /* number of codes of length len */ + int index; /* index of first code of length len in symbol table */ + int bitbuf; /* bits from stream */ + int left; /* bits left in next or left to process */ + short *next; /* next number of codes */ + + bitbuf = s->bitbuf; + left = s->bitcnt; + code = first = index = 0; + len = 1; + next = h->count + 1; + while (1) { + while (left--) { + code |= (bitbuf & 1) ^ 1; /* invert code */ + bitbuf >>= 1; + count = *next++; + if (code < first + count) { /* if length len, return symbol */ + s->bitbuf = bitbuf; + s->bitcnt = (s->bitcnt - len) & 7; + return h->symbol[index + (code - first)]; + } + index += count; /* else update for next length */ + first += count; + first <<= 1; + code <<= 1; + len++; + } + left = (MAXBITS+1) - len; + if (left == 0) break; + if (s->left == 0) { + s->left = s->infun(s->inhow, &(s->in)); + if (s->left == 0) longjmp(s->env, 1); /* out of input */ + } + bitbuf = *(s->in)++; + s->left--; + if (left > 8) left = 8; + } + return -9; /* ran out of codes */ +} + +/* + * Given a list of repeated code lengths rep[0..n-1], where each byte is a + * count (high four bits + 1) and a code length (low four bits), generate the + * list of code lengths. This compaction reduces the size of the object code. + * Then given the list of code lengths length[0..n-1] representing a canonical + * Huffman code for n symbols, construct the tables required to decode those + * codes. Those tables are the number of codes of each length, and the symbols + * sorted by length, retaining their original order within each length. The + * return value is zero for a complete code set, negative for an over- + * subscribed code set, and positive for an incomplete code set. The tables + * can be used if the return value is zero or positive, but they cannot be used + * if the return value is negative. If the return value is zero, it is not + * possible for decode() using that table to return an error--any stream of + * enough bits will resolve to a symbol. If the return value is positive, then + * it is possible for decode() using that table to return an error for received + * codes past the end of the incomplete lengths. + */ +local int construct(struct huffman *h, const unsigned char *rep, int n) +{ + int symbol; /* current symbol when stepping through length[] */ + int len; /* current length when stepping through h->count[] */ + int left; /* number of possible codes left of current length */ + short offs[MAXBITS+1]; /* offsets in symbol table for each length */ + short length[256]; /* code lengths */ + + /* convert compact repeat counts into symbol bit length list */ + symbol = 0; + do { + len = *rep++; + left = (len >> 4) + 1; + len &= 15; + do { + length[symbol++] = len; + } while (--left); + } while (--n); + n = symbol; + + /* count number of codes of each length */ + for (len = 0; len <= MAXBITS; len++) + h->count[len] = 0; + for (symbol = 0; symbol < n; symbol++) + (h->count[length[symbol]])++; /* assumes lengths are within bounds */ + if (h->count[0] == n) /* no codes! */ + return 0; /* complete, but decode() will fail */ + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; /* one possible code of zero length */ + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; /* one more bit, double codes left */ + left -= h->count[len]; /* deduct count from possible codes */ + if (left < 0) return left; /* over-subscribed--return negative */ + } /* left > 0 means incomplete */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + h->count[len]; + + /* + * put symbols in table sorted by length, by symbol order within each + * length + */ + for (symbol = 0; symbol < n; symbol++) + if (length[symbol] != 0) + h->symbol[offs[length[symbol]]++] = symbol; + + /* return zero for complete set, positive for incomplete set */ + return left; +} + +/* + * Decode PKWare Compression Library stream. + * + * Format notes: + * + * - First byte is 0 if literals are uncoded or 1 if they are coded. Second + * byte is 4, 5, or 6 for the number of extra bits in the distance code. + * This is the base-2 logarithm of the dictionary size minus six. + * + * - Compressed data is a combination of literals and length/distance pairs + * terminated by an end code. Literals are either Huffman coded or + * uncoded bytes. A length/distance pair is a coded length followed by a + * coded distance to represent a string that occurs earlier in the + * uncompressed data that occurs again at the current location. + * + * - A bit preceding a literal or length/distance pair indicates which comes + * next, 0 for literals, 1 for length/distance. + * + * - If literals are uncoded, then the next eight bits are the literal, in the + * normal bit order in th stream, i.e. no bit-reversal is needed. Similarly, + * no bit reversal is needed for either the length extra bits or the distance + * extra bits. + * + * - Literal bytes are simply written to the output. A length/distance pair is + * an instruction to copy previously uncompressed bytes to the output. The + * copy is from distance bytes back in the output stream, copying for length + * bytes. + * + * - Distances pointing before the beginning of the output data are not + * permitted. + * + * - Overlapped copies, where the length is greater than the distance, are + * allowed and common. For example, a distance of one and a length of 518 + * simply copies the last byte 518 times. A distance of four and a length of + * twelve copies the last four bytes three times. A simple forward copy + * ignoring whether the length is greater than the distance or not implements + * this correctly. + */ +local int decomp(struct state *s) +{ + int lit; /* true if literals are coded */ + int dict; /* log2(dictionary size) - 6 */ + int symbol; /* decoded symbol, extra bits for distance */ + int len; /* length for copy */ + int dist; /* distance for copy */ + int copy; /* copy counter */ + unsigned char *from, *to; /* copy pointers */ + static int virgin = 1; /* build tables once */ + static short litcnt[MAXBITS+1], litsym[256]; /* litcode memory */ + static short lencnt[MAXBITS+1], lensym[16]; /* lencode memory */ + static short distcnt[MAXBITS+1], distsym[64]; /* distcode memory */ + static struct huffman litcode = {litcnt, litsym}; /* length code */ + static struct huffman lencode = {lencnt, lensym}; /* length code */ + static struct huffman distcode = {distcnt, distsym};/* distance code */ + /* bit lengths of literal codes */ + static const unsigned char litlen[] = { + 11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8, + 9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5, + 7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12, + 8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27, + 44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45, + 44, 173}; + /* bit lengths of length codes 0..15 */ + static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23}; + /* bit lengths of distance codes 0..63 */ + static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248}; + static const short base[16] = { /* base for length codes */ + 3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264}; + static const char extra[16] = { /* extra bits for length codes */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8}; + + /* set up decoding tables (once--might not be thread-safe) */ + if (virgin) { + construct(&litcode, litlen, sizeof(litlen)); + construct(&lencode, lenlen, sizeof(lenlen)); + construct(&distcode, distlen, sizeof(distlen)); + virgin = 0; + } + + /* read header */ + lit = bits(s, 8); + if (lit > 1) return -1; + dict = bits(s, 8); + if (dict < 4 || dict > 6) return -2; + + /* decode literals and length/distance pairs */ + do { + if (bits(s, 1)) { + /* get length */ + symbol = decode(s, &lencode); + len = base[symbol] + bits(s, extra[symbol]); + if (len == 519) break; /* end code */ + + /* get distance */ + symbol = len == 2 ? 2 : dict; + dist = decode(s, &distcode) << symbol; + dist += bits(s, symbol); + dist++; + if (s->first && dist > s->next) + return -3; /* distance too far back */ + + /* copy length bytes from distance bytes back */ + do { + to = s->out + s->next; + from = to - dist; + copy = MAXWIN; + if (s->next < dist) { + from += copy; + copy = dist; + } + copy -= s->next; + if (copy > len) copy = len; + len -= copy; + s->next += copy; + do { + *to++ = *from++; + } while (--copy); + if (s->next == MAXWIN) { + if (s->outfun(s->outhow, s->out, s->next)) return 1; + s->next = 0; + s->first = 0; + } + } while (len != 0); + } + else { + /* get literal and write it */ + symbol = lit ? decode(s, &litcode) : bits(s, 8); + s->out[s->next++] = symbol; + if (s->next == MAXWIN) { + if (s->outfun(s->outhow, s->out, s->next)) return 1; + s->next = 0; + s->first = 0; + } + } + } while (1); + return 0; +} + +/* See comments in blast.h */ +int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow) +{ + struct state s; /* input/output state */ + int err; /* return value */ + + /* initialize input state */ + s.infun = infun; + s.inhow = inhow; + s.left = 0; + s.bitbuf = 0; + s.bitcnt = 0; + + /* initialize output state */ + s.outfun = outfun; + s.outhow = outhow; + s.next = 0; + s.first = 1; + + /* return if bits() or decode() tries to read past available input */ + if (setjmp(s.env) != 0) /* if came back here via longjmp(), */ + err = 2; /* then skip decomp(), return error */ + else + err = decomp(&s); /* decompress */ + + /* write any leftover output and update the error code if needed */ + if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0) + err = 1; + return err; +} + +#ifdef TEST +/* Example of how to use blast() */ +#include +#include + +#define CHUNK 16384 + +local unsigned inf(void *how, unsigned char **buf) +{ + static unsigned char hold[CHUNK]; + + *buf = hold; + return fread(hold, 1, CHUNK, (FILE *)how); +} + +local int outf(void *how, unsigned char *buf, unsigned len) +{ + return fwrite(buf, 1, len, (FILE *)how) != len; +} + +/* Decompress a PKWare Compression Library stream from stdin to stdout */ +int main(void) +{ + int ret, n; + + /* decompress to stdout */ + ret = blast(inf, stdin, outf, stdout); + if (ret != 0) fprintf(stderr, "blast error: %d\n", ret); + + /* see if there are any leftover bytes */ + n = 0; + while (getchar() != EOF) n++; + if (n) fprintf(stderr, "blast warning: %d unused bytes of input\n", n); + + /* return blast() error code */ + return ret; +} +#endif diff --git a/package/heirloom-cpio/src/blast.h b/package/heirloom-cpio/src/blast.h new file mode 100644 index 000000000..0c16d1391 --- /dev/null +++ b/package/heirloom-cpio/src/blast.h @@ -0,0 +1,76 @@ +/* + * Changes by Gunnar Ritter, Freiburg i. Br., Germany, February 2004. + * + * Sccsid @(#)blast.h 1.2 (gritter) 2/17/04 + */ +/* blast.h -- interface for blast.c + Copyright (C) 2003 Mark Adler + version 1.1, 16 Feb 2003 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. 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. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + + +/* + * blast() decompresses the PKWare Data Compression Library (DCL) compressed + * format. It provides the same functionality as the explode() function in + * that library. (Note: PKWare overused the "implode" verb, and the format + * used by their library implode() function is completely different and + * incompatible with the implode compression method supported by PKZIP.) + */ + + +typedef unsigned (*blast_in)(void *how, unsigned char **buf); +typedef int (*blast_out)(void *how, unsigned char *buf, unsigned len); +/* Definitions for input/output functions passed to blast(). See below for + * what the provided functions need to do. + */ + + +int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow); +/* Decompress input to output using the provided infun() and outfun() calls. + * On success, the return value of blast() is zero. If there is an error in + * the source data, i.e. it is not in the proper format, then a negative value + * is returned. If there is not enough input available or there is not enough + * output space, then a positive error is returned. + * + * The input function is invoked: len = infun(how, &buf), where buf is set by + * infun() to point to the input buffer, and infun() returns the number of + * available bytes there. If infun() returns zero, then blast() returns with + * an input error. (blast() only asks for input if it needs it.) inhow is for + * use by the application to pass an input descriptor to infun(), if desired. + * + * The output function is invoked: err = outfun(how, buf, len), where the bytes + * to be written are buf[0..len-1]. If err is not zero, then blast() returns + * with an output error. outfun() is always called with len <= 4096. outhow + * is for use by the application to pass an output descriptor to outfun(), if + * desired. + * + * The return codes are: + * + * 2: ran out of input before completing decompression + * 1: output error before completing decompression + * 0: successful decompression + * -1: literal flag not zero or one + * -2: dictionary size not in 4..6 + * -3: distance is too far back + * + * At the bottom of blast.c is an example program that uses blast() that can be + * compiled to produce a command-line decompression filter by defining TEST. + */ diff --git a/package/heirloom-cpio/src/cpio.1 b/package/heirloom-cpio/src/cpio.1 new file mode 100644 index 000000000..9c8b1f98c --- /dev/null +++ b/package/heirloom-cpio/src/cpio.1 @@ -0,0 +1,943 @@ +'\" t +.\" Copyright (c) 2003 Gunnar Ritter +.\" +.\" This software is provided 'as-is', without any express or implied +.\" warranty. In no event will the authors be held liable for any damages +.\" arising from the use of this software. +.\" +.\" Permission is granted to anyone to use this software for any purpose, +.\" including commercial applications, and to alter it and redistribute +.\" it freely, subject to the following restrictions: +.\" +.\" 1. 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. +.\" +.\" 2. Altered source versions must be plainly marked as such, and must not be +.\" misrepresented as being the original software. +.\" +.\" 3. This notice may not be removed or altered from any source distribution. +.\" Sccsid @(#)cpio.1 1.92 (gritter) 3/26/07 +.TH CPIO 1 "3/26/07" "Heirloom Toolchest" "User Commands" +.SH NAME +cpio \- copy file archives in and out +.SH SYNOPSIS +.PD 0 +.HP +.nh +.ad l +\fBcpio\fR \fB\-i\fR[\fBbcdfkmrstuvBSV6\fR] [\fB\-C\fI\ size\fR] +[\fB\-E\fI\ file\fR] [\fB\-H\fI\ hdr\fR] [[\fB\-I\fI\ file\fR] +[\fB\-M\fI\ msg\fR]] [\fB\-R\fI\ id\fR] [\fIpatterns\fR] +.HP +.ad l +\fBcpio\fR \fB\-o\fR[\fBacvABLPV\fR] [\fB\-C\fI\ size\fR] +[\fB\-H\fI\ hdr\fR] [[\fB\-M\fI\ msg\fR] [\fB\-O\fI\ file\fR]] +.HP +.ad l +\fBcpio\fR \fB\-p\fR[\fBadlmPuvLV\fR] [\fB\-R\fI\ id\fR] \fIdirectory\fR +.br +.PD +.ad b +.hy 1 +.SH DESCRIPTION +.I Cpio +creates and extracts file archives and copies files. +.PP +With the +.B \-i +option, +.I cpio +works in +.RI ` copy-in ' +mode and extracts files from a file archive. +By default, +the archive is read from standard input. +Optional arguments are interpreted as +.I patterns +and restrict the set of extracted files +to those matching any of the +.IR patterns . +A +.RB ` !\& ' +at the beginning of the +.I pattern +selects all files that do not match this +.IR pattern . +The syntax is otherwise identical to that described in +.IR glob (7), +except that the slash character +.RB ` / ' +is matched by +meta-character constructs with +.RB ` * ', +.RB ` ? ' +and +.RB ` [ '. +Care must be taken to quote meta-characters appropriately from the shell. +File permissions are set to those in the archive; +if the caller is the super-user, +ownerships are restored as well. +.I Cpio +will not create directories, +preserve modification times +or overwrite more recently modified target files +unless the appropriate +.IR \-d , +.I \-m +or +.I \-u +options are specified. +Archives compressed with +.IR bzip2 (1), +.IR compress (1), +.IR gzip (1), +or +.IR rpm (1) +are transparently de\%compressed on input. +.PP +With +.BR \-o , +.I cpio +works in +.RI ` copy-out ' +mode, +creates archives +and writes them to standard output per default. +A list of filenames to be included in the archive is +read from standard input; +if the name of a directory appears, +it is included in the archive, +but +.I cpio +will not include any of its members +unless they are explicitly given in addition. +The +.IR find (1) +utility is useful to generate a list of files +(see also its +.I \-cpio +and +.I \-ncpio +operators). +When producing a filename list for +.IR cpio , +find should always be invoked with +.I \-depth +since this makes it possible to extract write-protected directories +for users other than the super-user. +.PP +The +.B \-p +option selects +.RI ` pass ' +mode; +a list of files is read from standard input as described for +.IR \-o ; +files are copied to the specified +.IR directory , +preserving attributes as described for +.IR \-i . +Special files are re-created in the target hierarchy, +and hard links between copied files are preserved. +.PP +When a premature end-of-file is detected with +.I \-i +and +.I \-o +and the archive is a block or character special file, +the user is prompted for new media. +.PP +The following options alter the behavior of +.IR cpio : +.TP +.B \-a +Resets the access times of files +that were included in the archive with +.I \-o +or copied with +.IR \-p . +.TP +.B \-A +Append files to the archive. +The archive must be seekable, +such as a regular file or a block device, +or a tape device capable of writing between filemarks. +.TP +.B \-b +Swap bytes within each half word +and half words within each word +of input file data. +.TP +.B \-B +Blocks input and output archives at 5120 byte records. +The default blocking size is device dependent. +.TP +.B \-c +Specifies that archive headers are in SVR4 ASCII cpio format. +This option is ignored with +.I \-i +unless the +.I \-k +option is also present. +.TP +\fB\-C\fI size\fR +Blocks input and output archives at +.I size +byte records. +.TP +.B \-d +Creates missing parent directories +for each file extracted from the archive +and allows the extraction of directories. +.TP +\fB\-E\fI file\fR +Each line read from +.I file +is taken as a pattern in addition +to those specified on the command line. +.TP +.B \-f +Reverses the sense of patterns +such that a file that does not match any of the patterns +is selected. +.TP +\fB\-H\fI header\fR +Specifies the archive header format to be one of: +.sp +.in +6 +.TS +lfB l. +\fBcrc\fR SVR4 ASCII cpio format with checksum;\ +\fBsco\fR T{ +SCO UnixWare 7.1 ASCII cpio format; +T} +\fBscocrc\fR T{ +SCO UnixWare 7.1 ASCII cpio format with checksum; +T} +\fBodc\fR T{ +traditional ASCII cpio format, as standardized in IEEE Std. 1003.1, 1996; +T} +\fBbbs\fR byte-swapped binary cpio format; +\fBsgi\fR T{ +SGI IRIX extended binary cpio format; +T} +\fBcray\fR T{ +Cray UNICOS 9 cpio format; +T} +\fBcray5\fR T{ +Cray UNICOS 5 cpio format; +T} +\fBdec\fR T{ +Digital UNIX extended cpio format; +T} +\fBtar\fR tar format; +\fBotar\fR old tar format; +\fBustar\fR T{ +IEEE Std. 1003.1, 1996 tar format; +T} +.T& +l s. +\fBpax\fR[\fB:\fIoption\fB,\fR[\fIoption\fB,\fR\|...]] +.T& +l l. +\& T{ +IEEE Std. 1003.1, 2001 pax format. +Format-specific \fIoptions\fR are: +.in +2n +.ti 0 +.br +\fBlinkdata\fR +.br +For a regular file which has multiple hard links, +the file data is stored once for each link in the archive, +instead of being stored for the first entry only. +This option must be used with care +since many implementations are unable +to read the resulting archive. +.ti 0 +.br +\fBtimes\fR +.br +Causes the times of last access and last modification +of each archived file +to be stored in an extended \fIpax\fR header. +This in particular allows the time of last access +to be restored when the archive is read. +.br +.in -2n +T} +\fBsun\fR T{ +Sun Solaris 7 extended tar format; +T} +\fBgnu\fR T{ +GNU tar format; +T} +\fBbar\fR T{ +SunOS 4 bar format; +T} +\fBzip\fR[\fB:\fIcc\fR] T{ +zip format with optional compression method. +If \fIcc\fR is one of +\fBen\fR (normal, default), +\fBex\fR (extra), +\fBef\fR (fast), +or +\fBes\fR (super fast), +the standard \fIdeflate\fR compression is used. +\fBe0\fR selects no compression, +and +\fBbz2\fR selects \fIbzip2\fR compression. +T} +.TE +.in -6 +.sp +This option is ignored with +.I \-i +unless the +.I \-k +option is also present. +The default for +.I \-o +is binary cpio format. +.TP +\fB\-I\fI\ file\fR +Selects a +.I file +that is read with the +.I \-i +option instead of standard input. +.TP +.B \-k +Try to continue operation on read errors and invalid headers. +If an archive contains another archive, +files from either archive may be chosen. +.TP +.B \-l +Link files instead of copying them with +.I \-p +if possible. +.TP +.B \-L +Follow symbolic links when reading files with +.I \-o +or +.IR \-p . +.TP +.B \-m +Restore modification times of extracted files +to those given in the archive. +.TP +\fB\-M\fI message\fR +The given +.I message +is printed instead of the standard one +with +.I \-I +or +.I \-O +when changing media. +.TP +\fB\-O\fI file\fR +Selects an archive +.I file +that is written instead of standard output +with the +.I \-o +option. +.TP +.B \-P +In copy-out or pass mode, +interpret the data read from standard input +as prototype lines +of colon-separated fields +of the form +.in +3m +.sp +\fItype\fB:\fIuser\fB:\fIgroup\fB:\fImode\fB:\fIatime\fB:\fImtime\fB:\fImajor\fB:\fIminor\fB:\fIpath\fR +.sp +.in -3m +For each non-empty field, +the corresponding attribute of the input file is overridden. +With this option, +an unprivileged user can create +an archive that contains files +with arbitrary attributes. +The meanings of the individual fields are: +.RS +.TP 6 +.PD 0 +.I type +File type, one of: +\fBb\fR (block device), +\fBc\fR (character device), +\fBd\fR (directory), +\fBf\fR (plain file), +\fBp\fR (named pipe), +or +\fBs\fR (symbolic link). +.TP +.I user +The owner of the file, +which can be a numeric user ID or a user name. +.TP +.I group +The group owner of the file, +which can be a numeric group ID or a group name. +.TP +.I mode +The octal mode of the file. +.TP +.I atime +The time the file was last accessed. +Note that most archive formats cannot store this attribute, +in which case it is ignored. +The format is the same as that of the +.I mtime +field. +.TP +.I mtime +The time the file was last modified. +This is either a decimal integer +specifying the seconds past the epoch, +or an ISO\ 8601 date and time field +of the format \fIYYYYMMDD\fBT\fIHHMMSS\fR, +e.g. 20070326T190511, +the latter being relative to the current time zone +and with all digits past the \fBT\fR being optional. +.TP +.I major minor +Major and minor device numbers as with +.IR mknod (1M). +These fields are only allowed for block and character devices. +.TP +.I path +The name of the file to be archived. +If the file is not a symbolic link, +and the specification is otherwise sufficient, +the file needs not exist +at the time the archive is created. +A non-existent regular file will be empty in the archive. +.PD +.RE +.IP +This option is an extension. +.TP +.B \-r +Rename files interactively. +Before a file is extracted from the archive, +its file name is printed on standard error +and the user is prompted to specify a substitute file name. +If the line read from the terminal is empty, +the file is skipped; +if the line consists of a single dot, +the name is retained; +otherwise, +the line forms the new file name. +.TP +\fB\-R\fI user\fR +Set the ownership of extracted files +to the user and group ids of +.I user +instead of those specified in the archive. +Valid only for the super-user. +.TP +.B \-s +Swap bytes within each half word +of input file data. +.TP +.B \-S +Swap half words within each word +of input file data. +.TP +.B \-t +When combined with the +.I \-o +option, +a list of files in the archive is written to standard output; +no files are extracted. +.TP +.B \-u +.I Cpio +will overwrite existing target files +that were modified more recently than the file in the archive +when this option is given. +.TP +.B \-v +Prints the file names of archived or extracted files with +.I \-i +and +.I \-o +and a verbose output format with +.IR \-t . +If given twice +.RB ( \-vv ) +in combination with +.I \-t +when reading a +.I zip +archive, +information about compression level and method is printed. +.TP +.B \-V +Prints a dot for each archived or extracted file. +.TP +.B \-6 +Selects Unix 6th Edition archive format +(only in copy-in mode). +.PP +.ne 37 +Characteristics of archive formats are as follows: +.sp +.TS +allbox; +l r r r l +l1fB r2 n2 r2 c. + T{ +.ad l +maximum user/\%group id +T} T{ +.ad l +maximum file size +T} T{ +.ad l +maximum pathname length +T} T{ +.ad l +bits in dev_t (major/minor) +T} +binary 65535 2 GB\ 256 \ 16 +\-H\ sgi 65535 9 EB\ 256 \ 14/18 +\-H\ odc 262143 8 GB\ 256 \ 18 +\-H\ dec 262143 8 GB\ 256 \ 24/24 +T{ +\-c, \-H\ crc +T} 4.3e9 4 GB\ 1024 \ 32/32 +T{ +\-H\ sco, \-H\ scocrc +T} 4.3e9 9 EB\ 1024 \ 32/32 +T{ +\-H\ cray, \-H\ cray5 +T} 1.8e19 9 EB\ 65535 \ 64 +\-H\ otar 2097151 8 GB\ 99 \ n/a +T{ +\-H\ tar, +\-H\ ustar +T} 2097151 8 GB\ 256 (99) \ 21/21 +\-H\ pax 1.8e19 9 EB\ 65535 \ 21/21 +\-H\ sun 1.8e19 9 EB\ 65535 \ 63/63 +\-H\ gnu 1.8e19 9 EB\ 65535 \ 63/63 +\-H\ bar 2097151 8 GB\ 427 \ 21 +\-H\ zip 4.3e9 9 EB\ 60000 \ 32 +.TE +.sp +.PP +By default, +.B binary +cpio archives are written. +The byte order of such archives +depends on the machine +on which the archive is created. +Unlike some other implementations, +.I cpio +fully supports +archives of either byte order. +.I \-H\ bbs +can be used to create an archive +with the byte order opposed to that of the current machine. +.PP +The +.B sgi +format extends the binary format +to handle larger files and more device bits. +If an archive does not contain any entries +that actually need the extensions, +it is identical to a binary archive. +.I \-H\ sgi +archives are always created in MSB order. +.PP +The +.B odc +format was introduced with System\ III +and standardized with IEEE Std. 1003.1. +All known +.I cpio +implementations since around 1980 can read this format. +.PP +The +.B dec +format extends the +.I odc +format +to support more device bits. +Archives in this format are generally incompatible with +.I odc +archives +and need special implementation support to be read. +.PP +The +.B \-c +format was introduced with System\ V Release\ 4. +Except for the file size, +it imposes no practical limitations +on files archived. +The original SVR4 implementation +stores the contents of hard linked files +only once and with the last archived link. +This +.I cpio +ensures compatibility with SVR4. +With archives created by implementations that employ other methods +for storing hard linked files, +each file is extracted as a single link, +and some of these files may be empty. +Implementations that expect methods other than the original SVR4 one +may extract no data for hard linked files at all. +.PP +The +.B crc +format is essentially the same as the +.I \-c +format +but adds a simple checksum (not a CRC, despite its name) +for the data of regular files. +The checksum requires the implementation to read each file twice, +which can considerably increase running time and system overhead. +As not all implementations claiming to support this format +handle the checksum correctly, +it is of limited use. +.PP +The +.B sco +and +.B scocrc +formats are variants of the +.I \-c +and +.I \-H\ crc +formats, respectively, +with extensions to support larger files. +The extensions result in a different archive format +only if files larger than slightly below 2\ GB occur. +.PP +The +.B cray +format extends all header fields to 64 bits. +It thus imposes no practical limitations of any kind +on archived files, +but requires special implementation support +to be read. +Although it is originally a binary format, +the byte order is always MSB as on Cray machines. +The +.B cray5 +format is an older variant +that was used with UNICOS 5 and earlier. +.PP +The +.B otar +format was introduced with the Unix 7th Edition +.I tar +utility. +Archives in this format +can be read on all Unix systems since about 1980. +It can only hold regular files +(and, on more recent systems, symbolic links). +For file names that contain characters with the most significant bit set +(non-ASCII characters), +implementations differ in the interpretation of the header checksum. +.PP +The +.B ustar +format was introduced with IEEE Std. 1003.1. +It extends the old +.I tar +format +with support for directories, device files, +and longer file names. +Pathnames of single-linked files can consist of up to 256 characters, +dependent on the position of slashes. +Files with multiple links can only be archived +if the first link encountered is no longer than 100 characters. +Due to implementation errors, +file names longer than 99 characters +can not considered to be generally portable. +Another addition of the +.I ustar +format +are fields for the symbolic user and group IDs. +These fields are created by +.IR cpio , +but ignored when reading such archives. +.PP +With +.BR "\-H tar" , +a variant of the +.I ustar +format is selected +which stores file type bits in the mode field +to work around common implementation problems. +These bits are ignored by +.I cpio +when reading archives. +.PP +The +.B pax +format is an extension to the +.I ustar +format. +If attributes cannot be archived with +.IR ustar , +an extended header is written. +Unless the size of an entry is greater than 8\ GB, +a +.I pax +archive should be readable by any implementation +capable of reading +.I ustar +archives, +although files may be extracted under wrong names +and extended headers may be extracted as separate files. +If a file name contains non-UTF-8 characters, +it may not be archived or extracted correctly +because of a problem of the +.I pax +format specification. +.PP +The +.B sun +format extends the +.I ustar +format similar as the +.I pax +format does. +The extended headers in +.I sun +format archives are not understood +by implementations that support only the +.I pax +format and vice-versa. +The +.I sun +format has also problems with non-UTF-8 characters in file names. +.PP +The +.B GNU +.I tar +format is mostly compatible with the other +.I tar +formats, +unless an archive entry actually uses its extended features. +There are no practical limitations on files archived with this format. +The implementation of +.I cpio +is limited to expanded numerical fields +and long file names; +in particular, +there is no support for sparse files or incremental backups. +If +.I cpio +creates a multi-volume +.I GNU +archive, +it just splits a single-volume archive in multiple parts, +as with the other formats; +.I GNU +multi-volume archives are not supported. +.PP +The +.B bar +format is similar to the +.I tar +format, but can store longer file names. +It requires special implementation support to be read. +.PP +The +.B zip +format can be read in many non-Unix environments. +There are several restrictions on archives +intended for data exchange: +only regular files should be stored; +file times, permissions and ownerships +might be ignored by other implementations; +there should be no more than 65536 files in the archive; +the total archive size should not exceed 2 GB; +only +.I deflate +compression should be used. +Otherwise, +.I cpio +stores all information available with other archive formats +in extended +.I zip +file headers, +so if archive portability is of no concern, +the +.I zip +implementation in +.I cpio +can archive complete Unix file hierarchies. +.I Cpio +supports the +.I zip64 +format extension for large files; +it automatically writes +.I zip64 +entries if necessary. +.I Cpio +can extract all known +.I zip +format compression codes. +It does not support +.I zip +encryption. +Multi-volume +.I zip +archives are created as splitted single-volume archives, +as with the other formats written by +.IR cpio ; +generic multi-volume +.I zip +archives are not supported. +.SH EXAMPLES +Extract all files named +.I Makefile +or +.I makefile +from the archive stored on +.IR /dev/rmt/c0s0 , +overwriting recent files: +.RS 2 +.sp +cpio \-idmu \-I /dev/rmt/c0s0 \'[Mm]akefile\' \'*/[Mm]akefile\' +.RE +.PP +List the files contained in a software distribution archive: +.RS 2 +.sp +cpio \-itv \-I distribution.tar.gz +.RE +.PP +Write a +.IR gzip (1) +compressed +.I ustar +archive containing all files below the directory +.I \%project +to the file +.IR \%project.tar.gz , +excluding all directories named +.I CVS +or +.I SCCS +and their contents: +.RS 2 +.sp +find project \-depth \-print | egrep \-v \'/(CVS|SCCS)(/|$)\' | +.br + cpio \-o \-H ustar | gzip \-c > project.tar.gz +.RE +.PP +Copy the directory +.I work +and its contents +to the directory +.IR \%savedfiles : +.RS 2 +.sp +find work \-depth \-print | cpio \-pdm savedfiles +.RE +.PP +Self-extracting zip archives are not automatically recognized, +but can normally be read using the +.I \-k +option, as with +.RS 2 +.sp +cpio \-itvk \-H zip \-I archive.exe +.sp +.RE +.SH "ENVIRONMENT VARIABLES" +.TP +.BR LANG ", " LC_ALL +See +.IR locale (7). +.TP +.B LC_CTYPE +Selects the mapping of bytes to characters +used for matching patterns. +.TP +.B LC_TIME +Sets the month names printed with +.IR \-tv . +.TP +.B SYSV3 +If this variable is set, +the +.I \-c +option has the same effect as \fI\-H odc\fR; +\fB\-H newc\fR can be used +to select SVR4 ASCII format. +The output format of +.I \-tv +is changed, as well as the text of diagnostic messages. +.SH "SEE ALSO" +find(1), +pax(1), +tar(1) +.SH DIAGNOSTICS +.I Cpio +exits with +.sp +.TS +l8fB l. +0 after successful operation; +1 on usage errors; +2 when operation was continued after minor errors; +3 on fatal error conditions. +.TE +.SH NOTES +Device and inode numbers +are used for hard link recognition +with the various cpio formats. +Since the header space cannot hold +large numbers present in current file systems, +devices and inode numbers are set on a per-archive basis. +This enables hard link recognition with all cpio formats, +but the link connection to files appended with +.I \-A +is not preserved. +.PP +If a numeric user or group id does not fit +within the size of the header field in the selected format, +files are stored with the user id (or group id, respectively) +set to 60001. +.PP +Use of the +.I \-A +option with a +.I zip +format archive may cause data loss +if the archive was not previously created by +.I cpio +itself. +.PP +.I Cpio +cannot store file names that contain newline characters; +see the +.I NOTES +section of +.IR find (1) +for more information. +.PP +If the file names passed to +.I "cpio \-o" +begin with a slash character, +absolute path names are stored in the archive +and will be extracted to these path names later +regardless of the current working directory. +This is normally not advisable, +and relative path names should be passed to +.I cpio +only. diff --git a/package/heirloom-cpio/src/cpio.c b/package/heirloom-cpio/src/cpio.c new file mode 100644 index 000000000..e5090e4c9 --- /dev/null +++ b/package/heirloom-cpio/src/cpio.c @@ -0,0 +1,7172 @@ +/* + * cpio - copy file archives in and out + * + * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. + */ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +/* + * Sccsid @(#)cpio.c 1.304 (gritter) 2/14/09 + */ + +#include +#include +#ifdef __linux__ +#if !defined (__UCLIBC__) && !defined (__dietlibc__) +#include +#endif /* !__UCLIBC__, !__dietlibc__ */ +#include +#undef WNOHANG +#undef WUNTRACED +#undef P_ALL +#undef P_PID +#undef P_PGID +#ifdef __dietlibc__ +#undef NR_OPEN +#undef PATH_MAX +#endif /* __dietlibc__ */ +#endif /* __linux__ */ +#include +#include +#include +#include +#include +#include +#include "sigset.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "memalign.h" + +int sysv3; + +#if USE_ZLIB +#include +#endif /* USE_ZLIB */ + +#if USE_BZLIB +#include +#endif /* USE_BZLIB */ + +#include + +#if defined (__linux__) || defined (__sun) || defined (__FreeBSD__) || \ + defined (__hpux) || defined (_AIX) || defined (__NetBSD__) || \ + defined (__OpenBSD__) || defined (__DragonFly__) || \ + defined (__CYGWIN__) +#include +#endif + +#include +#include +#include + +#ifdef _AIX +#include +#endif /* _AIX */ + +#ifndef major +#include +#endif /* !major */ + +#include "cpio.h" +#include "blast.h" + +#ifdef __GLIBC__ +#ifdef _IO_putc_unlocked +#undef putc +#define putc(c, f) _IO_putc_unlocked(c, f) +#undef putchar +#define putchar(c) _IO_putc_unlocked(c, stdout) +#endif /* _IO_putc_unlocked */ +#endif /* __GLIBC__ */ + +/* + * The cpio code assumes that all following S_IFMT bits are the same as + * those of the mode fields in cpio headers. The only real Unix system + * known to deviate from this de facto standard is UNICOS which uses + * 0130000 for S_IFLNK. But this software does not run on UNICOS for + * a variety of other reasons anyway, so this should not be of much + * concern. + */ +#if S_IFIFO != 0010000 || \ + S_IFCHR != 0020000 || \ + S_IFDIR != 0040000 || \ + S_IFBLK != 0060000 || \ + S_IFREG != 0100000 || \ + S_IFLNK != 0120000 || \ + S_IFSOCK!= 0140000 || \ + S_IFMT != 0170000 +#error non-standard S_IFMT bits +#endif + +/* + * File types that are not present on all systems but that we want to + * recognize nevertheless. + */ +#ifndef S_IFDOOR +#define S_IFDOOR 0150000 /* Solaris door */ +#endif +#ifndef S_IFNAM +#define S_IFNAM 0050000 /* XENIX special named file */ +#endif +#ifndef S_INSEM +#define S_INSEM 0x1 /* XENIX semaphore subtype of IFNAM */ +#endif +#ifndef S_INSHD +#define S_INSHD 0x2 /* XENIX shared data subtype of IFNAM */ +#endif +#ifndef S_IFNWK +#define S_IFNWK 0110000 /* HP-UX network special file */ +#endif + +#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \ + defined (__DragonFly__) || defined (__APPLE__) +/* + * For whatever reason, FreeBSD casts the return values of major() and + * minor() to signed values so that normal limit comparisons will fail. + */ +static unsigned long +mymajor(long dev) +{ + return major(dev) & 0xFFFFFFFFUL; +} +#undef major +#define major(a) mymajor(a) +static unsigned long +myminor(long dev) +{ + return minor(dev) & 0xFFFFFFFFUL; +} +#undef minor +#define minor(a) myminor(a) +#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ + +/* + * Device and inode counts in cpio formats are too small to store the + * information used to detect hard links on today's systems. Keep track + * of all devices and inodes and store fake counts in the archive. + */ +struct ilink { + struct ilink *l_nxt; /* next link to same i-node */ + char *l_nam; /* link name */ + size_t l_siz; /* link name size */ +}; + +struct islot { + struct islot *i_lln; /* left link */ + struct islot *i_rln; /* right link */ + struct ilink *i_lnk; /* links list */ + struct stat *i_st; /* stat information */ + char *i_name;/* name of first link encountered */ + ino_t i_ino; /* real inode number */ + uint32_t i_fino; /* fake inode number */ + nlink_t i_nlk; /* number of remaining links */ +}; + +struct dslot { + struct dslot *d_nxt; /* next device */ + struct islot *d_isl; /* inode slots */ + uint32_t d_cnt; /* used inode number count */ + uint32_t d_fake; /* faked device id */ + dev_t d_dev; /* real device id */ +}; + +union types2 { + uint8_t byte[2]; + uint16_t sword; +}; + +union types4 { + uint8_t byte[4]; + uint16_t sword[2]; + uint32_t lword; +}; + +/* + * Store and retrieve integers in a defined endian order. + */ +static uint16_t +ple16(const char *cp) +{ + return (uint16_t)(cp[0]&0377) + + ((uint16_t)(cp[1]&0377) << 8); +} + +static uint16_t +pbe16(const char *cp) +{ + return (uint16_t)(cp[1]&0377) + + ((uint16_t)(cp[0]&0377) << 8); +} + +static uint32_t +ple32(const char *cp) +{ + return (uint32_t)(cp[0]&0377) + + ((uint32_t)(cp[1]&0377) << 8) + + ((uint32_t)(cp[2]&0377) << 16) + + ((uint32_t)(cp[3]&0377) << 24); +} + +static uint32_t +pbe32(const char *cp) +{ + return (uint32_t)(cp[3]&0377) + + ((uint32_t)(cp[2]&0377) << 8) + + ((uint32_t)(cp[1]&0377) << 16) + + ((uint32_t)(cp[0]&0377) << 24); +} + +static uint32_t +pme32(const char *cp) +{ + return (uint32_t)(cp[2]&0377) + + ((uint32_t)(cp[3]&0377) << 8) + + ((uint32_t)(cp[0]&0377) << 16) + + ((uint32_t)(cp[1]&0377) << 24); +} + +static uint64_t +ple64(const char *cp) +{ + return (uint64_t)(cp[0]&0377) + + ((uint64_t)(cp[1]&0377) << 8) + + ((uint64_t)(cp[2]&0377) << 16) + + ((uint64_t)(cp[3]&0377) << 24) + + ((uint64_t)(cp[4]&0377) << 32) + + ((uint64_t)(cp[5]&0377) << 40) + + ((uint64_t)(cp[6]&0377) << 48) + + ((uint64_t)(cp[7]&0377) << 56); +} + +static uint64_t +pbe64(const char *cp) +{ + return (uint64_t)(cp[7]&0377) + + ((uint64_t)(cp[6]&0377) << 8) + + ((uint64_t)(cp[5]&0377) << 16) + + ((uint64_t)(cp[4]&0377) << 24) + + ((uint64_t)(cp[3]&0377) << 32) + + ((uint64_t)(cp[2]&0377) << 40) + + ((uint64_t)(cp[1]&0377) << 48) + + ((uint64_t)(cp[0]&0377) << 56); +} + +static void +le16p(uint16_t n, char *cp) +{ + cp[0] = (n&0x00ff); + cp[1] = (n&0xff00) >> 8; +} + +static void +be16p(uint16_t n, char *cp) +{ + cp[1] = (n&0x00ff); + cp[0] = (n&0xff00) >> 8; +} + +static void +le32p(uint32_t n, char *cp) +{ + cp[0] = (n&0x000000ff); + cp[1] = (n&0x0000ff00) >> 8; + cp[2] = (n&0x00ff0000) >> 16; + cp[3] = (n&0xff000000) >> 24; +} + +static void +be32p(uint32_t n, char *cp) +{ + cp[3] = (n&0x000000ff); + cp[2] = (n&0x0000ff00) >> 8; + cp[1] = (n&0x00ff0000) >> 16; + cp[0] = (n&0xff000000) >> 24; +} + +static void +me32p(uint32_t n, char *cp) +{ + cp[2] = (n&0x000000ff); + cp[3] = (n&0x0000ff00) >> 8; + cp[0] = (n&0x00ff0000) >> 16; + cp[1] = (n&0xff000000) >> 24; +} + +static void +le64p(uint64_t n, char *cp) +{ + cp[0] = (n&0x00000000000000ffLL); + cp[1] = (n&0x000000000000ff00LL) >> 8; + cp[2] = (n&0x0000000000ff0000LL) >> 16; + cp[3] = (n&0x00000000ff000000LL) >> 24; + cp[4] = (n&0x000000ff00000000LL) >> 32; + cp[5] = (n&0x0000ff0000000000LL) >> 40; + cp[6] = (n&0x00ff000000000000LL) >> 48; + cp[7] = (n&0xff00000000000000LL) >> 56; +} + +static void +be64p(uint64_t n, char *cp) +{ + cp[7] = (n&0x00000000000000ffLL); + cp[6] = (n&0x000000000000ff00LL) >> 8; + cp[5] = (n&0x0000000000ff0000LL) >> 16; + cp[4] = (n&0x00000000ff000000LL) >> 24; + cp[3] = (n&0x000000ff00000000LL) >> 32; + cp[2] = (n&0x0000ff0000000000LL) >> 40; + cp[1] = (n&0x00ff000000000000LL) >> 48; + cp[0] = (n&0xff00000000000000LL) >> 56; +} + +#define TNAMSIZ 100 +#define TPFXSIZ 155 +#define TMAGSIZ 6 +#define TTIMSIZ 12 + +/* + * Structure of an archive header. + */ +union bincpio { + char data[4096]; +#define SIZEOF_hdr_cpio 26 + struct hdr_cpio { + char c_magic[2]; + char c_dev[2]; + char c_ino[2]; + char c_mode[2]; + char c_uid[2]; + char c_gid[2]; + char c_nlink[2]; + char c_rdev[2]; + char c_mtime[4]; + char c_namesize[2]; + char c_filesize[4]; + } Hdr; +#define SIZEOF_cray_hdr 152 + struct cray_hdr { /* with thanks to Cray-Cyber.org */ + char C_magic[8]; + char C_dev[8]; + char C_ino[8]; + char C_mode[8]; + char C_uid[8]; + char C_gid[8]; + char C_nlink[8]; + char C_rdev[8]; + /* + * The C_param field was introduced with + * UNICOS 6 and is simply not present in + * the earlier format. Following fields + * are the same for both revisions again. + */ +#define CRAY_PARAMSZ (8*8) + char C_param[CRAY_PARAMSZ]; + char C_mtime[8]; + char C_namesize[8]; + char C_filesize[8]; + } Crayhdr; +#define SIZEOF_c_hdr 76 + struct c_hdr { + char c_magic[6]; + char c_dev[6]; + char c_ino[6]; + char c_mode[6]; + char c_uid[6]; + char c_gid[6]; + char c_nlink[6]; + char c_rdev[6]; + char c_mtime[11]; + char c_namesz[6]; + char c_filesz[11]; + } Cdr; +#define SIZEOF_d_hdr 86 + struct d_hdr { + char d_magic[6]; + char d_dev[6]; + char d_ino[6]; + char d_mode[6]; + char d_uid[6]; + char d_gid[6]; + char d_nlink[6]; + char d_rmaj[8]; + char d_rmin[8]; + char d_mtime[11]; + char d_namesz[6]; + char d_filesz[11]; + } Ddr; +#define SIZEOF_Exp_cpio_hdr 110 + struct Exp_cpio_hdr { + char E_magic[6]; + char E_ino[8]; + char E_mode[8]; + char E_uid[8]; + char E_gid[8]; + char E_nlink[8]; + char E_mtime[8]; + char E_filesize[8]; + char E_maj[8]; + char E_min[8]; + char E_rmaj[8]; + char E_rmin[8]; + char E_namesize[8]; + char E_chksum[8]; + } Edr; + struct tar_header { + char t_name[TNAMSIZ]; + char t_mode[8]; + char t_uid[8]; + char t_gid[8]; + char t_size[12]; + char t_mtime[TTIMSIZ]; + char t_chksum[8]; + char t_linkflag; + char t_linkname[TNAMSIZ]; + char t_magic[TMAGSIZ]; + char t_version[2]; + char t_uname[32]; + char t_gname[32]; + char t_devmajor[8]; + char t_devminor[8]; + char t_prefix[TPFXSIZ]; + } Tdr; +#define SIZEOF_bar_header 84 + struct bar_header { + char b_mode[8]; + char b_uid[8]; + char b_gid[8]; + char b_size[12]; + char b_mtime[12]; + char b_chksum[8]; + char b_rdev[8]; + char b_linkflag; + char b_bar_magic[2]; + char b_volume_num[4]; + char b_compressed; + char b_date[12]; + } Bdr; +#define SIZEOF_zip_header 30 + struct zip_header { + char z_signature[4]; + char z_version[2]; + char z_gflag[2]; + char z_cmethod[2]; + char z_modtime[2]; + char z_moddate[2]; + char z_crc32[4]; + char z_csize[4]; + char z_nsize[4]; + char z_namelen[2]; + char z_extralen[2]; + } Zdr; +}; + +#define BCUT 0177777 +#define OCUT 0777777 +#define ECUT 0xFFFFFFFFUL + +static const char trailer[] = "TRAILER!!!"; + +/* + * Structure of per-file extra data for zip format. + */ +union zextra { + char data[1]; +#define SIZEOF_zextra_gn 4 + struct zextra_gn { + char ze_gn_tag[2]; + char ze_gn_tsize[2]; + } Ze_gn; +#define SIZEOF_zextra_64 32 /* regular size */ +#define SIZEOF_zextra_64_a 28 /* size without startn field */ +#define SIZEOF_zextra_64_b 20 /* size without reloff field */ + struct zextra_64 { + char ze_64_tag[2]; + char ze_64_tsize[2]; + char ze_64_nsize[8]; + char ze_64_csize[8]; + char ze_64_reloff[8]; + char ze_64_startn[4]; + } Ze_64; +#define SIZEOF_zextra_pk 16 + struct zextra_pk { + char ze_pk_tag[2]; + char ze_pk_tsize[2]; + char ze_pk_atime[4]; + char ze_pk_mtime[4]; + char ze_pk_uid[2]; + char ze_pk_gid[2]; + } Ze_pk; +#define SIZEOF_zextra_ek 17 + struct zextra_et { + char ze_et_tag[2]; + char ze_et_tsize[2]; + char ze_et_flags[1]; + char ze_et_mtime[4]; + char ze_et_atime[4]; + char ze_et_ctime[4]; + } Ze_et; +#define SIZEOF_zextra_i1 16 + struct zextra_i1 { + char ze_i1_tag[2]; + char ze_i1_tsize[2]; + char ze_i1_atime[4]; + char ze_i1_mtime[4]; + char ze_i1_uid[2]; + char ze_i1_gid[2]; + } Ze_i1; +#define SIZEOF_zextra_i2 8 + struct zextra_i2 { + char ze_i2_tag[2]; + char ze_i2_tsize[2]; + char ze_i2_uid[2]; + char ze_i2_gid[2]; + } Ze_i2; +#define SIZEOF_zextra_as 16 + struct zextra_as { + char ze_as_tag[2]; + char ze_as_tsize[2]; + char ze_as_crc[4]; + char ze_as_mode[2]; + char ze_as_sizdev[4]; + char ze_as_uid[2]; + char ze_as_gid[2]; + } Ze_as; +#define SIZEOF_zextra_cp 40 + struct zextra_cp { + char ze_cp_tag[2]; + char ze_cp_tsize[2]; + char ze_cp_dev[4]; + char ze_cp_ino[4]; + char ze_cp_mode[4]; + char ze_cp_uid[4]; + char ze_cp_gid[4]; + char ze_cp_nlink[4]; + char ze_cp_rdev[4]; + char ze_cp_mtime[4]; + char ze_cp_atime[4]; + } Ze_cp; +}; + +static struct zipstuff { /* stuff for central directory at EOF */ + struct zipstuff *zs_next; + char *zs_name; /* file name */ + long long zs_size; /* file size */ + long long zs_relative; /* offset of local header */ + long long zs_csize; /* compressed size */ + uint32_t zs_crc32; /* CRC */ + time_t zs_mtime; /* modification time */ + enum cmethod zs_cmethod; /* compression method */ + int zs_gflag; /* general flag */ + mode_t zs_mode; /* file mode */ +} *zipbulk; + +/* + * Structure of the central zip directory at the end of the file. This + * (obligatory) part of a zip file is written by this implementation, + * but is completely ignored on copy-in. This means that we miss the + * mode_t stored in zc_extralen if zc_versionmade[1] is 3 (Unix). We + * have to do this since it contains the S_IFMT bits, thus telling us + * whether something is a symbolic link and resulting in different + * behavior - but as the input had to be seekable in order to do this, + * we had to store entire archives in temporary files if input came + * from a pipe to be consistent. + */ +#define SIZEOF_zipcentral 46 +struct zipcentral { + char zc_signature[4]; + char zc_versionmade[2]; + char zc_versionextr[2]; + char zc_gflag[2]; + char zc_cmethod[2]; + char zc_modtime[2]; + char zc_moddate[2]; + char zc_crc32[4]; + char zc_csize[4]; + char zc_nsize[4]; + char zc_namelen[2]; + char zc_extralen[2]; + char zc_commentlen[2]; + char zc_disknstart[2]; + char zc_internal[2]; + char zc_external[4]; + char zc_relative[4]; +}; + +#define SIZEOF_zip64end 56 +struct zip64end { + char z6_signature[4]; + char z6_recsize[8]; + char z6_versionmade[2]; + char z6_versionextr[2]; + char z6_thisdiskn[4]; + char z6_alldiskn[4]; + char z6_thisentries[8]; + char z6_allentries[8]; + char z6_dirsize[8]; + char z6_startsize[8]; +}; + +#define SIZEOF_zip64loc 20 +struct zip64loc { + char z4_signature[4]; + char z4_startno[4]; + char z4_reloff[8]; + char z4_alldiskn[4]; +}; + +#define SIZEOF_zipend 22 +struct zipend { + char ze_signature[4]; + char ze_thisdiskn[2]; + char ze_alldiskn[2]; + char ze_thisentries[2]; + char ze_allentries[2]; + char ze_dirsize[4]; + char ze_startsize[4]; + char ze_commentlen[2]; +}; + +#define SIZEOF_zipddesc 16 +struct zipddesc { + char zd_signature[4]; + char zd_crc32[4]; + char zd_csize[4]; + char zd_nsize[4]; +}; + +#define SIZEOF_zipddesc64 24 +struct zipddesc64 { + char zd_signature[4]; + char zd_crc32[4]; + char zd_csize[8]; + char zd_nsize[8]; +}; + +/* + * Magic numbers and strings. + */ +static const uint16_t mag_bin = 070707; +/*static const uint16_t mag_bbs = 0143561;*/ +static const char mag_asc[6] = "070701"; +static const char mag_crc[6] = "070702"; +static const char mag_odc[6] = "070707"; +static const long mag_sco = 0x7ffffe00; + +static const char mag_ustar[6] = "ustar\0"; +static const char mag_gnutar[8] = "ustar \0"; +static const char mag_bar[2] = "V\0"; + +static const char mag_zipctr[4] = "PK\1\2"; +static const char mag_zipsig[4] = "PK\3\4"; +static const char mag_zipend[4] = "PK\5\6"; +static const char mag_zip64e[4] = "PK\6\6"; +static const char mag_zip64l[4] = "PK\6\7"; +static const char mag_zipdds[4] = "PK\7\10"; +#define mag_zip64f 0x0001 +#define mag_zipcpio 0x0707 + +/* + * Fields for the extended pax header. + */ +static enum paxrec { + PR_NONE = 0000, + PR_ATIME = 0001, + PR_GID = 0002, + PR_LINKPATH = 0004, + PR_MTIME = 0010, + PR_PATH = 0020, + PR_SIZE = 0040, + PR_UID = 0100, + PR_SUN_DEVMAJOR = 0200, + PR_SUN_DEVMINOR = 0400 +} paxrec, globrec; + +/* + * Prototype structure, collecting user-defined information + * about a file. + */ +struct prototype { + mode_t pt_mode; /* type and permission bits */ + uid_t pt_uid; /* owner */ + gid_t pt_gid; /* group owner */ + time_t pt_atime; /* time of last access */ + time_t pt_mtime; /* time of last modification */ + dev_t pt_rdev; /* device major/minor */ + enum { + PT_NONE = 0000, + PT_TYPE = 0001, + PT_OWNER = 0002, + PT_GROUP = 0004, + PT_MODE = 0010, + PT_ATIME = 0020, + PT_MTIME = 0040, + PT_RDEV = 0100 + } pt_spec; /* specified information */ +}; + +static struct stat globst; + +/* + * This sets a sanity check limit on path names. If a longer path name + * occurs in an archive, it is treated as corrupt. This is because no + * known Unix system can handle path names of arbitrary length; limits + * are typically between 1024 and 4096. Trying to extract longer path + * names would fail anyway and will cpio eventually fail to allocate + * memory. + */ +#define SANELIMIT 0177777 + +char *progname; /* argv[0] to main() */ +static struct dslot *devices; /* devices table */ +static struct dslot *markeddevs; /* unusable device numbers */ +static char *blkbuf; /* block buffer */ +int blksiz; /* block buffer size */ +static int blktop; /* top of filled part of buffer */ +static int curpos; /* position in blkbuf */ +static uint32_t fakedev; /* fake device for single link inodes */ +static uint32_t fakeino; /* fake inode for single link inodes */ +static uint32_t harddev; /* fake device used for hard links */ +static unsigned long long maxsize;/* maximum size for format */ +static unsigned long long maxrdev;/* maximum st_rdev for format */ +static unsigned long long maxmajor;/* maximum major(st_rdev) for format */ +static unsigned long long maxminor;/* maximum minor(st_rdev) for format */ +static unsigned long long maxuid; /* maximum user id for format */ +static unsigned long long maxgid; /* maximum group id for format */ +static unsigned long long maxnlink;/* maximum link count for format */ +static int mt; /* magtape file descriptor */ +static int mfl; /* magtape flags */ +static struct stat mtst; /* fstat() on mt */ +int aflag; /* reset access times */ +int Aflag; /* append to archive */ +int bflag; /* swap bytes */ +int Bflag; /* 5120 blocking */ +int cflag; /* ascii format */ +int Cflag; /* user-defined blocking */ +int dflag; /* create directories */ +int Dflag; /* do not ask for next device */ +int eflag; /* DEC format */ +int cray_eflag; /* do not archive if values too large */ +const char *Eflag; /* filename for files to be extracted */ +int fflag; /* pattern excludes */ +int Hflag; /* header format */ +const char *Iflag; /* input archive name */ +int kflag; /* skipt corrupted parts */ +int Kflag; /* IRIX-style large file support */ +int lflag; /* link of possible */ +int Lflag; /* follow symbolic links */ +int mflag; /* retain modification times */ +const char *Mflag; /* message when switching media */ +const char *Oflag; /* output archive name */ +int Pflag; /* prototype file list */ +int rflag; /* rename files */ +const char *Rflag; /* reassign ownerships */ +static uid_t Ruid; /* uid to assign */ +static gid_t Rgid; /* gid to assign */ +int sflag; /* swap half word bytes */ +int Sflag; /* swap word bytes */ +int tflag; /* print toc */ +int uflag; /* overwrite files unconditionally */ +int hp_Uflag; /* use umask when creating files */ +int vflag; /* verbose */ +int Vflag; /* special verbose */ +int sixflag; /* 6th Edition archives */ +int action; /* -i -o -p */ +long long errcnt; /* error status */ +static unsigned long long maxpath;/* maximum path length with -i */ +static uint32_t maxino; /* maximum inode number with -i */ +static uid_t myuid; /* user id of caller */ +static gid_t mygid; /* group id of caller */ +static long long blocks; /* copying statistics: full blocks */ +static long long bytes; /* copying statistics: partial blocks */ +static long long nwritten; /* bytes written to archive */ +static off_t aoffs; /* offset in archive */ +static off_t poffs; /* physical offset in archive */ +static int tapeblock = -1; /* physical tape block size */ +struct glist *patterns; /* patterns for -i */ +static int tty; /* terminal file descriptor */ +static const char *cur_ofile; /* current original file */ +static const char *cur_tfile; /* current temporary file */ +static mode_t umsk; /* user's umask */ +static int zipclevel; /* zip compression level */ +static struct islot *inull; /* splay tree null element */ +int printsev; /* print message severity strings */ +static int compressed_bar; /* this is a compressed bar archive */ +static int formatforced; /* -k -i -Hfmt forces a format */ +static long long lineno; /* input line number */ + +int pax_dflag; /* directory matches only itself */ +int pax_kflag; /* do not overwrite files */ +int pax_nflag; /* select first archive member only */ +int pax_sflag; /* substitute file names */ +int pax_uflag; /* add only recent files to archive */ +int pax_Xflag; /* do not cross device boundaries */ +static enum { + PO_NONE = 0, + PO_LINKDATA = 01, /* include link data in type 2 */ + PO_TIMES = 02, /* create atime and mtime fields */ +} pax_oflag; /* recognized -o options */ + +static void copyout(int (*)(const char *, struct stat *)); +static size_t ofiles_cpio(char **, size_t *); +static void dooutp(void); +static int outfile(const char *, struct stat *); +static int addfile(const char *, struct stat *, uint32_t, uint32_t, int, + const char *); +static void iflush(struct islot *, uint32_t); +static void lflush(void); +static int bigendian(void); +static void getbuf(char **, size_t *, size_t); +static void prdot(int); +static void newmedia(int); +static void mclose(void); +static ssize_t mwrite(int); +static void bwrite(const char *, size_t); +static void bflush(void); +static int sum(int, const char *, struct stat *, char *); +static int rstime(const char *, struct stat *, const char *); +static struct islot *isplay(ino_t, struct islot *); +static struct islot *ifind(ino_t, struct islot **); +static void iput(struct islot *, struct islot **); +static struct dslot *dfind(struct dslot **, dev_t); +static void done(int); +static void dopass(const char *); +static int passdata(struct file *, const char *, int); +static int passfile(const char *, struct stat *); +static int filein(struct file *, int (*)(struct file *, const char *, int), + char *); +static int linkunlink(const char *, const char *); +static void tunlink(char **); +static int filet(struct file *, int (*)(struct file *, const char *, int)); +static void filev(struct file *); +static int typec(struct stat *); +static void permbits(mode_t); +static void prtime_cpio(time_t); +static void getpath(const char *, char **, char **, size_t *, size_t *); +static void setpath(const char *, char **, char **, + size_t, size_t *, size_t *); +static int imdir(char *); +static int setattr(const char *, struct stat *); +static int setowner(const char *, struct stat *); +static int canlink(const char *, struct stat *, int); +static void doinp(void); +static void storelink(struct file *); +static void flushlinks(struct file *); +static void flushnode(struct islot *, struct file *); +static void flushrest(int); +static void flushtree(struct islot *, int); +static int inpone(struct file *, int); +static int readhdr(struct file *, union bincpio *); +static void whathdr(void); +static int infile(struct file *); +static int skipfile(struct file *); +static int skipdata(struct file *f, + int (*)(struct file *, const char *, int)); +static int indata(struct file *, const char *, int); +static int totrailer(void); +static long long rdoct(const char *, int); +static long long rdhex(const char *, int); +static ssize_t mread(void); +static void mstat(void); +static int skippad(unsigned long long, int); +static int allzero(const char *, int); +static const char *getuser(uid_t); +static const char *getgroup(gid_t); +static struct glist *want(struct file *, struct glist **); +static void patfile(void); +static int ckodd(long long, int, const char *, const char *); +static int rname(char **, size_t *); +static int redirect(const char *, const char *); +static char *tnameof(struct tar_header *, char *); +static int tmkname(struct tar_header *, const char *); +static void tlinkof(struct tar_header *, struct file *); +static int tmklink(struct tar_header *, const char *); +static int tlflag(struct stat *); +static void tchksum(union bincpio *); +static int tcssum(union bincpio *, int); +static int trdsum(union bincpio *); +static mode_t tifmt(int); +static void bchksum(union bincpio *); +static int bcssum(union bincpio *); +static void blinkof(const char *, struct file *, int); +static void dump_barhdr(void); +static int zcreat(const char *, mode_t); +static int zclose(int); +static void markdev(dev_t); +static int marked(dev_t); +static void cantsup(int, const char *); +static void onint(int); +static int zipread(struct file *, const char *, int, int); +static void zipreaddesc(struct file *); +static int cantunzip(struct file *, const char *); +static time_t gdostime(const char *, const char *); +static void mkdostime(time_t, char *, char *); +static ssize_t ziprxtra(struct file *, struct zip_header *); +static void ziptrailer(void); +static void zipdefer(const char *, struct stat *, long long, + uint32_t, long long, const struct zip_header *); +static int zipwrite(int, const char *, struct stat *, + union bincpio *, size_t, uint32_t, uint32_t, + uint32_t *, long long *); +static int zipwtemp(int, const char *, struct stat *, + union bincpio *, size_t, uint32_t, uint32_t, + uint32_t *, long long *); +#if USE_ZLIB +static int zipwdesc(int, const char *, struct stat *, + union bincpio *, size_t, uint32_t, uint32_t, + uint32_t *, long long *); +#endif /* USE_ZLIB */ +static int zipwxtra(const char *, struct stat *, uint32_t, uint32_t); +static void zipinfo(struct file *); +static void readK2hdr(struct file *); +static int readgnuname(char **, size_t *, long); +static void writegnuname(const char *, long, int); +static void tgetpax(struct tar_header *, struct file *); +static enum paxrec tgetrec(char **, char **, char **); +static void wrpax(const char *, const char *, struct stat *); +static void addrec(char **, long *, long *, + const char *, const char *, long long); +static void paxnam(struct tar_header *, const char *); +static char *sequence(void); +static char *joinpath(const char *, char *); +static int utf8(const char *); +static char *getproto(char *, struct prototype *); + +size_t (*ofiles)(char **, size_t *) = ofiles_cpio; +void (*prtime)(time_t) = prtime_cpio; + +int +main(int argc, char **argv) +{ + myuid = getuid(); + mygid = getgid(); + umask(umsk = umask(0)); + progname = basename(argv[0]); + setlocale(LC_CTYPE, ""); + setlocale(LC_TIME, ""); + inull = scalloc(1, sizeof *inull); + inull->i_lln = inull->i_rln = inull; + flags(argc, argv); + switch (action) { + case 'i': + if (sigset(SIGINT, SIG_IGN) != SIG_IGN) + sigset(SIGINT, onint); + doinp(); + break; + case 'o': + dooutp(); + break; + case 'p': + if (sigset(SIGINT, SIG_IGN) != SIG_IGN) + sigset(SIGINT, onint); + dopass(argv[optind]); + break; + } + if (tflag) + fflush(stdout); + else if (Vflag) + prdot(1); + if (pax != PAX_TYPE_CPIO) + pax_onexit(); + //fprintf(stderr, "%llu blocks\n", blocks + ((bytes + 0777) >> 9)); + mclose(); + if (errcnt && sysv3 == 0) + fprintf(stderr, "%llu error(s)\n", errcnt); + return errcnt ? sysv3 ? 1 : 2 : 0; +} + +static size_t +ofiles_cpio(char **name, size_t *namsiz) +{ + static struct iblok *ip; + + if (ip == NULL) + ip = ib_alloc(0, 0); + return ib_getlin(ip, name, namsiz, srealloc); +} + +/* + * Read the file name list for -o and -p and do initial processing + * for each name. + */ +static void +copyout(int (*copyfn)(const char *, struct stat *)) +{ + char *name = NULL, *np; + size_t namsiz = 0, namlen; + struct stat st; + struct prototype pt; + + while ((namlen = ofiles(&name, &namsiz)) != 0) { + lineno++; + if (name[namlen-1] == '\n') + name[--namlen] = '\0'; + if (Pflag) + np = getproto(name, &pt); + else + np = name; + while (np[0] == '.' && np[1] == '/') { + np += 2; + while (*np == '/') + np++; + if (*np == '\0') { + np = name; + break; + } + } + if (lstat(np, &st) < 0) { + if (Pflag && *np && ((pt.pt_spec & + (PT_TYPE|PT_OWNER|PT_GROUP|PT_MODE|PT_RDEV) && + ((pt.pt_mode&S_IFMT) == S_IFBLK || + (pt.pt_mode&S_IFMT) == S_IFCHR)) || + (pt.pt_spec & + (PT_TYPE|PT_OWNER|PT_GROUP|PT_MODE) && + ((pt.pt_mode&S_IFMT) == S_IFDIR || + (pt.pt_mode&S_IFMT) == S_IFIFO || + (pt.pt_mode&S_IFMT) == S_IFREG)))) { + memset(&st, 0, sizeof st); + st.st_mode = pt.pt_mode; + st.st_blksize = 4096; + st.st_nlink = 1; + goto missingok; + } + else if (sysv3 < 0) + msg(2, 0, "< %s > ?\n", np); + else if (sysv3 > 0) + msg(2, 0, "Cannot obtain information " + "about file: \"%s\".\n", + np); + else + emsg(2, "Error with lstat of \"%s\"", np); + errcnt++; + continue; + } + missingok: + if (Lflag && (st.st_mode&S_IFMT) == S_IFLNK) { + if (stat(np, &st) < 0) { + emsg(2, "Cannot follow \"%s\"", np); + errcnt++; + continue; + } + } + /* + * These file types are essentially useless in an archive + * since they are recreated by any process that needs them. + * We thus ignore them and do not even issue a warning, + * because that would only displace more important messages + * on a terminal and confuse people who just want to copy + * directory hierarchies.--But for pax, POSIX.1-2001 requires + * us to fail! + */ + if ((st.st_mode&S_IFMT) == S_IFSOCK || + (st.st_mode&S_IFMT) == S_IFDOOR) { + if (pax >= PAX_TYPE_PAX2001) { + msg(2, 0, "Cannot handle %s \"%s\".\n", + (st.st_mode&S_IFMT) == S_IFSOCK ? + "socket" : "door", np); + errcnt++; + } + continue; + } + if (Pflag) { + if (pt.pt_spec & PT_TYPE) + if ((st.st_mode&S_IFMT) != (pt.pt_mode&S_IFMT)) + msg(4, 0, "line %lld: types " + "do not match\n", lineno); + if (pt.pt_spec & PT_OWNER) + st.st_uid = pt.pt_uid; + if (pt.pt_spec & PT_GROUP) + st.st_gid = pt.pt_gid; + if (pt.pt_spec & PT_MODE) { + st.st_mode &= ~(mode_t)07777; + st.st_mode |= pt.pt_mode; + } + if (pt.pt_spec & PT_ATIME) + st.st_atime = pt.pt_atime; + if (pt.pt_spec & PT_MTIME) + st.st_mtime = pt.pt_mtime; + if (pt.pt_spec & PT_RDEV) { + if ((st.st_mode&S_IFMT) != S_IFBLK && + (st.st_mode&S_IFMT) != S_IFCHR) + msg(4, 0, "line %lld: device type " + "specified for non-device " + "file\n", lineno); + st.st_rdev = pt.pt_rdev; + } + } + if (pax_track(np, st.st_mtime) == 0) + continue; + if ((fmttype == FMT_ZIP || + fmttype & TYP_BAR || + fmttype == FMT_GNUTAR) + && (st.st_mode&S_IFMT) == S_IFDIR && + name[namlen-1] != '/') { + if (namlen+2 >= namsiz) { + size_t diff = np - name; + name = srealloc(name, namsiz = namlen+2); + np = &name[diff]; + } + name[namlen++] = '/'; + name[namlen] = '\0'; + } + errcnt += copyfn(np, &st); + } +} + +/* + * Execution for -o. + */ +static void +dooutp(void) +{ + if (Oflag) { + if ((mt = Aflag ? open(Oflag, O_RDWR, 0666) : + creat(Oflag, 0666)) < 0) { + if (sysv3) { + emsg(013, "Cannot open <%s> for %s.", Oflag, + Aflag ? "append" : "output"); + done(1); + } else + msg(3, -2, "Cannot open \"%s\" for %s\n", Oflag, + Aflag ? "append" : "output"); + } + } else + mt = dup(1); + mstat(); + blkbuf = svalloc(blksiz, 1); + if (Aflag) { + if (totrailer() != 0) + return; + } else if (fmttype == FMT_NONE) + fmttype = bigendian() ? FMT_BINBE : FMT_BINLE; + if (fmttype & TYP_BINARY) { + maxino = 0177777; + fakeino = 0177777; + maxpath = 256; + if (fmttype & TYP_SGI) { + maxsize = 0x7FFFFFFFFFFFFFFFLL; + maxmajor = 037777; + maxminor = 0777777; + } else { + maxsize = 0x7FFFFFFFLL; + maxrdev = 0177777; + } + maxuid = 0177777; + maxgid = 0177777; + maxnlink = 0177777; + } else if (fmttype == FMT_ODC) { + maxino = 0777777; + fakeino = 0777777; + maxpath = 256; + maxsize = 077777777777LL; + maxrdev = 0777777; + maxuid = 0777777; + maxgid = 0777777; + maxnlink = 0777777; + } else if (fmttype == FMT_DEC) { + maxino = 0777777; + fakeino = 0777777; + maxpath = 256; + maxsize = 077777777777LL; + maxmajor = 077777777; + maxminor = 077777777; + maxuid = 0777777; + maxgid = 0777777; + maxnlink = 0777777; + } else if (fmttype & TYP_NCPIO) { + maxino = 0xFFFFFFFFUL; + fakeino = 0xFFFFFFFFUL; + maxpath = 1024; + maxsize = fmttype&TYP_SCO ? 0x7FFFFFFFFFFFFFFFLL : 0xFFFFFFFFUL; + maxmajor = 0xFFFFFFFFUL; + maxminor = 0xFFFFFFFFUL; + maxuid = 0xFFFFFFFFUL; + maxgid = 0xFFFFFFFFUL; + maxnlink = 0xFFFFFFFFUL; + } else if (fmttype & TYP_CRAY) { + maxino = 0xFFFFFFFFUL; + fakeino = 0xFFFFFFFFUL; + maxpath = SANELIMIT; + maxsize = 0x7FFFFFFFFFFFFFFFLL; + maxrdev = 0x7FFFFFFFFFFFFFFFLL; + maxuid = 0x7FFFFFFFFFFFFFFFLL; + maxgid = 0x7FFFFFFFFFFFFFFFLL; + maxnlink = 0x7FFFFFFFFFFFFFFFLL; + } else if (fmttype == FMT_GNUTAR) { + maxino = 0xFFFFFFFFUL; + fakeino = 0xFFFFFFFFUL; + maxpath = SANELIMIT; + maxsize = 0x7FFFFFFFFFFFFFFFLL; + maxmajor = 0x7FFFFFFFFFFFFFFFLL; + maxminor = 0x7FFFFFFFFFFFFFFFLL; + maxuid = 0x7FFFFFFFFFFFFFFFLL; + maxgid = 0x7FFFFFFFFFFFFFFFLL; + maxnlink = 0x7FFFFFFFFFFFFFFFLL; + } else if (fmttype & TYP_PAX) { + maxino = 0xFFFFFFFFUL; + fakeino = 0xFFFFFFFFUL; + maxpath = SANELIMIT; + maxsize = 0x7FFFFFFFFFFFFFFFLL; + maxmajor = fmttype==FMT_SUN ? 0x7FFFFFFFFFFFFFFFLL : 07777777; + maxminor = fmttype==FMT_SUN ? 0x7FFFFFFFFFFFFFFFLL : 07777777; + maxuid = 0x7FFFFFFFFFFFFFFFLL; + maxgid = 0x7FFFFFFFFFFFFFFFLL; + maxnlink = 0x7FFFFFFFFFFFFFFFLL; + if (pax_oflag & PO_TIMES) + globrec |= PR_ATIME|PR_MTIME; + } else if (fmttype & TYP_BAR) { + maxino = 0xFFFFFFFFUL; + fakeino = 0xFFFFFFFFUL; + maxpath = 512 - SIZEOF_bar_header - 1; + maxsize = 077777777777LL; + maxrdev = 07777777; + maxuid = 07777777; + maxgid = 07777777; + maxnlink = 0x7FFFFFFFFFFFFFFFLL; + if (nwritten == 0) + dump_barhdr(); + } else if (fmttype & TYP_USTAR) { + maxino = 0xFFFFFFFFUL; + fakeino = 0xFFFFFFFFUL; + maxpath = 256; + maxsize = 077777777777LL; + maxmajor = 07777777; + maxminor = 07777777; + maxuid = 07777777; + maxgid = 07777777; + maxnlink = 0x7FFFFFFFFFFFFFFFLL; + } else if (fmttype & TYP_OTAR) { + maxino = 0xFFFFFFFFUL; + fakeino = 0xFFFFFFFFUL; + maxpath = 99; + maxsize = 077777777777LL; + maxuid = 07777777; + maxgid = 07777777; + maxnlink = 0x7FFFFFFFFFFFFFFFLL; + } else if (fmttype == FMT_ZIP) { + maxino = 0xFFFFFFFFUL; + fakeino = 0xFFFFFFFFUL; + maxpath = 60000; + maxsize = 0x7FFFFFFFFFFFFFFFLL; + maxrdev = 0xFFFFFFFFUL; + maxuid = 0xFFFFFFFFUL; + maxgid = 0xFFFFFFFFUL; + maxnlink = 0xFFFFFFFFUL; + } else + abort(); + fakedev = 0177777; + harddev = 1; + copyout(outfile); + if (fmttype & TYP_NCPIO) + lflush(); + if (fmttype & TYP_CPIO) { + struct stat st; + + memset(&st, 0, sizeof st); + st.st_nlink = 1; + outfile(trailer, &st); + } + if (fmttype & TYP_TAR) { + char b[512]; + + memset(b, 0, sizeof b); + bwrite(b, sizeof b); + bwrite(b, sizeof b); + } + if (fmttype == FMT_ZIP) + ziptrailer(); + bflush(); +} + +/* + * Handle a single file for -o, do sanity checks and detect hard links. + */ +static int +outfile(const char *file, struct stat *st) +{ + uint32_t dev, ino; + size_t pathsz; + + if ((st->st_mode&S_IFMT) == S_IFREG) + if (mtst.st_dev == st->st_dev && mtst.st_ino == st->st_ino) + return 0; + if (st->st_size > maxsize) { + msg(2, 0, "Size of %c%s%c >%lluGB. Not dumped\n", + sysv3 ? '<' : '"', + file, + sysv3 ? '>' : '"', + (maxsize+1) / (1024*1024*1024)); + return 1; + } + if (((st->st_mode&S_IFMT)==S_IFBLK||(st->st_mode&S_IFMT)==S_IFCHR) && + (maxrdev && + (unsigned long long)st->st_rdev > maxrdev || + maxmajor && + (unsigned long long)major(st->st_rdev) > maxmajor || + maxminor && + (unsigned long long)minor(st->st_rdev) > maxminor)) { + cantsup(1, file); + return 1; + } + if ((unsigned long long)st->st_uid > maxuid) { + if (cray_eflag) { + cantsup(1, file); + return 1; + } + cantsup(0, file); + st->st_uid = 60001; + if ((st->st_mode&S_IFMT) == S_IFREG && st->st_mode & 0111) + st->st_mode &= ~(mode_t)S_ISUID; + if ((unsigned long long)st->st_gid > maxgid) { + st->st_gid = 60001; + if ((st->st_mode&S_IFMT)==S_IFREG && st->st_mode&0010) + st->st_mode &= ~(mode_t)S_ISGID; + } + } else if ((unsigned long long)st->st_gid > maxgid) { + if (cray_eflag) { + cantsup(1, file); + return 1; + } + cantsup(0, file); + st->st_gid = 60001; + if ((st->st_mode&S_IFMT) == S_IFREG && st->st_mode & 0010) + st->st_mode &= ~(mode_t)S_ISGID; + } + if ((pathsz = strlen(file)) > maxpath) { + msg(2, 0, "%s: file name too long\n", file); + return 1; + } + /* + * Detect hard links and compute fake inode counts. The mechanism + * is as follows: If a file has more than one link, a fake device + * number starting at one is used for its device, and a fake inode + * number is used starting at one too. + * + * The information on links of directories is useless, so it is + * dropped and handled like a file with a single link only: Fake + * devices are allocated just below the format's limit, fake + * i-nodes the same. + * + * This way even the binary cpio format can have up to ~4G files. + */ + if (maxino && st->st_nlink > 1 && (st->st_mode&S_IFMT) != S_IFDIR) { + struct dslot *ds, *dp; + struct islot *ip; + + dev = 1; + ds = devices; + dp = NULL; +nextdev: + for (; ds; dp = ds, ds = ds->d_nxt, dev++ /* see below! */) + if (ds->d_dev == st->st_dev) + break; + if (markeddevs && marked(dev)) { + dev++; + goto nextdev; + } + if (dev >= fakedev) + msg(4, 1, "Too many devices in archive, exiting\n"); + if (ds == NULL) { + ds = scalloc(1, sizeof *ds); + ds->d_dev = st->st_dev; + ds->d_fake = dev; + if (devices == NULL) + devices = ds; + else + dp->d_nxt = ds; + } + harddev = dev; + if ((ip = ifind(st->st_ino, &ds->d_isl)) == NULL) { + if (ds->d_cnt >= maxino) { + /* corresponds to for loop above */ + dev++, dp = ds, ds = ds->d_nxt; + goto nextdev; + } + ip = scalloc(1, sizeof *ip); + ip->i_ino = st->st_ino; + ip->i_fino = ++ds->d_cnt; + ip->i_nlk = st->st_nlink; + if (fmttype & TYP_TAR) + ip->i_name = sstrdup(file); + if (fmttype & TYP_NCPIO) { + ip->i_st = smalloc(sizeof *ip->i_st); + *ip->i_st = *st; + } + iput(ip, &ds->d_isl); + } + ino = ip->i_fino; + if (fmttype & TYP_NCPIO) { + /* + * In SVR4 ascii cpio format, files with multiple + * links are stored with a zero size except for the + * last link, which contains the actual file content. + * As one cannot know which is the last link in + * advance since some links may be outside the + * archive content, all links have to be collected + * and written out at once. + */ + struct ilink *il, *ik; + + switch (ip->i_nlk) { + case 1: + /* + * This was the last link to a file. Write + * all previous links and break to write + * the actual file content. Free the pointers + * in islot; islot remains within the tree + * with a remaining link count of zero. + */ + ip->i_nlk--; + free(ip->i_st); + ip->i_st = NULL; + for (il = ip->i_lnk, ik = NULL; il; + ik = il, il = il->l_nxt, + ik ? free(ik), 0 : 0) { + errcnt += addfile(il->l_nam, st, + dev, ino, 1, 0); + free(il->l_nam); + } + break; + case 0: + /* + * This file got a link during operation, or + * -L was specified and we encountered a link + * more than once. Start with a fresh link + * count again. + */ + ip->i_nlk = st->st_nlink; + ip->i_lnk = NULL; + ip->i_st = smalloc(sizeof *ip->i_st); + *ip->i_st = *st; + /*FALLTHRU*/ + default: + /* + * There are more links to this file. Store + * only the name and return. + */ + ip->i_nlk--; + if (ip->i_lnk) { + for (il = ip->i_lnk; il->l_nxt; + il = il->l_nxt); + il->l_nxt = scalloc(1,sizeof*il->l_nxt); + il = il->l_nxt; + } else { + ip->i_lnk = scalloc(1,sizeof*ip->i_lnk); + il = ip->i_lnk; + } + il->l_nam = smalloc(pathsz + 1); + strcpy(il->l_nam, file); + return 0; + } + } else if (fmttype & TYP_TAR) { + if (strcmp(ip->i_name, file)) + return addfile(file, st, dev, ino, 1, + ip->i_name); + } + } else { /* single-linked or directory */ + dev = fakedev; + while (markeddevs && marked(dev)) + dev--; + if ((ino = fakeino--) == 0) { + if (--dev <= harddev) + msg(4, 1, "Too many devices in archive, " + "exiting\n"); + fakedev = dev; + ino = maxino; + fakeino = ino - 1; + } + } + return addfile(file, st, dev, ino, 0, 0); +} + +/* + * Add a single file to the archive with -o. + */ +static int +addfile(const char *realfile, struct stat *st, + uint32_t dev, uint32_t ino, int zerolink, const char *linkname) +{ + union bincpio bc; + int fd = -1; + long long size; + int pad, i; + ssize_t rsz = 0, wsz = 0, hsz, fsz, psz; + long long remsz, relative, nlink; + long long Kbase = 0, Krest = 0, Ksize = 0; + struct hdr_cpio K2hdr; + uint32_t crc = 0; + long long csize = 0; + char *file; + char *symblink = NULL; + int failure = 1; + + file = sstrdup(realfile); + if (pax != PAX_TYPE_CPIO && strcmp(file, trailer)) { + size_t junk = 0; + if (pax_sflag && pax_sname(&file, &junk) == 0) + goto cleanup; + if (rflag && rname(&file, &junk) == 0) + goto cleanup; + } + fsz = strlen(file); + relative = nwritten; + memset(bc.data, 0, sizeof bc.data); + if (fmttype == FMT_PAX && pax_oflag & PO_LINKDATA && + (st->st_mode&S_IFMT) == S_IFREG) + size = st->st_size; + else if (zerolink) + size = 0; + else if ((st->st_mode&S_IFMT) == S_IFREG) + size = st->st_size; + else if ((st->st_mode&S_IFMT) == S_IFLNK) { + i = st->st_size ? st->st_size : PATH_MAX; + symblink = smalloc(i+1); + if ((size = readlink(realfile, symblink, i)) < 0) { + emsg(3, "Cannot read symbolic link \"%s\"", realfile); + goto cleanup; + } + symblink[size] = '\0'; + } else + size = 0; + nlink = ((unsigned long long)st->st_nlink>maxnlink ? + maxnlink : st->st_nlink); + if (fmttype & TYP_NCPIO) { + long size1; + if (fmttype & TYP_SCO && size >= mag_sco) { + char *ofile = file; + size1 = mag_sco; + fsz += 22; + file = smalloc(fsz + 1); + snprintf(file, fsz + 1, "%s%csize=%016llx", + ofile, 0, size); + free(ofile); + } else + size1 = size; + pad = 4; + sprintf(bc.data, "%*.*s%08lx%08lx%08lx%08lx%08lx%08lx" + "%08lx%08lx%08lx%08lx%08lx%08lx%08lx", + (int)(fmttype&TYP_CRC? sizeof mag_crc:sizeof mag_asc), + (int)(fmttype&TYP_CRC? sizeof mag_crc:sizeof mag_asc), + fmttype & TYP_CRC ? mag_crc : mag_asc, + (long)ino & ECUT, + (long)st->st_mode & ECUT, + (long)st->st_uid & ECUT, + (long)st->st_gid & ECUT, + (long)nlink & ECUT, + (long)st->st_mtime & ECUT, + (long)size1 & ECUT, + (long)major(dev) & ECUT, + (long)minor(dev) & ECUT, + (long)major(st->st_rdev) & ECUT, + (long)minor(st->st_rdev) & ECUT, + (long)++fsz, + 0L); + hsz = SIZEOF_Exp_cpio_hdr; + if ((psz = (hsz + fsz) % pad) != 0) + psz = pad - psz; + } else if (fmttype == FMT_ODC) { + pad = 1; + sprintf(bc.data, "%*.*s%06lo%06lo%06lo%06lo%06lo%06lo%06lo" + "%011lo%06lo%011lo", + (int)sizeof mag_odc, (int)sizeof mag_odc, mag_odc, + (long)dev & OCUT, + (long)ino & OCUT, + (long)st->st_mode & OCUT, + (long)st->st_uid & OCUT, + (long)st->st_gid & OCUT, + (long)nlink & OCUT, + (long)st->st_rdev & OCUT, + (long)st->st_mtime, + (long)++fsz, + (long)size); + hsz = SIZEOF_c_hdr; + if ((psz = (hsz + fsz) % pad) != 0) + psz = pad - psz; + } else if (fmttype == FMT_DEC) { + pad = 1; + sprintf(bc.data, "%*.*s%06lo%06lo%06lo%06lo%06lo%06lo" + "%08lo%08lo%011lo%06lo%011lo", + (int)sizeof mag_odc, (int)sizeof mag_odc, mag_odc, + (long)dev & OCUT, + (long)ino & OCUT, + (long)st->st_mode & OCUT, + (long)st->st_uid & OCUT, + (long)st->st_gid & OCUT, + (long)nlink & OCUT, + (long)major(st->st_rdev) & 077777777, + (long)minor(st->st_rdev) & 077777777, + (long)st->st_mtime, + (long)++fsz, + (long)size); + hsz = SIZEOF_d_hdr; + if ((psz = (hsz + fsz) % pad) != 0) + psz = pad - psz; + } else if (fmttype & TYP_BINARY) { + /* + * To avoid gcc's stupid 'comparison is always false due to + * limited range of data type' warning. + */ + unsigned long long gcccrap; + pad = 2; + if (fmttype & TYP_BE) { + be16p(mag_bin, bc.Hdr.c_magic); + be16p(dev, bc.Hdr.c_dev); + be16p(ino, bc.Hdr.c_ino); + be16p(st->st_mode, bc.Hdr.c_mode); + be16p(st->st_uid, bc.Hdr.c_uid); + be16p(st->st_gid, bc.Hdr.c_gid); + be16p(nlink, bc.Hdr.c_nlink); + be16p(st->st_rdev, bc.Hdr.c_rdev); + be32p(st->st_mtime, bc.Hdr.c_mtime); + be16p(++fsz, bc.Hdr.c_namesize); + } else { + le16p(mag_bin, bc.Hdr.c_magic); + le16p(dev, bc.Hdr.c_dev); + le16p(ino, bc.Hdr.c_ino); + le16p(st->st_mode, bc.Hdr.c_mode); + le16p(st->st_uid, bc.Hdr.c_uid); + le16p(st->st_gid, bc.Hdr.c_gid); + le16p(nlink, bc.Hdr.c_nlink); + le16p(st->st_rdev, bc.Hdr.c_rdev); + me32p(st->st_mtime, bc.Hdr.c_mtime); + le16p(++fsz, bc.Hdr.c_namesize); + } + if (fmttype & TYP_SGI && size > 0x7FFFFFFFLL) { + Krest = size & 0x7FFFFFFFLL; + Kbase = size - Krest; + Ksize = 0x100000000LL - (Kbase >> 31); + if (fmttype & TYP_BE) + be32p(Ksize, bc.Hdr.c_filesize); + else + me32p(Ksize, bc.Hdr.c_filesize); + K2hdr = bc.Hdr; + if (fmttype & TYP_BE) + be32p(Krest, K2hdr.c_filesize); + else + me32p(Krest, K2hdr.c_filesize); + } else { + if (fmttype & TYP_BE) + be32p(size, bc.Hdr.c_filesize); + else + me32p(size, bc.Hdr.c_filesize); + } + if (fmttype & TYP_SGI && + (((st->st_mode&S_IFMT) == S_IFBLK || + (st->st_mode&S_IFMT) == S_IFCHR) && + ((unsigned long long)major(st->st_rdev)>0xFF || + (unsigned long long)minor(st->st_rdev)>0xFF) || + (gcccrap = st->st_rdev) > 0177777)) { + uint32_t rdev; + rdev = (minor(st->st_rdev) & 0x0003FFFF) + + ((major(st->st_rdev)<<18) & 0xFFFC0000); + if (fmttype & TYP_BE) { + be16p(0xFFFF, bc.Hdr.c_rdev); + be32p(rdev, bc.Hdr.c_filesize); + } else { + le16p(0xFFFF, bc.Hdr.c_rdev); + me32p(rdev, bc.Hdr.c_filesize); + } + } + hsz = SIZEOF_hdr_cpio; + psz = (hsz + fsz) % 2; + } else if (fmttype & TYP_CRAY) { + int diff5 = fmttype==FMT_CRAY5 ? CRAY_PARAMSZ : 0; + mode_t mo; + pad = 1; + be64p(mag_bin, bc.Crayhdr.C_magic); + be64p(dev, bc.Crayhdr.C_dev); + be64p(ino, bc.Crayhdr.C_ino); + if ((st->st_mode&S_IFMT) == S_IFLNK) /* non-standard */ + mo = st->st_mode&07777|0130000; /* S_IFLNK on Cray */ + else + mo = st->st_mode; + be64p(mo, bc.Crayhdr.C_mode); + be64p(st->st_uid, bc.Crayhdr.C_uid); + be64p(st->st_gid, bc.Crayhdr.C_gid); + be64p(nlink, bc.Crayhdr.C_nlink); + be64p(st->st_rdev, bc.Crayhdr.C_rdev); + be64p(st->st_mtime, bc.Crayhdr.C_mtime - diff5); + be64p(++fsz, bc.Crayhdr.C_namesize - diff5); + be64p(size, bc.Crayhdr.C_filesize - diff5); + hsz = SIZEOF_cray_hdr - diff5; + psz = 0; + } else if (fmttype & TYP_BAR) { + int c, n = 0; + pad = 512; + sprintf(bc.Bdr.b_mode, "%7.7o",(int)st->st_mode&(07777|S_IFMT)); + sprintf(bc.Bdr.b_uid, "%7.7lo", (long)st->st_uid); + sprintf(bc.Bdr.b_gid, "%7.7lo", (long)st->st_gid); + sprintf(bc.Bdr.b_size, "%11.11llo", + (st->st_mode&S_IFMT) == S_IFREG && !zerolink ? + (long long)st->st_size&077777777777LL : 0LL); + sprintf(bc.Bdr.b_mtime, "%11.11lo", (long)st->st_mtime); + sprintf(bc.Bdr.b_rdev, "%7.7lo", (long)st->st_rdev); + strcpy(&bc.data[SIZEOF_bar_header], file); + c = tlflag(st); + if (zerolink == 0) { + bc.Bdr.b_linkflag = c; + if (c == '2') { + strncpy(&bc.data[SIZEOF_bar_header+fsz+1], + symblink, + 512-SIZEOF_bar_header-fsz); + n = size; + } + } else { + bc.Bdr.b_linkflag = '1'; + strncpy(&bc.data[SIZEOF_bar_header+fsz+1], linkname, + 512-SIZEOF_bar_header-fsz-1); + n = strlen(linkname); + } + if (n > 512-SIZEOF_bar_header-fsz-1) { + msg(3, 0, "%s: linked name too long\n", realfile); + goto cleanup; + } + bchksum(&bc); + hsz = 512; + psz = 0; + fsz = 0; + } else if (fmttype & TYP_TAR) { + const char *cp; + int c; + /* + * Many SVR4 cpio derivatives expect the mode field + * to contain S_IFMT bits. The meaning of these bits + * in the mode field of the ustar header is left + * unspecified by IEEE Std 1003.1, 1996, 10.1.1. + */ + int mmask = fmttype == FMT_USTAR || fmttype == FMT_PAX ? + 07777 : 07777|S_IFMT; + + paxrec = globrec; + pad = 512; + if (tmkname(&bc.Tdr, file) != 0) + goto cleanup; + sprintf(bc.Tdr.t_mode, "%7.7o", (int)st->st_mode & mmask); + if (fmttype == FMT_GNUTAR && st->st_uid > 07777777) { + be64p(st->st_uid, bc.Tdr.t_uid); + bc.Tdr.t_uid[0] |= 0200; + } else { + sprintf(bc.Tdr.t_uid, "%7.7lo", + (long)st->st_uid&07777777); + if (fmttype & TYP_PAX && st->st_uid > 07777777) + paxrec |= PR_UID; + } + if (fmttype == FMT_GNUTAR && st->st_gid > 07777777) { + be64p(st->st_gid, bc.Tdr.t_gid); + bc.Tdr.t_gid[0] |= 0200; + } else { + sprintf(bc.Tdr.t_gid, "%7.7lo", + (long)st->st_gid&07777777); + if (fmttype & TYP_PAX && st->st_gid > 07777777) + paxrec |= PR_GID; + } + if (fmttype == FMT_GNUTAR && (st->st_mode&S_IFMT) == S_IFREG && + st->st_size > 077777777777LL && !zerolink) { + bc.Tdr.t_size[0] = '\200'; + be64p(st->st_size, &bc.Tdr.t_size[4]); + } else { + sprintf(bc.Tdr.t_size, "%11.11llo", + (st->st_mode&S_IFMT) == S_IFREG && + (!zerolink || fmttype == FMT_PAX && + pax_oflag & PO_LINKDATA) ? + (long long)st->st_size&077777777777LL : 0LL); + if (fmttype & TYP_PAX && + (st->st_mode&S_IFMT) == S_IFREG && + st->st_size > 077777777777LL && + (!zerolink || fmttype == FMT_PAX && + pax_oflag & PO_LINKDATA)) + paxrec |= PR_SIZE; + } + sprintf(bc.Tdr.t_mtime, "%11.11lo", (long)st->st_mtime); + if ((c = tlflag(st)) < 0) { + if ((st->st_mode&S_IFMT) != S_IFDIR) { + msg(2, 0, "%s is not a file. Not dumped\n", + realfile); + errcnt++; + } else + failure = 0; + goto cleanup; + } + if (zerolink == 0) { + bc.Tdr.t_linkflag = c; + if (c == '2') { + if (tmklink(&bc.Tdr, symblink) != 0) + goto cleanup; + } + } else { + bc.Tdr.t_linkflag = '1'; + if (tmklink(&bc.Tdr, linkname) != 0) + goto cleanup; + } + if (fmttype & TYP_USTAR) { + if (fmttype == FMT_GNUTAR) + strcpy(bc.Tdr.t_magic, mag_gnutar); + else { + strcpy(bc.Tdr.t_magic, mag_ustar); + bc.Tdr.t_version[0] = bc.Tdr.t_version[1] = '0'; + } + if ((cp = getuser(st->st_uid)) != NULL) + sprintf(bc.Tdr.t_uname, "%.31s", cp); + if ((cp = getgroup(st->st_gid)) != NULL) + sprintf(bc.Tdr.t_gname, "%.31s", cp); + else + msg(1, 0, "could not get group information " + "for %s\n", realfile); + if (fmttype == FMT_GNUTAR && + (unsigned long long)major(st->st_rdev) + > 077777777) { + be64p(major(st->st_rdev), bc.Tdr.t_devmajor); + bc.Tdr.t_devmajor[0] |= 0200; + } else { + if (fmttype == FMT_SUN && + (unsigned long long)major(st->st_rdev) + > 077777777 && + ((st->st_mode&S_IFMT)==S_IFBLK|| + (st->st_mode&S_IFMT)==S_IFCHR)) + paxrec |= PR_SUN_DEVMAJOR; + sprintf(bc.Tdr.t_devmajor, "%7.7o", + (int)major(st->st_rdev)&07777777); + } + if (fmttype == FMT_GNUTAR && + (unsigned long long)minor(st->st_rdev) + > 077777777) { + be64p(minor(st->st_rdev), bc.Tdr.t_devminor); + bc.Tdr.t_devminor[0] |= 0200; + } else { + if (fmttype == FMT_SUN && + (unsigned long long)minor(st->st_rdev) + > 077777777 && + ((st->st_mode&S_IFMT)==S_IFBLK|| + (st->st_mode&S_IFMT)==S_IFCHR)) + paxrec |= PR_SUN_DEVMINOR; + sprintf(bc.Tdr.t_devminor, "%7.7o", + (int)minor(st->st_rdev)&07777777); + } + } + tchksum(&bc); + hsz = 512; + psz = 0; + fsz = 0; + } else if (fmttype == FMT_ZIP) { + pad = 1; + memcpy(bc.Zdr.z_signature, mag_zipsig, sizeof mag_zipsig); + bc.Zdr.z_version[0] = 10; + mkdostime(st->st_mtime, bc.Zdr.z_modtime, bc.Zdr.z_moddate); + if ((st->st_mode&S_IFMT) == S_IFREG || + (st->st_mode&S_IFMT) == S_IFLNK) { + le32p(size, bc.Zdr.z_csize); + le32p(size, bc.Zdr.z_nsize); + csize = size; + } + le16p(fsz, bc.Zdr.z_namelen); + le16p(SIZEOF_zextra_cp, bc.Zdr.z_extralen); + hsz = SIZEOF_zip_header; + psz = 0; + } else + abort(); + /* + * Start writing the file to the archive. + */ + if ((st->st_mode&S_IFMT) == S_IFREG && st->st_size != 0 && + (zerolink == 0 || fmttype == FMT_PAX && + pax_oflag & PO_LINKDATA)) { + char *buf; + size_t bufsize; + int readerr = 0; + + if ((fd = open(realfile, O_RDONLY)) < 0) { + if (sysv3 < 0) + msg(0, 0, "< %s > ?\n", realfile); + else if (sysv3 > 0) + fprintf(stderr, "<%s> ?\n", realfile); + else + msg(0, 0, "\"%s\" ?\n", realfile); + goto cleanup; + } + if (fmttype == FMT_ZIP) { + if (zipwrite(fd, file, st, &bc, fsz, dev, ino, + &crc, &csize) < 0) + goto cleanup2; + goto done; + } + if (fmttype & TYP_CRC) + if (sum(fd, realfile, st, bc.Edr.E_chksum) < 0) + goto cleanup2; + if (fmttype & TYP_PAX && paxrec != PR_NONE) + wrpax(file, symblink?symblink:linkname, st); + bwrite(bc.data, hsz); + if (fsz) + bwrite(file, fsz); + if (psz) + bwrite(&bc.data[hsz], psz); + if (Kbase) + remsz = Kbase; + else + remsz = st->st_size; + getbuf(&buf, &bufsize, st->st_blksize); + again: while (remsz > 0) { + if (fd < 0 || (rsz = read(fd, &buf[wsz], + bufsize - wsz)) < 0) { + if (readerr == 0) { + emsg(3, "Cannot read \"%s\"", realfile); + if (fd >= 0) + errcnt++; + readerr = 1; + } + if (fd >= 0 && lseek(fd, bufsize - wsz, + SEEK_CUR) < 0) { + close(fd); + fd = -1; + } + rsz = bufsize - wsz; + if (rsz > remsz) + rsz = remsz; + memset(&buf[wsz], 0, rsz); + } + if (rsz > remsz) + rsz = remsz; + wsz += rsz; + remsz -= rsz; + bwrite(buf, wsz); + memset(buf, 0, wsz); + size = wsz; + wsz = 0; + } + wsz = size; + if (Kbase) { + if ((i = Ksize % pad) != 0) + bwrite(&bc.data[hsz], i); + bwrite((char *)&K2hdr, hsz); + if (fsz) + bwrite(file, fsz); + if (psz) + bwrite(&bc.data[hsz], psz); + remsz = Krest; + Kbase = 0; + wsz = 0; + goto again; + } else if (Ksize) + wsz = Krest; + } else if ((fmttype == FMT_ZIP || fmttype & TYP_CPIO) && + (st->st_mode&S_IFMT) == S_IFLNK) { + wsz = size; + if (fmttype == FMT_ZIP) { + crc = zipcrc(0, (unsigned char *)symblink, wsz); + le32p(crc, bc.Zdr.z_crc32); + bwrite(bc.data, SIZEOF_zip_header); + bwrite(file, fsz); + zipwxtra(file, st, dev, ino); + bwrite(symblink, wsz); + } else { + bwrite(bc.data, hsz); + if (fsz) + bwrite(file, fsz); + if (psz) + bwrite(&bc.data[hsz], psz); + bwrite(symblink, wsz); + } + } else { + if (fmttype & TYP_PAX && paxrec != PR_NONE) + wrpax(file, symblink?symblink:linkname, st); + bwrite(bc.data, hsz); + if (fsz) + bwrite(file, fsz); + if (psz) + bwrite(&bc.data[hsz], psz); + if (fmttype == FMT_ZIP) + zipwxtra(file, st, dev, ino); + } +done: if (fmttype == FMT_ZIP) { + zipdefer(file, st, relative, crc, csize, &bc.Zdr); + } + if ((i = wsz % pad) != 0) + bwrite(&bc.data[hsz], pad - i); + if (vflag && strcmp(file, trailer)) + fprintf(stderr, "%s\n", file); + else if (Vflag) + prdot(0); + failure = 0; +cleanup2: + if ((st->st_mode&S_IFMT) == S_IFREG) { + if (fd >= 0) + close(fd); + if (aflag) + errcnt += rstime(realfile, st, "access"); + } +cleanup: + free(file); + free(symblink); + return failure; +} + +/* + * Flush a SVR4 cpio format inode tree for -o. + */ +static void +iflush(struct islot *ip, uint32_t dev) +{ + if (ip == inull) + return; + iflush(ip->i_lln, dev); + iflush(ip->i_rln, dev); + if (ip->i_nlk > 0 && ip->i_st) { + struct ilink *il; + + for (il = ip->i_lnk; il->l_nxt; il = il->l_nxt) + errcnt += addfile(il->l_nam, ip->i_st, + dev, ip->i_fino, 1, 0); + errcnt += addfile(il->l_nam, ip->i_st, dev, ip->i_fino, 0, 0); + } +} + +/* + * Flush the SVR4 cpio link forest for -o. + */ +static void +lflush(void) +{ + struct dslot *ds; + + for (ds = devices; ds; ds = ds->d_nxt) + iflush(ds->d_isl, ds->d_fake); +} + +int +setfmt(char *s) +{ + int i, j; + + struct { + const char *ucs; + const char *lcs; + int type; + int bits; + } fs[] = { + { "NEWC", "newc", FMT_ASC, 00 }, + { "SCO", "sco", FMT_SCOASC, 00 }, + { "CRC", "crc", FMT_CRC, 00 }, + { "SCOCRC", "scocrc", FMT_SCOCRC, 00 }, + { "ODC", "odc", FMT_ODC, 00 }, + { "DEC", "dec", FMT_DEC, 00 }, + { "BIN", "bin", FMT_NONE, 00 }, + { "BBS", "bbs", TYP_BE, 00 }, + { "SGI", "sgi", FMT_SGIBE, 00 }, + { "CRAY", "cray", FMT_CRAY, 00 }, + { "CRAY5", "cray5", FMT_CRAY5, 00 }, + { "TAR", "tar", FMT_TAR, 00 }, + { "USTAR", "ustar", FMT_USTAR, 00 }, + { "PAX:", "pax:", FMT_PAX, 00 }, + { "SUN", "sun", FMT_SUN, 00 }, + { "GNU", "gnu", FMT_GNUTAR, 00 }, + { "OTAR", "otar", FMT_OTAR, 00 }, + { "BAR", "bar", FMT_BAR, 00 }, + { "ZIP:", "zip:", FMT_ZIP, 00 }, + { NULL, NULL, 0, 00 } + }; + for (i = 0; fs[i].ucs; i++) { + for (j = 0; s[j] && + (s[j] == fs[i].ucs[j] || s[j] == fs[i].lcs[j]); + j++) + if (fs[i].ucs[j] == ':') + break; + if (s[j] == '\0' && + (fs[i].ucs[j] == '\0' || fs[i].ucs[j] == ':') || + s[j] == ':' && fs[i].ucs[j] == ':') { + fmttype = fs[i].type; + if (fmttype == FMT_ZIP && s[j] == ':') { +#if USE_ZLIB + if (strcmp(&s[j+1], "en") == 0) + zipclevel = 00; + else if (strcmp(&s[j+1], "ex") == 0) + zipclevel = 01; + else if (strcmp(&s[j+1], "ef") == 0) + zipclevel = 02; + else if (strcmp(&s[j+1], "es") == 0) + zipclevel = 03; + else +#endif /* USE_ZLIB */ + if (strcmp(&s[j+1], "e0") == 0) + zipclevel = 04; + else +#if USE_BZLIB + if (strcmp(&s[j+1], "bz2") == 0) + zipclevel = 07; + else +#endif /* USE_BZLIB */ + continue; + } else if (fmttype == FMT_NONE) + fmttype = bigendian() ? FMT_BINBE : FMT_BINLE; + else if (fmttype == TYP_BE) + fmttype = bigendian() ? FMT_BINLE : FMT_BINBE; + else if (fmttype == FMT_PAX && s[j] == ':') { + if (pax_options(&s[j+1], 0) < 0) + continue; + } + return 0; + } + } + msg(3, 0, "Invalid header \"%s\" specified.\n", s); + return -1; +} + +static int +bigendian(void) +{ + union { + char u_c[2]; + int16_t u_i; + } u; + u.u_i = 1; + return u.u_c[1] == 1; +} + +int +setreassign(const char *s) +{ + struct passwd *pwd; + int val = 0; + + if (myuid != 0) { + msg(3, 0, "R option only valid for super-user.\n"); + val = -1; + } + if ((pwd = getpwnam(s)) == NULL) { + msg(3, 0, "\"%s\" is not a valid user id\n", s); + val = -1; + } else { + Ruid = pwd->pw_uid; + Rgid = pwd->pw_gid; + } + return val; +} + +void * +srealloc(void *m, size_t n) +{ + if ((m = realloc(m, n)) == NULL) { + write(2, "Out of memory.\n", 15); + _exit(sysv3 ? 2 : 3); + } + return m; +} + +void * +smalloc(size_t n) +{ + return srealloc(NULL, n); +} + +void * +scalloc(size_t nmemb, size_t size) +{ + void *vp; + + if ((vp = calloc(nmemb, size)) == NULL) { + write(2, "Out of memory.\n", 15); + _exit(sysv3 ? 2 : 3); + } + return vp; +} + +void * +svalloc(size_t n, int force) +{ + static long pagesize; + void *vp; + + if (pagesize == 0) + if ((pagesize = sysconf(_SC_PAGESIZE)) < 0) + pagesize = 4096; + if ((vp = memalign(pagesize, n)) == NULL && force) { + write(2, "Out of memory.\n", 15); + _exit(sysv3 ? 2 : 3); + } + return vp; +} + +/* + * A single static buffer is used for intermediate copying from file + * data to the tape buffer and vice versa, for creating checksums, and + * for data transfer with -p. + */ +static void +getbuf(char **bufp, size_t *sizep, size_t best) +{ + static char *buf; + static size_t size; + + if (size != best) { + if (buf) + free(buf); + size = best; + if (size == 0 || (buf = svalloc(size, 0)) == NULL) + buf = svalloc(size = 512, 1); + } + *bufp = buf; + *sizep = size; +} + +static void +sevprnt(int sev) +{ + if (printsev) switch (sev) { + case 1: + fprintf(stderr, "INFORM: "); + break; + case 2: + fprintf(stderr, "WARNING: "); + break; + case 3: + fprintf(stderr, "ERROR: "); + break; + case 4: + fprintf(stderr, "HALT: "); + break; + } +} + +void +msg(int sev, int err, const char *fmt, ...) +{ + va_list ap; + + /* + * The error message should appear near the file it refers to. + */ + if (tflag) + fflush(stdout); + else if (Vflag) + prdot(1); + if (sysv3 >= 0 && sev >= (printsev ? 0 : -1)) + fprintf(stderr, "%s: ", progname); + sevprnt(sev); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + if (err > 0) + done(err); + else if (err == -2) { + if (sysv3) + done(1); + usage(); + } +} + +void +emsg(int sev, const char *fmt, ...) +{ + char _fmt[60]; + int i, fl = sev & 030, n; + va_list ap; + + sev &= ~030; + i = errno; + if (tflag) + fflush(stdout); + else if (Vflag) + prdot(1); + fprintf(stderr, "%s: ", progname); + sevprnt(sev); + va_start(ap, fmt); + if (sysv3) { + if (fmt[(n=strlen(fmt))-1] == '"' && fmt[n-2] == 's' && + fmt[n-3] == '%' && fmt[n-4] == '"' && + n < sizeof _fmt) { + strcpy(_fmt, fmt); + _fmt[n-1] = '>'; + _fmt[n-4] = '<'; + fmt = _fmt; + } + } + vfprintf(stderr, fmt, ap); + va_end(ap); + if (sysv3 > 0 && sev >= 0 && fl & 010) + fprintf(stderr, "\n\t%s\n", strerror(i)); + else if (sysv3 < 0) { + if (fl & 020) + putc('\n', stderr); + else + fprintf(stderr, " (errno:%d)\n", i); + } else + fprintf(stderr, ", errno %d, %s\n", i, strerror(i)); +} + +static void +prdot(int flush) +{ + static int column; + + if (flush && column != 0 || column >= 50) { + write(action == 'o' && !Oflag ? 2 : 1, "\n", 1); + column = 0; + } + if (!flush) { + write(action == 'o' && !Oflag ? 2 : 1, ".", 1); + column++; + } +} + +/* + * Ask the user for new media if applicable, or exit. + */ +static void +newmedia(int err) +{ + static int mediacnt = 1; + static char answer[PATH_MAX+1]; + const char *mesf = action == 'i' ? + (Iflag && !sysv3 ? Iflag : "input") : + (Oflag && !sysv3 ? Oflag : "output"); + char c; + int i, j; + + if (mfl == 0 && close(mt) < 0) { + emsg(3, "Close error on \"%s\"", mesf); + errcnt++; + } + mfl = -1; + if ((mtst.st_mode&S_IFMT)!=S_IFCHR && (mtst.st_mode&S_IFMT)!=S_IFBLK || + Dflag) { + if (action == 'o') { + switch (err) { + case 0: + break; + case EFBIG: + msg(3, 0, "ulimit reached for output file.\n"); + break; + case ENOSPC: + msg(3, 0, "No space left for output file.\n"); + break; + default: + msg(3, 0, "I/O error - cannot continue, " + "errno %d, %s\n", + err, strerror(err)); + } + } + return; + } + if (err == ENOSPC || err == ENXIO || err == 0) + msg(-2, 0, sysv3 ? "Reached end of medium on %s.\a\n" : + "End of medium on \"%s\".\a\n", mesf); + else + msg(3, 0, "I/O error on \"%s\", errno %d, %s\a\n", mesf, + err, strerror(err)); + mediacnt++; + while (mfl < 0) { + if (Iflag || Oflag) + msg(-2, 0, Mflag ? Mflag : + "Change to part %d and press " + "RETURN key. [q] ", mediacnt); + else + msg(-2, 0, sysv3 ? "If you want to go on, " + "type device/file name when ready.\n" : + "To continue, type device/file name " + "when ready.\n"); + if (tty == 0) + if ((tty = open("/dev/tty", O_RDWR)) < 0 || + fcntl(tty, F_SETFD, FD_CLOEXEC) < 0) { + cantrt: errcnt++; + msg(4, 1, "Cannot read tty.\n"); + } + i = 0; + while ((j = read(tty, &c, 1)) == 1 && c != '\n') + if (i < sizeof answer - 1) + answer[i++] = c; + if (j != 1) + goto cantrt; + answer[i] = 0; + if (Iflag || Oflag) { + if (answer[0] == '\0') + snprintf(answer, sizeof answer, Iflag ? Iflag : + Oflag); + else if (answer[0] == 'q') + exit(errcnt != 0 ? sysv3 ? 1 : 2 : 0); + else if (Iflag) + Iflag = sstrdup(answer); + else if (Oflag) + Oflag = sstrdup(answer); + } else if (answer[0] == '\0') + return; + if ((mt = action == 'i' ? open(answer, O_RDONLY) : + creat(answer, 0666)) < 0) { + if (sysv3) + msg(-2, 0, "That didn't work, " + "cannot open \"%s\"\n%s\n", + answer, strerror(errno)); + else + emsg(3, "Cannot open \"%s\"", answer); + } + else + mfl = 0; + } + mstat(); +} + +static void +mclose(void) +{ + if (action == 'o' && mt >= 0 && close(mt) < 0) { + emsg(3, "Close error on \"%s\"", + Oflag && !sysv3 ? Oflag : "output"); + errcnt++; + } +} + +/* + * Write the archive buffer to tape. + */ +static ssize_t +mwrite(int max) +{ + ssize_t wo, wt = 0; + + do { + if ((wo = write(mt, blkbuf + wt, (max?max:blksiz) - wt)) < 0) { + if (errno == EINTR) { + continue; + } else { + newmedia(errno); + if (mfl == 0) { + if (fmttype & TYP_BAR) + dump_barhdr(); + continue; + } + else + done(1); + } + } + poffs += wo; + wt += wo; + } while (wt < (max?max:blksiz)); + blocks += wt >> 9; + bytes += wt & 0777; + return wt; +} + +/* + * Buffered writes to tape. + */ +static void +bwrite(const char *data, size_t sz) +{ + size_t di; + + nwritten += sz; + while (curpos + sz > blksiz) { + di = blksiz - curpos; + sz -= di; + memcpy(&blkbuf[curpos], data, di); + mwrite(0); + data += di; + curpos = 0; + } + memcpy(&blkbuf[curpos], data, sz); + curpos += sz; +} + +/* + * Flush the tape write buffer. + */ +static void +bflush(void) +{ + if (curpos) { + memset(&blkbuf[curpos], 0, blksiz - curpos); + mwrite(fmttype==FMT_ZIP && (mtst.st_mode&S_IFMT) == S_IFREG ? + curpos : 0); + } + curpos = 0; +} + +/* + * CRC format checksum calculation with -i. + */ +static int +sum(int fd, const char *fn, struct stat *sp, char *tg) +{ + char *buf; + size_t bufsize; + uint32_t size = sp->st_size, sum = 0; + ssize_t rd; + char c; + + getbuf(&buf, &bufsize, sp->st_blksize); + /* + * Unfortunately, SVR4 cpio derivatives (as on Solaris 8 and + * UnixWare 2.1) compute the checksum of signed char values, + * whereas GNU cpio and the pax implementations of AT&T and + * BSD use unsigned chars. Since there is no 'open' standard + * for the SVR4 CRC format, the SVR4 implementation should be + * taken as a de facto reference and we thus create SVR4 type + * checksums. + */ + while ((rd = read(fd, buf, size>bufsize ? bufsize : size )) > 0) { + size -= rd; + do + sum += ((signed char *)buf)[--rd]; + while (rd); + } + if (rd < 0) { + msg(3, 0, "Error computing checksum\n"); + return 1; + } + if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { + emsg(3, "Cannot reset file after checksum"); + return 1; + } + c = tg[8]; + sprintf(tg, "%08lx", (long)sum); + tg[8] = c; + return 0; +} + +static int +rstime(const char *fn, struct stat *st, const char *which) +{ + struct utimbuf utb; + + utb.actime = st->st_atime; + utb.modtime = st->st_mtime; + if (pax != PAX_TYPE_CPIO && + (pax_preserve&(PAX_P_ATIME|PAX_P_MTIME)) != 0 && + (pax_preserve&PAX_P_EVERY) == 0) { + struct stat xst; + if (stat(fn, &xst) < 0) + goto fail; + if (pax_preserve&PAX_P_ATIME) + utb.actime = xst.st_atime; + if (pax_preserve&PAX_P_MTIME) + utb.modtime = xst.st_mtime; + } + if (utime(fn, &utb) < 0) { + fail: emsg(2, "Unable to reset %s time for \"%s\"", which, fn); + return 1; + } + return 0; +} + +/* + * Top-down splay function for inode tree. + */ +static struct islot * +isplay(ino_t ino, struct islot *x) +{ + struct islot hdr; + struct islot *leftmax, *rightmin; + struct islot *y; + + hdr.i_lln = hdr.i_rln = inull; + leftmax = rightmin = &hdr; + inull->i_ino = ino; + while (ino != x->i_ino) { + if (ino < x->i_ino) { + if (ino < x->i_lln->i_ino) { + y = x->i_lln; + x->i_lln = y->i_rln; + y->i_rln = x; + x = y; + } + if (x->i_lln == inull) + break; + rightmin->i_lln = x; + rightmin = x; + x = x->i_lln; + } else { + if (ino > x->i_rln->i_ino) { + y = x->i_rln; + x->i_rln = y->i_lln; + y->i_lln = x; + x = y; + } + if (x->i_rln == inull) + break; + leftmax->i_rln = x; + leftmax = x; + x = x->i_rln; + } + } + leftmax->i_rln = x->i_lln; + rightmin->i_lln = x->i_rln; + x->i_lln = hdr.i_rln; + x->i_rln = hdr.i_lln; + inull->i_ino = !ino; + return x; +} + +/* + * Find the inode number ino. + */ +static struct islot * +ifind(ino_t ino, struct islot **it) +{ + if (*it == NULL) + return NULL; + *it = isplay(ino, *it); + return (*it)->i_ino == ino ? *it : NULL; +} + +/* + * Put ik into the tree. + */ +static void +iput(struct islot *ik, struct islot **it) +{ + if ((*it) == NULL) { + ik->i_lln = ik->i_rln = inull; + (*it) = ik; + } else { + /* ifind() is always called before */ + /*(*it) = isplay(ik->i_ino, (*it));*/ + if (ik->i_ino < (*it)->i_ino) { + ik->i_lln = (*it)->i_lln; + ik->i_rln = (*it); + (*it)->i_lln = inull; + (*it) = ik; + } else if ((*it)->i_ino < ik->i_ino) { + ik->i_rln = (*it)->i_rln; + ik->i_lln = (*it); + (*it)->i_rln = inull; + (*it) = ik; + } + } +} + +/* + * Find the device dev or add it to the device/inode forest if not + * already present. + */ +static struct dslot * +dfind(struct dslot **root, dev_t dev) +{ + struct dslot *ds, *dp; + + for (ds = *root, dp = NULL; ds; dp = ds, ds = ds->d_nxt) + if (ds->d_dev == dev) + break; + if (ds == NULL) { + ds = scalloc(1, sizeof *ds); + ds->d_dev = dev; + if (*root == NULL) + *root = ds; + else + dp->d_nxt = ds; + } + return ds; +} + +/* + * Exit on fatal error conditions. + */ +static void +done(int i) +{ + if (tflag) + fflush(stdout); + errcnt += i; + mclose(); + if (errcnt && !sysv3) + fprintf(stderr, "%llu errors\n", errcnt); + exit(sysv3 ? 2 : 3); +} + +static char *pcopy, *pcend; +static size_t psz, pslen, pss; + +/* + * Execution for -p. + */ +static void +dopass(const char *target) +{ + struct stat st; + + if (access(target, W_OK) < 0) { + emsg(033, sysv3 ? "cannot write in <%s>" : + "Error during access() of \"%s\"", target); + if (sysv3) + done(1); + usage(); + } + if (stat(target, &st) < 0) { + emsg(023, "Error during stat() of \"%s\"", target); + done(1); + } + if ((st.st_mode&S_IFMT) != S_IFDIR) + msg(3, 1, sysv3 ? "<%s> not a directory.\n" : + "\"%s\" is not a directory\n", target); + getpath(target, &pcopy, &pcend, &psz, &pslen); + copyout(passfile); +} + +/* + * Callback for sfile(). + */ +/*ARGSUSED*/ +void +writerr(void *vp, int count, int written) +{ +} + +/* + * Copy file data of regular files with -p. + */ +static int +passdata(struct file *f, const char *tgt, int tfd) +{ + char *buf; + size_t bufsize; + ssize_t rd = 0; + + if (f->f_fd < 0) /* is a zero-sized unreadable file */ + return 0; +#ifdef __linux__ + if (f->f_st.st_size > 0) { + long long sent; + + sent = sfile(tfd, f->f_fd, f->f_st.st_mode, f->f_st.st_size); + blocks += (sent + 0777) >> 9; + if (sent == f->f_st.st_size) + return 0; + if (sent < 0) + goto rerr; + } +#endif /* __linux__ */ + getbuf(&buf, &bufsize, f->f_st.st_blksize); + while ((rd = read(f->f_fd, buf, bufsize)) > 0) { + blocks += (rd + 0777) >> 9; + if (write(tfd, buf, rd) != rd) { + emsg(3, "Cannot write \"%s\"", tgt); + return -1; + } + } + if (rd < 0) { +#ifdef __linux__ + rerr: +#endif /* __linux__ */ + emsg(3, "Cannot read \"%s\"", f->f_name); + return -1; + } + return 0; +} + +/* + * Handle a single file for -p. + */ +static int +passfile(const char *fn, struct stat *st) +{ + struct file f; + ssize_t sz; + int val; + char *newfn; + size_t newsz = 0; + + newfn = sstrdup(fn); + if (pax != PAX_TYPE_CPIO) { + if (pax_sflag && pax_sname(&newfn, &newsz) == 0) + return 0; + if (rflag && rname(&newfn, &newsz) == 0) + return 0; + } + setpath(newfn, &pcopy, &pcend, pslen, &psz, &pss); + free(newfn); + memset(&f, 0, sizeof f); + f.f_name = sstrdup(fn); + f.f_nsiz = strlen(fn) + 1; + f.f_st = *st; + f.f_fd = -1; + if ((st->st_mode&S_IFMT) == S_IFLNK) { + sz = st->st_size ? st->st_size : PATH_MAX; + f.f_lnam = smalloc(sz+1); + if ((sz = readlink(fn, f.f_lnam, sz+1)) < 0) { + emsg(3, "Cannot read symbolic link \"%s\"", fn); + free(f.f_lnam); + return 1; + } + f.f_lnam[sz] = '\0'; + } else if ((st->st_mode&S_IFMT) == S_IFREG) { + if ((f.f_fd = open(fn, O_RDONLY)) < 0) { + if (sysv3) + msg(2, 0, "Cannot open file \"%s\".\n", fn); + else + emsg(2, "Cannot open \"%s\", skipped", fn); + if (st->st_size != 0) + return 1; + } + } + val = filein(&f, passdata, pcopy); + if (f.f_lnam) + free(f.f_lnam); + free(f.f_name); + if (f.f_fd >= 0) + close(f.f_fd); + if (val <= 1 && aflag && (st->st_mode&S_IFMT) == S_IFREG) + errcnt += rstime(fn, st, "access"); + return val != 0; +} + +/* + * Processing of a single file common to -i and -p. Return value: 0 if + * successful, 1 at failure if data was read, 2 at failure if no data + * was read. + */ +static int +filein(struct file *f, int (*copydata)(struct file *, const char *, int), + char *tgt) +{ + struct stat nst; + char *temp = NULL; + size_t len; + int fd, i, j, new; + int failure = 2; + + if (fmttype == FMT_ZIP && (f->f_st.st_mode&S_IFMT) != S_IFREG && + (f->f_st.st_mode&S_IFMT) != S_IFLNK && + (f->f_csize > 0 || f->f_gflag & FG_DESC)) + skipfile(f); + if ((new = lstat(tgt, &nst)) == 0) { + if (action == 'p' && f->f_st.st_dev == nst.st_dev && + f->f_st.st_ino == nst.st_ino) { + msg(3, 0, sysv3 ? + "Attempt to pass file to self!\n" : + "Attempt to pass a file to itself.\n"); + return 1; + } + if ((f->f_st.st_mode&S_IFMT) == S_IFDIR) { + if ((nst.st_mode&S_IFMT) == S_IFDIR) + return setattr(tgt, &f->f_st); + rmdir(tgt); + } else { + if (pax_kflag) { + failure = 0; + goto skip; + } + if (uflag == 0 && f->f_st.st_mtime <= nst.st_mtime) { + if (pax == PAX_TYPE_CPIO) + msg(-1, 0, sysv3 ? + "current <%s> newer or same age\n" : + "Existing \"%s\" same age or newer\n", + tgt); + else + failure = 0; + goto skip; + } + } + } else { + if (imdir(tgt) < 0) + goto skip; + } + if (Vflag && !vflag) + prdot(0); + if ((f->f_st.st_mode&S_IFMT) != S_IFDIR && lflag) { + if (Lflag) { + char *symblink, *name; + struct stat xst; + name = f->f_name; + for (;;) { + if (lstat(name, &xst) < 0) { + emsg(3, "Cannot lstat \"%s\"", name); + if (name != f->f_name) + free(name); + goto cantlink; + } + if ((xst.st_mode&S_IFMT) != S_IFLNK) + break; + i = xst.st_size ? xst.st_size : PATH_MAX; + symblink = smalloc(i+1); + if ((j = readlink(name, symblink, i)) < 0) { + emsg(3, "Cannot read symbolic link " + "\"%s\"", name); + free(symblink); + if (name != f->f_name) + free(name); + goto cantlink; + } + symblink[j] = '\0'; + symblink = joinpath(name, symblink); + if (name != f->f_name) + free(name); + name = symblink; + } + if (linkunlink(name, tgt) == 0) { + if (vflag) + fprintf(stderr, "%s\n", tgt); + if (name != f->f_name) + free(name); + return 0; + } + if (name != f->f_name) + free(name); + } else if (linkunlink(f->f_name, tgt) == 0) { + if (vflag) + fprintf(stderr, "%s\n", tgt); + return 0; + } +cantlink: errcnt += 1; + } + if ((f->f_st.st_mode&S_IFMT) != S_IFDIR && f->f_st.st_nlink > 1 && + (fmttype & TYP_CPIO || fmttype == FMT_ZIP + || action == 'p') && + (i = canlink(tgt, &f->f_st, 1)) != 0) { + if (i < 0) + goto skip; + /* + * At this point, hard links in SVR4 cpio format have + * been reordered and data is associated with the first + * link; remaining links have st_size == 0 so don't + * overwrite the data here. + */ + if (fmttype & TYP_NCPIO && f->f_st.st_size == 0 || + (f->f_st.st_mode&S_IFMT) != S_IFREG) { + if (vflag) + fprintf(stderr, "%s\n", f->f_name); + return 0; + } + /* + * Make sure we can creat() this file later. + */ + chmod(tgt, 0600); + } else if (fmttype & TYP_TAR && f->f_st.st_nlink > 1) { + if (linkunlink(f->f_lnam, f->f_name) == 0) { + if (fmttype & TYP_USTAR && f->f_st.st_size > 0) + chmod(tgt, 0600); + else { + if (vflag) + fprintf(stderr, "%s\n", f->f_name); + return 0; + } + } else { + goto restore; + } + } else if (new == 0 && (f->f_st.st_mode&S_IFMT) != S_IFDIR) { + len = strlen(tgt); + temp = smalloc(len + 7); + strcpy(temp, tgt); + strcpy(&temp[len], "XXXXXX"); + if ((fd = mkstemp(temp)) < 0 || close(fd) < 0) { + emsg(3, "Cannot create temporary file"); + if (fd < 0) { + free(temp); + temp = NULL; + } + goto skip; + } + cur_ofile = tgt; + cur_tfile = temp; + if (rename(tgt, temp) < 0) { + emsg(3, "Cannot rename current \"%s\"", tgt); + tunlink(&temp); + goto skip; + } + } + switch (f->f_st.st_mode & S_IFMT) { + case S_IFDIR: + if (!dflag) { + if (action == 'p') + msg(-1, 0, "Use -d option to copy \"%s\"\n", + f->f_name); + goto restore; + } + if (mkdir(tgt, 0777) < 0 && errno != EEXIST) { + emsg(-1, "Cannot create directory \"%s\"", tgt); + goto restore; + } + break; + case S_IFLNK: + if (symlink(f->f_lnam, tgt) < 0) { + emsg(3, "Cannot create \"%s\"", tgt); + goto restore; + } + break; + case S_IFREG: + if (temp && f->f_fd < 0) + goto restore; + cur_ofile = tgt; + if ((fd = (compressed_bar ? zcreat : creat)(tgt, + f->f_st.st_mode & 0777)) < 0) { + emsg(3, "Cannot create \"%s\"", tgt); + goto skip; + } + failure = 1; + if (copydata(f, tgt, fd) != 0) { + close(fd); + goto restore; + } + if ((compressed_bar ? zclose : close)(fd) < 0) { + emsg(3, "Close error on \"%s\"", tgt); + goto restore; + } + break; + case S_IFBLK: + case S_IFCHR: + case S_IFIFO: + case S_IFNAM: + case S_IFNWK: + if (mknod(tgt, f->f_st.st_mode&(S_IFMT|0777), + f->f_st.st_rdev) < 0) { + emsg(3, "Cannot mknod() \"%s\"", tgt); + goto restore; + } + break; + default: + msg(-1, 0, "Impossible file type\n"); + goto skip; + } + if (vflag) + fprintf(stderr, "%s\n", f->f_name); + tunlink(&temp); + return setattr(tgt, &f->f_st); +skip: if (copydata == indata) + skipdata(f, copydata); +restore: + if (temp) { + if (rename(temp, tgt) < 0) { + emsg(3, "Cannot recover original version of \"%s\"", + tgt); + tunlink(&temp); + } else + fprintf(stderr, "Restoring existing \"%s\"\n", tgt); + cur_tfile = cur_ofile = NULL; + } + return failure; +} + +static int +linkunlink(const char *path1, const char *path2) +{ + int twice = 0; + + do { + if (link(path1, path2) == 0) { + if (vflag && pax == PAX_TYPE_CPIO) + printf("%s linked to %s\n", path1, path2); + return 0; + } + if (errno == EEXIST && unlink(path2) < 0) + emsg(3, sysv3 ? "cannot unlink <%s>" : + "Error cannot unlink \"%s\"", path2); + } while (twice++ == 0); + emsg(023, sysv3 ? "Cannot link <%s> & <%s>" : + "Cannot link \"%s\" and \"%s\"", path1, path2); + return -1; +} + +static void +tunlink(char **fn) +{ + cur_tfile = cur_ofile = NULL; + if (*fn) { + if (unlink(*fn) < 0) + emsg(3, "Cannot unlink() temp file \"%s\"", *fn); + free(*fn); + *fn = NULL; + } +} + +/* + * For -it[v] option. + */ +static int +filet(struct file *f, int (*copydata)(struct file *, const char *, int)) +{ + if (vflag && ( + (fmttype == FMT_ZIP && f->f_gflag & FG_DESC && + (f->f_cmethod == C_DEFLATED || f->f_cmethod == C_ENHDEFLD) && + (f->f_gflag & FG_CRYPT) == 0) || + f->f_Kbase)) { + /* + * Need to read zip data descriptor located after the + * file contents in order to know the file size. Or + * need to read second header of -K archive. + */ + int i; + i = skipdata(f, copydata); + filev(f); + return i; + } + if (vflag) + filev(f); + else + puts(f->f_name); + return skipdata(f, copydata); +} + +static void +filev(struct file *f) +{ + const char *cp; + long c; + + if (pax == PAX_TYPE_CPIO && fmttype & TYP_TAR && f->f_st.st_nlink > 1) + printf("%s linked to %s\n", f->f_lnam, f->f_name); + if (sysv3) + printf("%-6o", (int)f->f_st.st_mode&(07777|S_IFMT)); + else { + c = typec(&f->f_st); + putchar(c); + permbits(f->f_st.st_mode); + } + if (fmttype == FMT_ZIP && vflag > 1) + zipinfo(f); + else { + if (sysv3 == 0) + printf(" %3d", fmttype&TYP_TAR && + (f->f_st.st_mode&S_IFMT) == S_IFLNK ? + 2 : (int)f->f_st.st_nlink); + if ((cp = getuser(f->f_st.st_uid)) != NULL) + printf(sysv3 ? " %-6s" : " %-8s", cp); + else + printf(sysv3 ? " %-6lu" : " %-8lu", + (long)f->f_st.st_uid); + if (sysv3 == 0) { + if ((cp = getgroup(f->f_st.st_gid)) != NULL) + printf(" %-8s", cp); + else + printf(" %-8lu", (long)f->f_st.st_gid); + } + } + if (sysv3 || (f->f_st.st_mode&S_IFMT)!=S_IFCHR && + (f->f_st.st_mode&S_IFMT)!=S_IFBLK && + (f->f_st.st_mode&S_IFMT)!=S_IFNAM && + (f->f_st.st_mode&S_IFMT)!=S_IFNWK) + printf(pax != PAX_TYPE_CPIO ? "%8llu" : + sysv3 ? "%7llu" : " %-7llu", f->f_dsize); + else + printf(" %3lu,%3lu", (long)f->f_rmajor, (long)f->f_rminor); + prtime(f->f_st.st_mtime); + printf("%s", f->f_name); + if ((f->f_st.st_mode&S_IFMT) == S_IFLNK) + printf(" -> %s", f->f_lnam); + if (pax != PAX_TYPE_CPIO && (f->f_st.st_mode&S_IFMT) != S_IFDIR && + f->f_st.st_nlink>1) { + if (fmttype & TYP_TAR) + printf(" == %s", f->f_lnam); + else + canlink(f->f_name, &f->f_st, 0); + } + putchar('\n'); +} + +static int +typec(struct stat *st) +{ + switch (st->st_mode&S_IFMT) { + case S_IFREG: + return '-'; + case S_IFDIR: + return 'd'; + case S_IFLNK: + return 'l'; + case S_IFCHR: + return 'c'; + case S_IFBLK: + return 'b'; + case S_IFIFO: + return 'p'; + case S_IFNWK: + return 'n'; + case S_IFNAM: + switch (st->st_rdev) { + case S_INSEM: + return 's'; + case S_INSHD: + return 'm'; + } + /*FALLTHRU*/ + default: + msg(-1, 0, "Impossible file type\n"); + errcnt++; + return '-'; + } +} + +static void +permbits(mode_t mode) +{ + mode_t mask = 0700, shft = 6; + + while (mask) { + if (((mode & mask) >> shft) & 04) + putchar('r'); + else + putchar('-'); + if (((mode & mask) >> shft) & 02) + putchar('w'); + else + putchar('-'); + if (mask == 0700 && mode & 04000) + putchar('s'); + else if (mask == 0070 && (mode & 02010) == 02010) + putchar('s'); + else if (mask == 0070 && mode & 02000) + putchar('l'); + else if (mask == 0007 && mode & 01000) + putchar('t'); + else if (((mode & mask) >> shft) & 01) + putchar('x'); + else + putchar('-'); + mask >>= 3; + shft -= 3; + } +} + +static void +prtime_cpio(time_t t) +{ + char b[30]; + + strftime(b, sizeof b, sysv3 ? "%b %e %H:%M:%S %Y" : "%b %e %H:%M %Y", + localtime(&t)); + printf(sysv3 ? " %s " : " %s, ", b); +} + +/* + * Prepare path to add names of files below it later. + */ +static void +getpath(const char *path, char **file, char **filend, size_t *sz, size_t *slen) +{ + *sz = 14 + strlen(path) + 2; + *file = smalloc(*sz); + *filend = *file; + if (path[0] == '/' && path[1] == '\0') + *(*filend)++ = '/'; + else { + const char *cp = path; + while ((*(*filend)++ = *cp++) != '\0'); + (*filend)[-1] = '/'; + } + *slen = *filend - *file; +} + +/* + * Concatenate base (prepared with getpath()) and file. + */ +static void +setpath(const char *base, char **file, char **filend, + size_t slen, size_t *sz, size_t *ss) +{ + if (slen + (*ss = strlen(base)) >= *sz) { + *sz += slen + *ss + 15; + *file = srealloc(*file, *sz); + *filend = &(*file)[slen]; + } + strcpy(*filend, base); +} + +/* + * Create intermediate directories with -m. + */ +static int +imdir(char *fn) +{ + struct stat st; + char *cp; + int dfl = dflag != 0; + + for (cp = fn; *cp == '/'; cp++); + do { + while (*cp && *cp != '/') + cp++; + if (*cp == '/') { + *cp = '\0'; + if (stat(fn, &st) < 0) { + if (dfl) { + if (mkdir(fn, 0777) < 0) { + *cp = '/'; + emsg(-1, "Cannot create " + "directory for \"%s\"", + fn); + return -1; + } + } else { + msg(-1, 0, sysv3 ? + "missing 'd' option\n" : + "Missing -d option\n"); + dfl = 2; + } + } + *cp = '/'; + while (*cp == '/') + cp++; + } + } while (*cp); + return 0; +} + +/* + * Set file attributes and make sure that suid/sgid bits are only restored + * if the owner is the same as on the tape. + */ +static int +setattr(const char *fn, struct stat *st) +{ + mode_t mode = st->st_mode & 07777; + uid_t uid = Rflag ? Ruid : myuid; + gid_t gid = Rflag ? Rgid : mygid; + + if ((pax != PAX_TYPE_CPIO || myuid == 0) && + (pax == PAX_TYPE_CPIO || + pax_preserve&(PAX_P_OWNER|PAX_P_EVERY))) { + if (setowner(fn, st) != 0) + return 1; + } + if (pax != PAX_TYPE_CPIO && + (pax_preserve&(PAX_P_OWNER|PAX_P_EVERY)) == 0) + mode &= ~(mode_t)(S_ISUID|S_ISGID); + if (myuid != 0 || Rflag) { + if (st->st_uid != uid || st->st_gid != gid) { + mode &= ~(mode_t)S_ISUID; + if ((st->st_mode&S_IFMT) != S_IFDIR && mode & 0010) + mode &= ~(mode_t)S_ISGID; + if ((st->st_mode&S_IFMT) == S_IFDIR && st->st_gid!=gid) + mode &= ~(mode_t)S_ISGID; + } + } + if ((st->st_mode&S_IFMT) == S_IFLNK) + return 0; + if (hp_Uflag) + mode &= ~umsk|S_IFMT; + if (pax != PAX_TYPE_CPIO && + (pax_preserve&(PAX_P_MODE|PAX_P_OWNER|PAX_P_EVERY))==0) + mode &= 01777|S_IFMT; + if ((pax == PAX_TYPE_CPIO || pax_preserve&(PAX_P_MODE|PAX_P_EVERY)) && + chmod(fn, mode) < 0) { + emsg(2, "Cannot chmod() \"%s\"", fn); + return 1; + } + if (pax != PAX_TYPE_CPIO ? + (pax_preserve&(PAX_P_ATIME|PAX_P_MTIME|PAX_P_EVERY)) != + (PAX_P_ATIME|PAX_P_MTIME) : mflag) + return rstime(fn, st, "modification"); + else + return 0; +} + +static int +setowner(const char *fn, struct stat *st) +{ + uid_t uid = Rflag ? Ruid : myuid ? myuid : st->st_uid; + gid_t gid = Rflag ? Rgid : st->st_gid; + + if (((st->st_mode&S_IFMT)==S_IFLNK?lchown:chown)(fn, uid, gid) < 0) { + emsg(2, "Cannot chown() \"%s\"", fn); + return 1; + } + if (pax >= PAX_TYPE_PAX2001 && myuid && myuid != st->st_uid && + pax_preserve & (PAX_P_OWNER|PAX_P_EVERY)) { + /* + * Do not even try to preserve user ownership in this case. + * It would either fail, or, without _POSIX_CHOWN_RESTRICTED, + * leave us with a file we do not own and which we thus could + * not chmod() later. + */ + errno = EPERM; + emsg(2, "Cannot chown() \"%s\"", fn); + return 1; + } + return 0; +} + +/* + * For -i and -p: Check if device/inode have been created already and + * if so, link path (or print the link name). + */ +static int +canlink(const char *path, struct stat *st, int really) +{ + struct dslot *ds; + struct islot *ip; + + ds = dfind(&devices, st->st_dev); + if ((ip = ifind(st->st_ino, &ds->d_isl)) == NULL || + ip->i_name == NULL) { + if (ip == NULL) { + ip = scalloc(1, sizeof *ip); + ip->i_ino = st->st_ino; + if ((fmttype&(TYP_NCPIO|TYP_TAR)) == 0) + ip->i_nlk = st->st_nlink; + iput(ip, &ds->d_isl); + } + ip->i_name = sstrdup(path); + } else { + if ((fmttype&(TYP_NCPIO|TYP_TAR)) == 0) { + /* + * If an archive inode has more links than given in + * st_nlink, write a new disk inode. See the comments + * to storelink() for the rationale. + */ + if (--ip->i_nlk == 0) { + free(ip->i_name); + ip->i_name = sstrdup(path); + ip->i_nlk = st->st_nlink; + return 0; + } + } + if (really) { + /* + * If there was file data before the last link with + * SVR4 cpio formats, do not create a hard link. + */ + if (fmttype & TYP_NCPIO && ip->i_nlk == 0) + return 0; + if (linkunlink(ip->i_name, path) == 0) + return 1; + else + return -1; + } else { + printf(" == %s", ip->i_name); + return 1; + } + } + return 0; +} + +/* + * Execution for -i. + */ +static void +doinp(void) +{ + union bincpio bc; + struct file f; + int n; + + memset(&f, 0, sizeof f); + if (Eflag) + patfile(); + if (Iflag) { + if ((mt = open(Iflag, O_RDONLY)) < 0) { + if (sysv3) { + emsg(3, "Cannot open <%s> for input.", Iflag); + done(1); + } + else + msg(3, -2, "Cannot open \"%s\" for input\n", + Iflag); + } + } else + mt = dup(0); + mstat(); + blkbuf = svalloc(blksiz, 1); + if ((n = mread()) == 0) + unexeoa(); + else if (n < 0) { + emsg(3, "Read error on \"%s\"", + Iflag && !sysv3 ? Iflag : "input"); + done(1); + } + if (kflag == 0 && sixflag == 0) + fmttype = FMT_NONE; + if (fmttype == FMT_NONE) + whathdr(); + else + formatforced = 1; + while (readhdr(&f, &bc) == 0) { + if (fmttype & TYP_NCPIO && f.f_st.st_nlink > 1 && + (f.f_st.st_mode&S_IFMT) != S_IFDIR) { + if (f.f_st.st_size != 0) + flushlinks(&f); + else + storelink(&f); + } else + inpone(&f, 1); + f.f_Kbase = f.f_Krest = f.f_Ksize = 0; + f.f_oflag = 0; + } + if (fmttype & TYP_NCPIO) + flushrest(f.f_pad); +} + +/* + * SVR4 cpio link handling with -i; called if we assume that more links + * to this file will follow. + */ +static void +storelink(struct file *f) +{ + struct dslot *ds; + struct islot *ip; + struct ilink *il, *iz; + + ds = dfind(&devices, f->f_st.st_dev); + if ((ip = ifind(f->f_st.st_ino, &ds->d_isl)) == NULL) { + ip = scalloc(1, sizeof *ip); + ip->i_ino = f->f_st.st_ino; + ip->i_nlk = f->f_st.st_nlink; + ip->i_st = smalloc(sizeof *ip->i_st); + *ip->i_st = f->f_st; + iput(ip, &ds->d_isl); + } else { + if (ip->i_nlk == 0) { + /* + * More links to an inode than given in the first + * st_nlink occurence are found within this archive. + * This happens if -L was specified and soft links + * point to a file with multiple hard links. We do + * the same as SVR4 cpio implementations here and + * associate these links with a new inode, since it + * is related to the way a file with a single hard + * link but referenced by soft links is unpacked. + */ + ip->i_nlk = f->f_st.st_nlink; + if (ip->i_name) + free(ip->i_name); + ip->i_name = NULL; + ip->i_st = smalloc(sizeof *ip->i_st); + *ip->i_st = f->f_st; + } else if (ip->i_nlk <= 2) { + /* + * We get here if + * - a file with multiple links is empty; + * - a broken implementation has stored file data + * before the last link; + * - a linked file has been added to the archive later + * again (does not happen with our implementation). + */ + flushnode(ip, f); + return; + } else + ip->i_nlk--; + } + for (il = ip->i_lnk, iz = NULL; il; il = il->l_nxt) + iz = il; + il = scalloc(1, sizeof *il); + il->l_siz = strlen(f->f_name) + 1; + il->l_nam = smalloc(il->l_siz); + strcpy(il->l_nam, f->f_name); + if (iz) + iz->l_nxt = il; + else + ip->i_lnk = il; +} + +/* + * Flush all links of a file with SVR4 cpio format and -i. + */ +static void +flushlinks(struct file *f) +{ + struct dslot *ds; + struct islot *ip; + + ds = dfind(&devices, f->f_st.st_dev); + ip = ifind(f->f_st.st_ino, &ds->d_isl); + flushnode(ip, f); +} + +/* + * Data of a multi-linked file shall be transferred now for SVR4 cpio + * format and -i. + */ +static void +flushnode(struct islot *ip, struct file *f) +{ + struct file nf; + struct ilink *il, *iz; + + f->f_dsize = f->f_st.st_size; + if (ip && ip->i_nlk > 0) { + /* + * Write out the file data with the first link the user + * wants to be extracted, but show the same display size + * for all links. + */ + for (il = ip->i_lnk, iz = NULL; il; + iz = il, il = il->l_nxt, iz ? free(iz), 0 : 0) { + memset(&nf, 0, sizeof nf); + nf.f_name = il->l_nam; + nf.f_nsiz = il->l_siz; + nf.f_st = f->f_st; + nf.f_chksum = f->f_chksum; + nf.f_pad = f->f_pad; + nf.f_dsize = f->f_dsize; + if (inpone(&nf, 0) == 0) { + f->f_chksum = 0; + f->f_st.st_size = 0; + } + free(il->l_nam); + } + ip->i_lnk = NULL; + if (ip->i_st) + free(ip->i_st); + ip->i_st = NULL; + } + if (f->f_name) + inpone(f, 1); + if (ip) { + if (ip->i_nlk <= 2 && ip->i_name) { + free(ip->i_name); + ip->i_name = NULL; + } + ip->i_nlk = 0; + } +} + +/* + * This writes all remaining multiply linked files, i. e. those with + * st_size == 0 and st_nlink > number of links within the archive. + */ +static void +flushrest(int pad) +{ + struct dslot *ds; + + for (ds = devices; ds; ds = ds->d_nxt) + if (ds->d_isl != NULL) + flushtree(ds->d_isl, pad); +} + +static void +flushtree(struct islot *ip, int pad) +{ + struct file f; + + if (ip == inull) + return; + flushtree(ip->i_lln, pad); + flushtree(ip->i_rln, pad); + if (ip->i_nlk > 0 && ip->i_st) { + memset(&f, 0, sizeof f); + f.f_st = *ip->i_st; + f.f_pad = pad; + flushnode(ip, &f); + } +} + +/* + * See if the user wants to have this file with -i, and extract it or + * skip its data on the tape. + */ +static int +inpone(struct file *f, int shallskip) +{ + struct glist *gp = NULL, *gb = NULL; + int val = -1, selected = 0; + + if ((patterns == NULL || (gp = want(f, &gb)) != NULL ^ fflag) && + pax_track(f->f_name, f->f_st.st_mtime)) { + selected = 1; + if ((pax_sflag == 0 || pax_sname(&f->f_name, &f->f_nsiz)) && + (rflag == 0 || rname(&f->f_name, &f->f_nsiz))) { + errcnt += infile(f); + val = 0; + } + } else if (shallskip) + errcnt += skipfile(f); + if (gp != NULL && selected) { + gp->g_gotcha = 1; + if (gp->g_nxt && gp->g_nxt->g_art) + gp->g_nxt->g_gotcha = 1; + else if (gp->g_art && gb) + gb->g_gotcha = 1; + } + return val; +} + +/* + * Read the header for a file with -i. Return values: 0 okay, 1 end of + * archive, -1 failure. + */ +static int +readhdr(struct file *f, union bincpio *bp) +{ + long namlen, l1, l2, rd, hsz; + static long attempts; + long long skipped = 0; + + if (fmttype & TYP_TAR) { + if (f->f_name) + f->f_name[0] = '\0'; + if (f->f_lnam) + f->f_lnam[0] = '\0'; + } + paxrec = globrec; +retry: f->f_st = globst; +retry2: if (fmttype & TYP_BINARY) { + hsz = SIZEOF_hdr_cpio; + if (attempts == 0 && bread(bp->data, hsz) != hsz) + unexeoa(); + if ((fmttype&TYP_BE ? pbe16(bp->Hdr.c_magic) : + ple16(bp->Hdr.c_magic)) != mag_bin) + goto badhdr; + if (fmttype & TYP_BE) { + f->f_st.st_dev = pbe16(bp->Hdr.c_dev)&0177777; + f->f_st.st_ino = pbe16(bp->Hdr.c_ino)&0177777; + f->f_st.st_mode = pbe16(bp->Hdr.c_mode); + } else { + f->f_st.st_dev = ple16(bp->Hdr.c_dev)&0177777; + f->f_st.st_ino = ple16(bp->Hdr.c_ino)&0177777; + f->f_st.st_mode = ple16(bp->Hdr.c_mode); + } + if (sixflag) { + /* + * relevant Unix 6th Edition style mode bits + * (according to /usr/sys/inode.h, untested:) + * + * 060000 IFMT type of file + * 040000 IFDIR directory + * 020000 IFCHR character special + * 060000 IFBLK block special, 0 is regular + * 007777 permission bits as today + */ + f->f_st.st_mode &= 067777; + if ((f->f_st.st_mode & 060000) == 0) + f->f_st.st_mode |= S_IFREG; + } + if (fmttype & TYP_BE) { + f->f_st.st_uid = pbe16(bp->Hdr.c_uid)&0177777; + f->f_st.st_gid = pbe16(bp->Hdr.c_gid)&0177777; + f->f_st.st_nlink = pbe16(bp->Hdr.c_nlink)&0177777; + f->f_st.st_mtime = pbe32(bp->Hdr.c_mtime); + f->f_st.st_rdev = pbe16(bp->Hdr.c_rdev); + namlen = pbe16(bp->Hdr.c_namesize); + f->f_st.st_size = pbe32(bp->Hdr.c_filesize)&0xFFFFFFFF; + } else { + f->f_st.st_uid = ple16(bp->Hdr.c_uid)&0177777; + f->f_st.st_gid = ple16(bp->Hdr.c_gid)&0177777; + f->f_st.st_nlink = ple16(bp->Hdr.c_nlink)&0177777; + f->f_st.st_mtime = pme32(bp->Hdr.c_mtime); + f->f_st.st_rdev = ple16(bp->Hdr.c_rdev); + namlen = ple16(bp->Hdr.c_namesize); + f->f_st.st_size = pme32(bp->Hdr.c_filesize)&0xFFFFFFFF; + } + f->f_rmajor = major(f->f_st.st_rdev); + f->f_rminor = minor(f->f_st.st_rdev); + if ((f->f_st.st_rdev&0xFFFF) == 0xFFFF && + f->f_st.st_size > 0 && + ((f->f_st.st_mode&S_IFMT) == S_IFBLK || + (f->f_st.st_mode&S_IFMT) == S_IFCHR && + (!formatforced || fmttype & TYP_SGI))) { + fmttype |= TYP_SGI; + f->f_rmajor = (f->f_st.st_size&0xFFFC0000)>>18; + f->f_rminor = f->f_st.st_size&0x0003FFFF; + f->f_st.st_rdev = makedev(f->f_rmajor, f->f_rminor); + f->f_st.st_size = 0; + } + if ((f->f_st.st_mode&S_IFMT) == S_IFREG && + f->f_st.st_size&0x80000000 && + (!formatforced || fmttype & TYP_SGI)) { + fmttype |= TYP_SGI; + f->f_Ksize = f->f_st.st_size&0xFFFFFFFF; + f->f_Kbase = (0x100000000LL-f->f_st.st_size) * + 0x80000000; + f->f_st.st_size = 0; + } + f->f_pad = 2; + rd = SIZEOF_hdr_cpio; + } else if (fmttype == FMT_ODC) { + hsz = SIZEOF_c_hdr; + if (attempts == 0 && bread(bp->data, hsz) != hsz) + unexeoa(); + if(memcmp(bp->Cdr.c_magic, mag_odc, sizeof mag_odc)) + goto badhdr; + f->f_st.st_dev = rdoct(bp->Cdr.c_dev, 6); + f->f_st.st_ino = rdoct(bp->Cdr.c_ino, 6); + f->f_st.st_mode = rdoct(bp->Cdr.c_mode, 6); + f->f_st.st_uid = rdoct(bp->Cdr.c_uid, 6); + f->f_st.st_gid = rdoct(bp->Cdr.c_gid, 6); + f->f_st.st_nlink = rdoct(bp->Cdr.c_nlink, 6); + f->f_st.st_rdev = rdoct(bp->Cdr.c_rdev, 6); + f->f_rmajor = major(f->f_st.st_rdev); + f->f_rminor = minor(f->f_st.st_rdev); + f->f_st.st_mtime = rdoct(bp->Cdr.c_mtime, 11); + namlen = rdoct(bp->Cdr.c_namesz, 6); + f->f_st.st_size = rdoct(bp->Cdr.c_filesz, 11); + f->f_pad = 1; + rd = SIZEOF_c_hdr; + } else if (fmttype == FMT_DEC) { + hsz = SIZEOF_d_hdr; + if (attempts == 0 && bread(bp->data, hsz) != hsz) + unexeoa(); + if(memcmp(bp->Ddr.d_magic, mag_odc, sizeof mag_odc)) + goto badhdr; + f->f_st.st_dev = rdoct(bp->Ddr.d_dev, 6); + f->f_st.st_ino = rdoct(bp->Ddr.d_ino, 6); + f->f_st.st_mode = rdoct(bp->Ddr.d_mode, 6); + f->f_st.st_uid = rdoct(bp->Ddr.d_uid, 6); + f->f_st.st_gid = rdoct(bp->Ddr.d_gid, 6); + f->f_st.st_nlink = rdoct(bp->Ddr.d_nlink, 6); + f->f_rmajor = rdoct(bp->Ddr.d_rmaj, 8); + f->f_rminor = rdoct(bp->Ddr.d_rmin, 8); + f->f_st.st_rdev = makedev(f->f_rmajor, f->f_rminor); + f->f_st.st_mtime = rdoct(bp->Ddr.d_mtime, 11); + namlen = rdoct(bp->Ddr.d_namesz, 6); + f->f_st.st_size = rdoct(bp->Ddr.d_filesz, 11); + f->f_pad = 1; + rd = SIZEOF_d_hdr; + } else if (fmttype & TYP_NCPIO) { + hsz = SIZEOF_Exp_cpio_hdr; + if (attempts == 0 && bread(bp->data, hsz) != hsz) + unexeoa(); + if (memcmp(bp->Edr.E_magic, mag_asc, sizeof mag_asc) && + memcmp(bp->Edr.E_magic, mag_crc, sizeof mag_crc)) + goto badhdr; + f->f_st.st_ino = rdhex(bp->Edr.E_ino, 8); + f->f_st.st_mode = rdhex(bp->Edr.E_mode, 8); + f->f_st.st_uid = rdhex(bp->Edr.E_uid, 8); + f->f_st.st_gid = rdhex(bp->Edr.E_gid, 8); + f->f_st.st_nlink = rdhex(bp->Edr.E_nlink, 8); + f->f_st.st_mtime = rdhex(bp->Edr.E_mtime, 8); + f->f_st.st_size = rdhex(bp->Edr.E_filesize, 8); + l1 = rdhex(bp->Edr.E_maj, 8); + l2 = rdhex(bp->Edr.E_min, 8); + f->f_st.st_dev = makedev(l1, l2); + f->f_rmajor = rdhex(bp->Edr.E_rmaj, 8); + f->f_rminor = rdhex(bp->Edr.E_rmin, 8); + f->f_st.st_rdev = makedev(f->f_rmajor, f->f_rminor); + namlen = rdhex(bp->Edr.E_namesize, 8); + f->f_chksum = rdhex(bp->Edr.E_chksum, 8); + f->f_pad = 4; + rd = SIZEOF_Exp_cpio_hdr; + } else if (fmttype & TYP_CRAY) { + int diff5 = fmttype==FMT_CRAY5 ? CRAY_PARAMSZ : 0; + hsz = SIZEOF_cray_hdr - diff5; + if (attempts == 0 && bread(bp->data, hsz) != hsz) + unexeoa(); + if (pbe64(bp->Crayhdr.C_magic) != mag_bin) + goto badhdr; + f->f_st.st_dev = pbe64(bp->Crayhdr.C_dev); + f->f_st.st_ino = pbe64(bp->Crayhdr.C_ino); + f->f_st.st_mode = pbe64(bp->Crayhdr.C_mode); + /* + * Some of the S_IFMT bits on Cray UNICOS 9 differ from + * the common Unix values, namely: + * + * S_IFLNK 0130000 symbolic link + * S_IFOFD 0110000 off line, with data + * S_IFOFL 0120000 off line, with no data + * + * We treat the latter ones as regular files. + */ + if ((f->f_st.st_mode&S_IFMT) == 0130000) + f->f_st.st_mode = f->f_st.st_mode&07777|S_IFLNK; + else if ((f->f_st.st_mode&S_IFMT) == 0110000 || + (f->f_st.st_mode&S_IFMT) == 0120000) + f->f_st.st_mode = f->f_st.st_mode&07777|S_IFREG; + f->f_st.st_uid = pbe64(bp->Crayhdr.C_uid); + f->f_st.st_gid = pbe64(bp->Crayhdr.C_gid); + f->f_st.st_nlink = pbe64(bp->Crayhdr.C_nlink); + f->f_st.st_mtime = pbe64(bp->Crayhdr.C_mtime - diff5); + f->f_st.st_rdev = pbe64(bp->Crayhdr.C_rdev); + f->f_rmajor = major(f->f_st.st_rdev); + f->f_rminor = minor(f->f_st.st_rdev); + f->f_st.st_size = pbe64(bp->Crayhdr.C_filesize - diff5); + namlen = pbe64(bp->Crayhdr.C_namesize - diff5); + f->f_pad = 1; + rd = SIZEOF_cray_hdr - diff5; + } else if (fmttype & TYP_BAR) { + hsz = 512; + if (attempts == 0 && bread(bp->data, hsz) != hsz) + unexeoa(); + if (bp->data[SIZEOF_bar_header] == '\0') { + if (kflag && !allzero(bp->data, hsz)) + goto badhdr; + return 1; + } + if (trdsum(bp) != 0 && kflag == 0) + goto badhdr; + bp->data[512] = bp->data[513] = '\0'; + if (f->f_name == NULL || f->f_name[0] == '\0') { + if (f->f_nsiz < 512) { + free(f->f_name); + f->f_name = smalloc(f->f_nsiz = 512); + } + strcpy(f->f_name, &bp->data[SIZEOF_bar_header]); + } + namlen = strlen(f->f_name) + 1; + f->f_st.st_mode = rdoct(bp->Bdr.b_mode, 8); + f->f_st.st_uid = rdoct(bp->Bdr.b_uid, 8); + f->f_st.st_gid = rdoct(bp->Bdr.b_gid, 8); + f->f_st.st_size = rdoct(bp->Bdr.b_size, 12); + f->f_st.st_mtime = rdoct(bp->Bdr.b_mtime, 12); + f->f_st.st_rdev = rdoct(bp->Bdr.b_rdev, 8); + f->f_rmajor = major(f->f_st.st_rdev); + f->f_rminor = minor(f->f_st.st_rdev); + switch (bp->Bdr.b_linkflag) { + case '0': + f->f_st.st_mode &= 07777; + if (f->f_name[namlen-2] == '/') + f->f_st.st_mode |= S_IFDIR; + else + f->f_st.st_mode |= S_IFREG; + break; + case '1': + if (f->f_lnam == NULL || f->f_lnam[0] == '\0') + blinkof(bp->data, f, namlen); + f->f_st.st_nlink = 2; + if ((f->f_st.st_mode&S_IFMT) == 0) + f->f_st.st_mode |= S_IFREG; + break; + case '2': + if (f->f_lnam == NULL || f->f_lnam[0] == '\0') + blinkof(bp->data, f, namlen); + f->f_st.st_mode &= 07777; + f->f_st.st_mode |= S_IFLNK; + } + f->f_pad = 512; + rd = 512; + } else if (fmttype & TYP_TAR) { + hsz = 512; + if (attempts == 0 && bread(bp->data, hsz) != hsz) + unexeoa(); + if (bp->Tdr.t_name[0] == '\0') { + if (kflag && !allzero(bp->data, hsz)) + goto badhdr; + return 1; + } + if (fmttype == FMT_GNUTAR) { + if (memcmp(bp->Tdr.t_magic, mag_gnutar, 8)) + goto badhdr; + } else if (fmttype & TYP_USTAR) { + if (memcmp(bp->Tdr.t_magic, mag_ustar, 6)) + goto badhdr; + } + if (trdsum(bp) != 0 && kflag == 0) + goto badhdr; + if ((fmttype & TYP_PAX) == 0 && (fmttype == FMT_GNUTAR || + strcmp(bp->Tdr.t_name, "././@LongLink") == 0)) { + switch (bp->Tdr.t_linkflag) { + case 'L': + if (readgnuname(&f->f_name, &f->f_nsiz, + rdoct(bp->Tdr.t_size, 12)) < 0) + goto badhdr; + goto retry; + case 'K': + if (readgnuname(&f->f_lnam, &f->f_lsiz, + rdoct(bp->Tdr.t_size, 12)) < 0) + goto badhdr; + goto retry; + } + } + if (fmttype & TYP_USTAR && fmttype != FMT_GNUTAR) { + switch (bp->Tdr.t_linkflag) { + case 'g': + case 'x': + if (formatforced && fmttype != FMT_PAX) + break; + fmttype = FMT_PAX; + tgetpax(&bp->Tdr, f); + goto retry2; + case 'X': + if (formatforced && fmttype != FMT_SUN) + break; + fmttype = FMT_SUN; + tgetpax(&bp->Tdr, f); + goto retry2; + } + } + if (f->f_name == NULL || f->f_name[0] == '\0') { + if (f->f_nsiz < TNAMSIZ+TPFXSIZ+2) { + free(f->f_name); + f->f_name= smalloc(f->f_nsiz=TNAMSIZ+TPFXSIZ+2); + } + tnameof(&bp->Tdr, f->f_name); + } + namlen = strlen(f->f_name) + 1; + f->f_st.st_mode = rdoct(bp->Tdr.t_mode, 8) & 07777; + if (paxrec & PR_UID) + /*EMPTY*/; + else if (fmttype == FMT_GNUTAR && bp->Tdr.t_uid[0] & 0200) + f->f_st.st_uid = pbe64(bp->Tdr.t_uid) & + 0x7FFFFFFFFFFFFFFFLL; + else + f->f_st.st_uid = rdoct(bp->Tdr.t_uid, 8); + if (paxrec & PR_GID) + /*EMPTY*/; + else if (fmttype == FMT_GNUTAR && bp->Tdr.t_gid[0] & 0200) + f->f_st.st_gid = pbe64(bp->Tdr.t_gid) & + 0x7FFFFFFFFFFFFFFFLL; + else + f->f_st.st_gid = rdoct(bp->Tdr.t_gid, 8); + if (paxrec & PR_SIZE) + /*EMPTY*/; + else if (fmttype == FMT_GNUTAR && bp->Tdr.t_size[0] == '\200') + f->f_st.st_size = pbe64(&bp->Tdr.t_size[4]); + else + f->f_st.st_size = rdoct(bp->Tdr.t_size, 12); + if ((paxrec & PR_MTIME) == 0) + f->f_st.st_mtime = rdoct(bp->Tdr.t_mtime, TTIMSIZ); + if (bp->Tdr.t_linkflag == '1') { + if (f->f_lnam == NULL || f->f_lnam[0] == '\0') + tlinkof(&bp->Tdr, f); + f->f_st.st_mode |= S_IFREG; /* for -tv */ + f->f_st.st_nlink = 2; + } else if (bp->Tdr.t_linkflag == '2') { + if (f->f_lnam == NULL || f->f_lnam[0] == '\0') + tlinkof(&bp->Tdr, f); + f->f_st.st_mode |= S_IFLNK; + } else if (tflag == 0 && (f->f_name)[namlen-2] == '/') + f->f_st.st_mode |= S_IFDIR; + else + f->f_st.st_mode |= tifmt(bp->Tdr.t_linkflag); + if (paxrec & PR_SUN_DEVMAJOR) + /*EMPTY*/; + else if (fmttype == FMT_GNUTAR && bp->Tdr.t_devmajor[0] & 0200) + f->f_rmajor = pbe64(bp->Tdr.t_devmajor) & + 0x7FFFFFFFFFFFFFFFLL; + else + f->f_rmajor = rdoct(bp->Tdr.t_devmajor, 8); + if (paxrec & PR_SUN_DEVMINOR) + /*EMPTY*/; + else if (fmttype == FMT_GNUTAR && bp->Tdr.t_devminor[0] & 0200) + f->f_rminor = pbe64(bp->Tdr.t_devminor) & + 0x7FFFFFFFFFFFFFFFLL; + else + f->f_rminor = rdoct(bp->Tdr.t_devminor, 8); + f->f_st.st_rdev = makedev(f->f_rmajor, f->f_rminor); + f->f_pad = 512; + rd = 512; + } else if (fmttype == FMT_ZIP) { + hsz = SIZEOF_zip_header; + if (attempts == 0 && bread(bp->data, hsz) != hsz) + unexeoa(); + if (memcmp(bp->Zdr.z_signature, mag_zipctr, + sizeof mag_zipctr) == 0 || + memcmp(bp->Zdr.z_signature, mag_zipend, + sizeof mag_zipend) == 0 || + memcmp(bp->Zdr.z_signature, mag_zip64e, + sizeof mag_zip64e) == 0 || + memcmp(bp->Zdr.z_signature, mag_zip64l, + sizeof mag_zip64l) == 0) + return 1; + if (memcmp(bp->Zdr.z_signature, mag_zipsig, sizeof mag_zipsig)) + goto badhdr; + f->f_st.st_uid = myuid; + f->f_st.st_gid = mygid; + f->f_st.st_nlink = 1; + f->f_st.st_mtime = + gdostime(bp->Zdr.z_modtime, bp->Zdr.z_moddate); + f->f_st.st_size = ple32(bp->Zdr.z_nsize); + f->f_csize = ple32(bp->Zdr.z_csize); + f->f_cmethod = ple16(bp->Zdr.z_cmethod); + f->f_chksum = ple32(bp->Zdr.z_crc32); + f->f_gflag = ple16(bp->Zdr.z_gflag); + rd = SIZEOF_zip_header; + namlen = ple16(bp->Zdr.z_namelen)&0177777; + if (f->f_nsiz < namlen+1) { + free(f->f_name); + f->f_name = smalloc(f->f_nsiz = namlen+1); + } + if (bread(f->f_name, namlen) != namlen) + goto corrupt; + (f->f_name)[namlen] = '\0'; + if (f->f_name[namlen-1] == '/') + f->f_st.st_mode = 0777&~(mode_t)umsk|S_IFDIR; + else + f->f_st.st_mode = 0666&~(mode_t)umsk|S_IFREG; + rd += namlen; + if ((l1 = ziprxtra(f, &bp->Zdr)) < 0) + goto corrupt; + rd += l1; + f->f_pad = 1; + } else + abort(); + if (fmttype & TYP_CPIO) { + if (f->f_st.st_nlink <= 0 || namlen <= 0 || namlen >= SANELIMIT) + goto corrupt; + if (namlen > f->f_nsiz) { + if (f->f_name) + free(f->f_name); + f->f_name = smalloc(f->f_nsiz = namlen); + } + if (bread(f->f_name, namlen) != namlen) + unexeoa(); + if (f->f_name[namlen-1] != '\0') + goto corrupt; + rd += namlen; + skippad(rd, f->f_pad); + if (fmttype & TYP_NCPIO && + (!formatforced || fmttype & TYP_SCO)) { + /* + * The UnixWare format is a hack, but not a bad + * one. It is backwards compatible as far as + * possible; old implementations can use the -k + * option and will then get only the beginning + * of a large file, but all other files in the + * archive. + */ + if (namlen >= 24 && memcmp(&f->f_name[namlen-23], + "\0size=", 6) == 0) { + fmttype |= TYP_SCO; + f->f_st.st_size = rdhex(&f->f_name[namlen-17], + 16); + } + } + } + if (attempts) { + if (tflag) + fflush(stdout); + msg(0, 0, sysv3 < 0 ? + "Re-synced after skipping %lld bytes.\n" : + "Re-synchronized on magic number/header.\n", + skipped); + } + attempts = 0; + if (f->f_st.st_atime == 0 || (pax_preserve&(PAX_P_ATIME|PAX_P_EVERY)) == + PAX_P_ATIME) + f->f_st.st_atime = f->f_st.st_mtime; + if ((f->f_dsize = f->f_st.st_size) < 0) + goto badhdr; + if (fmttype & TYP_CPIO && strcmp(f->f_name, trailer) == 0) + return 1; + return 0; +corrupt: + if (kflag) { + if (tflag) + fflush(stdout); + msg(3, 0, "Corrupt header, file(s) may be lost.\n"); + } +badhdr: + if (kflag) { + int next = fmttype & TYP_TAR ? 512 : 1; + if (attempts++ == 0) { + if (tflag) + fflush(stdout); + msg(1, 0, sysv3 < 0 ? "Out of phase; resyncing.\n" : + "Searching for magic number/header.\n"); + errcnt++; + } + for (l1 = next; l1 < hsz; l1++) + bp->data[l1-next] = bp->data[l1]; + if (bread(&bp->data[l1-next], next) != next) + unexeoa(); + skipped++; + goto retry; + } + if (tflag) + fflush(stdout); + msg(3, 1, sysv3 < 0 ? "Out of phase--get help\n" : + sysv3 > 0 ? "Out of sync, bad magic number/header.\n" : + "Bad magic number/header.\n"); + /*NOTREACHED*/ + return -1; +} + +/* + * Determine the kind of archive on tape. + */ +static void +whathdr(void) +{ +again: if (blktop >= SIZEOF_hdr_cpio && + ple16(blkbuf) == mag_bin) { + fmttype = FMT_BINLE; + } else if (blktop >= SIZEOF_hdr_cpio && + pbe16(blkbuf) == mag_bin) { + fmttype = FMT_BINBE; + } else if (blktop >= SIZEOF_c_hdr && + memcmp(blkbuf, mag_odc, sizeof mag_odc) == 0) { + /* + * The DEC format is rubbish. Instead of introducing a new + * archive magic, its engineers reused the POSIX/odc magic + * and changed the fields. But there's a workaround: For a + * real odc archive, the byte following the file name is a + * \0 byte (unless the archive is damaged, of course). If + * it is not a \0 byte, but a \0 byte appears at the + * corresponding location for the DEC format, this is + * treated as a DEC archive. It must be noted that the + * Tru64 UNIX 5.1 cpio command is too stupid even for + * doing that - it will spill out a list of complaints + * if an extended archive is read but -e is not given. + */ + int ns1, ns2; + ns1 = rdoct(((struct c_hdr *)blkbuf)->c_namesz, 6); + ns2 = rdoct(((struct d_hdr *)blkbuf)->d_namesz, 6); + if (blktop >= SIZEOF_d_hdr && + (ns1 >= blktop - SIZEOF_c_hdr || + blkbuf[SIZEOF_c_hdr+ns1-1] != '\0') && + ns2 <= blktop - SIZEOF_d_hdr && + blkbuf[SIZEOF_d_hdr+ns2-1] == '\0') + fmttype = FMT_DEC; + else + fmttype = FMT_ODC; + } else if (blktop >= SIZEOF_Exp_cpio_hdr && + memcmp(blkbuf, mag_asc, sizeof mag_asc) == 0) { + fmttype = FMT_ASC; + } else if (blktop >= SIZEOF_Exp_cpio_hdr && + memcmp(blkbuf, mag_crc, sizeof mag_crc) == 0) { + fmttype = FMT_CRC; + } else if (blktop >= SIZEOF_cray_hdr && + pbe64(blkbuf) == mag_bin) { + /* + * Old and new Cray headers are identical in the first + * 64 header bytes (including the magic). cpio(5) on + * UNICOS does not describe what the new param field + * is for. + * + * An archive is treated as old format if the mtime + * and namesize fields make sense and all characters + * of the name are non-null. + */ + struct cray_hdr *Cp = (struct cray_hdr *)blkbuf; + long long mtime, namesize; + fmttype = FMT_CRAY; + mtime = pbe64(Cp->C_mtime - CRAY_PARAMSZ); + namesize = pbe64(Cp->C_namesize - CRAY_PARAMSZ); + if (mtime > 0 && mtime < (1LL<<31) && + namesize > 0 && namesize < 2048 && + blktop > SIZEOF_cray_hdr- + CRAY_PARAMSZ+namesize+1) { + int i; + for (i = 0; i < namesize; i++) + if (blkbuf[SIZEOF_cray_hdr- + CRAY_PARAMSZ+i] == '\0') + break; + if (i == namesize-1) + fmttype = FMT_CRAY5; + } + } else if (blktop >= 512 && + memcmp(&blkbuf[257], mag_ustar, 6) == 0 && + tcssum((union bincpio *)blkbuf, 1) == 0) { + fmttype = FMT_USTAR; + } else if (blktop >= 512 && + memcmp(&blkbuf[257], mag_gnutar, 8) == 0 && + tcssum((union bincpio *)blkbuf, 1) == 0) { + fmttype = FMT_GNUTAR; + } else if (blktop >= 512 && blkbuf[0] && /* require filename + to avoid match on + /dev/zero etc. */ + memcmp(&blkbuf[257], "\0\0\0\0\0", 5) == 0 && + tcssum((union bincpio *)blkbuf, 0) == 0) { + fmttype = FMT_OTAR; + } else if (blktop >= SIZEOF_zip_header && + (memcmp(blkbuf, mag_zipctr, sizeof mag_zipctr) == 0 || + memcmp(blkbuf, mag_zipsig, sizeof mag_zipsig) == 0 || + memcmp(blkbuf, mag_zipend, sizeof mag_zipend) == 0 || + memcmp(blkbuf, mag_zip64e, sizeof mag_zip64e) == 0 || + memcmp(blkbuf, mag_zip64l, sizeof mag_zip64l) == 0)) { + fmttype = FMT_ZIP; + } else if (blktop >= 512 && memcmp(blkbuf,"\0\0\0\0\0\0\0\0",8) == 0 && + memcmp(&blkbuf[65], mag_bar, sizeof mag_bar) == 0 && + bcssum((union bincpio *)blkbuf) == 0) { + fmttype = FMT_BAR; + compressed_bar = blkbuf[71] == '1'; + curpos = 512; + } else if (!Aflag && blktop > 3 && memcmp(blkbuf, "BZh", 3) == 0 && + redirect("bzip2", "-cd") == 0) { + goto zip; + } else if (!Aflag && blktop > 2 && memcmp(blkbuf, "\37\235", 2) == 0 && + redirect("zcat", NULL) == 0) { + goto zip; + } else if (!Aflag && blktop > 2 && memcmp(blkbuf, "\37\213", 2) == 0 && + redirect("gzip", "-cd") == 0) { + goto zip; + } else if (!Aflag && blktop > 4 && + memcmp(blkbuf, "\355\253\356\333", 4) == 0 && + redirect("rpm2cpio", "-") == 0) { + goto zip; + } else { + msg(3, 0, sysv3 ? "This is not a cpio file, bad header.\n" : + "Not a cpio file, bad header.\n"); + done(1); + } + return; +zip: + blktop = curpos = 0; + blocks = 0; + bytes = 0; + mfl = 0; + mstat(); + if (mread() == 0) + unexeoa(); + goto again; +} + +/* + * Processing of a single file with -i. + */ +static int +infile(struct file *f) +{ + int val; + + if ((fmttype & TYP_CPIO || fmttype == FMT_ZIP && f->f_st.st_size) && + (f->f_st.st_mode&S_IFMT) == S_IFLNK) { + if (f->f_lsiz < f->f_st.st_size+1) + f->f_lnam = srealloc(f->f_lnam, + f->f_lsiz = f->f_st.st_size+1); + if (bread(f->f_lnam, f->f_st.st_size) != f->f_st.st_size) + unexeoa(); + f->f_lnam[f->f_st.st_size] = '\0'; + skippad(f->f_st.st_size, f->f_pad); + } + if (tflag) + val = filet(f, indata); + else + val = filein(f, indata, f->f_name); + return val != 0; +} + +/* + * Fetch the data of regular files from tape and write it to tfd or, if + * tfd < 0, discard it. + */ +static int +indata(struct file *f, const char *tgt, int tfd) +{ + char *buf; + size_t bufsize; + struct stat ts; + long long size; + ssize_t rd; + uint32_t ssum = 0, usum = 0; + int val = 0; + int doswap = 0; + + size = fmttype == FMT_ZIP ? f->f_csize : + f->f_Kbase ? f->f_Kbase : f->f_st.st_size; + doswap = ((bflag|sflag) == 0 || + ckodd(size, 2, "bytes", f->f_name) == 0) & + ((bflag|Sflag) == 0 || + ckodd(size, 4, "halfwords", f->f_name) == 0) & + (bflag|sflag|Sflag); + if (fmttype == FMT_ZIP && f->f_cmethod != C_STORED) + return zipread(f, tgt, tfd, doswap); + if (tfd < 0 || fstat(tfd, &ts) < 0) + ts.st_blksize = 4096; + getbuf(&buf, &bufsize, ts.st_blksize); +again: while (size) { + if ((rd = bread(buf, size > bufsize ? bufsize : size)) <= 0) + unexeoa(); + if (doswap) + swap(buf, rd, bflag || sflag, bflag || Sflag); + if (tfd >= 0 && write(tfd, buf, rd) != rd) { + emsg(3, "Cannot write \"%s\"", tgt); + tfd = -1; + val = -1; + } + size -= rd; + if (fmttype & TYP_CRC) + do { + rd--; + ssum += ((signed char *)buf)[rd]; + usum += ((unsigned char *)buf)[rd]; + } while (rd); + } + if (f->f_Kbase) { + skippad(f->f_Ksize, f->f_pad); + readK2hdr(f); + size = f->f_Krest; + goto again; + } + skippad(fmttype==FMT_ZIP ? f->f_csize : + f->f_Ksize ? f->f_Krest : f->f_st.st_size, f->f_pad); + if (fmttype & TYP_CRC) { + if (f->f_chksum != ssum && f->f_chksum != usum) { + msg(3, 0, "\"%s\" - checksum error\n", f->f_name); + if (kflag) + errcnt++; + else + val = -1; + } + } + return val; +} + +/* + * Skip the data for a file on tape. + */ +static int +skipfile(struct file *f) +{ + char b[4096]; + long long size; + ssize_t rd; + + if (fmttype & TYP_TAR && ((f->f_st.st_mode&S_IFMT) == S_IFLNK || + f->f_st.st_nlink > 1)) { + if (fmttype & TYP_USTAR && (!formatforced || + fmttype == FMT_PAX) && + f->f_st.st_nlink > 1 && + f->f_st.st_size > 0) + /*EMPTY*/; + else + return 0; + } + /* + * SVR4 cpio derivatives always ignore the size of these, + * even if not reading tar formats. We do the same for now, + * although POSIX (for -H odc format) says the contrary. + */ + if (fmttype != FMT_ZIP && ((f->f_st.st_mode&S_IFMT) == S_IFDIR || + (f->f_st.st_mode&S_IFMT) == S_IFCHR || + (f->f_st.st_mode&S_IFMT) == S_IFBLK || + (f->f_st.st_mode&S_IFMT) == S_IFIFO || + (f->f_st.st_mode&S_IFMT) == S_IFNAM || + (f->f_st.st_mode&S_IFMT) == S_IFNWK)) + return 0; + if (fmttype == FMT_ZIP && f->f_gflag & FG_DESC) + return zipread(f, f->f_name, -1, 0); + size = fmttype == FMT_ZIP ? f->f_csize : + f->f_Kbase ? f->f_Kbase : f->f_st.st_size; +again: while (size) { + if ((rd = bread(b, size > sizeof b ? sizeof b : size)) <= 0) + unexeoa(); + size -= rd; + } + if (f->f_Kbase) { + skippad(f->f_Ksize, f->f_pad); + readK2hdr(f); + size = f->f_Krest; + goto again; + } + skippad(fmttype==FMT_ZIP ? f->f_csize : + f->f_Ksize ? f->f_Krest : f->f_st.st_size, f->f_pad); + return 0; +} + +/* + * Skip data also, but perform checks as if copying. + */ +static int +skipdata(struct file *f, int (*copydata)(struct file *, const char *, int)) +{ + switch (f->f_st.st_mode&S_IFMT) { + case S_IFLNK: + break; + case S_IFDIR: + case S_IFBLK: + case S_IFCHR: + case S_IFIFO: + case S_IFNAM: + case S_IFNWK: + if (fmttype != FMT_ZIP) + break; + /*FALLTHRU*/ + case S_IFREG: + default: + if (fmttype & TYP_TAR && f->f_st.st_nlink > 1 && + ((fmttype & TYP_USTAR) == 0 || + formatforced && fmttype != FMT_PAX)) + break; + if (copydata(f, f->f_name, -1) != 0) + return 1; + } + return 0; +} + +/* + * Seek to a position in the archive measured from the begin of + * operation. Handle media-dependent seeks. n must be a multiple + * of the tape device's physical block size. + */ +static int +tseek(off_t n) +{ + int fault; + + if (tapeblock > 0) { + int i = (n - poffs) / tapeblock; +#if defined (__linux__) || defined (__sun) || defined (__FreeBSD__) || \ + defined (__hpux) || defined (_AIX) || defined (__NetBSD__) || \ + defined (__OpenBSD__) || defined (__DragonFly__) || \ + defined (__CYGWIN__) + struct mtop mo; + mo.mt_op = i > 0 ? MTFSR : MTBSR; + mo.mt_count = i > 0 ? i : -i; + fault = ioctl(mt, MTIOCTOP, &mo); +#endif + } else + fault = lseek(mt, n - poffs, SEEK_CUR) == (off_t)-1 ? -1 : 0; + if (fault == 0) + poffs = n; + return fault; +} + +/* + * Advance to the trailer on the tape (for -A). + */ +static int +totrailer(void) +{ + union bincpio bc; + struct file f; + off_t ooffs, noffs, diff; + int i; + + if (mread() == 0) + unexeoa(); + if (fmttype == FMT_NONE) + whathdr(); + memset(&f, 0, sizeof f); + for (;;) { + ooffs = aoffs; + if ((i = readhdr(&f, &bc)) < 0) + goto fail; + if (i > 0) + break; + markdev(f.f_st.st_dev); + if (skipfile(&f) != 0) + goto fail; + if (fmttype == FMT_ZIP) + zipdefer(f.f_name, &f.f_st, ooffs, + f.f_chksum, f.f_csize, &bc.Zdr); + pax_track(f.f_name, f.f_st.st_mtime); + } + /* + * Now seek to the position of the trailer, but retain the + * block alignment. + */ + diff = ooffs % blksiz; + noffs = ooffs - diff; + if (diff ? tseek(noffs) == 0 && mread() >= diff && tseek(noffs) == 0 + : tseek(ooffs) == 0) { + free(f.f_name); + free(f.f_lnam); + nwritten = ooffs; + curpos = diff; + return 0; + } +fail: msg(4, 1, "Unable to append to this archive\n"); + /*NOTREACHED*/ + return 1; +} + +static long long +rdoct(const char *data, int len) +{ + int i; + long long val = 0; + + for (i = 0; i < len && data[i] == ' '; i++); + for ( ; i < len && data[i] && data[i] != ' '; i++) { + val <<= 3; + val += data[i] - '0'; + } + return val; +} + +static long long +rdhex(const char *data, int len) +{ + int i; + long long val = 0; + + for (i = 0; i < len && data[i] == ' '; i++); + for ( ; i < len && data[i] && data[i] != ' '; i++) { + val <<= 4; + val += data[i] > '9' ? data[i] > 'F' ? data[i] - 'a' + 10 : + data[i] - 'A' + 10 : data[i] - '0'; + } + return val; +} + +void +unexeoa(void) +{ + if (sysv3) { + fprintf(stderr, + "Can't read input: end of file encountered " + "prior to expected end of archive.\n"); + done(1); + } + else + msg(3, 1, "Unexpected end-of-archive encountered.\n"); +} + +static char *peekdata; +static size_t peekbot, peektop, peeksize; + +void +bunread(const char *data, size_t sz) +{ + peekdata = srealloc(peekdata, peeksize += sz); + memcpy(&peekdata[peekbot], data, sz); + peektop += sz; + aoffs -= sz; +} + +/* + * Buffered read of data from tape. sz is the amount of data required + * by the archive format; if it cannot be retrieved, processing fails. + */ +ssize_t +bread(char *data, size_t sz) +{ + ssize_t rd = 0; + + if (peekdata) { + rd = sz>peektop-peekbot ? peektop-peekbot : sz; + memcpy(&data[0], &peekdata[peekbot], rd); + sz -= rd; + peekbot += rd; + if (peekbot == peektop) { + free(peekdata); + peekdata = 0; + peeksize = 0; + peekbot = peektop = 0; + } + } + while (sz) { + if (blktop - curpos >= sz) { + memcpy(&data[rd], &blkbuf[curpos], sz); + curpos += sz; + rd += sz; + aoffs += rd; + return rd; + } + if (blktop > curpos) { + memcpy(&data[rd], &blkbuf[curpos], blktop - curpos); + rd += blktop - curpos; + sz -= blktop - curpos; + curpos = blktop; + } + if (mfl < 0) { + if (mfl == -1) { + emsg(3, "I/O error on \"%s\"", + Iflag ? Iflag : "input"); + if (kflag == 0) + break; + if (tapeblock < 0 && ( + (mtst.st_mode&S_IFMT)==S_IFBLK|| + (mtst.st_mode&S_IFMT)==S_IFCHR|| + (mtst.st_mode&S_IFMT)==S_IFREG + ) && lseek(mt, blksiz, SEEK_CUR) + == (off_t)-1) { + emsg(3, "Cannot lseek()"); + done(1); + } + } + if (kflag == 0 || mfl == -2) { + if ((mtst.st_mode&S_IFMT)!=S_IFCHR && + (mtst.st_mode&S_IFMT)!=S_IFBLK) + break; + newmedia(mfl == -1 ? errno : 0); + if (mfl == -1) { + mfl = -2; + break; + } + if (fmttype & TYP_BAR) + curpos = 512; + } + } + mread(); + } + aoffs += rd; + return rd; +} + +/* + * Read a block of data from tape. + */ +static ssize_t +mread(void) +{ + ssize_t ro, rt = 0; + + do { + if ((ro = read(mt, blkbuf + rt, blksiz - rt)) <= 0) { + if (ro < 0) { + if (errno == EINTR) + continue; + mfl = -1; + } else + mfl = -2; + if (rt > 0) { + rt += ro; + break; + } + curpos = blktop = 0; + return ro; + } + rt += ro; + poffs += ro; + if (tapeblock == 0) { + tapeblock = ro; + if (!Bflag && !Cflag) + blksiz = ro; + } + } while (rt < blksiz); + curpos = 0; + blocks += rt >> 9; + bytes += rt & 0777; + blktop = rt; + return rt; +} + +/* + * Look what kind of tape or other archive media we are working on and + * set the buffer size appropriately (if not specified by the user). + */ +static void +mstat(void) +{ + if (fstat(mt, &mtst) < 0) { + emsg(3, "Error during stat() of archive"); + done(1); + } +#if defined (__linux__) + if ((mtst.st_mode&S_IFMT) == S_IFCHR) { + struct mtget mg; + if (ioctl(mt, MTIOCGET, &mg) == 0) + tapeblock = (mg.mt_dsreg&MT_ST_BLKSIZE_MASK) >> + MT_ST_BLKSIZE_SHIFT; + } else if ((mtst.st_mode&S_IFMT) == S_IFBLK) { + /* + * If using a block device, write blocks of the floppy + * disk sector with direct i/o. This enables signals + * after each block is written instead of being ~40 + * seconds in uninterruptible sleep when calling close() + * later. For block devices other than floppies, use the + * kernel defined i/o block size. For floppies, use direct + * i/o even when reading since it is faster. + */ + struct floppy_struct fs; + int floppy = -1; + int blkbsz; + + if (blksiz == 0) { + if ((floppy = ioctl(mt, FDGETPRM, &fs)) == 0) + blksiz = fs.sect * FD_SECTSIZE(&fs); +#ifdef BLKBSZGET + else if (ioctl(mt, BLKBSZGET, &blkbsz) == 0) + blksiz = blkbsz; +#endif /* BLKBSZGET */ + } +#ifdef O_DIRECT + if ((action == 'o' || floppy == 0) && blksiz != 0) { + int flags; + if ((flags = fcntl(mt, F_GETFL)) != -1) + fcntl(mt, F_SETFL, flags | O_DIRECT); + } + } +#endif /* O_DIRECT */ +#elif defined (__sun) + if ((mtst.st_mode&S_IFMT) == S_IFCHR) { + struct mtdrivetype_request mr; + static struct mtdrivetype md; + mr.size = sizeof md; + mr.mtdtp = &md; + if (ioctl(mt, MTIOCGETDRIVETYPE, &mr) == 0) + tapeblock = md.bsize; + } +#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) \ + || defined (__DragonFly__) + if ((mtst.st_mode&S_IFMT) == S_IFCHR) { + struct mtget mg; + if (ioctl(mt, MTIOCGET, &mg) == 0) + tapeblock = mg.mt_blksiz; + } +#elif defined (__CYGWIN__) + if ((mtst.st_mode&S_IFMT) == S_IFCHR) { + struct mtget mg; + if (ioctl(mt, MTIOCGET, &mg) == 0) + tapeblock = (mg.mt_dsreg&MT_ST_BLKSIZE_MASK) >> + MT_ST_BLKSIZE_SHIFT; + } +#elif defined (__hpux) || defined (_AIX) +#endif /* SVR4.2MP */ + if (blksiz == 0) + switch (mtst.st_mode&S_IFMT) { + case S_IFREG: + case S_IFBLK: + blksiz = 4096; + break; + case S_IFCHR: + if (action == 'o' && !Aflag) { + if (pax != PAX_TYPE_CPIO) { + if (fmttype & TYP_PAX) + blksiz = 5120; + else if (fmttype & TYP_TAR) + blksiz = 10240; + else if (fmttype & TYP_CPIO) + blksiz = 5120; + else + blksiz = 512; + } else + blksiz = tapeblock>0 ? tapeblock : 512; + } else + blksiz = tapeblock > 0 && tapeblock % 1024 ? + tapeblock : tapeblock > 10240 ? + tapeblock : 10240; + break; + default: + blksiz = 512; + } +} + +/* + * Skip tape data such that size becomes aligned to pad. + */ +static int +skippad(unsigned long long size, int pad) +{ + char b[512]; + int to; + + if ((to = size % pad) != 0) { + if (bread(b, pad - to) != pad - to) + unexeoa(); + } + return 0; +} + +static int +allzero(const char *bp, int n) +{ + int i; + + for (i = 0; i < n; i++) + if (bp[i] != '\0') + return 0; + return 1; +} + +#define CACHESIZE 16 + +static const char * +getuser(uid_t uid) +{ + static struct { + char *name; + uid_t uid; + } cache[CACHESIZE]; + static int last; + int i; + struct passwd *pwd; + const char *name; + + for (i = 0; i < CACHESIZE && cache[i].name; i++) + if (cache[i].uid == uid) + goto found; + if ((pwd = getpwuid(uid)) != NULL) + name = pwd->pw_name; + else + name = ""; + if (i >= CACHESIZE) { + if (last >= CACHESIZE) + last = 0; + i = last++; + } + if (cache[i].name) + free(cache[i].name); + cache[i].name = sstrdup(name); + cache[i].uid = uid; +found: return cache[i].name[0] ? cache[i].name : NULL; +} + +static const char * +getgroup(gid_t gid) +{ + static struct { + char *name; + gid_t gid; + } cache[CACHESIZE]; + static int last; + int i; + struct group *grp; + const char *name; + + for (i = 0; i < CACHESIZE && cache[i].name; i++) + if (cache[i].gid == gid) + goto found; + if ((grp = getgrgid(gid)) != NULL) + name = grp->gr_name; + else + name = ""; + if (i >= CACHESIZE) { + if (last >= CACHESIZE) + last = 0; + i = last++; + } + if (cache[i].name) + free(cache[i].name); + cache[i].name = sstrdup(name); + cache[i].gid = gid; +found: return cache[i].name[0] ? cache[i].name : NULL; +} + +/* + * Return a version of the passed string that contains at most one '%d' + * and no other printf formats. + */ +char * +oneintfmt(const char *op) +{ + char *new, *np; + int no = 0; + + np = new = smalloc(2 * strlen(op) + 1); + do { + if (*op == '%') { + *np++ = *op++; + if (*op != '%') + if (*op != 'd' || no++) + *np++ = '%'; + } + *np++ = *op; + } while (*op++); + return new; +} + +char * +sstrdup(const char *op) +{ + char *np; + + np = smalloc(strlen(op) + 1); + strcpy(np, op); + return np; +} + +/* + * Add this pattern to the extraction list with -i. + */ +void +addg(const char *pattern, int art) +{ + struct glist *gp; + + gp = scalloc(1, sizeof *gp); + if (pax == PAX_TYPE_CPIO && pattern[0] == '!') { + gp->g_not = 1; + pattern++; + } + gp->g_pat = sstrdup(pattern); + gp->g_art = art; + if (pax != PAX_TYPE_CPIO) { + struct glist *gb = NULL, *gc; + for (gc = patterns; gc; gc = gc->g_nxt) + gb = gc; + if (gb) + gb->g_nxt = gp; + else + patterns = gp; + } else { + gp->g_nxt = patterns; + patterns = gp; + } +} + +/* + * Check if the file name s matches any of the given patterns. + */ +static struct glist * +want(struct file *f, struct glist **gb) +{ + extern int gmatch(const char *, const char *); + struct glist *gp; + + for (gp = patterns; gp; gp = gp->g_nxt) { + if ((gmatch(f->f_name, gp->g_pat) != 0) ^ gp->g_not && + (pax_nflag == 0 || gp->g_gotcha == 0)) { + return gp; + } + *gb = gp; + } + return NULL; +} + +static void +patfile(void) +{ + struct iblok *ip; + char *name = NULL; + size_t namsiz = 0, namlen; + + if ((ip = ib_open(Eflag, 0)) == NULL) + msg(3, -2, "Cannot open \"%s\" to read patterns\n", Eflag); + while ((namlen = ib_getlin(ip, &name, &namsiz, srealloc)) != 0) { + if (name[namlen-1] == '\n') + name[--namlen] = '\0'; + addg(name, 0); + } + ib_close(ip); +} + +void +swap(char *b, size_t sz, int s8, int s16) +{ + uint8_t u8; + uint16_t u16; + union types2 *t2; + union types4 *t4; + int i; + + if (s8) { + for (i = 0; i < (sz >> 1); i++) { + t2 = &((union types2 *)b)[i]; + u8 = t2->byte[0]; + t2->byte[0] = t2->byte[1]; + t2->byte[1] = u8; + } + } + if (s16) { + for (i = 0; i < (sz >> 2); i++) { + t4 = &((union types4 *)b)[i]; + u16 = t4->sword[0]; + t4->sword[0] = t4->sword[1]; + t4->sword[1] = u16; + } + } +} + +static int +ckodd(long long size, int mod, const char *str, const char *fn) +{ + if (size % mod) { + msg(3, 0, "Cannot swap %s of \"%s\", odd number of %s\n", + str, fn, str); + errcnt++; + return 1; + } + return 0; +} + +/* + * Interactive rename (-r option). + */ +static int +rname(char **oldp, size_t *olds) +{ + char *new = NULL; + size_t newsize = 0; + int i, r; + char c; + + fprintf(stderr, "Rename \"%s\"? ", *oldp); + if (tty == 0) + if ((tty = open("/dev/tty", O_RDWR)) < 0 || + fcntl(tty, F_SETFD, FD_CLOEXEC) < 0) + err: msg(3, 1, "Cannot read tty.\n"); + i = 0; + while ((r = read(tty, &c, 1)) == 1 && c != '\n') { + if (i+1 >= newsize) + new = srealloc(new, newsize += 32); + new[i++] = c; + } + if (r <= 0) + goto err; + if (new == NULL) + return 0; + new[i] = '\0'; + if (new[0] == '.' && new[1] == '\0') { + free(new); + } else { + free(*oldp); + *oldp = new; + *olds = newsize; + } + return 1; +} + +/* + * Filter data from tape through the commands given in arg?. + */ +static int +redirect(const char *arg0, const char *arg1) +{ + int pd[2]; + + if (pipe(pd) < 0) + return -1; + switch (fork()) { + case 0: + if (tapeblock>=0 || lseek(mt, -blktop, SEEK_CUR) == (off_t)-1) { + int xpd[2]; + if (pipe(xpd) == 0 && fork() == 0) { + ssize_t rd, wo, wt; + close(xpd[0]); + do { + wo = wt = 0; + do { + if ((wo = write(xpd[1], + blkbuf + wt, + blktop - wt)) + <= 0) { + if (errno == EINTR) + continue; + _exit(0); + } + wt += wo; + } while (wt < blktop); + } while ((rd = mread()) >= 0); + if (rd < 0) { + emsg(3, "Read error on \"%s\"", + Iflag && !sysv3 ? + Iflag : "input"); + } + _exit(0); + } else { + close(xpd[1]); + dup2(xpd[0], 0); + close(xpd[0]); + } + } else { + dup2(mt, 0); + } + close(mt); + dup2(pd[1], 1); + close(pd[0]); + close(pd[1]); + execlp(arg0, arg0, arg1, NULL); + fprintf(stderr, "%s: could not exec %s: %s\n", + progname, arg0, strerror(errno)); + _exit(0177); + /*NOTREACHED*/ + default: + dup2(pd[0], mt); + close(pd[0]); + close(pd[1]); + tapeblock = -1; + break; + case -1: + return -1; + } + return 0; +} + +/* + * Get the name stored in a tar header. buf is expected to be at least + * TPFXSIZ+TNAMSIZ+2 bytes. + */ +static char * +tnameof(struct tar_header *hp, char *buf) +{ + const char *cp; + char *bp = buf; + + if (fmttype & TYP_USTAR && fmttype != FMT_GNUTAR && + hp->t_prefix[0] != '\0') { + cp = hp->t_prefix; + while (cp < &hp->t_prefix[TPFXSIZ] && *cp) + *bp++ = *cp++; + if (bp > buf) + *bp++ = '/'; + } + cp = hp->t_name; + while (cp < &hp->t_name[TNAMSIZ] && *cp) + *bp++ = *cp++; + *bp = '\0'; + return buf; +} + +/* + * Store fn as file name in a tar header. + */ +static int +tmkname(struct tar_header *hp, const char *fn) +{ + const char *cp, *cs = NULL; + + for (cp = fn; *cp; cp++) { + if (fmttype & TYP_USTAR && *cp == '/' && cp[1] != '\0' && + cp > fn && cp-fn <= TPFXSIZ) + cs = cp; + } + if (fmttype == FMT_GNUTAR && cp - fn > 99) { + writegnuname(fn, cp - fn + 1, 'L'); + cp = &fn[99]; + } else if (cp - (cs ? &cs[1] : fn) > TNAMSIZ) { + if (fmttype & TYP_PAX && utf8(fn)) { + paxrec |= PR_PATH; + strcpy(hp->t_name, sequence()); + return 0; + } + msg(3, 0, "%s: file name too long\n", fn); + return -1; + } + if (cs && cp - fn > TNAMSIZ) { + memcpy(hp->t_prefix, fn, cs - fn); + if (cs - fn < TPFXSIZ) + hp->t_prefix[cs - fn] = '\0'; + memcpy(hp->t_name, &cs[1], cp - &cs[1]); + if (cp - &cs[1] < TNAMSIZ) + hp->t_name[cp - &cs[1]] = '\0'; + } else { + memcpy(hp->t_name, fn, cp - fn); + if (cp - fn < TNAMSIZ) + hp->t_name[cp - fn] = '\0'; + } + return 0; +} + +/* + * Get the link name of a tar header. + */ +static void +tlinkof(struct tar_header *hp, struct file *f) +{ + const char *cp; + char *bp; + + + if (f->f_lsiz < TNAMSIZ+1) + f->f_lnam = srealloc(f->f_lnam, f->f_lsiz = TNAMSIZ+1); + cp = hp->t_linkname; + bp = f->f_lnam; + while (cp < &hp->t_linkname[TNAMSIZ] && *cp) + *bp++ = *cp++; + *bp = '\0'; +} + +/* + * Create the link name in a tar header. + */ +static int +tmklink(struct tar_header *hp, const char *fn) +{ + const char *cp; + + for (cp = fn; *cp; cp++); + if (fmttype == FMT_GNUTAR && cp - fn > 99) { + writegnuname(fn, cp - fn + 1, 'K'); + cp = &fn[99]; + } else if (cp - fn > TNAMSIZ) { + if (fmttype & TYP_PAX && utf8(fn)) { + paxrec |= PR_LINKPATH; + strcpy(hp->t_linkname, sequence()); + return 0; + } + msg(3, 0, "%s: linked name too long\n", fn); + return -1; + } + memcpy(hp->t_linkname, fn, cp - fn); + if (cp - fn < TNAMSIZ) + hp->t_linkname[cp - fn] = '\0'; + return 0; +} + +static int +tlflag(struct stat *st) +{ + if (fmttype & TYP_BAR) { + switch (st->st_mode & S_IFMT) { + case S_IFREG: + case S_IFDIR: + return '0'; + case S_IFLNK: + return '2'; + default: + return '3'; + } + } else if (fmttype & TYP_USTAR) { + switch (st->st_mode & S_IFMT) { + case S_IFREG: + return '0'; + case S_IFLNK: + return '2'; + case S_IFCHR: + return '3'; + case S_IFBLK: + return '4'; + case S_IFDIR: + return '5'; + case S_IFIFO: + return '6'; + default: + return -1; + } + } else { + switch (st->st_mode & S_IFMT) { + case S_IFREG: + return '\0'; + case S_IFLNK: + return '2'; + default: + return -1; + } + } +} + +/* + * Ustar checksums are created using unsigned chars, as specified by + * POSIX. Traditional tar implementations use signed chars. Some + * implementations (notably SVR4 cpio derivatives) use signed chars + * even for ustar archives, but this is clearly an implementation bug. + */ +static void +tchksum(union bincpio *bp) +{ + uint32_t sum; + char *cp; + + memset(bp->Tdr.t_chksum, ' ', sizeof bp->Tdr.t_chksum); + sum = 0; + if (fmttype & TYP_USTAR) + for (cp = bp->data; cp < &bp->data[512]; cp++) + sum += *((unsigned char *)cp); + else + for (cp = bp->data; cp < &bp->data[512]; cp++) + sum += *((signed char *)cp); + sprintf(bp->Tdr.t_chksum, "%7.7o", sum); +} + +static int +tcssum(union bincpio *bp, int ustar) +{ + uint32_t ssum = 0, usum = 0, osum; + char ochk[sizeof bp->Tdr.t_chksum]; + char *cp; + + osum = rdoct(bp->Tdr.t_chksum, 8); + memcpy(ochk, bp->Tdr.t_chksum, sizeof ochk); + memset(bp->Tdr.t_chksum, ' ', sizeof bp->Tdr.t_chksum); + for (cp = bp->data; cp < &bp->data[512]; cp++) { + ssum += *((signed char *)cp); + usum += *((unsigned char *)cp); + } + memcpy(bp->Tdr.t_chksum, ochk, sizeof bp->Tdr.t_chksum); + return ssum != osum && usum != osum; +} + +static int +trdsum(union bincpio *bp) +{ + int i; + + if (fmttype & TYP_BAR) + i = bcssum(bp); + else + i = tcssum(bp, fmttype & TYP_USTAR); + if (i) + msg(3, 0, "Bad header - checksum error.\n"); + return i; +} + +static mode_t +tifmt(int c) +{ + switch (c) { + default: + case '\0': + case '0': + return S_IFREG; + case '2': + return S_IFLNK; + case '3': + return S_IFCHR; + case '4': + return S_IFBLK; + case '5': + return S_IFDIR; + case '6': + return S_IFIFO; + } +} + +/* + * bar format support functions. + */ +static void +bchksum(union bincpio *bp) +{ + uint32_t sum; + char *cp; + + memset(bp->Bdr.b_chksum, ' ', sizeof bp->Bdr.b_chksum); + sum = 0; + for (cp = bp->data; cp < &bp->data[512]; cp++) + sum += *((signed char *)cp); + sprintf(bp->Bdr.b_chksum, "%7.7o", sum); +} + +static int +bcssum(union bincpio *bp) +{ + uint32_t sum, osum; + char ochk[sizeof bp->Bdr.b_chksum]; + char *cp; + + osum = rdoct(bp->Bdr.b_chksum, 8); + memcpy(ochk, bp->Bdr.b_chksum, sizeof ochk); + memset(bp->Bdr.b_chksum, ' ', sizeof bp->Bdr.b_chksum); + sum = 0; + for (cp = bp->data; cp < &bp->data[512]; cp++) + sum += *((signed char *)cp); + memcpy(bp->Bdr.b_chksum, ochk, sizeof bp->Bdr.b_chksum); + return sum != osum; +} + +static void +blinkof(const char *cp, struct file *f, int namlen) +{ + if (f->f_lsiz < 512) + f->f_lnam = srealloc(f->f_lnam, f->f_lsiz = 512); + strcpy(f->f_lnam, &cp[SIZEOF_bar_header + namlen]); +} + +static void +dump_barhdr(void) +{ + union bincpio bc; + static int volno; + static time_t now = -1; + + memset(&bc, 0, 512); + sprintf(bc.Bdr.b_uid, "%d", myuid & 07777777); + sprintf(bc.Bdr.b_gid, "%d", mygid & 07777777); + bc.Bdr.b_size[0] = '0'; + memcpy(bc.Bdr.b_bar_magic, mag_bar, sizeof bc.Bdr.b_bar_magic); + sprintf(bc.Bdr.b_volume_num, "%d", ++volno & 0777); + bc.Bdr.b_compressed = '0'; + if (now == (time_t)-1) + time(&now); + sprintf(bc.Bdr.b_date, "%llo", now & 077777777777LL); + bchksum(&bc); + bwrite(bc.data, 512); +} + +/* + * Support for compressed bar format (any regular file is piped through zcat). + */ +static pid_t zpid; + +static int +zcreat(const char *name, mode_t mode) +{ + int pd[2]; + int fd; + + if (pipe(pd) < 0) + return -1; + if ((fd = creat(name, mode)) < 0) { + fd = errno; + close(pd[0]); + close(pd[1]); + errno = fd; + return -1; + } + switch (zpid = fork()) { + case -1: + return -1; + case 0: + dup2(pd[0], 0); + dup2(fd, 1); + close(pd[0]); + close(pd[1]); + close(fd); + execlp("zcat", "zcat", NULL); + _exit(0177); + /*NOTREACHED*/ + } + close(pd[0]); + close(fd); + sigset(SIGPIPE, SIG_IGN); + return pd[1]; +} + +static int +zclose(int fd) +{ + int c, s; + + c = close(fd); + while (waitpid(zpid, &s, 0) != zpid); + return c != 0 || s != 0 ? -1 : 0; +} + +/* + * If using the -A option, device numbers that appear in the archive + * are not reused for appended files. This avoids wrong hardlink + * connections on extraction. + * + * In fact, this should be done even if we did not fake device and + * inode numbers, since it is not guaranteed that the archive was + * created on the same machine, or even on the same machine, inode + * number could have changed after a file was unlinked. + */ +static void +markdev(dev_t dev) +{ + struct dslot *dp, *dq = NULL;; + + for (dp = markeddevs; dp; dp = dp->d_nxt) { + if (dp->d_dev == dev) + return; + dq = dp; + } + dp = scalloc(1, sizeof *dp); + dp->d_dev = dev; + if (markeddevs == NULL) + markeddevs = dp; + else + dq->d_nxt = dp; +} + +static int +marked(dev_t dev) +{ + struct dslot *dp; + + for (dp = markeddevs; dp; dp = dp->d_nxt) + if (dp->d_dev == dev) + return 1; + return 0; +} + +static void +cantsup(int err, const char *file) +{ + if (sysv3) + msg(err ? 3 : 2, 0, + "format can't support expanded types on %s\n", + file); + else + msg(0, 0, "%s format can't support expanded types on %s\n", + err ? "Error" : "Warning", file); + errcnt++; +} + +static void +onint(int signo) +{ + if (cur_ofile && cur_tfile && rename(cur_tfile, cur_ofile) < 0) + emsg(3, "Cannot recover original \"%s\"", cur_ofile); + if (cur_ofile && cur_tfile == NULL && unlink(cur_ofile) < 0) + emsg(3, "Cannot remove incomplete \"%s\"", cur_ofile); + exit(signo | 0200); +} + +/* + * Read the compressed zip data part for a file. + */ +static int +zipread(struct file *f, const char *tgt, int tfd, int doswap) +{ + int val = 0; + uint32_t crc = 0; + + if (f->f_gflag & FG_DESC) { + if (f->f_cmethod != C_DEFLATED && f->f_cmethod != C_ENHDEFLD || + f->f_gflag & FG_CRYPT) + msg(4, 1, "Cannot handle zip data descriptor\n"); + f->f_csize = 0x7FFFFFFFFFFFFFFFLL; + f->f_st.st_size = 0x7FFFFFFFFFFFFFFFLL; + } else if (tfd < 0) + return skipfile(f); + if (f->f_gflag & FG_CRYPT) + return cantunzip(f, "encrypted"); + switch (f->f_cmethod) { + case C_DEFLATED: + case C_ENHDEFLD: + val = zipinflate(f, tgt, tfd, doswap, &crc); + break; + case C_SHRUNK: + val = zipunshrink(f, tgt, tfd, doswap, &crc); + break; + case C_IMPLODED: + val = zipexplode(f, tgt, tfd, doswap, &crc); + break; + case C_REDUCED1: + case C_REDUCED2: + case C_REDUCED3: + case C_REDUCED4: + val = zipexpand(f, tgt, tfd, doswap, &crc); + break; + case C_TOKENIZED: + return cantunzip(f, "tokenized"); + case C_DCLIMPLODED: + val = zipblast(f, tgt, tfd, doswap, &crc); + break; + case C_BZIP2: +#if USE_BZLIB + val = zipunbz2(f, tgt, tfd, doswap, &crc); + break; +#else /* !USE_BZLIB */ + return cantunzip(f, "bzip2 compressed"); +#endif /* !USE_BZLIB */ + default: + return cantunzip(f, "compressed"); + } + if (f->f_gflag & FG_DESC) + zipreaddesc(f); + if (val == 0 && crc != f->f_chksum) { + msg(3, 0, "\"%s\" - checksum error\n", f->f_name); + return -1; + } + return val; +} + +/* + * Read a zip data descriptor (i. e. a field after the compressed data + * that contains the actual values for sizes and crc). + */ +static void +zipreaddesc(struct file *f) +{ + if (f->f_oflag & OF_ZIP64) { + struct zipddesc64 zd64; + bread((char *)&zd64, SIZEOF_zipddesc64); + if (memcmp(zd64.zd_signature, mag_zipdds, sizeof mag_zipdds)) + msg(4, 1, "Invalid zip data descriptor\n"); + f->f_chksum = ple32(zd64.zd_crc32); + f->f_dsize = f->f_st.st_size = ple64(zd64.zd_nsize) & + 0xFFFFFFFFFFFFFFFFULL; + f->f_csize = ple64(zd64.zd_csize) & + 0xFFFFFFFFFFFFFFFFULL; + } else { + struct zipddesc zd; + bread((char *)&zd, SIZEOF_zipddesc); + if (memcmp(zd.zd_signature, mag_zipdds, sizeof mag_zipdds)) + msg(4, 1, "Invalid zip data descriptor\n"); + f->f_chksum = ple32(zd.zd_crc32); + f->f_dsize = f->f_st.st_size = ple32(zd.zd_nsize)&0xFFFFFFFFUL; + f->f_csize = ple32(zd.zd_csize)&0xFFFFFFFFUL; + } +} + +static int +cantunzip(struct file *f, const char *method) +{ + msg(3, 0, "Cannot unzip %s file \"%s\"\n", method, f->f_name); + errcnt++; + return skipfile(f); +} + +/* + * PC-DOS time format: + * + * 31 24 20 15 10 4 0 + * | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + * | | | | | + * |year |months |days |hours |minutes |biseconds| + * + * refers to local time on the machine it was created on. + */ + +static time_t +gdostime(const char *tp, const char *dp) +{ + uint32_t v; + struct tm tm; + + v = (int)(tp[0]&0377) + + ((int)(tp[1]&0377) << 8) + + ((int)(dp[0]&0377) << 16) + + ((int)(dp[1]&0377) << 24); + memset(&tm, 0, sizeof tm); + tm.tm_sec = (v&0x1F) << 1; + tm.tm_min = (v&0x7E0) >> 5; + tm.tm_hour = (v&0xF800) >> 11; + tm.tm_mday = ((v&0x1F0000) >> 16); + tm.tm_mon = ((v&0x1E00000) >> 21) - 1; + tm.tm_year = ((v&0xFE000000) >> 25) + 80; + tm.tm_isdst = -1; + return mktime(&tm); +} + +static void +mkdostime(time_t t, char *tp, char *dp) +{ + uint32_t v; + struct tm *tm; + + tm = localtime(&t); + v = (tm->tm_sec >> 1) + (tm->tm_sec&1) + (tm->tm_min << 5) + + (tm->tm_hour << 11) + (tm->tm_mday << 16) + + ((tm->tm_mon+1) << 21) + ((tm->tm_year - 80) << 25); + le16p(v&0x0000ffff, tp); + le16p((v&0xffff0000) >> 16, dp); +} + +/* + * Read and interpret the zip extra field for a file. + */ +static ssize_t +ziprxtra(struct file *f, struct zip_header *z) +{ + union zextra *x, *xp; + short tag, size; + ssize_t len; + + len = ple16(z->z_extralen)&0177777; + if (len > 0) { + x = smalloc(len); + if (bread((char *)x, len) != len) + return -1; + if (len < 4) + return len; + xp = x; + while (len > 0) { + if (len < 4) + return -1; + tag = ple16(xp->Ze_gn.ze_gn_tag); + size = (ple16(xp->Ze_gn.ze_gn_tsize)&0177777) + 4; + switch (tag) { + case mag_zip64f: /* ZIP64 extended information */ + if (size != SIZEOF_zextra_64 && + size != SIZEOF_zextra_64_a && + size != SIZEOF_zextra_64_b) + break; + if (f->f_st.st_size == 0xffffffff) + f->f_st.st_size = + ple64(xp->Ze_64.ze_64_nsize); + if (f->f_csize == 0xffffffff) + f->f_csize = + ple64(xp->Ze_64.ze_64_csize); + f->f_oflag |= OF_ZIP64; + break; + case 0x000d: /* PKWARE Unix Extra Field */ + if (size != SIZEOF_zextra_pk) + break; + f->f_st.st_atime = ple32(xp->Ze_pk.ze_pk_atime); + f->f_st.st_mtime = ple32(xp->Ze_pk.ze_pk_mtime); + f->f_st.st_uid = ple16(xp->Ze_pk.ze_pk_uid) & + 0177777; + f->f_st.st_gid = ple16(xp->Ze_pk.ze_pk_gid) & + 0177777; + break; + case 0x5455: /* Extended Timestamp Extra Field */ + if (xp->Ze_et.ze_et_flags[0] & 1) + f->f_st.st_atime = + ple32(xp->Ze_et.ze_et_atime); + if (xp->Ze_et.ze_et_flags[0] & 2) + f->f_st.st_mtime = + ple32(xp->Ze_et.ze_et_mtime); + if (xp->Ze_et.ze_et_flags[0] & 3) + f->f_st.st_ctime = + ple32(xp->Ze_et.ze_et_ctime); + break; + case 0x5855: /* Info-ZIP Unix Extra Field #1 */ + if (size != SIZEOF_zextra_i1) + break; + f->f_st.st_atime = ple32(xp->Ze_i1.ze_i1_atime); + f->f_st.st_mtime = ple32(xp->Ze_i1.ze_i1_mtime); + f->f_st.st_uid = ple16(xp->Ze_i1.ze_i1_uid) & + 0177777; + f->f_st.st_gid = ple16(xp->Ze_i1.ze_i1_gid) & + 0177777; + break; + case 0x7855: /* Info-ZIP Unix Extra Field #2 */ + if (size != SIZEOF_zextra_i2) + break; + f->f_st.st_uid = ple16(xp->Ze_i2.ze_i2_uid) & + 0177777; + f->f_st.st_gid = ple16(xp->Ze_i2.ze_i2_gid) & + 0177777; + break; + case 0x756e: /* ASi Unix Extra Field */ + if (size < SIZEOF_zextra_as) + break; + f->f_st.st_mode = ple16(xp->Ze_as.ze_as_mode); + f->f_st.st_uid = ple16(xp->Ze_as.ze_as_uid) & + 0177777; + f->f_st.st_gid = ple16(xp->Ze_as.ze_as_gid) & + 0177777; + if ((f->f_st.st_mode&S_IFMT) == S_IFLNK) { + if (f->f_lsiz < size-14+1) + f->f_lnam = srealloc(f->f_lnam, + f->f_lsiz = + size-18+1); + memcpy(f->f_lnam, &((char *)xp)[18], + size-18); + f->f_lnam[size-18] = '\0'; + f->f_st.st_size = size-18; + } else { + f->f_st.st_rdev = + ple32(xp->Ze_as.ze_as_sizdev); + f->f_rmajor = major(f->f_st.st_rdev); + f->f_rminor = minor(f->f_st.st_rdev); + } + break; + case mag_zipcpio: + if (size != SIZEOF_zextra_cp) + break; + f->f_st.st_dev = ple32(xp->Ze_cp.ze_cp_dev); + f->f_st.st_ino = ple32(xp->Ze_cp.ze_cp_ino); + f->f_st.st_mode = ple32(xp->Ze_cp.ze_cp_mode); + f->f_st.st_uid = ple32(xp->Ze_cp.ze_cp_uid) & + 0xFFFFFFFFUL; + f->f_st.st_gid = ple32(xp->Ze_cp.ze_cp_gid) & + 0xFFFFFFFFUL; + f->f_st.st_nlink = ple32(xp->Ze_cp.ze_cp_nlink)& + 0xFFFFFFFFUL; + f->f_st.st_rdev = ple32(xp->Ze_cp.ze_cp_rdev); + f->f_rmajor = major(f->f_st.st_rdev); + f->f_rminor = minor(f->f_st.st_rdev); + f->f_st.st_mtime = ple32(xp->Ze_cp.ze_cp_mtime); + f->f_st.st_atime = ple32(xp->Ze_cp.ze_cp_atime); + break; + } + xp = (union zextra *)&((char *)xp)[size]; + len -= size; + } + free(x); + } + return len; +} + +/* + * Write the central directory and the end of a zip file. + */ +static void +ziptrailer(void) +{ + struct zipstuff *zs; + struct zipcentral zc; + struct zipend ze; + long long cpstart, cpend, entries = 0; + size_t sz; + + cpstart = nwritten; + for (zs = zipbulk; zs; zs = zs->zs_next) { + entries++; + memset(&zc, 0, SIZEOF_zipcentral); + memcpy(zc.zc_signature, mag_zipctr, 4); + zc.zc_versionmade[0] = 20; + zc.zc_versionextr[0] = zs->zs_cmethod == 8 ? 20 : 10; + mkdostime(zs->zs_mtime, zc.zc_modtime, zc.zc_moddate); + le32p(zs->zs_crc32, zc.zc_crc32); + le16p(zs->zs_cmethod, zc.zc_cmethod); + le16p(zs->zs_gflag, zc.zc_gflag); + /* + * We flag files as created on PC-DOS / FAT filesystem + * and thus set PC-DOS attributes here. + */ + if ((zs->zs_mode&0222) == 0) + zc.zc_external[0] |= 0x01; /* readonly attribute */ + if ((zs->zs_mode&S_IFMT) == S_IFDIR) + zc.zc_external[0] |= 0x10; /* directory attr. */ + sz = strlen(zs->zs_name); + le16p(sz, zc.zc_namelen); + if (zs->zs_size >= 0xffffffff || zs->zs_csize >= 0xffffffff || + zs->zs_relative >= 0xffffffff) { + struct zextra_64 zf; + + memset(&zf, 0, SIZEOF_zextra_64); + le16p(mag_zip64f, zf.ze_64_tag); + le16p(SIZEOF_zextra_64 - 4, zf.ze_64_tsize); + if ((zs->zs_mode&S_IFMT) == S_IFREG || + (zs->zs_mode&S_IFMT) == S_IFLNK) { + le32p(0xffffffff, zc.zc_csize); + le32p(0xffffffff, zc.zc_nsize); + le64p(zs->zs_csize, zf.ze_64_csize); + le64p(zs->zs_size, zf.ze_64_nsize); + } + le64p(zs->zs_relative, zf.ze_64_reloff); + le32p(0xffffffff, zc.zc_relative); + le16p(SIZEOF_zextra_64, zc.zc_extralen); + bwrite((char *)&zc, SIZEOF_zipcentral); + bwrite(zs->zs_name, sz); + bwrite((char *)&zf, SIZEOF_zextra_64); + } else { + if ((zs->zs_mode&S_IFMT) == S_IFREG || + (zs->zs_mode&S_IFMT) == S_IFLNK) { + le32p(zs->zs_csize, zc.zc_csize); + le32p(zs->zs_size, zc.zc_nsize); + } + le32p(zs->zs_relative, zc.zc_relative); + bwrite((char *)&zc, SIZEOF_zipcentral); + bwrite(zs->zs_name, sz); + } + } + cpend = nwritten; + memset(&ze, 0, SIZEOF_zipend); + memcpy(ze.ze_signature, mag_zipend, 4); + if (cpend >= 0xffffffff || entries >= 0xffff) { + struct zip64end z6; + struct zip64loc z4; + + memset(&z6, 0, SIZEOF_zip64end); + memcpy(z6.z6_signature, mag_zip64e, 4); + le64p(SIZEOF_zip64end - 12, z6.z6_recsize); + z6.z6_versionmade[0] = 20; + z6.z6_versionextr[0] = 20; + le64p(entries, z6.z6_thisentries); + le64p(entries, z6.z6_allentries); + le64p(cpend - cpstart, z6.z6_dirsize); + le64p(cpstart, z6.z6_startsize); + bwrite((char *)&z6, SIZEOF_zip64end); + memset(&z4, 0, SIZEOF_zip64loc); + memcpy(z4.z4_signature, mag_zip64l, 4); + le64p(cpend, z4.z4_reloff); + le32p(1, z4.z4_alldiskn); + bwrite((char *)&z4, SIZEOF_zip64loc); + le16p(0xffff, ze.ze_thisentries); + le16p(0xffff, ze.ze_allentries); + le32p(0xffffffff, ze.ze_dirsize); + le32p(0xffffffff, ze.ze_startsize); + } else { + le16p(entries, ze.ze_thisentries); + le16p(entries, ze.ze_allentries); + le32p(cpend - cpstart, ze.ze_dirsize); + le32p(cpstart, ze.ze_startsize); + } + bwrite((char *)&ze, SIZEOF_zipend); +} + +/* + * Store the data later needed for the central directory. + */ +static void +zipdefer(const char *fn, struct stat *st, long long relative, + uint32_t crc, long long csize, const struct zip_header *zh) +{ + struct zipstuff *zp; + + zp = scalloc(1, sizeof *zp); + zp->zs_name = sstrdup(fn); + zp->zs_size = st->st_size; + zp->zs_mtime = st->st_mtime; + zp->zs_mode = st->st_mode; + zp->zs_relative = relative; + zp->zs_cmethod = ple16(zh->z_cmethod); + zp->zs_gflag = ple16(zh->z_gflag); + zp->zs_csize = csize; + zp->zs_crc32 = crc; + zp->zs_next = zipbulk; + zipbulk = zp; +} + +#define ziptrlevel() ( \ + zipclevel == 01 ? 9 : /* maximum */ \ + zipclevel == 02 ? 3 : /* fast */ \ + zipclevel == 03 ? 1 : /* super fast */\ + /*zipclevel==00*/ 6 /* normal */ \ +) + +/* + * Write (and compress) data for a regular file to a zip archive. + */ +static int +zipwrite(int fd, const char *fn, struct stat *st, union bincpio *bp, size_t sz, + uint32_t dev, uint32_t ino, uint32_t *crc, long long *csize) +{ +#if USE_ZLIB + struct z_stream_s z; + int i; + size_t osize = 0; +#endif /* USE_ZLIB */ + char *ibuf, *obuf = 0; + + if (st->st_size > 196608 || (ibuf = malloc(st->st_size)) == 0) { +#if USE_ZLIB + if (zipclevel < 04) + return zipwdesc(fd, fn, st, bp, sz, dev, ino, + crc, csize); +#endif /* USE_ZLIB */ + return zipwtemp(fd, fn, st, bp, sz, dev, ino, crc, csize); + } + *csize = 0; + if (read(fd, ibuf, st->st_size) != st->st_size) { + free(ibuf); + emsg(3, "Cannot read \"%s\"", fn); + close(fd); + return -1; + } + *crc = zipcrc(0, (unsigned char *)ibuf, st->st_size); +#if USE_BZLIB + if (zipclevel == 07) { + unsigned int sb; + if ((obuf = malloc(sb = st->st_size)) == 0) + goto store; + if (BZ2_bzBuffToBuffCompress(obuf, &sb, ibuf, st->st_size, + 9, 0, 0) != BZ_OK) + goto store; + *csize = sb; + bp->Zdr.z_cmethod[0] = C_BZIP2; + bp->Zdr.z_version[0] = 0x2e; + goto out; + } +#endif /* USE_BZLIB */ + if (zipclevel > 03) + goto store; +#if USE_ZLIB + memset(&z, 0, sizeof z); + if (deflateInit2(&z, ziptrlevel(), Z_DEFLATED, -15, + 8, Z_DEFAULT_STRATEGY) < 0) + goto store; + z.next_in = (unsigned char *)ibuf; + z.avail_in = z.total_in = st->st_size; + do { + if (z.avail_out == 0) { + if ((obuf = realloc(obuf, osize += 4096)) == 0) { + deflateEnd(&z); + goto store; + } + z.next_out = (unsigned char *)&obuf[*csize]; + z.avail_out = osize - *csize; + } + if ((i = deflate(&z, z.avail_in ? Z_NO_FLUSH : Z_FINISH)) < 0) { + deflateEnd(&z); + goto store; + } + *csize = osize - z.avail_out; + } while (z.avail_in || i != Z_STREAM_END); + deflateEnd(&z); + if (*csize < st->st_size) { + bp->Zdr.z_cmethod[0] = C_DEFLATED; + bp->Zdr.z_gflag[0] |= zipclevel << 1; + bp->Zdr.z_version[0] = 20; + } else +#endif /* USE_ZLIB */ + store: *csize = st->st_size; +#if USE_BZLIB +out: +#endif /* USE_BZLIB */ + le32p(*crc, bp->Zdr.z_crc32); + le32p(*csize, bp->Zdr.z_csize); + bwrite((char *)bp, SIZEOF_zip_header); + bwrite(fn, sz); + zipwxtra(fn, st, dev, ino); + switch (bp->Zdr.z_cmethod[0]) { + case C_DEFLATED: + case C_BZIP2: + bwrite(obuf, *csize); + break; + default: + bwrite(ibuf, *csize); + } + free(ibuf); + free(obuf); + close(fd); + return 0; +} + +/* + * Write and compress data to a zip archive for a file that is to large + * too be kept in memory. If there is an error with the temporary file + * (e. g. no space left on device), the file is stored in uncompressed + * form. + */ +static int +zipwtemp(int fd, const char *fn, struct stat *st, union bincpio *bp, size_t sz, + uint32_t dev, uint32_t ino, uint32_t *crc, long long *csize) +{ + static int tf = -1; + static char tlate[] = "/var/tmp/cpioXXXXXX"; + char ibuf[32768]; +#if USE_ZLIB || USE_BZLIB + char obuf[32768]; +#endif /* USE_ZLIB || USE_BZLIB */ + struct zextra_64 zf; + struct zextra_64 *zfp = 0; + long long size = st->st_size; + const char *sname; + int cuse, sf; + ssize_t rd; + + *csize = 0; + *crc = 0; +#if USE_ZLIB || USE_BZLIB + if (tf < 0) { + if ((tf = mkstemp(tlate)) >= 0) + unlink(tlate); + } else if (lseek(tf, 0, SEEK_SET) != 0) { + close(tf); + tf = -1; + } +#endif /* USE_ZLIB || USE_BZLIB */ +#if USE_ZLIB + if (zipclevel < 04) { + struct z_stream_s z; + memset(&z, 0, sizeof z); + if ((cuse = deflateInit2(&z, ziptrlevel(), Z_DEFLATED, + -15, 8, Z_DEFAULT_STRATEGY)) < 0) + goto store; + do { + if (z.avail_in == 0 && size > 0) { + if ((rd = read(fd, ibuf, sizeof ibuf)) <= 0) { + emsg(3, "Cannot read \"%s\"", fn); + close(fd); + ftruncate(tf, 0); + return -1; + } + z.next_in = (unsigned char *)ibuf; + z.avail_in = z.total_in = rd; + size -= rd; + *crc = zipcrc(*crc, (unsigned char *)ibuf, rd); + } + if (z.next_out == NULL || (char *)z.next_out > obuf) { + if (z.next_out && tf >= 0) { + if (write(tf, obuf, + (char *)z.next_out-obuf) != + (char *)z.next_out-obuf) { + close(tf); + tf = -1; + } + *csize += (char *)z.next_out - obuf; + } + z.next_out = (unsigned char *)obuf; + z.avail_out = sizeof obuf; + } + if (cuse >= 0 && cuse != Z_STREAM_END) + cuse = deflate(&z, + z.avail_in?Z_NO_FLUSH:Z_FINISH); + else + z.avail_in = 0; + } while (size>0 || (char *)z.next_out>obuf || + cuse>=0 && cuse!=Z_STREAM_END); + deflateEnd(&z); + goto out; + } +#endif /* USE_ZLIB */ +#if USE_BZLIB + if (zipclevel == 07) { + bz_stream bs; + int ok, on; + memset(&bs, sizeof bs, 0); + if ((ok = BZ2_bzCompressInit(&bs, 9, 0, 0)) != BZ_OK) + goto store; + cuse = 1; + do { + if (bs.avail_in == 0 && size > 0) { + if ((rd = read(fd, ibuf, sizeof ibuf)) <= 0) { + emsg(3, "Cannot read \"%s\"", fn); + close(fd); + ftruncate(tf, 0); + return -1; + } + bs.next_in = ibuf; + bs.avail_in = rd; + size -= rd; + *crc = zipcrc(*crc, (unsigned char *)ibuf, rd); + } + if (bs.next_out == NULL || bs.next_out > obuf) { + if (bs.next_out && tf >= 0) { + on = bs.next_out - obuf; + if (write(tf, obuf, on) != on) { + close(tf); + tf = -1; + } + *csize += on; + } + bs.next_out = obuf; + bs.avail_out = sizeof obuf; + } + if (ok != BZ_STREAM_END) { + switch (ok = BZ2_bzCompress(&bs, + bs.avail_in?BZ_RUN:BZ_FINISH)) { + case BZ_RUN_OK: + case BZ_FINISH_OK: + case BZ_STREAM_END: + break; + default: + msg(3, 1, "Compression error %d " + "on \"%s\"\n", ok, fn); + close(fd); + return -1; + } + } + } while (size > 0 || bs.next_out > obuf || ok != BZ_STREAM_END); + BZ2_bzCompressEnd(&bs); + goto out; + } +#endif /* USE_BZLIB */ +store: cuse = -1; + while (size > 0) { + if ((rd = read(fd, ibuf, sizeof ibuf)) <= 0) { + emsg(3, "Cannot read \"%s\"", fn); + close(fd); + return -1; + } + size -= rd; + *crc = zipcrc(*crc, (unsigned char *)ibuf, rd); + } +out: if (tf >= 0 && cuse >= 0 && *csize < st->st_size) { + if (zipclevel == 07) { + bp->Zdr.z_cmethod[0] = C_BZIP2; + bp->Zdr.z_version[0] = 0x2e; + } else { + bp->Zdr.z_cmethod[0] = C_DEFLATED; + bp->Zdr.z_gflag[0] |= zipclevel << 1; + bp->Zdr.z_version[0] = 20; + } + sf = tf; + sname = tlate; + } else { + *csize = st->st_size; + sf = fd; + sname = fn; + } + if ((lseek(sf, 0, SEEK_SET)) != 0) { + emsg(3, "Cannot rewind \"%s\"", sname); + errcnt++; + close(fd); + ftruncate(tf, 0); + return -1; + } + le32p(*crc, bp->Zdr.z_crc32); + if (st->st_size >= 0xffffffff || *csize >= 0xffffffff) { + int n; + zfp = &zf; + memset(&zf, 0, SIZEOF_zextra_64); + le16p(mag_zip64f, zf.ze_64_tag); + le16p(SIZEOF_zextra_64 - 4, zf.ze_64_tsize); + le64p(st->st_size, zf.ze_64_nsize); + le64p(*csize, zf.ze_64_csize); + le32p(0xffffffff, bp->Zdr.z_csize); + le32p(0xffffffff, bp->Zdr.z_nsize); + n = (ple16(bp->Zdr.z_extralen)&0177777) + SIZEOF_zextra_64; + le16p(n, bp->Zdr.z_extralen); + } else + le32p(*csize, bp->Zdr.z_csize); + bwrite((char *)bp, SIZEOF_zip_header); + bwrite(fn, sz); + if (zfp) + bwrite((char *)zfp, SIZEOF_zextra_64); + zipwxtra(fn, st, dev, ino); + size = *csize; + while (size) { + if ((rd=read(sf, ibuf, size>sizeof ibuf?sizeof ibuf:size)) <= 0) + msg(3, 1, "Cannot read \"%s\"\n", sname); + bwrite(ibuf, rd); + size -= rd; + } + ftruncate(tf, 0); + close(fd); + return 0; +} + +#if USE_ZLIB +/* + * Write a zip archive entry using the data descriptor structure. + */ +static int +zipwdesc(int fd, const char *fn, struct stat *st, union bincpio *bp, size_t sz, + uint32_t dev, uint32_t ino, uint32_t *crc, long long *csize) +{ + struct zextra_64 zf; + struct zextra_64 *zfp = 0; + char ibuf[32768], obuf[32768]; + long long size = st->st_size; + ssize_t rd; + struct z_stream_s z; + int cuse; + + *csize = 0; + *crc = 0; + memset(&z, 0, sizeof z); + if ((cuse = deflateInit2(&z, ziptrlevel(), Z_DEFLATED, + -15, 8, Z_DEFAULT_STRATEGY)) < 0) + return zipwtemp(fd, fn, st, bp, sz, dev, ino, crc, csize); + bp->Zdr.z_cmethod[0] = C_DEFLATED; + bp->Zdr.z_gflag[0] |= zipclevel << 1 | FG_DESC; + bp->Zdr.z_version[0] = 20; + /* + * RFC 1951 states that deflate compression needs 5 bytes additional + * space per 32k block in the worst case. Thus a compressed size + * greater than 4G-1 can be reached if at least 131052 blocks are + * used. + */ + if (st->st_size >= 131052LL*32768) { + int n; + zfp = &zf; + memset(&zf, 0, SIZEOF_zextra_64); + le16p(mag_zip64f, zf.ze_64_tag); + le16p(SIZEOF_zextra_64 - 4, zf.ze_64_tsize); + le32p(0xffffffff, bp->Zdr.z_csize); + le32p(0xffffffff, bp->Zdr.z_nsize); + n = (ple16(bp->Zdr.z_extralen)&0177777) + SIZEOF_zextra_64; + le16p(n, bp->Zdr.z_extralen); + } + bwrite((char *)bp, SIZEOF_zip_header); + bwrite(fn, sz); + if (zfp) + bwrite((char *)zfp, SIZEOF_zextra_64); + zipwxtra(fn, st, dev, ino); + do { + if (z.avail_in == 0 && size > 0) { + if ((rd = read(fd, ibuf, sizeof ibuf)) <= 0) { + emsg(3, "Cannot read \"%s\"", fn); + st->st_size -= size; + size = 0; /* can't simply stop here */ + rd = 0; /* no data */ + } + z.next_in = (unsigned char *)ibuf; + z.avail_in = z.total_in = rd; + size -= rd; + *crc = zipcrc(*crc, (unsigned char *)ibuf, rd); + } + if (z.next_out == NULL || (char *)z.next_out > obuf) { + if (z.next_out) { + bwrite(obuf, (char *)z.next_out - obuf); + *csize += (char *)z.next_out - obuf; + } + z.next_out = (unsigned char *)obuf; + z.avail_out = sizeof obuf; + } + if (cuse >= 0 && cuse != Z_STREAM_END) + cuse = deflate(&z, z.avail_in?Z_NO_FLUSH:Z_FINISH); + else + z.avail_in = 0; + } while (size > 0 || (char *)z.next_out > obuf || + cuse >= 0 && cuse != Z_STREAM_END); + deflateEnd(&z); + if (zfp) { + struct zipddesc64 zd64; + memcpy(zd64.zd_signature, mag_zipdds, sizeof mag_zipdds); + le32p(*crc, zd64.zd_crc32); + le64p(st->st_size, zd64.zd_nsize); + le64p(*csize, zd64.zd_csize); + bwrite((char *)&zd64, SIZEOF_zipddesc64); + } else { + struct zipddesc zd; + memcpy(zd.zd_signature, mag_zipdds, sizeof mag_zipdds); + le32p(*crc, zd.zd_crc32); + le32p(st->st_size, zd.zd_nsize); + le32p(*csize, zd.zd_csize); + bwrite((char *)&zd, SIZEOF_zipddesc); + } + close(fd); + return 0; +} +#endif /* USE_ZLIB */ + +/* + * Write the extra fields for a file to a zip archive (currently + * our own field type). Note that the z_extralen field in the file + * header must correspond to the size of the data written here. + */ +static int +zipwxtra(const char *fn, struct stat *st, uint32_t dev, uint32_t ino) +{ + struct zextra_cp z; + + memset(&z, 0, SIZEOF_zextra_cp); + le16p(mag_zipcpio, z.ze_cp_tag); + le16p(SIZEOF_zextra_cp - 4, z.ze_cp_tsize); + le32p(dev, z.ze_cp_mode); + le32p(ino, z.ze_cp_ino); + le32p(st->st_mode&(S_IFMT|07777), z.ze_cp_mode); + le32p(st->st_uid, z.ze_cp_uid); + le32p(st->st_gid, z.ze_cp_gid); + le32p(st->st_nlink, z.ze_cp_nlink); + le32p(st->st_rdev, z.ze_cp_rdev); + le32p(st->st_mtime, z.ze_cp_mtime); + le32p(st->st_atime, z.ze_cp_atime); + bwrite((char *)&z, SIZEOF_zextra_cp); + return SIZEOF_zextra_cp; +} + +static void +zipinfo(struct file *f) +{ + const char *cp; + char b[5]; + int i; + + printf(" %7llu", f->f_csize); + if (f->f_dsize) { + i = f->f_csize*100 / f->f_dsize; + i += f->f_csize*200 / f->f_dsize & 1; + i = 100 - i; + } else + i = 0; + printf(" %3d%%", i); + switch (f->f_cmethod) { + case C_STORED: + cp = "stor"; + break; + case C_SHRUNK: + cp = "shrk"; + break; + case C_REDUCED1: + cp = "re:1"; + break; + case C_REDUCED2: + cp = "re:2"; + break; + case C_REDUCED3: + cp = "re:3"; + break; + case C_REDUCED4: + cp = "re:4"; + break; + case C_IMPLODED: + b[0] = 'i'; + b[1] = f->f_gflag & FG_BIT1 ? '8' : '4'; + b[2] = ':'; + b[3] = f->f_gflag & FG_BIT2 ? '3' : '2'; + b[4] = '\0'; + cp = b; + break; + case C_TOKENIZED: + cp = "tokn"; + break; + case C_DEFLATED: + b[0] = 'd', b[1] = 'e', b[2] = 'f', b[4] = '\0'; + if (f->f_gflag & FG_BIT2) + b[3] = f->f_gflag & FG_BIT1 ? 'S' : 'F'; + else + b[3] = f->f_gflag & FG_BIT1 ? 'X' : 'N'; + cp = b; + break; + case C_ENHDEFLD: + cp = "edef"; + break; + case C_DCLIMPLODED: + cp = "dcli"; + break; + case C_BZIP2: + cp = "bz2 "; + break; + default: + snprintf(b, sizeof b, "%4.4X", f->f_cmethod); + cp = b; + } + printf(" %s", cp); +} + +#if USE_BZLIB +int +zipunbz2(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) +{ + bz_stream bs; + long long isize = f->f_csize; + char ibuf[4096], obuf[8192]; + int in, on, val = 0, ok; + + memset(&bs, 0, sizeof bs); + + if ((ok = BZ2_bzDecompressInit(&bs, 0, 0)) != BZ_OK) { + msg(3, 0, "bzip2 initialization error %d on \"%s\"\n", + ok, f->f_name); + errcnt++; + return skipfile(f); + } + while (isize > 0 || ok == BZ_OK) { + if (bs.avail_in == 0 && isize > 0) { + in = sizeof ibuf < isize ? sizeof ibuf : isize; + isize -= in; + if (bread(ibuf, in) != in) + unexeoa(); + if (doswap) + swap(ibuf, in, bflag || sflag, bflag || Sflag); + bs.next_in = ibuf; + bs.avail_in = in; + } + if (ok == BZ_OK) { + bs.next_out = obuf; + bs.avail_out = sizeof obuf; + switch (ok = BZ2_bzDecompress(&bs)) { + case BZ_OK: + case BZ_STREAM_END: + on = sizeof obuf - bs.avail_out; + if (tfd >= 0 && write(tfd, obuf, on) != on) { + emsg(3, "Cannot write \"%s\"", tgt); + tfd = -1; + val = 1; + } + *crc = zipcrc(*crc, (unsigned char *)obuf, on); + break; + default: + msg(3, 0, "compression error %d on \"%s\"\n", + ok, f->f_name); + errcnt++; + val = 1; + } + } + } + BZ2_bzDecompressEnd(&bs); + return val; +} +#endif /* USE_BZLIB */ + +struct blasthow { + struct file *bh_f; + const char *bh_tgt; + long long bh_isize; + uint32_t *bh_crc; + int bh_tfd; + int bh_doswap; + int bh_val; +}; + +static unsigned +blastin(void *how, unsigned char **buf) +{ + const int chunk = 16384; + static unsigned char *hold; + struct blasthow *bp = how; + unsigned sz; + + if (bp->bh_isize <= 0) + return 0; + if (hold == NULL) + hold = smalloc(chunk); + sz = bp->bh_isize > chunk ? chunk : bp->bh_isize; + bp->bh_isize -= sz; + if (bread((char *)hold, sz) != sz) + unexeoa(); + if (bp->bh_doswap) + swap((char *)hold, sz, bflag || sflag, bflag || Sflag); + *buf = hold; + return sz; +} + +static int +blastout(void *how, unsigned char *buf, unsigned len) +{ + struct blasthow *bp = how; + + if (bp->bh_tfd >= 0 && write(bp->bh_tfd, buf, len) != len) { + emsg(3, "Cannot write \"%s\"", bp->bh_tgt); + bp->bh_tfd = -1; + bp->bh_val = 1; + } + *bp->bh_crc = zipcrc(*bp->bh_crc, buf, len); + return 0; +} + +int +zipblast(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) +{ + struct blasthow bh; + int n; + + bh.bh_f = f; + bh.bh_tgt = tgt; + bh.bh_isize = f->f_csize; + bh.bh_crc = crc; + bh.bh_tfd = tfd; + bh.bh_doswap = doswap; + bh.bh_val = 0; + switch (n = blast(blastin, &bh, blastout, &bh)) { + case 0: + break; + default: + msg(3, 0, "compression error %d on \"%s\"\n", n, f->f_name); + errcnt++; + bh.bh_val = 1; + } + while (bh.bh_isize) { + char buf[4096]; + unsigned n; + n = bh.bh_isize > sizeof buf ? sizeof buf : bh.bh_isize; + if (bread(buf, n) != n) + unexeoa(); + bh.bh_isize -= n; + } + return bh.bh_val; +} + +/* + * The SGI -K format was introduced with SGI's IRIX 5.X. It is essentially + * a slightly extended binary format. The known additions are: + * + * - If the major or minor st_rdev device number exceeds the limit of + * 255 imposed by the 16-bit c_rdev field, this field is set to 0xFFFF + * and st_rdev is stored in the c_filesize 32-bit field. The first 14 + * bits of this field compose the major device number, the minor is + * stored in the remaining 18 bits. This enables implementations to + * read the modified format without special support if they ignore + * the size of device files; otherwise they will try to read a lot + * of archive data and fail. + * + * - If the file is larger than 2 GB - 1 byte, two nearly identical + * archive headers are stored for it. The only difference is in + * the c_filesize field: + * + * [first header: file size X times 2 GB] + * [first data part: X times 2 GB] + * [second header: file size modulo 2 GB] + * [second data part: rest of data] + * + * The first header can be recognized by a negative c_filesize. A + * value of 0xFFFFFFFF means that 2 GB follow, 0xFFFFFFFE -> 4 GB + * 0xFFFFFFFD -> 6 GB, 0xFFFFFFFC -> 8 GB, and so forth. The second + * is a standard binary cpio header, although the following data is + * meant to be appended to the preceding file. + * + * It is important to note that padding follows the number in + * c_filesize, not the amount of data written; thus all data parts + * with odd c_filesize fields (0xFFFFFFFF = 2+ GB, 0xFFFFFFFD = 6+ GB + * etc.) cause the following archive entries to be aligned on an odd + * offset. This seems to be an implementation artifact but has to be + * followed for compatibility. + * + * This extension seems a bit weird since no known cpio implementation + * is able to read these archive entries without special support. Thus + * a more straightforward extension (such as storing the size just past + * the file name) would well have had the same effect. Nevertheless, + * the cpio -K format is useful, so it is implemented here. + * + * --Note that IRIX 6.X tar also has a -K option. This option extends + * the tar format in essentially the same way as the second extension + * to cpio described above. Unfortunately, the result is definitively + * broken. Contrasting to the binary cpio format, the standard POSIX + * tar format is well able to hold files of size 0xFFFFFFFF and below + * in a regular manner. Thus, a tar -K archive entry is _exactly_ the + * same as two regular POSIX tar entries for the same file. And this + * situation even occurs on a regular basis with tar -r! For this + * reason, we do not implement the IRIX tar -K format and will probably + * never do so unless it is changed (the tar format really has a lot + * of options to indicate extensions that might be used for this). + * + * Many thanks to Sven Mascheck who made archiving tests on the IRIX + * machine. + */ +/* + * This function reads the second header of a SGI -K format archive. + */ +static void +readK2hdr(struct file *f) +{ + struct file n; + union bincpio bc; + + n.f_name = n.f_lnam = NULL; + n.f_nsiz = n.f_lsiz = 0; + readhdr(&n, &bc); + f->f_Krest = n.f_st.st_size; + f->f_dsize = f->f_st.st_size = n.f_st.st_size + f->f_Kbase; + f->f_Kbase = 0; + free(n.f_name); + free(n.f_lnam); +} + +/* + * Read the data of a GNU filename extra header. + */ +static int +readgnuname(char **np, size_t *sp, long length) +{ + if (length > SANELIMIT) + return -1; + if (*sp == 0 || *sp <= length) + *np = srealloc(*np, *sp = length+1); + bread(*np, length); + (*np)[length] = '\0'; + skippad(length, 512); + return 0; +} + +/* + * Write a GNU filename extra header and its data. + */ +static void +writegnuname(const char *fn, long length, int flag) +{ + union bincpio bc; + + memset(bc.data, 0, 512); + strcpy(bc.Tdr.t_name, "././@LongLink"); + sprintf(bc.Tdr.t_mode, "%7.7o", 0); + sprintf(bc.Tdr.t_uid, "%7.7o", 0); + sprintf(bc.Tdr.t_gid, "%7.7o", 0); + sprintf(bc.Tdr.t_size, "%11.11lo", length); + sprintf(bc.Tdr.t_mtime, "%11.11lo", 0L); + bc.Tdr.t_linkflag = flag; + memcpy(bc.Tdr.t_magic, mag_gnutar, 8); + strcpy(bc.Tdr.t_uname, "root"); + strcpy(bc.Tdr.t_gname, "root"); + tchksum(&bc); + bwrite(bc.data, 512); + bwrite(fn, length); + length %= 512; + memset(bc.data, 0, 512 - length); + bwrite(bc.data, 512 - length); +} + +/* + * POSIX.1-2001 pax format support. + */ +static void +tgetpax(struct tar_header *tp, struct file *f) +{ + char *keyword, *value; + char *block, *bp; + long long n; + enum paxrec pr; + + n = rdoct(tp->t_size, 12); + bp = block = smalloc(n+1); + bread(block, n); + skippad(n, 512); + block[n] = '\0'; + while (bp < &block[n]) { + int c; + pr = tgetrec(&bp, &keyword, &value); + switch (pr) { + case PR_ATIME: + f->f_st.st_atime = strtoll(value, NULL, 10); + break; + case PR_GID: + f->f_st.st_gid = strtoll(value, NULL, 10); + break; + case PR_LINKPATH: + c = strlen(value); + if (f->f_lnam == NULL || f->f_lsiz < c+1) { + f->f_lsiz = c+1; + f->f_lnam = srealloc(f->f_lnam, c+1); + } + strcpy(f->f_lnam, value); + break; + case PR_MTIME: + f->f_st.st_mtime = strtoll(value, NULL, 10); + break; + case PR_PATH: + c = strlen(value); + if (f->f_name == NULL || f->f_nsiz < c+1) { + f->f_nsiz = c+1; + f->f_name = srealloc(f->f_name, c+1); + } + strcpy(f->f_name, value); + break; + case PR_SIZE: + f->f_st.st_size = strtoll(value, NULL, 10); + break; + case PR_UID: + f->f_st.st_uid = strtoll(value, NULL, 10); + break; + case PR_SUN_DEVMAJOR: + f->f_rmajor = strtoll(value, NULL, 10); + break; + case PR_SUN_DEVMINOR: + f->f_rminor = strtoll(value, NULL, 10); + break; + } + paxrec |= pr; + } + if (tp->t_linkflag == 'g') { + globrec = paxrec & ~(PR_LINKPATH|PR_PATH|PR_SIZE); + globst = f->f_st; + } + free(block); +} + +static enum paxrec +tgetrec(char **bp, char **keyword, char **value) +{ + char *x; + long n = 0; + enum paxrec pr; + + *keyword = ""; + *value = ""; + while (**bp && (n = strtol(*bp, &x, 10)) <= 0 && (*x!=' ' || *x!='\t')) + do + (*bp)++; + while (**bp && **bp != '\n'); + if (*x == '\0' || **bp == '\0') { + (*bp)++; + return PR_NONE; + } + while (x < &(*bp)[n] && (*x == ' ' || *x == '\t')) + x++; + if (x == &(*bp)[n] || *x == '=') + goto out; + *keyword = x; + while (x < &(*bp)[n] && *x != '=') + x++; + if (x == &(*bp)[n]) + goto out; + *x = '\0'; + if (&x[1] < &(*bp)[n]) + *value = &x[1]; + (*bp)[n-1] = '\0'; +out: *bp = &(*bp)[n]; + if (strcmp(*keyword, "atime") == 0) + pr = PR_ATIME; + else if (strcmp(*keyword, "gid") == 0) + pr = PR_GID; + else if (strcmp(*keyword, "linkpath") == 0) + pr = PR_LINKPATH; + else if (strcmp(*keyword, "mtime") == 0) + pr = PR_MTIME; + else if (strcmp(*keyword, "path") == 0) + pr = PR_PATH; + else if (strcmp(*keyword, "size") == 0) + pr = PR_SIZE; + else if (strcmp(*keyword, "uid") == 0) + pr = PR_UID; + else if (strcmp(*keyword, "SUN.devmajor") == 0) + pr = PR_SUN_DEVMAJOR; + else if (strcmp(*keyword, "SUN.devminor") == 0) + pr = PR_SUN_DEVMINOR; + else + pr = PR_NONE; + return pr; +} + +static void +wrpax(const char *longname, const char *linkname, struct stat *sp) +{ + union bincpio bc; + char *pdata = NULL; + long psize = 0, pcur = 0; + long long blocks; + + memset(bc.data, 0, 512); + if (paxrec & PR_ATIME) + addrec(&pdata, &psize, &pcur, "atime", NULL, sp->st_atime); + if (paxrec & PR_GID) + addrec(&pdata, &psize, &pcur, "gid", NULL, sp->st_gid); + if (paxrec & PR_LINKPATH) + addrec(&pdata, &psize, &pcur, "linkpath", linkname, 0); + if (paxrec & PR_MTIME) + addrec(&pdata, &psize, &pcur, "mtime", NULL, sp->st_mtime); + if (paxrec & PR_PATH) + addrec(&pdata, &psize, &pcur, "path", longname, 0); + if (paxrec & PR_SIZE) + addrec(&pdata, &psize, &pcur, "size", NULL, sp->st_size); + if (paxrec & PR_UID) + addrec(&pdata, &psize, &pcur, "uid", NULL, sp->st_uid); + if (paxrec & PR_SUN_DEVMAJOR) + addrec(&pdata, &psize, &pcur, "SUN.devmajor", NULL, + major(sp->st_rdev)); + if (paxrec & PR_SUN_DEVMINOR) + addrec(&pdata, &psize, &pcur, "SUN.devminor", NULL, + minor(sp->st_rdev)); + paxnam(&bc.Tdr, longname); + sprintf(bc.Tdr.t_mode, "%7.7o", fmttype==FMT_SUN ? 0444|S_IFREG : 0444); + sprintf(bc.Tdr.t_uid, "%7.7o", 0); + sprintf(bc.Tdr.t_gid, "%7.7o", 0); + sprintf(bc.Tdr.t_size, "%11.11lo", pcur); + sprintf(bc.Tdr.t_mtime, "%11.11o", 0); + strcpy(bc.Tdr.t_magic, "ustar"); + bc.Tdr.t_version[0] = bc.Tdr.t_version[1] = '0'; + strcpy(bc.Tdr.t_uname, "root"); + strcpy(bc.Tdr.t_gname, "root"); + bc.Tdr.t_linkflag = fmttype==FMT_SUN ? 'X' : 'x'; + tchksum(&bc); + bwrite(bc.data, 512); + memset(&pdata[pcur], 0, psize - pcur); + blocks = (pcur + (512-1)) / 512; + bwrite(pdata, blocks * 512); + free(pdata); +} + +static void +addrec(char **pdata, long *psize, long *pcur, + const char *keyword, const char *sval, long long lval) +{ + char dval[25], xval[25]; + long od, d, r; + + if (sval == 0) { + sprintf(xval, "%lld", lval); + sval = xval; + } + r = strlen(keyword) + strlen(sval) + 3; + d = 0; + do { + od = d; + d = sprintf(dval, "%ld", od + r); + } while (d != od); + *psize += d + r + 1 + 512; + *pdata = srealloc(*pdata, *psize); + sprintf(&(*pdata)[*pcur], "%s %s=%s\n", dval, keyword, sval); + *pcur += d + r; +} + +static void +paxnam(struct tar_header *hp, const char *name) +{ + char buf[257], *bp; + const char *cp, *np; + int bl = 0; + static int pid; + + if (pid == 0) + pid = getpid(); + for (np = name; *np; np++); + while (np > name && *np != '/') { + np--; + bl++; + } + if ((np > name || *name == '/') && np-name <= 120) + for (bp = buf, cp = name; cp < np; bp++, cp++) + *bp = *cp; + else { + *buf = '.'; + bp = &buf[1]; + } + snprintf(bp, sizeof buf - (bp - buf), "/PaxHeaders.%d/%s", + pid, bl < 100 ? np>name?&np[1]:name : sequence()); + tmkname(hp, buf); +} + +static char * +sequence(void) +{ + static char buf[25]; + static long long d; + + sprintf(buf, "%10.10lld", ++d); + return buf; +} + +static int +pax_oneopt(const char *s, int warn) +{ + if (strcmp(s, "linkdata") == 0) + pax_oflag |= PO_LINKDATA; + else if (strcmp(s, "times") == 0) + pax_oflag |= PO_TIMES; + else { + if (warn) + msg(2, 0, "Unknown flag \"-o %s\"\n", s); + return -1; + } + return 0; +} + +int +pax_options(char *s, int warn) +{ + char *o = s, c; + int val = 0, word = 0; + + do { + if (word == 0) { + if (isspace(*s&0377)) + o = &s[1]; + else + word = 1; + } + if (*s == ',' || *s == '\0') { + c = *s; + *s = '\0'; + val |= pax_oneopt(o, warn); + *s = c; + o = &s[1]; + word = 0; + } + } while (*s++); + return val; +} + +/* + * Given a symbolic link "base" and the result of readlink "name", form + * a valid path name for the link target. + */ +static char * +joinpath(const char *base, char *name) +{ + const char *bp = NULL, *cp; + char *new, *np; + + if (*name == '/') + return name; + for (cp = base; *cp; cp++) + if (*cp == '/') + bp = cp; + if (bp == NULL) + return name; + np = new = smalloc(bp - base + strlen(name) + 2); + for (cp = base; cp < bp; cp++) + *np++ = *cp; + *np++ = '/'; + for (cp = name; *cp; cp++) + *np++ = *cp; + *np = '\0'; + free(name); + return new; +} + +static int +utf8(const char *cp) +{ + int c, n; + + while (*cp) if ((c = *cp++ & 0377) & 0200) { + if (c == (c & 037 | 0300)) + n = 1; + else if (c == (c & 017 | 0340)) + n = 2; + else if (c == (c & 07 | 0360)) + n = 3; + else if (c == (c & 03 | 0370)) + n = 4; + else if (c == (c & 01 | 0374)) + n = 5; + else + return 0; + while (n--) { + c = *cp++ & 0377; + if (c != (c & 077 | 0200)) + return 0; + } + } + return 1; +} + +static time_t +fetchtime(const char *cp) +{ + struct tm tm; + time_t t; + char *xp; + int n; + + t = strtoll(cp, &xp, 10); + if (*xp == '\0') + return t; + memset(&tm, 0, sizeof tm); + n = sscanf(cp, "%4d%2d%2dT%2d%2d%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + tm.tm_year -= 1900; + tm.tm_mon--; + tm.tm_isdst = -1; + t = mktime(&tm); + if (n < 3 || t == (time_t)-1) + msg(4, 1, "line %lld: illegal time \"%s\"\n", + lineno, cp); + return t; +} + +static char * +nextfield(char *cp, const char *fieldname) +{ + while (*cp && *cp != ':') + cp++; + if (*cp == 0) + msg(4, 1, "line %lld: unterminated \"%s\" field\n", + lineno, fieldname); + *cp++ = 0; + return cp; +} + +static char * +getproto(char *np, struct prototype *pp) +{ + char *tp, *xp; + long long t, u; + + memset(pp, 0, sizeof *pp); + if (*np == ':') + np++; + else { + tp = nextfield(np, "type"); + if (np[1]) + goto notype; + switch (np[0]) { + case 'b': + pp->pt_mode |= S_IFBLK; + break; + case 'c': + pp->pt_mode |= S_IFCHR; + break; + case 'd': + pp->pt_mode |= S_IFDIR; + break; + case 'f': + pp->pt_mode |= S_IFREG; + break; + case 'p': + pp->pt_mode |= S_IFIFO; + break; + case 's': + pp->pt_mode |= S_IFLNK; + break; + default: + notype: + msg(4, 1, "line %lld: unknown type \"%s\"\n", + lineno, np); + } + pp->pt_spec |= PT_TYPE; + np = tp; + } + if (*np == ':') + np++; + else { + struct passwd *pwd; + tp = nextfield(np, "owner"); + t = strtoll(np, &xp, 10); + if (*xp == '\0') + pp->pt_uid = t; + else { + if ((pwd = getpwnam(np)) == NULL) + msg(4, 1, "line %lld: unknown user \"%s\"\n", + lineno, np); + pp->pt_uid = pwd->pw_uid; + } + pp->pt_spec |= PT_OWNER; + np = tp; + } + if (*np == ':') + np++; + else { + struct group *grp; + tp = nextfield(np, "group"); + t = strtoll(np, &xp, 10); + if (*xp == '\0') + pp->pt_gid = t; + else { + if ((grp = getgrnam(np)) == NULL) + msg(4, 1, "line %lld: unknown group \"%s\"\n", + lineno, np); + pp->pt_gid = grp->gr_gid; + } + pp->pt_spec |= PT_GROUP; + np = tp; + } + if (*np == ':') + np++; + else { + tp = nextfield(np, "mode"); + t = strtol(np, &xp, 8); + if (t & ~07777 || *xp) + msg(4, 1, "line %lld: illegal mode \"%s\"\n", + lineno, np); + pp->pt_mode |= t; + pp->pt_spec |= PT_MODE; + np = tp; + } + if (*np == ':') + np++; + else { + tp = nextfield(np, "access time"); + pp->pt_atime = fetchtime(np); + pp->pt_spec |= PT_ATIME; + np = tp; + } + if (*np == ':') + np++; + else { + tp = nextfield(np, "modification time"); + pp->pt_mtime = fetchtime(np); + pp->pt_spec |= PT_MTIME; + np = tp; + } + if (*np == ':') { + np++; + if (*np++ != ':') + majmin: msg(4, 1, "line %lld: need either both major and " + "minor or none\n", + lineno); + } else { + tp = nextfield(np, "major"); + t = strtoll(np, &xp, 10); + if (*xp) + msg(4, 1, "line %lld: illegal major \"%s\"\n", + lineno, np); + np = tp; + if (*np == ':') + goto majmin; + tp = nextfield(np, "minor"); + u = strtoll(np, &xp, 10); + if (*xp) + msg(4, 1, "line %lld: illegal minor \"%s\"\n", + lineno, np); + np = tp; + pp->pt_rdev = makedev(t, u); + pp->pt_spec |= PT_RDEV; + } + return np; +} diff --git a/package/heirloom-cpio/src/cpio.h b/package/heirloom-cpio/src/cpio.h new file mode 100644 index 000000000..131a3d388 --- /dev/null +++ b/package/heirloom-cpio/src/cpio.h @@ -0,0 +1,232 @@ +/* + * cpio - copy file archives in and out + * + * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. + */ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +/* Sccsid @(#)cpio.h 1.29 (gritter) 3/26/07 */ + +#include +#include +#include + +enum { + FMT_NONE = 00000000, /* no format chosen yet */ + + TYP_PAX = 00000010, /* uses pax-like extended headers */ + TYP_BE = 00000100, /* this binary archive is big-endian */ + TYP_SGI = 00000200, /* SGI cpio -K flag binary archive */ + TYP_SCO = 00000200, /* SCO UnixWare 7.1 extended archive */ + TYP_CRC = 00000400, /* this has a SVR4 'crc' checksum */ + TYP_BINARY = 00001000, /* this is a binary cpio type */ + TYP_OCPIO = 00002000, /* this is an old cpio type */ + TYP_NCPIO = 00004000, /* this is a SVR4 cpio type */ + TYP_CRAY = 00010000, /* this is a Cray cpio archive */ + TYP_CPIO = 00077000, /* this is a cpio type */ + TYP_OTAR = 00100000, /* this is an old tar type */ + TYP_USTAR = 00200000, /* this is a ustar type */ + TYP_BAR = 00400000, /* this is a bar type */ + TYP_TAR = 00700000, /* this is a tar type */ + + FMT_ODC = 00002001, /* POSIX ASCII cpio format */ + FMT_DEC = 00002002, /* DEC extended cpio format */ + FMT_BINLE = 00003001, /* binary (default) cpio format LE */ + FMT_BINBE = 00003101, /* binary (default) cpio format BE */ + FMT_SGILE = 00003201, /* IRIX-style -K binary format LE */ + FMT_SGIBE = 00003301, /* IRIX-style -K binary format BE */ + FMT_ASC = 00004001, /* SVR4 ASCII cpio format */ + FMT_SCOASC = 00004201, /* UnixWare 7.1 ASCII cpio format */ + FMT_CRC = 00004401, /* SVR4 ASCII cpio format w/checksum */ + FMT_SCOCRC = 00004601, /* UnixWare 7.1 ASCII cpio w/checksum */ + FMT_CRAY = 00010001, /* Cray cpio, UNICOS 6 and later */ + FMT_CRAY5 = 00010002, /* Cray cpio, UNICOS 5 and earlier */ + FMT_OTAR = 00100001, /* obsolete tar format */ + FMT_TAR = 00200001, /* our tar format type */ + FMT_USTAR = 00200002, /* ustar format */ + FMT_GNUTAR = 00200003, /* GNU tar format type */ + FMT_PAX = 00200011, /* POSIX.1-2001 pax format type */ + FMT_SUN = 00200012, /* Sun extended tar format type */ + FMT_BAR = 00400001, /* bar format type */ + + FMT_ZIP = 01000000 /* zip format */ +} fmttype; + +/* + * Zip compression method. + */ +enum cmethod { + C_STORED = 0, /* no compression */ + C_SHRUNK = 1, + C_REDUCED1 = 2, + C_REDUCED2 = 3, + C_REDUCED3 = 4, + C_REDUCED4 = 5, + C_IMPLODED = 6, + C_TOKENIZED = 7, + C_DEFLATED = 8, + C_ENHDEFLD = 9, + C_DCLIMPLODED = 10, + C_PKRESERVED = 11, + C_BZIP2 = 12, +}; + +/* + * A collection of the interesting facts about a file in copy-in mode. + */ +struct file { + struct stat f_st; /* file stat */ + long long f_rmajor; /* st_rdev major */ + long long f_rminor; /* st_rdev minor */ + long long f_dsize; /* display size */ + long long f_csize; /* compressed size */ + long long f_Kbase; /* base size for -K */ + long long f_Krest; /* rest size for -K */ + long long f_Ksize; /* faked -K size field */ + char *f_name; /* file name */ + size_t f_nsiz; /* file name size */ + char *f_lnam; /* link name */ + size_t f_lsiz; /* link name size */ + uint32_t f_chksum; /* checksum */ + int f_pad; /* padding size */ + int f_fd; /* file descriptor (for pass mode) */ + enum cmethod f_cmethod; /* zip compression method */ + enum { + FG_CRYPT = 0001, /* encrypted zip file */ + FG_BIT1 = 0002, + FG_BIT2 = 0004, + FG_DESC = 0010 /* zip file with data descriptor */ + } f_gflag; /* zip general flag */ + enum { + OF_ZIP64 = 0001 /* is a zip64 archive entry */ + } f_oflag; /* other flags */ +}; + +/* + * Patterns for gmatch(). + */ +struct glist { + struct glist *g_nxt; + const char *g_pat; + unsigned g_gotcha : 1; + unsigned g_not : 1; + unsigned g_art : 1; +}; + +extern int aflag; +extern int Aflag; +extern int bflag; +extern int Bflag; +extern int cflag; +extern int Cflag; +extern int dflag; +extern int Dflag; +extern int eflag; +extern int cray_eflag; +extern const char *Eflag; +extern int fflag; +extern int Hflag; +extern const char *Iflag; +extern int kflag; +extern int Kflag; +extern int lflag; +extern int Lflag; +extern int mflag; +extern const char *Mflag; +extern const char *Oflag; +extern int Pflag; +extern int rflag; +extern const char *Rflag; +extern int sflag; +extern int Sflag; +extern int tflag; +extern int uflag; +extern int hp_Uflag; +extern int vflag; +extern int Vflag; +extern int sixflag; +extern int action; +extern long long errcnt; +extern int blksiz; +extern int sysv3; +extern int printsev; +extern char *progname; +extern struct glist *patterns; + +enum { /* type of pax command this is */ + PAX_TYPE_CPIO = 0, /* not a pax command */ + PAX_TYPE_PAX1992 = 1, /* POSIX.2 pax command */ + PAX_TYPE_PAX2001 = 2 /* POSIX.1-2001 pax command */ +} pax; +extern int pax_dflag; +extern int pax_kflag; +extern int pax_nflag; +extern int pax_sflag; +extern int pax_uflag; +extern int pax_Xflag; + +enum { + PAX_P_NONE = 0000, + PAX_P_ATIME = 0001, + PAX_P_MTIME = 0004, + PAX_P_OWNER = 0010, + PAX_P_MODE = 0020, + PAX_P_EVERY = 0400 +} pax_preserve; + +extern size_t (*ofiles)(char **, size_t *); +extern void (*prtime)(time_t); + +extern ssize_t bread(char *, size_t); +extern void bunread(const char *, size_t); +extern void swap(char *, size_t, int, int); +extern void msg(int, int, const char *, ...); +extern void emsg(int, const char *, ...); +extern void unexeoa(void); +extern int setfmt(char *); +extern char *oneintfmt(const char *); +extern int setreassign(const char *); +extern void addg(const char *, int); +extern void *srealloc(void *, size_t); +extern void *smalloc(size_t); +extern void *scalloc(size_t, size_t); +extern void *svalloc(size_t, int); +extern char *sstrdup(const char *); +extern int pax_options(char *, int); + +extern int zipunshrink(struct file *, const char *, int, int, uint32_t *); +extern int zipexplode(struct file *, const char *, int, int, uint32_t *); +extern int zipexpand(struct file *, const char *, int, int, uint32_t *); +extern int zipinflate(struct file *, const char *, int, int, uint32_t *); +extern int zipunbz2(struct file *, const char *, int, int, uint32_t *); +extern int zipblast(struct file *, const char *, int, int, uint32_t *); + +extern uint32_t zipcrc(uint32_t, const uint8_t *, size_t); + +extern void flags(int, char **); +extern void usage(void); + +extern int pax_track(const char *, time_t); +extern void pax_prlink(struct file *); +extern int pax_sname(char **, size_t *); +extern void pax_onexit(void); diff --git a/package/heirloom-cpio/src/crc32.c b/package/heirloom-cpio/src/crc32.c new file mode 100644 index 000000000..084cb52cf --- /dev/null +++ b/package/heirloom-cpio/src/crc32.c @@ -0,0 +1,115 @@ +/* + * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. + * + * Derived from zlib 1.1.4 + * + * Sccsid @(#)crc32.c 1.2 (gritter) 5/29/03 + */ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. 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. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + */ + +#include "cpio.h" + +/* + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +static const uint32_t crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +uint32_t +zipcrc(uint32_t crc, const uint8_t *buf, size_t len) +{ + if (buf == 0) + return 0L; + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} diff --git a/package/heirloom-cpio/src/expand.c b/package/heirloom-cpio/src/expand.c new file mode 100644 index 000000000..5a5233f3e --- /dev/null +++ b/package/heirloom-cpio/src/expand.c @@ -0,0 +1,193 @@ +/* + * cpio - copy file archives in and out + * + * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. + */ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +/* Sccsid @(#)expand.c 1.6 (gritter) 12/15/03 */ + +#include +#include +#include +#include +#include + +#include "cpio.h" + +#define DLE 144 + +static void +zexread(char *data, size_t size, int doswap) +{ + if (bread(data, size) != size) + unexeoa(); + if (doswap) + swap(data, size, bflag || sflag, bflag || Sflag); +} + +#define nextbyte() ( \ + ipos >= sizeof ibuf && isize > 0 ? ( \ + zexread(ibuf, isize>sizeof ibuf?sizeof ibuf:isize, doswap), \ + ipos = 0 \ + ) : 0, \ + isize--, \ + ibuf[ipos++] & 0377 \ +) + +#define nextbit() ( \ + ibit = ibit >= 7 ? (ibyte = nextbyte(), 0) : ibit + 1, \ + isize < 0 ? (ieof = 1, -1) : (ibyte & (1<> ibit \ +) + +#define sixbits(n) { \ + int t; \ + (n) = 0; \ + for (t = 0; t < 6; t++) \ + (n) |= nextbit() << t; \ +} + +#define eightbits(n) { \ + int t; \ + (n) = 0; \ + for (t = 0; t < 8; t++) \ + (n) |= nextbit() << t; \ +} + +static void +zexwrite(int *tfd, char *data, size_t size, uint32_t *crc, int *val, + const char *tgt, long long *nsize) +{ + if (size) { + if (size > *nsize) + size = *nsize; + if (*tfd >= 0 && write(*tfd, data, size) != size) { + emsg(3, "Cannot write \"%s\"", tgt); + *tfd = -1; + *val = -1; + } + *crc = zipcrc(*crc, (unsigned char *)data, size); + *nsize -= size; + } +} + +#define wadd(c) ( \ + wpos >= sizeof wbuf ? ( \ + zexwrite(&tfd, wbuf, sizeof wbuf, crc, &val, tgt, &nsize), \ + wpos = 0 \ + ) : 0, \ + wsize++, \ + wbuf[wpos++] = (c) \ +) + +#define zex_L(x) ( \ + f->f_cmethod == C_REDUCED1 ? (x) & 0177 : \ + f->f_cmethod == C_REDUCED2 ? (x) & 077 : \ + f->f_cmethod == C_REDUCED3 ? (x) & 037 : \ + /* f->f_cmethod == C_REDUCED4 */ (x) & 017 \ +) + +#define zex_F(x) ( \ + f->f_cmethod == C_REDUCED1 ? (x) == 0177 ? 2 : 3 : \ + f->f_cmethod == C_REDUCED2 ? (x) == 077 ? 2 : 3 : \ + f->f_cmethod == C_REDUCED3 ? (x) == 037 ? 2 : 3 : \ + /* f->f_cmethod == C_REDUCED4 */ (x) == 017 ? 2 : 3 \ +) + +#define zex_D(x, y) ( \ + f->f_cmethod == C_REDUCED1 ? (((x)&0200)>>7) * 0400 + (y) + 1 : \ + f->f_cmethod == C_REDUCED2 ? (((x)&0300)>>6) * 0400 + (y) + 1 : \ + f->f_cmethod == C_REDUCED3 ? (((x)&0340)>>5) * 0400 + (y) + 1 : \ + /* f->f_cmethod == C_REDUCED4 */ (((x)&0360)>>4) * 0400 + (y) + 1 \ +) + +int +zipexpand(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) +{ + char fset[256][33]; + char ibuf[4096], ibyte = 0, wbuf[8192]; + long ipos = sizeof ibuf, wpos = 0, isize = f->f_csize, wsize = 0; + int val = 0, ieof = 0; + int c = 0, i, j, k, n, ibit = 7, lastc, state, v = 0, len = 0; + long long nsize = f->f_st.st_size; + + *crc = 0; + memset(fset, 0, sizeof fset); + for (j = 255; j >= 0; j--) { + sixbits(n); + for (i = 0; i < n; i++) { + eightbits(fset[j][i]); + } + fset[j][32] = n<1?0:n<3?1:n<5?2:n<9?3:n<17?4:n<37?5:n<65?6:7; + } + lastc = 0; + state = 0; + while (ieof == 0) { + if (fset[lastc][32] == 0) { + eightbits(c); + } else { + if (nextbit() != 0) { + eightbits(c); + } else { + i = 0; + for (k = 0; k < fset[lastc][32]; k++) + i |= nextbit() << k; + c = fset[lastc][i] & 0377; + } + } + lastc = c; + switch (state) { + case 0: + if (c != DLE) + wadd(c); + else + state = 1; + break; + case 1: + if (c != 0) { + v = c; + len = zex_L(v); + state = zex_F(len); + } else { + wadd(DLE); + state = 0; + } + break; + case 2: + len += c; + state = 3; + break; + case 3: + n = wsize - zex_D(v, c); + for (i = 0; i < len + 3; i++) { + c = n+i >= 0 ? wbuf[n+i&sizeof wbuf-1]&0377 : 0; + wadd(c); + } + state = 0; + } + } + zexwrite(&tfd, wbuf, wpos, crc, &val, tgt, &nsize); + while (isize >= 0) + nextbyte(); + return val; +} diff --git a/package/heirloom-cpio/src/explode.c b/package/heirloom-cpio/src/explode.c new file mode 100644 index 000000000..863dbf672 --- /dev/null +++ b/package/heirloom-cpio/src/explode.c @@ -0,0 +1,1138 @@ +/* + * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. + * + * Derived from unzip 5.40. + * + * Sccsid @(#)explode.c 1.6 (gritter) 9/30/03 + */ +/* explode.c -- put in the public domain by Mark Adler + version c15, 6 July 1996 */ + + +/* You can do whatever you like with this source file, though I would + prefer that if you modify it and redistribute it that you include + comments to that effect with your name and the date. Thank you. + + History: + vers date who what + ---- --------- -------------- ------------------------------------ + c1 30 Mar 92 M. Adler explode that uses huft_build from inflate + (this gives over a 70% speed improvement + over the original unimplode.c, which + decoded a bit at a time) + c2 4 Apr 92 M. Adler fixed bug for file sizes a multiple of 32k. + c3 10 Apr 92 M. Adler added a little memory tracking if DEBUG + c4 11 Apr 92 M. Adler added NOMEMCPY do kill use of memcpy() + c5 21 Apr 92 M. Adler added the WSIZE #define to allow reducing + the 32K window size for specialized + applications. + c6 31 May 92 M. Adler added typecasts to eliminate some warnings + c7 27 Jun 92 G. Roelofs added more typecasts. + c8 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch. + c9 19 Jul 93 J. Bush added more typecasts (to return values); + made l[256] array static for Amiga. + c10 8 Oct 93 G. Roelofs added used_csize for diagnostics; added + buf and unshrink arguments to flush(); + undef'd various macros at end for Turbo C; + removed NEXTBYTE macro (now in unzip.h) + and bytebuf variable (not used); changed + memset() to memzero(). + c11 9 Jan 94 M. Adler fixed incorrect used_csize calculation. + c12 9 Apr 94 G. Roelofs fixed split comments on preprocessor lines + to avoid bug in Encore compiler. + c13 25 Aug 94 M. Adler fixed distance-length comment (orig c9 fix) + c14 22 Nov 95 S. Maxwell removed unnecessary "static" on auto array + c15 6 Jul 96 W. Haidinger added ulg typecasts to flush() calls. + c16 8 Feb 98 C. Spieler added ZCONST modifiers to const tables + and #ifdef DEBUG around debugging code. + c16b 25 Mar 98 C. Spieler modified DLL code for slide redirection. + + 23 May 03 Gunnar Ritter use cpio structures; C99 conversion. + */ + + +/* + Explode imploded (PKZIP method 6 compressed) data. This compression + method searches for as much of the current string of bytes (up to a length + of ~320) in the previous 4K or 8K bytes. If it doesn't find any matches + (of at least length 2 or 3), it codes the next byte. Otherwise, it codes + the length of the matched string and its distance backwards from the + current position. Single bytes ("literals") are preceded by a one (a + single bit) and are either uncoded (the eight bits go directly into the + compressed stream for a total of nine bits) or Huffman coded with a + supplied literal code tree. If literals are coded, then the minimum match + length is three, otherwise it is two. + + There are therefore four kinds of imploded streams: 8K search with coded + literals (min match = 3), 4K search with coded literals (min match = 3), + 8K with uncoded literals (min match = 2), and 4K with uncoded literals + (min match = 2). The kind of stream is identified in two bits of a + general purpose bit flag that is outside of the compressed stream. + + Distance-length pairs for matched strings are preceded by a zero bit (to + distinguish them from literals) and are always coded. The distance comes + first and is either the low six (4K) or low seven (8K) bits of the + distance (uncoded), followed by the high six bits of the distance coded. + Then the length is six bits coded (0..63 + min match length), and if the + maximum such length is coded, then it's followed by another eight bits + (uncoded) to be added to the coded length. This gives a match length + range of 2..320 or 3..321 bytes. + + The literal, length, and distance codes are all represented in a slightly + compressed form themselves. What is sent are the lengths of the codes for + each value, which is sufficient to construct the codes. Each byte of the + code representation is the code length (the low four bits representing + 1..16), and the number of values sequentially with that length (the high + four bits also representing 1..16). There are 256 literal code values (if + literals are coded), 64 length code values, and 64 distance code values, + in that order at the beginning of the compressed stream. Each set of code + values is preceded (redundantly) with a byte indicating how many bytes are + in the code description that follows, in the range 1..256. + + The codes themselves are decoded using tables made by huft_build() from + the bit lengths. That routine and its comments are in the inflate.c + module. + */ + +#include +#include +#include +#include + +#include "cpio.h" +#include "unzip.h" /* must supply slide[] (uint8_t) array and NEXTBYTE macro */ + +/* routines here */ +static int get_tree(struct globals *, unsigned *l, unsigned n); +static int explode_lit8(struct globals *, struct huft *tb, struct huft *tl, + struct huft *td, int bb, int bl, int bd); +static int explode_lit4(struct globals *, struct huft *tb, struct huft *tl, + struct huft *td, int bb, int bl, int bd); +static int explode_nolit8(struct globals *, struct huft *tl, struct huft *td, + int bl, int bd); +static int explode_nolit4(struct globals *, struct huft *tl, struct huft *td, + int bl, int bd); + +/* The implode algorithm uses a sliding 4K or 8K byte window on the + uncompressed stream to find repeated byte strings. This is implemented + here as a circular buffer. The index is updated simply by incrementing + and then and'ing with 0x0fff (4K-1) or 0x1fff (8K-1). Here, the 32K + buffer of inflate is used, and it works just as well to always have + a 32K circular buffer, so the index is anded with 0x7fff. This is + done to allow the window to also be used as the output buffer. */ +/* This must be supplied in an external module useable like + "uint8_t slide[8192];" or "uint8_t *slide;", where the latter would + be malloc'ed. In unzip, slide[] is actually a 32K area for use by + inflate, which uses a 32K sliding window. + */ + + +/* Tables for length and distance */ +static const uint16_t cplen2[] = + {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65}; +static const uint16_t cplen3[] = + {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66}; +static const uint8_t extra[] = + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8}; +static const uint16_t cpdist4[] = + {1, 65, 129, 193, 257, 321, 385, 449, 513, 577, 641, 705, + 769, 833, 897, 961, 1025, 1089, 1153, 1217, 1281, 1345, 1409, 1473, + 1537, 1601, 1665, 1729, 1793, 1857, 1921, 1985, 2049, 2113, 2177, + 2241, 2305, 2369, 2433, 2497, 2561, 2625, 2689, 2753, 2817, 2881, + 2945, 3009, 3073, 3137, 3201, 3265, 3329, 3393, 3457, 3521, 3585, + 3649, 3713, 3777, 3841, 3905, 3969, 4033}; +static const uint16_t cpdist8[] = + {1, 129, 257, 385, 513, 641, 769, 897, 1025, 1153, 1281, + 1409, 1537, 1665, 1793, 1921, 2049, 2177, 2305, 2433, 2561, 2689, + 2817, 2945, 3073, 3201, 3329, 3457, 3585, 3713, 3841, 3969, 4097, + 4225, 4353, 4481, 4609, 4737, 4865, 4993, 5121, 5249, 5377, 5505, + 5633, 5761, 5889, 6017, 6145, 6273, 6401, 6529, 6657, 6785, 6913, + 7041, 7169, 7297, 7425, 7553, 7681, 7809, 7937, 8065}; + + +/* Macros for inflate() bit peeking and grabbing. + The usage is: + + NEEDBITS(j) + x = b & mask_bits[j]; + DUMPBITS(j) + + where NEEDBITS makes sure that b has at least j bits in it, and + DUMPBITS removes the bits from b. The macros use the variable k + for the number of bits in b. Normally, b and k are register + variables for speed. + */ + +#define NEEDBITS(n) {while(k<(n)){b|=((uint32_t)NEXTBYTE)<>=(n);k-=(n);} + +#define Bits 16 +#define Nob 16 +#define Eob 15 + +#define G (*Gp) + +static int +get_tree(struct globals *Gp, unsigned *l, unsigned n) +/*unsigned *l;*/ /* bit lengths */ +/*unsigned n;*/ /* number expected */ +/* Get the bit lengths for a code representation from the compressed + stream. If get_tree() returns 4, then there is an error in the data. + Otherwise zero is returned. */ +{ + unsigned i; /* bytes remaining in list */ + unsigned k; /* lengths entered */ + unsigned j; /* number of codes */ + unsigned b; /* bit length for those codes */ + + + /* get bit lengths */ + i = NEXTBYTE + 1; /* length/count pairs to read */ + k = 0; /* next code */ + do { + b = ((j = NEXTBYTE) & 0xf) + 1; /* bits in code (1..16) */ + j = ((j & 0xf0) >> 4) + 1; /* codes with those bits (1..16) */ + if (k + j > n) + return 4; /* don't overflow l[] */ + do { + l[k++] = b; + } while (--j); + } while (--i); + return k != n ? 4 : 0; /* should have read n of them */ +} + + + +static int +explode_lit8(struct globals *Gp, + struct huft *tb, struct huft *tl, struct huft *td, + int bb, int bl, int bd) +/*struct huft *tb, *tl, *td;*/ /* literal, length, and distance tables */ +/*int bb, bl, bd;*/ /* number of bits decoded by those */ +/* Decompress the imploded data using coded literals and an 8K sliding + window. */ +{ + long s; /* bytes to decompress */ + register unsigned e; /* table entry flag/number of extra bits */ + unsigned n, d; /* length and index for copy */ + unsigned w; /* current window position */ + struct huft *t; /* pointer to table entry */ + unsigned mb, ml, md; /* masks for bb, bl, and bd bits */ + register uint32_t b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + unsigned u; /* true if unflushed */ + + + /* explode the coded data */ + b = k = w = 0; /* initialize bit buffer, window */ + u = 1; /* buffer unflushed */ + mb = mask_bits[bb]; /* precompute masks for speed */ + ml = mask_bits[bl]; + md = mask_bits[bd]; + s = G.ucsize; + while (s > 0) /* do until ucsize bytes uncompressed */ + { + NEEDBITS(1) + if (b & 1) /* then literal--decode it */ + { + DUMPBITS(1) + s--; + NEEDBITS((unsigned)bb) /* get coded literal */ + if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + redirSlide[w++] = (uint8_t)t->v.n; + if (w == WSIZE) + { + flush(&G, redirSlide, (uint32_t)w); + w = u = 0; + } + } + else /* else distance/length */ + { + DUMPBITS(1) + NEEDBITS(7) /* get distance low bits */ + d = (unsigned)b & 0x7f; + DUMPBITS(7) + NEEDBITS((unsigned)bd) /* get coded distance high bits */ + if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + d = w - d - t->v.n; /* construct offset */ + NEEDBITS((unsigned)bl) /* get coded length */ + if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + n = t->v.n; + if (e) /* get length extra bits */ + { + NEEDBITS(8) + n += (unsigned)b & 0xff; + DUMPBITS(8) + } + + /* do the copy */ + s -= n; + do { + n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); + if (u && w <= d) + { + memset(redirSlide + w, 0, e); + w += e; + d += e; + } + else +#ifndef NOMEMCPY + if (w - d >= e) /* (this test assumes unsigned comparison) */ + { + memcpy(redirSlide + w, redirSlide + d, e); + w += e; + d += e; + } + else /* do it slow to avoid memcpy() overlap */ +#endif /* !NOMEMCPY */ + do { + redirSlide[w++] = redirSlide[d++]; + } while (--e); + if (w == WSIZE) + { + flush(&G, redirSlide, (uint32_t)w); + w = u = 0; + } + } while (n); + } + } + + /* flush out redirSlide */ + flush(&G, redirSlide, (uint32_t)w); + if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ + { /* sometimes read one too many: k>>3 compensates */ + /*G.used_csize = G.zsize - G.csize - G.incnt - (k >> 3);*/ + return 5; + } + return 0; +} + + + +static int +explode_lit4(struct globals *Gp, + struct huft *tb, struct huft *tl, struct huft *td, + int bb, int bl, int bd) +/*struct huft *tb, *tl, *td;*/ /* literal, length, and distance tables */ +/*int bb, bl, bd;*/ /* number of bits decoded by those */ +/* Decompress the imploded data using coded literals and a 4K sliding + window. */ +{ + long s; /* bytes to decompress */ + register unsigned e; /* table entry flag/number of extra bits */ + unsigned n, d; /* length and index for copy */ + unsigned w; /* current window position */ + struct huft *t; /* pointer to table entry */ + unsigned mb, ml, md; /* masks for bb, bl, and bd bits */ + register uint32_t b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + unsigned u; /* true if unflushed */ + + + /* explode the coded data */ + b = k = w = 0; /* initialize bit buffer, window */ + u = 1; /* buffer unflushed */ + mb = mask_bits[bb]; /* precompute masks for speed */ + ml = mask_bits[bl]; + md = mask_bits[bd]; + s = G.ucsize; + while (s > 0) /* do until ucsize bytes uncompressed */ + { + NEEDBITS(1) + if (b & 1) /* then literal--decode it */ + { + DUMPBITS(1) + s--; + NEEDBITS((unsigned)bb) /* get coded literal */ + if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + redirSlide[w++] = (uint8_t)t->v.n; + if (w == WSIZE) + { + flush(&G, redirSlide, (uint32_t)w); + w = u = 0; + } + } + else /* else distance/length */ + { + DUMPBITS(1) + NEEDBITS(6) /* get distance low bits */ + d = (unsigned)b & 0x3f; + DUMPBITS(6) + NEEDBITS((unsigned)bd) /* get coded distance high bits */ + if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + d = w - d - t->v.n; /* construct offset */ + NEEDBITS((unsigned)bl) /* get coded length */ + if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + n = t->v.n; + if (e) /* get length extra bits */ + { + NEEDBITS(8) + n += (unsigned)b & 0xff; + DUMPBITS(8) + } + + /* do the copy */ + s -= n; + do { + n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); + if (u && w <= d) + { + memset(redirSlide + w, 0, e); + w += e; + d += e; + } + else +#ifndef NOMEMCPY + if (w - d >= e) /* (this test assumes unsigned comparison) */ + { + memcpy(redirSlide + w, redirSlide + d, e); + w += e; + d += e; + } + else /* do it slow to avoid memcpy() overlap */ +#endif /* !NOMEMCPY */ + do { + redirSlide[w++] = redirSlide[d++]; + } while (--e); + if (w == WSIZE) + { + flush(&G, redirSlide, (uint32_t)w); + w = u = 0; + } + } while (n); + } + } + + /* flush out redirSlide */ + flush(&G, redirSlide, (uint32_t)w); + if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ + { /* sometimes read one too many: k>>3 compensates */ + /*G.used_csize = G.zsize - G.csize - G.incnt - (k >> 3);*/ + return 5; + } + return 0; +} + + + +static int +explode_nolit8(struct globals *Gp, + struct huft *tl, struct huft *td, int bl, int bd) +/*struct huft *tl, *td;*/ /* length and distance decoder tables */ +/*int bl, bd;*/ /* number of bits decoded by tl[] and td[] */ +/* Decompress the imploded data using uncoded literals and an 8K sliding + window. */ +{ + long s; /* bytes to decompress */ + register unsigned e; /* table entry flag/number of extra bits */ + unsigned n, d; /* length and index for copy */ + unsigned w; /* current window position */ + struct huft *t; /* pointer to table entry */ + unsigned ml, md; /* masks for bl and bd bits */ + register uint32_t b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + unsigned u; /* true if unflushed */ + + + /* explode the coded data */ + b = k = w = 0; /* initialize bit buffer, window */ + u = 1; /* buffer unflushed */ + ml = mask_bits[bl]; /* precompute masks for speed */ + md = mask_bits[bd]; + s = G.ucsize; + while (s > 0) /* do until ucsize bytes uncompressed */ + { + NEEDBITS(1) + if (b & 1) /* then literal--get eight bits */ + { + DUMPBITS(1) + s--; + NEEDBITS(8) + redirSlide[w++] = (uint8_t)b; + if (w == WSIZE) + { + flush(&G, redirSlide, (uint32_t)w); + w = u = 0; + } + DUMPBITS(8) + } + else /* else distance/length */ + { + DUMPBITS(1) + NEEDBITS(7) /* get distance low bits */ + d = (unsigned)b & 0x7f; + DUMPBITS(7) + NEEDBITS((unsigned)bd) /* get coded distance high bits */ + if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + d = w - d - t->v.n; /* construct offset */ + NEEDBITS((unsigned)bl) /* get coded length */ + if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + n = t->v.n; + if (e) /* get length extra bits */ + { + NEEDBITS(8) + n += (unsigned)b & 0xff; + DUMPBITS(8) + } + + /* do the copy */ + s -= n; + do { + n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); + if (u && w <= d) + { + memset(redirSlide + w, 0, e); + w += e; + d += e; + } + else +#ifndef NOMEMCPY + if (w - d >= e) /* (this test assumes unsigned comparison) */ + { + memcpy(redirSlide + w, redirSlide + d, e); + w += e; + d += e; + } + else /* do it slow to avoid memcpy() overlap */ +#endif /* !NOMEMCPY */ + do { + redirSlide[w++] = redirSlide[d++]; + } while (--e); + if (w == WSIZE) + { + flush(&G, redirSlide, (uint32_t)w); + w = u = 0; + } + } while (n); + } + } + + /* flush out redirSlide */ + flush(&G, redirSlide, (uint32_t)w); + if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ + { /* sometimes read one too many: k>>3 compensates */ + /*G.used_csize = G.zsize - G.csize - G.incnt - (k >> 3);*/ + return 5; + } + return 0; +} + + + +static int +explode_nolit4(struct globals *Gp, + struct huft *tl, struct huft *td, int bl, int bd) +/*struct huft *tl, *td;*/ /* length and distance decoder tables */ +/*int bl, bd;*/ /* number of bits decoded by tl[] and td[] */ +/* Decompress the imploded data using uncoded literals and a 4K sliding + window. */ +{ + long s; /* bytes to decompress */ + register unsigned e; /* table entry flag/number of extra bits */ + unsigned n, d; /* length and index for copy */ + unsigned w; /* current window position */ + struct huft *t; /* pointer to table entry */ + unsigned ml, md; /* masks for bl and bd bits */ + register uint32_t b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + unsigned u; /* true if unflushed */ + + + /* explode the coded data */ + b = k = w = 0; /* initialize bit buffer, window */ + u = 1; /* buffer unflushed */ + ml = mask_bits[bl]; /* precompute masks for speed */ + md = mask_bits[bd]; + s = G.ucsize; + while (s > 0) /* do until ucsize bytes uncompressed */ + { + NEEDBITS(1) + if (b & 1) /* then literal--get eight bits */ + { + DUMPBITS(1) + s--; + NEEDBITS(8) + redirSlide[w++] = (uint8_t)b; + if (w == WSIZE) + { + flush(&G, redirSlide, (uint32_t)w); + w = u = 0; + } + DUMPBITS(8) + } + else /* else distance/length */ + { + DUMPBITS(1) + NEEDBITS(6) /* get distance low bits */ + d = (unsigned)b & 0x3f; + DUMPBITS(6) + NEEDBITS((unsigned)bd) /* get coded distance high bits */ + if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + d = w - d - t->v.n; /* construct offset */ + NEEDBITS((unsigned)bl) /* get coded length */ + if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + n = t->v.n; + if (e) /* get length extra bits */ + { + NEEDBITS(8) + n += (unsigned)b & 0xff; + DUMPBITS(8) + } + + /* do the copy */ + s -= n; + do { + n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); + if (u && w <= d) + { + memset(redirSlide + w, 0, e); + w += e; + d += e; + } + else +#ifndef NOMEMCPY + if (w - d >= e) /* (this test assumes unsigned comparison) */ + { + memcpy(redirSlide + w, redirSlide + d, e); + w += e; + d += e; + } + else /* do it slow to avoid memcpy() overlap */ +#endif /* !NOMEMCPY */ + do { + redirSlide[w++] = redirSlide[d++]; + } while (--e); + if (w == WSIZE) + { + flush(&G, redirSlide, (uint32_t)w); + w = u = 0; + } + } while (n); + } + } + + /* flush out redirSlide */ + flush(&G, redirSlide, (uint32_t)w); + if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ + { /* sometimes read one too many: k>>3 compensates */ + /*G.used_csize = G.zsize - G.csize - G.incnt - (k >> 3);*/ + return 5; + } + return 0; +} + +#undef G + +int +zipexplode(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) +/* Explode an imploded compressed stream. Based on the general purpose + bit flag, decide on coded or uncoded literals, and an 8K or 4K sliding + window. Construct the literal (if any), length, and distance codes and + the tables needed to decode them (using huft_build() from inflate.c), + and call the appropriate routine for the type of data in the remainder + of the stream. The four routines are nearly identical, differing only + in whether the literal is decoded or simply read in, and in how many + bits are read in, uncoded, for the low distance bits. */ +{ + struct globals G; + unsigned r; /* return codes */ + struct huft *tb; /* literal code table */ + struct huft *tl; /* length code table */ + struct huft *td; /* distance code table */ + int bb; /* bits for tb */ + int bl; /* bits for tl */ + int bd; /* bits for td */ + unsigned l[256]; /* bit lengths for codes */ + + memset(&G, 0, sizeof G); + G.tgt = tgt; + G.tfd = tfd; + G.doswap = doswap; + G.crc = crc; + G.zsize = G.uzsize = f->f_csize; + G.ucsize = f->f_st.st_size; + + /* Tune base table sizes. Note: I thought that to truly optimize speed, + I would have to select different bl, bd, and bb values for different + compressed file sizes. I was surprised to find out that the values of + 7, 7, and 9 worked best over a very wide range of sizes, except that + bd = 8 worked marginally better for large compressed sizes. */ + bl = 7; + bd = (G.csize + G.incnt) > 200000L ? 8 : 7; + + + /* With literal tree--minimum match length is 3 */ +#ifdef DEBUG + G.hufts = 0; /* initialize huft's malloc'ed */ +#endif + if (f->f_gflag & FG_BIT2) + { + bb = 9; /* base table size for literals */ + if ((r = get_tree(&G, l, 256)) != 0) + goto err; + if ((r = huft_build(l, 256, 256, NULL, NULL, &tb, &bb, + Bits, Nob, Eob)) != 0) + { + if (r == 1) + huft_free(tb); + goto err; + } + if ((r = get_tree(&G, l, 64)) != 0) + goto err; + if ((r = huft_build(l, 64, 0, cplen3, extra, &tl, &bl, + Bits, Nob, Eob)) != 0) + { + if (r == 1) + huft_free(tl); + huft_free(tb); + goto err; + } + if ((r = get_tree(&G, l, 64)) != 0) + goto err; + if (f->f_gflag & FG_BIT1) /* true if 8K */ + { + if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd, + Bits, Nob, Eob)) != 0) + { + if (r == 1) + huft_free(td); + huft_free(tl); + huft_free(tb); + goto err; + } + r = explode_lit8(&G, tb, tl, td, bb, bl, bd); + } + else /* else 4K */ + { + if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd, + Bits, Nob, Eob)) != 0) + { + if (r == 1) + huft_free(td); + huft_free(tl); + huft_free(tb); + goto err; + } + r = explode_lit4(&G, tb, tl, td, bb, bl, bd); + } + huft_free(td); + huft_free(tl); + huft_free(tb); + } + else + + + /* No literal tree--minimum match length is 2 */ + { + if ((r = get_tree(&G, l, 64)) != 0) + goto err; + if ((r = huft_build(l, 64, 0, cplen2, extra, &tl, &bl, + Bits, Nob, Eob)) != 0) + { + if (r == 1) + huft_free(tl); + goto err; + } + if ((r = get_tree(&G, l, 64)) != 0) + goto err; + if (f->f_gflag & FG_BIT1) /* true if 8K */ + { + if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd, + Bits, Nob, Eob)) != 0) + { + if (r == 1) + huft_free(td); + huft_free(tl); + goto err; + } + r = explode_nolit8(&G, tl, td, bl, bd); + } + else /* else 4K */ + { + if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd, + Bits, Nob, Eob)) != 0) + { + if (r == 1) + huft_free(td); + huft_free(tl); + goto err; + } + r = explode_nolit4(&G, tl, td, bl, bd); + } + huft_free(td); + huft_free(tl); + } + Trace((stderr, "<%u > ", G.hufts)); +err: + switch (r) { + case 0: + break; + case 5: + while (G.uzsize > 0) + NEXTBYTE; + /*FALLTHRU*/ + default: + msg(3, 0, "compression error on \"%s\"\n", f->f_name); + } + return r || G.status ? -1 : 0; +} + +/* The following code is derived from: */ + +/* inflate.c -- put in the public domain by Mark Adler + version c16b, 29 March 1998 */ + +/* If BMAX needs to be larger than 16, then h and x[] should be uint32_t. */ +#define BMAX 16 /* maximum bit length of any code (16 for explode) */ +#define N_MAX 288 /* maximum number of codes in any set */ + + +int +huft_build(const unsigned *b, unsigned n, unsigned s, + const uint16_t *d, const uint8_t *e, + struct huft **t, int *m, + int bits, int nob, int eob) +/*const unsigned *b;*/ /* code lengths in bits (all assumed <= BMAX) */ +/*unsigned n;*/ /* number of codes (assumed <= N_MAX) */ +/*unsigned s;*/ /* number of simple-valued codes (0..s-1) */ +/*const uint16_t *d;*/ /* list of base values for non-simple codes */ +/*const uint16_t *e;*/ /* list of extra bits for non-simple codes */ +/*struct huft **t;*/ /* result: starting table */ +/*int *m;*/ /* maximum lookup bits, returns actual */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return zero on success, one if + the given code set is incomplete (the tables are still built in this + case), two if the input is invalid (all zero length codes or an + oversubscribed set of lengths), and three if not enough memory. + The code with value 256 is special, and the tables are constructed + so that no bits beyond that code are fetched when that code is + decoded. */ +{ + unsigned a; /* counter for codes of length k */ + unsigned c[BMAX+1]; /* bit length count table */ + unsigned el; /* length of EOB code (value 256) */ + unsigned f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register unsigned i; /* counter, current code */ + register unsigned j; /* counter */ + register int k; /* number of bits in current code */ + int lx[BMAX+1]; /* memory for l[-1..BMAX-1] */ + int *l = lx+1; /* stack of bits per table */ + register unsigned *p; /* pointer into c[], b[], or v[] */ + register struct huft *q; /* points to current table */ + struct huft r; /* table entry for structure assignment */ + struct huft *u[BMAX]; /* table stack */ + unsigned v[N_MAX]; /* values in order of bit length */ + register int w; /* bits before this table == (l * h) */ + unsigned x[BMAX+1]; /* bit offsets, then code stack */ + unsigned *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + unsigned z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + el = n > 256 ? b[256] : BMAX; /* set length of EOB code, if any */ + memset(c, 0, sizeof c); + p = (unsigned *)b; i = n; + do { + c[*p]++; p++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = NULL; + *m = 0; + return 0; + } + + + /* Find minimum and maximum length, bound *m by those */ + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((unsigned)*m < j) + *m = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((unsigned)*m > i) + *m = i; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return 2; /* bad input: more codes than bits */ + if ((y -= c[i]) < 0) + return 2; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + memset(v, 0, sizeof v); + p = (unsigned *)b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; /* set n to length of v */ + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = l[-1] = 0; /* no bits decoded yet */ + u[0] = NULL; /* just to keep compilers happy */ + q = NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l[h]) + { + w += l[h++]; /* add bits already decoded */ + + /* compute minimum size table less than or equal to *m bits */ + z = (z = g - w) > (unsigned)*m ? *m : z; /* upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + if ((unsigned)w + j > el && (unsigned)w < el) + j = el - w; /* make EOB code end at table */ + z = 1 << j; /* table entries for j-bit table */ + l[h] = j; /* set table size in stack */ + + /* allocate and link in new table */ + if ((q = malloc((z + 1)*sizeof(struct huft))) == NULL) + { + if (h) + huft_free(u[0]); + return 3; /* not enough memory */ + } +#ifdef DEBUG + G.hufts += z + 1; /* track memory usage */ +#endif + *t = q + 1; /* link to list for huft_free() */ + *(t = &(q->v.t)) = NULL; + u[h] = ++q; /* table starts after link */ + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.b = (uint8_t)l[h-1]; /* bits to dump before this table */ + r.e = (uint8_t)(bits + j); /* bits in this table */ + r.v.t = q; /* pointer to this table */ + j = (i & ((1 << w) - 1)) >> (w - l[h-1]); + u[h-1][j] = r; /* connect to last table */ + } + } + + /* set up table entry in r */ + r.b = (uint8_t)(k - w); + if (p >= v + n) + r.e = 99; /* out of values--invalid code */ + else if (*p < s) + { + r.e = (uint8_t)(*p < 256 ? nob : eob); /* 256 is end-of-block code */ + r.v.n = (uint16_t)*p++; /* simple code is just the value */ + } + else + { + r.e = (uint8_t)e[*p - s]; /* non-simple--look up in lists */ + r.v.n = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != x[h]) + w -= l[--h]; /* don't need to update q */ + } + } + + + /* return actual size of base table */ + *m = l[0]; + + + /* Return true (1) if we were given an incomplete table */ + return y != 0 && g != 1; +} + + +void +huft_free(struct huft *t) +/*struct huft *t;*/ /* table to free */ +/* Free the malloc'ed tables built by huft_build(), which makes a linked + list of the tables it made, with the links in a dummy first entry of + each table. */ +{ + register struct huft *p, *q; + + + /* Go through linked list, freeing from the malloced (t[-1]) address. */ + p = t; + while (p != NULL) + { + q = (--p)->v.t; + free(p); + p = q; + } +} + +const uint16_t mask_bits[] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + +void +flush(struct globals *Gp, const void *data, size_t size) +{ + if (Gp->tfd>=0 && write(Gp->tfd, data, size) != size) { + emsg(3, "Cannot write \"%s\"", Gp->tgt); + Gp->tfd = -1; + Gp->status = -1; + } + *Gp->crc = zipcrc(*Gp->crc, data, size); +} + +int +readbyte(struct globals *Gp) +{ + if (Gp->uzsize <= 0) + return EOF; + Gp->incnt = bread((char *)Gp->inbuf, + Gp->uzsize>sizeof Gp->inbuf?sizeof Gp->inbuf:Gp->uzsize); + if (Gp->incnt <= 0) + unexeoa(); + if (Gp->doswap) + swap((char *)Gp->inbuf, Gp->incnt, bflag||sflag,bflag||Sflag); + Gp->uzsize -= Gp->incnt; + Gp->incnt--; + Gp->inptr = Gp->inbuf; + return (int)(*Gp->inptr++); +} diff --git a/package/heirloom-cpio/src/flags.c b/package/heirloom-cpio/src/flags.c new file mode 100644 index 000000000..e06c8e80d --- /dev/null +++ b/package/heirloom-cpio/src/flags.c @@ -0,0 +1,257 @@ +/* + * cpio - copy file archives in and out + * + * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. + */ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +/* Sccsid @(#)flags.c 1.6 (gritter) 3/26/07 */ + +#include +#include +#include +#include + +#include "cpio.h" + +void +flags(int ac, char **av) +{ + const char optstring[] = + "iopaAbBcC:dDeE:fH:I:kKlLmM:O:PrR:sStTuvV6"; + int i, illegal = 0; + + if (getenv("SYSV3") != NULL) + sysv3 = printsev = 1; + while ((i = getopt(ac, av, optstring)) != EOF) { + switch (i) { + case 'i': + case 'o': + case 'p': + if (action && action != i) + illegal = 1; + action = i; + break; + case 'a': + aflag = 1; + break; + case 'A': + Aflag = 1; + break; + case 'b': + bflag = 1; + break; + case 'B': + blksiz = 5120; + Bflag = 1; + break; + case 'c': + fmttype = sysv3 ? FMT_ODC : FMT_ASC; + cflag = 1; + break; + case 'C': + if ((blksiz = atol(optarg)) <= 0) + msg(4, -2, + "Illegal size given for -C option.\n"); + Cflag = 1; + break; + case 'd': + dflag = 1; + break; + case 'D': + Dflag = 1; + break; + case 'e': + /* + * This option is accepted for compatibility only, + * -Hdec should be used instead. + */ + fmttype = FMT_DEC; + eflag = 1; + break; + case 'E': + Eflag = optarg; + break; + case 'f': + fflag = 1; + break; + case 'H': + if (setfmt(optarg) < 0) + illegal = 1; + Hflag = 1; + break; + case 'I': + Iflag = optarg; + break; + case 'k': + kflag = 1; + break; + case 'K': + /* + * This option is accepted for compatibility only, + * -Hsgi should be used instead. + */ + fmttype = FMT_SGIBE; + Kflag = 1; + break; + case 'l': + lflag = 1; + break; + case 'L': + Lflag = 1; + break; + case 'm': + mflag = 1; + break; + case 'M': + Mflag = oneintfmt(optarg); + break; + case 'O': + Oflag = optarg; + break; + case 'P': + Pflag = 1; + break; + case 'r': + rflag = 1; + break; + case 'R': + if (setreassign(Rflag = optarg) < 0) + illegal = 1; + break; + case 's': + sflag = 1; + break; + case 'S': + Sflag = 1; + break; + case 't': + tflag = 1; + break; + case 'u': + uflag = 1; + break; + case 'v': + vflag++; + break; + case 'V': + Vflag = 1; + break; + case '6': + sixflag = 1; + fmttype = FMT_BINLE; + break; + default: + if (sysv3) + usage(); + illegal = 1; + } + } + switch (action) { + case 'i': + if (Oflag || Kflag || eflag || Lflag || lflag || aflag || + Aflag || Pflag) + illegal = 1; + for (i = optind; i < ac; i++) + addg(av[i], 0); + break; + case 'o': + if (Iflag || dflag || fflag || kflag || mflag || + rflag || tflag || uflag || + sixflag || Eflag || Rflag) + illegal = 1; + if (optind != ac) + illegal = 1; + break; + case 'p': + if (Iflag || Oflag || blksiz || Eflag || fmttype != FMT_NONE || + Mflag || bflag || fflag || kflag || sflag || + tflag || Sflag || sixflag) + illegal = 1; + if (optind + 1 != ac) + illegal = 1; + break; + default: + if (sysv3 == 0) + msg(3, 0, "One of -i, -o or -p must be specified.\n"); + else if (ac > 1) + msg(3, -2, "Options must include one: -o, -i, -p.\n"); + illegal = 1; + } + /* + * Sanity checks. No check for multiple occurences of options + * since they can make sense, behave as other programs and use + * the latter one. + */ + /*if (aflag && mflag) { + msg(3, 0, "-a and -m are mutually exclusive.\n"); + illegal = 1; + } why? */ + /*if (cflag && (Hflag || Kflag || eflag)) { + msg(3, 0, "-c and -H are mutually exclusive.\n"); + illegal = 1; + } allow overriding -c with -H and vice versa */ + if ((vflag || tflag) && Vflag) { + msg(3, 0, "-v and -V are mutually exclusive.\n"); + illegal = 1; + } + /*if (Bflag && Cflag) { + msg(3, 0, "-B and -C are mutually exclusive.\n"); + illegal = 1; + } allow overriding of block sizes */ + if ((Hflag || cflag || Kflag || eflag) && sixflag) { + msg(3, 0, "-H and -6 are mutually exclusive.\n"); + illegal = 1; + } + if (!sysv3 && Mflag && Oflag == NULL && Iflag == NULL) { + msg(3, 0, "-M not meaningful without -O or -I.\n"); + illegal = 1; + } + if (!sysv3 && Aflag && Oflag == NULL) { + msg(3, 0, "-A requires the -O option\n"); + illegal = 1; + } + if (illegal) + usage(); +} + +void +usage(void) +{ + if (sysv3) + fprintf(stderr, "\ +Usage: %s -o[acvVABL] [-Csize] [-Hhdr] [-Mmsg] collection\n\ +\t%s -o[acvVABL] -Ocollection [-Csize] [-Hhdr] [-Mmsg] SEGV. + */ +#undef _FILE_OFFSET_BITS +#endif /* !__linux__ */ + +#include +#include +#include +#include +#include + +#if defined (__UCLIBC__) +#include +#include +#define getdents(a, b, c) __getdents64(a, b, c) +#define dirent dirent64 +extern int getdents(int, struct dirent *, size_t); +#elif defined (__GLIBC__) || defined (__FreeBSD__) || defined (_AIX) || \ + defined (__NetBSD__) || defined (__OpenBSD__) || \ + defined (__DragonFly__) || defined (__APPLE__) +#include +#define getdents(a, b, c) getdirentries((a), (char *)(b), (c), &(db->g_offs)) +#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \ + defined (__DragonFly__) || defined (__APPLE__) +#undef d_ino +#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ + || __APPLE__ */ +#elif defined (__dietlibc__) +#include +#include +#else /* !__GLIBC__, !__dietlibc__ */ +#ifdef __hpux +#define _KERNEL +#endif /* __hpux */ +#include +#ifdef __hpux +#ifndef _INO64_T +typedef unsigned long long uint64_t; +typedef uint64_t ino64_t; +#endif /* !_INO64_T */ +#ifdef __LP64__ +#define dirent __dirent64 +#else /* !__LP64__ */ +#define dirent __dirent32 +#endif /* !__LP64__ */ +#define d_reclen __d_reclen +#define d_name __d_name +#define d_ino __d_ino +#endif /* __hpux */ +#endif /* !__GLIBC__, !__dietlibc__ */ + +#include "getdir.h" + +#define DIBSIZE 5120 + +struct getdb { +#if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \ + && !defined (__DragonFly__) && !defined (__APPLE__) + off_t g_offs; +#else /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ + long g_offs; +#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ + struct dirent *g_dirp; + const char *g_path; + struct direc g_dic; + union { + char g_dirbuf[DIBSIZE+1]; + struct dirent g_dummy[1]; + } g_u; + int g_num; + int g_fd; +}; + +struct getdb * +getdb_alloc(const char *path, int fd) +{ + struct getdb *db; + + if ((db = malloc(sizeof *db)) == NULL) + return NULL; + db->g_dirp = NULL; + db->g_offs = 0; + db->g_fd = fd; + db->g_path = path; + return db; +} + +void +getdb_free(struct getdb *db) +{ + free(db); +} + +struct direc * +getdir(struct getdb *db, int *err) +{ + int reclen; + + *err = 0; + while (db->g_dirp == NULL) + { + /*LINTED*/ + db->g_num = getdents(db->g_fd, + (struct dirent *)db->g_u.g_dirbuf, + DIBSIZE); + if (db->g_num <= 0) { + if (db->g_num < 0) + *err = errno; + db->g_offs = 0; + return NULL; + } + /*LINTED*/ + db->g_dirp = (struct dirent *)db->g_u.g_dirbuf; + while (db->g_dirp && +#if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \ + && !defined (__DragonFly__) && !defined (__APPLE__) + db->g_dirp->d_ino == 0 +#else /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ + (db->g_dirp->d_fileno == 0 +#ifdef DT_WHT + || db->g_dirp->d_type == DT_WHT +#endif + ) +#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ + ) + { + next: +#ifndef __DragonFly__ + reclen = db->g_dirp->d_reclen; +#else + reclen = _DIRENT_DIRSIZ(db->g_dirp); +#endif + if ((db->g_num -= reclen) == 0 || reclen == 0) + db->g_dirp = NULL; + else + db->g_dirp = + /*LINTED*/ + (struct dirent *)((char *)db->g_dirp + + reclen); + } + } +#if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \ + && !defined (__DragonFly__) && !defined (__APPLE__) + if (db->g_dirp->d_ino == 0) + goto next; + db->g_dic.d_ino = db->g_dirp->d_ino; +#else /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ + if (db->g_dirp->d_fileno == 0 +#ifdef DT_WHT + || db->g_dirp->d_type == DT_WHT +#endif + ) + { + goto next; + } + db->g_dic.d_ino = db->g_dirp->d_fileno; +#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ + db->g_dic.d_name = db->g_dirp->d_name; +#ifndef __DragonFly__ + reclen = db->g_dirp->d_reclen; +#else + reclen = _DIRENT_DIRSIZ(db->g_dirp); +#endif + if ((db->g_num -= reclen) == 0 || reclen == 0) + db->g_dirp = NULL; + else + /*LINTED*/ + db->g_dirp = (struct dirent *)((char *)db->g_dirp + reclen); + return &(db->g_dic); +} diff --git a/package/heirloom-cpio/src/getdir.h b/package/heirloom-cpio/src/getdir.h new file mode 100644 index 000000000..29d107b6f --- /dev/null +++ b/package/heirloom-cpio/src/getdir.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)getdir.h 1.4 (gritter) 10/19/03 */ + +#include + +struct direc { + unsigned long long d_ino; + char *d_name; +}; + +extern struct getdb *getdb_alloc(const char *, int); +extern void getdb_free(struct getdb *); +extern struct direc *getdir(struct getdb *, int *); diff --git a/package/heirloom-cpio/src/getopt.c b/package/heirloom-cpio/src/getopt.c new file mode 100644 index 000000000..0a68ac8e9 --- /dev/null +++ b/package/heirloom-cpio/src/getopt.c @@ -0,0 +1,141 @@ +/* + * getopt() - command option parsing + * + * Gunnar Ritter, Freiburg i. Br., Germany, March 2002. + */ + +/* Sccsid @(#)getopt.c 1.6 (gritter) 12/16/07 */ + +#include +#include +#include +#include "msgselect.h" + +/* + * One should not think that re-implementing this is necessary, but + * + * - Some libcs print weird messages. + * + * - GNU libc getopt() is totally brain-damaged, as it requires special + * care _not_ to reorder parameters and can't be told to work correctly + * with ':' as first optstring character at all. + */ + +char *optarg = 0; +int optind = 1; +int opterr = 1; +int optopt = 0; +extern char *pfmt_label__; + +static void +error(const char *s, int c) +{ + /* + * Avoid including , in case its getopt() declaration + * conflicts. + */ + extern ssize_t write(int, const void *, size_t); + const char *msg = 0; + char *buf, *bp; + + if (pfmt_label__) + s = pfmt_label__; + switch (c) { + case '?': + msg = ": " msgselect("I","i") "llegal option -- "; + break; + case ':': + msg = ": " msgselect("O","o") "ption requires an argument -- "; + break; + } + bp = buf = alloca(strlen(s) + strlen(msg) + 2); + while (*s) + *bp++ = *s++; + while (*msg) + *bp++ = *msg++; + *bp++ = optopt; + *bp++ = '\n'; + write(2, buf, bp - buf); +} + +int +getopt(int argc, char *const argv[], const char *optstring) +{ + int colon; + static const char *lastp; + const char *curp; + + if (optstring[0] == ':') { + colon = 1; + optstring++; + } else + colon = 0; + if (lastp) { + curp = lastp; + lastp = 0; + } else { + if (optind >= argc || argv[optind] == 0 || + argv[optind][0] != '-' || + argv[optind][1] == '\0') + return -1; + if (argv[optind][1] == '-' && argv[optind][2] == '\0') { + optind++; + return -1; + } + curp = &argv[optind][1]; + } + optopt = curp[0] & 0377; + while (optstring[0]) { + if (optstring[0] == ':') { + optstring++; + continue; + } + if ((optstring[0] & 0377) == optopt) { + if (optstring[1] == ':') { + if (curp[1] != '\0') { + optarg = (char *)&curp[1]; + optind++; + } else { + if ((optind += 2) > argc) { + if (!colon && opterr) + error(argv[0], ':'); + return colon ? ':' : '?'; + } + optarg = argv[optind - 1]; + } + } else { + if (curp[1] != '\0') + lastp = &curp[1]; + else + optind++; + optarg = 0; + } + return optopt; + } + optstring++; + } + if (!colon && opterr) + error(argv[0], '?'); + if (curp[1] != '\0') + lastp = &curp[1]; + else + optind++; + optarg = 0; + return '?'; +} + +#ifdef __APPLE__ +/* + * Starting with Mac OS 10.5 Leopard, turns getopt() + * into getopt$UNIX2003() by default. Consequently, this function + * is called instead of the one defined above. However, optind is + * still taken from this file, so in effect, options are not + * properly handled. Defining an own getopt$UNIX2003() function + * works around this issue. + */ +int +getopt$UNIX2003(int argc, char *const argv[], const char *optstring) +{ + return getopt(argc, argv, optstring); +} +#endif /* __APPLE__ */ diff --git a/package/heirloom-cpio/src/gmatch.c b/package/heirloom-cpio/src/gmatch.c new file mode 100644 index 000000000..a2c5eb7ba --- /dev/null +++ b/package/heirloom-cpio/src/gmatch.c @@ -0,0 +1,136 @@ +/* + * Derived from /usr/src/cmd/sh/expand.c, Unix 7th Edition: + * + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``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 CALDERA INTERNATIONAL, INC. 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. + */ + +#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 +#define USED __attribute__ ((used)) +#elif defined __GNUC__ +#define USED __attribute__ ((unused)) +#else +#define USED +#endif +static const char sccsid[] USED = "@(#)gmatch.sl 1.5 (gritter) 5/29/05"; + +#include +#include +#include + +#include "mbtowi.h" + +#define fetch(wc, s, n) ((mb_cur_max > 1 && *(s) & 0200 ? \ + ((n) = mbtowi(&(wc), (s), mb_cur_max), \ + (n) = ((n) > 0 ? (n) : (n) < 0 ? (wc = WEOF, 1) : 1)) :\ + ((wc) = *(s) & 0377, (n) = 1)), (s) += (n), (wc)) + +int +gmatch(const char *s, const char *p) +{ + const char *bs = s; + int mb_cur_max = MB_CUR_MAX; + wint_t c, scc; + int n; + + if (fetch(scc, s, n) == WEOF) + return (0); + switch (fetch(c, p, n)) { + + case '[': { + int ok = 0, excl; + unsigned long lc = ULONG_MAX; + const char *bp; + + if (*p == '!') { + p++; + excl = 1; + } else + excl = 0; + fetch(c, p, n); + bp = p; + while (c != '\0') { + if (c == ']' && p > bp) + return (ok ^ excl ? gmatch(s, p) : 0); + else if (c == '-' && p > bp && *p != ']') { + if (*p == '\\') + p++; + if (fetch(c, p, n) == '\0') + break; + if (lc <= scc && scc <= c) + ok = 1; + } else { + if (c == '\\') { + if (fetch(c, p, n) == '\0') + break; + } + if (scc == (lc = c)) + ok = 1; + } + fetch(c, p, n); + } + return (0); + } + + case '\\': + fetch(c, p, n); + if (c == '\0') + return (0); + /*FALLTHRU*/ + + default: + if (c != scc) + return (0); + /*FALLTHRU*/ + + case '?': + return (scc ? gmatch(s, p) : 0); + + case '*': + if (*p == '\0') + return (1); + s = bs; + while (*s) { + if (gmatch(s, p)) + return (1); + fetch(scc, s, n); + } + return (0); + + case '\0': + return (scc == '\0'); + + case WEOF: + return (0); + + } +} diff --git a/package/heirloom-cpio/src/ib_alloc.c b/package/heirloom-cpio/src/ib_alloc.c new file mode 100644 index 000000000..4020940ce --- /dev/null +++ b/package/heirloom-cpio/src/ib_alloc.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)ib_alloc.c 1.5 (gritter) 3/12/05 */ + +#include +#include +#include +#include +#include +#include +#include + +#include "memalign.h" +#include "iblok.h" + +struct iblok * +ib_alloc(int fd, unsigned blksize) +{ + static long pagesize; + struct iblok *ip; + struct stat st; + + if (pagesize == 0) + if ((pagesize = sysconf(_SC_PAGESIZE)) < 0) + pagesize = 4096; + if (blksize == 0) { + if (fstat(fd, &st) < 0) + return NULL; + blksize = st.st_blksize > 0 ? st.st_blksize : 512; + } + if ((ip = calloc(1, sizeof *ip)) == NULL) + return NULL; + if ((ip->ib_blk = memalign(pagesize, blksize)) == NULL) { + free(ip); + return NULL; + } + ip->ib_blksize = blksize; + ip->ib_fd = fd; + ip->ib_mb_cur_max = MB_CUR_MAX; + return ip; +} diff --git a/package/heirloom-cpio/src/ib_close.c b/package/heirloom-cpio/src/ib_close.c new file mode 100644 index 000000000..946bb9ef6 --- /dev/null +++ b/package/heirloom-cpio/src/ib_close.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)ib_close.c 1.2 (gritter) 4/17/03 */ + +#include + +#include "iblok.h" + +int +ib_close(struct iblok *ip) +{ + int fd; + + fd = ip->ib_fd; + ib_free(ip); + return close(fd); +} diff --git a/package/heirloom-cpio/src/ib_free.c b/package/heirloom-cpio/src/ib_free.c new file mode 100644 index 000000000..72143afef --- /dev/null +++ b/package/heirloom-cpio/src/ib_free.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)ib_free.c 1.2 (gritter) 4/17/03 */ + +#include + +#include "iblok.h" + +void +ib_free(struct iblok *ip) +{ + free(ip->ib_blk); + free(ip); +} diff --git a/package/heirloom-cpio/src/ib_getlin.c b/package/heirloom-cpio/src/ib_getlin.c new file mode 100644 index 000000000..ddee226b4 --- /dev/null +++ b/package/heirloom-cpio/src/ib_getlin.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)ib_getlin.c 1.2 (gritter) 4/17/03 */ + +#include +#include +#include "iblok.h" + +size_t +ib_getlin(struct iblok *ip, char **line, size_t *alcd, + void *(*reallc)(void *, size_t)) +{ + char *nl; + size_t sz, llen = 0, nllen; + + for (;;) { + if (ip->ib_cur >= ip->ib_end) { + if (ip->ib_incompl) { + ip->ib_incompl = 0; + return 0; + } + if (ib_read(ip) == EOF) { + if (llen) { + ip->ib_incompl++; + (*line)[llen] = '\0'; + return llen; + } else + return 0; + } + /* + * ib_read() advances ib_cur since *ib_cur++ gives + * better performance than *++ib_cur for ib_get(). + * Go back again. + */ + ip->ib_cur--; + } + sz = ip->ib_end - ip->ib_cur; + if ((nl = memchr(ip->ib_cur, '\n', sz)) != NULL) { + sz = nl - ip->ib_cur + 1; + if ((nllen = llen + sz + 1) > *alcd) { + *line = reallc(*line, nllen); + *alcd = nllen; + } + memcpy(&(*line)[llen], ip->ib_cur, sz); + (*line)[llen + sz] = '\0'; + ip->ib_cur = nl + 1; + return llen + sz; + } + if ((nllen = llen + sz + 1) > *alcd) { + *line = reallc(*line, nllen); + *alcd = nllen; + } + memcpy(&(*line)[llen], ip->ib_cur, sz); + llen += sz; + ip->ib_cur = ip->ib_end; + } + /*NOTREACHED*/ + return 0; +} diff --git a/package/heirloom-cpio/src/ib_getw.c b/package/heirloom-cpio/src/ib_getw.c new file mode 100644 index 000000000..b7f2e6762 --- /dev/null +++ b/package/heirloom-cpio/src/ib_getw.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)ib_getw.c 1.5 (gritter) 7/16/04 */ + +#include +#include +#include "iblok.h" +#include "mbtowi.h" + +char * +ib_getw(struct iblok *ip, wint_t *wc, int *len) +{ + size_t rest; + int c, i, n; + + i = 0; + rest = ip->ib_mend - ip->ib_mcur; + if (rest && ip->ib_mcur > ip->ib_mbuf) { + do + ip->ib_mbuf[i] = ip->ib_mcur[i]; + while (i++, --rest); + } else if (ip->ib_incompl) { + ip->ib_incompl = 0; + *wc = WEOF; + ip->ib_mend = ip->ib_mcur = NULL; + return NULL; + } + if (i == 0) { + c = ib_get(ip); + if (c == EOF) { + *wc = WEOF; + ip->ib_mend = ip->ib_mcur = NULL; + return NULL; + } + ip->ib_mbuf[i++] = (char)c; + } + if (ip->ib_mbuf[0] & 0200) { + while (ip->ib_mbuf[i-1] != '\n' && i < ip->ib_mb_cur_max && + ip->ib_incompl == 0) { + c = ib_get(ip); + if (c != EOF) + ip->ib_mbuf[i++] = (char)c; + else + ip->ib_incompl = 1; + } + n = mbtowi(wc, ip->ib_mbuf, i); + if (n < 0) { + *len = 1; + *wc = WEOF; + } else if (n == 0) { + *len = 1; + *wc = '\0'; + } else + *len = n; + } else { + *wc = ip->ib_mbuf[0]; + *len = n = 1; + } + ip->ib_mcur = &ip->ib_mbuf[*len]; + ip->ib_mend = &ip->ib_mcur[i - *len]; + return ip->ib_mbuf; +} diff --git a/package/heirloom-cpio/src/ib_open.c b/package/heirloom-cpio/src/ib_open.c new file mode 100644 index 000000000..18e09c776 --- /dev/null +++ b/package/heirloom-cpio/src/ib_open.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)ib_open.c 1.2 (gritter) 4/17/03 */ + +#include +#include +#include +#include +#include +#include +#include + +#include "iblok.h" + +struct iblok * +ib_open(const char *name, unsigned blksize) +{ + struct iblok *ip; + int fd, err; + + if ((fd = open(name, O_RDONLY)) < 0) + return NULL; + if ((ip = ib_alloc(fd, blksize)) == NULL) { + err = errno; + close(fd); + errno = err; + } + return ip; +} diff --git a/package/heirloom-cpio/src/ib_popen.c b/package/heirloom-cpio/src/ib_popen.c new file mode 100644 index 000000000..9aa873042 --- /dev/null +++ b/package/heirloom-cpio/src/ib_popen.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)ib_popen.c 1.2 (gritter) 4/17/03 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iblok.h" + +struct iblok * +ib_popen(const char *cmd, unsigned blksize) +{ + struct iblok *ip; + int fd[2], err; + pid_t pid; + char *shell; + + if (pipe(fd) < 0) + return NULL; + switch (pid = fork()) { + case -1: + return NULL; + case 0: + close(fd[0]); + dup2(fd[1], 1); + close(fd[1]); + if ((shell = getenv("SHELL")) == NULL) + shell = "/bin/sh"; + execl(shell, shell, "-c", cmd, NULL); + _exit(0177); + /*NOTREACHED*/ + } + close(fd[1]); + if ((ip = ib_alloc(fd[0], blksize)) == NULL) { + err = errno; + close(fd[0]); + errno = err; + } + ip->ib_pid = pid; + return ip; +} + +int +ib_pclose(struct iblok *ip) +{ + struct sigaction oldhup, oldint, oldquit, act; + int status; + + close(ip->ib_fd); + act.sa_handler = SIG_IGN; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGHUP, &act, &oldhup); + sigaction(SIGINT, &act, &oldint); + sigaction(SIGQUIT, &act, &oldquit); + while (waitpid(ip->ib_pid, &status, 0) < 0 && errno == EINTR); + sigaction(SIGHUP, &oldhup, NULL); + sigaction(SIGINT, &oldint, NULL); + sigaction(SIGQUIT, &oldquit, NULL); + return status; +} diff --git a/package/heirloom-cpio/src/ib_read.c b/package/heirloom-cpio/src/ib_read.c new file mode 100644 index 000000000..3794f3e95 --- /dev/null +++ b/package/heirloom-cpio/src/ib_read.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)ib_read.c 1.2 (gritter) 4/17/03 */ + +#include +#include +#include +#include +#include +#include +#include + +#include "iblok.h" + +int +ib_read(struct iblok *ip) +{ + ssize_t sz; + + do { + if ((sz = read(ip->ib_fd, ip->ib_blk, ip->ib_blksize)) > 0) { + ip->ib_endoff += sz; + ip->ib_cur = ip->ib_blk; + ip->ib_end = &ip->ib_blk[sz]; + return *ip->ib_cur++ & 0377; + } + } while (sz < 0 && errno == EINTR); + if (sz < 0) + ip->ib_errno = errno; + ip->ib_cur = ip->ib_end = NULL; + return EOF; +} diff --git a/package/heirloom-cpio/src/ib_seek.c b/package/heirloom-cpio/src/ib_seek.c new file mode 100644 index 000000000..48b2f99bc --- /dev/null +++ b/package/heirloom-cpio/src/ib_seek.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)ib_seek.c 1.4 (gritter) 5/8/03 */ + +#include +#include +#include +#include +#include +#include +#include + +#include "iblok.h" + +off_t +ib_seek(struct iblok *ip, off_t off, int whence) +{ + if (whence == SEEK_CUR) { + off = ip->ib_endoff - (ip->ib_end - ip->ib_cur); + whence = SEEK_SET; + } + if (ip->ib_seekable && whence == SEEK_SET && ip->ib_cur && ip->ib_end && + off < ip->ib_endoff && + off >= ip->ib_endoff - (ip->ib_end - ip->ib_blk)) { + ip->ib_cur = ip->ib_end - (ip->ib_endoff - off); + return off; + } + if ((off = lseek(ip->ib_fd, off, whence)) == (off_t)-1) + return -1; + ip->ib_cur = ip->ib_end = NULL; + ip->ib_endoff = off; + ip->ib_seekable = 1; + return off; +} diff --git a/package/heirloom-cpio/src/iblok.h b/package/heirloom-cpio/src/iblok.h new file mode 100644 index 000000000..66964627f --- /dev/null +++ b/package/heirloom-cpio/src/iblok.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)iblok.h 1.5 (gritter) 7/16/04 */ + +/* + * Functions to read a file sequentially. + */ + +#include /* for off_t, pid_t */ +#include /* for EOF */ +#include /* for wchar_t */ +#include /* for MB_LEN_MAX */ + +struct iblok { + long long ib_endoff; /* offset of endc from start of file */ + char ib_mbuf[MB_LEN_MAX+1]; /* multibyte overflow buffer */ + char *ib_mcur; /* next byte to read in ib_mbuf */ + char *ib_mend; /* one beyond last byte in ib_mbuf */ + char *ib_blk; /* buffered data */ + char *ib_cur; /* next character in ib_blk */ + char *ib_end; /* one beyond last byte in ib_blk */ + int ib_fd; /* input file descriptor */ + int ib_errno; /* errno on error, or 0 */ + int ib_incompl; /* had an incomplete last line */ + int ib_mb_cur_max; /* MB_CUR_MAX at time of ib_alloc() */ + int ib_seekable; /* had a successful lseek() */ + pid_t ib_pid; /* child from ib_popen() */ + unsigned ib_blksize; /* buffer size */ +}; + +/* + * Allocate an input buffer with file descriptor fd. blksize may be + * either the size of a buffer to allocate in ib_blk, or 0 if the + * size is determined automatically. On error, NULL is returned and + * errno indicates the offending error. + */ +extern struct iblok *ib_alloc(int fd, unsigned blksize); + +/* + * Deallocate the passed input buffer. The file descriptor is not + * closed. + */ +extern void ib_free(struct iblok *ip); + +/* + * Open file name and do ib_alloc() on the descriptor. + */ +extern struct iblok *ib_open(const char *name, unsigned blksize); + +/* + * Close the file descriptor in ip and do ib_free(). Return value is + * the result of close(). + */ +extern int ib_close(struct iblok *ip); + +/* + * A workalike of popen(cmd, "r") using iblok facilities. + */ +extern struct iblok *ib_popen(const char *cmd, unsigned blksize); + +/* + * Close an iblok opened with ib_popen(). + */ +extern int ib_pclose(struct iblok *ip); + +/* + * Read new input buffer. Returns the next character (or EOF) and advances + * ib_cur by one above the bottom of the buffer. + */ +extern int ib_read(struct iblok *ip); + +/* + * Get next character. Return EOF at end-of-file or read error. + */ +#define ib_get(ip) ((ip)->ib_cur < (ip)->ib_end ? *(ip)->ib_cur++ & 0377 :\ + ib_read(ip)) + +/* + * Unget a character. Note that this implementation alters the read buffer. + * Caution: Calling this macro more than once might underflow ib_blk. + */ +#define ib_unget(c, ip) (*(--(ip)->ib_cur) = (char)(c)) + +/* + * Get file offset of last read character. + */ +#define ib_offs(ip) ((ip)->ib_endoff - ((ip)->ib_end - (ip)->ib_cur - 1)) + +/* + * Read a wide character using ib_get() facilities. *wc is used to store + * the wide character, or WEOF if an invalid byte sequence was found. + * The number of bytes consumed is stored in *len. Return value is the + * corresponding byte sequence, or NULL at end-of-file in input. + * + * Note that it is not possible to mix calls to ib_getw() with calls to + * ib_get(), ib_unget() or ib_seek() unless the last character read by + * ib_getw() was L'\n'. + */ +extern char *ib_getw(struct iblok *ip, wint_t *wc, int *len); + +/* + * Get a line from ip, returning the line length. Further arguments are either + * the pointer to a malloc()ed buffer and a pointer to its size, or (NULL, 0) + * if ib_getlin() shall allocate the buffer itselves. ib_getlin() will use + * the realloc-style function reallc() to increase the buffer if necessary; + * this function is expected never to fail (i. e., it must longjmp() or abort + * if it cannot allocate a buffer of the demanded size). + * On end-of-file or error, 0 is returned. + */ +extern size_t ib_getlin(struct iblok *ip, char **line, size_t *alcd, + void *(*reallc)(void *, size_t)); + +/* + * Like lseek(). + */ +extern off_t ib_seek(struct iblok *ip, off_t off, int whence); diff --git a/package/heirloom-cpio/src/inflate.c b/package/heirloom-cpio/src/inflate.c new file mode 100644 index 000000000..2c6d3e59f --- /dev/null +++ b/package/heirloom-cpio/src/inflate.c @@ -0,0 +1,991 @@ +/* + * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. + * + * Derived from Info-ZIP 5.50. + * + * Sccsid @(#)inflate.c 1.6 (gritter) 10/13/04 + */ +/* +This is version 2002-Feb-16 of the Info-ZIP copyright and license. +The definitive version of this document should be available at +ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely. + + +Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + +For the purposes of this copyright and license, "Info-ZIP" is defined as +the following set of individuals: + + Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois, + Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris Herborth, Dirk Haase, + Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, David Kirschbaum, + Johnny Lee, Onno van der Linden, Igor Mandrichenko, Steve P. Miller, + Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, Kai Uwe Rommel, + Steve Salisbury, Dave Smith, Christian Spieler, Antoine Verheijen, + Paul von Behren, Rich Wales, Mike White + +This software is provided "as is," without warranty of any kind, express +or implied. In no event shall Info-ZIP or its contributors be held liable +for any direct, indirect, incidental, special or consequential damages +arising out of the use of or inability to use this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright notice, + definition, disclaimer, and this list of conditions. + + 2. Redistributions in binary form (compiled executables) must reproduce + the above copyright notice, definition, disclaimer, and this list of + conditions in documentation and/or other materials provided with the + distribution. The sole exception to this condition is redistribution + of a standard UnZipSFX binary as part of a self-extracting archive; + that is permitted without inclusion of this license, as long as the + normal UnZipSFX banner has not been removed from the binary or disabled. + + 3. Altered versions--including, but not limited to, ports to new operating + systems, existing ports with new graphical interfaces, and dynamic, + shared, or static library versions--must be plainly marked as such + and must not be misrepresented as being the original source. Such + altered versions also must not be misrepresented as being Info-ZIP + releases--including, but not limited to, labeling of the altered + versions with the names "Info-ZIP" (or any variation thereof, including, + but not limited to, different capitalizations), "Pocket UnZip," "WiZ" + or "MacZip" without the explicit permission of Info-ZIP. Such altered + versions are further prohibited from misrepresentative use of the + Zip-Bugs or Info-ZIP e-mail addresses or of the Info-ZIP URL(s). + + 4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip," + "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its + own source and binary releases. +*/ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in unzip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* inflate.c -- by Mark Adler + version c17a, 04 Feb 2001 */ + + +/* Copyright history: + - Starting with UnZip 5.41 of 16-April-2000, this source file + is covered by the Info-Zip LICENSE cited above. + - Prior versions of this source file, found in UnZip source packages + up to UnZip 5.40, were put in the public domain. + The original copyright note by Mark Adler was: + "You can do whatever you like with this source file, + though I would prefer that if you modify it and + redistribute it that you include comments to that effect + with your name and the date. Thank you." + + History: + vers date who what + ---- --------- -------------- ------------------------------------ + a ~~ Feb 92 M. Adler used full (large, one-step) lookup table + b1 21 Mar 92 M. Adler first version with partial lookup tables + b2 21 Mar 92 M. Adler fixed bug in fixed-code blocks + b3 22 Mar 92 M. Adler sped up match copies, cleaned up some + b4 25 Mar 92 M. Adler added prototypes; removed window[] (now + is the responsibility of unzip.h--also + changed name to slide[]), so needs diffs + for unzip.c and unzip.h (this allows + compiling in the small model on MSDOS); + fixed cast of q in huft_build(); + b5 26 Mar 92 M. Adler got rid of unintended macro recursion. + b6 27 Mar 92 M. Adler got rid of nextbyte() routine. fixed + bug in inflate_fixed(). + c1 30 Mar 92 M. Adler removed lbits, dbits environment variables. + changed BMAX to 16 for explode. Removed + OUTB usage, and replaced it with flush()-- + this was a 20% speed improvement! Added + an explode.c (to replace unimplod.c) that + uses the huft routines here. Removed + register union. + c2 4 Apr 92 M. Adler fixed bug for file sizes a multiple of 32k. + c3 10 Apr 92 M. Adler reduced memory of code tables made by + huft_build significantly (factor of two to + three). + c4 15 Apr 92 M. Adler added NOMEMCPY do kill use of memcpy(). + worked around a Turbo C optimization bug. + c5 21 Apr 92 M. Adler added the WSIZE #define to allow reducing + the 32K window size for specialized + applications. + c6 31 May 92 M. Adler added some typecasts to eliminate warnings + c7 27 Jun 92 G. Roelofs added some more typecasts (444: MSC bug). + c8 5 Oct 92 J-l. Gailly added ifdef'd code to deal with PKZIP bug. + c9 9 Oct 92 M. Adler removed a memory error message (~line 416). + c10 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch, + removed old inflate, renamed inflate_entry + to inflate, added Mark's fix to a comment. + c10.5 14 Dec 92 M. Adler fix up error messages for incomplete trees. + c11 2 Jan 93 M. Adler fixed bug in detection of incomplete + tables, and removed assumption that EOB is + the longest code (bad assumption). + c12 3 Jan 93 M. Adler make tables for fixed blocks only once. + c13 5 Jan 93 M. Adler allow all zero length codes (pkzip 2.04c + outputs one zero length code for an empty + distance tree). + c14 12 Mar 93 M. Adler made inflate.c standalone with the + introduction of inflate.h. + c14b 16 Jul 93 G. Roelofs added (unsigned) typecast to w at 470. + c14c 19 Jul 93 J. Bush changed v[N_MAX], l[288], ll[28x+3x] arrays + to static for Amiga. + c14d 13 Aug 93 J-l. Gailly de-complicatified Mark's c[*p++]++ thing. + c14e 8 Oct 93 G. Roelofs changed memset() to memzero(). + c14f 22 Oct 93 G. Roelofs renamed quietflg to qflag; made Trace() + conditional; added inflate_free(). + c14g 28 Oct 93 G. Roelofs changed l/(lx+1) macro to pointer (Cray bug) + c14h 7 Dec 93 C. Ghisler huft_build() optimizations. + c14i 9 Jan 94 A. Verheijen set fixed_t{d,l} to NULL after freeing; + G. Roelofs check NEXTBYTE macro for EOF. + c14j 23 Jan 94 G. Roelofs removed Ghisler "optimizations"; ifdef'd + EOF check. + c14k 27 Feb 94 G. Roelofs added some typecasts to avoid warnings. + c14l 9 Apr 94 G. Roelofs fixed split comments on preprocessor lines + to avoid bug in Encore compiler. + c14m 7 Jul 94 P. Kienitz modified to allow assembler version of + inflate_codes() (define ASM_INFLATECODES) + c14n 22 Jul 94 G. Roelofs changed fprintf to macro for DLL versions + c14o 23 Aug 94 C. Spieler added a newline to a debug statement; + G. Roelofs added another typecast to avoid MSC warning + c14p 4 Oct 94 G. Roelofs added (voidp *) cast to free() argument + c14q 30 Oct 94 G. Roelofs changed fprintf macro to MESSAGE() + c14r 1 Nov 94 G. Roelofs fixed possible redefinition of CHECK_EOF + c14s 7 May 95 S. Maxwell OS/2 DLL globals stuff incorporated; + P. Kienitz "fixed" ASM_INFLATECODES macro/prototype + c14t 18 Aug 95 G. Roelofs added UZinflate() to use zlib functions; + changed voidp to zvoid; moved huft_build() + and huft_free() to end of file + c14u 1 Oct 95 G. Roelofs moved G into definition of MESSAGE macro + c14v 8 Nov 95 P. Kienitz changed ASM_INFLATECODES to use a regular + call with __G__ instead of a macro + c15 3 Aug 96 M. Adler fixed bomb-bug on random input data (Adobe) + c15b 24 Aug 96 M. Adler more fixes for random input data + c15c 28 Mar 97 G. Roelofs changed USE_ZLIB fatal exit code from + PK_MEM2 to PK_MEM3 + c16 20 Apr 97 J. Altman added memzero(v[]) in huft_build() + c16b 29 Mar 98 C. Spieler modified DLL code for slide redirection + c16c 04 Apr 99 C. Spieler fixed memory leaks when processing gets + stopped because of input data errors + c16d 05 Jul 99 C. Spieler take care of FLUSH() return values and + stop processing in case of errors + c17 31 Dec 00 C. Spieler added preliminary support for Deflate64 + c17a 04 Feb 01 C. Spieler complete integration of Deflate64 support + c17b 16 Feb 02 C. Spieler changed type of "extra bits" arrays and + corresponding huft_buid() parameter e from + ush into uch, to save space + */ + + +/* + Inflate deflated (PKZIP's method 8 compressed) data. The compression + method searches for as much of the current string of bytes (up to a + length of 258) in the previous 32K bytes. If it doesn't find any + matches (of at least length 3), it codes the next byte. Otherwise, it + codes the length of the matched string and its distance backwards from + the current position. There is a single Huffman code that codes both + single bytes (called "literals") and match lengths. A second Huffman + code codes the distance information, which follows a length code. Each + length or distance code actually represents a base value and a number + of "extra" (sometimes zero) bits to get to add to the base value. At + the end of each deflated block is a special end-of-block (EOB) literal/ + length code. The decoding process is basically: get a literal/length + code; if EOB then done; if a literal, emit the decoded byte; if a + length then get the distance and emit the referred-to bytes from the + sliding window of previously emitted data. + + There are (currently) three kinds of inflate blocks: stored, fixed, and + dynamic. The compressor outputs a chunk of data at a time and decides + which method to use on a chunk-by-chunk basis. A chunk might typically + be 32K to 64K, uncompressed. If the chunk is uncompressible, then the + "stored" method is used. In this case, the bytes are simply stored as + is, eight bits per byte, with none of the above coding. The bytes are + preceded by a count, since there is no longer an EOB code. + + If the data are compressible, then either the fixed or dynamic methods + are used. In the dynamic method, the compressed data are preceded by + an encoding of the literal/length and distance Huffman codes that are + to be used to decode this block. The representation is itself Huffman + coded, and so is preceded by a description of that code. These code + descriptions take up a little space, and so for small blocks, there is + a predefined set of codes, called the fixed codes. The fixed method is + used if the block ends up smaller that way (usually for quite small + chunks); otherwise the dynamic method is used. In the latter case, the + codes are customized to the probabilities in the current block and so + can code it much better than the pre-determined fixed codes can. + + The Huffman codes themselves are decoded using a multi-level table + lookup, in order to maximize the speed of decoding plus the speed of + building the decoding tables. See the comments below that precede the + lbits and dbits tuning parameters. + + GRR: return values(?) + 0 OK + 1 incomplete table + 2 bad input + 3 not enough memory + the following return codes are passed through from FLUSH() errors + 50 (PK_DISK) "overflow of output space" + 80 (IZ_CTRLC) "canceled by user's request" + */ + + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + 14. The Deflate64 (PKZIP method 9) variant of the compression algorithm + differs from "classic" deflate in the following 3 aspect: + a) The size of the sliding history window is expanded to 64 kByte. + b) The previously unused distance codes #30 and #31 code distances + from 32769 to 49152 and 49153 to 65536. Both codes take 14 bits + of extra data to determine the exact position in their 16 kByte + range. + c) The last lit/length code #285 gets a different meaning. Instead + of coding a fixed maximum match length of 258, it is used as a + "generic" match length code, capable of coding any length from + 3 (min match length + 0) to 65538 (min match length + 65535). + This means that the length code #285 takes 16 bits (!) of uncoded + extra data, added to a fixed min length of 3. + Changes a) and b) would have been transparent for valid deflated + data, but change c) requires to switch decoder configurations between + Deflate and Deflate64 modes. + */ + +#include +#include +#include +#include "cpio.h" +#include "unzip.h" + +/* + inflate.h must supply the uch slide[WSIZE] array, the zvoid typedef + (void if (void *) is accepted, else char) and the NEXTBYTE, + FLUSH() and memzero macros. If the window size is not 32K, it + should also define WSIZE. If INFMOD is defined, it can include + compiled functions to support the NEXTBYTE and/or FLUSH() macros. + There are defaults for NEXTBYTE and FLUSH() below for use as + examples of what those functions need to do. Normally, you would + also want FLUSH() to compute a crc on the data. inflate.h also + needs to provide these typedefs: + + typedef unsigned char uch; + typedef unsigned short ush; + typedef unsigned long ulg; + + This module uses the external functions malloc() and free() (and + probably memset() or bzero() in the memzero() macro). Their + prototypes are normally found in and . + */ + +/* marker for "unused" huft code, and corresponding check macro */ +#define INVALID_CODE 99 +#define IS_INVALID_CODE(c) ((c) == INVALID_CODE) + +static int inflate_codes(struct globals *Gp, + struct huft *tl, struct huft *td, + int bl, int bd); +static int inflate_stored(struct globals *Gp); +static int inflate_fixed(struct globals *Gp); +static int inflate_dynamic(struct globals *Gp); +static int inflate_block(struct globals *Gp, int *e); + +#define FLUSH(n) (flush(&G, redirSlide, (n)), 0) + +/* The inflate algorithm uses a sliding 32K byte window on the uncompressed + stream to find repeated byte strings. This is implemented here as a + circular buffer. The index is updated simply by incrementing and then + and'ing with 0x7fff (32K-1). */ +/* It is left to other modules to supply the 32K area. It is assumed + to be usable as if it were declared "uch slide[32768];" or as just + "uch *slide;" and then malloc'ed in the latter case. The definition + must be in unzip.h, included above. */ + + +/* Tables for deflate from PKZIP's appnote.txt. */ +/* - Order of the bit length code lengths */ +static const unsigned border[] = { + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* - Copy lengths for literal codes 257..285 */ +static const uint16_t cplens64[] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 3, 0, 0}; + /* For Deflate64, the code 285 is defined differently. */ +static const uint16_t cplens32[] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* note: see note #13 above about the 258 in this list. */ +/* - Extra bits for literal codes 257..285 */ +static const uint8_t cplext64[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16, INVALID_CODE, INVALID_CODE}; +static const uint8_t cplext32[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, INVALID_CODE, INVALID_CODE}; + +/* - Copy offsets for distance codes 0..29 (0..31 for Deflate64) */ +static const uint16_t cpdist[] = { + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 32769, 49153}; + +/* - Extra bits for distance codes 0..29 (0..31 for Deflate64) */ +static const uint8_t cpdext64[] = { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13, 14, 14}; +static const uint8_t cpdext32[] = { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13, INVALID_CODE, INVALID_CODE}; + +# define MAXLITLENS 288 +# define MAXDISTS 32 + +/* Macros for inflate() bit peeking and grabbing. + The usage is: + + NEEDBITS(j) + x = b & mask_bits[j]; + DUMPBITS(j) + + where NEEDBITS makes sure that b has at least j bits in it, and + DUMPBITS removes the bits from b. The macros use the variable k + for the number of bits in b. Normally, b and k are register + variables for speed and are initialized at the begining of a + routine that uses these macros from a global bit buffer and count. + + In order to not ask for more bits than there are in the compressed + stream, the Huffman tables are constructed to only ask for just + enough bits to make up the end-of-block code (value 256). Then no + bytes need to be "returned" to the buffer at the end of the last + block. See the huft_build() routine. + */ + +# define NEEDBITS(n) {while(k<(n)){int c=NEXTBYTE;\ + if(c==EOF){retval=1;goto cleanup_and_exit;}\ + b|=((uint32_t)c)<>=(n);k-=(n);} + +#define Bits 32 +#define Nob 32 +#define Eob 31 + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + are not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +static const int lbits = 9; /* bits in base literal/length lookup table */ +static const int dbits = 6; /* bits in base distance lookup table */ + +#define G (*Gp) + +static int +inflate_codes(struct globals *Gp, + struct huft *tl, struct huft *td, int bl, int bd) +/*struct huft *tl, *td;*/ /* literal/length and distance decoder tables */ +/*int bl, bd;*/ /* number of bits decoded by tl[] and td[] */ +/* inflate (decompress) the codes in a deflated (compressed) block. + Return an error code or zero if it all goes ok. */ +{ + register unsigned e; /* table entry flag/number of extra bits */ + unsigned d; /* index for copy */ + uint32_t n; /* length for copy (deflate64: might be 64k+2) */ + uint32_t w; /* current window position (deflate64: up to 64k) */ + struct huft *t; /* pointer to table entry */ + unsigned ml, md; /* masks for bl and bd bits */ + register uint32_t b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + int retval = 0; /* error code returned: initialized to "no error" */ + + + /* make local copies of globals */ + b = G.bb; /* initialize bit buffer */ + k = G.bk; + w = G.wp; /* initialize window position */ + + + /* inflate the coded data */ + ml = mask_bits[bl]; /* precompute masks for speed */ + md = mask_bits[bd]; + while (1) /* do until end of block */ + { + NEEDBITS((unsigned)bl) + t = tl + ((unsigned)b & ml); + while (1) { + DUMPBITS(t->b) + + if ((e = t->e) == 32) /* then it's a literal */ + { + redirSlide[w++] = (uint8_t)t->v.n; + if (w == WSIZE) + { + if ((retval = FLUSH(w)) != 0) goto cleanup_and_exit; + w = 0; + } + break; + } + + if (e < 31) /* then it's a length */ + { + /* get length of block to copy */ + NEEDBITS(e) + n = t->v.n + ((unsigned)b & mask_bits[e]); + DUMPBITS(e) + + /* decode distance of block to copy */ + NEEDBITS((unsigned)bd) + t = td + ((unsigned)b & md); + while (1) { + DUMPBITS(t->b) + if ((e = t->e) < 32) + break; + if (IS_INVALID_CODE(e)) + return 1; + e &= 31; + NEEDBITS(e) + t = t->v.t + ((unsigned)b & mask_bits[e]); + } + NEEDBITS(e) + d = (unsigned)w - t->v.n - ((unsigned)b & mask_bits[e]); + DUMPBITS(e) + + /* do the copy */ + do { + e = (unsigned)(WSIZE - + ((d &= (unsigned)(WSIZE-1)) > (unsigned)w ? + (uint32_t)d : w)); + if ((uint32_t)e > n) e = (unsigned)n; + n -= e; +#ifndef NOMEMCPY + if ((unsigned)w - d >= e) + /* (this test assumes unsigned comparison) */ + { + memcpy(redirSlide + (unsigned)w, redirSlide + d, e); + w += e; + d += e; + } + else /* do it slowly to avoid memcpy() overlap */ +#endif /* !NOMEMCPY */ + do { + redirSlide[w++] = redirSlide[d++]; + } while (--e); + if (w == WSIZE) + { + if ((retval = FLUSH(w)) != 0) goto cleanup_and_exit; + w = 0; + } + } while (n); + break; + } + + if (e == 31) /* it's the EOB signal */ + { + /* sorry for this goto, but we have to exit two loops at once */ + goto cleanup_decode; + } + + if (IS_INVALID_CODE(e)) + return 1; + + e &= 31; + NEEDBITS(e) + t = t->v.t + ((unsigned)b & mask_bits[e]); + } + } +cleanup_decode: + + /* restore the globals from the locals */ + G.wp = (unsigned)w; /* restore global window pointer */ + G.bb = b; /* restore global bit buffer */ + G.bk = k; + + +cleanup_and_exit: + /* done */ + return retval; +} + +static int +inflate_stored(struct globals *Gp) +/* "decompress" an inflated type 0 (stored) block. */ +{ + uint32_t w; /* current window position (deflate64: up to 64k!) */ + unsigned n; /* number of bytes in block */ + register uint32_t b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + int retval = 0; /* error code returned: initialized to "no error" */ + + + /* make local copies of globals */ + Trace((stderr, "\nstored block")); + b = G.bb; /* initialize bit buffer */ + k = G.bk; + w = G.wp; /* initialize window position */ + + + /* go to byte boundary */ + n = k & 7; + DUMPBITS(n); + + + /* get the length and its complement */ + NEEDBITS(16) + n = ((unsigned)b & 0xffff); + DUMPBITS(16) + NEEDBITS(16) + if (n != (unsigned)((~b) & 0xffff)) + return 1; /* error in compressed data */ + DUMPBITS(16) + + + /* read and output the compressed data */ + while (n--) + { + NEEDBITS(8) + redirSlide[w++] = (uint8_t)b; + if (w == WSIZE) + { + if ((retval = FLUSH(w)) != 0) goto cleanup_and_exit; + w = 0; + } + DUMPBITS(8) + } + + + /* restore the globals from the locals */ + G.wp = (unsigned)w; /* restore global window pointer */ + G.bb = b; /* restore global bit buffer */ + G.bk = k; + +cleanup_and_exit: + return retval; +} + + +static int +inflate_fixed(struct globals *Gp) +/* decompress an inflated type 1 (fixed Huffman codes) block. We should + either replace this with a custom decoder, or at least precompute the + Huffman tables. */ +{ + /* if first time, set up tables for fixed blocks */ + Trace((stderr, "\nliteral block")); + if (G.fixed_tl == NULL) + { + int i; /* temporary variable */ + unsigned l[288]; /* length list for huft_build */ + + /* literal table */ + for (i = 0; i < 144; i++) + l[i] = 8; + for (; i < 256; i++) + l[i] = 9; + for (; i < 280; i++) + l[i] = 7; + for (; i < 288; i++) /* make a complete, but wrong code set */ + l[i] = 8; + G.fixed_bl = 7; + if ((i = huft_build(l, 288, 257, G.cplens, G.cplext, + &G.fixed_tl, &G.fixed_bl, + Bits, Nob, Eob)) != 0) + { + G.fixed_tl = NULL; + return i; + } + + /* distance table */ + for (i = 0; i < MAXDISTS; i++) /* make an incomplete code set */ + l[i] = 5; + G.fixed_bd = 5; + if ((i = huft_build(l, MAXDISTS, 0, cpdist, G.cpdext, + &G.fixed_td, &G.fixed_bd, + Bits, Nob, Eob)) > 1) + { + huft_free(G.fixed_tl); + G.fixed_td = G.fixed_tl = NULL; + return i; + } + } + + /* decompress until an end-of-block code */ + return inflate_codes(&G, G.fixed_tl, G.fixed_td, + G.fixed_bl, G.fixed_bd); +} + + + +static int inflate_dynamic(struct globals *Gp) +/* decompress an inflated type 2 (dynamic Huffman codes) block. */ +{ + int i; /* temporary variables */ + unsigned j; + unsigned l; /* last length */ + unsigned m; /* mask for bit lengths table */ + unsigned n; /* number of lengths to get */ + struct huft *tl; /* literal/length code table */ + struct huft *td; /* distance code table */ + int bl; /* lookup bits for tl */ + int bd; /* lookup bits for td */ + unsigned nb; /* number of bit length codes */ + unsigned nl; /* number of literal/length codes */ + unsigned nd; /* number of distance codes */ + unsigned ll[MAXLITLENS+MAXDISTS]; /* lit./length and distance code lengths */ + register uint32_t b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + int retval = 0; /* error code returned: initialized to "no error" */ + + + /* make local bit buffer */ + Trace((stderr, "\ndynamic block")); + b = G.bb; + k = G.bk; + + + /* read in table lengths */ + NEEDBITS(5) + nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */ + DUMPBITS(5) + NEEDBITS(5) + nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */ + DUMPBITS(5) + NEEDBITS(4) + nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */ + DUMPBITS(4) + if (nl > MAXLITLENS || nd > MAXDISTS) + return 1; /* bad lengths */ + + + /* read in bit-length-code lengths */ + for (j = 0; j < nb; j++) + { + NEEDBITS(3) + ll[border[j]] = (unsigned)b & 7; + DUMPBITS(3) + } + for (; j < 19; j++) + ll[border[j]] = 0; + + + /* build decoding table for trees--single level, 7 bit lookup */ + bl = 7; + retval = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl, + Bits, Nob, Eob); + if (bl == 0) /* no bit lengths */ + retval = 1; + if (retval) + { + if (retval == 1) + huft_free(tl); + return retval; /* incomplete code set */ + } + + + /* read in literal and distance code lengths */ + n = nl + nd; + m = mask_bits[bl]; + i = l = 0; + while ((unsigned)i < n) + { + NEEDBITS((unsigned)bl) + j = (td = tl + ((unsigned)b & m))->b; + DUMPBITS(j) + j = td->v.n; + if (j < 16) /* length of code in bits (0..15) */ + ll[i++] = l = j; /* save last length in l */ + else if (j == 16) /* repeat last length 3 to 6 times */ + { + NEEDBITS(2) + j = 3 + ((unsigned)b & 3); + DUMPBITS(2) + if ((unsigned)i + j > n) + return 1; + while (j--) + ll[i++] = l; + } + else if (j == 17) /* 3 to 10 zero length codes */ + { + NEEDBITS(3) + j = 3 + ((unsigned)b & 7); + DUMPBITS(3) + if ((unsigned)i + j > n) + return 1; + while (j--) + ll[i++] = 0; + l = 0; + } + else /* j == 18: 11 to 138 zero length codes */ + { + NEEDBITS(7) + j = 11 + ((unsigned)b & 0x7f); + DUMPBITS(7) + if ((unsigned)i + j > n) + return 1; + while (j--) + ll[i++] = 0; + l = 0; + } + } + + + /* free decoding table for trees */ + huft_free(tl); + + + /* restore the global bit buffer */ + G.bb = b; + G.bk = k; + + + /* build the decoding tables for literal/length and distance codes */ + bl = lbits; + retval = huft_build(ll, nl, 257, G.cplens, G.cplext, &tl, &bl, + Bits, Nob, Eob); + if (bl == 0) /* no literals or lengths */ + retval = 1; + if (retval) + { + if (retval == 1) { + /*if (!uO.qflag) + MESSAGE((uint8_t *)"(incomplete l-tree) ", 21L, 1);*/ + huft_free(tl); + } + return retval; /* incomplete code set */ + } + bd = dbits; + retval = huft_build(ll + nl, nd, 0, cpdist, G.cpdext, &td, &bd, + Bits, Nob, Eob); + if (retval == 1) + retval = 0; + if (bd == 0 && nl > 257) /* lengths but no distances */ + retval = 1; + if (retval) + { + if (retval == 1) { + /*if (!uO.qflag) + MESSAGE((uint8_t *)"(incomplete d-tree) ", 21L, 1);*/ + huft_free(td); + } + huft_free(tl); + return retval; + } + + /* decompress until an end-of-block code */ + retval = inflate_codes(&G, tl, td, bl, bd); + +cleanup_and_exit: + /* free the decoding tables, return */ + huft_free(tl); + huft_free(td); + return retval; +} + + + +static int inflate_block(struct globals *Gp, int *e) +/*int *e;*/ /* last block flag */ +/* decompress an inflated block */ +{ + unsigned t; /* block type */ + register uint32_t b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + int retval = 0; /* error code returned: initialized to "no error" */ + + + /* make local bit buffer */ + b = G.bb; + k = G.bk; + + + /* read in last block bit */ + NEEDBITS(1) + *e = (int)b & 1; + DUMPBITS(1) + + + /* read in block type */ + NEEDBITS(2) + t = (unsigned)b & 3; + DUMPBITS(2) + + + /* restore the global bit buffer */ + G.bb = b; + G.bk = k; + + + /* inflate that block type */ + if (t == 2) + return inflate_dynamic(&G); + if (t == 0) + return inflate_stored(&G); + if (t == 1) + return inflate_fixed(&G); + + + /* bad block type */ + retval = 2; + +cleanup_and_exit: + return retval; +} + +#undef G + +int +zipinflate(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) +/* decompress an inflated entry */ +{ + struct globals G; + int e = 0; /* last block flag */ + int r; /* result code */ + int is_defl64; +#ifdef DEBUG + unsigned h = 0; /* maximum struct huft's malloc'ed */ +#endif + + is_defl64 = f->f_cmethod == C_ENHDEFLD; + memset(&G, 0, sizeof G); + G.tgt = tgt; + G.tfd = tfd; + G.doswap = doswap; + G.crc = crc; + G.zsize = G.uzsize = f->f_csize; + G.ucsize = f->f_st.st_size; + /* initialize window, bit buffer */ + G.wp = 0; + G.bk = 0; + G.bb = 0; + + if (is_defl64) { + G.cplens = cplens64; + G.cplext = cplext64; + G.cpdext = cpdext64; + G.fixed_tl = G.fixed_tl64; + G.fixed_bl = G.fixed_bl64; + G.fixed_td = G.fixed_td64; + G.fixed_bd = G.fixed_bd64; + } else { + G.cplens = cplens32; + G.cplext = cplext32; + G.cpdext = cpdext32; + G.fixed_tl = G.fixed_tl32; + G.fixed_bl = G.fixed_bl32; + G.fixed_td = G.fixed_td32; + G.fixed_bd = G.fixed_bd32; + } + + /* decompress until the last block */ + do { +#ifdef DEBUG + G.hufts = 0; +#endif + if ((r = inflate_block(&G, &e)) != 0) { + if ((f->f_gflag & FG_DESC) == 0) + while (G.uzsize > 0) + NEXTBYTE; + msg(3, 0, "compression error on \"%s\"\n", f->f_name); + return -1; + } +#ifdef DEBUG + if (G.hufts > h) + h = G.hufts; +#endif + } while (!e); + + Trace((stderr, "\n%u bytes in Huffman tables (%u/entry)\n", + h * (unsigned)sizeof(struct huft), (unsigned)sizeof(struct huft))); + + if (is_defl64) { + G.fixed_tl64 = G.fixed_tl; + G.fixed_bl64 = G.fixed_bl; + G.fixed_td64 = G.fixed_td; + G.fixed_bd64 = G.fixed_bd; + } else { + G.fixed_tl32 = G.fixed_tl; + G.fixed_bl32 = G.fixed_bl; + G.fixed_td32 = G.fixed_td; + G.fixed_bd32 = G.fixed_bd; + } + + /* flush out redirSlide and return (success, unless final FLUSH failed) */ + (FLUSH(G.wp)); + if (f->f_gflag & FG_DESC) + bunread((char *)G.inptr, G.incnt); + return G.status; +} diff --git a/package/heirloom-cpio/src/mbtowi.h b/package/heirloom-cpio/src/mbtowi.h new file mode 100644 index 000000000..525ad08d1 --- /dev/null +++ b/package/heirloom-cpio/src/mbtowi.h @@ -0,0 +1,22 @@ +/* Sccsid @(#)mbtowi.h 1.2 (gritter) 7/16/04 */ + +#ifndef LIBCOMMON_MBTOWI_H +#define LIBCOMMON_MBTOWI_H + +static +#if defined (__GNUC__) || defined (__USLC__) || defined (__INTEL_COMPILER) || \ + defined (__IBMC__) || defined (__SUNPRO_C) + inline +#endif + int +mbtowi(wint_t *pwi, const char *s, size_t n) +{ + wchar_t wc; + int i; + + i = mbtowc(&wc, s, n); + *pwi = wc; + return i; +} + +#endif /* !LIBCOMMON_MBTOWI_H */ diff --git a/package/heirloom-cpio/src/memalign.c b/package/heirloom-cpio/src/memalign.c new file mode 100644 index 000000000..268949b20 --- /dev/null +++ b/package/heirloom-cpio/src/memalign.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)memalign.c 1.7 (gritter) 1/22/06 */ + +#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (_AIX) || \ + defined (__NetBSD__) || defined (__OpenBSD__) || \ + defined (__DragonFly__) || defined (__APPLE__) +/* + * FreeBSD malloc(3) promises to page-align the return of malloc() calls + * if size is at least a page. This serves for a poor man's memalign() + * implementation that matches our needs. + */ +#include +#include + +#include "memalign.h" + +void * +memalign(size_t alignment, size_t size) +{ + static long pagesize; + + if (pagesize == 0) + pagesize = sysconf(_SC_PAGESIZE); + if (alignment != pagesize) + return NULL; + if (size < pagesize) + size = pagesize; + return malloc(size); +} +#endif /* __FreeBSD__ || __dietlibc__ || _AIX || __NetBSD__ || __OpenBSD__ || + __DragonFly__ || __APPLE__ */ diff --git a/package/heirloom-cpio/src/memalign.h b/package/heirloom-cpio/src/memalign.h new file mode 100644 index 000000000..edaef031b --- /dev/null +++ b/package/heirloom-cpio/src/memalign.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)memalign.h 1.7 (gritter) 1/22/06 */ + +#ifndef LIBCOMMON_MEMALIGN_H +#define LIBCOMMON_MEMALIGN_H + +#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (_AIX) || \ + defined (__NetBSD__) || defined (__OpenBSD__) || \ + defined (__DragonFly__) || defined (__APPLE__) +#include + +extern void *memalign(size_t, size_t); +#endif /* __FreeBSD__ || __dietlibc__ || _AIX || __NetBSD__ || __OpenBSD__ || + __DragonFly__ || __APPLE__ */ +#endif /* !LIBCOMMON_MEMALIGN_H */ diff --git a/package/heirloom-cpio/src/msgselect.h b/package/heirloom-cpio/src/msgselect.h new file mode 100644 index 000000000..94a5daa9f --- /dev/null +++ b/package/heirloom-cpio/src/msgselect.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)msgselect.h 1.2 (gritter) 9/21/03 */ + +#define MSG_LEVEL 0 + +#if MSG_LEVEL == 1 +#define msgselect(a, b) a +#else +#define msgselect(a, b) b +#endif diff --git a/package/heirloom-cpio/src/nonpax.c b/package/heirloom-cpio/src/nonpax.c new file mode 100644 index 000000000..d0eb585b7 --- /dev/null +++ b/package/heirloom-cpio/src/nonpax.c @@ -0,0 +1,55 @@ +/* + * cpio - copy file archives in and out + * + * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. + */ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +/* Sccsid @(#)nonpax.c 1.1 (gritter) 2/24/04 */ + +#include "cpio.h" + +/*ARGSUSED*/ +int +pax_track(const char *name, time_t mtime) +{ + return 1; +} + +/*ARGSUSED*/ +void +pax_prlink(struct file *f) +{ +} + +/*ARGSUSED*/ +int +pax_sname(char **oldp, size_t *olds) +{ + return 1; +} + +void +pax_onexit(void) +{ +} diff --git a/package/heirloom-cpio/src/oblok.c b/package/heirloom-cpio/src/oblok.c new file mode 100644 index 000000000..38859ba6d --- /dev/null +++ b/package/heirloom-cpio/src/oblok.c @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)oblok.c 1.7 (gritter) 7/16/04 */ + +#include +#include +#include +#include +#include +#include +#include + +#include "memalign.h" +#include "oblok.h" + +struct list { + struct list *l_nxt; + struct oblok *l_op; +}; + +static struct list *bloks; +static int exitset; + +int +ob_clear(void) +{ + struct list *lp; + int val = 0; + + for (lp = bloks; lp; lp = lp->l_nxt) { + if (ob_flush(lp->l_op) < 0) + val = -1; + else if (val >= 0) + val++; + } + return val; +} + +static void +add(struct oblok *op) +{ + struct list *lp, *lq; + + if ((lp = calloc(1, sizeof *lp)) != NULL) { + lp->l_nxt = NULL; + lp->l_op = op; + if (bloks) { + for (lq = bloks; lq->l_nxt; lq = lq->l_nxt); + lq->l_nxt = lp; + } else + bloks = lp; + if (exitset == 0) { + exitset = 1; + atexit((void (*)(void))ob_clear); + } + } +} + +static void +del(struct oblok *op) +{ + struct list *lp, *lq = NULL; + + if (bloks) { + for (lp = bloks; lp && lp->l_op != op; lp = lp->l_nxt) + lq = lp; + if (lp) { + if (lq) + lq->l_nxt = lp->l_nxt; + if (lp == bloks) + bloks = bloks->l_nxt; + free(lp); + } + } +} + +struct oblok * +ob_alloc(int fd, enum ob_mode bf) +{ + static long pagesize; + struct oblok *op; + + if (pagesize == 0) + if ((pagesize = sysconf(_SC_PAGESIZE)) < 0) + pagesize = 4096; + if ((op = memalign(pagesize, sizeof *op)) == NULL) + return NULL; + memset(op, 0, sizeof *op); + op->ob_fd = fd; + switch (bf) { + case OB_EBF: + op->ob_bf = isatty(fd) ? OB_LBF : OB_FBF; + break; + default: + op->ob_bf = bf; + } + add(op); + return op; +} + +ssize_t +ob_free(struct oblok *op) +{ + ssize_t wrt; + + wrt = ob_flush(op); + del(op); + free(op); + return wrt; +} + +static ssize_t +swrite(int fd, const char *data, size_t sz) +{ + ssize_t wo, wt = 0; + + do { + if ((wo = write(fd, data + wt, sz - wt)) < 0) { + if (errno == EINTR) + continue; + else + return wt; + } + wt += wo; + } while (wt < sz); + return sz; +} + +ssize_t +ob_write(struct oblok *op, const char *data, size_t sz) +{ + ssize_t wrt; + size_t di, isz; + + switch (op->ob_bf) { + case OB_NBF: + wrt = swrite(op->ob_fd, data, sz); + op->ob_wrt += wrt; + if (wrt != sz) { + op->ob_bf = OB_EBF; + writerr(op, sz, wrt>0?wrt:0); + return -1; + } + return wrt; + case OB_LBF: + case OB_FBF: + isz = sz; + while (op->ob_pos + sz > (OBLOK)) { + di = (OBLOK) - op->ob_pos; + sz -= di; + if (op->ob_pos > 0) { + memcpy(&op->ob_blk[op->ob_pos], data, di); + wrt = swrite(op->ob_fd, op->ob_blk, (OBLOK)); + } else + wrt = swrite(op->ob_fd, data, (OBLOK)); + op->ob_wrt += wrt; + if (wrt != (OBLOK)) { + op->ob_bf = OB_EBF; + writerr(op, (OBLOK), wrt>0?wrt:0); + return -1; + } + data += di; + op->ob_pos = 0; + } + if (op->ob_bf == OB_LBF) { + const char *cp; + + cp = data; + while (cp < &data[sz]) { + if (*cp == '\n') { + di = cp - data + 1; + sz -= di; + if (op->ob_pos > 0) { + memcpy(&op->ob_blk[op->ob_pos], + data, di); + wrt = swrite(op->ob_fd, + op->ob_blk, + op->ob_pos + di); + } else + wrt = swrite(op->ob_fd, + data, di); + op->ob_wrt += wrt; + if (wrt != op->ob_pos + di) { + op->ob_bf = OB_EBF; + writerr(op, di, wrt>0?wrt:0); + return -1; + } + op->ob_pos = 0; + data += di; + cp = data; + } + cp++; + } + } + if (sz == (OBLOK)) { + wrt = swrite(op->ob_fd, data, sz); + op->ob_wrt += wrt; + if (wrt != sz) { + op->ob_bf = OB_EBF; + writerr(op, sz, wrt>0?wrt:0); + return -1; + } + } else if (sz) { + memcpy(&op->ob_blk[op->ob_pos], data, sz); + op->ob_pos += sz; + } + return isz; + case OB_EBF: + ; + } + return -1; +} + +ssize_t +ob_flush(struct oblok *op) +{ + ssize_t wrt = 0; + + if (op->ob_pos) { + wrt = swrite(op->ob_fd, op->ob_blk, op->ob_pos); + op->ob_wrt += wrt; + if (wrt != op->ob_pos) { + op->ob_bf = OB_EBF; + writerr(op, op->ob_pos, wrt>0?wrt:0); + wrt = -1; + } + op->ob_pos = 0; + } + return wrt; +} + +int +ob_chr(int c, struct oblok *op) +{ + char b; + ssize_t wrt; + + b = (char)c; + wrt = ob_write(op, &b, 1); + return wrt < 0 ? EOF : c; +} diff --git a/package/heirloom-cpio/src/oblok.h b/package/heirloom-cpio/src/oblok.h new file mode 100644 index 000000000..1ee91b1c5 --- /dev/null +++ b/package/heirloom-cpio/src/oblok.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)oblok.h 1.3 (gritter) 4/17/03 */ + +#include + +#ifndef OBLOK +enum { + OBLOK = 4096 +}; +#endif /* !OBLOK */ + +enum ob_mode { + OB_EBF = 0, /* error or mode unset */ + OB_NBF = 1, /* not buffered */ + OB_LBF = 2, /* line buffered */ + OB_FBF = 3 /* fully buffered */ +}; + +struct oblok { + char ob_blk[OBLOK]; /* buffered data */ + long long ob_wrt; /* amount of data written */ + int ob_pos; /* position of first empty date byte */ + int ob_fd; /* file descriptor to write to */ + enum ob_mode ob_bf; /* buffering mode */ +}; + +/* + * Allocate an output buffer with file descriptor fd and buffer mode bf. + * If bf is OB_EBF, the choice is made dependant upon the file type. + * NULL is returned if no memory is available. + */ +extern struct oblok *ob_alloc(int fd, enum ob_mode bf); + +/* + * Deallocate the passed output buffer, flushing all data. The file + * descriptor is not closed. Returns -1 if flushing fails. + */ +extern ssize_t ob_free(struct oblok *op); + +/* + * Write data of length sz to the passed output buffer. Returns -1 on + * error or the amount of data written. + */ +extern ssize_t ob_write(struct oblok *op, const char *data, size_t sz); + +/* + * Flush all data in the passed output buffer. Returns -1 on error or + * the amount of data written; 0 is success and means 'nothing to flush'. + * The underlying device is not flushed (i. e. no fsync() is performed). + */ +extern ssize_t ob_flush(struct oblok *op); + +/* + * Flush all output buffers. Called automatically using atexit(). Returns + * -1 on error or the number of buffers flushed; 0 is success. + */ +extern int ob_clear(void); + +/* + * putc() workalike. + */ +#define ob_put(c, op) ((op)->ob_bf != OB_FBF || (op)->ob_pos >= (OBLOK) - 1 ?\ + ob_chr((c), (op)) : \ + (int)((op)->ob_blk[(op)->ob_pos++] = (char)(c))) + + +/* + * fputc() workalike. + */ +extern int ob_chr(int c, struct oblok *op); + +/* + * This function must be supplied by the calling code; it is called on + * write error. + */ +extern void writerr(struct oblok *op, int count, int written); diff --git a/package/heirloom-cpio/src/pathconf.c b/package/heirloom-cpio/src/pathconf.c new file mode 100644 index 000000000..a6b91ef86 --- /dev/null +++ b/package/heirloom-cpio/src/pathconf.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2004 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)pathconf.c 1.2 (gritter) 5/1/04 */ + +#ifdef __dietlibc__ +#include +#include "pathconf.h" + +static long +pc(int name) +{ + switch (name) { + case _PC_PATH_MAX: + return 1024; + case _PC_VDISABLE: + return 0; + default: + return -1; + } +} + +long +fpathconf(int fildes, int name) +{ + return pc(name); +} + +long +pathconf(const char *path, int name) { + return pc(name); +} +#endif /* __dietlibc__ */ diff --git a/package/heirloom-cpio/src/pathconf.h b/package/heirloom-cpio/src/pathconf.h new file mode 100644 index 000000000..79696b6da --- /dev/null +++ b/package/heirloom-cpio/src/pathconf.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2004 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)pathconf.h 1.2 (gritter) 5/1/04 */ + +#ifdef __dietlibc__ +#include + +extern long fpathconf(int, int); +extern long pathconf(const char *, int); +#endif /* __dietlibc__ */ diff --git a/package/heirloom-cpio/src/pax.1 b/package/heirloom-cpio/src/pax.1 new file mode 100644 index 000000000..4fb9206f9 --- /dev/null +++ b/package/heirloom-cpio/src/pax.1 @@ -0,0 +1,919 @@ +'\" t +.\" Copyright (c) 2004 Gunnar Ritter +.\" +.\" This software is provided 'as-is', without any express or implied +.\" warranty. In no event will the authors be held liable for any damages +.\" arising from the use of this software. +.\" +.\" Permission is granted to anyone to use this software for any purpose, +.\" including commercial applications, and to alter it and redistribute +.\" it freely, subject to the following restrictions: +.\" +.\" 1. 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. +.\" +.\" 2. Altered source versions must be plainly marked as such, and must not be +.\" misrepresented as being the original software. +.\" +.\" 3. This notice may not be removed or altered from any source distribution. +.\" Sccsid @(#)pax.1 1.38 (gritter) 8/13/09 +.TH PAX 1 "8/13/09" "Heirloom Toolchest" "User Commands" +.SH NAME +pax \- portable archive interchange +.SH SYNOPSIS +.PD 0 +.HP +.nh +.ad l +\fBpax\fR [\fB\-cdnvK\fR] [\fB\-b\ \fIsize\fR] +[\fB\-f\ \fIfile\fR] [\fB\-s\ \fIreplstr\fR] +[\fB\-x\ \fIhdr\fR] [\fIpatterns\fR] +.HP +.ad l +\fBpax\fR \fB\-r\fR[\fBcdiknuvK\fR] [\fB\-b\ \fIsize\fR] +[\fB\-f\ \fIfile\fR] +[\fB\-o\ \fIoptions\fR] +[\fB\-p\ \fIpriv\fR] [\fB\-s\ \fIreplstr\fR] +[\fB\-x\ \fIhdr\fR] [\fIpatterns\fR] +.HP +.ad l +\fBpax\fR \fB\-w\fR[\fBadiHtuvLX\fR] [\fB\-b\ \fIsize\fR] +[\fB\-f\ \fIfile\fR] +[\fB\-o\ \fIoptions\fR] +[\fB\-s\ \fIreplstr\fR] +[\fB\-x\ \fIhdr\fR] [\fIfiles\fR] +.HP +.ad l +\fBpax\fR \fB\-rw\fR[\fBdiHklntuvLX\fR] +[\fB\-p\ \fIpriv\fR] [\fB\-s\ \fIreplstr\fR] +[\fIfiles\fR] \fIdirectory\fR +.br +.ad b +.hy 1 +.PD +.SH DESCRIPTION +.I Pax +creates and extracts file archives and copies files. +.PP +If neither the +.I \-r +or +.I \-w +options are given, +.I pax +works in +.I list +mode +and prints the contents of the archive. +.PP +With the +.B \-r +option, +.I pax +works in +.RI ` read ' +mode and extracts files from a file archive. +By default, +the archive is read from standard input. +Optional arguments are interpreted as +.I patterns +and restrict the set of extracted files +to those matching any of the +.IR patterns . +The syntax is identical to that described in +.IR glob (7), +except that the slash character +.RB ` / ' +is matched by +meta-character constructs with +.RB ` * ', +.RB ` ? ' +and +.RB ` [ '. +Care must be taken to quote meta-characters appropriately from the shell. +If a pattern matches the prefix name of a directory in the archive, +all files below that directory are also extracted. +File permissions are set to those in the archive; +if the caller is the super-user, +ownerships are restored as well. +options are specified. +Archives compressed with +.IR bzip2 (1), +.IR compress (1), +.IR gzip (1), +or +.IR rpm (1) +are transparently de\%compressed on input. +.PP +With +.BR \-w , +.I pax +works in +.RI ` write ' +mode, +creates archives +and writes them to standard output per default. +A list of filenames to be included in the archive is +read from standard input; +if the name of a directory appears, +all its members and the directory itself are recursively +included in the archive. +The +.IR find (1) +utility is useful to generate a list of files +(see also its +.I \-cpio +and +.I \-ncpio +operators). +When producing a filename list for +.IR pax , +find should always be invoked with +.I \-depth +since this makes it possible to extract write-protected directories +for users other than the super-user. +If +.I files +are given on the command line, +they are included in the archive +in the same manner as described above +and standard input is not read. +.PP +The +.B \-rw +options selects +.RI ` copy ' +mode; +a list of +.I files +is read from standard input +or taken from the command line +as described for +.IR \-w ; +files are copied to the specified +.IR directory , +preserving attributes as described for +.IR \-r . +Special files are re-created in the target hierarchy, +and hard links between copied files are preserved. +.PP +When a premature end-of-file is detected with +.I \-r +and +.I \-w +and the archive is a block or character special file, +the user is prompted for new media. +.PP +The following options alter the behavior of +.IR pax : +.TP +.B \-a +Append files to the archive. +The archive must be seekable, +such as a regular file or a block device, +or a tape device capable of writing between filemarks. +.TP +\fB\-b\fI size\fR[\fBw\fR|\fBb\fR|\fBk\fR|\fBm\fR] +Blocks input and output archives at +.I size +byte records. +The optional suffix multiplies +.I size +by 2 for +.BR w , +512 for +.BR b , +1024 for +.BR k , +and 1048576 for +.BR m . +.TP +.B \-c +Reverses the sense of patterns +such that a file that does not match any of the patterns +is selected. +.TP +.B \-d +Causes +.I pax +to ignore files below directories. +In read mode, +patterns matching directories +cause only the directory itself to extracted, +files below will be ignored +unless another pattern applies to them. +In write mode, +arguments or standard input lines referring to directories +do not cause files below the respective directory +to be archived. +.TP +\fB\-f\fI\ file\fR +Selects a +.I file +that is read with the +.I \-r +option instead of standard input +or written with the +.I \-w +option instead of standard output. +.TP +.B \-H +Follow symbolic links given on the command line when reading files with +.I \-w +or +.IR \-rw , +but do not follow symbolic links encountered during directory traversal. +.TP +.B \-i +Rename files interactively. +Before a file is extracted from the archive, +its file name is printed on standard error +and the user is prompted to specify a substitute file name. +If the line read from the terminal is empty, +the file is skipped; +if the line consists of a single dot, +the name is retained; +otherwise, +the line forms the new file name. +.TP +.B \-k +Causes existing files not to be overwritten. +.TP +.B \-K +Try to continue operation on read errors and invalid headers. +If an archive contains another archive, +files from either archive may be chosen. +.TP +.B \-l +Link files instead of copying them with +.I \-rw +if possible. +.TP +.B \-L +Follow symbolic links when reading files with +.I \-w +or +.IR \-rw . +.B /usr/posix2001/bin/pax +terminates immediately when it +detects a symbolic link loop with this option. +.TP +.B \-n +If any +.I pattern +arguments are present, +each pattern can match exactly one archive member; +further members that could match the particular pattern are ignored. +Without +.I pattern +arguments, +only the first occurence of +a file that occurs more than once in the archive +is selected, the following are ignored. +.TP +\fB\-o\ \fIoption\fB,\fR[\fIoption\fB,\fR\|...] +Specifies options as described for \fI\-x pax\fR. +.TP +\fB\-p\ \fIstring\fR +Specifies which file modes are to be preserved or ignored. +.I string +may contain one or more of +.RS +.TP +.B a +Inhibits preservation of file access times. +.TP +.B e +Causes preservation of every possible mode, ownership and time. +.TP +.B m +Inhibits preservation of file modification times. +.TP +.B o +Causes preservation of owner and group IDs. +.TP +.B p +Causes preservation of file mode bits +regardless of the umask +(see +.IR umask (2)). +.RE +.IP +If file ownership is preserved, +.I pax +tries to set the group ownerships to those specified in the archive +or the original hierarchy, respectively, +regardless of the privilegues of the invoking user. +.BR /usr/5bin/pax , +.BR /usr/5bin/s42/pax , +and +.B /usr/5bin/posix/pax +try to set the user ownerships only if invoked by the super-user; +if invoked by regular users, +.B /usr/5bin/posix2001/pax +will produce an error for any file that is not owned by the invoking user. +.TP +\fB\-s\ /\fIregular expression\fB/\fIreplacement\fB/\fR[\fBgp\fR] +Modifies file names in a manner similar to that described in +.IR ed (1). +The +.I p +flag causes each modified file name to printed. +Any character can be used as delimiter instead of +.RI ` / '. +If a file name is empty after the replacement is done, +the file is ignored. +This option can be specified multiple times +to execute multiple substitutions in the order specified. +.TP +.B \-t +Resets the access times of files +that were included in the archive with +.IR \-r . +.TP +.B \-u +In read mode, +.I pax +will not overwrite existing target files +that were modified more recently than the file in the archive +when this option is given. +In write mode, +.I pax +will read the archive first. +It will then only append those files to the archive +that are not already included +or were more recently modified. +.TP +.B \-v +Prints the file names of archived or extracted files with +.I \-r +and +.I \-w +and a verbose output format +if neither of them is given. +.TP +\fB\-x\fI header\fR +Specifies the archive header format to be one of: +.sp +.in +6 +.TS +lfB l. +\fBnewc\fR SVR4 ASCII cpio format;\ +\fBcrc\fR SVR4 ASCII cpio format with checksum;\ +\fBsco\fR T{ +SCO UnixWare 7.1 ASCII cpio format; +T} +\fBscocrc\fR T{ +SCO UnixWare 7.1 ASCII cpio format with checksum; +T} +\fBodc\fR T{ +traditional ASCII cpio format, as standardized in IEEE Std. 1003.1, 1996; +T} +\fBcpio\fR T{ +same as \fIodc\fR; +T} +\fBbin\fR binary cpio format; +\fBbbs\fR byte-swapped binary cpio format; +\fBsgi\fR T{ +SGI IRIX extended binary cpio format; +T} +\fBcray\fR T{ +Cray UNICOS 9 cpio format; +T} +\fBcray5\fR T{ +Cray UNICOS 5 cpio format; +T} +\fBdec\fR T{ +Digital UNIX extended cpio format; +T} +\fBtar\fR tar format; +\fBotar\fR old tar format; +\fBustar\fR T{ +IEEE Std. 1003.1, 1996 tar format; +T} +.T& +l s. +\fBpax\fR[\fB:\fIoption\fB,\fR[\fIoption\fB,\fR\|...]] +.T& +l l. +\& T{ +IEEE Std. 1003.1, 2001 pax format. +Format-specific \fIoptions\fR are: +.in +2n +.ti 0 +.br +\fBlinkdata\fR +.br +For a regular file which has multiple hard links, +the file data is stored once for each link in the archive, +instead of being stored for the first entry only. +This option must be used with care +since many implementations are unable +to read the resulting archive. +.ti 0 +.br +\fBtimes\fR +.br +Causes the times of last access and last modification +of each archived file +to be stored in an extended \fIpax\fR header. +This in particular allows the time of last access +to be restored when the archive is read. +.br +.in -2n +T} +\fBsun\fR T{ +Sun Solaris 7 extended tar format; +T} +\fBbar\fR T{ +SunOS 4 bar format; +T} +\fBgnu\fR T{ +GNU tar format; +T} +\fBzip\fR[\fB:\fIcc\fR] T{ +zip format with optional compression method. +If \fIcc\fR is one of +\fBen\fR (normal, default), +\fBex\fR (extra), +\fBef\fR (fast), +or +\fBes\fR (super fast), +the standard \fIdeflate\fR compression is used. +\fBe0\fR selects no compression, +and +\fBbz2\fR selects \fIbzip2\fR compression. +T} +.TE +.in -6 +.sp +This option is ignored with +.I \-r +unless the +.I \-K +option is also present. +The default for +.I \-w +is traditional ASCII cpio +.I (odc) +format. +.PP +.ne 38 +Characteristics of archive formats are as follows: +.sp +.TS +allbox; +l r r r l +l1fB r2 n2 r2 c. + T{ +.ad l +maximum user/\%group id +T} T{ +.ad l +maximum file size +T} T{ +.ad l +maximum pathname length +T} T{ +.ad l +bits in dev_t (major/minor) +T} +\-x\ bin 65535 2 GB\ 256 \ 16 +\-x\ sgi 65535 9 EB\ 256 \ 14/18 +T{ +\-x\ odc +T} 262143 8 GB\ 256 \ 18 +\-x\ dec 262143 8 GB\ 256 \ 24/24 +T{ +\-x\ newc, +\-x\ crc +T} 4.3e9 4 GB\ 1024 \ 32/32 +T{ +\-x\ sco, \-x\ scocrc +T} 4.3e9 9 EB\ 1024 \ 32/32 +T{ +\-x\ cray, \-x\ cray5 +T} 1.8e19 9 EB\ 65535 \ 64 +\-x\ otar 2097151 8 GB\ 99 \ n/a +T{ +\-x\ tar, +\-x\ ustar +T} 2097151 8 GB\ 256 (99) \ 21/21 +\-x\ pax 1.8e19 9 EB\ 65535 \ 21/21 +\-x\ sun 1.8e19 9 EB\ 65535 \ 63/63 +\-x\ gnu 1.8e19 9 EB\ 65535 \ 63/63 +\-x\ bar 2097151 8 GB\ 427 \ 21 +\-x\ zip 4.3e9 9 EB\ 60000 \ 32 +.TE +.sp +.PP +The byte order of +.B binary +cpio archives +depends on the machine +on which the archive is created. +Unlike some other implementations, +.I pax +fully supports +archives of either byte order. +.I \-x\ bbs +can be used to create an archive +with the byte order opposed to that of the current machine. +.PP +The +.B sgi +format extends the binary format +to handle larger files and more device bits. +If an archive does not contain any entries +that actually need the extensions, +it is identical to a binary archive. +.I \-x\ sgi +archives are always created in MSB order. +.PP +The +.B odc +format was introduced with System\ III +and standardized with IEEE Std. 1003.1. +All known +.I cpio +and +.I pax +implementations since around 1980 can read this format. +.PP +The +.B dec +format extends the +.I odc +format +to support more device bits. +Archives in this format are generally incompatible with +.I odc +archives +and need special implementation support to be read. +.PP +The +.B \-x\ newc +format was introduced with System\ V Release\ 4. +Except for the file size, +it imposes no practical limitations +on files archived. +The original SVR4 implementation +stores the contents of hard linked files +only once and with the last archived link. +This +.I pax +ensures compatibility with SVR4. +With archives created by implementations that employ other methods +for storing hard linked files, +each file is extracted as a single link, +and some of these files may be empty. +Implementations that expect methods other than the original SVR4 one +may extract no data for hard linked files at all. +.PP +The +.B crc +format is essentially the same as the +.I \-x\ newc +format +but adds a simple checksum (not a CRC, despite its name) +for the data of regular files. +The checksum requires the implementation to read each file twice, +which can considerably increase running time and system overhead. +As not all implementations claiming to support this format +handle the checksum correctly, +it is of limited use. +.PP +The +.B sco +and +.B scocrc +formats are variants of the +.I \-x\ newc +and +.I \-x\ crc +formats, respectively, +with extensions to support larger files. +The extensions result in a different archive format +only if files larger than slightly below 2\ GB occur. +.PP +The +.B cray +format extends all header fields to 64 bits. +It thus imposes no practical limitations of any kind +on archived files, +but requires special implementation support +to be read. +Although it is originally a binary format, +the byte order is always MSB as on Cray machines. +The +.B cray5 +format is an older variant +that was used with UNICOS 5 and earlier. +.PP +The +.B otar +format was introduced with the Unix 7th Edition +.I tar +utility. +Archives in this format +can be read on all Unix systems since about 1980. +It can only hold regular files +(and, on more recent systems, symbolic links). +For file names that contain characters with the most significant bit set +(non-ASCII characters), +implementations differ in the interpretation of the header checksum. +.PP +The +.B ustar +format was introduced with IEEE Std. 1003.1. +It extends the old +.I tar +format +with support for directories, device files, +and longer file names. +Pathnames of single-linked files can consist of up to 256 characters, +dependent on the position of slashes. +Files with multiple links can only be archived +if the first link encountered is no longer than 100 characters. +Due to implementation errors, +file names longer than 99 characters +can not considered to be generally portable. +Another addition of the +.I ustar +format +are fields for the symbolic user and group IDs. +These fields are created by +.IR pax , +but ignored when reading such archives. +.PP +With +.BR "\-x tar" , +a variant of the +.I ustar +format is selected +which stores file type bits in the mode field +to work around common implementation problems. +These bits are ignored by +.I pax +when reading archives. +.PP +The +.B pax +format is an extension to the +.I ustar +format. +If attributes cannot be archived with +.IR ustar , +an extended header is written. +Unless the size of an entry is greater than 8\ GB, +a +.I pax +archive should be readable by any implementation +capable of reading +.I ustar +archives, +although files may be extracted under wrong names +and extended headers may be extracted as separate files. +If a file name contains non-UTF-8 characters, +it may not be archived or extracted correctly +because of a problem of the +.I pax +format specification. +.PP +The +.B sun +format extends the +.I ustar +format similar as the +.I pax +format does. +The extended headers in +.I sun +format archives are not understood +by implementations that support only the +.I pax +format and vice-versa. +The +.I sun +format has also problems with non-UTF-8 characters in file names. +.PP +The +.B GNU +.I tar +format is mostly compatible with the other +.I tar +formats, +unless an archive entry actually uses its extended features. +There are no practical limitations on files archived with this format. +The implementation of +.I pax +is limited to expanded numerical fields +and long file names; +in particular, +there is no support for sparse files or incremental backups. +If +.I pax +creates a multi-volume +.I GNU +archive, +it just splits a single-volume archive in multiple parts, +as with the other formats; +.I GNU +multi-volume archives are not supported. +.PP +The +.B bar +format is similar to the +.I tar +format, but can store longer file names. +It requires special implementation support to be read. +.PP +The +.B zip +format can be read in many non-Unix environments. +There are several restrictions on archives +intended for data exchange: +only regular files should be stored; +file times, permissions and ownerships +might be ignored by other implementations; +there should be no more than 65536 files in the archive; +the total archive size should not exceed 2 GB; +only +.I deflate +compression should be used. +Otherwise, +.I pax +stores all information available with other archive formats +in extended +.I zip +file headers, +so if archive portability is of no concern, +the +.I zip +implementation in +.I pax +can archive complete Unix file hierarchies. +.I Pax +supports the +.I zip64 +format extension for large files; +it automatically writes +.I zip64 +entries if necessary. +.I Pax +can extract all known +.I zip +format compression codes. +It does not support +.I zip +encryption. +Multi-volume +.I zip +archives are created as splitted single-volume archives, +as with the other formats written by +.IR pax ; +generic multi-volume +.I zip +archives are not supported. +.SH EXAMPLES +Extract all files named +.I Makefile +or +.I makefile +from the archive stored on +.IR /dev/rmt/c0s0 , +overwriting recent files: +.RS 2 +.sp +pax \-r \-f /dev/rmt/c0s0 \'[Mm]akefile\' \'*/[Mm]akefile\' +.RE +.PP +List the files contained in a software distribution archive: +.RS 2 +.sp +pax \-v \-f distribution.tar.gz +.RE +.PP +Write a +.IR gzip (1) +compressed +.I ustar +archive containing all files below the directory +.I \%project +to the file +.IR \%project.tar.gz , +excluding all directories named +.I CVS +or +.I SCCS +and their contents: +.RS 2 +.sp +find project \-depth \-print | egrep \-v \'/(CVS|SCCS)(/|$)\' | +.br + pax \-wd \-x ustar | gzip \-c > project.tar.gz +.RE +.PP +Copy the directory +.I work +and its contents +to the directory +.IR \%savedfiles , +preserving all file attributes: +.RS 2 +.sp +pax \-rw \-pe work savedfiles +.RE +.PP +Self-extracting zip archives are not automatically recognized, +but can normally be read using the +.I \-K +option, as with +.RS 2 +.sp +pax \-rK \-x zip \-f archive.exe +.sp +.RE +.SH "ENVIRONMENT VARIABLES" +.TP +.BR LANG ", " LC_ALL +See +.IR locale (7). +.TP +.B LC_CTYPE +Selects the mapping of bytes to characters +used for matching patterns +and regular expressions. +.TP +.B LC_TIME +Sets the month names printed in list mode. +.SH "SEE ALSO" +cpio(1), +find(1), +tar(1) +.SH DIAGNOSTICS +.I Pax +exits with +.sp +.TS +l8fB l. +0 after successful operation; +1 on usage errors; +2 when operation was continued after minor errors; +3 on fatal error conditions. +.TE +.SH NOTES +Device and inode numbers +are used for hard link recognition +with the various cpio formats. +Since the header space cannot hold +large numbers present in current file systems, +devices and inode numbers are set on a per-archive basis. +This enables hard link recognition with all cpio formats, +but the link connection to files appended with +.I \-a +is not preserved. +.PP +If a numeric user or group id does not fit +within the size of the header field in the selected format, +files are stored with the user id (or group id, respectively) +set to 60001. +.PP +Use of the +.I \-a +option with a +.I zip +format archive may cause data loss +if the archive was not previously created by +.I cpio +or +.I pax +itself. +.PP +If the file names passed to +.I "pax -w" +begin with a slash character, +absolute path names are stored in the archive +and will be extracted to these path names later +regardless of the current working directory. +This is normally not advisable, +and relative path names should be passed to +.I pax +only. +The +.I \-s +option can be used to substitute relative for absolute path names +and vice-versa. +.PP +.I Pax +does not currently accept the +\fB\-o delete\fR, +\fB\-o exthdr.name\fR, +\fB\-o globexthdr.name\fR, +\fB\-o invalid\fR, +\fB\-o listopt\fR, +and +\fB\-o keyword\fR +options from POSIX.1-2001. diff --git a/package/heirloom-cpio/src/pax.c b/package/heirloom-cpio/src/pax.c new file mode 100644 index 000000000..50632b6b1 --- /dev/null +++ b/package/heirloom-cpio/src/pax.c @@ -0,0 +1,757 @@ +/* + * cpio - copy file archives in and out + * + * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. + */ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 +#define USED __attribute__ ((used)) +#elif defined __GNUC__ +#define USED __attribute__ ((unused)) +#else +#define USED +#endif +#if defined (SU3) +static const char sccsid[] USED = "@(#)pax_su3.sl 1.26 (gritter) 6/26/05"; +#else +static const char sccsid[] USED = "@(#)pax.sl 1.26 (gritter) 6/26/05"; +#endif +/* Sccsid @(#)pax.c 1.26 (gritter) 6/26/05 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iblok.h" +#include "cpio.h" + +static char **files; +static int filec; +static struct iblok *filinp; +static char *path; +static size_t pathsz; +static int pax_Hflag; + +static void setpres(const char *); +static size_t ofiles_pax(char **, size_t *); +static void prtime_pax(time_t); +static void parsesub(char *); + +void +flags(int ac, char **av) +{ + const char optstring[] = "rwab:cdf:HikKlLno:p:s:tuvx:X"; + int i; + int illegal = 0; + char *x; + +#if defined (SU3) + pax = PAX_TYPE_PAX2001; +#else + pax = PAX_TYPE_PAX1992; +#endif + dflag = 1; + uflag = 1; + ofiles = ofiles_pax; + prtime = prtime_pax; + while ((i = getopt(ac, av, optstring)) != EOF) { + switch (i) { + case 'r': + if (action && action != 'i') + action = 'p'; + else + action = 'i'; + break; + case 'w': + if (action && action != 'o') + action = 'p'; + else + action = 'o'; + break; + case 'a': + Aflag = 1; + break; + case 'b': + blksiz = strtol(optarg, &x, 10); + switch (*x) { + case 'b': + blksiz *= 512; + break; + case 'k': + blksiz *= 1024; + break; + case 'm': + blksiz *= 1048576; + break; + case 'w': + blksiz *= 2; + break; + } + if (blksiz <= 0) + msg(4, -2, + "Illegal size given for -b option.\n"); + Cflag = 1; + break; + case 'c': + fflag = 1; + break; + case 'd': + pax_dflag = 1; + break; + case 'f': + Oflag = Iflag = optarg; + break; + case 'H': + pax_Hflag = 1; + break; + case 'i': + rflag = 1; + break; + case 'k': + pax_kflag = 1; + break; + case 'K': + kflag = 1; + break; + case 'l': + lflag = 1; + break; + case 'L': + Lflag = 1; + break; + case 'n': + pax_nflag = 1; + break; + case 'o': + pax_options(optarg, 1); + break; + case 'p': + setpres(optarg); + break; + case 's': + pax_sflag = 1; + parsesub(optarg); + break; + case 't': + aflag = 1; + break; + case 'u': + uflag = 0; + pax_uflag = 1; + break; + case 'v': + vflag = 1; + break; + case 'x': + if (strcmp(optarg, "cpio") == 0) + fmttype = FMT_ODC; + else { + if (setfmt(optarg) < 0) + illegal = 1; + } + break; + case 'X': + pax_Xflag = 1; + break; + default: + illegal = 1; + } + } + switch (action) { + case 0: + if (rflag || pax_kflag || pax_uflag || pax_preserve) + illegal = 1; + action = 'i'; + tflag = 1; + setvbuf(stdout, NULL, _IOLBF, 0); + /*FALLTHRU*/ + case 'i': + if (aflag || pax_Xflag || lflag) + illegal = 1; + for (i = optind; i < ac; i++) { + addg(av[i], 0); + if (pax_dflag == 0) { + char *da; + int j; + + da = smalloc(strlen(av[i]) + 2); + for (j = 0; av[i][j]; j++) + da[j] = av[i][j]; + da[j++] = '/'; + da[j++] = '*'; + da[j] = 0; + addg(da, 1); + free(da); + } + } + break; + case 'o': + if (fflag || pax_kflag || pax_nflag || kflag) + illegal = 1; + if (Aflag && Oflag == NULL) { + msg(3, 0, "-a requires the -f option\n"); + illegal = 1; + } + if (optind != ac) { + files = &av[optind]; + filec = ac - optind; + } else + filinp = ib_alloc(0, 0); + if (pax_uflag) + Aflag = 1; + if (Aflag == 0 && fmttype == FMT_NONE) + fmttype = FMT_ODC; + break; + case 'p': + if (fflag || blksiz || Oflag || Iflag || fmttype != FMT_NONE || + kflag) + illegal = 1; + if (optind == ac) + illegal = 1; + else if (optind+1 != ac) { + files = &av[optind]; + filec = ac - optind - 1; + optind = ac - 1; + } else + filinp = ib_alloc(0, 0); + break; + } + if (illegal) + usage(); +} + +void +usage(void) +{ + fprintf(stderr, "USAGE:\n\ +\t%s [-cdnvK] [-b size] [-f file] [-s replstr] [-x hdr] [patterns]\n\ +\t%s -r[cdiknuvK] [-b size] [-f file] [-p priv] [-s replstr] [-x hdr] [patterns]\n\ +\t%s -w[adituvLX] [-b size] [-f file] [-s replstr] [-x hdr] [files]\n\ +\t%s -rw[diklntuvLX] [-p priv] [-s replstr] [files] directory\n", + progname, progname, progname, progname); + exit(1); +} + +static void +setpres(const char *s) +{ + s--; + while (*++s) { + pax_preserve &= ~PAX_P_EVERY; + switch (*s) { + case 'a': + pax_preserve |= PAX_P_ATIME; + break; + case 'e': + pax_preserve |= PAX_P_EVERY; + break; + case 'm': + pax_preserve |= PAX_P_MTIME; + break; + case 'o': + pax_preserve |= PAX_P_OWNER; + break; + case 'p': + pax_preserve |= PAX_P_MODE; + break; + default: + msg(2, 0, "ignoring unknown option \"-p%c\"\n", + *s&0377); + } + } + if (pax_preserve & PAX_P_EVERY) + pax_preserve |= PAX_P_OWNER|PAX_P_MODE; +} + +int +gmatch(const char *s, const char *p) +{ + int val; +#ifdef __GLIBC__ + /* avoid glibc's broken [^...] */ + extern char **environ; + char **savenv = environ; + char *newenv[] = { "POSIXLY_CORRECT=", NULL }; + environ = newenv; +#endif /* __GLIBC__ */ + val = fnmatch(p, s, 0) == 0; +#ifdef __GLIBC__ + environ = savenv; +#endif /* __GLIBC__ */ + return val; +} + +static const char * +nextfile(void) +{ + char *line = NULL; + size_t linsiz = 0, linlen; + + if (filinp) { + pax_Hflag = 0; + if ((linlen=ib_getlin(filinp, &line, &linsiz, srealloc)) == 0) { + filinp = NULL; + return NULL; + } + if (line[linlen-1] == '\n') + line[--linlen] = '\0'; + return line; + } else if (filec > 0) { + filec--; + return *files++; + } else + return NULL; +} + +static size_t +catpath(size_t pend, const char *base) +{ + size_t blen = strlen(base); + + if (pend + blen + 2 >= pathsz) + path = srealloc(path, pathsz = pend + blen + 16); + if (pend == 0 || path[pend-1] != '/') + path[pend++] = '/'; + strcpy(&path[pend], base); + return pend + blen; +} + +/* + * Descend the directory hierarchies given using stdin or arguments + * and return file names one per one. + */ +static size_t +ofiles_pax(char **name, size_t *namsiz) +{ + static DIR **dt; + static int dti, dts; + static int *pend; + static dev_t *curdev; + static ino_t *curino; + struct stat st; + struct dirent *dp; + const char *nf; + int i; + + if (dt == NULL) { + dt = scalloc(dts = 1, sizeof *dt); + pend = scalloc(dts, sizeof *pend); + curdev = scalloc(dts, sizeof *curdev); + curino = scalloc(dts, sizeof *curino); + } + for (;;) { + if (dti >= 0 && dt[dti] != NULL) { + if ((dp = readdir(dt[dti])) != NULL) { + if (dp->d_name[0] == '.' && + (dp->d_name[1] == '\0' || + dp->d_name[1] == '.' && + dp->d_name[2] == '\0')) + continue; + if (dti+1 <= dts) { + dt = srealloc(dt, sizeof *dt * ++dts); + pend = srealloc(pend, sizeof *pend*dts); + curdev = srealloc(curdev, sizeof *curdev + * dts); + curino = srealloc(curino, sizeof *curino + * dts); + } + pend[dti+1] = catpath(pend[dti], dp->d_name); + if (pax_Hflag) + Lflag = dti < 0; + if ((Lflag ? stat : lstat)(path, &st) < 0) { + emsg(2, "Error with %s of \"%s\"", + lflag? "stat" : "lstat", + path); + errcnt++; + } else if ((st.st_mode&S_IFMT) == S_IFDIR && + (pax_Xflag == 0 || + curdev[0] == st.st_dev)) { + if (Lflag) { + for (i = 0; i <= dti; i++) + if (st.st_dev == + curdev[i] && + st.st_ino == + curino[i]) { + if (pax == + PAX_TYPE_PAX2001) + msg(4, 1, + "Symbolic link " + "loop at " + "\"%s\"\n", + path); + break; + } + if (i <= dti) + break; + } + if ((dt[dti+1]=opendir(path)) == NULL) { + emsg(2, "Cannot open directory " + "\"%s\"", path); + errcnt++; + } else { + dti++; + curdev[dti] = st.st_dev; + curino[dti] = st.st_ino; + continue; + } + } else + break; + } else { + path[pend[dti]] = '\0'; + closedir(dt[dti]); + dt[dti--] = NULL; + if (pax_Hflag) + Lflag = dti < 0; + break; + } + } else { + if (pax_Hflag) + Lflag = 1; + while ((nf = nextfile()) != NULL && + (Lflag ? stat : lstat)(nf, &st) < 0) { + emsg(2, "Error with stat of \"%s\"", nf); + errcnt++; + } + if (nf == NULL) + return 0; + dti = 0; + if (path) + free(path); + pend[dti] = strlen(nf); + strcpy(path = smalloc(pathsz = pend[dti]+1), nf); + if (pax_dflag || (st.st_mode&S_IFMT) != S_IFDIR) { + dti = -1; + break; + } + curdev[dti] = st.st_dev; + curino[dti] = st.st_ino; + if ((dt[dti] = opendir(path)) == NULL) { + emsg(2, "Cannot open directory \"%s\"", path); + errcnt++; + } + } + } + if (*name == NULL || *namsiz < pathsz) { + free(*name); + *name = smalloc(*namsiz=pathsz); + } + strcpy(*name, path); + return pend[dti+1]; +} + +struct pax_had { + struct pax_had *p_next; + const char *p_name; + time_t p_mtime; +}; + +static int pprime = 7919; + +static int +phash(const char *s) +{ + uint32_t h = 0, g; + + s--; + while (*++s) { + h = (h << 4) + (*s & 0377); + if (g = h & 0xf0000000) { + h = h ^ (g >> 24); + h = h ^ g; + } + } + return h % pprime; +} + +static int +plook(const char *name, struct pax_had **pp) +{ + static struct pax_had **pt; + uint32_t h, had; + + if (pt == NULL) + pt = scalloc(pprime, sizeof *pt); + (*pp) = pt[h = phash(name)]; + while (*pp != NULL) { + if (strcmp((*pp)->p_name, name) == 0) + break; + *pp = (*pp)->p_next; + } + had = *pp != NULL; + if (*pp == NULL) { + *pp = scalloc(1, sizeof **pp); + (*pp)->p_name = sstrdup(name); + (*pp)->p_next = pt[h]; + pt[h] = *pp; + } + return had; +} + +int +pax_track(const char *name, time_t mtime) +{ + struct pax_had *pp; + struct stat st; + + if (pax_uflag == 0 && (pax_nflag == 0 || patterns)) + return 1; + if (action == 'i' && pax_uflag) { + if (lstat(name, &st) == 0 && mtime < st.st_mtime) + return 0; + } + if (action != 'i' || pax_nflag) { + if (plook(name, &pp) != 0) { + if (action != 'i' && pax_uflag == 0) + return 0; + if (mtime > pp->p_mtime) { + pp->p_mtime = mtime; + return 1; + } + return 0; + } else + pp->p_mtime = mtime; + } + return 1; +} + +static void +prtime_pax(time_t t) +{ + char b[30]; + time_t now; + + time(&now); + if (t > now || t < now - (6*30*86400)) + strftime(b, sizeof b, "%b %e %Y", localtime(&t)); + else + strftime(b, sizeof b, "%b %e %H:%M", localtime(&t)); + printf(" %s ", b); +} + +struct replacement { + regex_t r_re; + const char *r_rhs; + int r_nbra; + enum { + REPL_0 = 0, + REPL_G = 1, + REPL_P = 2 + } r_flags; +} *rep; + +#define NBRA 9 +static int ren, res; +static int mb_cur_max; + +static wchar_t +nextc(char **sc, int *np) +{ + char *p = *sc; + wchar_t wcbuf; + int len; + + if (**sc == '\0') { + *np = 0; + return 0; + } + if (mb_cur_max == 1 || (**sc&0200) == 0) { + *np = 1; + return *(*sc)++ & 0377; + } + if ((len = mbtowc(&wcbuf, p, mb_cur_max)) < 0) + msg(3, -2, "Invalid multibyte character for \"-s\" option\n"); + *np = len; + *sc += len; + return wcbuf; +} + +static void +parsesub(char *s) +{ + int len; + char *ps = NULL; + wchar_t seof = nextc(&s, &len); + wint_t c, d; + int nbra = 0; + int reflags; + + if (seof == 0) + goto unt; + mb_cur_max = MB_CUR_MAX; + ps = s; + do { + if ((c = nextc(&s, &len)) == seof) + break; + if (c == '\\') { + if ((c = nextc(&s, &len)) == '(') + nbra++; + continue; + } else if (c == '[') { + d = WEOF; + do { + if ((c = nextc(&s, &len)) == '\0') + continue; + if (d == '[' && (c == ':' || c == '.' || + c == '=')) { + d = c; + do { + if ((c=nextc(&s, &len)) == '\0') + continue; + } while (c != d || *s != ']'); + nextc(&s, &len); + c = WEOF; /* reset d and continue */ + } + d = c; + } while (c != ']'); + } + } while (*s != '\0'); + if (c != seof) + unt: msg(3, -2, "Unterminated argument for \"-s\" option.\n"); + s[-len] = '\0'; + if (ren <= res) + rep = srealloc(rep, ++res * sizeof *rep); + reflags = REG_ANGLES; + if (pax >= PAX_TYPE_PAX2001) + reflags |= REG_AVOIDNULL; + if (regcomp(&rep[ren].r_re, ps, reflags) != 0) + msg(3, -2, "Regular expression error in \"-s\" option\n"); + rep[ren].r_rhs = s; + rep[ren].r_nbra = nbra; + while ((c = nextc(&s, &len)) != 0) { + if (c == '\\') + c = nextc(&s, &len); + else if (c == seof) + break; + } + rep[ren].r_flags = 0; + if (c == seof) { + s[-len] = '\0'; + while ((c = nextc(&s, &len)) != '\0') { + switch (c) { + case 'g': + rep[ren].r_flags |= REPL_G; + break; + case 'p': + rep[ren].r_flags |= REPL_P; + break; + default: + msg(2, 0, "Ignoring unknown -s flag \"%c\"\n", + c); + } + } + } + ren++; +} + +#define put(c) ((new = innew+1>=newsize ? srealloc(new, newsize+=32) : new), \ + new[innew++] = (c)) + +int +pax_sname(char **oldp, size_t *olds) +{ + char *new = NULL; + size_t newsize = 0; + regmatch_t bralist[NBRA+1]; + int c, i, k, l, y, z; + int innew = 0, ef = 0; + char *inp = *oldp; + + for (z = 0; z < ren; z++) { + in: if (regexec(&rep[z].r_re, inp, NBRA+1, bralist, ef) != 0) { + if (ef == 0) + continue; + goto out; + } + for (i = 0; i < bralist[0].rm_so; i++) + put(inp[i]); + k = 0; + while (c = rep[z].r_rhs[k++] & 0377) { + y = -1; + if (c == '&') + y = 0; + else if (c == '\\') { + c = rep[z].r_rhs[k++] & 0377; + if (c >= '1' && c < rep[z].r_nbra+'1') + y = c - '0'; + } + if (y >= 0) + for (l = bralist[y].rm_so; l < bralist[y].rm_eo; + l++) + put(inp[l]); + else + put(c); + } + k = innew; + for (i = bralist[0].rm_eo; inp[i]; i++) + put(inp[i]); + put('\0'); + if (rep[z].r_flags & REPL_G) { + ef = REG_NOTBOL; + inp = &inp[bralist[0].rm_eo]; + innew = k; + if (bralist[0].rm_so == bralist[0].rm_eo) { + if (inp[0] && (nextc(&inp, &l), inp[0])) + innew++; + else + goto out; + } + goto in; + } + out: if (rep[z].r_flags & REPL_P) + fprintf(stderr, "%s >> %s\n", *oldp, new); + free(*oldp); + *oldp = new; + *olds = newsize; + return *new != '\0'; + } + return 1; +} + +void +pax_onexit(void) +{ + struct glist *gp; + + for (gp = patterns; gp; gp = gp->g_nxt) { + if (gp->g_art) + continue; + if (gp->g_gotcha == 0 && (gp->g_nxt == NULL || + gp->g_nxt->g_art == 0 || + gp->g_gotcha == 0)) { + msg(3, 0, "Pattern not matched: \"%s\"\n", gp->g_pat); + errcnt++; + } + } +} diff --git a/package/heirloom-cpio/src/pfmt.c b/package/heirloom-cpio/src/pfmt.c new file mode 100644 index 000000000..8adc22f23 --- /dev/null +++ b/package/heirloom-cpio/src/pfmt.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)pfmt.c 1.2 (gritter) 9/21/03 */ + +#include +#include + +#include "pfmt.h" + +int +pfmt(FILE *stream, long flags, const char *fmt, ...) +{ + va_list ap; + int i; + + va_start(ap, fmt); + i = vpfmt(stream, flags, fmt, ap); + va_end(ap); + return i; +} diff --git a/package/heirloom-cpio/src/pfmt.h b/package/heirloom-cpio/src/pfmt.h new file mode 100644 index 000000000..012667b0b --- /dev/null +++ b/package/heirloom-cpio/src/pfmt.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)pfmt.h 1.2 (gritter) 9/21/03 */ + +#include + +extern int pfmt(FILE *stream, long flags, const char *format, ...); + +#include + +extern int vpfmt(FILE *stream, long flags, const char *format, va_list ap); + +#define MM_HALT 0x00000001 +#define MM_ERROR 0x00000000 +#define MM_WARNING 0x00000002 +#define MM_INFO 0x00000004 +#define MM_ACTION 0x00000100 +#define MM_NOSTD 0x00000200 +#define MM_STD 0x00000000 +#define MM_NOGET 0x00000400 +#define MM_GET 0x00000000 + +extern int setlabel(const char *label); +extern int setuxlabel(const char *label); + +#define setcat(s) (s) +#define gettxt(n, s) (s) diff --git a/package/heirloom-cpio/src/pfmt_label.c b/package/heirloom-cpio/src/pfmt_label.c new file mode 100644 index 000000000..5b1a53f0a --- /dev/null +++ b/package/heirloom-cpio/src/pfmt_label.c @@ -0,0 +1 @@ +char *pfmt_label__; diff --git a/package/heirloom-cpio/src/regexp.h b/package/heirloom-cpio/src/regexp.h new file mode 100644 index 000000000..5b1fee5e6 --- /dev/null +++ b/package/heirloom-cpio/src/regexp.h @@ -0,0 +1,1211 @@ +/* + * Simple Regular Expression functions. Derived from Unix 7th Edition, + * /usr/src/cmd/expr.y + * + * Modified by Gunnar Ritter, Freiburg i. Br., Germany, February 2002. + * + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``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 CALDERA INTERNATIONAL, INC. 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. + */ + +#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 +#define REGEXP_H_USED __attribute__ ((used)) +#elif defined __GNUC__ +#define REGEXP_H_USED __attribute__ ((unused)) +#else +#define REGEXP_H_USED +#endif +static const char regexp_h_sccsid[] REGEXP_H_USED = + "@(#)regexp.sl 1.56 (gritter) 5/29/05"; + +#if !defined (REGEXP_H_USED_FROM_VI) && !defined (__dietlibc__) +#define REGEXP_H_WCHARS +#endif + +#define CBRA 2 +#define CCHR 4 +#define CDOT 8 +#define CCL 12 +/* CLNUM 14 used in sed */ +/* CEND 16 used in sed */ +#define CDOL 20 +#define CCEOF 22 +#define CKET 24 +#define CBACK 36 +#define CNCL 40 +#define CBRC 44 +#define CLET 48 +#define CCH1 52 +#define CCH2 56 +#define CCH3 60 + +#define STAR 01 +#define RNGE 03 +#define REGEXP_H_LEAST 0100 + +#ifdef REGEXP_H_WCHARS +#define CMB 0200 +#else /* !REGEXP_H_WCHARS */ +#define CMB 0 +#endif /* !REGEXP_H_WCHARS */ + +#define NBRA 9 + +#define PLACE(c) ep[c >> 3] |= bittab[c & 07] +#define ISTHERE(c) (ep[c >> 3] & bittab[c & 07]) + +#ifdef REGEXP_H_WCHARS +#define REGEXP_H_IS_THERE(ep, c) ((ep)[c >> 3] & bittab[c & 07]) +#endif + +#include +#include +#include +#ifdef REGEXP_H_WCHARS +#include +#include +#include +#endif /* REGEXP_H_WCHARS */ + +#define regexp_h_uletter(c) (isalpha(c) || (c) == '_') +#ifdef REGEXP_H_WCHARS +#define regexp_h_wuletter(c) (iswalpha(c) || (c) == L'_') + +/* + * Used to allocate memory for the multibyte star algorithm. + */ +#ifndef regexp_h_malloc +#define regexp_h_malloc(n) malloc(n) +#endif +#ifndef regexp_h_free +#define regexp_h_free(p) free(p) +#endif + +/* + * Can be predefined to 'inline' to inline some multibyte functions; + * may improve performance for files that contain many multibyte + * sequences. + */ +#ifndef regexp_h_inline +#define regexp_h_inline +#endif + +/* + * Mask to determine whether the first byte of a sequence possibly + * starts a multibyte character. Set to 0377 to force mbtowc() for + * any byte sequence (except 0). + */ +#ifndef REGEXP_H_MASK +#define REGEXP_H_MASK 0200 +#endif +#endif /* REGEXP_H_WCHARS */ + +/* + * For regexpr.h. + */ +#ifndef regexp_h_static +#define regexp_h_static +#endif +#ifndef REGEXP_H_STEP_INIT +#define REGEXP_H_STEP_INIT +#endif +#ifndef REGEXP_H_ADVANCE_INIT +#define REGEXP_H_ADVANCE_INIT +#endif + +char *braslist[NBRA]; +char *braelist[NBRA]; +int nbra; +char *loc1, *loc2, *locs; +int sed; +int nodelim; + +regexp_h_static int circf; +regexp_h_static int low; +regexp_h_static int size; + +regexp_h_static unsigned char bittab[] = { + 1, + 2, + 4, + 8, + 16, + 32, + 64, + 128 +}; +static int regexp_h_advance(register const char *lp, + register const char *ep); +static void regexp_h_getrnge(register const char *str, int least); + +static const char *regexp_h_bol; /* beginning of input line (for \<) */ + +#ifdef REGEXP_H_WCHARS +static int regexp_h_wchars; +static int regexp_h_mbcurmax; + +static const char *regexp_h_firstwc; /* location of first + multibyte character + on input line */ + +#define regexp_h_getwc(c) { \ + if (regexp_h_wchars) { \ + char mbbuf[MB_LEN_MAX + 1], *mbptr; \ + wchar_t wcbuf; \ + int mb, len; \ + mbptr = mbbuf; \ + do { \ + mb = GETC(); \ + *mbptr++ = mb; \ + *mbptr = '\0'; \ + } while ((len = mbtowc(&wcbuf, mbbuf, regexp_h_mbcurmax)) < 0 \ + && mb != eof && mbptr < mbbuf + MB_LEN_MAX); \ + if (len == -1) \ + ERROR(67); \ + c = wcbuf; \ + } else { \ + c = GETC(); \ + } \ +} + +#define regexp_h_store(wc, mb, me) { \ + int len; \ + if (wc == WEOF) \ + ERROR(67); \ + if ((len = me - mb) <= regexp_h_mbcurmax) { \ + char mt[MB_LEN_MAX]; \ + if (wctomb(mt, wc) >= len) \ + ERROR(50); \ + } \ + switch (len = wctomb(mb, wc)) { \ + case -1: \ + ERROR(67); \ + case 0: \ + mb++; \ + break; \ + default: \ + mb += len; \ + } \ +} + +static regexp_h_inline wint_t +regexp_h_fetchwc(const char **mb, int islp) +{ + wchar_t wc; + int len; + + if ((len = mbtowc(&wc, *mb, regexp_h_mbcurmax)) < 0) { + (*mb)++; + return WEOF; + } + if (islp && regexp_h_firstwc == NULL) + regexp_h_firstwc = *mb; + /*if (len == 0) { + (*mb)++; + return L'\0'; + } handled in singlebyte code */ + *mb += len; + return wc; +} + +#define regexp_h_fetch(mb, islp) ((*(mb) & REGEXP_H_MASK) == 0 ? \ + (*(mb)++&0377): \ + regexp_h_fetchwc(&(mb), islp)) + +static regexp_h_inline wint_t +regexp_h_showwc(const char *mb) +{ + wchar_t wc; + + if (mbtowc(&wc, mb, regexp_h_mbcurmax) < 0) + return WEOF; + return wc; +} + +#define regexp_h_show(mb) ((*(mb) & REGEXP_H_MASK) == 0 ? (*(mb)&0377): \ + regexp_h_showwc(mb)) + +/* + * Return the character immediately preceding mb. Since no byte is + * required to be the first byte of a character, the longest multibyte + * character ending at &[mb-1] is searched. + */ +static regexp_h_inline wint_t +regexp_h_previous(const char *mb) +{ + const char *p = mb; + wchar_t wc, lastwc = WEOF; + int len, max = 0; + + if (regexp_h_firstwc == NULL || mb <= regexp_h_firstwc) + return (mb > regexp_h_bol ? (mb[-1] & 0377) : WEOF); + while (p-- > regexp_h_bol) { + mbtowc(NULL, NULL, 0); + if ((len = mbtowc(&wc, p, mb - p)) >= 0) { + if (len < max || len < mb - p) + break; + max = len; + lastwc = wc; + } else if (len < 0 && max > 0) + break; + } + return lastwc; +} + +#define regexp_h_cclass(set, c, af) \ + ((c) == 0 || (c) == WEOF ? 0 : ( \ + ((c) > 0177) ? \ + regexp_h_cclass_wc(set, c, af) : ( \ + REGEXP_H_IS_THERE((set)+1, (c)) ? (af) : !(af) \ + ) \ + ) \ + ) + +static regexp_h_inline int +regexp_h_cclass_wc(const char *set, register wint_t c, int af) +{ + register wint_t wc, wl = WEOF; + const char *end; + + end = &set[18] + set[0] - 1; + set += 17; + while (set < end) { + wc = regexp_h_fetch(set, 0); +#ifdef REGEXP_H_VI_BACKSLASH + if (wc == '\\' && set < end && + (*set == ']' || *set == '-' || + *set == '^' || *set == '\\')) { + wc = regexp_h_fetch(set, 0); + } else +#endif /* REGEXP_H_VI_BACKSLASH */ + if (wc == '-' && wl != WEOF && set < end) { + wc = regexp_h_fetch(set, 0); +#ifdef REGEXP_H_VI_BACKSLASH + if (wc == '\\' && set < end && + (*set == ']' || *set == '-' || + *set == '^' || *set == '\\')) { + wc = regexp_h_fetch(set, 0); + } +#endif /* REGEXP_H_VI_BACKSLASH */ + if (c > wl && c < wc) + return af; + } + if (c == wc) + return af; + wl = wc; + } + return !af; +} +#else /* !REGEXP_H_WCHARS */ +#define regexp_h_wchars 0 +#define regexp_h_getwc(c) { c = GETC(); } +#endif /* !REGEXP_H_WCHARS */ + +regexp_h_static char * +compile(char *instring, char *ep, const char *endbuf, int seof) +{ + INIT /* Dependent declarations and initializations */ + register int c; + register int eof = seof; + char *lastep = instring; + int cclcnt; + char bracket[NBRA], *bracketp; + int closed; + char neg; + int lc; + int i, cflg; + +#ifdef REGEXP_H_WCHARS + char *eq; + regexp_h_mbcurmax = MB_CUR_MAX; + regexp_h_wchars = regexp_h_mbcurmax > 1 ? CMB : 0; +#endif + lastep = 0; + bracketp = bracket; + if((c = GETC()) == eof || c == '\n') { + if (c == '\n') { + UNGETC(c); + nodelim = 1; + } + if(*ep == 0 && !sed) + ERROR(41); + if (bracketp > bracket) + ERROR(42); + RETURN(ep); + } + circf = closed = nbra = 0; + if (c == '^') + circf++; + else + UNGETC(c); + for (;;) { + if (ep >= endbuf) + ERROR(50); + regexp_h_getwc(c); + if(c != '*' && ((c != '\\') || (PEEKC() != '{'))) + lastep = ep; + if (c == eof) { + *ep++ = CCEOF; + if (bracketp > bracket) + ERROR(42); + RETURN(ep); + } + switch (c) { + + case '.': + *ep++ = CDOT|regexp_h_wchars; + continue; + + case '\n': + if (sed == 0) { + UNGETC(c); + *ep++ = CCEOF; + nodelim = 1; + RETURN(ep); + } + ERROR(36); + case '*': + if (lastep==0 || *lastep==CBRA || *lastep==CKET || + *lastep==(CBRC|regexp_h_wchars) || + *lastep==(CLET|regexp_h_wchars)) + goto defchar; + *lastep |= STAR; + continue; + + case '$': + if(PEEKC() != eof) + goto defchar; + *ep++ = CDOL; + continue; + + case '[': +#ifdef REGEXP_H_WCHARS + if (regexp_h_wchars == 0) { +#endif + if(&ep[33] >= endbuf) + ERROR(50); + + *ep++ = CCL; + lc = 0; + for(i = 0; i < 32; i++) + ep[i] = 0; + + neg = 0; + if((c = GETC()) == '^') { + neg = 1; + c = GETC(); + } + + do { + c &= 0377; + if(c == '\0' || c == '\n') + ERROR(49); +#ifdef REGEXP_H_VI_BACKSLASH + if(c == '\\' && ((c = PEEKC()) == ']' || + c == '-' || c == '^' || + c == '\\')) { + c = GETC(); + c &= 0377; + } else +#endif /* REGEXP_H_VI_BACKSLASH */ + if(c == '-' && lc != 0) { + if ((c = GETC()) == ']') { + PLACE('-'); + break; + } +#ifdef REGEXP_H_VI_BACKSLASH + if(c == '\\' && + ((c = PEEKC()) == ']' || + c == '-' || + c == '^' || + c == '\\')) + c = GETC(); +#endif /* REGEXP_H_VI_BACKSLASH */ + c &= 0377; + while(lc < c) { + PLACE(lc); + lc++; + } + } + lc = c; + PLACE(c); + } while((c = GETC()) != ']'); + if(neg) { + for(cclcnt = 0; cclcnt < 32; cclcnt++) + ep[cclcnt] ^= 0377; + ep[0] &= 0376; + } + + ep += 32; +#ifdef REGEXP_H_WCHARS + } else { + if (&ep[18] >= endbuf) + ERROR(50); + *ep++ = CCL|CMB; + *ep++ = 0; + lc = 0; + for (i = 0; i < 16; i++) + ep[i] = 0; + eq = &ep[16]; + regexp_h_getwc(c); + if (c == L'^') { + regexp_h_getwc(c); + ep[-2] = CNCL|CMB; + } + do { + if (c == '\0' || c == '\n') + ERROR(49); +#ifdef REGEXP_H_VI_BACKSLASH + if(c == '\\' && ((c = PEEKC()) == ']' || + c == '-' || c == '^' || + c == '\\')) { + regexp_h_store(c, eq, endbuf); + regexp_h_getwc(c); + } else +#endif /* REGEXP_H_VI_BACKSLASH */ + if (c == '-' && lc != 0 && lc <= 0177) { + regexp_h_store(c, eq, endbuf); + regexp_h_getwc(c); + if (c == ']') { + PLACE('-'); + break; + } +#ifdef REGEXP_H_VI_BACKSLASH + if(c == '\\' && + ((c = PEEKC()) == ']' || + c == '-' || + c == '^' || + c == '\\')) { + regexp_h_store(c, eq, + endbuf); + regexp_h_getwc(c); + } +#endif /* REGEXP_H_VI_BACKSLASH */ + while (lc < (c & 0177)) { + PLACE(lc); + lc++; + } + } + lc = c; + if (c <= 0177) + PLACE(c); + regexp_h_store(c, eq, endbuf); + regexp_h_getwc(c); + } while (c != L']'); + if ((i = eq - &ep[16]) > 255) + ERROR(50); + lastep[1] = i; + ep = eq; + } +#endif /* REGEXP_H_WCHARS */ + + continue; + + case '\\': + regexp_h_getwc(c); + switch(c) { + + case '(': + if(nbra >= NBRA) + ERROR(43); + *bracketp++ = nbra; + *ep++ = CBRA; + *ep++ = nbra++; + continue; + + case ')': + if(bracketp <= bracket) + ERROR(42); + *ep++ = CKET; + *ep++ = *--bracketp; + closed++; + continue; + + case '<': + *ep++ = CBRC|regexp_h_wchars; + continue; + + case '>': + *ep++ = CLET|regexp_h_wchars; + continue; + + case '{': + if(lastep == (char *) (0)) + goto defchar; + *lastep |= RNGE; + cflg = 0; + nlim: + c = GETC(); + i = 0; + do { + if ('0' <= c && c <= '9') + i = 10 * i + c - '0'; + else + ERROR(16); + } while(((c = GETC()) != '\\') && (c != ',')); + if (i > 255) + ERROR(11); + *ep++ = i; + if (c == ',') { + if(cflg++) + ERROR(44); + if((c = GETC()) == '\\') { + *ep++ = (char)255; + *lastep |= REGEXP_H_LEAST; + } else { + UNGETC(c); + goto nlim; /* get 2'nd number */ + } + } + if(GETC() != '}') + ERROR(45); + if(!cflg) /* one number */ + *ep++ = i; + else if((ep[-1] & 0377) < (ep[-2] & 0377)) + ERROR(46); + continue; + + case '\n': + ERROR(36); + + case 'n': + c = '\n'; + goto defchar; + + default: + if(c >= '1' && c <= '9') { + if((c -= '1') >= closed) + ERROR(25); + *ep++ = CBACK; + *ep++ = c; + continue; + } + } + /* Drop through to default to use \ to turn off special chars */ + + defchar: + default: + lastep = ep; +#ifdef REGEXP_H_WCHARS + if (regexp_h_wchars == 0) { +#endif + *ep++ = CCHR; + *ep++ = c; +#ifdef REGEXP_H_WCHARS + } else { + char mbbuf[MB_LEN_MAX]; + + switch (wctomb(mbbuf, c)) { + case 1: *ep++ = CCH1; + break; + case 2: *ep++ = CCH2; + break; + case 3: *ep++ = CCH3; + break; + default: + *ep++ = CCHR|CMB; + } + regexp_h_store(c, ep, endbuf); + } +#endif /* REGEXP_H_WCHARS */ + } + } +} + +int +step(const char *p1, const char *p2) +{ + register int c; +#ifdef REGEXP_H_WCHARS + register int d; +#endif /* REGEXP_H_WCHARS */ + + REGEXP_H_STEP_INIT /* get circf */ + regexp_h_bol = p1; +#ifdef REGEXP_H_WCHARS + regexp_h_firstwc = NULL; +#endif /* REGEXP_H_WCHARS */ + if (circf) { + loc1 = (char *)p1; + return(regexp_h_advance(p1, p2)); + } + /* fast check for first character */ + if (*p2==CCHR) { + c = p2[1] & 0377; + do { + if ((*p1 & 0377) != c) + continue; + if (regexp_h_advance(p1, p2)) { + loc1 = (char *)p1; + return(1); + } + } while (*p1++); + return(0); + } +#ifdef REGEXP_H_WCHARS + else if (*p2==CCH1) { + do { + if (p1[0] == p2[1] && regexp_h_advance(p1, p2)) { + loc1 = (char *)p1; + return(1); + } + c = regexp_h_fetch(p1, 1); + } while (c); + return(0); + } else if (*p2==CCH2) { + do { + if (p1[0] == p2[1] && p1[1] == p2[2] && + regexp_h_advance(p1, p2)) { + loc1 = (char *)p1; + return(1); + } + c = regexp_h_fetch(p1, 1); + } while (c); + return(0); + } else if (*p2==CCH3) { + do { + if (p1[0] == p2[1] && p1[1] == p2[2] && p1[2] == p2[3]&& + regexp_h_advance(p1, p2)) { + loc1 = (char *)p1; + return(1); + } + c = regexp_h_fetch(p1, 1); + } while (c); + return(0); + } else if ((*p2&0377)==(CCHR|CMB)) { + d = regexp_h_fetch(p2, 0); + do { + c = regexp_h_fetch(p1, 1); + if (c == d && regexp_h_advance(p1, p2)) { + loc1 = (char *)p1; + return(1); + } + } while(c); + return(0); + } + /* regular algorithm */ + if (regexp_h_wchars) + do { + if (regexp_h_advance(p1, p2)) { + loc1 = (char *)p1; + return(1); + } + c = regexp_h_fetch(p1, 1); + } while (c); + else +#endif /* REGEXP_H_WCHARS */ + do { + if (regexp_h_advance(p1, p2)) { + loc1 = (char *)p1; + return(1); + } + } while (*p1++); + return(0); +} + +#ifdef REGEXP_H_WCHARS +/* + * It is painfully slow to read character-wise backwards in a + * multibyte string (see regexp_h_previous() above). For the star + * algorithm, we therefore keep track of every character as it is + * read in forward direction. + * + * Don't use alloca() for stack blocks since there is no measurable + * speedup and huge amounts of memory are used up for long input + * lines. + */ +#ifndef REGEXP_H_STAKBLOK +#define REGEXP_H_STAKBLOK 1000 +#endif + +struct regexp_h_stack { + struct regexp_h_stack *s_nxt; + struct regexp_h_stack *s_prv; + const char *s_ptr[REGEXP_H_STAKBLOK]; +}; + +#define regexp_h_push(sb, sp, sc, lp) (regexp_h_wchars ? \ + regexp_h_pushwc(sb, sp, sc, lp) : (void)0) + +static regexp_h_inline void +regexp_h_pushwc(struct regexp_h_stack **sb, + struct regexp_h_stack **sp, + const char ***sc, const char *lp) +{ + if (regexp_h_firstwc == NULL || lp < regexp_h_firstwc) + return; + if (*sb == NULL) { + if ((*sb = regexp_h_malloc(sizeof **sb)) == NULL) + return; + (*sb)->s_nxt = (*sb)->s_prv = NULL; + *sp = *sb; + *sc = &(*sb)->s_ptr[0]; + } else if (*sc >= &(*sp)->s_ptr[REGEXP_H_STAKBLOK]) { + if ((*sp)->s_nxt == NULL) { + struct regexp_h_stack *bq; + + if ((bq = regexp_h_malloc(sizeof *bq)) == NULL) + return; + bq->s_nxt = NULL; + bq->s_prv = *sp; + (*sp)->s_nxt = bq; + *sp = bq; + } else + *sp = (*sp)->s_nxt; + *sc = &(*sp)->s_ptr[0]; + } + *(*sc)++ = lp; +} + +static regexp_h_inline const char * +regexp_h_pop(struct regexp_h_stack **sb, struct regexp_h_stack **sp, + const char ***sc, const char *lp) +{ + if (regexp_h_firstwc == NULL || lp <= regexp_h_firstwc) + return &lp[-1]; + if (*sp == NULL) + return regexp_h_firstwc; + if (*sc == &(*sp)->s_ptr[0]) { + if ((*sp)->s_prv == NULL) { + regexp_h_free(*sp); + *sp = NULL; + *sb = NULL; + return regexp_h_firstwc; + } + *sp = (*sp)->s_prv; + regexp_h_free((*sp)->s_nxt); + (*sp)->s_nxt = NULL ; + *sc = &(*sp)->s_ptr[REGEXP_H_STAKBLOK]; + } + return *(--(*sc)); +} + +static void +regexp_h_zerostak(struct regexp_h_stack **sb, struct regexp_h_stack **sp) +{ + for (*sp = *sb; *sp && (*sp)->s_nxt; *sp = (*sp)->s_nxt) + if ((*sp)->s_prv) + regexp_h_free((*sp)->s_prv); + if (*sp) { + if ((*sp)->s_prv) + regexp_h_free((*sp)->s_prv); + regexp_h_free(*sp); + } + *sp = *sb = NULL; +} +#else /* !REGEXP_H_WCHARS */ +#define regexp_h_push(sb, sp, sc, lp) +#endif /* !REGEXP_H_WCHARS */ + +static int +regexp_h_advance(const char *lp, const char *ep) +{ + register const char *curlp; + int c, least; +#ifdef REGEXP_H_WCHARS + int d; + struct regexp_h_stack *sb = NULL, *sp = NULL; + const char **sc; +#endif /* REGEXP_H_WCHARS */ + char *bbeg; + int ct; + + for (;;) switch (least = *ep++ & 0377, least & ~REGEXP_H_LEAST) { + + case CCHR: +#ifdef REGEXP_H_WCHARS + case CCH1: +#endif + if (*ep++ == *lp++) + continue; + return(0); + +#ifdef REGEXP_H_WCHARS + case CCHR|CMB: + if (regexp_h_fetch(ep, 0) == regexp_h_fetch(lp, 1)) + continue; + return(0); + + case CCH2: + if (ep[0] == lp[0] && ep[1] == lp[1]) { + ep += 2, lp += 2; + continue; + } + return(0); + + case CCH3: + if (ep[0] == lp[0] && ep[1] == lp[1] && ep[2] == lp[2]) { + ep += 3, lp += 3; + continue; + } + return(0); +#endif /* REGEXP_H_WCHARS */ + + case CDOT: + if (*lp++) + continue; + return(0); +#ifdef REGEXP_H_WCHARS + case CDOT|CMB: + if ((c = regexp_h_fetch(lp, 1)) != L'\0' && c != WEOF) + continue; + return(0); +#endif /* REGEXP_H_WCHARS */ + + case CDOL: + if (*lp==0) + continue; + return(0); + + case CCEOF: + loc2 = (char *)lp; + return(1); + + case CCL: + c = *lp++ & 0377; + if(ISTHERE(c)) { + ep += 32; + continue; + } + return(0); + +#ifdef REGEXP_H_WCHARS + case CCL|CMB: + case CNCL|CMB: + c = regexp_h_fetch(lp, 1); + if (regexp_h_cclass(ep, c, (ep[-1] & 0377) == (CCL|CMB))) { + ep += (*ep & 0377) + 17; + continue; + } + return 0; +#endif /* REGEXP_H_WCHARS */ + + case CBRA: + braslist[*ep++ & 0377] = (char *)lp; + continue; + + case CKET: + braelist[*ep++ & 0377] = (char *)lp; + continue; + + case CBRC: + if (lp == regexp_h_bol && locs == NULL) + continue; + if ((isdigit(lp[0] & 0377) || regexp_h_uletter(lp[0] & 0377)) + && !regexp_h_uletter(lp[-1] & 0377) + && !isdigit(lp[-1] & 0377)) + continue; + return(0); + +#ifdef REGEXP_H_WCHARS + case CBRC|CMB: + c = regexp_h_show(lp); + d = regexp_h_previous(lp); + if ((iswdigit(c) || regexp_h_wuletter(c)) + && !regexp_h_wuletter(d) + && !iswdigit(d)) + continue; + return(0); +#endif /* REGEXP_H_WCHARS */ + + case CLET: + if (!regexp_h_uletter(lp[0] & 0377) && !isdigit(lp[0] & 0377)) + continue; + return(0); + +#ifdef REGEXP_H_WCHARS + case CLET|CMB: + c = regexp_h_show(lp); + if (!regexp_h_wuletter(c) && !iswdigit(c)) + continue; + return(0); +#endif /* REGEXP_H_WCHARS */ + + case CCHR|RNGE: + c = *ep++; + regexp_h_getrnge(ep, least); + while(low--) + if(*lp++ != c) + return(0); + curlp = lp; + while(size--) { + regexp_h_push(&sb, &sp, &sc, lp); + if(*lp++ != c) + break; + } + if(size < 0) { + regexp_h_push(&sb, &sp, &sc, lp); + lp++; + } + ep += 2; + goto star; + +#ifdef REGEXP_H_WCHARS + case CCHR|RNGE|CMB: + case CCH1|RNGE: + case CCH2|RNGE: + case CCH3|RNGE: + c = regexp_h_fetch(ep, 0); + regexp_h_getrnge(ep, least); + while (low--) + if (regexp_h_fetch(lp, 1) != c) + return 0; + curlp = lp; + while (size--) { + regexp_h_push(&sb, &sp, &sc, lp); + if (regexp_h_fetch(lp, 1) != c) + break; + } + if(size < 0) { + regexp_h_push(&sb, &sp, &sc, lp); + regexp_h_fetch(lp, 1); + } + ep += 2; + goto star; +#endif /* REGEXP_H_WCHARS */ + + case CDOT|RNGE: + regexp_h_getrnge(ep, least); + while(low--) + if(*lp++ == '\0') + return(0); + curlp = lp; + while(size--) { + regexp_h_push(&sb, &sp, &sc, lp); + if(*lp++ == '\0') + break; + } + if(size < 0) { + regexp_h_push(&sb, &sp, &sc, lp); + lp++; + } + ep += 2; + goto star; + +#ifdef REGEXP_H_WCHARS + case CDOT|RNGE|CMB: + regexp_h_getrnge(ep, least); + while (low--) + if ((c = regexp_h_fetch(lp, 1)) == L'\0' || c == WEOF) + return 0; + curlp = lp; + while (size--) { + regexp_h_push(&sb, &sp, &sc, lp); + if ((c = regexp_h_fetch(lp, 1)) == L'\0' || c == WEOF) + break; + } + if (size < 0) { + regexp_h_push(&sb, &sp, &sc, lp); + regexp_h_fetch(lp, 1); + } + ep += 2; + goto star; +#endif /* REGEXP_H_WCHARS */ + + case CCL|RNGE: + regexp_h_getrnge(ep + 32, least); + while(low--) { + c = *lp++ & 0377; + if(!ISTHERE(c)) + return(0); + } + curlp = lp; + while(size--) { + regexp_h_push(&sb, &sp, &sc, lp); + c = *lp++ & 0377; + if(!ISTHERE(c)) + break; + } + if(size < 0) { + regexp_h_push(&sb, &sp, &sc, lp); + lp++; + } + ep += 34; /* 32 + 2 */ + goto star; + +#ifdef REGEXP_H_WCHARS + case CCL|RNGE|CMB: + case CNCL|RNGE|CMB: + regexp_h_getrnge(ep + (*ep & 0377) + 17, least); + while (low--) { + c = regexp_h_fetch(lp, 1); + if (!regexp_h_cclass(ep, c, + (ep[-1] & 0377 & ~REGEXP_H_LEAST) + == (CCL|RNGE|CMB))) + return 0; + } + curlp = lp; + while (size--) { + regexp_h_push(&sb, &sp, &sc, lp); + c = regexp_h_fetch(lp, 1); + if (!regexp_h_cclass(ep, c, + (ep[-1] & 0377 & ~REGEXP_H_LEAST) + == (CCL|RNGE|CMB))) + break; + } + if (size < 0) { + regexp_h_push(&sb, &sp, &sc, lp); + regexp_h_fetch(lp, 1); + } + ep += (*ep & 0377) + 19; + goto star; +#endif /* REGEXP_H_WCHARS */ + + case CBACK: + bbeg = braslist[*ep & 0377]; + ct = braelist[*ep++ & 0377] - bbeg; + + if(strncmp(bbeg, lp, ct) == 0) { + lp += ct; + continue; + } + return(0); + + case CBACK|STAR: + bbeg = braslist[*ep & 0377]; + ct = braelist[*ep++ & 0377] - bbeg; + curlp = lp; + while(strncmp(bbeg, lp, ct) == 0) + lp += ct; + + while(lp >= curlp) { + if(regexp_h_advance(lp, ep)) return(1); + lp -= ct; + } + return(0); + + + case CDOT|STAR: + curlp = lp; + do + regexp_h_push(&sb, &sp, &sc, lp); + while (*lp++); + goto star; + +#ifdef REGEXP_H_WCHARS + case CDOT|STAR|CMB: + curlp = lp; + do + regexp_h_push(&sb, &sp, &sc, lp); + while ((c = regexp_h_fetch(lp, 1)) != L'\0' && c != WEOF); + goto star; +#endif /* REGEXP_H_WCHARS */ + + case CCHR|STAR: + curlp = lp; + do + regexp_h_push(&sb, &sp, &sc, lp); + while (*lp++ == *ep); + ep++; + goto star; + +#ifdef REGEXP_H_WCHARS + case CCHR|STAR|CMB: + case CCH1|STAR: + case CCH2|STAR: + case CCH3|STAR: + curlp = lp; + d = regexp_h_fetch(ep, 0); + do + regexp_h_push(&sb, &sp, &sc, lp); + while (regexp_h_fetch(lp, 1) == d); + goto star; +#endif /* REGEXP_H_WCHARS */ + + case CCL|STAR: + curlp = lp; + do { + regexp_h_push(&sb, &sp, &sc, lp); + c = *lp++ & 0377; + } while(ISTHERE(c)); + ep += 32; + goto star; + +#ifdef REGEXP_H_WCHARS + case CCL|STAR|CMB: + case CNCL|STAR|CMB: + curlp = lp; + do { + regexp_h_push(&sb, &sp, &sc, lp); + c = regexp_h_fetch(lp, 1); + } while (regexp_h_cclass(ep, c, (ep[-1] & 0377) + == (CCL|STAR|CMB))); + ep += (*ep & 0377) + 17; + goto star; +#endif /* REGEXP_H_WCHARS */ + + star: +#ifdef REGEXP_H_WCHARS + if (regexp_h_wchars == 0) { +#endif + do { + if(--lp == locs) + break; + if (regexp_h_advance(lp, ep)) + return(1); + } while (lp > curlp); +#ifdef REGEXP_H_WCHARS + } else { + do { + lp = regexp_h_pop(&sb, &sp, &sc, lp); + if (lp <= locs) + break; + if (regexp_h_advance(lp, ep)) { + regexp_h_zerostak(&sb, &sp); + return(1); + } + } while (lp > curlp); + regexp_h_zerostak(&sb, &sp); + } +#endif /* REGEXP_H_WCHARS */ + return(0); + + } +} + +static void +regexp_h_getrnge(register const char *str, int least) +{ + low = *str++ & 0377; + size = least & REGEXP_H_LEAST ? /*20000*/INT_MAX : (*str & 0377) - low; +} + +int +advance(const char *lp, const char *ep) +{ + REGEXP_H_ADVANCE_INIT /* skip past circf */ + regexp_h_bol = lp; +#ifdef REGEXP_H_WCHARS + regexp_h_firstwc = NULL; +#endif /* REGEXP_H_WCHARS */ + return regexp_h_advance(lp, ep); +} diff --git a/package/heirloom-cpio/src/regexpr.c b/package/heirloom-cpio/src/regexpr.c new file mode 100644 index 000000000..40dceb525 --- /dev/null +++ b/package/heirloom-cpio/src/regexpr.c @@ -0,0 +1,90 @@ +/* + * Simple Regular Expression functions. Derived from Unix 7th Edition, + * /usr/src/cmd/expr.y + * + * Modified by Gunnar Ritter, Freiburg i. Br., Germany, January 2003. + * + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``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 CALDERA INTERNATIONAL, INC. 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. + */ + +/* Sccsid @(#)regexpr.c 1.8 (gritter) 10/13/04 */ + +#include +#include "regexpr.h" + +int regerrno, reglength; +static int circf; + +static char *regexpr_compile(char *, char *, const char *, int); + +char * +compile(const char *instring, char *ep, char *endbuf) +{ + char *cp; + int sz = 0; + + if (ep == 0) { + for (cp = (char *)instring; *cp != '\0'; cp++) + if (*cp == '[') + sz += 32; + sz += 2 * (cp - instring) + 5; + if ((ep = malloc(sz)) == 0) { + regerrno = 11; + return 0; + } + endbuf = &ep[sz]; + ep[1] = '\0'; + } + if ((cp=regexpr_compile((char *)instring, &ep[1], endbuf, '\0')) == 0) { + if (sz) + free(ep); + return 0; + } + ep[0] = circf; + reglength = cp - ep; + return sz ? ep : cp; +} + +#define INIT register char *sp = instring; +#define GETC() (*sp++) +#define PEEKC() (*sp) +#define UNGETC(c) (--sp) +#define RETURN(c) return (c); +#define ERROR(c) { regerrno = c; return 0; } + +#define compile(a, b, c, d) regexpr_compile(a, b, c, d) +#define regexp_h_static static +#define REGEXP_H_STEP_INIT circf = *p2++; +#define REGEXP_H_ADVANCE_INIT circf = *ep++; + +#include "regexp.h" diff --git a/package/heirloom-cpio/src/regexpr.h b/package/heirloom-cpio/src/regexpr.h new file mode 100644 index 000000000..74f4a1426 --- /dev/null +++ b/package/heirloom-cpio/src/regexpr.h @@ -0,0 +1,53 @@ +/* + * Simple Regular Expression functions. Derived from Unix 7th Edition, + * /usr/src/cmd/expr.y + * + * Modified by Gunnar Ritter, Freiburg i. Br., Germany, January 2003. + * + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``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 CALDERA INTERNATIONAL, INC. 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. + */ + +/* Sccsid @(#)regexpr.h 1.2 (gritter) 1/11/03 */ + +#define NBRA 9 + +extern char *braslist[NBRA]; +extern char *braelist[NBRA]; +extern int nbra; +extern int regerrno, reglength; +extern char *loc1, *loc2, *locs; +extern int sed; + +extern char *compile(const char *, char *, char *); +extern int step(const char *, const char *); +extern int advance(const char *, const char *); diff --git a/package/heirloom-cpio/src/setlabel.c b/package/heirloom-cpio/src/setlabel.c new file mode 100644 index 000000000..a1db0646e --- /dev/null +++ b/package/heirloom-cpio/src/setlabel.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)setlabel.c 1.1 (gritter) 9/21/03 */ + +extern char *pfmt_label__; + +int +setlabel(const char *s) +{ + static char lbuf[26]; + char *lp; + + if (s && s[0]) { + for (lp = lbuf; *s && lp < &lbuf[sizeof lbuf-1]; s++, lp++) + *lp = *s; + *lp = '\0'; + pfmt_label__ = lbuf; + } else + pfmt_label__ = 0; + return 0; +} diff --git a/package/heirloom-cpio/src/setuxlabel.c b/package/heirloom-cpio/src/setuxlabel.c new file mode 100644 index 000000000..9d304869e --- /dev/null +++ b/package/heirloom-cpio/src/setuxlabel.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)setuxlabel.c 1.1 (gritter) 9/21/03 */ + +#include "msgselect.h" + +extern char *pfmt_label__; + +int +setuxlabel(const char *s) +{ + static char lbuf[msgselect(29,26)]; + char *lp, *mp; + + if (s && s[0]) { + lp = lbuf; + mp = msgselect("UX:",""); + while (*mp) + *lp++ = *mp++; + lbuf[0] = 'U', lbuf[1] = 'X', lbuf[2] = ':'; + while (*s && lp < &lbuf[sizeof lbuf-1]) + *lp++ = *s++; + *lp = '\0'; + pfmt_label__ = lbuf; + } else + pfmt_label__ = 0; + return 0; +} diff --git a/package/heirloom-cpio/src/sfile.c b/package/heirloom-cpio/src/sfile.c new file mode 100644 index 000000000..089d85fdf --- /dev/null +++ b/package/heirloom-cpio/src/sfile.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)sfile.c 1.9 (gritter) 6/7/04 */ + +#ifdef __linux__ +#undef _FILE_OFFSET_BITS + +#include +#include +#include +#include +#include +#include +#include "sfile.h" + +long long +sfile(int dfd, int sfd, mode_t mode, long long count) +{ + static int enosys, einval, success; + off_t offset; + ssize_t sent, total; + extern void writerr(void *, int, int); + /* + * A process is not interruptible while executing a sendfile() + * system call. So it is not advisable to to send an entire + * file with one call; it is sent in parts so signals can + * be delivered in between. + */ + const ssize_t chunk = 196608; + + /* + * If a previous call returned ENOSYS, the operating system does + * not support sendfile() at all and it makes no sense to try it + * again. + * + * If a previous call returned EINVAL and there was no successful + * call yet, it is very likely that this is a permanent error + * condition (on Linux 2.6.0-test4, sendfile() may be used for + * socket targets only; older versions don't support tmpfs as + * source file system etc.). + */ + if (enosys || !success && einval || + (mode&S_IFMT) != S_IFREG || count > SSIZE_MAX) + return 0; + offset = lseek(sfd, 0, SEEK_CUR); + sent = 0, total = 0; + while (count > 0 && (sent = sendfile(dfd, sfd, &offset, + count > chunk ? chunk : count)) > 0) { + count -= sent, total += sent; + } + if (total && lseek(sfd, offset, SEEK_SET) == (off_t)-1) + return -1; + if (count == 0 || sent == 0) { + success = 1; + return total; + } + switch (errno) { + case ENOSYS: + enosys = 1; + return 0; + case EINVAL: + einval = 1; + return 0; + case ENOMEM: + return 0; + default: + writerr(NULL, count > chunk ? chunk : count, 0); + return -1; + } +} +#else /* !__linux__ */ +#include + +/*ARGSUSED*/ +long long +sfile(int dfd, int sfd, mode_t mode, long long count) +{ + return 0; +} +#endif /* __linux__ */ diff --git a/package/heirloom-cpio/src/sfile.h b/package/heirloom-cpio/src/sfile.h new file mode 100644 index 000000000..53d832a6f --- /dev/null +++ b/package/heirloom-cpio/src/sfile.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)sfile.h 1.4 (gritter) 4/17/03 */ + +/* + * Return values: + * + * src_size The entire range has been copied. The file offset of both + * dst_fd and src_fd have been set to this position. The + * operation has been completed successfully. + * + * >0 Number of bytes written. The file offset of both dst_fd + * and src_fd have been set to this position. The operation + * may continue using read()/write(). + * + * 0 No data was written; operation may continue. + * + * -1 An error occured; operation may not continue. + */ +extern long long sfile(int dst_fd, int src_fd, mode_t src_mode, + long long src_size); diff --git a/package/heirloom-cpio/src/sighold.c b/package/heirloom-cpio/src/sighold.c new file mode 100644 index 000000000..bae3bc393 --- /dev/null +++ b/package/heirloom-cpio/src/sighold.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2004 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)sighold.c 1.7 (gritter) 1/22/06 */ + +#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ + defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ + defined (__UCLIBC__) +#include +#include "sigset.h" + +int +sighold(int sig) +{ + sigset_t set, oset; + + if (sig <= 0) + return -1; + sigemptyset(&set); + sigaddset(&set, sig); + return sigprocmask(SIG_BLOCK, &set, &oset); +} +#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || + __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/package/heirloom-cpio/src/sigignore.c b/package/heirloom-cpio/src/sigignore.c new file mode 100644 index 000000000..6938ef676 --- /dev/null +++ b/package/heirloom-cpio/src/sigignore.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2004 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)sigignore.c 1.6 (gritter) 1/22/06 */ + +#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ + defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) +#include +#include "sigset.h" + +int +sigignore(int sig) +{ + struct sigaction act; + + if (sig <= 0) + return -1; + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + if (sig == SIGCHLD) + act.sa_flags |= SA_NOCLDSTOP|SA_NOCLDWAIT; + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask, sig); + return sigaction(sig, &act, (struct sigaction *)0); +} +#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || + __DragonFly__ || __APPLE__ */ diff --git a/package/heirloom-cpio/src/signal.c b/package/heirloom-cpio/src/signal.c new file mode 100644 index 000000000..1f9d51cb7 --- /dev/null +++ b/package/heirloom-cpio/src/signal.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2004 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)signal.c 1.6 (gritter) 1/22/06 */ + +#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ + defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ + defined (__UCLIBC__) +#include +#include "sigset.h" + +void (*signal(int sig, void (*func)(int)))(int) +{ + struct sigaction nact, oact; + + if (sig <= 0) + return SIG_ERR; + nact.sa_handler = func; + nact.sa_flags = SA_RESETHAND|SA_NODEFER; + if (sig == SIGCHLD && func == SIG_IGN) + nact.sa_flags |= SA_NOCLDSTOP|SA_NOCLDWAIT; + sigemptyset(&nact.sa_mask); + if (sigaction(sig, &nact, &oact) == -1) + return SIG_ERR; + return oact.sa_handler; +} +#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || + __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/package/heirloom-cpio/src/sigpause.c b/package/heirloom-cpio/src/sigpause.c new file mode 100644 index 000000000..504a5ed4d --- /dev/null +++ b/package/heirloom-cpio/src/sigpause.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2004 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)sigpause.c 1.6 (gritter) 1/22/06 */ + +#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ + defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) +#include +#include "sigset.h" + +int +sigpause(int sig) +{ + sigset_t nset, oset; + int ret; + + if (sig <= 0) + return -1; + sigemptyset(&nset); + sigaddset(&nset, sig); + if (sigprocmask(SIG_UNBLOCK, &nset, &oset) < 0) + return -1; + sigemptyset(&nset); + ret = sigsuspend(&nset); + if (sigprocmask(SIG_SETMASK, &oset, (sigset_t *)0) < 0) + ret = -1; + return ret; +} +#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || + __DragonFly__ || __APPLE__ */ diff --git a/package/heirloom-cpio/src/sigrelse.c b/package/heirloom-cpio/src/sigrelse.c new file mode 100644 index 000000000..d74de74bf --- /dev/null +++ b/package/heirloom-cpio/src/sigrelse.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2004 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)sigrelse.c 1.8 (gritter) 1/22/06 */ + +#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ + defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ + defined (__UCLIBC__) +#include +#include "sigset.h" + +int +sigrelse(int sig) +{ + sigset_t set, oset; + + if (sig <= 0) + return -1; + sigemptyset(&set); + sigaddset(&set, sig); + return sigprocmask(SIG_UNBLOCK, &set, &oset); +} +#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || + __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/package/heirloom-cpio/src/sigset.c b/package/heirloom-cpio/src/sigset.c new file mode 100644 index 000000000..d561d541d --- /dev/null +++ b/package/heirloom-cpio/src/sigset.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2004 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)sigset.c 1.7 (gritter) 1/22/06 */ + +#include +#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ + defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ + defined (__UCLIBC__) +#include +#include "sigset.h" + +void (*sigset(int sig, void (*func)(int)))(int) +{ + struct sigaction nact, oact; + sigset_t nset, oset; + + if (sig <= 0) + return SIG_ERR; + sigemptyset(&nset); + sigaddset(&nset, sig); + if (sigprocmask(func==SIG_HOLD?SIG_BLOCK:SIG_UNBLOCK, &nset, &oset) < 0) + return SIG_ERR; + nact.sa_handler = func; + nact.sa_flags = 0; + if (sig == SIGCHLD && func == SIG_IGN) + nact.sa_flags |= SA_NOCLDSTOP|SA_NOCLDWAIT; + sigemptyset(&nact.sa_mask); + sigaddset(&nact.sa_mask, sig); + if (sigaction(sig, func==SIG_HOLD?(struct sigaction *)0:&nact, &oact) + == -1) + return SIG_ERR; + if (sigismember(&oset, sig)) + return SIG_HOLD; + else + return (oact.sa_handler); +} +#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || + __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/package/heirloom-cpio/src/sigset.h b/package/heirloom-cpio/src/sigset.h new file mode 100644 index 000000000..ada73a884 --- /dev/null +++ b/package/heirloom-cpio/src/sigset.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2004 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)sigset.h 1.9 (gritter) 1/22/06 */ + +#include +#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ + defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ + defined (__UCLIBC__) + +#ifndef SIG_HOLD +#define SIG_HOLD ((void (*)(int))2) +#endif /* !SIG_HOLD */ + +extern int sighold(int); +extern int sigignore(int); +//extern int sigpause(int); +extern int sigrelse(int); +extern void (*sigset(int, void (*)(int)))(int); +extern void (*signal(int, void (*)(int)))(int); +#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || + __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/package/heirloom-cpio/src/strtol.c b/package/heirloom-cpio/src/strtol.c new file mode 100644 index 000000000..cd8ecfe7a --- /dev/null +++ b/package/heirloom-cpio/src/strtol.c @@ -0,0 +1,117 @@ +/* Sccsid @(#)strtol.c 1.6 (gritter) 7/18/04 */ + +#if defined (__hpux) || defined (_AIX) || \ + defined (__FreeBSD__) && (__FreeBSD__) < 5 + +#include +#include +#include + +#include "atoll.h" + +#ifdef __hpux +#ifndef _INCLUDE__STDC_A1_SOURCE +#error You must use cc -D_INCLUDE__STDC_A1_SOURCE on HP-UX +#endif +#endif /* __hpux */ + +static long long +internal(const char *nptr, char **endptr, int base, int flags) +{ + const char *pp = nptr, *bptr; + long long v = 0, ov; + int sign = 1; + int c; + int valid = 1; + + /* XXX + * iswspace() should be used. + */ + for (bptr = nptr; isspace(*bptr&0377); bptr++); + if (*bptr == '-') { + sign = -1; + bptr++; + } else if (*bptr == '+') + bptr++; + if (base == 0) { + if (*bptr >= '1' && *bptr <= '9') + base = 10; + else if (*bptr == '0') { + if (bptr[1] == 'x' || bptr[1] == 'X') + base = 16; + else + base = 8; + } else { + if (flags&1) + errno = EINVAL; + goto out; + } + } + if (base < 2 || base > 36) { + if (flags&1) + errno = EINVAL; + goto out; + } + if (base == 16 && bptr[0] == '0' && + (bptr[1] == 'x' || bptr[1] == 'X')) + bptr += 2; + pp = bptr; + for (;;) { + if (*pp >= '0' && *pp <= '9') + c = *pp - '0'; + else if (*pp >= 'a' && *pp <= 'z') + c = *pp - 'a' + 10; + else if (*pp >= 'A' && *pp <= 'A') + c = *pp - 'A' + 10; + else + break; + if (c >= base) + break; + pp++; + if (valid) { + ov = v; + v = v * base + c; + if (flags&1) { + if (flags&2 && (unsigned long long)v < + (unsigned long long)ov || + v < ov) { + sign = 1; + errno = ERANGE; + v = -1; + if ((flags&2)==0) + v = (unsigned long long)v >> 1; + valid = 0; + } + } + } + } +out: if (pp <= bptr) { + if (flags&1) + errno = EINVAL; + if (endptr) + *endptr = (char *)nptr; + } else { + if (endptr) + *endptr = (char *)pp; + } + return v * sign; +} + +long long +strtoll(const char *nptr, char **endptr, int base) +{ + return internal(nptr, endptr, base, 1); +} + +unsigned long long +strtoull(const char *nptr, char **endptr, int base) +{ + return (unsigned long long)internal(nptr, endptr, base, 3); +} + +long long +atoll(const char *nptr) +{ + return internal(nptr, NULL, 10, 0); +} +#endif /* __hpux || _AIX || __FreeBSD__ < 5 */ diff --git a/package/heirloom-cpio/src/unshrink.c b/package/heirloom-cpio/src/unshrink.c new file mode 100644 index 000000000..61f5c507c --- /dev/null +++ b/package/heirloom-cpio/src/unshrink.c @@ -0,0 +1,307 @@ +/* + * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. + * + * Derived from unzip 5.40. + * + * Sccsid @(#)unshrink.c 1.4 (gritter) 6/18/04 + */ +/*--------------------------------------------------------------------------- + + unshrink.c version 1.21 23 Nov 95 + + + NOTE: This code may or may not infringe on the so-called "Welch + patent" owned by Unisys. (From reading the patent, it appears + that a pure LZW decompressor is *not* covered, but this claim has + not been tested in court, and Unisys is reported to believe other- + wise.) It is therefore the responsibility of the user to acquire + whatever license(s) may be required for legal use of this code. + + THE INFO-ZIP GROUP DISCLAIMS ALL LIABILITY FOR USE OF THIS CODE + IN VIOLATION OF APPLICABLE PATENT LAW. + + + Shrinking is basically a dynamic LZW algorithm with allowed code sizes of + up to 13 bits; in addition, there is provision for partial clearing of + leaf nodes. PKWARE uses the special code 256 (decimal) to indicate a + change in code size or a partial clear of the code tree: 256,1 for the + former and 256,2 for the latter. [Note that partial clearing can "orphan" + nodes: the parent-to-be can be cleared before its new child is added, + but the child is added anyway (as an orphan, as though the parent still + existed). When the tree fills up to the point where the parent node is + reused, the orphan is effectively "adopted." Versions prior to 1.05 were + affected more due to greater use of pointers (to children and siblings + as well as parents).] + + This replacement version of unshrink.c was written from scratch. It is + based only on the algorithms described in Mark Nelson's _The Data Compres- + sion Book_ and in Terry Welch's original paper in the June 1984 issue of + IEEE _Computer_; no existing source code, including any in Nelson's book, + was used. + + Memory requirements have been reduced in this version and are now no more + than the original Sam Smith code. This is still larger than any of the + other algorithms: at a minimum, 8K+8K+16K (stack+values+parents) assuming + 16-bit short ints, and this does not even include the output buffer (the + other algorithms leave the uncompressed data in the work area, typically + called slide[]). For machines with a 64KB data space this is a problem, + particularly when text conversion is required and line endings have more + than one character. UnZip's solution is to use two roughly equal halves + of outbuf for the ASCII conversion in such a case; the "unshrink" argument + to flush() signals that this is the case. + + For large-memory machines, a second outbuf is allocated for translations, + but only if unshrinking and only if translations are required. + + | binary mode | text mode + --------------------------------------------------- + big mem | big outbuf | big outbuf + big outbuf2 <- malloc'd here + small mem | small outbuf | half + half small outbuf + + Copyright 1994, 1995 Greg Roelofs. See the accompanying file "COPYING" + in UnZip 5.20 (or later) source or binary distributions. + + From "COPYING": + + The following copyright applies to the new version of unshrink.c, + distributed with UnZip version 5.2 and later: + + * Copyright (c) 1994 Greg Roelofs. + * Permission is granted to any individual/institution/corporate + * entity to use, copy, redistribute or modify this software for + * any purpose whatsoever, subject to the conditions noted in the + * Frequently Asked Questions section below, plus one additional + * condition: namely, that my name not be removed from the source + * code. (Other names may, of course, be added as modifications + * are made.) Corporate legal staff (like at IBM :-) ) who have + * problems understanding this can contact me through Zip-Bugs... + + + Q. Can I use the source code of Zip and UnZip in my commercial + application? + + A. Yes, so long as you include in your product an acknowledgment; a + pointer to the original, free compression sources; and a statement + making it clear that there are no extra or hidden charges resulting + from the use of our compression code in your product (see below for + an example). The acknowledgment should appear in at least one piece + of human-readable documentation (e.g., a README file or man page), + although additionally putting it in the executable(s) is OK, too. + In other words, you are allowed to sell only your own work, not ours, + and we'd like a little credit. (Note the additional restrictions + above on the code in unreduce.c, unshrink.c, vms.c, time_lib.c, and + everything in the wince and windll subdirectories.) Contact us at + Zip-Bugs@lists.wku.edu if you have special requirements. We also + like to hear when our code is being used, but we don't require that. + + incorporates compression code from the Info-ZIP group. + There are no extra charges or costs due to the use of this code, + and the original compression sources are freely available from + http://www.cdrom.com/pub/infozip/ or ftp://ftp.cdrom.com/pub/infozip/ + on the Internet. + + If you only need compression capability, not full zipfile support, + you might want to look at zlib instead; it has fewer restrictions + on commercial use. See http://www.cdrom.com/pub/infozip/zlib/ . + + ---------------------------------------------------------------------------*/ + +#include +#include + +#include "cpio.h" +#include "unzip.h" + +static void partial_clear(struct globals *); + +#define trace() + +/* HSIZE is defined as 2^13 (8192) in unzip.h */ +#define BOGUSCODE 256 +#define FLAG_BITS parent /* upper bits of parent[] used as flag bits */ +#define CODE_MASK (HSIZE - 1) /* 0x1fff (lower bits are parent's index) */ +#define FREE_CODE HSIZE /* 0x2000 (code is unused or was cleared) */ +#define HAS_CHILD (HSIZE << 1) /* 0x4000 (code has a child--do not clear) */ + +#define parent G.area.shrink.Parent +#define Value G.area.shrink.value /* "value" conflicts with Pyramid ioctl.h */ +#define stack G.area.shrink.Stack + +/***********************/ +/* Function unshrink() */ +/***********************/ + +int +zipunshrink(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) +{ + struct globals G; + int offset = (HSIZE - 1); + uint8_t *stacktop = stack + offset; + register uint8_t *newstr; + int codesize=9, len, KwKwK; + int16_t code, oldcode, freecode, curcode; + int16_t lastfreecode; + unsigned int outbufsiz; + +/*--------------------------------------------------------------------------- + Initialize various variables. + ---------------------------------------------------------------------------*/ + + memset(&G, 0, sizeof G); + G.tgt = tgt; + G.tfd = tfd; + G.doswap = doswap; + G.crc = crc; + G.zsize = G.uzsize = f->f_csize; + lastfreecode = BOGUSCODE; + + for (code = 0; code < BOGUSCODE; ++code) { + Value[code] = (uint8_t)code; + parent[code] = BOGUSCODE; + } + for (code = BOGUSCODE+1; code < HSIZE; ++code) + parent[code] = FREE_CODE; + + outbufsiz = OUTBUFSIZ; + G.outptr = G.outbuf; + G.outcnt = 0L; + +/*--------------------------------------------------------------------------- + Get and output first code, then loop over remaining ones. + ---------------------------------------------------------------------------*/ + + READBITS(codesize, oldcode) + if (!G.zipeof) { + *G.outptr++ = (uint8_t)oldcode; + ++G.outcnt; + } + + do { + READBITS(codesize, code) + if (G.zipeof) + break; + if (code == BOGUSCODE) { /* possible to have consecutive escapes? */ + READBITS(codesize, code) + if (code == 1) { + ++codesize; + Trace((stderr, " (codesize now %d bits)\n", codesize)); + } else if (code == 2) { + Trace((stderr, " (partial clear code)\n")); + partial_clear(&G); /* clear leafs (nodes with no children) */ + Trace((stderr, " (done with partial clear)\n")); + lastfreecode = BOGUSCODE; /* reset start of free-node search */ + } + continue; + } + + /*----------------------------------------------------------------------- + Translate code: traverse tree from leaf back to root. + -----------------------------------------------------------------------*/ + + newstr = stacktop; + curcode = code; + + if (parent[curcode] == FREE_CODE) { + /* or (FLAG_BITS[curcode] & FREE_CODE)? */ + KwKwK = TRUE; + Trace((stderr, " (found a KwKwK code %d; oldcode = %d)\n", code, + oldcode)); + --newstr; /* last character will be same as first character */ + curcode = oldcode; + } else + KwKwK = FALSE; + + do { + *newstr-- = Value[curcode]; + curcode = (int16_t)(parent[curcode] & CODE_MASK); + } while (curcode != BOGUSCODE); + + len = (int)(stacktop - newstr++); + if (KwKwK) + *stacktop = *newstr; + + /*----------------------------------------------------------------------- + Write expanded string in reverse order to output buffer. + -----------------------------------------------------------------------*/ + + Trace((stderr, "code %4d; oldcode %4d; char %3d (%c); string [", code, + oldcode, (int)(*newstr), (*newstr<32 || *newstr>=127)? ' ':*newstr)); + + { + register uint8_t *p; + + for (p = newstr; p < newstr+len; ++p) { + *G.outptr++ = *p; + if (++G.outcnt == outbufsiz) { + flush(&G, G.outbuf, G.outcnt); + G.outptr = G.outbuf; + G.outcnt = 0L; + } + } + } + + /*----------------------------------------------------------------------- + Add new leaf (first character of newstr) to tree as child of oldcode. + -----------------------------------------------------------------------*/ + + /* search for freecode */ + freecode = (int16_t)(lastfreecode + 1); + /* add if-test before loop for speed? */ + while (parent[freecode] != FREE_CODE) + ++freecode; + lastfreecode = freecode; + Trace((stderr, "]; newcode %d\n", freecode)); + + Value[freecode] = *newstr; + parent[freecode] = oldcode; + oldcode = code; + + } while (!G.zipeof); + +/*--------------------------------------------------------------------------- + Flush any remaining data and return to sender... + ---------------------------------------------------------------------------*/ + + if (G.outcnt > 0L) + flush(&G, G.outbuf, G.outcnt); + + return G.status; + +} /* end function unshrink() */ + + + + + +/****************************/ +/* Function partial_clear() */ /* no longer recursive... */ +/****************************/ + +static void +partial_clear(struct globals *Gp) +{ +#define G (*Gp) + register int16_t code; + + /* clear all nodes which have no children (i.e., leaf nodes only) */ + + /* first loop: mark each parent as such */ + for (code = BOGUSCODE+1; code < HSIZE; ++code) { + register int16_t cparent = (int16_t)(parent[code] & CODE_MASK); + + if (cparent > BOGUSCODE && cparent != FREE_CODE) + FLAG_BITS[cparent] |= HAS_CHILD; /* set parent's child-bit */ + } + + /* second loop: clear all nodes *not* marked as parents; reset flag bits */ + for (code = BOGUSCODE+1; code < HSIZE; ++code) { + if (FLAG_BITS[code] & HAS_CHILD) /* just clear child-bit */ + FLAG_BITS[code] &= ~HAS_CHILD; + else { /* leaf: lose it */ + Trace((stderr, "%d\n", code)); + parent[code] = FREE_CODE; + } + } + + return; +} diff --git a/package/heirloom-cpio/src/unzip.h b/package/heirloom-cpio/src/unzip.h new file mode 100644 index 000000000..d53f81024 --- /dev/null +++ b/package/heirloom-cpio/src/unzip.h @@ -0,0 +1,121 @@ +/* + * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. + * + * Derived from unzip 5.40. + * + * Sccsid @(#)unzip.h 1.5 (gritter) 7/16/04 + */ + +#include + +#define Trace(a) + +#define MAX_BITS 13 +#define HSIZE (1 << MAX_BITS) +#define WSIZE 65536L /* at least 64K for enhanced deflate */ + +#define redirSlide G.area.Slide + +#define NEXTBYTE (--G.incnt >= 0 ? (int)(*G.inptr++) : readbyte(&G)) + +#define READBITS(nbits, zdest) { \ + if (nbits > G.bits_left) { \ + int temp; \ + G.zipeof = 1; \ + while (G.bits_left <= 8 * (int)(sizeof G.bitbuf - 1) && \ + (temp = NEXTBYTE) != EOF) { \ + G.bitbuf |= (uint32_t)temp << G.bits_left; \ + G.bits_left += 8; \ + G.zipeof = 0; \ + } \ + } \ + zdest = (int16_t)((uint16_t)G.bitbuf & mask_bits[nbits]); \ + G.bitbuf >>= nbits; \ + G.bits_left -= nbits; \ +} + +#undef FALSE +#undef TRUE +enum { + FALSE = 0, + TRUE = 1 +}; + +union work { + struct { + int16_t Parent[HSIZE]; + uint8_t value[HSIZE]; + uint8_t Stack[HSIZE]; + } shrink; + uint8_t Slide[WSIZE]; +}; + +#define OUTBUFSIZ 4096 + +struct globals { + union work area; + uint8_t inbuf[4096]; + long long zsize; + long long uzsize; + uint8_t *inptr; + const char *tgt; + struct huft *fixed_tl; + struct huft *fixed_td; + struct huft *fixed_tl64; + struct huft *fixed_td64; + struct huft *fixed_tl32; + struct huft *fixed_td32; + const uint16_t *cplens; + const uint8_t *cplext; + const uint8_t *cpdext; + long csize; + long ucsize; + uint8_t outbuf[OUTBUFSIZ]; + uint8_t *outptr; + uint32_t *crc; + uint32_t bitbuf; + uint32_t wp; + uint32_t bb; + uint32_t bk; + unsigned outcnt; + int tfd; + int doswap; + int incnt; + int bits_left; + int zipeof; + int fixed_bl; + int fixed_bd; + int fixed_bl64; + int fixed_bd64; + int fixed_bl32; + int fixed_bd32; + int status; +}; + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). + Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 + means that v is a literal, 16 < e < 32 means that v is a pointer to + the next table, which codes e - 16 bits, and lastly e == 99 indicates + an unused code. If a code with e == 99 is looked up, this implies an + error in the data. */ + +struct huft { + uint8_t e; /* number of extra bits or operation */ + uint8_t b; /* number of bits in this code or subcode */ + union { + uint16_t n; /* literal, length base, or distance base */ + struct huft *t; /* pointer to next level of table */ + } v; +}; + +extern const uint16_t mask_bits[]; + +extern void flush(struct globals *, const void *, size_t); +extern int readbyte(struct globals *); + +extern int huft_build(const unsigned *b, unsigned n, unsigned s, + const uint16_t *d, const uint8_t *e, + struct huft **t, int *m, + int bits, int nob, int eob); +extern void huft_free(struct huft *); diff --git a/package/heirloom-cpio/src/utmpx.c b/package/heirloom-cpio/src/utmpx.c new file mode 100644 index 000000000..d88a627a7 --- /dev/null +++ b/package/heirloom-cpio/src/utmpx.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2004 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)utmpx.c 1.13 (gritter) 12/16/07 */ + +#include + +#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ + defined (__UCLIBC__) || defined (__OpenBSD__) || \ + defined (__DragonFly__) || \ + defined (__APPLE__) && \ + (__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_OS_X_VERSION_10_5) +#include +#include +#include +#include + +#include "utmpx.h" + +static FILE *utfp; +static struct utmpx utx; +static const char *utmpfile = _PATH_UTMP; + +static FILE * +init(void) +{ + if (utfp == NULL && (utfp = fopen(utmpfile, "r+")) == NULL) + if ((utfp = fopen(utmpfile, "r")) == NULL) + return NULL; + return utfp; +} + +static struct utmpx * +utmp2utmpx(struct utmpx *ux, const struct utmp *up) +{ +#ifndef __dietlibc__ + memset(ux, 0, sizeof *ux); + ux->ut_tv.tv_sec = up->ut_time; + memcpy(ux->ut_line, up->ut_line, UT_LINESIZE); + memcpy(ux->ut_user, up->ut_name, UT_NAMESIZE); + memcpy(ux->ut_host, up->ut_host, UT_HOSTSIZE); + if (strcmp(up->ut_line, "~") == 0) + ux->ut_type = BOOT_TIME; + else if (strcmp(up->ut_line, "|") == 0) + ux->ut_type = OLD_TIME; + else if (strcmp(up->ut_line, "}") == 0) + ux->ut_type = NEW_TIME; + else if (*up->ut_name == 0) + ux->ut_type = DEAD_PROCESS; + else + ux->ut_type = USER_PROCESS; +#else /* __dietlibc__ */ + *ux = *up; +#endif /* __dietlibc__ */ + return ux; +} + +static struct utmp * +utmpx2utmp(struct utmp *up, const struct utmpx *ux) +{ +#ifndef __dietlibc__ + memset(up, 0, sizeof *up); + up->ut_time = ux->ut_tv.tv_sec; + switch (ux->ut_type) { + case DEAD_PROCESS: + memcpy(up->ut_line, ux->ut_line, UT_LINESIZE); + break; + default: + case EMPTY: + case INIT_PROCESS: + case LOGIN_PROCESS: + case RUN_LVL: + case ACCOUNTING: + return NULL; + case BOOT_TIME: + strcpy(up->ut_name, "reboot"); + strcpy(up->ut_line, "~"); + break; + case OLD_TIME: + strcpy(up->ut_name, "date"); + strcpy(up->ut_line, "|"); + break; + case NEW_TIME: + strcpy(up->ut_name, "date"); + strcpy(up->ut_line, "{"); + break; + case USER_PROCESS: + memcpy(up->ut_line, ux->ut_line, UT_LINESIZE); + memcpy(up->ut_name, ux->ut_user, UT_NAMESIZE); + memcpy(up->ut_host, ux->ut_host, UT_HOSTSIZE); + } +#else /* __dietlibc__ */ + *up = *ux; +#endif /* __dietlibc__ */ + return up; +} + +struct utmpx * +getutxent(void) +{ + static struct utmp zero; + struct utmp ut; + + if (init() == NULL) + return NULL; + do { + if (fread(&ut, sizeof ut, 1, utfp) != 1) + return NULL; + } while (memcmp(&ut, &zero, sizeof ut) == 0); + return utmp2utmpx(&utx, &ut); +} + +struct utmpx * +getutxline(const struct utmpx *ux) +{ + struct utmp ut; + + if (init() == NULL) + return NULL; + fseek(utfp, 0, SEEK_SET); + while (fread(&ut, sizeof ut, 1, utfp) == 1) { + utmp2utmpx(&utx, &ut); + if ((utx.ut_type == LOGIN_PROCESS || + utx.ut_type == USER_PROCESS) && + strcmp(ut.ut_line, utx.ut_line) == 0) + return &utx; + } + return NULL; +} + +struct utmpx * +getutxid(const struct utmpx *ux) +{ +#ifdef __dietlibc__ + struct utmp ut; +#endif + + if (init() == NULL) + return NULL; +#ifdef __dietlibc__ + fseek(utfp, 0, SEEK_SET); + while (fread(&ut, sizeof ut, 1, utfp) == 1) { + utmp2utmpx(&utx, &ut); + switch (ux->ut_type) { + case BOOT_TIME: + case OLD_TIME: + case NEW_TIME: + if (ux->ut_type == utx.ut_type) + return &utx; + break; + case INIT_PROCESS: + case LOGIN_PROCESS: + case USER_PROCESS: + case DEAD_PROCESS: + if (ux->ut_type == utx.ut_type && + ux->ut_id == utx.ut_id) + return &utx; + break; + } + } +#endif /* __dietlibc__ */ + return NULL; +} + +void +setutxent(void) +{ + if (init() == NULL) + return; + fseek(utfp, 0, SEEK_SET); +} + +void +endutxent(void) +{ + FILE *fp; + + if (init() == NULL) + return; + fp = utfp; + utfp = NULL; + fclose(fp); +} + +int +utmpxname(const char *name) +{ + utmpfile = strdup(name); + return 0; +} + +extern struct utmpx * +pututxline(const struct utmpx *up) +{ + struct utmp ut; + struct utmpx *rp; + + if (init() == NULL) + return NULL; + /* + * Cannot use getutxid() because there is no id field. Use + * the equivalent of getutxline() instead. + */ + while (fread(&ut, sizeof ut, 1, utfp) == 1) { + if (strncmp(ut.ut_line, up->ut_line, UT_LINESIZE) == 0) { + fseek(utfp, -sizeof ut, SEEK_CUR); + break; + } + } + fflush(utfp); + if (utmpx2utmp(&ut, up) == NULL) + rp = NULL; + else if (fwrite(&ut, sizeof ut, 1, utfp) == 1) { + utx = *up; + rp = &utx; + } else + rp = NULL; + fflush(utfp); + return rp; +} + +extern void +updwtmpx(const char *name, const struct utmpx *up) +{ + FILE *fp; + + if ((fp = fopen(name, "a")) == NULL) + return; + fwrite(up, sizeof *up, 1, fp); + fclose(fp); +} + +#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __UCLIBC__ || + __OpenBSD__ || __DragonFly__ || __APPLE__ */ diff --git a/package/heirloom-cpio/src/version.c b/package/heirloom-cpio/src/version.c new file mode 100644 index 000000000..a9d4a4681 --- /dev/null +++ b/package/heirloom-cpio/src/version.c @@ -0,0 +1,26 @@ +#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 +#define USED __attribute__ ((used)) +#elif defined __GNUC__ +#define USED __attribute__ ((unused)) +#else +#define USED +#endif +static const char sccsid[] USED = "@(#)cpio.sl 2.9 (gritter) 8/14/09"; +/* SLIST */ +/* +blast.c: * Sccsid @(#)blast.c 1.2 (gritter) 2/17/04 +blast.h: * Sccsid @(#)blast.h 1.2 (gritter) 2/17/04 +cpio.c: * Sccsid @(#)cpio.c 1.305 (gritter) 8/14/09 +cpio.h: Sccsid @(#)cpio.h 1.29 (gritter) 3/26/07 +crc32.c: * Sccsid @(#)crc32.c 1.2 (gritter) 5/29/03 +expand.c: Sccsid @(#)expand.c 1.6 (gritter) 12/15/03 +explode.c: * Sccsid @(#)explode.c 1.6 (gritter) 9/30/03 +flags.c: Sccsid @(#)flags.c 1.6 (gritter) 3/26/07 +inflate.c: * Sccsid @(#)inflate.c 1.6 (gritter) 10/13/04 +nonpax.c: Sccsid @(#)nonpax.c 1.1 (gritter) 2/24/04 +pax.c:static const char sccsid[] USED = "@(#)pax_su3.sl 1.26 (gritter) 6/26/05"; +pax.c:static const char sccsid[] USED = "@(#)pax.sl 1.26 (gritter) 6/26/05"; +pax.c: Sccsid @(#)pax.c 1.26 (gritter) 6/26/05 +unshrink.c: * Sccsid @(#)unshrink.c 1.4 (gritter) 6/18/04 +unzip.h: * Sccsid @(#)unzip.h 1.5 (gritter) 7/16/04 +*/ diff --git a/package/heirloom-cpio/src/vpfmt.c b/package/heirloom-cpio/src/vpfmt.c new file mode 100644 index 000000000..fdbb4ccb0 --- /dev/null +++ b/package/heirloom-cpio/src/vpfmt.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. 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. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +/* Sccsid @(#)vpfmt.c 1.2 (gritter) 9/21/03 */ + +#include +#include + +#include "pfmt.h" + +extern char *pfmt_label__; + +/* + * Strip catalog and msgnum from s, but only if they actually appear. + */ +static const char * +begin(const char *s, long flags) +{ + const char *sp; + + if (flags & MM_NOGET) + return s; + sp = s; + if (*sp && *sp != ':') { + sp++; + while (*sp && *sp != '/' && *sp != ':' && sp - s < 14) + sp++; + } + if (*sp++ != ':') + return s; + while (*sp >= '0' && *sp <= '9') + sp++; + if (*sp++ != ':' || *sp == '\0') + return s; + return sp; +} + +int +vpfmt(FILE *stream, long flags, const char *fmt, va_list ap) +{ + int n = 0; + const char *severity = NULL; + char sevbuf[25]; + + if ((flags&MM_NOSTD) == 0) { + if (flags & MM_ACTION) + severity = "TO FIX"; + else switch (flags & 0377) { + case MM_HALT: + severity = "HALT"; + break; + case MM_WARNING: + severity = "WARNING"; + break; + case MM_INFO: + severity = "INFO"; + break; + case MM_ERROR: + severity = "ERROR"; + break; + default: + snprintf(sevbuf, sizeof sevbuf, "SEV=%ld", flags&0377); + severity = sevbuf; + } + if (pfmt_label__) + n = fprintf(stream, "%s: ", pfmt_label__); + if (severity) + n += fprintf(stream, "%s: ", severity); + } + n += vfprintf(stream, begin(fmt, flags), ap); + return n; +} diff --git a/package/liblzo/Makefile b/package/liblzo/Makefile index 3f79d0317..cd6783111 100644 --- a/package/liblzo/Makefile +++ b/package/liblzo/Makefile @@ -9,7 +9,6 @@ PKG_RELEASE:= 1 PKG_MD5SUM:= 95380bd4081f85ef08c5209f4107e9f8 PKG_DESCR:= a real-time data compression library PKG_SECTION:= libs -PKG_BUILDDEP:= liblzo-host PKG_URL:= http://www.oberhumer.com/opensource/lzo PKG_SITES:= http://www.oberhumer.com/opensource/lzo/download/ PKG_LIBNAME:= liblzo diff --git a/package/lzma/Makefile b/package/lzma/Makefile new file mode 100644 index 000000000..7d2a2e653 --- /dev/null +++ b/package/lzma/Makefile @@ -0,0 +1,28 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include $(TOPDIR)/rules.mk + +PKG_NAME:= lzma +PKG_VERSION:= 4.32.7 +PKG_RELEASE:= 1 +PKG_MD5SUM:= 2a748b77a2f8c3cbc322dbd0b4c9d06a +PKG_DESCR:= LZMA compression utility +PKG_SECTION:= archive +PKG_URL:= http://tukaani.org/lzma/ +PKG_SITES:= http://tukaani.org/lzma/ + +include $(TOPDIR)/mk/host.mk +include $(TOPDIR)/mk/package.mk + +$(eval $(call HOST_template,LZMA,lzma,$(PKG_VERSION)-${PKG_RELEASE})) +$(eval $(call PKG_template,LZMA,lzma,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) + +HOST_STYLE:= auto + +lzma-install: + $(INSTALL_DIR) $(IDIR_LZMA)/usr/bin + $(INSTALL_BIN) $(WRKINST)/usr/bin/lzma $(IDIR_LZMA)/usr/bin + +include ${TOPDIR}/mk/host-bottom.mk +include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/lzop/Makefile b/package/lzop/Makefile index f939092a5..95278fcd3 100644 --- a/package/lzop/Makefile +++ b/package/lzop/Makefile @@ -11,15 +11,21 @@ PKG_DESCR:= LZO compression utility PKG_SECTION:= archive PKG_DEPENDS:= liblzo PKG_BUILDDEP:= liblzo +HOST_BUILDDEP:= liblzo-host PKG_URL:= http://www.lzop.org/ PKG_SITES:= http://www.lzop.org/download/ +include $(TOPDIR)/mk/host.mk include $(TOPDIR)/mk/package.mk +$(eval $(call HOST_template,LZOP,lzop,$(PKG_VERSION)-${PKG_RELEASE})) $(eval $(call PKG_template,LZOP,lzop,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) +HOST_STYLE:= auto + lzop-install: $(INSTALL_DIR) $(IDIR_LZOP)/usr/bin $(INSTALL_BIN) $(WRKINST)/usr/bin/lzop $(IDIR_LZOP)/usr/bin +include ${TOPDIR}/mk/host-bottom.mk include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/mkcrypt/Makefile b/package/mkcrypt/Makefile new file mode 100644 index 000000000..6f8f873a7 --- /dev/null +++ b/package/mkcrypt/Makefile @@ -0,0 +1,31 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include ${TOPDIR}/rules.mk + +PKG_NAME:= mkcrypt +PKG_VERSION:= 1.0 +PKG_RELEASE:= 1 +PKG_DESCR:= mkcrypt utility +PKG_SECTION:= misc + +PKG_CFLINE_MKCRYPT:= depends on ADK_HOST_ONLY + +NO_DISTFILES:= 1 + +include ${TOPDIR}/mk/host.mk +include ${TOPDIR}/mk/package.mk + +$(eval $(call HOST_template,MKCRYPT,mkcrypt,${PKG_VERSION}-${PKG_RELEASE})) + +HOST_STYLE:= manual + +host-build: + $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -o ${WRKBUILD}/mkcrypt ${WRKBUILD}/mkcrypt.c + +mkcrypt-hostinstall: + ${INSTALL_DIR} ${STAGING_HOST_DIR}/usr/bin + ${INSTALL_BIN} ${WRKBUILD}/mkcrypt ${STAGING_HOST_DIR}/usr/bin + +include ${TOPDIR}/mk/host-bottom.mk +include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/mkcrypt/src/mkcrypt.c b/package/mkcrypt/src/mkcrypt.c new file mode 100644 index 000000000..a856759df --- /dev/null +++ b/package/mkcrypt/src/mkcrypt.c @@ -0,0 +1,441 @@ +/*- + * Copyright (c) 2007 + * Thorsten Glaser + * + * Provided that these terms and disclaimer and all copyright notices + * are retained or reproduced in an accompanying document, permission + * is granted to deal in this work without restriction, including un- + * limited rights to use, publicly perform, distribute, sell, modify, + * merge, give away, or sublicence. + * + * Advertising materials mentioning features or use of this work must + * display the following acknowledgement: + * This product includes material provided by Thorsten Glaser. + * This product includes software developed by Niels Provos. + * + * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to + * the utmost extent permitted by applicable law, neither express nor + * implied; without malicious intent or gross negligence. In no event + * may a licensor, author or contributor be held liable for indirect, + * direct, other damage, loss, or other issues arising in any way out + * of dealing in the work, even if advised of the possibility of such + * damage or existence of a defect, except proven that it results out + * of said person's immediate fault when using the work as intended. + */ + +#include +#include +#include +#include +#include + +#define MD5_BLOCK_LENGTH 64 +#define MD5_DIGEST_LENGTH 16 +#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1) + +typedef struct MD5Context { + u_int32_t state[4]; + u_int64_t count; + u_int8_t buffer[MD5_BLOCK_LENGTH]; +} MD5_CTX; + +/* low-level MD5 functions from md5c.c */ +void MD5Init(MD5_CTX *); +void MD5Update(MD5_CTX *, const u_int8_t *, size_t); +void MD5Pad(MD5_CTX *); +void MD5Final(u_int8_t [MD5_DIGEST_LENGTH], MD5_CTX *); +void MD5Transform(u_int32_t [4], const u_int8_t [MD5_BLOCK_LENGTH]); + +/* high-level functions from mdXhl.c */ +char *MD5End(MD5_CTX *, char *); +char *MD5File(const char *, char *); +char *MD5FileChunk(const char *, char *, off_t, off_t); +char *MD5Data(const u_int8_t *, size_t, char *); + +void to64(char *, u_int32_t, int); +char *md5crypt(const char *pw, const char *salt); +int pwd_gensalt(char *, int); + +static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +void +to64(char *s, u_int32_t v, int n) +{ + while (--n >= 0) { + *s++ = itoa64[v&0x3f]; + v >>= 6; + } +} + +#define PUT_64BIT_LE(cp, value) do { \ + (cp)[7] = (value) >> 56; \ + (cp)[6] = (value) >> 48; \ + (cp)[5] = (value) >> 40; \ + (cp)[4] = (value) >> 32; \ + (cp)[3] = (value) >> 24; \ + (cp)[2] = (value) >> 16; \ + (cp)[1] = (value) >> 8; \ + (cp)[0] = (value); } while (0) + +#define PUT_32BIT_LE(cp, value) do { \ + (cp)[3] = (value) >> 24; \ + (cp)[2] = (value) >> 16; \ + (cp)[1] = (value) >> 8; \ + (cp)[0] = (value); } while (0) + +static u_int8_t PADDING[MD5_BLOCK_LENGTH] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void +MD5Init(MD5_CTX *ctx) +{ + ctx->count = 0; + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xefcdab89; + ctx->state[2] = 0x98badcfe; + ctx->state[3] = 0x10325476; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void +MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len) +{ + size_t have, need; + + /* Check how many bytes we already have and how many more we need. */ + have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); + need = MD5_BLOCK_LENGTH - have; + + /* Update bitcount */ + ctx->count += (u_int64_t)len << 3; + + if (len >= need) { + if (have != 0) { + memcpy(ctx->buffer + have, input, need); + MD5Transform(ctx->state, ctx->buffer); + input += need; + len -= need; + have = 0; + } + + /* Process data in MD5_BLOCK_LENGTH-byte chunks. */ + while (len >= MD5_BLOCK_LENGTH) { + MD5Transform(ctx->state, input); + input += MD5_BLOCK_LENGTH; + len -= MD5_BLOCK_LENGTH; + } + } + + /* Handle any remaining bytes of data. */ + if (len != 0) + memcpy(ctx->buffer + have, input, len); +} + +/* + * Pad pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void +MD5Pad(MD5_CTX *ctx) +{ + u_int8_t count[8]; + size_t padlen; + + /* Convert count to 8 bytes in little endian order. */ + PUT_64BIT_LE(count, ctx->count); + + /* Pad out to 56 mod 64. */ + padlen = MD5_BLOCK_LENGTH - + ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); + if (padlen < 1 + 8) + padlen += MD5_BLOCK_LENGTH; + MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ + MD5Update(ctx, count, 8); +} + +/* + * Final wrapup--call MD5Pad, fill in digest and zero out ctx. + */ +void +MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx) +{ + int i; + + MD5Pad(ctx); + if (digest != NULL) { + for (i = 0; i < 4; i++) + PUT_32BIT_LE(digest + i * 4, ctx->state[i]); + memset(ctx, 0, sizeof(*ctx)); + } +} + + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void +MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH]) +{ + u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4]; + +#if BYTE_ORDER == LITTLE_ENDIAN + memcpy(in, block, sizeof(in)); +#else + for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) { + in[a] = (u_int32_t)( + (u_int32_t)(block[a * 4 + 0]) | + (u_int32_t)(block[a * 4 + 1]) << 8 | + (u_int32_t)(block[a * 4 + 2]) << 16 | + (u_int32_t)(block[a * 4 + 3]) << 24); + } +#endif + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + + MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21); + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; +} + +/* + * UNIX password + * + * Use MD5 for what it is best at... + */ + +char * +md5crypt(const char *pw, const char *salt) +{ + /* + * This string is magic for this algorithm. Having + * it this way, we can get get better later on + */ + static const unsigned char *magic = (const unsigned char *)"$1$"; + + static char passwd[120], *p; + static const unsigned char *sp,*ep; + unsigned char final[16]; + int sl,pl,i; + MD5_CTX ctx,ctx1; + u_int32_t l; + + /* Refine the Salt first */ + sp = (const unsigned char *)salt; + + /* If it starts with the magic string, then skip that */ + if(!strncmp((const char *)sp,(const char *)magic,strlen((const char *)magic))) + sp += strlen((const char *)magic); + + /* It stops at the first '$', max 8 chars */ + for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++) + continue; + + /* get the length of the true salt */ + sl = ep - sp; + + MD5Init(&ctx); + + /* The password first, since that is what is most unknown */ + MD5Update(&ctx,(const unsigned char *)pw,strlen(pw)); + + /* Then our magic string */ + MD5Update(&ctx,magic,strlen((const char *)magic)); + + /* Then the raw salt */ + MD5Update(&ctx,sp,sl); + + /* Then just as many characters of the MD5(pw,salt,pw) */ + MD5Init(&ctx1); + MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); + MD5Update(&ctx1,sp,sl); + MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); + MD5Final(final,&ctx1); + for(pl = strlen(pw); pl > 0; pl -= 16) + MD5Update(&ctx,final,pl>16 ? 16 : pl); + + /* Don't leave anything around in vm they could use. */ + memset(final,0,sizeof final); + + /* Then something really weird... */ + for (i = strlen(pw); i ; i >>= 1) + if(i&1) + MD5Update(&ctx, final, 1); + else + MD5Update(&ctx, (const unsigned char *)pw, 1); + + /* Now make the output string */ + snprintf(passwd, sizeof(passwd), "%s%.*s$", magic, + sl, (const char *)sp); + + MD5Final(final,&ctx); + + /* + * and now, just to make sure things don't run too fast + * On a 60 Mhz Pentium this takes 34 msec, so you would + * need 30 seconds to build a 1000 entry dictionary... + */ + for(i=0;i<1000;i++) { + MD5Init(&ctx1); + if(i & 1) + MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); + else + MD5Update(&ctx1,final,16); + + if(i % 3) + MD5Update(&ctx1,sp,sl); + + if(i % 7) + MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); + + if(i & 1) + MD5Update(&ctx1,final,16); + else + MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); + MD5Final(final,&ctx1); + } + + p = passwd + strlen(passwd); + + l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4; + l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4; + l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4; + l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4; + l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4; + l = final[11] ; to64(p,l,2); p += 2; + *p = '\0'; + + /* Don't leave anything around in vm they could use. */ + memset(final, 0, sizeof final); + + return passwd; +} + +int pwd_gensalt(char *salt, int saltlen) { + + *salt = '\0'; + + if (saltlen < 13) { /* $1$8salt$\0 */ + return 0; + } + + strcpy(salt, "$1$"); + to64(&salt[3], random(), 4); + to64(&salt[7], random(), 4); + strcpy(&salt[11], "$"); + return 1; +} + +int main(int argc, char *argv[]) { + char salt[16]; + char *pw; + + if (!argv[1]) { + fprintf(stderr, "Syntax Error!\n"); + return (1); + } + if (!pwd_gensalt(salt, sizeof (salt))) + return (255); + if ((pw = md5crypt(argv[1], salt)) == NULL) { + fprintf(stderr, "Error generating password!\n"); + return (1); + } + printf("%s\n", pw); + return (0); +} diff --git a/package/mkimage/Makefile b/package/mkimage/Makefile new file mode 100644 index 000000000..3d6fbc45d --- /dev/null +++ b/package/mkimage/Makefile @@ -0,0 +1,33 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include $(TOPDIR)/rules.mk + +PKG_NAME:= mkimage +PKG_VERSION:= 0.1 +PKG_RELEASE:= 1 +PKG_MD5SUM:= 1b7a781fb4cf8938842279bd3e8ee852 +PKG_DESCR:= stripped down mkimage utility +PKG_SECTION:= misc + +NO_DISTFILES:= 1 + +PKG_CFLINE_MKIMAGE:= depends on ADK_HOST_ONLY + +include $(TOPDIR)/mk/host.mk +include $(TOPDIR)/mk/package.mk + +$(eval $(call HOST_template,MKIMAGE,mkimage,$(PKG_VERSION)-${PKG_RELEASE})) + +HOST_STYLE:= manual + +host-build: + $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -o ${WRKBUILD}/mkimage ${WRKBUILD}/mkimage.c ${WRKBUILD}/crc32.c + +mkimage-hostinstall: + ${INSTALL_DIR} ${STAGING_HOST_DIR}/usr/bin + ${INSTALL_BIN} ${WRKBUILD}/mkimage \ + ${STAGING_HOST_DIR}/usr/bin + +include ${TOPDIR}/mk/host-bottom.mk +include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/mkimage/src/crc32.c b/package/mkimage/src/crc32.c new file mode 100644 index 000000000..067b3106c --- /dev/null +++ b/package/mkimage/src/crc32.c @@ -0,0 +1,200 @@ +/* + * This file is derived from crc32.c from the zlib-1.1.3 distribution + * by Jean-loup Gailly and Mark Adler. + */ + +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#define USE_HOSTCC + +#ifndef USE_HOSTCC /* Shut down "ANSI does not permit..." warnings */ +#include /* to get command definitions like CFG_CMD_JFFS2 */ +#endif + +#include "zlib.h" + +#define local static +#define ZEXPORT /* empty */ +unsigned long crc32 (unsigned long, const unsigned char *, unsigned int); + +#ifdef DYNAMIC_CRC_TABLE + +local int crc_table_empty = 1; +local uLongf crc_table[256]; +local void make_crc_table OF((void)); + +/* + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +local void make_crc_table() +{ + uLong c; + int n, k; + uLong poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) + poly |= 1L << (31 - p[n]); + + for (n = 0; n < 256; n++) + { + c = (uLong)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[n] = c; + } + crc_table_empty = 0; +} +#else +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +local const uLongf crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +#endif + +#if 0 +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const uLongf * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) make_crc_table(); +#endif + return (const uLongf *)crc_table; +} +#endif + +/* ========================================================================= */ +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +uLong ZEXPORT crc32(crc, buf, len) + uLong crc; + const Bytef *buf; + uInt len; +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} + +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) || \ + ((CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)) + +/* No ones complement version. JFFS2 (and other things ?) + * don't use ones compliment in their CRC calculations. + */ +uLong ZEXPORT crc32_no_comp(uLong crc, const Bytef *buf, uInt len) +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + + return crc; +} + +#endif /* CFG_CMD_JFFS2 */ diff --git a/package/mkimage/src/image.h b/package/mkimage/src/image.h new file mode 100644 index 000000000..cb62cde5b --- /dev/null +++ b/package/mkimage/src/image.h @@ -0,0 +1,161 @@ +/* + * (C) Copyright 2000-2005 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ******************************************************************** + * NOTE: This header file defines an interface to U-Boot. Including + * this (unmodified) header file in another file is considered normal + * use of U-Boot, and does *not* fall under the heading of "derived + * work". + ******************************************************************** + */ + +#ifndef __IMAGE_H__ +#define __IMAGE_H__ + +/* + * Operating System Codes + */ +#define IH_OS_INVALID 0 /* Invalid OS */ +#define IH_OS_OPENBSD 1 /* OpenBSD */ +#define IH_OS_NETBSD 2 /* NetBSD */ +#define IH_OS_FREEBSD 3 /* FreeBSD */ +#define IH_OS_4_4BSD 4 /* 4.4BSD */ +#define IH_OS_LINUX 5 /* Linux */ +#define IH_OS_SVR4 6 /* SVR4 */ +#define IH_OS_ESIX 7 /* Esix */ +#define IH_OS_SOLARIS 8 /* Solaris */ +#define IH_OS_IRIX 9 /* Irix */ +#define IH_OS_SCO 10 /* SCO */ +#define IH_OS_DELL 11 /* Dell */ +#define IH_OS_NCR 12 /* NCR */ +#define IH_OS_LYNXOS 13 /* LynxOS */ +#define IH_OS_VXWORKS 14 /* VxWorks */ +#define IH_OS_PSOS 15 /* pSOS */ +#define IH_OS_QNX 16 /* QNX */ +#define IH_OS_U_BOOT 17 /* Firmware */ +#define IH_OS_RTEMS 18 /* RTEMS */ +#define IH_OS_ARTOS 19 /* ARTOS */ +#define IH_OS_UNITY 20 /* Unity OS */ + +/* + * CPU Architecture Codes (supported by Linux) + */ +#define IH_CPU_INVALID 0 /* Invalid CPU */ +#define IH_CPU_ALPHA 1 /* Alpha */ +#define IH_CPU_ARM 2 /* ARM */ +#define IH_CPU_I386 3 /* Intel x86 */ +#define IH_CPU_IA64 4 /* IA64 */ +#define IH_CPU_MIPS 5 /* MIPS */ +#define IH_CPU_MIPS64 6 /* MIPS 64 Bit */ +#define IH_CPU_PPC 7 /* PowerPC */ +#define IH_CPU_S390 8 /* IBM S390 */ +#define IH_CPU_SH 9 /* SuperH */ +#define IH_CPU_SPARC 10 /* Sparc */ +#define IH_CPU_SPARC64 11 /* Sparc 64 Bit */ +#define IH_CPU_M68K 12 /* M68K */ +#define IH_CPU_NIOS 13 /* Nios-32 */ +#define IH_CPU_MICROBLAZE 14 /* MicroBlaze */ +#define IH_CPU_NIOS2 15 /* Nios-II */ +#define IH_CPU_BLACKFIN 16 /* Blackfin */ +#define IH_CPU_AVR32 17 /* AVR32 */ + +/* + * Image Types + * + * "Standalone Programs" are directly runnable in the environment + * provided by U-Boot; it is expected that (if they behave + * well) you can continue to work in U-Boot after return from + * the Standalone Program. + * "OS Kernel Images" are usually images of some Embedded OS which + * will take over control completely. Usually these programs + * will install their own set of exception handlers, device + * drivers, set up the MMU, etc. - this means, that you cannot + * expect to re-enter U-Boot except by resetting the CPU. + * "RAMDisk Images" are more or less just data blocks, and their + * parameters (address, size) are passed to an OS kernel that is + * being started. + * "Multi-File Images" contain several images, typically an OS + * (Linux) kernel image and one or more data images like + * RAMDisks. This construct is useful for instance when you want + * to boot over the network using BOOTP etc., where the boot + * server provides just a single image file, but you want to get + * for instance an OS kernel and a RAMDisk image. + * + * "Multi-File Images" start with a list of image sizes, each + * image size (in bytes) specified by an "uint32_t" in network + * byte order. This list is terminated by an "(uint32_t)0". + * Immediately after the terminating 0 follow the images, one by + * one, all aligned on "uint32_t" boundaries (size rounded up to + * a multiple of 4 bytes - except for the last file). + * + * "Firmware Images" are binary images containing firmware (like + * U-Boot or FPGA images) which usually will be programmed to + * flash memory. + * + * "Script files" are command sequences that will be executed by + * U-Boot's command interpreter; this feature is especially + * useful when you configure U-Boot to use a real shell (hush) + * as command interpreter (=> Shell Scripts). + */ + +#define IH_TYPE_INVALID 0 /* Invalid Image */ +#define IH_TYPE_STANDALONE 1 /* Standalone Program */ +#define IH_TYPE_KERNEL 2 /* OS Kernel Image */ +#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */ +#define IH_TYPE_MULTI 4 /* Multi-File Image */ +#define IH_TYPE_FIRMWARE 5 /* Firmware Image */ +#define IH_TYPE_SCRIPT 6 /* Script file */ +#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */ +#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */ + +/* + * Compression Types + */ +#define IH_COMP_NONE 0 /* No Compression Used */ +#define IH_COMP_GZIP 1 /* gzip Compression Used */ +#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */ +#define IH_COMP_LZMA 3 /* lzma Compression Used */ + +#define IH_MAGIC 0x27051956 /* Image Magic Number */ +#define IH_NMLEN 32 /* Image Name Length */ + +/* + * all data in network byte order (aka natural aka bigendian) + */ + +typedef struct image_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ + uint8_t ih_name[IH_NMLEN]; /* Image Name */ +} image_header_t; + + +#endif /* __IMAGE_H__ */ diff --git a/package/mkimage/src/mkimage.c b/package/mkimage/src/mkimage.c new file mode 100644 index 000000000..7c0432bad --- /dev/null +++ b/package/mkimage/src/mkimage.c @@ -0,0 +1,755 @@ +/* + * (C) Copyright 2000-2004 + * DENX Software Engineering + * Wolfgang Denk, wd@denx.de + * All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifdef __APPLE__ +#define __FreeBSD__ 10 +#endif + +#include +#include +#include +#include +#include +#ifndef __WIN32__ +#include /* for host / network byte order conversions */ +#endif +#include +#include +#include +#include + +#if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__) +#include +#include +#endif +#ifdef __WIN32__ +typedef unsigned int __u32; + +#define SWAP_LONG(x) \ + ((__u32)( \ + (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ + (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ + (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ + (((__u32)(x) & (__u32)0xff000000UL) >> 24) )) +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; + +#define ntohl(a) SWAP_LONG(a) +#define htonl(a) SWAP_LONG(a) +#endif /* __WIN32__ */ + +#ifndef O_BINARY /* should be define'd on __WIN32__ */ +#define O_BINARY 0 +#endif + +#include "image.h" + +extern int errno; + +#ifndef MAP_FAILED +#define MAP_FAILED (-1) +#endif + +char *cmdname; + +extern unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len); + +typedef struct table_entry { + int val; /* as defined in image.h */ + char *sname; /* short (input) name */ + char *lname; /* long (output) name */ +} table_entry_t; + +table_entry_t arch_name[] = { + { IH_CPU_INVALID, NULL, "Invalid CPU", }, + { IH_CPU_ALPHA, "alpha", "Alpha", }, + { IH_CPU_ARM, "arm", "ARM", }, + { IH_CPU_I386, "x86", "Intel x86", }, + { IH_CPU_IA64, "ia64", "IA64", }, + { IH_CPU_M68K, "m68k", "MC68000", }, + { IH_CPU_MICROBLAZE, "microblaze", "MicroBlaze", }, + { IH_CPU_MIPS, "mips", "MIPS", }, + { IH_CPU_MIPS64, "mips64", "MIPS 64 Bit", }, + { IH_CPU_NIOS, "nios", "NIOS", }, + { IH_CPU_NIOS2, "nios2", "NIOS II", }, + { IH_CPU_PPC, "ppc", "PowerPC", }, + { IH_CPU_S390, "s390", "IBM S390", }, + { IH_CPU_SH, "sh", "SuperH", }, + { IH_CPU_SPARC, "sparc", "SPARC", }, + { IH_CPU_SPARC64, "sparc64", "SPARC 64 Bit", }, + { IH_CPU_BLACKFIN, "blackfin", "Blackfin", }, + { IH_CPU_AVR32, "avr32", "AVR32", }, + { -1, "", "", }, +}; + +table_entry_t os_name[] = { + { IH_OS_INVALID, NULL, "Invalid OS", }, + { IH_OS_4_4BSD, "4_4bsd", "4_4BSD", }, + { IH_OS_ARTOS, "artos", "ARTOS", }, + { IH_OS_DELL, "dell", "Dell", }, + { IH_OS_ESIX, "esix", "Esix", }, + { IH_OS_FREEBSD, "freebsd", "FreeBSD", }, + { IH_OS_IRIX, "irix", "Irix", }, + { IH_OS_LINUX, "linux", "Linux", }, + { IH_OS_LYNXOS, "lynxos", "LynxOS", }, + { IH_OS_NCR, "ncr", "NCR", }, + { IH_OS_NETBSD, "netbsd", "NetBSD", }, + { IH_OS_OPENBSD, "openbsd", "OpenBSD", }, + { IH_OS_PSOS, "psos", "pSOS", }, + { IH_OS_QNX, "qnx", "QNX", }, + { IH_OS_RTEMS, "rtems", "RTEMS", }, + { IH_OS_SCO, "sco", "SCO", }, + { IH_OS_SOLARIS, "solaris", "Solaris", }, + { IH_OS_SVR4, "svr4", "SVR4", }, + { IH_OS_U_BOOT, "u-boot", "U-Boot", }, + { IH_OS_VXWORKS, "vxworks", "VxWorks", }, + { -1, "", "", }, +}; + +table_entry_t type_name[] = { + { IH_TYPE_INVALID, NULL, "Invalid Image", }, + { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", }, + { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, + { IH_TYPE_KERNEL, "kernel", "Kernel Image", }, + { IH_TYPE_MULTI, "multi", "Multi-File Image", }, + { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, + { IH_TYPE_SCRIPT, "script", "Script", }, + { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, + { IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", }, + { -1, "", "", }, +}; + +table_entry_t comp_name[] = { + { IH_COMP_NONE, "none", "uncompressed", }, + { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", }, + { IH_COMP_GZIP, "gzip", "gzip compressed", }, + { IH_COMP_LZMA, "lzma", "lzma compressed", }, + { -1, "", "", }, +}; + +static void copy_file (int, const char *, int); +static void usage (void); +static void print_header (image_header_t *); +static void print_type (image_header_t *); +static char *put_table_entry (table_entry_t *, char *, int); +static char *put_arch (int); +static char *put_type (int); +static char *put_os (int); +static char *put_comp (int); +static int get_table_entry (table_entry_t *, char *, char *); +static int get_arch(char *); +static int get_comp(char *); +static int get_os (char *); +static int get_type(char *); + + +char *datafile; +char *imagefile; + +int dflag = 0; +int eflag = 0; +int lflag = 0; +int vflag = 0; +int xflag = 0; +int opt_os = IH_OS_LINUX; +int opt_arch = IH_CPU_PPC; +int opt_type = IH_TYPE_KERNEL; +int opt_comp = IH_COMP_GZIP; + +image_header_t header; +image_header_t *hdr = &header; + +int +main (int argc, char **argv) +{ + int ifd; + uint32_t checksum; + uint32_t addr; + uint32_t ep; + struct stat sbuf; + unsigned char *ptr; + char *name = ""; + + cmdname = *argv; + + addr = ep = 0; + + while (--argc > 0 && **++argv == '-') { + while (*++*argv) { + switch (**argv) { + case 'l': + lflag = 1; + break; + case 'A': + if ((--argc <= 0) || + (opt_arch = get_arch(*++argv)) < 0) + usage (); + goto NXTARG; + case 'C': + if ((--argc <= 0) || + (opt_comp = get_comp(*++argv)) < 0) + usage (); + goto NXTARG; + case 'O': + if ((--argc <= 0) || + (opt_os = get_os(*++argv)) < 0) + usage (); + goto NXTARG; + case 'T': + if ((--argc <= 0) || + (opt_type = get_type(*++argv)) < 0) + usage (); + goto NXTARG; + + case 'a': + if (--argc <= 0) + usage (); + addr = strtoul (*++argv, (char **)&ptr, 16); + if (*ptr) { + fprintf (stderr, + "%s: invalid load address %s\n", + cmdname, *argv); + exit (EXIT_FAILURE); + } + goto NXTARG; + case 'd': + if (--argc <= 0) + usage (); + datafile = *++argv; + dflag = 1; + goto NXTARG; + case 'e': + if (--argc <= 0) + usage (); + ep = strtoul (*++argv, (char **)&ptr, 16); + if (*ptr) { + fprintf (stderr, + "%s: invalid entry point %s\n", + cmdname, *argv); + exit (EXIT_FAILURE); + } + eflag = 1; + goto NXTARG; + case 'n': + if (--argc <= 0) + usage (); + name = *++argv; + goto NXTARG; + case 'v': + vflag++; + break; + case 'x': + xflag++; + break; + default: + usage (); + } + } +NXTARG: ; + } + + if ((argc != 1) || ((lflag ^ dflag) == 0)) + usage(); + + if (!eflag) { + ep = addr; + /* If XIP, entry point must be after the U-Boot header */ + if (xflag) + ep += sizeof(image_header_t); + } + + /* + * If XIP, ensure the entry point is equal to the load address plus + * the size of the U-Boot header. + */ + if (xflag) { + if (ep != addr + sizeof(image_header_t)) { + fprintf (stderr, + "%s: For XIP, the entry point must be the load addr + %lu\n", + cmdname, + (unsigned long)sizeof(image_header_t)); + exit (EXIT_FAILURE); + } + } + + imagefile = *argv; + + if (lflag) { + ifd = open(imagefile, O_RDONLY|O_BINARY); + } else { + ifd = open(imagefile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666); + } + + if (ifd < 0) { + fprintf (stderr, "%s: Can't open %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (lflag) { + int len; + char *data; + /* + * list header information of existing image + */ + if (fstat(ifd, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if ((unsigned)sbuf.st_size < sizeof(image_header_t)) { + fprintf (stderr, + "%s: Bad size: \"%s\" is no valid image\n", + cmdname, imagefile); + exit (EXIT_FAILURE); + } + + ptr = (unsigned char *)mmap(0, sbuf.st_size, + PROT_READ, MAP_SHARED, ifd, 0); + if ((caddr_t)ptr == (caddr_t)-1) { + fprintf (stderr, "%s: Can't read %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + /* + * create copy of header so that we can blank out the + * checksum field for checking - this can't be done + * on the PROT_READ mapped data. + */ + memcpy (hdr, ptr, sizeof(image_header_t)); + + if (ntohl(hdr->ih_magic) != IH_MAGIC) { + fprintf (stderr, + "%s: Bad Magic Number: \"%s\" is no valid image\n", + cmdname, imagefile); + exit (EXIT_FAILURE); + } + + data = (char *)hdr; + len = sizeof(image_header_t); + + checksum = ntohl(hdr->ih_hcrc); + hdr->ih_hcrc = htonl(0); /* clear for re-calculation */ + + if (crc32 (0, data, len) != checksum) { + fprintf (stderr, + "%s: ERROR: \"%s\" has bad header checksum!\n", + cmdname, imagefile); + exit (EXIT_FAILURE); + } + + data = (char *)(ptr + sizeof(image_header_t)); + len = sbuf.st_size - sizeof(image_header_t) ; + + if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) { + fprintf (stderr, + "%s: ERROR: \"%s\" has corrupted data!\n", + cmdname, imagefile); + exit (EXIT_FAILURE); + } + + /* for multi-file images we need the data part, too */ + print_header ((image_header_t *)ptr); + + (void) munmap((void *)ptr, sbuf.st_size); + (void) close (ifd); + + exit (EXIT_SUCCESS); + } + + /* + * Must be -w then: + * + * write dummy header, to be fixed later + */ + memset (hdr, 0, sizeof(image_header_t)); + + if (write(ifd, hdr, sizeof(image_header_t)) != sizeof(image_header_t)) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (opt_type == IH_TYPE_MULTI || opt_type == IH_TYPE_SCRIPT) { + char *file = datafile; + uint32_t size; + + for (;;) { + char *sep = NULL; + + if (file) { + if ((sep = strchr(file, ':')) != NULL) { + *sep = '\0'; + } + + if (stat (file, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + cmdname, file, strerror(errno)); + exit (EXIT_FAILURE); + } + size = htonl(sbuf.st_size); + } else { + size = 0; + } + + if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (!file) { + break; + } + + if (sep) { + *sep = ':'; + file = sep + 1; + } else { + file = NULL; + } + } + + file = datafile; + + for (;;) { + char *sep = strchr(file, ':'); + if (sep) { + *sep = '\0'; + copy_file (ifd, file, 1); + *sep++ = ':'; + file = sep; + } else { + copy_file (ifd, file, 0); + break; + } + } + } else { + copy_file (ifd, datafile, 0); + } + + /* We're a bit of paranoid */ +#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) + (void) fdatasync (ifd); +#else + (void) fsync (ifd); +#endif + + if (fstat(ifd, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + ptr = (unsigned char *)mmap(0, sbuf.st_size, + PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0); + if (ptr == (unsigned char *)MAP_FAILED) { + fprintf (stderr, "%s: Can't map %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + hdr = (image_header_t *)ptr; + + checksum = crc32 (0, + (const char *)(ptr + sizeof(image_header_t)), + sbuf.st_size - sizeof(image_header_t) + ); + + /* Build new header */ + hdr->ih_magic = htonl(IH_MAGIC); + hdr->ih_time = htonl(sbuf.st_mtime); + hdr->ih_size = htonl(sbuf.st_size - sizeof(image_header_t)); + hdr->ih_load = htonl(addr); + hdr->ih_ep = htonl(ep); + hdr->ih_dcrc = htonl(checksum); + hdr->ih_os = opt_os; + hdr->ih_arch = opt_arch; + hdr->ih_type = opt_type; + hdr->ih_comp = opt_comp; + + strncpy((char *)hdr->ih_name, name, IH_NMLEN); + + checksum = crc32(0,(const char *)hdr,sizeof(image_header_t)); + + hdr->ih_hcrc = htonl(checksum); + + print_header (hdr); + + (void) munmap((void *)ptr, sbuf.st_size); + + /* We're a bit of paranoid */ +#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) + (void) fdatasync (ifd); +#else + (void) fsync (ifd); +#endif + + if (close(ifd)) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + exit (EXIT_SUCCESS); +} + +static void +copy_file (int ifd, const char *datafile, int pad) +{ + int dfd; + struct stat sbuf; + unsigned char *ptr; + int tail; + int zero = 0; + int offset = 0; + int size; + + if (vflag) { + fprintf (stderr, "Adding Image %s\n", datafile); + } + + if ((dfd = open(datafile, O_RDONLY|O_BINARY)) < 0) { + fprintf (stderr, "%s: Can't open %s: %s\n", + cmdname, datafile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (fstat(dfd, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + cmdname, datafile, strerror(errno)); + exit (EXIT_FAILURE); + } + + ptr = (unsigned char *)mmap(0, sbuf.st_size, + PROT_READ, MAP_SHARED, dfd, 0); + if (ptr == (unsigned char *)MAP_FAILED) { + fprintf (stderr, "%s: Can't read %s: %s\n", + cmdname, datafile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (xflag) { + unsigned char *p = NULL; + /* + * XIP: do not append the image_header_t at the + * beginning of the file, but consume the space + * reserved for it. + */ + + if ((unsigned)sbuf.st_size < sizeof(image_header_t)) { + fprintf (stderr, + "%s: Bad size: \"%s\" is too small for XIP\n", + cmdname, datafile); + exit (EXIT_FAILURE); + } + + for (p=ptr; p < ptr+sizeof(image_header_t); p++) { + if ( *p != 0xff ) { + fprintf (stderr, + "%s: Bad file: \"%s\" has invalid buffer for XIP\n", + cmdname, datafile); + exit (EXIT_FAILURE); + } + } + + offset = sizeof(image_header_t); + } + + size = sbuf.st_size - offset; + if (write(ifd, ptr + offset, size) != size) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (pad && ((tail = size % 4) != 0)) { + + if (write(ifd, (char *)&zero, 4-tail) != 4-tail) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + } + + (void) munmap((void *)ptr, sbuf.st_size); + (void) close (dfd); +} + +void +usage () +{ + fprintf (stderr, "Usage: %s -l image\n" + " -l ==> list image header information\n" + " %s [-x] -A arch -O os -T type -C comp " + "-a addr -e ep -n name -d data_file[:data_file...] image\n", + cmdname, cmdname); + fprintf (stderr, " -A ==> set architecture to 'arch'\n" + " -O ==> set operating system to 'os'\n" + " -T ==> set image type to 'type'\n" + " -C ==> set compression type 'comp'\n" + " -a ==> set load address to 'addr' (hex)\n" + " -e ==> set entry point to 'ep' (hex)\n" + " -n ==> set image name to 'name'\n" + " -d ==> use image data from 'datafile'\n" + " -x ==> set XIP (execute in place)\n" + ); + exit (EXIT_FAILURE); +} + +static void +print_header (image_header_t *hdr) +{ + time_t timestamp; + uint32_t size; + + timestamp = (time_t)ntohl(hdr->ih_time); + size = ntohl(hdr->ih_size); + + printf ("Image Name: %.*s\n", IH_NMLEN, hdr->ih_name); + printf ("Created: %s", ctime(×tamp)); + printf ("Image Type: "); print_type(hdr); + printf ("Data Size: %d Bytes = %.2f kB = %.2f MB\n", + size, (double)size / 1.024e3, (double)size / 1.048576e6 ); + printf ("Load Address: 0x%08X\n", ntohl(hdr->ih_load)); + printf ("Entry Point: 0x%08X\n", ntohl(hdr->ih_ep)); + + if (hdr->ih_type == IH_TYPE_MULTI || hdr->ih_type == IH_TYPE_SCRIPT) { + int i, ptrs; + uint32_t pos; + uint32_t *len_ptr = (uint32_t *) ( + (unsigned long)hdr + sizeof(image_header_t) + ); + + /* determine number of images first (to calculate image offsets) */ + for (i=0; len_ptr[i]; ++i) /* null pointer terminates list */ + ; + ptrs = i; /* null pointer terminates list */ + + pos = sizeof(image_header_t) + ptrs * sizeof(long); + printf ("Contents:\n"); + for (i=0; len_ptr[i]; ++i) { + size = ntohl(len_ptr[i]); + + printf (" Image %d: %8d Bytes = %4d kB = %d MB\n", + i, size, size>>10, size>>20); + if (hdr->ih_type == IH_TYPE_SCRIPT && i > 0) { + /* + * the user may need to know offsets + * if planning to do something with + * multiple files + */ + printf (" Offset = %08X\n", pos); + } + /* copy_file() will pad the first files to even word align */ + size += 3; + size &= ~3; + pos += size; + } + } +} + + +static void +print_type (image_header_t *hdr) +{ + printf ("%s %s %s (%s)\n", + put_arch (hdr->ih_arch), + put_os (hdr->ih_os ), + put_type (hdr->ih_type), + put_comp (hdr->ih_comp) + ); +} + +static char *put_arch (int arch) +{ + return (put_table_entry(arch_name, "Unknown Architecture", arch)); +} + +static char *put_os (int os) +{ + return (put_table_entry(os_name, "Unknown OS", os)); +} + +static char *put_type (int type) +{ + return (put_table_entry(type_name, "Unknown Image", type)); +} + +static char *put_comp (int comp) +{ + return (put_table_entry(comp_name, "Unknown Compression", comp)); +} + +static char *put_table_entry (table_entry_t *table, char *msg, int type) +{ + for (; table->val>=0; ++table) { + if (table->val == type) + return (table->lname); + } + return (msg); +} + +static int get_arch(char *name) +{ + return (get_table_entry(arch_name, "CPU", name)); +} + + +static int get_comp(char *name) +{ + return (get_table_entry(comp_name, "Compression", name)); +} + + +static int get_os (char *name) +{ + return (get_table_entry(os_name, "OS", name)); +} + + +static int get_type(char *name) +{ + return (get_table_entry(type_name, "Image", name)); +} + +static int get_table_entry (table_entry_t *table, char *msg, char *name) +{ + table_entry_t *t; + int first = 1; + + for (t=table; t->val>=0; ++t) { + if (t->sname && strcasecmp(t->sname, name)==0) + return (t->val); + } + fprintf (stderr, "\nInvalid %s Type - valid names are", msg); + for (t=table; t->val>=0; ++t) { + if (t->sname == NULL) + continue; + fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname); + first = 0; + } + fprintf (stderr, "\n"); + return (-1); +} diff --git a/package/mksh/Makefile b/package/mksh/Makefile index 63d391e18..4f65a97f7 100644 --- a/package/mksh/Makefile +++ b/package/mksh/Makefile @@ -17,9 +17,11 @@ PKG_DFLT_MKSH:= y if !ADK_TOOLCHAIN_ONLY DISTFILES= ${PKG_NAME}-R${PKG_VERSION}.tgz WRKDIST= ${WRKDIR}/${PKG_NAME} +include ${TOPDIR}/mk/host.mk include ${TOPDIR}/mk/package.mk -$(eval $(call PKG_template,MKSH,mksh,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) +$(eval $(call HOST_template,MKSH,mksh,${PKG_VERSION}-${PKG_RELEASE})) +$(eval $(call PKG_template,MKSH,mksh,${PKG_VERSION}-${PKG_RELEASE},,${PKG_DESCR},${PKG_SECTION})) ifeq ($(ADK_STATIC),y) TARGET_CFLAGS+= -static @@ -28,19 +30,31 @@ endif TARGET_CPPFLAGS+= -DMKSH_SMALL=1 TARGET_LDFLAGS+= -static-libgcc + +HOST_STYLE:= manual CONFIG_STYLE:= manual BUILD_STYLE:= manual INSTALL_STYLE:= manual +host-build: + cd ${WRKBUILD} && HAVE_CAN_FSTACKPROTECTORALL=0 \ + TARGET_OS=Linux ${BASH} ${WRKSRC}/Build.sh -Q -r -c lto + +mksh-hostinstall: + ${INSTALL_DIR} ${STAGING_HOST_DIR}/usr/bin + ${INSTALL_BIN} ${WRKBUILD}/mksh \ + ${STAGING_HOST_DIR}/usr/bin + do-build: cd ${WRKBUILD} && CC='${TARGET_CC}' CFLAGS='${TARGET_CFLAGS}' \ CPPFLAGS='${TARGET_CPPFLAGS}' LDFLAGS='${TARGET_LDFLAGS}' \ HAVE_CAN_FSTACKPROTECTORALL=0 \ TARGET_OS=Linux ${BASH} ${WRKSRC}/Build.sh -Q -r -c lto -do-install: +mksh-install: ${INSTALL_DIR} ${IDIR_MKSH}/bin ${IDIR_MKSH}/root ${INSTALL_BIN} ${WRKBUILD}/mksh ${IDIR_MKSH}/bin/ ${CP} ${WRKSRC}/dot.mkshrc ${IDIR_MKSH}/root/.mkshrc +include ${TOPDIR}/mk/host-bottom.mk include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/mtd-utils/Makefile b/package/mtd-utils/Makefile new file mode 100644 index 000000000..19c81ae4a --- /dev/null +++ b/package/mtd-utils/Makefile @@ -0,0 +1,35 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include $(TOPDIR)/rules.mk + +PKG_NAME:= mtd-utils +PKG_VERSION:= 1.5.0 +PKG_RELEASE:= 1 +PKG_MD5SUM:= a4df1ad29684be79b0fa699bdae01faf +PKG_DESCR:= mtd-utils filesystem utilities +PKG_SECTION:= fs +HOST_BUILDDEP:= liblzo-host +PKG_SITES:= http://openadk.org/distfiles/ + +PKG_CFLINE_MTD_UTILS:= depends on ADK_HOST_ONLY + +include $(TOPDIR)/mk/host.mk +include $(TOPDIR)/mk/package.mk + +$(eval $(call HOST_template,MTD_UTILS,mtd-utils,$(PKG_VERSION)-${PKG_RELEASE})) + +HOST_STYLE:= manual +CPPFLAGS_FOR_BUILD+= -DWITHOUT_XATTR=1 -I./include + +host-build: + (cd ${WRKBUILD} && env ${HOST_MAKE_ENV} ${MAKE} -f ${MAKE_FILE} \ + ${HOST_MAKE_FLAGS} ${HOST_ALL_TARGET}) + +mtd-utils-hostinstall: + ${INSTALL_DIR} ${STAGING_HOST_DIR}/usr/bin + ${INSTALL_BIN} ${WRKBUILD}/mkfs.jffs2 \ + ${STAGING_HOST_DIR}/usr/bin + +include ${TOPDIR}/mk/host-bottom.mk +include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/mtd-utils/patches/patch-Makefile b/package/mtd-utils/patches/patch-Makefile new file mode 100644 index 000000000..53ed8640e --- /dev/null +++ b/package/mtd-utils/patches/patch-Makefile @@ -0,0 +1,65 @@ +--- mtd-utils-1.5.0.orig/Makefile 2012-05-07 09:19:39.000000000 +0200 ++++ mtd-utils-1.5.0/Makefile 2014-03-30 15:49:30.000000000 +0200 +@@ -16,27 +16,13 @@ endif + + TESTS = tests + +-MTD_BINS = \ +- ftl_format flash_erase nanddump doc_loadbios \ +- ftl_check mkfs.jffs2 flash_lock flash_unlock \ +- flash_otp_info flash_otp_dump mtd_debug flashcp nandwrite nandtest \ +- jffs2dump \ +- nftldump nftl_format docfdisk \ +- rfddump rfdformat \ +- serve_image recv_image \ +- sumtool jffs2reader +-UBI_BINS = \ +- ubiupdatevol ubimkvol ubirmvol ubicrc32 ubinfo ubiattach \ +- ubidetach ubinize ubiformat ubirename mtdinfo ubirsvol ++MTD_BINS = mkfs.jffs2 + + BINS = $(MTD_BINS) +-BINS += mkfs.ubifs/mkfs.ubifs +-BINS += $(addprefix ubi-utils/,$(UBI_BINS)) + SCRIPTS = flash_eraseall + + TARGETS = $(BINS) + TARGETS += lib/libmtd.a +-TARGETS += ubi-utils/libubi.a + + OBJDEPS = $(BUILDDIR)/include/version.h + +@@ -83,12 +69,12 @@ $(BUILDDIR)/include/version.h.tmp: + # + # Utils in top level + # +-obj-mkfs.jffs2 = compr_rtime.o compr_zlib.o compr_lzo.o compr.o rbtree.o +-LDFLAGS_mkfs.jffs2 = $(ZLIBLDFLAGS) $(LZOLDFLAGS) +-LDLIBS_mkfs.jffs2 = -lz $(LZOLDLIBS) ++obj-mkfs.jffs2 = compr_rtime.o compr_zlib.o compr.o rbtree.o ++LDFLAGS_mkfs.jffs2 = $(ZLIBLDFLAGS) ++LDLIBS_mkfs.jffs2 = -lz + +-LDFLAGS_jffs2reader = $(ZLIBLDFLAGS) $(LZOLDFLAGS) +-LDLIBS_jffs2reader = -lz $(LZOLDLIBS) ++LDFLAGS_jffs2reader = $(ZLIBLDFLAGS) ++LDLIBS_jffs2reader = -lz + + $(foreach v,$(MTD_BINS),$(eval $(call mkdep,,$(v)))) + +@@ -103,7 +89,7 @@ $(call _mkdep,lib/,libmtd.a) + # + obj-mkfs.ubifs = crc16.o lpt.o compr.o devtable.o \ + hashtable/hashtable.o hashtable/hashtable_itr.o +-LDLIBS_mkfs.ubifs = -lz -llzo2 -lm -luuid ++LDLIBS_mkfs.ubifs = -lz -lm -luuid + $(call mkdep,mkfs.ubifs/,mkfs.ubifs,,ubi-utils/libubi.a) + + # +@@ -117,6 +103,3 @@ obj-libubigen.a = libubigen.o + obj-mtdinfo = libubigen.a + obj-ubinize = libubigen.a libiniparser.a + obj-ubiformat = libubigen.a libscan.a +- +-$(foreach v,libubi.a libubigen.a libiniparser.a libscan.a,$(eval $(call _mkdep,ubi-utils/,$(v)))) +-$(foreach v,$(UBI_BINS),$(eval $(call mkdep,ubi-utils/,$(v),libubi.a ubiutils-common.o))) diff --git a/package/mtd-utils/patches/patch-common_mk b/package/mtd-utils/patches/patch-common_mk new file mode 100644 index 000000000..6881db87e --- /dev/null +++ b/package/mtd-utils/patches/patch-common_mk @@ -0,0 +1,11 @@ +--- mtd-utils-1.5.0.orig/common.mk 2012-05-07 09:19:39.000000000 +0200 ++++ mtd-utils-1.5.0/common.mk 2014-03-30 15:49:26.000000000 +0200 +@@ -13,8 +13,6 @@ WFLAGS := -Wall \ + $(call cc-option,-Wwrite-strings) \ + $(call cc-option,-Wno-sign-compare) + CFLAGS += $(WFLAGS) +-SECTION_CFLAGS := $(call cc-option,-ffunction-sections -fdata-sections -Wl$(comma)--gc-sections) +-CFLAGS += $(SECTION_CFLAGS) + + ifneq ($(WITHOUT_LARGEFILE), 1) + CPPFLAGS += -D_FILE_OFFSET_BITS=64 diff --git a/package/mtd-utils/patches/patch-compr_c b/package/mtd-utils/patches/patch-compr_c new file mode 100644 index 000000000..c69e133b9 --- /dev/null +++ b/package/mtd-utils/patches/patch-compr_c @@ -0,0 +1,21 @@ +--- mtd-utils-1.5.0.orig/compr.c 2012-05-07 09:19:39.000000000 +0200 ++++ mtd-utils-1.5.0/compr.c 2014-03-30 15:49:30.000000000 +0200 +@@ -517,9 +517,6 @@ int jffs2_compressors_init(void) + #ifdef CONFIG_JFFS2_RTIME + jffs2_rtime_init(); + #endif +-#ifdef CONFIG_JFFS2_LZO +- jffs2_lzo_init(); +-#endif + return 0; + } + +@@ -531,8 +528,5 @@ int jffs2_compressors_exit(void) + #ifdef CONFIG_JFFS2_ZLIB + jffs2_zlib_exit(); + #endif +-#ifdef CONFIG_JFFS2_LZO +- jffs2_lzo_exit(); +-#endif + return 0; + } diff --git a/package/mtd-utils/patches/patch-compr_lzo_c b/package/mtd-utils/patches/patch-compr_lzo_c new file mode 100644 index 000000000..98f235c5b --- /dev/null +++ b/package/mtd-utils/patches/patch-compr_lzo_c @@ -0,0 +1,10 @@ +--- mtd-utils-1.5.0.orig/compr_lzo.c 2012-05-07 09:19:39.000000000 +0200 ++++ mtd-utils-1.5.0/compr_lzo.c 2014-03-30 15:49:26.000000000 +0200 +@@ -26,7 +26,6 @@ + #include + + #ifndef WITHOUT_LZO +-#include + #include + #include + #include "compr.h" diff --git a/package/mtd-utils/patches/patch-compr_zlib_c b/package/mtd-utils/patches/patch-compr_zlib_c new file mode 100644 index 000000000..200bb55ce --- /dev/null +++ b/package/mtd-utils/patches/patch-compr_zlib_c @@ -0,0 +1,10 @@ +--- mtd-utils-1.5.0.orig/compr_zlib.c 2012-05-07 09:19:39.000000000 +0200 ++++ mtd-utils-1.5.0/compr_zlib.c 2014-03-30 15:49:26.000000000 +0200 +@@ -39,7 +39,6 @@ + #include + #undef crc32 + #include +-#include + #include + #include "common.h" + #include "compr.h" diff --git a/package/mtd-utils/patches/patch-include_mtd_jffs2-user_h b/package/mtd-utils/patches/patch-include_mtd_jffs2-user_h new file mode 100644 index 000000000..1373b66f2 --- /dev/null +++ b/package/mtd-utils/patches/patch-include_mtd_jffs2-user_h @@ -0,0 +1,16 @@ +--- mtd-utils-1.5.0.orig/include/mtd/jffs2-user.h 2012-05-07 09:19:39.000000000 +0200 ++++ mtd-utils-1.5.0/include/mtd/jffs2-user.h 2014-03-30 15:49:26.000000000 +0200 +@@ -9,8 +9,13 @@ + + /* This file is blessed for inclusion by userspace */ + #include ++#if defined(__APPLE__) ++#include "endian.h" ++#include "byteswap.h" ++#else + #include + #include ++#endif + + #undef cpu_to_je16 + #undef cpu_to_je32 diff --git a/package/mtd-utils/patches/patch-include_mtd_mtd-abi_h b/package/mtd-utils/patches/patch-include_mtd_mtd-abi_h new file mode 100644 index 000000000..9a95c4127 --- /dev/null +++ b/package/mtd-utils/patches/patch-include_mtd_mtd-abi_h @@ -0,0 +1,14 @@ +--- mtd-utils-1.5.0.orig/include/mtd/mtd-abi.h 2012-05-07 09:19:39.000000000 +0200 ++++ mtd-utils-1.5.0/include/mtd/mtd-abi.h 2014-03-30 15:49:26.000000000 +0200 +@@ -171,9 +171,9 @@ struct otp_info { + /* Get info about OOB modes (e.g., RAW, PLACE, AUTO) - legacy interface */ + #define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo) + /* Check if an eraseblock is bad */ +-#define MEMGETBADBLOCK _IOW('M', 11, __kernel_loff_t) ++#define MEMGETBADBLOCK _IOW('M', 11, off_t) + /* Mark an eraseblock as bad */ +-#define MEMSETBADBLOCK _IOW('M', 12, __kernel_loff_t) ++#define MEMSETBADBLOCK _IOW('M', 12, off_t) + /* Set OTP (One-Time Programmable) mode (factory vs. user) */ + #define OTPSELECT _IOR('M', 13, int) + /* Get number of OTP (One-Time Programmable) regions */ diff --git a/package/mtd-utils/patches/patch-include_mtd_ubi-media_h b/package/mtd-utils/patches/patch-include_mtd_ubi-media_h new file mode 100644 index 000000000..33feabf92 --- /dev/null +++ b/package/mtd-utils/patches/patch-include_mtd_ubi-media_h @@ -0,0 +1,18 @@ +--- mtd-utils-1.5.0.orig/include/mtd/ubi-media.h 2012-05-07 09:19:39.000000000 +0200 ++++ mtd-utils-1.5.0/include/mtd/ubi-media.h 2014-03-30 15:49:26.000000000 +0200 +@@ -30,7 +30,15 @@ + #ifndef __UBI_MEDIA_H__ + #define __UBI_MEDIA_H__ + ++#ifdef __linux__ + #include ++#else ++#include ++typedef uint8_t __u8; ++typedef uint16_t __be16; ++typedef uint32_t __be32; ++typedef uint64_t __be64; ++#endif + + /* The version of UBI images supported by this implementation */ + #define UBI_VERSION 1 diff --git a/package/mtd-utils/patches/patch-lib_libfec_c b/package/mtd-utils/patches/patch-lib_libfec_c new file mode 100644 index 000000000..7b198d0fb --- /dev/null +++ b/package/mtd-utils/patches/patch-lib_libfec_c @@ -0,0 +1,20 @@ +--- mtd-utils-1.5.0.orig/lib/libfec.c 2012-05-07 09:19:39.000000000 +0200 ++++ mtd-utils-1.5.0/lib/libfec.c 2014-03-30 15:49:26.000000000 +0200 +@@ -61,8 +61,6 @@ struct timeval { + }; + #define gettimeofday(x, dummy) { (x)->ticks = clock() ; } + #define DIFF_T(a,b) (1+ 1000000*(a.ticks - b.ticks) / CLOCKS_PER_SEC ) +-typedef unsigned long u_long ; +-typedef unsigned short u_short ; + #else /* typically, unix systems */ + #include + #define DIFF_T(a,b) \ +@@ -625,7 +623,7 @@ init_fec(void) + #define FEC_MAGIC 0xFECC0DEC + + struct fec_parms { +- u_long magic ; ++ unsigned long magic ; + int k, n ; /* parameters of the code */ + gf *enc_matrix ; + } ; diff --git a/package/mtd-utils/patches/patch-lib_libmtd_c b/package/mtd-utils/patches/patch-lib_libmtd_c new file mode 100644 index 000000000..af0f9a837 --- /dev/null +++ b/package/mtd-utils/patches/patch-lib_libmtd_c @@ -0,0 +1,38 @@ +--- mtd-utils-1.5.0.orig/lib/libmtd.c 2012-05-07 09:19:39.000000000 +0200 ++++ mtd-utils-1.5.0/lib/libmtd.c 2014-03-30 15:49:26.000000000 +0200 +@@ -1006,7 +1006,7 @@ out: + int mtd_is_bad(const struct mtd_dev_info *mtd, int fd, int eb) + { + int ret; +- loff_t seek; ++ off_t seek; + + ret = mtd_valid_erase_block(mtd, eb); + if (ret) +@@ -1015,7 +1015,7 @@ int mtd_is_bad(const struct mtd_dev_info + if (!mtd->bb_allowed) + return 0; + +- seek = (loff_t)eb * mtd->eb_size; ++ seek = (off_t)eb * mtd->eb_size; + ret = ioctl(fd, MEMGETBADBLOCK, &seek); + if (ret == -1) + return mtd_ioctl_error(mtd, eb, "MEMGETBADBLOCK"); +@@ -1025,7 +1025,7 @@ int mtd_is_bad(const struct mtd_dev_info + int mtd_mark_bad(const struct mtd_dev_info *mtd, int fd, int eb) + { + int ret; +- loff_t seek; ++ off_t seek; + + if (!mtd->bb_allowed) { + errno = EINVAL; +@@ -1036,7 +1036,7 @@ int mtd_mark_bad(const struct mtd_dev_in + if (ret) + return ret; + +- seek = (loff_t)eb * mtd->eb_size; ++ seek = (off_t)eb * mtd->eb_size; + ret = ioctl(fd, MEMSETBADBLOCK, &seek); + if (ret == -1) + return mtd_ioctl_error(mtd, eb, "MEMSETBADBLOCK"); diff --git a/package/mtd-utils/patches/patch-lib_libmtd_legacy_c b/package/mtd-utils/patches/patch-lib_libmtd_legacy_c new file mode 100644 index 000000000..bcd66374f --- /dev/null +++ b/package/mtd-utils/patches/patch-lib_libmtd_legacy_c @@ -0,0 +1,11 @@ +--- mtd-utils-1.5.0.orig/lib/libmtd_legacy.c 2012-05-07 09:19:39.000000000 +0200 ++++ mtd-utils-1.5.0/lib/libmtd_legacy.c 2014-03-30 15:49:26.000000000 +0200 +@@ -234,7 +234,7 @@ int legacy_get_dev_info(const char *node + struct stat st; + struct mtd_info_user ui; + int fd, ret; +- loff_t offs = 0; ++ off_t offs = 0; + struct proc_parse_info pi; + + if (stat(node, &st)) { diff --git a/package/mtd-utils/patches/patch-mkfs_jffs2_c b/package/mtd-utils/patches/patch-mkfs_jffs2_c new file mode 100644 index 000000000..766e2204a --- /dev/null +++ b/package/mtd-utils/patches/patch-mkfs_jffs2_c @@ -0,0 +1,15 @@ +--- mtd-utils-1.5.0.orig/mkfs.jffs2.c 2012-05-07 09:19:39.000000000 +0200 ++++ mtd-utils-1.5.0/mkfs.jffs2.c 2014-03-30 15:49:26.000000000 +0200 +@@ -70,7 +70,12 @@ + #include + #include + #endif ++#if defined(__APPLE__) ++#include "endian.h" ++#include "byteswap.h" ++#else + #include ++#endif + #include + #include + diff --git a/package/mtd-utils/patches/patch-rbtree_h b/package/mtd-utils/patches/patch-rbtree_h new file mode 100644 index 000000000..b7d34b937 --- /dev/null +++ b/package/mtd-utils/patches/patch-rbtree_h @@ -0,0 +1,12 @@ +--- mtd-utils-1.5.0.orig/rbtree.h 2012-05-07 09:19:39.000000000 +0200 ++++ mtd-utils-1.5.0/rbtree.h 2014-03-30 15:49:26.000000000 +0200 +@@ -94,8 +94,7 @@ static inline struct page * rb_insert_pa + #ifndef _LINUX_RBTREE_H + #define _LINUX_RBTREE_H + +-#include +-#include ++#include + + struct rb_node + { diff --git a/package/pcre/Makefile b/package/pcre/Makefile index 211f8f375..174315a81 100644 --- a/package/pcre/Makefile +++ b/package/pcre/Makefile @@ -22,11 +22,14 @@ ifeq ($(ADK_STATIC),y) PKG_OPTS+= libmix endif +include ${TOPDIR}/mk/host.mk include ${TOPDIR}/mk/package.mk +$(eval $(call HOST_template,PCRE,pcre,${PKG_VERSION}-${PKG_RELEASE})) $(eval $(call PKG_template,LIBPCRE,libpcre,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION},${PKG_OPTS})) $(eval $(call PKG_template,LIBPCRECPP,libpcrecpp,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKGSD_LIBPCRECPP},${PKG_SECTION})) +HOST_STYLE:= auto CONFIGURE_ARGS+= --enable-utf XAKE_FLAGS+= ${TARGET_CONFIGURE_OPTS} @@ -38,4 +41,5 @@ libpcrecpp-install: ${INSTALL_DIR} ${IDIR_LIBPCRECPP}/usr/lib ${CP} ${WRKINST}/usr/lib/libpcrecpp.so* ${IDIR_LIBPCRECPP}/usr/lib +include ${TOPDIR}/mk/host-bottom.mk include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/squashfs/Makefile b/package/squashfs/Makefile new file mode 100644 index 000000000..575849acd --- /dev/null +++ b/package/squashfs/Makefile @@ -0,0 +1,37 @@ +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include $(TOPDIR)/rules.mk + +PKG_NAME:= squashfs +PKG_VERSION:= 4.2 +PKG_RELEASE:= 1 +PKG_MD5SUM:= 1b7a781fb4cf8938842279bd3e8ee852 +PKG_DESCR:= squashfs filesystem utilities +PKG_SECTION:= fs +PKG_SITES:= ${MASTER_SITE_SOURCEFORGE:=squashfs/} + +DISTFILES:= ${PKG_NAME}${PKG_VERSION}.tar.gz +WRKDIST= ${WRKDIR}/$(PKG_NAME)${PKG_VERSION} + +PKG_CFLINE_SQUASHFS:= depends on ADK_HOST_ONLY + +include $(TOPDIR)/mk/host.mk +include $(TOPDIR)/mk/package.mk + +$(eval $(call HOST_template,SQUASHFS,squashfs,$(PKG_VERSION)-${PKG_RELEASE})) + +HOST_STYLE:= manual +HOST_MAKE_FLAGS+= XATTR_SUPPORT=0 XZ_SUPPORT=1 EXTRA_LDFLAGS=$(LDFLAGS_FOR_BUILD) + +host-build: + (cd ${WRKBUILD}/squashfs-tools && env ${HOST_MAKE_ENV} ${MAKE} -f ${MAKE_FILE} \ + ${HOST_MAKE_FLAGS} ${HOST_ALL_TARGET}) + +squashfs-hostinstall: + ${INSTALL_DIR} ${STAGING_HOST_DIR}/usr/bin + ${INSTALL_BIN} ${WRKBUILD}/squashfs-tools/mksquashfs \ + ${STAGING_HOST_DIR}/usr/bin + +include ${TOPDIR}/mk/host-bottom.mk +include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/squashfs/patches/patch-squashfs-tools_Makefile b/package/squashfs/patches/patch-squashfs-tools_Makefile new file mode 100644 index 000000000..cc764141f --- /dev/null +++ b/package/squashfs/patches/patch-squashfs-tools_Makefile @@ -0,0 +1,11 @@ +--- squashfs4.2.orig/squashfs-tools/Makefile 2011-02-28 21:04:15.000000000 +0100 ++++ squashfs4.2/squashfs-tools/Makefile 2014-03-29 15:02:11.000000000 +0100 +@@ -93,7 +93,7 @@ XATTR_DEFAULT = 1 + # End of BUILD options section # + ############################################### + +-INCLUDEDIR = -I. ++INCLUDEDIR = -I. $(CPPFLAGS_FOR_BUILD) + INSTALL_DIR = /usr/local/bin + + MKSQUASHFS_OBJS = mksquashfs.o read_fs.o sort.o swap.o pseudo.o compressor.o diff --git a/package/squashfs/patches/patch-squashfs-tools_mksquashfs_c b/package/squashfs/patches/patch-squashfs-tools_mksquashfs_c new file mode 100644 index 000000000..877894c6c --- /dev/null +++ b/package/squashfs/patches/patch-squashfs-tools_mksquashfs_c @@ -0,0 +1,47 @@ +--- squashfs4.2.orig/squashfs-tools/mksquashfs.c 2011-02-28 23:24:09.000000000 +0100 ++++ squashfs4.2/squashfs-tools/mksquashfs.c 2014-03-29 15:02:16.000000000 +0100 +@@ -60,6 +60,10 @@ + #include + #endif + ++#ifndef FNM_EXTMATCH ++#define FNM_EXTMATCH 0 ++#endif ++ + #ifdef SQUASHFS_TRACE + #define TRACE(s, args...) \ + do { \ +@@ -721,13 +725,13 @@ void cache_block_put(struct file_buffer + + (((char *)A) - data_cache))) + + +-inline void inc_progress_bar() ++static inline void inc_progress_bar() + { + cur_uncompressed ++; + } + + +-inline void update_progress_bar() ++static inline void update_progress_bar() + { + pthread_mutex_lock(&progress_mutex); + pthread_cond_signal(&progress_wait); +@@ -735,7 +739,7 @@ inline void update_progress_bar() + } + + +-inline void waitforthread(int i) ++static inline void waitforthread(int i) + { + TRACE("Waiting for thread %d\n", i); + while(thread[i] != 0) +@@ -3340,7 +3344,7 @@ struct inode_info *lookup_inode(struct s + } + + +-inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, ++static inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, + struct inode_info *inode_info, struct dir_info *dir) + { + if((dir->count % DIR_ENTRIES) == 0) { diff --git a/package/squashfs/patches/patch-squashfs-tools_unsquashfs_c b/package/squashfs/patches/patch-squashfs-tools_unsquashfs_c new file mode 100644 index 000000000..d57b184de --- /dev/null +++ b/package/squashfs/patches/patch-squashfs-tools_unsquashfs_c @@ -0,0 +1,39 @@ +--- squashfs4.2.orig/squashfs-tools/unsquashfs.c 2011-02-28 23:27:06.000000000 +0100 ++++ squashfs4.2/squashfs-tools/unsquashfs.c 2014-03-29 15:02:16.000000000 +0100 +@@ -29,7 +29,13 @@ + #include "compressor.h" + #include "xattr.h" + ++#ifndef FNM_EXTMATCH ++#define FNM_EXTMATCH 0 ++#endif ++ ++#ifdef __linux__ + #include ++#endif + #include + + struct cache *fragment_cache, *data_cache; +@@ -1810,7 +1816,7 @@ void initialise_threads(int fragment_buf + "\n"); + + if(processors == -1) { +-#ifndef linux ++#if 0 + int mib[2]; + size_t len = sizeof(processors); + +@@ -1821,11 +1827,13 @@ void initialise_threads(int fragment_buf + mib[1] = HW_NCPU; + #endif + ++#ifdef __linux__ + if(sysctl(mib, 2, &processors, &len, NULL, 0) == -1) { + ERROR("Failed to get number of available processors. " + "Defaulting to 1\n"); + processors = 1; + } ++#endif + #else + processors = sysconf(_SC_NPROCESSORS_ONLN); + #endif diff --git a/package/syslinux/Makefile b/package/syslinux/Makefile index b84c0b9ad..00168274b 100644 --- a/package/syslinux/Makefile +++ b/package/syslinux/Makefile @@ -4,29 +4,36 @@ include $(TOPDIR)/rules.mk PKG_NAME:= syslinux -PKG_VERSION:= 4.03 +PKG_VERSION:= 6.02 PKG_RELEASE:= 1 -PKG_MD5SUM:= 086ac1c569d226a5e2ae3d605de09a1d +PKG_MD5SUM:= 1df6ff6e4a82b9d7d71a9e7cb5851a5f PKG_DESCR:= lightweight bootloaders -PKG_SECTION:= misc -PKG_BUILDDEP:= nasm +PKG_SECTION:= boot +HOST_BUILDDEP:= nasm-host PKG_URL:= http://syslinux.zytor.com/wiki/index.php/The_Syslinux_Project PKG_SITES:= http://www.kernel.org/pub/linux/utils/boot/syslinux/ -PKG_ARCH_DEPENDS:= native -PKG_HOST_DEPENDS:= !darwin !netbsd !openbsd !cygwin !freebsd +PKG_CFLINE_SYSLINUX:= depends on ADK_HOST_ONLY +include $(TOPDIR)/mk/host.mk include $(TOPDIR)/mk/package.mk -$(eval $(call PKG_template,SYSLINUX,syslinux,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) +$(eval $(call HOST_template,SYSLINUX,syslinux,$(PKG_VERSION)-${PKG_RELEASE})) -CONFIG_STYLE:= manual -FAKE_FLAGS+= INSTALLROOT=${WRKINST} -TARGET_CFLAGS+= -std=c99 +HOST_STYLE:= manual +HOST_ALL_TARGET:= bios installer -syslinux-install: - $(INSTALL_DIR) $(IDIR_SYSLINUX)/usr/bin - $(INSTALL_BIN) $(WRKINST)/usr/bin/syslinux \ - $(IDIR_SYSLINUX)/usr/bin +host-build: + (cd ${WRKBUILD} && env ${HOST_MAKE_ENV} ${MAKE} -f ${MAKE_FILE} \ + ${HOST_MAKE_FLAGS} ${HOST_ALL_TARGET}) +syslinux-hostinstall: + $(INSTALL_DIR) $(STAGING_HOST_DIR)/usr/bin + $(INSTALL_DIR) $(STAGING_HOST_DIR)/usr/share/syslinux + $(CP) $(WRKBUILD)/bios/core/isolinux.bin \ + $(STAGING_HOST_DIR)/usr/share/syslinux + $(CP) $(WRKBUILD)/bios/com32/elflink/ldlinux/ldlinux.c32 \ + $(STAGING_HOST_DIR)/usr/share/syslinux + +include ${TOPDIR}/mk/host-bottom.mk include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/xz/Makefile b/package/xz/Makefile index 1793f8eaf..ac68ff653 100644 --- a/package/xz/Makefile +++ b/package/xz/Makefile @@ -13,13 +13,18 @@ PKG_URL:= http://tukaani.org/xz/ PKG_SITES:= http://tukaani.org/xz/ PKG_OPTS:= dev +include ${TOPDIR}/mk/host.mk include ${TOPDIR}/mk/package.mk +$(eval $(call HOST_template,XZ,xz,${PKG_VERSION}-${PKG_RELEASE})) $(eval $(call PKG_template,XZ,xz,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION},${PKG_OPTS})) +HOST_STYLE:= auto + xz-install: ${INSTALL_DIR} ${IDIR_XZ}/usr/bin ${IDIR_XZ}/usr/lib ${CP} ${WRKINST}/usr/bin/* ${IDIR_XZ}/usr/bin ${CP} ${WRKINST}/usr/lib/*.so* ${IDIR_XZ}/usr/lib +include ${TOPDIR}/mk/host-bottom.mk include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/scripts/adkprepare.sh b/scripts/adkprepare.sh index 08d1ee1a1..5b18d30e3 100755 --- a/scripts/adkprepare.sh +++ b/scripts/adkprepare.sh @@ -21,36 +21,28 @@ openbsd() { PKG_PATH="ftp://ftp.openbsd.org/pub/OpenBSD/${ver}/packages/${arch}/" export PKG_PATH pkg_add -v gmake - pkg_add -v git pkg_add -v bash pkg_add -v wget pkg_add -v gtar-- pkg_add -v gawk pkg_add -v gsed - pkg_add -v screen-- - pkg_add -v vim--no_x11 - pkg_add -v py-libxml } netbsd() { echo "Preparing NetBSD for OpenADK" PKG_PATH="ftp://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/${arch}/${ver}/All/" export PKG_PATH - pkg_add -vu scmgit pkg_add -vu gmake pkg_add -vu bash pkg_add -vu wget pkg_add -vu gtar pkg_add -vu gsed pkg_add -vu gawk - pkg_add -vu vim - pkg_add -vu screen - pkg_add -vu mksh } freebsd() { echo "Preparing FreeBSD for OpenADK" - pkg_add -r git gmake bash wget gtar gsed gawk screen mksh vim + pkg_add -r gmake bash wget gtar gsed gawk } case $os in diff --git a/target/config/Config.in b/target/config/Config.in index 794cc934f..2b9afa98e 100644 --- a/target/config/Config.in +++ b/target/config/Config.in @@ -786,7 +786,7 @@ config ADK_TARGET_ROOTFS_SQUASHFS config ADK_TARGET_ROOTFS_JFFS2 bool "Compressed read-write root filesystem (jffs2)" select ADK_KERNEL_JFFS2_FS - select ADK_HOST_NEED_JFFS2 + select ADK_HOST_NEED_MTD_UTILS select ADK_TARGET_QEMU_WITH_BLOCK if ADK_HARDWARE_QEMU depends on ADK_TARGET_WITH_MTD help @@ -867,8 +867,9 @@ config ADK_TARGET_ROOTFS_ISO select ADK_KERNEL_JOLIET select ADK_KERNEL_SCSI select ADK_KERNEL_BLK_DEV_SR - select ADK_HOST_NEED_MKISOFS + select ADK_HOST_NEED_CDRTOOLS select ADK_HOST_NEED_SYSLINUX + select ADK_TARGET_QEMU_WITH_BLOCK if ADK_HARDWARE_QEMU depends on ADK_HOST_LINUX depends on ADK_LINUX_X86 help diff --git a/target/config/Config.in.tools b/target/config/Config.in.tools index b232a3674..8ef6ee2d7 100644 --- a/target/config/Config.in.tools +++ b/target/config/Config.in.tools @@ -1,4 +1,24 @@ -config ADK_HOST_NEED_MKISOFS +config ADK_HOST_NEED_HEIRLOOM_CPIO + boolean + default y + +config ADK_HOST_NEED_BC + boolean + default y + +config ADK_HOST_NEED_MKCRYPT + boolean + default y + +config ADK_HOST_NEED_FILE + boolean + default y + +config ADK_HOST_NEED_BZIP2 + boolean + default n + +config ADK_HOST_NEED_CDRTOOLS boolean default n @@ -10,7 +30,7 @@ config ADK_HOST_NEED_SQUASHFS boolean default n -config ADK_HOST_NEED_JFFS2 +config ADK_HOST_NEED_MTD_UTILS boolean default n @@ -26,10 +46,6 @@ config ADK_HOST_NEED_LZMA boolean default n -config ADK_HOST_NEED_BZIP2 - boolean - default n - config ADK_HOST_NEED_XZ boolean default n @@ -42,6 +58,10 @@ config ADK_HOST_NEED_MKIMAGE boolean default n +config ADK_HOST_NEED_MKSH + boolean + default n + config ADK_HOST_NEED_PCRE boolean default y if ADK_HOST_DARWIN diff --git a/target/microblaze/sys-available/qemu-microblaze b/target/microblaze/sys-available/qemu-microblaze index a5bdb65e8..ee9cb6a52 100644 --- a/target/microblaze/sys-available/qemu-microblaze +++ b/target/microblaze/sys-available/qemu-microblaze @@ -6,7 +6,6 @@ config ADK_TARGET_SYSTEM_QEMU_MICROBLAZE select ADK_HARDWARE_QEMU select ADK_TARGET_WITH_MTD select ADK_TARGET_KERNEL_LINUXBIN - select ADK_HOST_NEED_MKIMAGE help Qemu support for microblaze big endian architecture. diff --git a/target/microblaze/sys-available/qemu-microblazeel b/target/microblaze/sys-available/qemu-microblazeel index 4d752a942..8dff0e260 100644 --- a/target/microblaze/sys-available/qemu-microblazeel +++ b/target/microblaze/sys-available/qemu-microblazeel @@ -6,7 +6,6 @@ config ADK_TARGET_SYSTEM_QEMU_MICROBLAZEEL select ADK_HARDWARE_QEMU select ADK_TARGET_WITH_MTD select ADK_TARGET_KERNEL_LINUXBIN - select ADK_HOST_NEED_MKIMAGE help Qemu support for microblaze little endian architecture. diff --git a/tests/adk.exp.in b/tests/adk.exp.in deleted file mode 100644 index c5a7b8948..000000000 --- a/tests/adk.exp.in +++ /dev/null @@ -1,5 +0,0 @@ -load_generic_config "unix"; -set_board_info hostname @ADK_TARGET_IP@ -set_board_info username root -set_board_info rsh_prog "/usr/bin/ssh -p @ADK_TARGET_PORT@" -set_board_info rcp_prog "/usr/bin/scp -P @ADK_TARGET_PORT@" diff --git a/tests/master.exp.in b/tests/master.exp.in deleted file mode 100644 index 72d8ab9e6..000000000 --- a/tests/master.exp.in +++ /dev/null @@ -1,5 +0,0 @@ -lappend boards_dir @TOPDIR@/tests -lappend boards_dir /usr/share/dejagnu -set myboard adk -set target_list adk -set verbose 1 diff --git a/toolchain/binutils/Makefile.inc b/toolchain/binutils/Makefile.inc index 16cfc47df..a7a2c3980 100644 --- a/toolchain/binutils/Makefile.inc +++ b/toolchain/binutils/Makefile.inc @@ -3,7 +3,6 @@ PKG_NAME:= binutils PKG_VERSION:= 2.24 -PKG_MD5SUM:= e0f71a7b2ddab0f8612336ac81d9636b +PKG_MD5SUM:= a5dd5dd2d212a282cc1d4a84633e0d88 PKG_RELEASE:= 1 PKG_SITES:= ${MASTER_SITE_GNU:=binutils/} -DISTFILES:= $(PKG_NAME)-$(PKG_VERSION).tar.bz2 diff --git a/toolchain/gcc/Makefile.inc b/toolchain/gcc/Makefile.inc index 25e51178a..21720e4aa 100644 --- a/toolchain/gcc/Makefile.inc +++ b/toolchain/gcc/Makefile.inc @@ -7,8 +7,7 @@ PKG_VERSION:= 4.7.3 PKG_MD5SUM:= 86f428a30379bdee0224e353ee2f999e else PKG_VERSION:= 4.8.2 -PKG_MD5SUM:= a3d7d63b9cb6b6ea049469a0c4a43c9d +PKG_MD5SUM:= deca88241c1135e2ff9fa5486ab5957b endif PKG_RELEASE:= 1 PKG_SITES:= ${MASTER_SITE_GNU:=gcc/gcc-${PKG_VERSION}/} -DISTFILES:= $(PKG_NAME)-$(PKG_VERSION).tar.bz2 diff --git a/toolchain/gdb/Makefile.inc b/toolchain/gdb/Makefile.inc index 23912e1e6..c3807f8fe 100644 --- a/toolchain/gdb/Makefile.inc +++ b/toolchain/gdb/Makefile.inc @@ -3,7 +3,6 @@ PKG_NAME:= gdb PKG_VERSION:= 7.7 -PKG_MD5SUM:= 271a18f41858a7e98b28ae4eb91287c9 +PKG_MD5SUM:= 40051ff95b39bd57b14b1809e2c16152 PKG_RELEASE:= 1 PKG_SITES:= ${MASTER_SITE_GNU:=gdb/} -DISTFILES:= $(PKG_NAME)-$(PKG_VERSION).tar.bz2 diff --git a/toolchain/uClibc/Makefile.inc b/toolchain/uClibc/Makefile.inc index 60e87966c..eff931e2b 100644 --- a/toolchain/uClibc/Makefile.inc +++ b/toolchain/uClibc/Makefile.inc @@ -5,6 +5,6 @@ PKG_NAME:= uClibc PKG_VERSION:= 0.9.33.2 GIT_VERSION:= 0.9.34-git PKG_RELEASE:= 1 -PKG_MD5SUM:= a338aaffc56f0f5040e6d9fa8a12eda1 +PKG_MD5SUM:= 73e6fe215648d02246f4d195b25fb17e PKG_SITES:= http://uclibc.org/downloads/ -DISTFILES:= $(PKG_NAME)-$(PKG_VERSION).tar.bz2 +DISTFILES:= $(PKG_NAME)-$(PKG_VERSION).tar.xz diff --git a/tools/Makefile b/tools/Makefile deleted file mode 100644 index bfed325e0..000000000 --- a/tools/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -TARGETS:=adk mksh mkcrypt cpio m4 flex bc bzip2 xz - -ifeq ($(ADK_HOST_NEED_GENEXT2FS),y) -TARGETS+=genext2fs -endif -ifeq ($(ADK_HOST_NEED_MKIMAGE),y) -TARGETS+=mkimage -endif -ifeq ($(ADK_HOST_NEED_MKISOFS),y) -TARGETS+=cdrtools -endif -ifeq ($(ADK_HOST_NEED_SYSLINUX),y) -TARGETS+=syslinux -endif -ifeq ($(ADK_HOST_NEED_JFFS2),y) -TARGETS+=mtd-utils -endif -ifeq ($(ADK_HOST_NEED_SQUASHFS),y) -TARGETS+=squashfs -endif -ifeq ($(ADK_HOST_NEED_LZOP),y) -TARGETS+=lzo lzop -endif -ifeq ($(ADK_HOST_NEED_LZMA),y) -TARGETS+=lzma -endif -ifeq ($(ADK_HOST_NEED_CCACHE),y) -TARGETS+=ccache -endif -ifeq ($(ADK_HOST_NEED_PCRE),y) -TARGETS+=pcre -endif - -TARGETS_INSTALL:=$(patsubst %,%-install,$(TARGETS)) -TARGETS_CLEAN:=$(patsubst %,%-clean,$(TARGETS)) - -all: install -compile: -install: $(TARGETS_INSTALL) -clean: $(TARGETS_CLEAN) - -%-compile: $(TOOLS_BUILD_DIR) - $(TRACE) "tools/$(patsubst %-compile,%,$@)/compile " - $(MAKE) -C $(patsubst %-compile,%,$@) compile $(MAKE_TRACE) - -%-install: - $(TRACE) "tools/$(patsubst %-install,%,$@)/install " - $(MAKE) -C $(patsubst %-install,%,$@) install $(MAKE_TRACE) - -%-clean: - $(TRACE) "tools/$(patsubst %-clean,%,$@)/clean " - $(MAKE) -C $(patsubst %-clean,%,$@) clean diff --git a/tools/addpattern/Makefile b/tools/addpattern/Makefile deleted file mode 100644 index 10ba05933..000000000 --- a/tools/addpattern/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -include $(TOPDIR)/rules.mk - -all: addpattern.c - $(CC_FOR_BUILD) $(FLAGS_FOR_BUILD) -o ${STAGING_HOST_DIR}/usr/bin/addpattern addpattern.c diff --git a/tools/addpattern/addpattern.c b/tools/addpattern/addpattern.c deleted file mode 100644 index 8133bf26e..000000000 --- a/tools/addpattern/addpattern.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (C) 2004 Manuel Novoa III - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* July 29, 2004 - * - * This is a hacked replacement for the 'addpattern' utility used to - * create wrt54g .bin firmware files. It isn't pretty, but it does - * the job for me. - * - * Extensions: - * -v allows setting the version string on the command line. - * -{0|1} sets the (currently ignored) hw_ver flag in the header - * to 0 or 1 respectively. - */ - -/* January 12, 2005 - * - * Modified by rodent at rodent dot za dot net - * Support added for the new WRT54G v2.2 and WRT54GS v1.1 "flags" - * Without the flags set to 0x7, the above units will refuse to flash. - * - * Extensions: - * -{0|1|2} sets {0|1} sets hw_ver flag to 0/1. {2} sets hw_ver to 1 - * and adds the new hardware "flags" for the v2.2/v1.1 units -*/ - -/* January 1, 2007 - * - * Modified by juan.i.gonzalez at subdown dot net - * Support added for the AG241v2 and similar - * - * Extensions: - * -r #.# adds revision hardware flags. AG241v2 and similar. - * - * AG241V2 firmware sets the hw_ver to 0x44. - * - * Example: -r 2.0 - * - * Convert 2.0 to 20 to be an integer, and add 0x30 to skip special ASCII - * #define HW_Version ((HW_REV * 10) + 0x30) -> from cyutils.h -*/ - -#include -#include -#include -#include -#include -#include - -/**********************************************************************/ - -#define CODE_ID "U2ND" /* from code_pattern.h */ -#define CODE_PATTERN "W54S" /* from code_pattern.h */ -#define PBOT_PATTERN "PBOT" - -#define CYBERTAN_VERSION "v3.37.2" /* from cyutils.h */ - -/* WRT54G v2.2 and WRT54GS v1.1 "flags" (from 3.37.32 firmware cyutils.h) */ -#define SUPPORT_4712_CHIP 0x0001 -#define SUPPORT_INTEL_FLASH 0x0002 -#define SUPPORT_5325E_SWITCH 0x0004 - -struct code_header { /* from cyutils.h */ - char magic[4]; - char res1[4]; /* for extra magic */ - char fwdate[3]; - char fwvern[3]; - char id[4]; /* U2ND */ - char hw_ver; /* 0: for 4702, 1: for 4712 -- new in 2.04.3 */ - char unused; - unsigned char flags[2]; /* SUPPORT_ flags new for 3.37.2 (WRT54G v2.2 and WRT54GS v1.1) */ - unsigned char res2[10]; -} ; - -/**********************************************************************/ - -void usage(void) __attribute__ (( __noreturn__ )); - -void usage(void) -{ - fprintf(stderr, "Usage: addpattern [-i trxfile] [-o binfile] [-p pattern] [-g] [-b] [-v v#.#.#] [-r #.#] [-{0|1|2|4}] -h\n"); - exit(EXIT_FAILURE); -} - -int main(int argc, char **argv) -{ - char buf[1024]; /* keep this at 1k or adjust garbage calc below */ - struct code_header *hdr; - FILE *in = stdin; - FILE *out = stdout; - char *ifn = NULL; - char *ofn = NULL; - char *pattern = CODE_PATTERN; - char *pbotpat = PBOT_PATTERN; - char *version = CYBERTAN_VERSION; - int gflag = 0; - int pbotflag = 0; - int c; - int v0, v1, v2; - size_t off, n; - time_t t; - struct tm *ptm; - - hdr = (struct code_header *) buf; - memset(hdr, 0, sizeof(struct code_header)); - - while ((c = getopt(argc, argv, "i:o:p:gbv:0124hr:")) != -1) { - switch (c) { - case 'i': - ifn = optarg; - break; - case 'o': - ofn = optarg; - break; - case 'p': - pattern = optarg; - break; - case 'g': - gflag = 1; - break; - case 'b': - pbotflag = 1; - break; - case 'v': /* extension to allow setting version */ - version = optarg; - break; - case '0': - hdr->hw_ver = 0; - break; - case '1': - hdr->hw_ver = 1; - break; - case '2': /* new 54G v2.2 and 54GS v1.1 flags */ - hdr->hw_ver = 1; - hdr->flags[0] |= SUPPORT_4712_CHIP; - hdr->flags[0] |= SUPPORT_INTEL_FLASH; - hdr->flags[0] |= SUPPORT_5325E_SWITCH; - break; - case '4': - /* V4 firmware sets the flags to 0x1f */ - hdr->hw_ver = 0; - hdr->flags[0] = 0x1f; - break; - case 'r': - hdr->hw_ver = (char)(atof(optarg)*10)+0x30; - break; - - case 'h': - default: - usage(); - } - } - - if (optind != argc || optind == 1) { - fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); - usage(); - } - - if (strlen(pattern) != 4) { - fprintf(stderr, "illegal pattern \"%s\": length != 4\n", pattern); - usage(); - } - - if (ifn && !(in = fopen(ifn, "r"))) { - fprintf(stderr, "can not open \"%s\" for reading\n", ifn); - usage(); - } - - if (ofn && !(out = fopen(ofn, "w"))) { - fprintf(stderr, "can not open \"%s\" for writing\n", ofn); - usage(); - } - - if (time(&t) == (time_t)(-1)) { - fprintf(stderr, "time call failed\n"); - return EXIT_FAILURE; - } - - ptm = localtime(&t); - - if (3 != sscanf(version, "v%d.%d.%d", &v0, &v1, &v2)) { - fprintf(stderr, "bad version string \"%s\"\n", version); - return EXIT_FAILURE; - } - - memcpy(&hdr->magic, pattern, 4); - if (pbotflag) - memcpy(&hdr->res1, pbotpat, 4); - hdr->fwdate[0] = ptm->tm_year % 100; - hdr->fwdate[1] = ptm->tm_mon + 1; - hdr->fwdate[2] = ptm->tm_mday; - hdr->fwvern[0] = v0; - hdr->fwvern[1] = v1; - hdr->fwvern[2] = v2; - memcpy(&hdr->id, CODE_ID, strlen(CODE_ID)); - - off = sizeof(struct code_header); - - fprintf(stderr, "writing firmware v%d.%d.%d on %d/%d/%d (y/m/d)\n", - v0, v1, v2, - hdr->fwdate[0], hdr->fwdate[1], hdr->fwdate[2]); - - - while ((n = fread(buf + off, 1, sizeof(buf)-off, in) + off) > 0) { - off = 0; - if (n < sizeof(buf)) { - if (ferror(in)) { - FREAD_ERROR: - fprintf(stderr, "fread error\n"); - return EXIT_FAILURE; - } - if (gflag) { - gflag = sizeof(buf) - n; - memset(buf + n, 0xff, gflag); - n = sizeof(buf); - } - } - if (!fwrite(buf, n, 1, out)) { - FWRITE_ERROR: - fprintf(stderr, "fwrite error\n"); - return EXIT_FAILURE; - } - } - - if (ferror(in)) { - goto FREAD_ERROR; - } - - if (fflush(out)) { - goto FWRITE_ERROR; - } - - fclose(in); - fclose(out); - - return EXIT_SUCCESS; -} diff --git a/tools/adk/Makefile b/tools/adk/Makefile deleted file mode 100644 index edd559f85..000000000 --- a/tools/adk/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/depmaker ${STAGING_HOST_DIR}/usr/bin/pkgrebuild ${STAGING_HOST_DIR}/usr/bin/dkgetsz - -${STAGING_HOST_DIR}/usr/bin/depmaker: depmaker.c - ${CC_FOR_BUILD} ${FLAGS_FOR_BUILD} -o $@ depmaker.c - -${STAGING_HOST_DIR}/usr/bin/pkgrebuild: pkgrebuild.c strmap.c - ${CC_FOR_BUILD} ${FLAGS_FOR_BUILD} -o $@ pkgrebuild.c strmap.c - -${STAGING_HOST_DIR}/usr/bin/dkgetsz: dkgetsz.c - ${CC_FOR_BUILD} ${FLAGS_FOR_BUILD} -o $@ dkgetsz.c - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/adk/depmaker.c b/tools/adk/depmaker.c deleted file mode 100644 index 023e58504..000000000 --- a/tools/adk/depmaker.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * depmaker - create package/Depends.mk for OpenADK buildsystem - * - * Copyright (C) 2010-2014 Waldemar Brodkorb - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#define MAXLINE 1024 -#define MAXPATH 128 - -static int prefix = 0; -static int hprefix = 0; - -static int check_symbol(char *symbol) { - - FILE *config; - char buf[MAXLINE]; - char *sym; - int ret; - - if ((sym = malloc(strlen(symbol) + 2)) != NULL) - memset(sym, 0, strlen(symbol) + 2); - else { - perror("Can not allocate memory."); - exit(EXIT_FAILURE); - } - - strncat(sym, symbol, strlen(symbol)); - strncat(sym, "=", 1); - if ((config = fopen(".config", "r")) == NULL) { - perror("Can not open file \".config\"."); - exit(EXIT_FAILURE); - } - - ret = 1; - while (fgets(buf, MAXLINE, config) != NULL) { - if (strncmp(buf, sym, strlen(sym)) == 0) - ret = 0; - } - - free(sym); - if (fclose(config) != 0) - perror("Closing file stream failed"); - - return(ret); -} - -/*@null@*/ -static char *parse_line(char *package, char *pkgvar, char *string, int checksym, int pprefix, int system, int *prefixp) { - - char *key, *value, *dep, *key_sym, *pkgdeps; - char temp[MAXLINE]; - - string[strlen(string)-1] = '\0'; - if ((key = strtok(string, ":=")) == NULL) { - perror("Can not get key from string."); - exit(EXIT_FAILURE); - } - - if (checksym == 1) { - /* extract symbol */ - if ((key_sym = malloc(MAXLINE)) != NULL) - memset(key_sym, 0, MAXLINE); - else { - perror("Can not allocate memory."); - exit(EXIT_FAILURE); - } - if (system == 0) { - if (pprefix == 0) { - if (snprintf(key_sym, MAXLINE, "ADK_PACKAGE_%s_", pkgvar) < 0) - perror("Can not create string variable."); - } else { - if (snprintf(key_sym, MAXLINE, "ADK_PACKAGE_") < 0) - perror("Can not create string variable."); - } - strncat(key_sym, key+6, strlen(key)-6); - } else { - if (snprintf(key_sym, MAXLINE, "ADK_TARGET_SYSTEM_%s", pkgvar) < 0) - perror("Can not create string variable."); - } - - if (check_symbol(key_sym) != 0) { - free(key_sym); - return(NULL); - } - free(key_sym); - } - - if ((pkgdeps = malloc(MAXLINE)) != NULL) - memset(pkgdeps, 0, MAXLINE); - else { - perror("Can not allocate memory."); - exit(EXIT_FAILURE); - } - - value = strtok(NULL, "=\t"); - dep = strtok(value, " "); - while (dep != NULL) { - if (*prefixp == 0) { - *prefixp = 1; - if (snprintf(temp, MAXLINE, "%s-compile: %s-compile", package, dep) < 0) - perror("Can not create string variable."); - } else { - if (snprintf(temp, MAXLINE, " %s-compile", dep) < 0) - perror("Can not create string variable."); - } - strncat(pkgdeps, temp, strlen(temp)); - dep = strtok(NULL, " "); - } - return(pkgdeps); -} - -int main() { - - DIR *pkgdir; - struct dirent *pkgdirp; - FILE *pkg; - char buf[MAXLINE]; - char path[MAXPATH]; - char *string, *pkgvar, *pkgdeps, *hpkgdeps = NULL, *tmp, *fpkg, *cpkg, *spkg, *key, *check, *dpkg; - char *stringtmp; - int i; - - spkg = NULL; - cpkg = NULL; - fpkg = NULL; - - /* read Makefile's for all packages */ - pkgdir = opendir("package"); - while ((pkgdirp = readdir(pkgdir)) != NULL) { - /* skip dotfiles */ - if (strncmp(pkgdirp->d_name, ".", 1) > 0) { - if (snprintf(path, MAXPATH, "package/%s/Makefile", pkgdirp->d_name) < 0) - perror("Can not create string variable."); - pkg = fopen(path, "r"); - if (pkg == NULL) - continue; - - /* transform to uppercase variable name */ - pkgvar = strdup(pkgdirp->d_name); - for (i=0; i<(int)strlen(pkgvar); i++) { - if (pkgvar[i] == '+') - pkgvar[i] = 'X'; - if (pkgvar[i] == '-') - pkgvar[i] = '_'; - pkgvar[i] = toupper(pkgvar[i]); - } - - /* exclude manual maintained packages from package/Makefile */ - if ( - !(strncmp(pkgdirp->d_name, "libpthread", 10) == 0 && strlen(pkgdirp->d_name) == 10) && - !(strncmp(pkgdirp->d_name, "uclibc++", 8) == 0) && - !(strncmp(pkgdirp->d_name, "uclibc", 6) == 0) && - !(strncmp(pkgdirp->d_name, "musl", 4) == 0) && - !(strncmp(pkgdirp->d_name, "glibc", 5) == 0)) { - /* print result to stdout */ - printf("package-$(ADK_COMPILE_%s) += %s\n", pkgvar, pkgdirp->d_name); - } - - if ((pkgdeps = malloc(MAXLINE)) != NULL) - memset(pkgdeps, 0, MAXLINE); - else { - perror("Can not allocate memory."); - exit(EXIT_FAILURE); - } - prefix = 0; - hprefix = 0; - - /* generate build dependencies */ - while (fgets(buf, MAXLINE, pkg) != NULL) { - if ((tmp = malloc(MAXLINE)) != NULL) - memset(tmp, 0 , MAXLINE); - else { - perror("Can not allocate memory."); - exit(EXIT_FAILURE); - } - - /* just read variables prefixed with PKG */ - if (strncmp(buf, "PKG", 3) == 0) { - - string = strstr(buf, "PKG_BUILDDEP:="); - if (string != NULL) { - tmp = parse_line(pkgdirp->d_name, pkgvar, string, 0, 0, 0, &prefix); - if (tmp != NULL) { - strncat(pkgdeps, tmp, strlen(tmp)); - } - } - - string = strstr(buf, "PKG_BUILDDEP+="); - if (string != NULL) { - tmp = parse_line(pkgdirp->d_name, pkgvar, string, 0, 0, 0, &prefix); - if (tmp != NULL) - strncat(pkgdeps, tmp, strlen(tmp)); - } - - // We need to find the system name here - string = strstr(buf, "PKG_BUILDDEP_"); - if (string != NULL) { - check = strstr(buf, ":="); - if (check != NULL) { - stringtmp = strdup(string); - string[strlen(string)-1] = '\0'; - key = strtok(string, ":="); - dpkg = strdup(key+13); - tmp = parse_line(pkgdirp->d_name, dpkg, stringtmp, 1, 0, 1, &prefix); - if (tmp != NULL) - strncat(pkgdeps, tmp, strlen(tmp)); - } - } - - // We need to find the subpackage name here - string = strstr(buf, "PKG_FLAVOURS_"); - if (string != NULL) { - check = strstr(buf, ":="); - if (check != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, ":="); - fpkg = strdup(key+13); - } - } - - string = strstr(buf, "PKGFB_"); - if (string != NULL) { - tmp = parse_line(pkgdirp->d_name, fpkg, string, 1, 0, 0, &prefix); - if (tmp != NULL) - strncat(pkgdeps, tmp, strlen(tmp)); - } - - // We need to find the subpackage name here - string = strstr(buf, "PKG_CHOICES_"); - if (string != NULL) { - check = strstr(buf, ":="); - if (check != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, ":="); - cpkg = strdup(key+12); - } - } - string = strstr(buf, "PKGCB_"); - if (string != NULL) { - tmp = parse_line(pkgdirp->d_name, cpkg, string, 1, 0, 0, &prefix); - if (tmp != NULL) - strncat(pkgdeps, tmp, strlen(tmp)); - } - - // We need to find the subpackage name here - string = strstr(buf, "PKG_SUBPKGS_"); - if (string != NULL) { - check = strstr(buf, ":="); - if (check != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, ":="); - spkg = strdup(key+12); - } - } - - string = strstr(buf, "PKGSB_"); - if (string != NULL) { - tmp = parse_line(pkgdirp->d_name, spkg, string, 1, 1, 0, &prefix); - if (tmp != NULL) { - strncat(pkgdeps, tmp, strlen(tmp)); - } - } - } else if (strncmp(buf, "HOST_BUILDDEP", 13) == 0) { - asprintf(&string, "%s-host", pkgdirp->d_name); - // check retval; string for NULL - tmp = parse_line(string, NULL, buf, 0, 0, 0, &hprefix); - if (tmp && *tmp) { - asprintf(&string, "%s%s", - hpkgdeps ? hpkgdeps : "", - tmp); - free(hpkgdeps); - hpkgdeps = string; - } - } - free(tmp); - } - if (strlen(pkgdeps) != 0) - printf("%s\n", pkgdeps); - if (hpkgdeps && *hpkgdeps) - printf("%s\n", hpkgdeps); - free(hpkgdeps); - hpkgdeps = NULL; - free(pkgdeps); - free(pkgvar); - if (fclose(pkg) != 0) - perror("Closing file stream failed"); - } - } - if (closedir(pkgdir) != 0) - perror("Closing directory stream failed"); - - return(0); -} diff --git a/tools/adk/dkgetsz.c b/tools/adk/dkgetsz.c deleted file mode 100644 index b8315be70..000000000 --- a/tools/adk/dkgetsz.c +++ /dev/null @@ -1,95 +0,0 @@ -/*- - * Copyright © 2010 - * Waldemar Brodkorb - * Thorsten Glaser - * - * Provided that these terms and disclaimer and all copyright notices - * are retained or reproduced in an accompanying document, permission - * is granted to deal in this work without restriction, including un‐ - * limited rights to use, publicly perform, distribute, sell, modify, - * merge, give away, or sublicence. - * - * This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to - * the utmost extent permitted by applicable law, neither express nor - * implied; without malicious intent or gross negligence. In no event - * may a licensor, author or contributor be held liable for indirect, - * direct, other damage, loss, or other issues arising in any way out - * of dealing in the work, even if advised of the possibility of such - * damage or existence of a defect, except proven that it results out - * of said person’s immediate fault when using the work as intended. - * - * Alternatively, this work may be distributed under the terms of the - * General Public License, any version, as published by the Free Soft- - * ware Foundation. - *- - * Display the size of a block device (e.g. USB stick, CF/SF/MMC card - * or hard disc) in 512-byte sectors. - */ - -#define _FILE_OFFSET_BITS 64 - -#include -#include -#include -#include - -#if defined(__APPLE__) -#include -#endif - -#if defined(DIOCGDINFO) -#include -#endif - -#include -#include -#include -#include - -unsigned long long numsecs(int); - -int -main(int argc, char *argv[]) { - int fd; - - if (argc != 2) - errx(255, "Syntax: dkgetsz /dev/sda"); - - if ((fd = open(argv[1], O_RDONLY)) == -1) - err(1, "open"); - printf("%llu\n", numsecs(fd)); - close(fd); - return (0); -} - -unsigned long long -numsecs(int fd) -{ -#if defined(BLKGETSIZE) || defined(DKIOCGETBLOCKCOUNT) -/* - * note: BLKGETSIZE64 returns bytes, not sectors, but the return - * type is size_t which is 32 bits on an ILP32 platform, so it - * fails interestingly here… thus we use BLKGETSIZE instead. - */ -#if defined(DKIOCGETBLOCKCOUNT) - uint64_t nsecs; -#define THEIOCTL DKIOCGETBLOCKCOUNT -#define STRIOCTL "DKIOCGETBLOCKCOUNT" -#else - unsigned long nsecs; -#define THEIOCTL BLKGETSIZE -#define STRIOCTL "BLKGETSIZE" -#endif - if (ioctl(fd, THEIOCTL, &nsecs) == -1) - err(1, "ioctl %s", STRIOCTL); - return ((unsigned long long)nsecs); -#elif defined(DIOCGDINFO) - struct disklabel dl; - - if (ioctl(fd, DIOCGDINFO, &dl) == -1) - err(1, "ioctl DIOCGDINFO"); - return ((unsigned long long)dl.d_secperunit); -#else -#warning PLEASE DO IMPLEMENT numsecs FOR THIS PLATFORM. -#endif -} diff --git a/tools/adk/pkgmaker.c b/tools/adk/pkgmaker.c deleted file mode 100644 index 51d31aa70..000000000 --- a/tools/adk/pkgmaker.c +++ /dev/null @@ -1,1194 +0,0 @@ -/* - * pkgmaker - create package meta-data for OpenADK buildsystem - * - * Copyright (C) 2010-2014 Waldemar Brodkorb - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sortfile.h" -#include "strmap.h" - -#define MAXLINE 4096 -#define MAXVALUE 168 -#define MAXVAR 64 -#define MAXPATH 320 -#define HASHSZ 96 - -static int nobinpkgs; - -#define fatal_error(...) { \ - fprintf(stderr, "Fatal error. "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - exit(1); \ -} - -static int parse_var_hash(char *buf, const char *varname, StrMap *strmap) { - - char *key, *value, *string; - - string = strstr(buf, varname); - if (string != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, ":="); - value = strtok(NULL, "=\t"); - if (value != NULL) - strmap_put(strmap, key, value); - return(0); - } - return(1); -} - -static int parse_var(char *buf, const char *varname, char *pvalue, char **result) { - - char *pkg_var; - char *key, *value, *string; - char pkg_str[MAXVAR]; - - if ((pkg_var = malloc(MAXLINE)) != NULL) - memset(pkg_var, 0, MAXLINE); - else { - perror("Can not allocate memory"); - exit(EXIT_FAILURE); - } - - if (snprintf(pkg_str, MAXVAR, "%s:=", varname) < 0) - perror("can not create path variable."); - string = strstr(buf, pkg_str); - if (string != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, ":="); - value = strtok(NULL, "=\t"); - if (value != NULL) { - strncat(pkg_var, value, strlen(value)); - *result = strdup(pkg_var); - } else { - nobinpkgs = 1; - *result = NULL; - } - free(pkg_var); - return(0); - } else { - if (snprintf(pkg_str, MAXVAR, "%s+=", varname) < 0) - perror("can not create path variable."); - string = strstr(buf, pkg_str); - if (string != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, "+="); - value = strtok(NULL, "=\t"); - if (pvalue != NULL) - strncat(pkg_var, pvalue, strlen(pvalue)); - strncat(pkg_var, " ", 1); - if (value != NULL) - strncat(pkg_var, value, strlen(value)); - *result = strdup(pkg_var); - free(pkg_var); - return(0); - } - } - free(pkg_var); - return(1); -} - -static int parse_var_with_system(char *buf, const char *varname, char *pvalue, char **result, char **sysname, int varlen) { - - char *pkg_var, *check; - char *key, *value, *string; - - if ((pkg_var = malloc(MAXLINE)) != NULL) - memset(pkg_var, 0, MAXLINE); - else { - perror("Can not allocate memory"); - exit(EXIT_FAILURE); - } - - check = strstr(buf, ":="); - if (check != NULL) { - string = strstr(buf, varname); - if (string != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, ":="); - *sysname = strdup(key+varlen); - value = strtok(NULL, "=\t"); - if (value != NULL) { - strncat(pkg_var, value, strlen(value)); - *result = strdup(pkg_var); - } - free(pkg_var); - return(0); - } - } else { - string = strstr(buf, varname); - if (string != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, "+="); - value = strtok(NULL, "=\t"); - if (pvalue != NULL) - strncat(pkg_var, pvalue, strlen(pvalue)); - strncat(pkg_var, " ", 1); - if (value != NULL) - strncat(pkg_var, value, strlen(value)); - *result = strdup(pkg_var); - free(pkg_var); - return(0); - } - } - free(pkg_var); - return(1); -} - -static int parse_var_with_pkg(char *buf, const char *varname, char *pvalue, char **result, char **pkgname, int varlen) { - - char *pkg_var, *check; - char *key, *value, *string; - - if ((pkg_var = malloc(MAXLINE)) != NULL) - memset(pkg_var, 0, MAXLINE); - else { - perror("Can not allocate memory"); - exit(EXIT_FAILURE); - } - - check = strstr(buf, ":="); - if (check != NULL) { - string = strstr(buf, varname); - if (string != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, ":="); - *pkgname = strdup(key+varlen); - value = strtok(NULL, "=\t"); - if (value != NULL) { - strncat(pkg_var, value, strlen(value)); - *result = strdup(pkg_var); - } - free(pkg_var); - return(0); - } - } else { - string = strstr(buf, varname); - if (string != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, "+="); - value = strtok(NULL, "=\t"); - if (pvalue != NULL) - strncat(pkg_var, pvalue, strlen(pvalue)); - strncat(pkg_var, " ", 1); - if (value != NULL) - strncat(pkg_var, value, strlen(value)); - *result = strdup(pkg_var); - free(pkg_var); - return(0); - } - } - free(pkg_var); - return(1); -} - -#if 0 -static void iter_debug(const char *key, const char *value, const void *obj) { - fprintf(stderr, "HASHMAP key: %s value: %s\n", key, value); -} -#endif - -static int hash_str(char *string) { - - int i; - int hash; - - hash = 0; - for (i=0; i<(int)strlen(string); i++) { - hash += string[i]; - } - return(hash); -} - -static void iter(const char *key, const char *value, const void *obj) { - - FILE *config, *section; - int hash; - char *valuestr, *pkg, *subpkg; - char buf[MAXPATH]; - char infile[MAXPATH]; - char outfile[MAXPATH]; - - valuestr = strdup(value); - config = fopen("package/Config.in.auto", "a"); - if (config == NULL) - fatal_error("Can not open file package/Config.in.auto"); - - hash = hash_str(valuestr); - snprintf(infile, MAXPATH, "package/pkglist.d/sectionlst.%d", hash); - snprintf(outfile, MAXPATH, "package/pkglist.d/sectionlst.%d.sorted", hash); - - if (access(infile, F_OK) == 0) { - valuestr[strlen(valuestr)-1] = '\0'; - fprintf(config, "menu \"%s\"\n", valuestr); - sortfile(infile, outfile); - /* avoid duplicate section entries */ - unlink(infile); - section = fopen(outfile, "r"); - while (fgets(buf, MAXPATH, section) != NULL) { - buf[strlen(buf)-1] = '\0'; - if (buf[strlen(buf)-1] == '@') { - buf[strlen(buf)-1] = '\0'; - fprintf(config, "source \"package/%s/Config.in.manual\"\n", buf); - } else { - subpkg = strtok(buf, "|"); - subpkg[strlen(subpkg)-1] = '\0'; - pkg = strtok(NULL, "|"); - fprintf(config, "source \"package/pkgconfigs.d/%s/Config.in.%s\"\n", pkg, subpkg); - } - } - fprintf(config, "endmenu\n\n"); - fclose(section); - } - fclose(config); -} - -static char *tolowerstr(char *string) { - - int i; - char *str; - - /* transform to lowercase variable name */ - str = strdup(string); - for (i=0; i<(int)strlen(str); i++) { - if (str[i] == '_') - str[i] = '-'; - str[i] = tolower(str[i]); - } - return(str); -} - -static char *toupperstr(char *string) { - - int i; - char *str; - - /* transform to uppercase variable name */ - str = strdup(string); - for (i=0; i<(int)strlen(str); i++) { - if (str[i] == '+') - str[i] = 'X'; - if (str[i] == '-') - str[i] = '_'; - /* remove negation here, useful for package host depends */ - if (str[i] == '!') - str[i] = '_'; - str[i] = toupper(str[i]); - } - return(str); -} - - -int main() { - - DIR *pkgdir, *pkglistdir; - struct dirent *pkgdirp; - FILE *pkg, *cfg, *menuglobal, *section; - char hvalue[MAXVALUE]; - char buf[MAXPATH]; - char tbuf[MAXPATH]; - char path[MAXPATH]; - char spath[MAXPATH]; - char dir[MAXPATH]; - char variable[2*MAXVAR]; - char *key, *value, *token, *cftoken, *sp, *hkey, *val, *pkg_fd; - char *pkg_name, *pkg_depends, *pkg_depends_system, *pkg_section, *pkg_descr, *pkg_url; - char *pkg_cxx, *pkg_subpkgs, *pkg_cfline, *pkg_dflt, *pkg_multi; - char *pkg_need_cxx, *pkg_need_java, *pkgname, *sysname, *pkg_debug; - char *pkg_libc_depends, *pkg_host_depends, *pkg_system_depends, *pkg_arch_depends, *pkg_flavours, *pkg_flavours_string, *pkg_choices, *pseudo_name; - char *packages, *pkg_name_u, *pkgs, *pkg_opts, *pkg_libname; - char *saveptr, *p_ptr, *s_ptr, *pkg_helper; - int result; - StrMap *pkgmap, *sectionmap; - - pkg_name = NULL; - pkg_descr = NULL; - pkg_section = NULL; - pkg_url = NULL; - pkg_depends = NULL; - pkg_depends_system = NULL; - pkg_opts = NULL; - pkg_libname = NULL; - pkg_flavours = NULL; - pkg_flavours_string = NULL; - pkg_choices = NULL; - pkg_subpkgs = NULL; - pkg_arch_depends = NULL; - pkg_system_depends = NULL; - pkg_host_depends = NULL; - pkg_libc_depends = NULL; - pkg_cxx = NULL; - pkg_dflt = NULL; - pkg_cfline = NULL; - pkg_multi = NULL; - pkg_need_cxx = NULL; - pkg_need_java = NULL; - pkgname = NULL; - sysname = NULL; - pkg_helper = NULL; - pkg_debug = NULL; - - p_ptr = NULL; - s_ptr = NULL; - - unlink("package/Config.in.auto"); - /* open global sectionfile */ - menuglobal = fopen("package/Config.in.auto.global", "w"); - if (menuglobal == NULL) - fatal_error("global section file not writable."); - - /* read section list and create a hash table */ - section = fopen("package/section.lst", "r"); - if (section == NULL) - fatal_error("section listfile is missing"); - - sectionmap = strmap_new(HASHSZ); - while (fgets(tbuf, MAXPATH, section) != NULL) { - key = strtok(tbuf, "\t"); - value = strtok(NULL, "\t"); - strmap_put(sectionmap, key, value); - } - fclose(section); - - if (mkdir("package/pkgconfigs.d", S_IRWXU) > 0) - fatal_error("creation of package/pkgconfigs.d failed."); - if (mkdir("package/pkgconfigs.d/gcc", S_IRWXU) > 0) - fatal_error("creation of package/pkgconfigs.d/gcc failed."); - if (mkdir("package/pkglist.d", S_IRWXU) > 0) - fatal_error("creation of package/pkglist.d failed."); - - /* delete Config.in.dev */ - if (snprintf(path, MAXPATH, "package/pkgconfigs.d/gcc/Config.in.dev") < 0) - fatal_error("failed to create path variable."); - unlink(path); - cfg = fopen(path, "w"); - if (cfg == NULL) - fatal_error("Config.in.dev can not be opened"); - fprintf(cfg, "config ADK_PACKAGE_GLIBC_DEV\n"); - fprintf(cfg, "\tprompt \"glibc-dev............ development files for glibc\"\n"); - fprintf(cfg, "\ttristate\n"); - fprintf(cfg, "\tdefault n\n"); - fprintf(cfg, "\tdepends on ADK_TARGET_LIB_GLIBC\n"); - fprintf(cfg, "\thelp\n"); - fprintf(cfg, "\t GNU C library header files.\n\n"); - fprintf(cfg, "config ADK_PACKAGE_UCLIBC_DEV\n"); - fprintf(cfg, "\tprompt \"uclibc-dev........... development files for uclibc\"\n"); - fprintf(cfg, "\ttristate\n"); - fprintf(cfg, "\tdefault n\n"); - fprintf(cfg, "\tdepends on ADK_TARGET_LIB_UCLIBC\n"); - fprintf(cfg, "\thelp\n"); - fprintf(cfg, "\t C library header files.\n\n"); - fprintf(cfg, "config ADK_PACKAGE_MUSL_DEV\n"); - fprintf(cfg, "\tprompt \"musl-dev............. development files for musl\"\n"); - fprintf(cfg, "\ttristate\n"); - fprintf(cfg, "\tdefault n\n"); - fprintf(cfg, "\tdepends on ADK_TARGET_LIB_MUSL\n"); - fprintf(cfg, "\thelp\n"); - fprintf(cfg, "\t C library header files.\n\n"); - fclose(cfg); - - /* read Makefile's for all packages */ - pkgdir = opendir("package"); - while ((pkgdirp = readdir(pkgdir)) != NULL) { - /* skip dotfiles */ - if (strncmp(pkgdirp->d_name, ".", 1) > 0) { - if (snprintf(path, MAXPATH, "package/%s/Makefile", pkgdirp->d_name) < 0) - fatal_error("can not create path variable."); - pkg = fopen(path, "r"); - if (pkg == NULL) - continue; - - /* skip manually maintained packages */ - if (snprintf(path, MAXPATH, "package/%s/Config.in.manual", pkgdirp->d_name) < 0) - fatal_error("can not create path variable."); - if (!access(path, F_OK)) { - while (fgets(buf, MAXPATH, pkg) != NULL) { - if ((parse_var(buf, "PKG_SECTION", NULL, &pkg_section)) == 0) - continue; - } - - memset(hvalue, 0 , MAXVALUE); - result = strmap_get(sectionmap, pkg_section, hvalue, sizeof(hvalue)); - if (result == 1) { - if (snprintf(spath, MAXPATH, "package/pkglist.d/sectionlst.%d", hash_str(hvalue)) < 0) - fatal_error("can not create path variable."); - section = fopen(spath, "a"); - if (section != NULL) { - fprintf(section, "%s@\n", pkgdirp->d_name); - fclose(section); - } - } else - fatal_error("Can not find section description for package %s.", - pkgdirp->d_name); - - fclose(pkg); - continue; - } - - nobinpkgs = 0; - - /* create output directories */ - if (snprintf(dir, MAXPATH, "package/pkgconfigs.d/%s", pkgdirp->d_name) < 0) - fatal_error("can not create dir variable."); - if (mkdir(dir, S_IRWXU) > 0) - fatal_error("can not create directory."); - - - /* allocate memory */ - hkey = malloc(MAXVAR); - memset(hkey, 0, MAXVAR); - memset(variable, 0, 2*MAXVAR); - - pkgmap = strmap_new(HASHSZ); - - /* parse package Makefile */ - while (fgets(buf, MAXPATH, pkg) != NULL) { - /* just read variables prefixed with PKG */ - if (strncmp(buf, "PKG", 3) == 0) { - if ((parse_var(buf, "PKG_NAME", NULL, &pkg_name)) == 0) - continue; - if (pkg_name != NULL) - pkg_name_u = toupperstr(pkg_name); - else - pkg_name_u = toupperstr(pkgdirp->d_name); - - snprintf(variable, MAXVAR, "PKG_CFLINE_%s", pkg_name_u); - if ((parse_var(buf, variable, pkg_cfline, &pkg_cfline)) == 0) - continue; - snprintf(variable, MAXVAR, "PKG_DFLT_%s", pkg_name_u); - if ((parse_var(buf, variable, NULL, &pkg_dflt)) == 0) - continue; - if ((parse_var(buf, "PKG_LIBC_DEPENDS", NULL, &pkg_libc_depends)) == 0) - continue; - if ((parse_var(buf, "PKG_HOST_DEPENDS", NULL, &pkg_host_depends)) == 0) - continue; - if ((parse_var(buf, "PKG_ARCH_DEPENDS", NULL, &pkg_arch_depends)) == 0) - continue; - if ((parse_var(buf, "PKG_SYSTEM_DEPENDS", NULL, &pkg_system_depends)) == 0) - continue; - if ((parse_var(buf, "PKG_DESCR", NULL, &pkg_descr)) == 0) - continue; - if ((parse_var(buf, "PKG_SECTION", NULL, &pkg_section)) == 0) - continue; - if ((parse_var(buf, "PKG_URL", NULL, &pkg_url)) == 0) - continue; - if ((parse_var(buf, "PKG_CXX", NULL, &pkg_cxx)) == 0) - continue; - if ((parse_var(buf, "PKG_NEED_CXX", NULL, &pkg_need_cxx)) == 0) - continue; - if ((parse_var(buf, "PKG_NEED_JAVA", NULL, &pkg_need_java)) == 0) - continue; - if ((parse_var(buf, "PKG_MULTI", NULL, &pkg_multi)) == 0) - continue; - if ((parse_var(buf, "PKG_DEPENDS", pkg_depends, &pkg_depends)) == 0) - continue; - if ((parse_var_with_system(buf, "PKG_DEPENDS_", pkg_depends_system, &pkg_depends_system, &sysname, 12)) == 0) - continue; - if ((parse_var(buf, "PKG_LIBNAME", pkg_libname, &pkg_libname)) == 0) - continue; - if ((parse_var(buf, "PKG_OPTS", pkg_opts, &pkg_opts)) == 0) - continue; - if ((parse_var_with_pkg(buf, "PKG_FLAVOURS_STRING_", pkg_flavours_string, &pkg_flavours_string, &pkgname, 20)) == 0) - continue; - if ((parse_var_with_pkg(buf, "PKG_FLAVOURS_", pkg_flavours, &pkg_flavours, &pkgname, 13)) == 0) - continue; - if ((parse_var_hash(buf, "PKGFD_", pkgmap)) == 0) - continue; - if ((parse_var_hash(buf, "PKGFX_", pkgmap)) == 0) - continue; - if ((parse_var_hash(buf, "PKGFS_", pkgmap)) == 0) - continue; - if ((parse_var_hash(buf, "PKGFC_", pkgmap)) == 0) - continue; - if ((parse_var_with_pkg(buf, "PKG_CHOICES_", pkg_choices, &pkg_choices, &pkgname, 12)) == 0) - continue; - if ((parse_var_hash(buf, "PKGCD_", pkgmap)) == 0) - continue; - if ((parse_var_hash(buf, "PKGCS_", pkgmap)) == 0) - continue; - if ((parse_var(buf, "PKG_SUBPKGS", pkg_subpkgs, &pkg_subpkgs)) == 0) - continue; - if ((parse_var_hash(buf, "PKGSD_", pkgmap)) == 0) - continue; - if ((parse_var_hash(buf, "PKGSS_", pkgmap)) == 0) - continue; - if ((parse_var_hash(buf, "PKGSC_", pkgmap)) == 0) - continue; - } - } - - /* when PKG_LIBNAME exist use this instead of PKG_NAME, but only for !libmix */ - if (pkg_libname != NULL) - if (pkg_opts != NULL) - if (strstr(pkg_opts, "libmix") == NULL) - pkg_name = strdup(pkg_libname); - - /* end of package Makefile parsing */ - if (fclose(pkg) != 0) - perror("Failed to close file stream for Makefile"); - -#if 0 - if (pkg_name != NULL) - fprintf(stderr, "Package name is %s\n", pkg_name); - if (pkg_libname != NULL) - fprintf(stderr, "Package library name is %s\n", pkg_libname); - if (pkg_section != NULL) - fprintf(stderr, "Package section is %s\n", pkg_section); - if (pkg_descr != NULL) - fprintf(stderr, "Package description is %s\n", pkg_descr); - if (pkg_depends != NULL) - fprintf(stderr, "Package dependencies are %s\n", pkg_depends); - if (pkg_depends_system != NULL) - fprintf(stderr, "Package systemspecific dependencies are %s\n", pkg_depends_system); - if (pkg_subpkgs != NULL) - fprintf(stderr, "Package subpackages are %s\n", pkg_subpkgs); - if (pkg_flavours != NULL && pkgname != NULL) - fprintf(stderr, "Package flavours for %s are %s\n", pkgname, pkg_flavours); - if (pkg_flavours_string != NULL && pkgname != NULL) - fprintf(stderr, "Package string flavours for %s are %s\n", pkgname, pkg_flavours_string); - if (pkg_choices != NULL && pkgname != NULL) - fprintf(stderr, "Package choices for %s are %s\n", pkgname, pkg_choices); - if (pkg_url != NULL) - fprintf(stderr, "Package homepage is %s\n", pkg_url); - if (pkg_cfline != NULL) - fprintf(stderr, "Package cfline is %s\n", pkg_cfline); - if (pkg_multi != NULL) - fprintf(stderr, "Package multi is %s\n", pkg_multi); - if (pkg_opts != NULL) - fprintf(stderr, "Package options are %s\n", pkg_opts); - - strmap_enum(pkgmap, iter_debug, NULL); -#endif - - /* generate master source Config.in file */ - if (snprintf(path, MAXPATH, "package/pkgconfigs.d/%s/Config.in", pkgdirp->d_name) < 0) - fatal_error("path variable creation failed."); - fprintf(menuglobal, "source \"%s\"\n", path); - /* recreating file is faster than truncating with w+ */ - unlink(path); - cfg = fopen(path, "w"); - if (cfg == NULL) - continue; - - pkgs = NULL; - if (pkg_subpkgs != NULL) - pkgs = strdup(pkg_subpkgs); - - fprintf(cfg, "config ADK_COMPILE_%s\n", toupperstr(pkgdirp->d_name)); - fprintf(cfg, "\ttristate\n"); - if (nobinpkgs == 0) { - fprintf(cfg, "\tdepends on "); - if (pkgs != NULL) { - if (pkg_multi != NULL) - if (strncmp(pkg_multi, "1", 1) == 0) - fprintf(cfg, "ADK_HAVE_DOT_CONFIG || "); - token = strtok(pkgs, " "); - fprintf(cfg, "ADK_PACKAGE_%s", token); - token = strtok(NULL, " "); - while (token != NULL) { - fprintf(cfg, " || ADK_PACKAGE_%s", token); - token = strtok(NULL, " "); - } - fprintf(cfg, "\n"); - } else { - fprintf(cfg, "ADK_PACKAGE_%s\n", toupperstr(pkg_name)); - } - } - fprintf(cfg, "\tdefault n\n"); - fclose(cfg); - free(pkgs); - - - /* skip packages without binary package output */ - if (nobinpkgs == 1) - continue; - - /* generate binary package specific Config.in files */ - if (pkg_subpkgs != NULL) - packages = tolowerstr(pkg_subpkgs); - else - packages = strdup(pkg_name); - - token = strtok_r(packages, " ", &p_ptr); - while (token != NULL) { - strncat(hkey, "PKGSC_", 6); - strncat(hkey, toupperstr(token), strlen(token)); - memset(hvalue, 0 , MAXVALUE); - result = strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); - memset(hkey, 0 , MAXVAR); - if (result == 1) - pkg_section = strdup(hvalue); - - strncat(hkey, "PKGSD_", 6); - strncat(hkey, toupperstr(token), strlen(token)); - memset(hvalue, 0 , MAXVALUE); - result = strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); - memset(hkey, 0 , MAXVAR); - if (result == 1) - pkg_descr = strdup(hvalue); - - pseudo_name = malloc(MAXLINE); - memset(pseudo_name, 0, MAXLINE); - strncat(pseudo_name, token, strlen(token)); - while (strlen(pseudo_name) < 20) - strncat(pseudo_name, ".", 1); - - if (snprintf(path, MAXPATH, "package/pkgconfigs.d/%s/Config.in.%s", pkgdirp->d_name, token) < 0) - fatal_error("failed to create path variable."); - - /* create temporary section files */ - memset(hvalue, 0 , MAXVALUE); - result = strmap_get(sectionmap, pkg_section, hvalue, sizeof(hvalue)); - if (result == 1) { - if (snprintf(spath, MAXPATH, "package/pkglist.d/sectionlst.%d", hash_str(hvalue)) < 0) - fatal_error("failed to create path variable."); - section = fopen(spath, "a"); - if (section != NULL) { - fprintf(section, "%s |%s\n", token, pkgdirp->d_name); - fclose(section); - } - } else - fatal_error("Can not find section description for package %s.", pkgdirp->d_name); - - unlink(path); - cfg = fopen(path, "w"); - if (cfg == NULL) - perror("Can not open Config.in file"); - - if (pkg_need_cxx != NULL) { - fprintf(cfg, "comment \"%s... %s (disabled, c++ missing)\"\n", token, pkg_descr); - fprintf(cfg, "depends on !ADK_TOOLCHAIN_GCC_CXX\n\n"); - } - - /* save token in pkg_debug */ - pkg_debug = strdup(token); - fprintf(cfg, "config ADK_PACKAGE_%s\n", toupperstr(token)); - /* no prompt for devonly packages */ - if (pkg_opts != NULL) { - if (strstr(pkg_opts, "devonly") != NULL) { - fprintf(cfg, "\t#prompt \"%s. %s\"\n", pseudo_name, pkg_descr); - } else { - fprintf(cfg, "\tprompt \"%s. %s\"\n", pseudo_name, pkg_descr); - } - } else { - fprintf(cfg, "\tprompt \"%s. %s\"\n", pseudo_name, pkg_descr); - } - - fprintf(cfg, "\ttristate\n"); - if (pkg_multi != NULL) - if (strncmp(pkg_multi, "1", 1) == 0) - if (strncmp(toupperstr(token), toupperstr(pkgdirp->d_name), strlen(token)) != 0) - fprintf(cfg, "\tdepends on ADK_PACKAGE_%s\n", toupperstr(pkgdirp->d_name)); - - free(pseudo_name); - - /* print custom cf line */ - if (pkg_cfline != NULL) { - cftoken = strtok_r(pkg_cfline, "@", &saveptr); - while (cftoken != NULL) { - fprintf(cfg, "\t%s\n", cftoken); - cftoken = strtok_r(NULL, "@", &saveptr); - } - free(pkg_cfline); - pkg_cfline = NULL; - } - - /* add sub package dependencies */ - strncat(hkey, "PKGSS_", 6); - strncat(hkey, toupperstr(token), strlen(token)); - memset(hvalue, 0, MAXVALUE); - result = strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); - if (result == 1) { - val = strtok_r(hvalue, " ", &saveptr); - while (val != NULL) { - if (strncmp(val, "kmod", 4) == 0) - fprintf(cfg, "\tselect ADK_KPACKAGE_%s\n", toupperstr(val)); - else - fprintf(cfg, "\tselect ADK_PACKAGE_%s\n", toupperstr(val)); - val = strtok_r(NULL, " ", &saveptr); - } - } - memset(hkey, 0, MAXVAR); - - /* create package target system dependency information */ - if (pkg_system_depends != NULL) { - pkg_helper = strdup(pkg_system_depends); - token = strtok(pkg_helper, " "); - fprintf(cfg, "\tdepends on "); - sp = ""; - while (token != NULL) { - if(strncmp(token, "!", 1) == 0) { - fprintf(cfg, "%s!ADK_TARGET_SYSTEM%s", sp, toupperstr(token)); - sp = " && "; - } else { - fprintf(cfg, "%sADK_TARGET_SYSTEM_%s", sp, toupperstr(token)); - sp = " || "; - } - token = strtok(NULL, " "); - } - fprintf(cfg, "\n"); - free(pkg_helper); - pkg_helper = NULL; - } - /* create package host dependency information */ - if (pkg_host_depends != NULL) { - pkg_helper = strdup(pkg_host_depends); - token = strtok(pkg_helper, " "); - fprintf(cfg, "\tdepends on "); - sp = ""; - while (token != NULL) { - if(strncmp(token, "!", 1) == 0) { - fprintf(cfg, "%s!ADK_HOST%s", sp, toupperstr(token)); - sp = " && "; - } else { - fprintf(cfg, "%sADK_HOST_%s", sp, toupperstr(token)); - sp = " || "; - } - token = strtok(NULL, " "); - } - fprintf(cfg, "\n"); - free(pkg_helper); - pkg_helper = NULL; - } - - /* create package libc dependency information */ - if (pkg_libc_depends != NULL) { - pkg_helper = strdup(pkg_libc_depends); - token = strtok(pkg_helper, " "); - fprintf(cfg, "\tdepends on "); - sp = ""; - while (token != NULL) { - if(strncmp(token, "!", 1) == 0) { - fprintf(cfg, "%s!ADK_TARGET_LIB_%s", sp, toupperstr(token)); - sp = " && "; - } else { - fprintf(cfg, "%sADK_TARGET_LIB_%s", sp, toupperstr(token)); - sp = " || "; - } - token = strtok(NULL, " "); - } - fprintf(cfg, "\n"); - free(pkg_helper); - pkg_helper = NULL; - } - /* create package target architecture dependency information */ - if (pkg_arch_depends != NULL) { - pkg_helper = strdup(pkg_arch_depends); - token = strtok(pkg_helper, " "); - fprintf(cfg, "\tdepends on "); - sp = ""; - while (token != NULL) { - if(strncmp(token, "!", 1) == 0) { - fprintf(cfg, "%s!ADK_LINUX%s", sp, toupperstr(token)); - sp = " && "; - } else { - fprintf(cfg, "%sADK_LINUX_%s", sp, toupperstr(token)); - sp = " || "; - } - token = strtok(NULL, " "); - } - fprintf(cfg, "\n"); - free(pkg_helper); - pkg_helper = NULL; - } - - /* create package dependency information */ - if (pkg_depends != NULL) { - token = strtok(pkg_depends, " "); - while (token != NULL) { - if (strncmp(token, "kmod", 4) == 0) - fprintf(cfg, "\tselect ADK_KPACKAGE_%s\n", toupperstr(token)); - else - fprintf(cfg, "\tselect ADK_PACKAGE_%s\n", toupperstr(token)); - token = strtok(NULL, " "); - } - free(pkg_depends); - pkg_depends = NULL; - } - /* create system specific package dependency information */ - if (pkg_depends_system != NULL) { - token = strtok(pkg_depends_system, " "); - while (token != NULL) { - fprintf(cfg, "\tselect ADK_PACKAGE_%s if ADK_TARGET_SYSTEM_%s\n", toupperstr(token), sysname); - token = strtok(NULL, " "); - } - free(pkg_depends_system); - pkg_depends_system = NULL; - } - - if (pkg_need_cxx != NULL) { - fprintf(cfg, "\tdepends on ADK_TOOLCHAIN_GCC_CXX\n"); - } - if (pkg_need_java != NULL) { - fprintf(cfg, "\tdepends on ADK_TOOLCHAIN_GCC_JAVA\n"); - pkg_need_java = NULL; - } - - fprintf(cfg, "\tselect ADK_COMPILE_%s\n", toupperstr(pkgdirp->d_name)); - - if (pkg_dflt != NULL) { - fprintf(cfg, "\tdefault %s\n", pkg_dflt); - pkg_dflt = NULL; - } else { - fprintf(cfg, "\tdefault n\n"); - } - - fprintf(cfg, "\thelp\n"); - fprintf(cfg, "\t %s\n\n", pkg_descr); - if (pkg_url != NULL) - fprintf(cfg, "\t WWW: %s\n", pkg_url); - - /* handle special C++ packages */ - if (pkg_cxx != NULL) { - fprintf(cfg, "\nchoice\n"); - fprintf(cfg, "prompt \"C++ library to use\"\n"); - fprintf(cfg, "depends on ADK_COMPILE_%s\n\n", toupperstr(pkgdirp->d_name)); - fprintf(cfg, "default ADK_COMPILE_%s_WITH_STDCXX if ADK_TARGET_LIB_GLIBC\n", pkg_cxx); - fprintf(cfg, "default ADK_COMPILE_%s_WITH_UCLIBCXX if ADK_TARGET_LIB_UCLIBC\n\n", pkg_cxx); - fprintf(cfg, "config ADK_COMPILE_%s_WITH_STDCXX\n", pkg_cxx); - fprintf(cfg, "\tbool \"GNU C++ library\"\n"); - fprintf(cfg, "\tselect ADK_PACKAGE_LIBSTDCXX\n\n"); - fprintf(cfg, "config ADK_COMPILE_%s_WITH_UCLIBCXX\n", pkg_cxx); - fprintf(cfg, "\tbool \"uClibc++ library\"\n"); - fprintf(cfg, "\tselect ADK_PACKAGE_UCLIBCXX\n\n"); - fprintf(cfg, "endchoice\n"); - free(pkg_cxx); - pkg_cxx = NULL; - } - - /* handle debug subpackages */ - fprintf(cfg, "\nconfig ADK_PACKAGE_%s_DBG\n", toupperstr(pkg_debug)); - fprintf(cfg, "\tprompt \"add debug symbols package\"\n"); - fprintf(cfg, "\ttristate\n"); - fprintf(cfg, "\tdepends on ADK_PACKAGE_GDB\n"); - fprintf(cfg, "\tdepends on !ADK_DEBUG\n"); - fprintf(cfg, "\tdepends on ADK_PACKAGE_%s\n", toupperstr(pkg_debug)); - fprintf(cfg, "\tdefault n\n"); - fprintf(cfg, "\thelp\n\n"); - - /* package flavours */ - if (pkg_flavours != NULL) { - token = strtok(pkg_flavours, " "); - while (token != NULL) { - fprintf(cfg, "\nconfig ADK_PACKAGE_%s_%s\n", pkgname, toupperstr(token)); - - // process default value - strncat(hkey, "PKGFX_", 6); - strncat(hkey, token, strlen(token)); - memset(hvalue, 0 , MAXVALUE); - strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); - memset(hkey, 0 , MAXVAR); - pkg_fd = strdup(hvalue); - if (strlen(pkg_fd) > 0) - fprintf(cfg, "\tdefault %s\n", pkg_fd); - else - fprintf(cfg, "\tdefault n\n"); - - - // process flavour cfline - strncat(hkey, "PKGFC_", 6); - strncat(hkey, token, strlen(token)); - memset(hvalue, 0 , MAXVALUE); - strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); - memset(hkey, 0 , MAXVAR); - pkg_fd = strdup(hvalue); - if (strlen(pkg_fd) > 0) - fprintf(cfg, "\t%s\n", pkg_fd); - - fprintf(cfg, "\tboolean "); - strncat(hkey, "PKGFD_", 6); - strncat(hkey, token, strlen(token)); - memset(hvalue, 0 , MAXVALUE); - strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); - memset(hkey, 0 , MAXVAR); - pkg_fd = strdup(hvalue); - - fprintf(cfg, "\"%s\"\n", pkg_fd); - fprintf(cfg, "\tdepends on ADK_PACKAGE_%s\n", pkgname); - strncat(hkey, "PKGFS_", 6); - strncat(hkey, token, strlen(token)); - - result = strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); - if (result == 1) { - val = strtok_r(hvalue, " ", &saveptr); - while (val != NULL) { - if (strncmp(val, "kmod", 4) == 0) - fprintf(cfg, "\tselect ADK_KPACKAGE_%s\n", toupperstr(val)); - else - fprintf(cfg, "\tselect ADK_PACKAGE_%s\n", toupperstr(val)); - val = strtok_r(NULL, " ", &saveptr); - } - } - memset(hkey, 0, MAXVAR); - fprintf(cfg, "\thelp\n"); - fprintf(cfg, "\t %s\n", pkg_fd); - token = strtok(NULL, " "); - } - free(pkg_flavours); - pkg_flavours = NULL; - } - - /* package flavours string */ - if (pkg_flavours_string != NULL) { - token = strtok(pkg_flavours_string, " "); - while (token != NULL) { - fprintf(cfg, "\nconfig ADK_PACKAGE_%s_%s\n", pkgname, toupperstr(token)); - - // process default value - strncat(hkey, "PKGFX_", 6); - strncat(hkey, token, strlen(token)); - memset(hvalue, 0 , MAXVALUE); - strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); - memset(hkey, 0 , MAXVAR); - pkg_fd = strdup(hvalue); - if (strlen(pkg_fd) > 0) - fprintf(cfg, "\tdefault \"%s\"\n", pkg_fd); - - // process flavour cfline - strncat(hkey, "PKGFC_", 6); - strncat(hkey, token, strlen(token)); - memset(hvalue, 0 , MAXVALUE); - strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); - memset(hkey, 0 , MAXVAR); - pkg_fd = strdup(hvalue); - if (strlen(pkg_fd) > 0) - fprintf(cfg, "\t%s\n", pkg_fd); - - fprintf(cfg, "\tstring "); - strncat(hkey, "PKGFD_", 6); - strncat(hkey, token, strlen(token)); - memset(hvalue, 0 , MAXVALUE); - strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); - memset(hkey, 0 , MAXVAR); - pkg_fd = strdup(hvalue); - fprintf(cfg, "\"%s\"\n", pkg_fd); - - fprintf(cfg, "\tdepends on ADK_PACKAGE_%s\n", pkgname); - strncat(hkey, "PKGFS_", 6); - strncat(hkey, token, strlen(token)); - - result = strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); - if (result == 1) { - val = strtok_r(hvalue, " ", &saveptr); - while (val != NULL) { - if (strncmp(val, "kmod", 4) == 0) - fprintf(cfg, "\tselect ADK_KPACKAGE_%s\n", toupperstr(val)); - else - fprintf(cfg, "\tselect ADK_PACKAGE_%s\n", toupperstr(val)); - val = strtok_r(NULL, " ", &saveptr); - } - } - memset(hkey, 0, MAXVAR); - fprintf(cfg, "\thelp\n"); - fprintf(cfg, "\t %s\n", pkg_fd); - token = strtok(NULL, " "); - } - free(pkg_flavours_string); - pkg_flavours_string = NULL; - } - - /* package choices */ - if (pkg_choices != NULL) { - fprintf(cfg, "\nchoice\n"); - fprintf(cfg, "prompt \"Package flavour choice\"\n"); - fprintf(cfg, "depends on ADK_PACKAGE_%s\n\n", pkgname); - token = strtok(pkg_choices, " "); - while (token != NULL) { - fprintf(cfg, "config ADK_PACKAGE_%s_%s\n", pkgname, toupperstr(token)); - - fprintf(cfg, "\tbool "); - strncat(hkey, "PKGCD_", 6); - strncat(hkey, token, strlen(token)); - memset(hvalue, 0 , MAXVALUE); - strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); - memset(hkey, 0 , MAXVAR); - fprintf(cfg, "\"%s\"\n", hvalue); - - strncat(hkey, "PKGCS_", 6); - strncat(hkey, token, strlen(token)); - memset(hvalue, 0, MAXVALUE); - result = strmap_get(pkgmap, hkey, hvalue, sizeof(hvalue)); - if (result == 1) { - val = strtok_r(hvalue, " ", &saveptr); - while (val != NULL) { - if (strncmp(val, "kmod", 4) == 0) - fprintf(cfg, "\tselect ADK_KPACKAGE_%s\n", toupperstr(val)); - else - fprintf(cfg, "\tselect ADK_PACKAGE_%s\n", toupperstr(val)); - val = strtok_r(NULL, " ", &saveptr); - } - } - memset(hkey, 0, MAXVAR); - token = strtok(NULL, " "); - } - fprintf(cfg, "\nendchoice\n"); - free(pkg_choices); - pkg_choices = NULL; - } - /* close file descriptor for Config.in file */ - fclose(cfg); - /* create Config.in files for development packages */ - if (pkg_opts != NULL) { - if (strstr(pkg_opts, "dev") != NULL) { - if (snprintf(path, MAXPATH, "package/pkgconfigs.d/gcc/Config.in.dev") < 0) - fatal_error("failed to create path variable."); - cfg = fopen(path, "a"); - if (cfg == NULL) - perror("Can not open Config.in.dev file"); - - if (pkg_libname == NULL) - pkg_libname = strdup(pkg_name); - - fprintf(cfg, "\n"); - fprintf(cfg, "config ADK_PACKAGE_%s_DEV\n", toupperstr(pkg_libname)); - - pseudo_name = malloc(MAXLINE); - memset(pseudo_name, 0, MAXLINE); - strncat(pseudo_name, pkg_libname, strlen(pkg_libname)); - strncat(pseudo_name, "-dev", 4); - while (strlen(pseudo_name) < 20) - strncat(pseudo_name, ".", 1); - - fprintf(cfg, "\tprompt \"%s. development files for %s\"\n", pseudo_name, pkg_libname); - fprintf(cfg, "\ttristate\n"); - - /* create package target architecture dependency information */ - if (pkg_arch_depends != NULL) { - pkg_helper = strdup(pkg_arch_depends); - token = strtok(pkg_helper, " "); - fprintf(cfg, "\tdepends on "); - sp = ""; - while (token != NULL) { - if(strncmp(token, "!", 1) == 0) { - fprintf(cfg, "%s!ADK_LINUX%s", sp, toupperstr(token)); - sp = " && "; - } else { - fprintf(cfg, "%sADK_LINUX_%s", sp, toupperstr(token)); - sp = " || "; - } - token = strtok(NULL, " "); - } - fprintf(cfg, "\n"); - free(pkg_helper); - pkg_helper = NULL; - } - - fprintf(cfg, "\tdepends on ADK_PACKAGE_GCC\n"); - fprintf(cfg, "\tselect ADK_PACKAGE_%s\n", toupperstr(pkg_libname)); - fprintf(cfg, "\tdefault n\n"); - fclose(cfg); - free(pseudo_name); - free(pkg_libname); - pkg_libname = NULL; - } - pkg_opts = NULL; - } - /* parse next package */ - token = strtok_r(NULL, " ", &p_ptr); - } - - /* end of package output generation */ - free(packages); - packages = NULL; - - pkg_need_cxx = NULL; - pkg_need_java = NULL; - /* reset flags, free memory */ - free(pkg_name); - free(pkg_libname); - free(pkg_descr); - free(pkg_section); - free(pkg_url); - free(pkg_depends); - free(pkg_flavours); - free(pkg_flavours_string); - free(pkg_choices); - free(pkg_subpkgs); - free(pkg_arch_depends); - free(pkg_system_depends); - free(pkg_host_depends); - free(pkg_libc_depends); - free(pkg_cxx); - free(pkg_dflt); - free(pkg_cfline); - free(pkg_multi); - pkg_name = NULL; - pkg_libname = NULL; - pkg_descr = NULL; - pkg_section = NULL; - pkg_url = NULL; - pkg_depends = NULL; - pkg_flavours = NULL; - pkg_flavours_string = NULL; - pkg_choices = NULL; - pkg_subpkgs = NULL; - pkg_arch_depends = NULL; - pkg_system_depends = NULL; - pkg_host_depends = NULL; - pkg_libc_depends = NULL; - pkg_cxx = NULL; - pkg_dflt = NULL; - pkg_cfline = NULL; - pkg_multi = NULL; - - strmap_delete(pkgmap); - nobinpkgs = 0; - free(hkey); - } - } - - /* add menu to gcc package */ - if (snprintf(path, MAXPATH, "package/pkgconfigs.d/gcc/Config.in.gcc") < 0) - fatal_error("failed to create path variable."); - cfg = fopen(path, "a"); - if (cfg == NULL) - perror("Can not open Config.in.gcc file"); - fprintf(cfg, "menu \"Development packages\"\n"); - fprintf(cfg, "depends on ADK_PACKAGE_GCC\n"); - fprintf(cfg, "source \"package/pkgconfigs.d/gcc/Config.in.dev\"\n"); - fprintf(cfg, "endmenu\n"); - fclose(cfg); - - /* create Config.in.auto */ - strmap_enum(sectionmap, iter, NULL); - - strmap_delete(sectionmap); - fclose(menuglobal); - closedir(pkgdir); - - /* remove temporary section files */ - pkglistdir = opendir("package/pkglist.d"); - while ((pkgdirp = readdir(pkglistdir)) != NULL) { - if (strncmp(pkgdirp->d_name, "sectionlst.", 11) == 0) { - if (snprintf(path, MAXPATH, "package/pkglist.d/%s", pkgdirp->d_name) < 0) - fatal_error("creating path variable failed."); - if (unlink(path) < 0) - fatal_error("removing file failed."); - } - } - closedir(pkglistdir); - return(0); -} diff --git a/tools/adk/pkgrebuild.c b/tools/adk/pkgrebuild.c deleted file mode 100644 index e7f037ae5..000000000 --- a/tools/adk/pkgrebuild.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * pkgrebuild - recognize required package rebuilds in OpenADK - * - * Copyright (C) 2010,2011 Waldemar Brodkorb - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "strmap.h" - -StrMap *configmap, *configoldmap, *pkgmap; - -/* -static void iter(const char *key, const char *value, const void *obj) { - fprintf(stderr, "key: %s value: %s\n", key, value); -} -*/ - -static void iter_disabled(const char *key, const char *value, const void *obj) { - - char hvalue[256]; - char tfile[256]; - int fd; - - memset(hvalue, 0, 256); - if (strmap_exists(configmap, key) == 0) { - //fprintf(stderr, "disabled variables: %s\n", key); - if (strmap_get(pkgmap, key, hvalue, sizeof(hvalue)) == 1) { - //fprintf(stderr, "Symbol is a flavour/choice: %s\n", hvalue); - if (snprintf(tfile, 256, ".rebuild.%s", hvalue) < 0) - perror("can not create file variable."); - fd = open(tfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - close(fd); - } - } - -} - -static void iter_enabled(const char *key, const char *value, const void *obj) { - - char hvalue[256]; - char tfile[256]; - int fd; - - memset(hvalue, 0, 256); - if (strmap_exists(configoldmap, key) == 0) { - //fprintf(stderr, "enabled variables: %s\n", key); - if (strmap_get(pkgmap, key, hvalue, sizeof(hvalue)) == 1) { - //fprintf(stderr, "Symbol is a flavour/choice\n"); - if (snprintf(tfile, 256, ".rebuild.%s", hvalue) < 0) - perror("can not create file variable."); - fd = open(tfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - close(fd); - } - } -} - -static char *toupperstr(char *string) { - - int i; - char *str; - - /* transform to uppercase variable name */ - str = strdup(string); - for (i=0; i<(int)strlen(str); i++) { - if (str[i] == '+') - str[i] = 'X'; - if (str[i] == '-') - str[i] = '_'; - str[i] = toupper(str[i]); - } - return(str); -} - - - -int main() { - - FILE *config, *configold, *pkg; - char *key, *value, *string, *token, *check; - char *pkg_name, *keystr, *realpkgname; - char buf[128]; - char path[320]; - char pbuf[320]; - DIR *pkgdir; - struct dirent *pkgdirp; - - pkg_name = NULL; - /* read Makefile's for all packages */ - pkgmap = strmap_new(1024); - pkgdir = opendir("package"); - while ((pkgdirp = readdir(pkgdir)) != NULL) { - /* skip dotfiles */ - if (strncmp(pkgdirp->d_name, ".", 1) > 0) { - if (snprintf(path, 320, "package/%s/Makefile", pkgdirp->d_name) < 0) - perror("can not create path variable."); - pkg = fopen(path, "r"); - if (pkg == NULL) - continue; - - while (fgets(pbuf, 320, pkg) != NULL) { - if (strncmp(pbuf, "PKG", 3) == 0) { - string = strstr(pbuf, "PKG_NAME:="); - if (string != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, ":="); - value = strtok(NULL, "=\t"); - if (value != NULL) - pkg_name = strdup(value); - } - string = strstr(pbuf, "PKG_SUBPKGS:="); - if (string != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, ":="); - value = strtok(NULL, "=\t"); - token = strtok(value, " "); - while (token != NULL) { - keystr = malloc(256); - memset(keystr, 0, 256); - strncat(keystr, "ADK_PACKAGE_", 12); - strncat(keystr, token, strlen(token)); - strmap_put(pkgmap, keystr, pkgdirp->d_name); - token = strtok(NULL, " "); - free(keystr); - keystr = NULL; - } - } - string = strstr(pbuf, "PKG_SUBPKGS+="); - if (string != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, "+="); - value = strtok(NULL, "=\t"); - token = strtok(value, " "); - while (token != NULL) { - keystr = malloc(256); - memset(keystr, 0, 256); - strncat(keystr, "ADK_PACKAGE_", 12); - strncat(keystr, token, strlen(token)); - strmap_put(pkgmap, keystr, pkgdirp->d_name); - token = strtok(NULL, " "); - free(keystr); - keystr = NULL; - } - } - string = strstr(pbuf, "PKG_FLAVOURS_"); - if (string != NULL) { - check = strstr(pbuf, ":="); - if (check != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, ":="); - realpkgname = strdup(key+13); - value = strtok(NULL, "=\t"); - token = strtok(value, " "); - while (token != NULL) { - keystr = malloc(256); - memset(keystr, 0, 256); - strncat(keystr, "ADK_PACKAGE_", 12); - strncat(keystr, realpkgname, strlen(realpkgname)); - strncat(keystr, "_", 1); - strncat(keystr, token, strlen(token)); - strmap_put(pkgmap, keystr, pkgdirp->d_name); - token = strtok(NULL, " "); - free(keystr); - keystr = NULL; - } - } else { - string[strlen(string)-1] = '\0'; - key = strtok(string, "+="); - realpkgname = strdup(key+13); - value = strtok(NULL, "=\t"); - token = strtok(value, " "); - while (token != NULL) { - keystr = malloc(256); - memset(keystr, 0, 256); - strncat(keystr, "ADK_PACKAGE_", 12); - strncat(keystr, realpkgname, strlen(realpkgname)); - strncat(keystr, "_", 1); - strncat(keystr, token, strlen(token)); - strmap_put(pkgmap, keystr, pkgdirp->d_name); - token = strtok(NULL, " "); - free(keystr); - keystr = NULL; - } - } - } - string = strstr(pbuf, "PKG_CHOICES_"); - if (string != NULL) { - string[strlen(string)-1] = '\0'; - key = strtok(string, ":="); - value = strtok(NULL, "=\t"); - token = strtok(value, " "); - while (token != NULL) { - keystr = malloc(256); - memset(keystr, 0, 256); - strncat(keystr, "ADK_PACKAGE_", 12); - strncat(keystr, toupperstr(pkg_name), strlen(pkg_name)); - strncat(keystr, "_", 1); - strncat(keystr, token, strlen(token)); - strmap_put(pkgmap, keystr, pkgdirp->d_name); - token = strtok(NULL, " "); - free(keystr); - keystr = NULL; - } - } - } - } - fclose(pkg); - } - } - closedir(pkgdir); - - config = fopen(".config", "r"); - if (config == NULL) - perror(".config is missing."); - - configmap = strmap_new(1024); - while (fgets(buf, 128, config) != NULL) { - if (strncmp(buf, "ADK_PACKAGE", 11) == 0) { - key = strtok(buf, "="); - value = strtok(NULL, "="); - strmap_put(configmap, key, value); - } - } - fclose(config); - - configold = fopen(".config.old", "r"); - if (configold == NULL) - perror(".config.old is missing."); - - configoldmap = strmap_new(1024); - while (fgets(buf, 128, configold) != NULL) { - if (strncmp(buf, "ADK_PACKAGE", 11) == 0) { - key = strtok(buf, "="); - value = strtok(NULL, "="); - strmap_put(configoldmap, key, value); - } - } - fclose(configold); - - //fprintf(stdout, "Config Count: %d\n", strmap_get_count(configmap)); - //fprintf(stdout, "Config Old Count: %d\n", strmap_get_count(configoldmap)); - - strmap_enum(configoldmap, iter_disabled, NULL); - strmap_enum(configmap, iter_enabled, NULL); - //strmap_enum(pkgmap, iter, NULL); - - strmap_delete(pkgmap); - strmap_delete(configmap); - strmap_delete(configoldmap); - - return(0); -} diff --git a/tools/adk/sortfile.c b/tools/adk/sortfile.c deleted file mode 100644 index 1e9fc9623..000000000 --- a/tools/adk/sortfile.c +++ /dev/null @@ -1,153 +0,0 @@ -/*- - * Copyright (c) 2010 - * Thorsten Glaser - * - * Provided that these terms and disclaimer and all copyright notices - * are retained or reproduced in an accompanying document, permission - * is granted to deal in this work without restriction, including un- - * limited rights to use, publicly perform, distribute, sell, modify, - * merge, give away, or sublicence. - * - * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to - * the utmost extent permitted by applicable law, neither express nor - * implied; without malicious intent or gross negligence. In no event - * may a licensor, author or contributor be held liable for indirect, - * direct, other damage, loss, or other issues arising in any way out - * of dealing in the work, even if advised of the possibility of such - * damage or existence of a defect, except proven that it results out - * of said person's immediate fault when using the work as intended. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct ptrsize { - const char *ptr; - size_t size; -}; - -static void *xrecalloc(void *, size_t, size_t); -static int cmpfn(const void *, const void *); - -#define MUL_NO_OVERFLOW (1UL << (sizeof (size_t) * 8 / 2)) - -#ifndef SIZE_MAX -#ifdef SIZE_T_MAX -#define SIZE_MAX SIZE_T_MAX -#else -#define SIZE_MAX ((size_t)-1) -#endif -#endif - -#if !defined(MAP_FAILED) -/* XXX imake style */ -# if defined(__linux) -#define MAP_FAILED ((void *)-1) -# elif defined(__bsdi__) || defined(__osf__) || defined(__ultrix) -#define MAP_FAILED ((caddr_t)-1) -# endif -#endif - -static void * -xrecalloc(void *ptr, size_t nmemb, size_t size) -{ - void *rv; - - if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - nmemb > 0 && SIZE_MAX / nmemb < size) - errx(1, "attempted integer overflow: %zu * %zu", nmemb, size); - size *= nmemb; - if ((rv = realloc(ptr, size)) == NULL) - err(1, "cannot allocate %zu bytes", size); - return (rv); -} - -int -sortfile(char *infile, char *outfile) -{ - int fd, fdout; - size_t fsz, asz, anents; - char *cp, *thefile, *endfile; - struct ptrsize *thearray; - - if ((fd = open(infile, O_RDONLY)) < 0) - err(1, "open: %s", infile); - else { - struct stat sb; - - /* reasonable maximum size: 3/4 of SIZE_MAX */ - fsz = (SIZE_MAX / 2) + (SIZE_MAX / 4); - - if (fstat(fd, &sb)) - err(1, "stat: %s", infile); - if (sb.st_size > fsz) - errx(1, "file %s too big, %llu > %zu", infile, - (unsigned long long)sb.st_size, fsz); - fsz = (size_t)sb.st_size; - } - - if ((thefile = mmap(NULL, fsz, PROT_READ, MAP_FILE | MAP_PRIVATE, - fd, (off_t)0)) == MAP_FAILED) - err(1, "mmap %zu bytes from %s", fsz, infile); - /* last valid byte in the file, must be newline anyway */ - endfile = thefile + fsz - 1; - - thearray = xrecalloc(NULL, (asz = 8), sizeof(thearray[0])); - thearray[(anents = 0)].ptr = cp = thefile; - - while ((cp = memchr(cp, '\n', endfile - cp)) != NULL) { - /* byte after the \n */ - if (++cp > endfile) - /* end of file */ - break; - thearray[anents].size = cp - thearray[anents].ptr; - if (++anents == asz) - /* resize array */ - thearray = xrecalloc(thearray, (asz <<= 1), - sizeof(thearray[0])); - thearray[anents].ptr = cp; - } - thearray[anents].size = endfile - thearray[anents].ptr + 1; - - qsort(thearray, ++anents, sizeof(thearray[0]), cmpfn); - - if ((fdout = open(outfile, O_WRONLY | O_CREAT, S_IRWXU)) < 0) - err(1, "open: %s", outfile); - else { - for (asz = 0; asz < anents; ++asz) - if ((size_t)write(fdout, thearray[asz].ptr, - thearray[asz].size) != thearray[asz].size) - err(1, "write %zu bytes", thearray[asz].size); - } - - if (munmap(thefile, fsz)) - warn("munmap"); - - free(thearray); - close(fd); - - return (0); -} - -static int -cmpfn(const void *p1, const void *p2) -{ - int rv; - const struct ptrsize *a1 = (const struct ptrsize *)p1; - const struct ptrsize *a2 = (const struct ptrsize *)p2; - - if ((rv = memcmp(a1->ptr, a2->ptr, (a1->size > a2->size ? - a2->size : a1->size) - /* '\n' */ 1)) != 0) - /* unequal in the common part */ - return (rv); - - /* shorter string is smaller */ - return (a1->size > a2->size ? 1 : a1->size == a2->size ? 0 : -1); -} diff --git a/tools/adk/sortfile.h b/tools/adk/sortfile.h deleted file mode 100644 index c54294e69..000000000 --- a/tools/adk/sortfile.h +++ /dev/null @@ -1 +0,0 @@ -int sortfile(char *infile, char *outfile); diff --git a/tools/adk/strmap.c b/tools/adk/strmap.c deleted file mode 100644 index f2c660e1f..000000000 --- a/tools/adk/strmap.c +++ /dev/null @@ -1,510 +0,0 @@ -/* - * strmap version 1.0.0 - * - * ANSI C hash table for strings. - * - * strmap.c - * - * Copyright (c) 2009 Per Ola Kristensson. - * - * Per Ola Kristensson - * Inference Group, Department of Physics - * University of Cambridge - * Cavendish Laboratory - * JJ Thomson Avenue - * CB3 0HE Cambridge - * United Kingdom - * - * strmap is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * strmap is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with strmap. If not, see . - */ -#include "strmap.h" - -typedef struct Pair Pair; - -typedef struct Bucket Bucket; - -struct Pair { - char *key; - char *value; -}; - -struct Bucket { - unsigned int count; - Pair *pairs; -}; - -struct StrMap { - unsigned int count; - Bucket *buckets; -}; - -static Pair * get_pair(Bucket *bucket, const char *key); -static unsigned long hash(const char *str); - -StrMap * strmap_new(unsigned int capacity) -{ - StrMap *map; - - map = malloc(sizeof(StrMap)); - if (map == NULL) { - return NULL; - } - map->count = capacity; - map->buckets = malloc(map->count * sizeof(Bucket)); - if (map->buckets == NULL) { - free(map); - return NULL; - } - memset(map->buckets, 0, map->count * sizeof(Bucket)); - return map; -} - -void strmap_delete(StrMap *map) -{ - unsigned int i, j, n, m; - Bucket *bucket; - Pair *pair; - - if (map == NULL) { - return; - } - n = map->count; - bucket = map->buckets; - i = 0; - while (i < n) { - m = bucket->count; - pair = bucket->pairs; - j = 0; - while(j < m) { - free(pair->key); - free(pair->value); - pair++; - j++; - } - free(bucket->pairs); - bucket++; - i++; - } - free(map->buckets); - free(map); -} - -int strmap_get(const StrMap *map, const char *key, char *out_buf, unsigned int n_out_buf) -{ - unsigned int index; - Bucket *bucket; - Pair *pair; - - if (map == NULL) { - return 0; - } - if (key == NULL) { - return 0; - } - index = hash(key) % map->count; - bucket = &(map->buckets[index]); - pair = get_pair(bucket, key); - if (pair == NULL) { - return 0; - } - if (out_buf == NULL && n_out_buf == 0) { - return strlen(pair->value) + 1; - } - if (out_buf == NULL) { - return 0; - } - if (strlen(pair->value) >= n_out_buf) { - return 0; - } - strcpy(out_buf, pair->value); - return 1; -} - -int strmap_exists(const StrMap *map, const char *key) -{ - unsigned int index; - Bucket *bucket; - Pair *pair; - - if (map == NULL) { - return 0; - } - if (key == NULL) { - return 0; - } - index = hash(key) % map->count; - bucket = &(map->buckets[index]); - pair = get_pair(bucket, key); - if (pair == NULL) { - return 0; - } - return 1; -} - -int strmap_put(StrMap *map, const char *key, const char *value) -{ - unsigned int key_len, value_len, index; - Bucket *bucket; - Pair *tmp_pairs, *pair; - char *tmp_value; - char *new_key, *new_value; - - if (map == NULL) { - return 0; - } - if (key == NULL || value == NULL) { - return 0; - } - key_len = strlen(key); - value_len = strlen(value); - /* Get a pointer to the bucket the key string hashes to */ - index = hash(key) % map->count; - bucket = &(map->buckets[index]); - /* Check if we can handle insertion by simply replacing - * an existing value in a key-value pair in the bucket. - */ - if ((pair = get_pair(bucket, key)) != NULL) { - /* The bucket contains a pair that matches the provided key, - * change the value for that pair to the new value. - */ - if (strlen(pair->value) < value_len) { - /* If the new value is larger than the old value, re-allocate - * space for the new larger value. - */ - tmp_value = realloc(pair->value, (value_len + 1) * sizeof(char)); - if (tmp_value == NULL) { - return 0; - } - pair->value = tmp_value; - } - /* Copy the new value into the pair that matches the key */ - strcpy(pair->value, value); - return 1; - } - /* Allocate space for a new key and value */ - new_key = malloc((key_len + 1) * sizeof(char)); - if (new_key == NULL) { - return 0; - } - new_value = malloc((value_len + 1) * sizeof(char)); - if (new_value == NULL) { - free(new_key); - return 0; - } - /* Create a key-value pair */ - if (bucket->count == 0) { - /* The bucket is empty, lazily allocate space for a single - * key-value pair. - */ - bucket->pairs = malloc(sizeof(Pair)); - if (bucket->pairs == NULL) { - free(new_key); - free(new_value); - return 0; - } - bucket->count = 1; - } - else { - /* The bucket wasn't empty but no pair existed that matches the provided - * key, so create a new key-value pair. - */ - tmp_pairs = realloc(bucket->pairs, (bucket->count + 1) * sizeof(Pair)); - if (tmp_pairs == NULL) { - free(new_key); - free(new_value); - return 0; - } - bucket->pairs = tmp_pairs; - bucket->count++; - } - /* Get the last pair in the chain for the bucket */ - pair = &(bucket->pairs[bucket->count - 1]); - pair->key = new_key; - pair->value = new_value; - /* Copy the key and its value into the key-value pair */ - strcpy(pair->key, key); - strcpy(pair->value, value); - return 1; -} - -int strmap_get_count(const StrMap *map) -{ - unsigned int i, j, n, m; - unsigned int count; - Bucket *bucket; - Pair *pair; - - if (map == NULL) { - return 0; - } - bucket = map->buckets; - n = map->count; - i = 0; - count = 0; - while (i < n) { - pair = bucket->pairs; - m = bucket->count; - j = 0; - while (j < m) { - count++; - pair++; - j++; - } - bucket++; - i++; - } - return count; -} - -int strmap_enum(const StrMap *map, strmap_enum_func enum_func, const void *obj) -{ - unsigned int i, j, n, m; - Bucket *bucket; - Pair *pair; - - if (map == NULL) { - return 0; - } - if (enum_func == NULL) { - return 0; - } - bucket = map->buckets; - n = map->count; - i = 0; - while (i < n) { - pair = bucket->pairs; - m = bucket->count; - j = 0; - while (j < m) { - enum_func(pair->key, pair->value, obj); - pair++; - j++; - } - bucket++; - i++; - } - return 1; -} - -/* - * Returns a pair from the bucket that matches the provided key, - * or null if no such pair exist. - */ -static Pair * get_pair(Bucket *bucket, const char *key) -{ - unsigned int i, n; - Pair *pair; - - n = bucket->count; - if (n == 0) { - return NULL; - } - pair = bucket->pairs; - i = 0; - while (i < n) { - if (pair->key != NULL && pair->value != NULL) { - if (strcmp(pair->key, key) == 0) { - return pair; - } - } - pair++; - i++; - } - return NULL; -} - -/* - * Returns a hash code for the provided string. - */ -static unsigned long hash(const char *str) -{ - unsigned long hash = 5381; - int c; - c = 0; - - while (c == *str++) { - hash = ((hash << 5) + hash) + c; - } - return hash; -} - -/* - - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. - -*/ diff --git a/tools/adk/strmap.h b/tools/adk/strmap.h deleted file mode 100644 index 99687b236..000000000 --- a/tools/adk/strmap.h +++ /dev/null @@ -1,350 +0,0 @@ -/* - * strmap version 1.0.0 - * - * ANSI C hash table for strings. - * - * strmap.h - * - * Copyright (c) 2009 Per Ola Kristensson. - * - * Per Ola Kristensson - * Inference Group, Department of Physics - * University of Cambridge - * Cavendish Laboratory - * JJ Thomson Avenue - * CB3 0HE Cambridge - * United Kingdom - * - * strmap is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * strmap is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with strmap. If not, see . - */ -#ifndef _STRMAP_H_ -#define _STRMAP_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include - -typedef struct StrMap StrMap; - -/* - * This callback function is called once per key-value when enumerating - * all keys associated to values. - * - * Parameters: - * - * key: A pointer to a null-terminated C string. The string must not - * be modified by the client. - * - * value: A pointer to a null-terminated C string. The string must - * not be modified by the client. - * - * obj: A pointer to a client-specific object. This parameter may be - * null. - * - * Return value: None. - */ -typedef void(*strmap_enum_func)(const char *key, const char *value, const void *obj); - -/* - * Creates a string map. - * - * Parameters: - * - * capacity: The number of top-level slots this string map - * should allocate. This parameter must be > 0. - * - * Return value: A pointer to a string map object, - * or null if a new string map could not be allocated. - */ -StrMap * strmap_new(unsigned int capacity); - -/* - * Releases all memory held by a string map object. - * - * Parameters: - * - * map: A pointer to a string map. This parameter cannot be null. - * If the supplied string map has been previously released, the - * behaviour of this function is undefined. - * - * Return value: None. - */ -void strmap_delete(StrMap *map); - -/* - * Returns the value associated with the supplied key. - * - * Parameters: - * - * map: A pointer to a string map. This parameter cannot be null. - * - * key: A pointer to a null-terminated C string. This parameter cannot - * be null. - * - * out_buf: A pointer to an output buffer which will contain the value, - * if it exists and fits into the buffer. - * - * n_out_buf: The size of the output buffer in bytes. - * - * Return value: If out_buf is set to null and n_out_buf is set to 0 the return - * value will be the number of bytes required to store the value (if it exists) - * and its null-terminator. For all other parameter configurations the return value - * is 1 if an associated value was found and completely copied into the output buffer, - * 0 otherwise. - */ -int strmap_get(const StrMap *map, const char *key, char *out_buf, unsigned int n_out_buf); - -/* - * Queries the existence of a key. - * - * Parameters: - * - * map: A pointer to a string map. This parameter cannot be null. - * - * key: A pointer to a null-terminated C string. This parameter cannot - * be null. - * - * Return value: 1 if the key exists, 0 otherwise. - */ -int strmap_exists(const StrMap *map, const char *key); - -/* - * Associates a value with the supplied key. If the key is already - * associated with a value, the previous value is replaced. - * - * Parameters: - * - * map: A pointer to a string map. This parameter cannot be null. - * - * key: A pointer to a null-terminated C string. This parameter - * cannot be null. The string must have a string length > 0. The - * string will be copied. - * - * value: A pointer to a null-terminated C string. This parameter - * cannot be null. The string must have a string length > 0. The - * string will be copied. - * - * Return value: 1 if the association succeeded, 0 otherwise. - */ -int strmap_put(StrMap *map, const char *key, const char *value); - -/* - * Returns the number of associations between keys and values. - * - * Parameters: - * - * map: A pointer to a string map. This parameter cannot be null. - * - * Return value: The number of associations between keys and values. - */ -int strmap_get_count(const StrMap *map); - -/* - * Enumerates all associations between keys and values. - * - * Parameters: - * - * map: A pointer to a string map. This parameter cannot be null. - * - * enum_func: A pointer to a callback function that will be - * called by this procedure once for every key associated - * with a value. This parameter cannot be null. - * - * obj: A pointer to a client-specific object. This parameter will be - * passed back to the client's callback function. This parameter can - * be null. - * - * Return value: 1 if enumeration completed, 0 otherwise. - */ -int strmap_enum(const StrMap *map, strmap_enum_func enum_func, const void *obj); - -#ifdef __cplusplus -} -#endif - -#endif - -/* - - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. - -*/ diff --git a/tools/bc/Makefile b/tools/bc/Makefile deleted file mode 100644 index 8b984e734..000000000 --- a/tools/bc/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= bc -PKG_VERSION:= 1.06 -PKG_RELEASE:= 1 -PKG_MD5SUM:= d44b5dddebd8a7a7309aea6c36fda117 -PKG_SITES:= http://ftp.gnu.org/pub/gnu/bc/ - -include ../rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/bc - -$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared - (cd ${WRKBUILD}; PATH="$(STAGING_HOST_DIR)/usr/bin:$$PATH" ./configure) - ${MAKE} -C ${WRKBUILD} CC='${CC_FOR_BUILD}' - touch $@ - -${STAGING_HOST_DIR}/usr/bin/bc: $(WRKBUILD)/.compiled - $(INSTALL_BIN) $(WRKBUILD)/bc/bc \ - ${STAGING_HOST_DIR}/usr/bin - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/bzip2/Makefile b/tools/bzip2/Makefile deleted file mode 100644 index a739f8d5f..000000000 --- a/tools/bzip2/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= bzip2 -PKG_VERSION:= 1.0.6 -PKG_RELEASE:= 1 -PKG_MD5SUM:= 00b516f4704d4a7cb50a1d97e6e8e15b -PKG_SITES:= http://www.bzip.org/${PKG_VERSION}/ - -include ../rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/bzip2 - -$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared - ${MAKE} -C ${WRKBUILD} CC='${CC_FOR_BUILD}' PREFIX=$(STAGING_HOST_DIR)/usr - touch $@ - -${STAGING_HOST_DIR}/usr/bin/bzip2: $(WRKBUILD)/.compiled - $(INSTALL_BIN) $(WRKBUILD)/bzip2 \ - ${STAGING_HOST_DIR}/usr/bin - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/ccache/Makefile b/tools/ccache/Makefile deleted file mode 100644 index fde838067..000000000 --- a/tools/ccache/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= ccache -PKG_VERSION:= 3.1.9 -PKG_RELEASE:= 1 -PKG_MD5SUM:= a5e9954b1dae036762f7b13673a2cf76 -PKG_SITES:= http://samba.org/ftp/ccache/ - -include ../rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/ccache - -$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared - (cd ${WRKBUILD}; ./configure --prefix=$(STAGING_HOST_DIR)/usr) - ${MAKE} -C ${WRKBUILD} CC='${CC_FOR_BUILD}' - touch $@ - -${STAGING_HOST_DIR}/usr/bin/ccache: $(WRKBUILD)/.compiled - $(INSTALL_BIN) $(WRKBUILD)/ccache \ - ${STAGING_HOST_DIR}/usr/bin - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/cdrtools/Makefile b/tools/cdrtools/Makefile deleted file mode 100644 index 6522b5760..000000000 --- a/tools/cdrtools/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= cdrtools -PKG_VERSION:= 3.00 -PKG_RELEASE:= 1 -PKG_MD5SUM:= bb21cefefcfbb76cf249120e8978ffdd -PKG_SITES:= ftp://ftp.berlios.de/pub/cdrecord/ - -include ../rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/mkisofs - -$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared - #(cd ${WRKBUILD}; ./configure) - ${MAKE} -C ${WRKBUILD} CC='${CC_FOR_BUILD}' - touch $@ - -${STAGING_HOST_DIR}/usr/bin/mkisofs: $(WRKBUILD)/.compiled - $(INSTALL_BIN) $(WRKBUILD)/mkisofs/OBJ/*/mkisofs \ - ${STAGING_HOST_DIR}/usr/bin - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/cpio/Makefile b/tools/cpio/Makefile deleted file mode 100644 index ffccd1480..000000000 --- a/tools/cpio/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/cpio - -SRCS:= src/ib_open.c \ - src/ib_close.c \ - src/ib_read.c \ - src/ib_alloc.c \ - src/ib_free.c \ - src/ib_getlin.c \ - src/sfile.c \ - src/gmatch.c \ - src/sigset.c \ - src/memalign.c \ - src/version.c \ - src/blast.c \ - src/crc32.c \ - src/expand.c \ - src/explode.c \ - src/flags.c \ - src/inflate.c \ - src/unshrink.c \ - src/nonpax.c \ - src/cpio.c - -${STAGING_HOST_DIR}/usr/bin/cpio: ${SRCS} - ${CC_FOR_BUILD} ${FLAGS_FOR_BUILD} -D_GNU_SOURCE -Isrc -o $@ $^ - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/cpio/src/_alloca.h b/tools/cpio/src/_alloca.h deleted file mode 100644 index dc2afe5b4..000000000 --- a/tools/cpio/src/_alloca.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)_alloca.h 1.5 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -#include -#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ diff --git a/tools/cpio/src/_malloc.h b/tools/cpio/src/_malloc.h deleted file mode 100644 index 1693e3673..000000000 --- a/tools/cpio/src/_malloc.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)_malloc.h 1.2 (gritter) 5/1/04 */ - -#include - -extern void *memalign(size_t, size_t); diff --git a/tools/cpio/src/_utmpx.h b/tools/cpio/src/_utmpx.h deleted file mode 100644 index c32bd9527..000000000 --- a/tools/cpio/src/_utmpx.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)_utmpx.h 1.9 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__UCLIBC__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -#include -#include -#include - -#ifndef __dietlibc__ -struct utmpx { - char ut_user[UT_NAMESIZE]; - char ut_id[UT_LINESIZE]; - char ut_line[UT_LINESIZE]; - char ut_host[UT_HOSTSIZE]; - pid_t ut_pid; - short ut_type; - struct timeval ut_tv; - struct { - int e_termination; - int e_exit; - } ut_exit; -}; - -#ifndef EMPTY -#define EMPTY 0 -#endif -#ifndef BOOT_TIME -#define BOOT_TIME 1 -#endif -#ifndef OLD_TIME -#define OLD_TIME 2 -#endif -#ifndef NEW_TIME -#define NEW_TIME 3 -#endif -#ifndef USER_PROCESS -#define USER_PROCESS 4 -#endif -#ifndef INIT_PROCESS -#define INIT_PROCESS 5 -#endif -#ifndef LOGIN_PROCESS -#define LOGIN_PROCESS 6 -#endif -#ifndef DEAD_PROCESS -#define DEAD_PROCESS 7 -#endif -#ifndef RUN_LVL -#define RUN_LVL 8 -#endif -#ifndef ACCOUNTING -#define ACCOUNTING 9 -#endif -#else /* __dietlibc__ */ -#define utmpx utmp -#endif /* __dietlibc__ */ - -extern void endutxent(void); -extern struct utmpx *getutxent(void); -extern struct utmpx *getutxid(const struct utmpx *); -extern struct utmpx *getutxline(const struct utmpx *); -extern struct utmpx *pututxline(const struct utmpx *); -extern void setutxent(void); -extern int utmpxname(const char *); -extern void updwtmpx(const char *, const struct utmpx *); -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __UCLIBC__ || - __OpenBSD__ || __DragonFly__ || __APPLE__ */ diff --git a/tools/cpio/src/asciitype.c b/tools/cpio/src/asciitype.c deleted file mode 100644 index f7f322173..000000000 --- a/tools/cpio/src/asciitype.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)asciitype.c 1.4 (gritter) 4/17/03 */ - -#include "asciitype.h" - -const unsigned char class_char[] = { -/* 000 nul 001 soh 002 stx 003 etx 004 eot 005 enq 006 ack 007 bel */ - C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL, -/* 010 bs 011 ht 012 nl 013 vt 014 np 015 cr 016 so 017 si */ - C_CNTRL,C_BLANK,C_WHITE,C_SPACE,C_SPACE,C_SPACE,C_CNTRL,C_CNTRL, -/* 020 dle 021 dc1 022 dc2 023 dc3 024 dc4 025 nak 026 syn 027 etb */ - C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL, -/* 030 can 031 em 032 sub 033 esc 034 fs 035 gs 036 rs 037 us */ - C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL, -/* 040 sp 041 ! 042 " 043 # 044 $ 045 % 046 & 047 ' */ - C_BLANK,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT, -/* 050 ( 051 ) 052 * 053 + 054 , 055 - 056 . 057 / */ - C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT, -/* 060 0 061 1 062 2 063 3 064 4 065 5 066 6 067 7 */ - C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL, -/* 070 8 071 9 072 : 073 ; 074 < 075 = 076 > 077 ? */ - C_DIGIT,C_DIGIT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT, -/* 100 @ 101 A 102 B 103 C 104 D 105 E 106 F 107 G */ - C_PUNCT,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER, -/* 110 H 111 I 112 J 113 K 114 L 115 M 116 N 117 O */ - C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER, -/* 120 P 121 Q 122 R 123 S 124 T 125 U 126 V 127 W */ - C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER, -/* 130 X 131 Y 132 Z 133 [ 134 \ 135 ] 136 ^ 137 _ */ - C_UPPER,C_UPPER,C_UPPER,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT, -/* 140 ` 141 a 142 b 143 c 144 d 145 e 146 f 147 g */ - C_PUNCT,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER, -/* 150 h 151 i 152 j 153 k 154 l 155 m 156 n 157 o */ - C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER, -/* 160 p 161 q 162 r 163 s 164 t 165 u 166 v 167 w */ - C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER, -/* 170 x 171 y 172 z 173 { 174 | 175 } 176 ~ 177 del */ - C_LOWER,C_LOWER,C_LOWER,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_CNTRL -}; diff --git a/tools/cpio/src/asciitype.h b/tools/cpio/src/asciitype.h deleted file mode 100644 index 6ac1961a1..000000000 --- a/tools/cpio/src/asciitype.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)asciitype.h 1.6 (gritter) 9/9/05 */ - -/* - * Locale-independent character classes. - */ -enum { - C_CNTRL = 0000, - C_BLANK = 0001, - C_WHITE = 0002, - C_SPACE = 0004, - C_PUNCT = 0010, - C_OCTAL = 0020, - C_DIGIT = 0040, - C_UPPER = 0100, - C_LOWER = 0200 -}; - -extern const unsigned char class_char[]; - -#define asciichar(c) ((unsigned)(c) <= 0177) -#define alnumchar(c) (asciichar(c)&&(class_char[c]&\ - (C_DIGIT|C_OCTAL|C_UPPER|C_LOWER))) -#define alphachar(c) (asciichar(c)&&(class_char[c]&(C_UPPER|C_LOWER))) -#define blankchar(c) (asciichar(c)&&(class_char[c]&(C_BLANK))) -#define cntrlchar(c) (asciichar(c)&&(class_char[c]==C_CNTRL) -#define digitchar(c) (asciichar(c)&&(class_char[c]&(C_DIGIT|C_OCTAL))) -#define lowerchar(c) (asciichar(c)&&(class_char[c]&(C_LOWER))) -#define punctchar(c) (asciichar(c)&&(class_char[c]&(C_PUNCT))) -#define spacechar(c) (asciichar(c)&&(class_char[c]&(C_BLANK|C_SPACE|C_WHITE))) -#define upperchar(c) (asciichar(c)&&(class_char[c]&(C_UPPER))) -#define whitechar(c) (asciichar(c)&&(class_char[c]&(C_BLANK|C_WHITE))) -#define octalchar(c) (asciichar(c)&&(class_char[c]&(C_OCTAL))) -#define graphchar(c) (asciichar(c)&&(class_char[c]&\ - (C_UPPER|C_LOWER|C_DIGIT|C_OCTAL|C_PUNCT))) -#define printchar(c) ((c)==' ' || asciichar(c)&&(class_char[c]&\ - (C_UPPER|C_LOWER|C_DIGIT|C_OCTAL|C_PUNCT))) - -#define upperconv(c) (lowerchar(c) ? (c)-'a'+'A' : (c)) -#define lowerconv(c) (upperchar(c) ? (c)-'A'+'a' : (c)) diff --git a/tools/cpio/src/atoll.h b/tools/cpio/src/atoll.h deleted file mode 100644 index 8283aff64..000000000 --- a/tools/cpio/src/atoll.h +++ /dev/null @@ -1,8 +0,0 @@ -/* Sccsid @(#)atoll.h 1.4 (gritter) 7/18/04 */ - -#if defined (__hpux) || defined (_AIX) || \ - defined (__FreeBSD__) && (__FreeBSD__) < 5 -extern long long strtoll(const char *nptr, char **endptr, int base); -extern unsigned long long strtoull(const char *nptr, char **endptr, int base); -extern long long atoll(const char *nptr); -#endif /* __hpux || _AIX || __FreeBSD__ < 5 */ diff --git a/tools/cpio/src/blank.h b/tools/cpio/src/blank.h deleted file mode 100644 index 1ab3d57b8..000000000 --- a/tools/cpio/src/blank.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * isblank() and iswblank() are not available with many pre-XSH6 - * systems. Check whether isblank was defined, and assume it is - * not available if not. - */ -/* Sccsid @(#)blank.h 1.3 (gritter) 5/1/04 */ - -#ifndef __dietlibc__ -#ifndef LIBCOMMON_BLANK_H -#define LIBCOMMON_BLANK_H 1 - -#include -#include - -#ifndef isblank - -static -#ifdef __GNUC__ -__inline__ -#endif /* __GNUC__ */ -int -my_isblank(int c) -{ - return c == ' ' || c == '\t'; -} -#define isblank(c) my_isblank(c) - -static int -my_iswblank(wint_t c) -{ - return c == L' ' || c == L'\t'; -} -#undef iswblank -#define iswblank(c) my_iswblank(c) - -#endif /* !isblank */ -#endif /* !LIBCOMMON_BLANK_H */ -#endif /* !__dietlibc__ */ diff --git a/tools/cpio/src/blast.c b/tools/cpio/src/blast.c deleted file mode 100644 index b62efd585..000000000 --- a/tools/cpio/src/blast.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, February 2004. - * - * Sccsid @(#)blast.c 1.2 (gritter) 2/17/04 - */ -/* blast.c - * Copyright (C) 2003 Mark Adler - * For conditions of distribution and use, see copyright notice in blast.h - * version 1.1, 16 Feb 2003 - * - * blast.c decompresses data compressed by the PKWare Compression Library. - * This function provides functionality similar to the explode() function of - * the PKWare library, hence the name "blast". - * - * This decompressor is based on the excellent format description provided by - * Ben Rudiak-Gould in comp.compression on August 13, 2001. Interestingly, the - * example Ben provided in the post is incorrect. The distance 110001 should - * instead be 111000. When corrected, the example byte stream becomes: - * - * 00 04 82 24 25 8f 80 7f - * - * which decompresses to "AIAIAIAIAIAIA" (without the quotes). - */ - -/* - * Change history: - * - * 1.0 12 Feb 2003 - First version - * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data - */ - -#include /* for setjmp(), longjmp(), and jmp_buf */ -#include "blast.h" /* prototype for blast() */ - -#define local static /* for local function definitions */ -#define MAXBITS 13 /* maximum code length */ -#define MAXWIN 4096 /* maximum window size */ - -/* input and output state */ -struct state { - /* input state */ - blast_in infun; /* input function provided by user */ - void *inhow; /* opaque information passed to infun() */ - unsigned char *in; /* next input location */ - unsigned left; /* available input at in */ - int bitbuf; /* bit buffer */ - int bitcnt; /* number of bits in bit buffer */ - - /* input limit error return state for bits() and decode() */ - jmp_buf env; - - /* output state */ - blast_out outfun; /* output function provided by user */ - void *outhow; /* opaque information passed to outfun() */ - unsigned next; /* index of next write location in out[] */ - int first; /* true to check distances (for first 4K) */ - unsigned char out[MAXWIN]; /* output buffer and sliding window */ -}; - -/* - * Return need bits from the input stream. This always leaves less than - * eight bits in the buffer. bits() works properly for need == 0. - * - * Format notes: - * - * - Bits are stored in bytes from the least significant bit to the most - * significant bit. Therefore bits are dropped from the bottom of the bit - * buffer, using shift right, and new bytes are appended to the top of the - * bit buffer, using shift left. - */ -local int bits(struct state *s, int need) -{ - int val; /* bit accumulator */ - - /* load at least need bits into val */ - val = s->bitbuf; - while (s->bitcnt < need) { - if (s->left == 0) { - s->left = s->infun(s->inhow, &(s->in)); - if (s->left == 0) longjmp(s->env, 1); /* out of input */ - } - val |= (int)(*(s->in)++) << s->bitcnt; /* load eight bits */ - s->left--; - s->bitcnt += 8; - } - - /* drop need bits and update buffer, always zero to seven bits left */ - s->bitbuf = val >> need; - s->bitcnt -= need; - - /* return need bits, zeroing the bits above that */ - return val & ((1 << need) - 1); -} - -/* - * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of - * each length, which for a canonical code are stepped through in order. - * symbol[] are the symbol values in canonical order, where the number of - * entries is the sum of the counts in count[]. The decoding process can be - * seen in the function decode() below. - */ -struct huffman { - short *count; /* number of symbols of each length */ - short *symbol; /* canonically ordered symbols */ -}; - -/* - * Decode a code from the stream s using huffman table h. Return the symbol or - * a negative value if there is an error. If all of the lengths are zero, i.e. - * an empty code, or if the code is incomplete and an invalid code is received, - * then -9 is returned after reading MAXBITS bits. - * - * Format notes: - * - * - The codes as stored in the compressed data are bit-reversed relative to - * a simple integer ordering of codes of the same lengths. Hence below the - * bits are pulled from the compressed data one at a time and used to - * build the code value reversed from what is in the stream in order to - * permit simple integer comparisons for decoding. - * - * - The first code for the shortest length is all ones. Subsequent codes of - * the same length are simply integer decrements of the previous code. When - * moving up a length, a one bit is appended to the code. For a complete - * code, the last code of the longest length will be all zeros. To support - * this ordering, the bits pulled during decoding are inverted to apply the - * more "natural" ordering starting with all zeros and incrementing. - */ -local int decode(struct state *s, struct huffman *h) -{ - int len; /* current number of bits in code */ - int code; /* len bits being decoded */ - int first; /* first code of length len */ - int count; /* number of codes of length len */ - int index; /* index of first code of length len in symbol table */ - int bitbuf; /* bits from stream */ - int left; /* bits left in next or left to process */ - short *next; /* next number of codes */ - - bitbuf = s->bitbuf; - left = s->bitcnt; - code = first = index = 0; - len = 1; - next = h->count + 1; - while (1) { - while (left--) { - code |= (bitbuf & 1) ^ 1; /* invert code */ - bitbuf >>= 1; - count = *next++; - if (code < first + count) { /* if length len, return symbol */ - s->bitbuf = bitbuf; - s->bitcnt = (s->bitcnt - len) & 7; - return h->symbol[index + (code - first)]; - } - index += count; /* else update for next length */ - first += count; - first <<= 1; - code <<= 1; - len++; - } - left = (MAXBITS+1) - len; - if (left == 0) break; - if (s->left == 0) { - s->left = s->infun(s->inhow, &(s->in)); - if (s->left == 0) longjmp(s->env, 1); /* out of input */ - } - bitbuf = *(s->in)++; - s->left--; - if (left > 8) left = 8; - } - return -9; /* ran out of codes */ -} - -/* - * Given a list of repeated code lengths rep[0..n-1], where each byte is a - * count (high four bits + 1) and a code length (low four bits), generate the - * list of code lengths. This compaction reduces the size of the object code. - * Then given the list of code lengths length[0..n-1] representing a canonical - * Huffman code for n symbols, construct the tables required to decode those - * codes. Those tables are the number of codes of each length, and the symbols - * sorted by length, retaining their original order within each length. The - * return value is zero for a complete code set, negative for an over- - * subscribed code set, and positive for an incomplete code set. The tables - * can be used if the return value is zero or positive, but they cannot be used - * if the return value is negative. If the return value is zero, it is not - * possible for decode() using that table to return an error--any stream of - * enough bits will resolve to a symbol. If the return value is positive, then - * it is possible for decode() using that table to return an error for received - * codes past the end of the incomplete lengths. - */ -local int construct(struct huffman *h, const unsigned char *rep, int n) -{ - int symbol; /* current symbol when stepping through length[] */ - int len; /* current length when stepping through h->count[] */ - int left; /* number of possible codes left of current length */ - short offs[MAXBITS+1]; /* offsets in symbol table for each length */ - short length[256]; /* code lengths */ - - /* convert compact repeat counts into symbol bit length list */ - symbol = 0; - do { - len = *rep++; - left = (len >> 4) + 1; - len &= 15; - do { - length[symbol++] = len; - } while (--left); - } while (--n); - n = symbol; - - /* count number of codes of each length */ - for (len = 0; len <= MAXBITS; len++) - h->count[len] = 0; - for (symbol = 0; symbol < n; symbol++) - (h->count[length[symbol]])++; /* assumes lengths are within bounds */ - if (h->count[0] == n) /* no codes! */ - return 0; /* complete, but decode() will fail */ - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; /* one possible code of zero length */ - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; /* one more bit, double codes left */ - left -= h->count[len]; /* deduct count from possible codes */ - if (left < 0) return left; /* over-subscribed--return negative */ - } /* left > 0 means incomplete */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + h->count[len]; - - /* - * put symbols in table sorted by length, by symbol order within each - * length - */ - for (symbol = 0; symbol < n; symbol++) - if (length[symbol] != 0) - h->symbol[offs[length[symbol]]++] = symbol; - - /* return zero for complete set, positive for incomplete set */ - return left; -} - -/* - * Decode PKWare Compression Library stream. - * - * Format notes: - * - * - First byte is 0 if literals are uncoded or 1 if they are coded. Second - * byte is 4, 5, or 6 for the number of extra bits in the distance code. - * This is the base-2 logarithm of the dictionary size minus six. - * - * - Compressed data is a combination of literals and length/distance pairs - * terminated by an end code. Literals are either Huffman coded or - * uncoded bytes. A length/distance pair is a coded length followed by a - * coded distance to represent a string that occurs earlier in the - * uncompressed data that occurs again at the current location. - * - * - A bit preceding a literal or length/distance pair indicates which comes - * next, 0 for literals, 1 for length/distance. - * - * - If literals are uncoded, then the next eight bits are the literal, in the - * normal bit order in th stream, i.e. no bit-reversal is needed. Similarly, - * no bit reversal is needed for either the length extra bits or the distance - * extra bits. - * - * - Literal bytes are simply written to the output. A length/distance pair is - * an instruction to copy previously uncompressed bytes to the output. The - * copy is from distance bytes back in the output stream, copying for length - * bytes. - * - * - Distances pointing before the beginning of the output data are not - * permitted. - * - * - Overlapped copies, where the length is greater than the distance, are - * allowed and common. For example, a distance of one and a length of 518 - * simply copies the last byte 518 times. A distance of four and a length of - * twelve copies the last four bytes three times. A simple forward copy - * ignoring whether the length is greater than the distance or not implements - * this correctly. - */ -local int decomp(struct state *s) -{ - int lit; /* true if literals are coded */ - int dict; /* log2(dictionary size) - 6 */ - int symbol; /* decoded symbol, extra bits for distance */ - int len; /* length for copy */ - int dist; /* distance for copy */ - int copy; /* copy counter */ - unsigned char *from, *to; /* copy pointers */ - static int virgin = 1; /* build tables once */ - static short litcnt[MAXBITS+1], litsym[256]; /* litcode memory */ - static short lencnt[MAXBITS+1], lensym[16]; /* lencode memory */ - static short distcnt[MAXBITS+1], distsym[64]; /* distcode memory */ - static struct huffman litcode = {litcnt, litsym}; /* length code */ - static struct huffman lencode = {lencnt, lensym}; /* length code */ - static struct huffman distcode = {distcnt, distsym};/* distance code */ - /* bit lengths of literal codes */ - static const unsigned char litlen[] = { - 11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8, - 9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5, - 7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12, - 8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27, - 44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45, - 44, 173}; - /* bit lengths of length codes 0..15 */ - static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23}; - /* bit lengths of distance codes 0..63 */ - static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248}; - static const short base[16] = { /* base for length codes */ - 3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264}; - static const char extra[16] = { /* extra bits for length codes */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8}; - - /* set up decoding tables (once--might not be thread-safe) */ - if (virgin) { - construct(&litcode, litlen, sizeof(litlen)); - construct(&lencode, lenlen, sizeof(lenlen)); - construct(&distcode, distlen, sizeof(distlen)); - virgin = 0; - } - - /* read header */ - lit = bits(s, 8); - if (lit > 1) return -1; - dict = bits(s, 8); - if (dict < 4 || dict > 6) return -2; - - /* decode literals and length/distance pairs */ - do { - if (bits(s, 1)) { - /* get length */ - symbol = decode(s, &lencode); - len = base[symbol] + bits(s, extra[symbol]); - if (len == 519) break; /* end code */ - - /* get distance */ - symbol = len == 2 ? 2 : dict; - dist = decode(s, &distcode) << symbol; - dist += bits(s, symbol); - dist++; - if (s->first && dist > s->next) - return -3; /* distance too far back */ - - /* copy length bytes from distance bytes back */ - do { - to = s->out + s->next; - from = to - dist; - copy = MAXWIN; - if (s->next < dist) { - from += copy; - copy = dist; - } - copy -= s->next; - if (copy > len) copy = len; - len -= copy; - s->next += copy; - do { - *to++ = *from++; - } while (--copy); - if (s->next == MAXWIN) { - if (s->outfun(s->outhow, s->out, s->next)) return 1; - s->next = 0; - s->first = 0; - } - } while (len != 0); - } - else { - /* get literal and write it */ - symbol = lit ? decode(s, &litcode) : bits(s, 8); - s->out[s->next++] = symbol; - if (s->next == MAXWIN) { - if (s->outfun(s->outhow, s->out, s->next)) return 1; - s->next = 0; - s->first = 0; - } - } - } while (1); - return 0; -} - -/* See comments in blast.h */ -int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow) -{ - struct state s; /* input/output state */ - int err; /* return value */ - - /* initialize input state */ - s.infun = infun; - s.inhow = inhow; - s.left = 0; - s.bitbuf = 0; - s.bitcnt = 0; - - /* initialize output state */ - s.outfun = outfun; - s.outhow = outhow; - s.next = 0; - s.first = 1; - - /* return if bits() or decode() tries to read past available input */ - if (setjmp(s.env) != 0) /* if came back here via longjmp(), */ - err = 2; /* then skip decomp(), return error */ - else - err = decomp(&s); /* decompress */ - - /* write any leftover output and update the error code if needed */ - if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0) - err = 1; - return err; -} - -#ifdef TEST -/* Example of how to use blast() */ -#include -#include - -#define CHUNK 16384 - -local unsigned inf(void *how, unsigned char **buf) -{ - static unsigned char hold[CHUNK]; - - *buf = hold; - return fread(hold, 1, CHUNK, (FILE *)how); -} - -local int outf(void *how, unsigned char *buf, unsigned len) -{ - return fwrite(buf, 1, len, (FILE *)how) != len; -} - -/* Decompress a PKWare Compression Library stream from stdin to stdout */ -int main(void) -{ - int ret, n; - - /* decompress to stdout */ - ret = blast(inf, stdin, outf, stdout); - if (ret != 0) fprintf(stderr, "blast error: %d\n", ret); - - /* see if there are any leftover bytes */ - n = 0; - while (getchar() != EOF) n++; - if (n) fprintf(stderr, "blast warning: %d unused bytes of input\n", n); - - /* return blast() error code */ - return ret; -} -#endif diff --git a/tools/cpio/src/blast.h b/tools/cpio/src/blast.h deleted file mode 100644 index 0c16d1391..000000000 --- a/tools/cpio/src/blast.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, February 2004. - * - * Sccsid @(#)blast.h 1.2 (gritter) 2/17/04 - */ -/* blast.h -- interface for blast.c - Copyright (C) 2003 Mark Adler - version 1.1, 16 Feb 2003 - - This software is provided 'as-is', without any express or implied - warranty. In no event will the author be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. 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. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Mark Adler madler@alumni.caltech.edu - */ - - -/* - * blast() decompresses the PKWare Data Compression Library (DCL) compressed - * format. It provides the same functionality as the explode() function in - * that library. (Note: PKWare overused the "implode" verb, and the format - * used by their library implode() function is completely different and - * incompatible with the implode compression method supported by PKZIP.) - */ - - -typedef unsigned (*blast_in)(void *how, unsigned char **buf); -typedef int (*blast_out)(void *how, unsigned char *buf, unsigned len); -/* Definitions for input/output functions passed to blast(). See below for - * what the provided functions need to do. - */ - - -int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow); -/* Decompress input to output using the provided infun() and outfun() calls. - * On success, the return value of blast() is zero. If there is an error in - * the source data, i.e. it is not in the proper format, then a negative value - * is returned. If there is not enough input available or there is not enough - * output space, then a positive error is returned. - * - * The input function is invoked: len = infun(how, &buf), where buf is set by - * infun() to point to the input buffer, and infun() returns the number of - * available bytes there. If infun() returns zero, then blast() returns with - * an input error. (blast() only asks for input if it needs it.) inhow is for - * use by the application to pass an input descriptor to infun(), if desired. - * - * The output function is invoked: err = outfun(how, buf, len), where the bytes - * to be written are buf[0..len-1]. If err is not zero, then blast() returns - * with an output error. outfun() is always called with len <= 4096. outhow - * is for use by the application to pass an output descriptor to outfun(), if - * desired. - * - * The return codes are: - * - * 2: ran out of input before completing decompression - * 1: output error before completing decompression - * 0: successful decompression - * -1: literal flag not zero or one - * -2: dictionary size not in 4..6 - * -3: distance is too far back - * - * At the bottom of blast.c is an example program that uses blast() that can be - * compiled to produce a command-line decompression filter by defining TEST. - */ diff --git a/tools/cpio/src/cpio.1 b/tools/cpio/src/cpio.1 deleted file mode 100644 index 9c8b1f98c..000000000 --- a/tools/cpio/src/cpio.1 +++ /dev/null @@ -1,943 +0,0 @@ -'\" t -.\" Copyright (c) 2003 Gunnar Ritter -.\" -.\" This software is provided 'as-is', without any express or implied -.\" warranty. In no event will the authors be held liable for any damages -.\" arising from the use of this software. -.\" -.\" Permission is granted to anyone to use this software for any purpose, -.\" including commercial applications, and to alter it and redistribute -.\" it freely, subject to the following restrictions: -.\" -.\" 1. 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. -.\" -.\" 2. Altered source versions must be plainly marked as such, and must not be -.\" misrepresented as being the original software. -.\" -.\" 3. This notice may not be removed or altered from any source distribution. -.\" Sccsid @(#)cpio.1 1.92 (gritter) 3/26/07 -.TH CPIO 1 "3/26/07" "Heirloom Toolchest" "User Commands" -.SH NAME -cpio \- copy file archives in and out -.SH SYNOPSIS -.PD 0 -.HP -.nh -.ad l -\fBcpio\fR \fB\-i\fR[\fBbcdfkmrstuvBSV6\fR] [\fB\-C\fI\ size\fR] -[\fB\-E\fI\ file\fR] [\fB\-H\fI\ hdr\fR] [[\fB\-I\fI\ file\fR] -[\fB\-M\fI\ msg\fR]] [\fB\-R\fI\ id\fR] [\fIpatterns\fR] -.HP -.ad l -\fBcpio\fR \fB\-o\fR[\fBacvABLPV\fR] [\fB\-C\fI\ size\fR] -[\fB\-H\fI\ hdr\fR] [[\fB\-M\fI\ msg\fR] [\fB\-O\fI\ file\fR]] -.HP -.ad l -\fBcpio\fR \fB\-p\fR[\fBadlmPuvLV\fR] [\fB\-R\fI\ id\fR] \fIdirectory\fR -.br -.PD -.ad b -.hy 1 -.SH DESCRIPTION -.I Cpio -creates and extracts file archives and copies files. -.PP -With the -.B \-i -option, -.I cpio -works in -.RI ` copy-in ' -mode and extracts files from a file archive. -By default, -the archive is read from standard input. -Optional arguments are interpreted as -.I patterns -and restrict the set of extracted files -to those matching any of the -.IR patterns . -A -.RB ` !\& ' -at the beginning of the -.I pattern -selects all files that do not match this -.IR pattern . -The syntax is otherwise identical to that described in -.IR glob (7), -except that the slash character -.RB ` / ' -is matched by -meta-character constructs with -.RB ` * ', -.RB ` ? ' -and -.RB ` [ '. -Care must be taken to quote meta-characters appropriately from the shell. -File permissions are set to those in the archive; -if the caller is the super-user, -ownerships are restored as well. -.I Cpio -will not create directories, -preserve modification times -or overwrite more recently modified target files -unless the appropriate -.IR \-d , -.I \-m -or -.I \-u -options are specified. -Archives compressed with -.IR bzip2 (1), -.IR compress (1), -.IR gzip (1), -or -.IR rpm (1) -are transparently de\%compressed on input. -.PP -With -.BR \-o , -.I cpio -works in -.RI ` copy-out ' -mode, -creates archives -and writes them to standard output per default. -A list of filenames to be included in the archive is -read from standard input; -if the name of a directory appears, -it is included in the archive, -but -.I cpio -will not include any of its members -unless they are explicitly given in addition. -The -.IR find (1) -utility is useful to generate a list of files -(see also its -.I \-cpio -and -.I \-ncpio -operators). -When producing a filename list for -.IR cpio , -find should always be invoked with -.I \-depth -since this makes it possible to extract write-protected directories -for users other than the super-user. -.PP -The -.B \-p -option selects -.RI ` pass ' -mode; -a list of files is read from standard input as described for -.IR \-o ; -files are copied to the specified -.IR directory , -preserving attributes as described for -.IR \-i . -Special files are re-created in the target hierarchy, -and hard links between copied files are preserved. -.PP -When a premature end-of-file is detected with -.I \-i -and -.I \-o -and the archive is a block or character special file, -the user is prompted for new media. -.PP -The following options alter the behavior of -.IR cpio : -.TP -.B \-a -Resets the access times of files -that were included in the archive with -.I \-o -or copied with -.IR \-p . -.TP -.B \-A -Append files to the archive. -The archive must be seekable, -such as a regular file or a block device, -or a tape device capable of writing between filemarks. -.TP -.B \-b -Swap bytes within each half word -and half words within each word -of input file data. -.TP -.B \-B -Blocks input and output archives at 5120 byte records. -The default blocking size is device dependent. -.TP -.B \-c -Specifies that archive headers are in SVR4 ASCII cpio format. -This option is ignored with -.I \-i -unless the -.I \-k -option is also present. -.TP -\fB\-C\fI size\fR -Blocks input and output archives at -.I size -byte records. -.TP -.B \-d -Creates missing parent directories -for each file extracted from the archive -and allows the extraction of directories. -.TP -\fB\-E\fI file\fR -Each line read from -.I file -is taken as a pattern in addition -to those specified on the command line. -.TP -.B \-f -Reverses the sense of patterns -such that a file that does not match any of the patterns -is selected. -.TP -\fB\-H\fI header\fR -Specifies the archive header format to be one of: -.sp -.in +6 -.TS -lfB l. -\fBcrc\fR SVR4 ASCII cpio format with checksum;\ -\fBsco\fR T{ -SCO UnixWare 7.1 ASCII cpio format; -T} -\fBscocrc\fR T{ -SCO UnixWare 7.1 ASCII cpio format with checksum; -T} -\fBodc\fR T{ -traditional ASCII cpio format, as standardized in IEEE Std. 1003.1, 1996; -T} -\fBbbs\fR byte-swapped binary cpio format; -\fBsgi\fR T{ -SGI IRIX extended binary cpio format; -T} -\fBcray\fR T{ -Cray UNICOS 9 cpio format; -T} -\fBcray5\fR T{ -Cray UNICOS 5 cpio format; -T} -\fBdec\fR T{ -Digital UNIX extended cpio format; -T} -\fBtar\fR tar format; -\fBotar\fR old tar format; -\fBustar\fR T{ -IEEE Std. 1003.1, 1996 tar format; -T} -.T& -l s. -\fBpax\fR[\fB:\fIoption\fB,\fR[\fIoption\fB,\fR\|...]] -.T& -l l. -\& T{ -IEEE Std. 1003.1, 2001 pax format. -Format-specific \fIoptions\fR are: -.in +2n -.ti 0 -.br -\fBlinkdata\fR -.br -For a regular file which has multiple hard links, -the file data is stored once for each link in the archive, -instead of being stored for the first entry only. -This option must be used with care -since many implementations are unable -to read the resulting archive. -.ti 0 -.br -\fBtimes\fR -.br -Causes the times of last access and last modification -of each archived file -to be stored in an extended \fIpax\fR header. -This in particular allows the time of last access -to be restored when the archive is read. -.br -.in -2n -T} -\fBsun\fR T{ -Sun Solaris 7 extended tar format; -T} -\fBgnu\fR T{ -GNU tar format; -T} -\fBbar\fR T{ -SunOS 4 bar format; -T} -\fBzip\fR[\fB:\fIcc\fR] T{ -zip format with optional compression method. -If \fIcc\fR is one of -\fBen\fR (normal, default), -\fBex\fR (extra), -\fBef\fR (fast), -or -\fBes\fR (super fast), -the standard \fIdeflate\fR compression is used. -\fBe0\fR selects no compression, -and -\fBbz2\fR selects \fIbzip2\fR compression. -T} -.TE -.in -6 -.sp -This option is ignored with -.I \-i -unless the -.I \-k -option is also present. -The default for -.I \-o -is binary cpio format. -.TP -\fB\-I\fI\ file\fR -Selects a -.I file -that is read with the -.I \-i -option instead of standard input. -.TP -.B \-k -Try to continue operation on read errors and invalid headers. -If an archive contains another archive, -files from either archive may be chosen. -.TP -.B \-l -Link files instead of copying them with -.I \-p -if possible. -.TP -.B \-L -Follow symbolic links when reading files with -.I \-o -or -.IR \-p . -.TP -.B \-m -Restore modification times of extracted files -to those given in the archive. -.TP -\fB\-M\fI message\fR -The given -.I message -is printed instead of the standard one -with -.I \-I -or -.I \-O -when changing media. -.TP -\fB\-O\fI file\fR -Selects an archive -.I file -that is written instead of standard output -with the -.I \-o -option. -.TP -.B \-P -In copy-out or pass mode, -interpret the data read from standard input -as prototype lines -of colon-separated fields -of the form -.in +3m -.sp -\fItype\fB:\fIuser\fB:\fIgroup\fB:\fImode\fB:\fIatime\fB:\fImtime\fB:\fImajor\fB:\fIminor\fB:\fIpath\fR -.sp -.in -3m -For each non-empty field, -the corresponding attribute of the input file is overridden. -With this option, -an unprivileged user can create -an archive that contains files -with arbitrary attributes. -The meanings of the individual fields are: -.RS -.TP 6 -.PD 0 -.I type -File type, one of: -\fBb\fR (block device), -\fBc\fR (character device), -\fBd\fR (directory), -\fBf\fR (plain file), -\fBp\fR (named pipe), -or -\fBs\fR (symbolic link). -.TP -.I user -The owner of the file, -which can be a numeric user ID or a user name. -.TP -.I group -The group owner of the file, -which can be a numeric group ID or a group name. -.TP -.I mode -The octal mode of the file. -.TP -.I atime -The time the file was last accessed. -Note that most archive formats cannot store this attribute, -in which case it is ignored. -The format is the same as that of the -.I mtime -field. -.TP -.I mtime -The time the file was last modified. -This is either a decimal integer -specifying the seconds past the epoch, -or an ISO\ 8601 date and time field -of the format \fIYYYYMMDD\fBT\fIHHMMSS\fR, -e.g. 20070326T190511, -the latter being relative to the current time zone -and with all digits past the \fBT\fR being optional. -.TP -.I major minor -Major and minor device numbers as with -.IR mknod (1M). -These fields are only allowed for block and character devices. -.TP -.I path -The name of the file to be archived. -If the file is not a symbolic link, -and the specification is otherwise sufficient, -the file needs not exist -at the time the archive is created. -A non-existent regular file will be empty in the archive. -.PD -.RE -.IP -This option is an extension. -.TP -.B \-r -Rename files interactively. -Before a file is extracted from the archive, -its file name is printed on standard error -and the user is prompted to specify a substitute file name. -If the line read from the terminal is empty, -the file is skipped; -if the line consists of a single dot, -the name is retained; -otherwise, -the line forms the new file name. -.TP -\fB\-R\fI user\fR -Set the ownership of extracted files -to the user and group ids of -.I user -instead of those specified in the archive. -Valid only for the super-user. -.TP -.B \-s -Swap bytes within each half word -of input file data. -.TP -.B \-S -Swap half words within each word -of input file data. -.TP -.B \-t -When combined with the -.I \-o -option, -a list of files in the archive is written to standard output; -no files are extracted. -.TP -.B \-u -.I Cpio -will overwrite existing target files -that were modified more recently than the file in the archive -when this option is given. -.TP -.B \-v -Prints the file names of archived or extracted files with -.I \-i -and -.I \-o -and a verbose output format with -.IR \-t . -If given twice -.RB ( \-vv ) -in combination with -.I \-t -when reading a -.I zip -archive, -information about compression level and method is printed. -.TP -.B \-V -Prints a dot for each archived or extracted file. -.TP -.B \-6 -Selects Unix 6th Edition archive format -(only in copy-in mode). -.PP -.ne 37 -Characteristics of archive formats are as follows: -.sp -.TS -allbox; -l r r r l -l1fB r2 n2 r2 c. - T{ -.ad l -maximum user/\%group id -T} T{ -.ad l -maximum file size -T} T{ -.ad l -maximum pathname length -T} T{ -.ad l -bits in dev_t (major/minor) -T} -binary 65535 2 GB\ 256 \ 16 -\-H\ sgi 65535 9 EB\ 256 \ 14/18 -\-H\ odc 262143 8 GB\ 256 \ 18 -\-H\ dec 262143 8 GB\ 256 \ 24/24 -T{ -\-c, \-H\ crc -T} 4.3e9 4 GB\ 1024 \ 32/32 -T{ -\-H\ sco, \-H\ scocrc -T} 4.3e9 9 EB\ 1024 \ 32/32 -T{ -\-H\ cray, \-H\ cray5 -T} 1.8e19 9 EB\ 65535 \ 64 -\-H\ otar 2097151 8 GB\ 99 \ n/a -T{ -\-H\ tar, -\-H\ ustar -T} 2097151 8 GB\ 256 (99) \ 21/21 -\-H\ pax 1.8e19 9 EB\ 65535 \ 21/21 -\-H\ sun 1.8e19 9 EB\ 65535 \ 63/63 -\-H\ gnu 1.8e19 9 EB\ 65535 \ 63/63 -\-H\ bar 2097151 8 GB\ 427 \ 21 -\-H\ zip 4.3e9 9 EB\ 60000 \ 32 -.TE -.sp -.PP -By default, -.B binary -cpio archives are written. -The byte order of such archives -depends on the machine -on which the archive is created. -Unlike some other implementations, -.I cpio -fully supports -archives of either byte order. -.I \-H\ bbs -can be used to create an archive -with the byte order opposed to that of the current machine. -.PP -The -.B sgi -format extends the binary format -to handle larger files and more device bits. -If an archive does not contain any entries -that actually need the extensions, -it is identical to a binary archive. -.I \-H\ sgi -archives are always created in MSB order. -.PP -The -.B odc -format was introduced with System\ III -and standardized with IEEE Std. 1003.1. -All known -.I cpio -implementations since around 1980 can read this format. -.PP -The -.B dec -format extends the -.I odc -format -to support more device bits. -Archives in this format are generally incompatible with -.I odc -archives -and need special implementation support to be read. -.PP -The -.B \-c -format was introduced with System\ V Release\ 4. -Except for the file size, -it imposes no practical limitations -on files archived. -The original SVR4 implementation -stores the contents of hard linked files -only once and with the last archived link. -This -.I cpio -ensures compatibility with SVR4. -With archives created by implementations that employ other methods -for storing hard linked files, -each file is extracted as a single link, -and some of these files may be empty. -Implementations that expect methods other than the original SVR4 one -may extract no data for hard linked files at all. -.PP -The -.B crc -format is essentially the same as the -.I \-c -format -but adds a simple checksum (not a CRC, despite its name) -for the data of regular files. -The checksum requires the implementation to read each file twice, -which can considerably increase running time and system overhead. -As not all implementations claiming to support this format -handle the checksum correctly, -it is of limited use. -.PP -The -.B sco -and -.B scocrc -formats are variants of the -.I \-c -and -.I \-H\ crc -formats, respectively, -with extensions to support larger files. -The extensions result in a different archive format -only if files larger than slightly below 2\ GB occur. -.PP -The -.B cray -format extends all header fields to 64 bits. -It thus imposes no practical limitations of any kind -on archived files, -but requires special implementation support -to be read. -Although it is originally a binary format, -the byte order is always MSB as on Cray machines. -The -.B cray5 -format is an older variant -that was used with UNICOS 5 and earlier. -.PP -The -.B otar -format was introduced with the Unix 7th Edition -.I tar -utility. -Archives in this format -can be read on all Unix systems since about 1980. -It can only hold regular files -(and, on more recent systems, symbolic links). -For file names that contain characters with the most significant bit set -(non-ASCII characters), -implementations differ in the interpretation of the header checksum. -.PP -The -.B ustar -format was introduced with IEEE Std. 1003.1. -It extends the old -.I tar -format -with support for directories, device files, -and longer file names. -Pathnames of single-linked files can consist of up to 256 characters, -dependent on the position of slashes. -Files with multiple links can only be archived -if the first link encountered is no longer than 100 characters. -Due to implementation errors, -file names longer than 99 characters -can not considered to be generally portable. -Another addition of the -.I ustar -format -are fields for the symbolic user and group IDs. -These fields are created by -.IR cpio , -but ignored when reading such archives. -.PP -With -.BR "\-H tar" , -a variant of the -.I ustar -format is selected -which stores file type bits in the mode field -to work around common implementation problems. -These bits are ignored by -.I cpio -when reading archives. -.PP -The -.B pax -format is an extension to the -.I ustar -format. -If attributes cannot be archived with -.IR ustar , -an extended header is written. -Unless the size of an entry is greater than 8\ GB, -a -.I pax -archive should be readable by any implementation -capable of reading -.I ustar -archives, -although files may be extracted under wrong names -and extended headers may be extracted as separate files. -If a file name contains non-UTF-8 characters, -it may not be archived or extracted correctly -because of a problem of the -.I pax -format specification. -.PP -The -.B sun -format extends the -.I ustar -format similar as the -.I pax -format does. -The extended headers in -.I sun -format archives are not understood -by implementations that support only the -.I pax -format and vice-versa. -The -.I sun -format has also problems with non-UTF-8 characters in file names. -.PP -The -.B GNU -.I tar -format is mostly compatible with the other -.I tar -formats, -unless an archive entry actually uses its extended features. -There are no practical limitations on files archived with this format. -The implementation of -.I cpio -is limited to expanded numerical fields -and long file names; -in particular, -there is no support for sparse files or incremental backups. -If -.I cpio -creates a multi-volume -.I GNU -archive, -it just splits a single-volume archive in multiple parts, -as with the other formats; -.I GNU -multi-volume archives are not supported. -.PP -The -.B bar -format is similar to the -.I tar -format, but can store longer file names. -It requires special implementation support to be read. -.PP -The -.B zip -format can be read in many non-Unix environments. -There are several restrictions on archives -intended for data exchange: -only regular files should be stored; -file times, permissions and ownerships -might be ignored by other implementations; -there should be no more than 65536 files in the archive; -the total archive size should not exceed 2 GB; -only -.I deflate -compression should be used. -Otherwise, -.I cpio -stores all information available with other archive formats -in extended -.I zip -file headers, -so if archive portability is of no concern, -the -.I zip -implementation in -.I cpio -can archive complete Unix file hierarchies. -.I Cpio -supports the -.I zip64 -format extension for large files; -it automatically writes -.I zip64 -entries if necessary. -.I Cpio -can extract all known -.I zip -format compression codes. -It does not support -.I zip -encryption. -Multi-volume -.I zip -archives are created as splitted single-volume archives, -as with the other formats written by -.IR cpio ; -generic multi-volume -.I zip -archives are not supported. -.SH EXAMPLES -Extract all files named -.I Makefile -or -.I makefile -from the archive stored on -.IR /dev/rmt/c0s0 , -overwriting recent files: -.RS 2 -.sp -cpio \-idmu \-I /dev/rmt/c0s0 \'[Mm]akefile\' \'*/[Mm]akefile\' -.RE -.PP -List the files contained in a software distribution archive: -.RS 2 -.sp -cpio \-itv \-I distribution.tar.gz -.RE -.PP -Write a -.IR gzip (1) -compressed -.I ustar -archive containing all files below the directory -.I \%project -to the file -.IR \%project.tar.gz , -excluding all directories named -.I CVS -or -.I SCCS -and their contents: -.RS 2 -.sp -find project \-depth \-print | egrep \-v \'/(CVS|SCCS)(/|$)\' | -.br - cpio \-o \-H ustar | gzip \-c > project.tar.gz -.RE -.PP -Copy the directory -.I work -and its contents -to the directory -.IR \%savedfiles : -.RS 2 -.sp -find work \-depth \-print | cpio \-pdm savedfiles -.RE -.PP -Self-extracting zip archives are not automatically recognized, -but can normally be read using the -.I \-k -option, as with -.RS 2 -.sp -cpio \-itvk \-H zip \-I archive.exe -.sp -.RE -.SH "ENVIRONMENT VARIABLES" -.TP -.BR LANG ", " LC_ALL -See -.IR locale (7). -.TP -.B LC_CTYPE -Selects the mapping of bytes to characters -used for matching patterns. -.TP -.B LC_TIME -Sets the month names printed with -.IR \-tv . -.TP -.B SYSV3 -If this variable is set, -the -.I \-c -option has the same effect as \fI\-H odc\fR; -\fB\-H newc\fR can be used -to select SVR4 ASCII format. -The output format of -.I \-tv -is changed, as well as the text of diagnostic messages. -.SH "SEE ALSO" -find(1), -pax(1), -tar(1) -.SH DIAGNOSTICS -.I Cpio -exits with -.sp -.TS -l8fB l. -0 after successful operation; -1 on usage errors; -2 when operation was continued after minor errors; -3 on fatal error conditions. -.TE -.SH NOTES -Device and inode numbers -are used for hard link recognition -with the various cpio formats. -Since the header space cannot hold -large numbers present in current file systems, -devices and inode numbers are set on a per-archive basis. -This enables hard link recognition with all cpio formats, -but the link connection to files appended with -.I \-A -is not preserved. -.PP -If a numeric user or group id does not fit -within the size of the header field in the selected format, -files are stored with the user id (or group id, respectively) -set to 60001. -.PP -Use of the -.I \-A -option with a -.I zip -format archive may cause data loss -if the archive was not previously created by -.I cpio -itself. -.PP -.I Cpio -cannot store file names that contain newline characters; -see the -.I NOTES -section of -.IR find (1) -for more information. -.PP -If the file names passed to -.I "cpio \-o" -begin with a slash character, -absolute path names are stored in the archive -and will be extracted to these path names later -regardless of the current working directory. -This is normally not advisable, -and relative path names should be passed to -.I cpio -only. diff --git a/tools/cpio/src/cpio.c b/tools/cpio/src/cpio.c deleted file mode 100644 index e5090e4c9..000000000 --- a/tools/cpio/src/cpio.c +++ /dev/null @@ -1,7172 +0,0 @@ -/* - * cpio - copy file archives in and out - * - * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. - */ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ - -/* - * Sccsid @(#)cpio.c 1.304 (gritter) 2/14/09 - */ - -#include -#include -#ifdef __linux__ -#if !defined (__UCLIBC__) && !defined (__dietlibc__) -#include -#endif /* !__UCLIBC__, !__dietlibc__ */ -#include -#undef WNOHANG -#undef WUNTRACED -#undef P_ALL -#undef P_PID -#undef P_PGID -#ifdef __dietlibc__ -#undef NR_OPEN -#undef PATH_MAX -#endif /* __dietlibc__ */ -#endif /* __linux__ */ -#include -#include -#include -#include -#include -#include -#include "sigset.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "memalign.h" - -int sysv3; - -#if USE_ZLIB -#include -#endif /* USE_ZLIB */ - -#if USE_BZLIB -#include -#endif /* USE_BZLIB */ - -#include - -#if defined (__linux__) || defined (__sun) || defined (__FreeBSD__) || \ - defined (__hpux) || defined (_AIX) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || \ - defined (__CYGWIN__) -#include -#endif - -#include -#include -#include - -#ifdef _AIX -#include -#endif /* _AIX */ - -#ifndef major -#include -#endif /* !major */ - -#include "cpio.h" -#include "blast.h" - -#ifdef __GLIBC__ -#ifdef _IO_putc_unlocked -#undef putc -#define putc(c, f) _IO_putc_unlocked(c, f) -#undef putchar -#define putchar(c) _IO_putc_unlocked(c, stdout) -#endif /* _IO_putc_unlocked */ -#endif /* __GLIBC__ */ - -/* - * The cpio code assumes that all following S_IFMT bits are the same as - * those of the mode fields in cpio headers. The only real Unix system - * known to deviate from this de facto standard is UNICOS which uses - * 0130000 for S_IFLNK. But this software does not run on UNICOS for - * a variety of other reasons anyway, so this should not be of much - * concern. - */ -#if S_IFIFO != 0010000 || \ - S_IFCHR != 0020000 || \ - S_IFDIR != 0040000 || \ - S_IFBLK != 0060000 || \ - S_IFREG != 0100000 || \ - S_IFLNK != 0120000 || \ - S_IFSOCK!= 0140000 || \ - S_IFMT != 0170000 -#error non-standard S_IFMT bits -#endif - -/* - * File types that are not present on all systems but that we want to - * recognize nevertheless. - */ -#ifndef S_IFDOOR -#define S_IFDOOR 0150000 /* Solaris door */ -#endif -#ifndef S_IFNAM -#define S_IFNAM 0050000 /* XENIX special named file */ -#endif -#ifndef S_INSEM -#define S_INSEM 0x1 /* XENIX semaphore subtype of IFNAM */ -#endif -#ifndef S_INSHD -#define S_INSHD 0x2 /* XENIX shared data subtype of IFNAM */ -#endif -#ifndef S_IFNWK -#define S_IFNWK 0110000 /* HP-UX network special file */ -#endif - -#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -/* - * For whatever reason, FreeBSD casts the return values of major() and - * minor() to signed values so that normal limit comparisons will fail. - */ -static unsigned long -mymajor(long dev) -{ - return major(dev) & 0xFFFFFFFFUL; -} -#undef major -#define major(a) mymajor(a) -static unsigned long -myminor(long dev) -{ - return minor(dev) & 0xFFFFFFFFUL; -} -#undef minor -#define minor(a) myminor(a) -#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - -/* - * Device and inode counts in cpio formats are too small to store the - * information used to detect hard links on today's systems. Keep track - * of all devices and inodes and store fake counts in the archive. - */ -struct ilink { - struct ilink *l_nxt; /* next link to same i-node */ - char *l_nam; /* link name */ - size_t l_siz; /* link name size */ -}; - -struct islot { - struct islot *i_lln; /* left link */ - struct islot *i_rln; /* right link */ - struct ilink *i_lnk; /* links list */ - struct stat *i_st; /* stat information */ - char *i_name;/* name of first link encountered */ - ino_t i_ino; /* real inode number */ - uint32_t i_fino; /* fake inode number */ - nlink_t i_nlk; /* number of remaining links */ -}; - -struct dslot { - struct dslot *d_nxt; /* next device */ - struct islot *d_isl; /* inode slots */ - uint32_t d_cnt; /* used inode number count */ - uint32_t d_fake; /* faked device id */ - dev_t d_dev; /* real device id */ -}; - -union types2 { - uint8_t byte[2]; - uint16_t sword; -}; - -union types4 { - uint8_t byte[4]; - uint16_t sword[2]; - uint32_t lword; -}; - -/* - * Store and retrieve integers in a defined endian order. - */ -static uint16_t -ple16(const char *cp) -{ - return (uint16_t)(cp[0]&0377) + - ((uint16_t)(cp[1]&0377) << 8); -} - -static uint16_t -pbe16(const char *cp) -{ - return (uint16_t)(cp[1]&0377) + - ((uint16_t)(cp[0]&0377) << 8); -} - -static uint32_t -ple32(const char *cp) -{ - return (uint32_t)(cp[0]&0377) + - ((uint32_t)(cp[1]&0377) << 8) + - ((uint32_t)(cp[2]&0377) << 16) + - ((uint32_t)(cp[3]&0377) << 24); -} - -static uint32_t -pbe32(const char *cp) -{ - return (uint32_t)(cp[3]&0377) + - ((uint32_t)(cp[2]&0377) << 8) + - ((uint32_t)(cp[1]&0377) << 16) + - ((uint32_t)(cp[0]&0377) << 24); -} - -static uint32_t -pme32(const char *cp) -{ - return (uint32_t)(cp[2]&0377) + - ((uint32_t)(cp[3]&0377) << 8) + - ((uint32_t)(cp[0]&0377) << 16) + - ((uint32_t)(cp[1]&0377) << 24); -} - -static uint64_t -ple64(const char *cp) -{ - return (uint64_t)(cp[0]&0377) + - ((uint64_t)(cp[1]&0377) << 8) + - ((uint64_t)(cp[2]&0377) << 16) + - ((uint64_t)(cp[3]&0377) << 24) + - ((uint64_t)(cp[4]&0377) << 32) + - ((uint64_t)(cp[5]&0377) << 40) + - ((uint64_t)(cp[6]&0377) << 48) + - ((uint64_t)(cp[7]&0377) << 56); -} - -static uint64_t -pbe64(const char *cp) -{ - return (uint64_t)(cp[7]&0377) + - ((uint64_t)(cp[6]&0377) << 8) + - ((uint64_t)(cp[5]&0377) << 16) + - ((uint64_t)(cp[4]&0377) << 24) + - ((uint64_t)(cp[3]&0377) << 32) + - ((uint64_t)(cp[2]&0377) << 40) + - ((uint64_t)(cp[1]&0377) << 48) + - ((uint64_t)(cp[0]&0377) << 56); -} - -static void -le16p(uint16_t n, char *cp) -{ - cp[0] = (n&0x00ff); - cp[1] = (n&0xff00) >> 8; -} - -static void -be16p(uint16_t n, char *cp) -{ - cp[1] = (n&0x00ff); - cp[0] = (n&0xff00) >> 8; -} - -static void -le32p(uint32_t n, char *cp) -{ - cp[0] = (n&0x000000ff); - cp[1] = (n&0x0000ff00) >> 8; - cp[2] = (n&0x00ff0000) >> 16; - cp[3] = (n&0xff000000) >> 24; -} - -static void -be32p(uint32_t n, char *cp) -{ - cp[3] = (n&0x000000ff); - cp[2] = (n&0x0000ff00) >> 8; - cp[1] = (n&0x00ff0000) >> 16; - cp[0] = (n&0xff000000) >> 24; -} - -static void -me32p(uint32_t n, char *cp) -{ - cp[2] = (n&0x000000ff); - cp[3] = (n&0x0000ff00) >> 8; - cp[0] = (n&0x00ff0000) >> 16; - cp[1] = (n&0xff000000) >> 24; -} - -static void -le64p(uint64_t n, char *cp) -{ - cp[0] = (n&0x00000000000000ffLL); - cp[1] = (n&0x000000000000ff00LL) >> 8; - cp[2] = (n&0x0000000000ff0000LL) >> 16; - cp[3] = (n&0x00000000ff000000LL) >> 24; - cp[4] = (n&0x000000ff00000000LL) >> 32; - cp[5] = (n&0x0000ff0000000000LL) >> 40; - cp[6] = (n&0x00ff000000000000LL) >> 48; - cp[7] = (n&0xff00000000000000LL) >> 56; -} - -static void -be64p(uint64_t n, char *cp) -{ - cp[7] = (n&0x00000000000000ffLL); - cp[6] = (n&0x000000000000ff00LL) >> 8; - cp[5] = (n&0x0000000000ff0000LL) >> 16; - cp[4] = (n&0x00000000ff000000LL) >> 24; - cp[3] = (n&0x000000ff00000000LL) >> 32; - cp[2] = (n&0x0000ff0000000000LL) >> 40; - cp[1] = (n&0x00ff000000000000LL) >> 48; - cp[0] = (n&0xff00000000000000LL) >> 56; -} - -#define TNAMSIZ 100 -#define TPFXSIZ 155 -#define TMAGSIZ 6 -#define TTIMSIZ 12 - -/* - * Structure of an archive header. - */ -union bincpio { - char data[4096]; -#define SIZEOF_hdr_cpio 26 - struct hdr_cpio { - char c_magic[2]; - char c_dev[2]; - char c_ino[2]; - char c_mode[2]; - char c_uid[2]; - char c_gid[2]; - char c_nlink[2]; - char c_rdev[2]; - char c_mtime[4]; - char c_namesize[2]; - char c_filesize[4]; - } Hdr; -#define SIZEOF_cray_hdr 152 - struct cray_hdr { /* with thanks to Cray-Cyber.org */ - char C_magic[8]; - char C_dev[8]; - char C_ino[8]; - char C_mode[8]; - char C_uid[8]; - char C_gid[8]; - char C_nlink[8]; - char C_rdev[8]; - /* - * The C_param field was introduced with - * UNICOS 6 and is simply not present in - * the earlier format. Following fields - * are the same for both revisions again. - */ -#define CRAY_PARAMSZ (8*8) - char C_param[CRAY_PARAMSZ]; - char C_mtime[8]; - char C_namesize[8]; - char C_filesize[8]; - } Crayhdr; -#define SIZEOF_c_hdr 76 - struct c_hdr { - char c_magic[6]; - char c_dev[6]; - char c_ino[6]; - char c_mode[6]; - char c_uid[6]; - char c_gid[6]; - char c_nlink[6]; - char c_rdev[6]; - char c_mtime[11]; - char c_namesz[6]; - char c_filesz[11]; - } Cdr; -#define SIZEOF_d_hdr 86 - struct d_hdr { - char d_magic[6]; - char d_dev[6]; - char d_ino[6]; - char d_mode[6]; - char d_uid[6]; - char d_gid[6]; - char d_nlink[6]; - char d_rmaj[8]; - char d_rmin[8]; - char d_mtime[11]; - char d_namesz[6]; - char d_filesz[11]; - } Ddr; -#define SIZEOF_Exp_cpio_hdr 110 - struct Exp_cpio_hdr { - char E_magic[6]; - char E_ino[8]; - char E_mode[8]; - char E_uid[8]; - char E_gid[8]; - char E_nlink[8]; - char E_mtime[8]; - char E_filesize[8]; - char E_maj[8]; - char E_min[8]; - char E_rmaj[8]; - char E_rmin[8]; - char E_namesize[8]; - char E_chksum[8]; - } Edr; - struct tar_header { - char t_name[TNAMSIZ]; - char t_mode[8]; - char t_uid[8]; - char t_gid[8]; - char t_size[12]; - char t_mtime[TTIMSIZ]; - char t_chksum[8]; - char t_linkflag; - char t_linkname[TNAMSIZ]; - char t_magic[TMAGSIZ]; - char t_version[2]; - char t_uname[32]; - char t_gname[32]; - char t_devmajor[8]; - char t_devminor[8]; - char t_prefix[TPFXSIZ]; - } Tdr; -#define SIZEOF_bar_header 84 - struct bar_header { - char b_mode[8]; - char b_uid[8]; - char b_gid[8]; - char b_size[12]; - char b_mtime[12]; - char b_chksum[8]; - char b_rdev[8]; - char b_linkflag; - char b_bar_magic[2]; - char b_volume_num[4]; - char b_compressed; - char b_date[12]; - } Bdr; -#define SIZEOF_zip_header 30 - struct zip_header { - char z_signature[4]; - char z_version[2]; - char z_gflag[2]; - char z_cmethod[2]; - char z_modtime[2]; - char z_moddate[2]; - char z_crc32[4]; - char z_csize[4]; - char z_nsize[4]; - char z_namelen[2]; - char z_extralen[2]; - } Zdr; -}; - -#define BCUT 0177777 -#define OCUT 0777777 -#define ECUT 0xFFFFFFFFUL - -static const char trailer[] = "TRAILER!!!"; - -/* - * Structure of per-file extra data for zip format. - */ -union zextra { - char data[1]; -#define SIZEOF_zextra_gn 4 - struct zextra_gn { - char ze_gn_tag[2]; - char ze_gn_tsize[2]; - } Ze_gn; -#define SIZEOF_zextra_64 32 /* regular size */ -#define SIZEOF_zextra_64_a 28 /* size without startn field */ -#define SIZEOF_zextra_64_b 20 /* size without reloff field */ - struct zextra_64 { - char ze_64_tag[2]; - char ze_64_tsize[2]; - char ze_64_nsize[8]; - char ze_64_csize[8]; - char ze_64_reloff[8]; - char ze_64_startn[4]; - } Ze_64; -#define SIZEOF_zextra_pk 16 - struct zextra_pk { - char ze_pk_tag[2]; - char ze_pk_tsize[2]; - char ze_pk_atime[4]; - char ze_pk_mtime[4]; - char ze_pk_uid[2]; - char ze_pk_gid[2]; - } Ze_pk; -#define SIZEOF_zextra_ek 17 - struct zextra_et { - char ze_et_tag[2]; - char ze_et_tsize[2]; - char ze_et_flags[1]; - char ze_et_mtime[4]; - char ze_et_atime[4]; - char ze_et_ctime[4]; - } Ze_et; -#define SIZEOF_zextra_i1 16 - struct zextra_i1 { - char ze_i1_tag[2]; - char ze_i1_tsize[2]; - char ze_i1_atime[4]; - char ze_i1_mtime[4]; - char ze_i1_uid[2]; - char ze_i1_gid[2]; - } Ze_i1; -#define SIZEOF_zextra_i2 8 - struct zextra_i2 { - char ze_i2_tag[2]; - char ze_i2_tsize[2]; - char ze_i2_uid[2]; - char ze_i2_gid[2]; - } Ze_i2; -#define SIZEOF_zextra_as 16 - struct zextra_as { - char ze_as_tag[2]; - char ze_as_tsize[2]; - char ze_as_crc[4]; - char ze_as_mode[2]; - char ze_as_sizdev[4]; - char ze_as_uid[2]; - char ze_as_gid[2]; - } Ze_as; -#define SIZEOF_zextra_cp 40 - struct zextra_cp { - char ze_cp_tag[2]; - char ze_cp_tsize[2]; - char ze_cp_dev[4]; - char ze_cp_ino[4]; - char ze_cp_mode[4]; - char ze_cp_uid[4]; - char ze_cp_gid[4]; - char ze_cp_nlink[4]; - char ze_cp_rdev[4]; - char ze_cp_mtime[4]; - char ze_cp_atime[4]; - } Ze_cp; -}; - -static struct zipstuff { /* stuff for central directory at EOF */ - struct zipstuff *zs_next; - char *zs_name; /* file name */ - long long zs_size; /* file size */ - long long zs_relative; /* offset of local header */ - long long zs_csize; /* compressed size */ - uint32_t zs_crc32; /* CRC */ - time_t zs_mtime; /* modification time */ - enum cmethod zs_cmethod; /* compression method */ - int zs_gflag; /* general flag */ - mode_t zs_mode; /* file mode */ -} *zipbulk; - -/* - * Structure of the central zip directory at the end of the file. This - * (obligatory) part of a zip file is written by this implementation, - * but is completely ignored on copy-in. This means that we miss the - * mode_t stored in zc_extralen if zc_versionmade[1] is 3 (Unix). We - * have to do this since it contains the S_IFMT bits, thus telling us - * whether something is a symbolic link and resulting in different - * behavior - but as the input had to be seekable in order to do this, - * we had to store entire archives in temporary files if input came - * from a pipe to be consistent. - */ -#define SIZEOF_zipcentral 46 -struct zipcentral { - char zc_signature[4]; - char zc_versionmade[2]; - char zc_versionextr[2]; - char zc_gflag[2]; - char zc_cmethod[2]; - char zc_modtime[2]; - char zc_moddate[2]; - char zc_crc32[4]; - char zc_csize[4]; - char zc_nsize[4]; - char zc_namelen[2]; - char zc_extralen[2]; - char zc_commentlen[2]; - char zc_disknstart[2]; - char zc_internal[2]; - char zc_external[4]; - char zc_relative[4]; -}; - -#define SIZEOF_zip64end 56 -struct zip64end { - char z6_signature[4]; - char z6_recsize[8]; - char z6_versionmade[2]; - char z6_versionextr[2]; - char z6_thisdiskn[4]; - char z6_alldiskn[4]; - char z6_thisentries[8]; - char z6_allentries[8]; - char z6_dirsize[8]; - char z6_startsize[8]; -}; - -#define SIZEOF_zip64loc 20 -struct zip64loc { - char z4_signature[4]; - char z4_startno[4]; - char z4_reloff[8]; - char z4_alldiskn[4]; -}; - -#define SIZEOF_zipend 22 -struct zipend { - char ze_signature[4]; - char ze_thisdiskn[2]; - char ze_alldiskn[2]; - char ze_thisentries[2]; - char ze_allentries[2]; - char ze_dirsize[4]; - char ze_startsize[4]; - char ze_commentlen[2]; -}; - -#define SIZEOF_zipddesc 16 -struct zipddesc { - char zd_signature[4]; - char zd_crc32[4]; - char zd_csize[4]; - char zd_nsize[4]; -}; - -#define SIZEOF_zipddesc64 24 -struct zipddesc64 { - char zd_signature[4]; - char zd_crc32[4]; - char zd_csize[8]; - char zd_nsize[8]; -}; - -/* - * Magic numbers and strings. - */ -static const uint16_t mag_bin = 070707; -/*static const uint16_t mag_bbs = 0143561;*/ -static const char mag_asc[6] = "070701"; -static const char mag_crc[6] = "070702"; -static const char mag_odc[6] = "070707"; -static const long mag_sco = 0x7ffffe00; - -static const char mag_ustar[6] = "ustar\0"; -static const char mag_gnutar[8] = "ustar \0"; -static const char mag_bar[2] = "V\0"; - -static const char mag_zipctr[4] = "PK\1\2"; -static const char mag_zipsig[4] = "PK\3\4"; -static const char mag_zipend[4] = "PK\5\6"; -static const char mag_zip64e[4] = "PK\6\6"; -static const char mag_zip64l[4] = "PK\6\7"; -static const char mag_zipdds[4] = "PK\7\10"; -#define mag_zip64f 0x0001 -#define mag_zipcpio 0x0707 - -/* - * Fields for the extended pax header. - */ -static enum paxrec { - PR_NONE = 0000, - PR_ATIME = 0001, - PR_GID = 0002, - PR_LINKPATH = 0004, - PR_MTIME = 0010, - PR_PATH = 0020, - PR_SIZE = 0040, - PR_UID = 0100, - PR_SUN_DEVMAJOR = 0200, - PR_SUN_DEVMINOR = 0400 -} paxrec, globrec; - -/* - * Prototype structure, collecting user-defined information - * about a file. - */ -struct prototype { - mode_t pt_mode; /* type and permission bits */ - uid_t pt_uid; /* owner */ - gid_t pt_gid; /* group owner */ - time_t pt_atime; /* time of last access */ - time_t pt_mtime; /* time of last modification */ - dev_t pt_rdev; /* device major/minor */ - enum { - PT_NONE = 0000, - PT_TYPE = 0001, - PT_OWNER = 0002, - PT_GROUP = 0004, - PT_MODE = 0010, - PT_ATIME = 0020, - PT_MTIME = 0040, - PT_RDEV = 0100 - } pt_spec; /* specified information */ -}; - -static struct stat globst; - -/* - * This sets a sanity check limit on path names. If a longer path name - * occurs in an archive, it is treated as corrupt. This is because no - * known Unix system can handle path names of arbitrary length; limits - * are typically between 1024 and 4096. Trying to extract longer path - * names would fail anyway and will cpio eventually fail to allocate - * memory. - */ -#define SANELIMIT 0177777 - -char *progname; /* argv[0] to main() */ -static struct dslot *devices; /* devices table */ -static struct dslot *markeddevs; /* unusable device numbers */ -static char *blkbuf; /* block buffer */ -int blksiz; /* block buffer size */ -static int blktop; /* top of filled part of buffer */ -static int curpos; /* position in blkbuf */ -static uint32_t fakedev; /* fake device for single link inodes */ -static uint32_t fakeino; /* fake inode for single link inodes */ -static uint32_t harddev; /* fake device used for hard links */ -static unsigned long long maxsize;/* maximum size for format */ -static unsigned long long maxrdev;/* maximum st_rdev for format */ -static unsigned long long maxmajor;/* maximum major(st_rdev) for format */ -static unsigned long long maxminor;/* maximum minor(st_rdev) for format */ -static unsigned long long maxuid; /* maximum user id for format */ -static unsigned long long maxgid; /* maximum group id for format */ -static unsigned long long maxnlink;/* maximum link count for format */ -static int mt; /* magtape file descriptor */ -static int mfl; /* magtape flags */ -static struct stat mtst; /* fstat() on mt */ -int aflag; /* reset access times */ -int Aflag; /* append to archive */ -int bflag; /* swap bytes */ -int Bflag; /* 5120 blocking */ -int cflag; /* ascii format */ -int Cflag; /* user-defined blocking */ -int dflag; /* create directories */ -int Dflag; /* do not ask for next device */ -int eflag; /* DEC format */ -int cray_eflag; /* do not archive if values too large */ -const char *Eflag; /* filename for files to be extracted */ -int fflag; /* pattern excludes */ -int Hflag; /* header format */ -const char *Iflag; /* input archive name */ -int kflag; /* skipt corrupted parts */ -int Kflag; /* IRIX-style large file support */ -int lflag; /* link of possible */ -int Lflag; /* follow symbolic links */ -int mflag; /* retain modification times */ -const char *Mflag; /* message when switching media */ -const char *Oflag; /* output archive name */ -int Pflag; /* prototype file list */ -int rflag; /* rename files */ -const char *Rflag; /* reassign ownerships */ -static uid_t Ruid; /* uid to assign */ -static gid_t Rgid; /* gid to assign */ -int sflag; /* swap half word bytes */ -int Sflag; /* swap word bytes */ -int tflag; /* print toc */ -int uflag; /* overwrite files unconditionally */ -int hp_Uflag; /* use umask when creating files */ -int vflag; /* verbose */ -int Vflag; /* special verbose */ -int sixflag; /* 6th Edition archives */ -int action; /* -i -o -p */ -long long errcnt; /* error status */ -static unsigned long long maxpath;/* maximum path length with -i */ -static uint32_t maxino; /* maximum inode number with -i */ -static uid_t myuid; /* user id of caller */ -static gid_t mygid; /* group id of caller */ -static long long blocks; /* copying statistics: full blocks */ -static long long bytes; /* copying statistics: partial blocks */ -static long long nwritten; /* bytes written to archive */ -static off_t aoffs; /* offset in archive */ -static off_t poffs; /* physical offset in archive */ -static int tapeblock = -1; /* physical tape block size */ -struct glist *patterns; /* patterns for -i */ -static int tty; /* terminal file descriptor */ -static const char *cur_ofile; /* current original file */ -static const char *cur_tfile; /* current temporary file */ -static mode_t umsk; /* user's umask */ -static int zipclevel; /* zip compression level */ -static struct islot *inull; /* splay tree null element */ -int printsev; /* print message severity strings */ -static int compressed_bar; /* this is a compressed bar archive */ -static int formatforced; /* -k -i -Hfmt forces a format */ -static long long lineno; /* input line number */ - -int pax_dflag; /* directory matches only itself */ -int pax_kflag; /* do not overwrite files */ -int pax_nflag; /* select first archive member only */ -int pax_sflag; /* substitute file names */ -int pax_uflag; /* add only recent files to archive */ -int pax_Xflag; /* do not cross device boundaries */ -static enum { - PO_NONE = 0, - PO_LINKDATA = 01, /* include link data in type 2 */ - PO_TIMES = 02, /* create atime and mtime fields */ -} pax_oflag; /* recognized -o options */ - -static void copyout(int (*)(const char *, struct stat *)); -static size_t ofiles_cpio(char **, size_t *); -static void dooutp(void); -static int outfile(const char *, struct stat *); -static int addfile(const char *, struct stat *, uint32_t, uint32_t, int, - const char *); -static void iflush(struct islot *, uint32_t); -static void lflush(void); -static int bigendian(void); -static void getbuf(char **, size_t *, size_t); -static void prdot(int); -static void newmedia(int); -static void mclose(void); -static ssize_t mwrite(int); -static void bwrite(const char *, size_t); -static void bflush(void); -static int sum(int, const char *, struct stat *, char *); -static int rstime(const char *, struct stat *, const char *); -static struct islot *isplay(ino_t, struct islot *); -static struct islot *ifind(ino_t, struct islot **); -static void iput(struct islot *, struct islot **); -static struct dslot *dfind(struct dslot **, dev_t); -static void done(int); -static void dopass(const char *); -static int passdata(struct file *, const char *, int); -static int passfile(const char *, struct stat *); -static int filein(struct file *, int (*)(struct file *, const char *, int), - char *); -static int linkunlink(const char *, const char *); -static void tunlink(char **); -static int filet(struct file *, int (*)(struct file *, const char *, int)); -static void filev(struct file *); -static int typec(struct stat *); -static void permbits(mode_t); -static void prtime_cpio(time_t); -static void getpath(const char *, char **, char **, size_t *, size_t *); -static void setpath(const char *, char **, char **, - size_t, size_t *, size_t *); -static int imdir(char *); -static int setattr(const char *, struct stat *); -static int setowner(const char *, struct stat *); -static int canlink(const char *, struct stat *, int); -static void doinp(void); -static void storelink(struct file *); -static void flushlinks(struct file *); -static void flushnode(struct islot *, struct file *); -static void flushrest(int); -static void flushtree(struct islot *, int); -static int inpone(struct file *, int); -static int readhdr(struct file *, union bincpio *); -static void whathdr(void); -static int infile(struct file *); -static int skipfile(struct file *); -static int skipdata(struct file *f, - int (*)(struct file *, const char *, int)); -static int indata(struct file *, const char *, int); -static int totrailer(void); -static long long rdoct(const char *, int); -static long long rdhex(const char *, int); -static ssize_t mread(void); -static void mstat(void); -static int skippad(unsigned long long, int); -static int allzero(const char *, int); -static const char *getuser(uid_t); -static const char *getgroup(gid_t); -static struct glist *want(struct file *, struct glist **); -static void patfile(void); -static int ckodd(long long, int, const char *, const char *); -static int rname(char **, size_t *); -static int redirect(const char *, const char *); -static char *tnameof(struct tar_header *, char *); -static int tmkname(struct tar_header *, const char *); -static void tlinkof(struct tar_header *, struct file *); -static int tmklink(struct tar_header *, const char *); -static int tlflag(struct stat *); -static void tchksum(union bincpio *); -static int tcssum(union bincpio *, int); -static int trdsum(union bincpio *); -static mode_t tifmt(int); -static void bchksum(union bincpio *); -static int bcssum(union bincpio *); -static void blinkof(const char *, struct file *, int); -static void dump_barhdr(void); -static int zcreat(const char *, mode_t); -static int zclose(int); -static void markdev(dev_t); -static int marked(dev_t); -static void cantsup(int, const char *); -static void onint(int); -static int zipread(struct file *, const char *, int, int); -static void zipreaddesc(struct file *); -static int cantunzip(struct file *, const char *); -static time_t gdostime(const char *, const char *); -static void mkdostime(time_t, char *, char *); -static ssize_t ziprxtra(struct file *, struct zip_header *); -static void ziptrailer(void); -static void zipdefer(const char *, struct stat *, long long, - uint32_t, long long, const struct zip_header *); -static int zipwrite(int, const char *, struct stat *, - union bincpio *, size_t, uint32_t, uint32_t, - uint32_t *, long long *); -static int zipwtemp(int, const char *, struct stat *, - union bincpio *, size_t, uint32_t, uint32_t, - uint32_t *, long long *); -#if USE_ZLIB -static int zipwdesc(int, const char *, struct stat *, - union bincpio *, size_t, uint32_t, uint32_t, - uint32_t *, long long *); -#endif /* USE_ZLIB */ -static int zipwxtra(const char *, struct stat *, uint32_t, uint32_t); -static void zipinfo(struct file *); -static void readK2hdr(struct file *); -static int readgnuname(char **, size_t *, long); -static void writegnuname(const char *, long, int); -static void tgetpax(struct tar_header *, struct file *); -static enum paxrec tgetrec(char **, char **, char **); -static void wrpax(const char *, const char *, struct stat *); -static void addrec(char **, long *, long *, - const char *, const char *, long long); -static void paxnam(struct tar_header *, const char *); -static char *sequence(void); -static char *joinpath(const char *, char *); -static int utf8(const char *); -static char *getproto(char *, struct prototype *); - -size_t (*ofiles)(char **, size_t *) = ofiles_cpio; -void (*prtime)(time_t) = prtime_cpio; - -int -main(int argc, char **argv) -{ - myuid = getuid(); - mygid = getgid(); - umask(umsk = umask(0)); - progname = basename(argv[0]); - setlocale(LC_CTYPE, ""); - setlocale(LC_TIME, ""); - inull = scalloc(1, sizeof *inull); - inull->i_lln = inull->i_rln = inull; - flags(argc, argv); - switch (action) { - case 'i': - if (sigset(SIGINT, SIG_IGN) != SIG_IGN) - sigset(SIGINT, onint); - doinp(); - break; - case 'o': - dooutp(); - break; - case 'p': - if (sigset(SIGINT, SIG_IGN) != SIG_IGN) - sigset(SIGINT, onint); - dopass(argv[optind]); - break; - } - if (tflag) - fflush(stdout); - else if (Vflag) - prdot(1); - if (pax != PAX_TYPE_CPIO) - pax_onexit(); - //fprintf(stderr, "%llu blocks\n", blocks + ((bytes + 0777) >> 9)); - mclose(); - if (errcnt && sysv3 == 0) - fprintf(stderr, "%llu error(s)\n", errcnt); - return errcnt ? sysv3 ? 1 : 2 : 0; -} - -static size_t -ofiles_cpio(char **name, size_t *namsiz) -{ - static struct iblok *ip; - - if (ip == NULL) - ip = ib_alloc(0, 0); - return ib_getlin(ip, name, namsiz, srealloc); -} - -/* - * Read the file name list for -o and -p and do initial processing - * for each name. - */ -static void -copyout(int (*copyfn)(const char *, struct stat *)) -{ - char *name = NULL, *np; - size_t namsiz = 0, namlen; - struct stat st; - struct prototype pt; - - while ((namlen = ofiles(&name, &namsiz)) != 0) { - lineno++; - if (name[namlen-1] == '\n') - name[--namlen] = '\0'; - if (Pflag) - np = getproto(name, &pt); - else - np = name; - while (np[0] == '.' && np[1] == '/') { - np += 2; - while (*np == '/') - np++; - if (*np == '\0') { - np = name; - break; - } - } - if (lstat(np, &st) < 0) { - if (Pflag && *np && ((pt.pt_spec & - (PT_TYPE|PT_OWNER|PT_GROUP|PT_MODE|PT_RDEV) && - ((pt.pt_mode&S_IFMT) == S_IFBLK || - (pt.pt_mode&S_IFMT) == S_IFCHR)) || - (pt.pt_spec & - (PT_TYPE|PT_OWNER|PT_GROUP|PT_MODE) && - ((pt.pt_mode&S_IFMT) == S_IFDIR || - (pt.pt_mode&S_IFMT) == S_IFIFO || - (pt.pt_mode&S_IFMT) == S_IFREG)))) { - memset(&st, 0, sizeof st); - st.st_mode = pt.pt_mode; - st.st_blksize = 4096; - st.st_nlink = 1; - goto missingok; - } - else if (sysv3 < 0) - msg(2, 0, "< %s > ?\n", np); - else if (sysv3 > 0) - msg(2, 0, "Cannot obtain information " - "about file: \"%s\".\n", - np); - else - emsg(2, "Error with lstat of \"%s\"", np); - errcnt++; - continue; - } - missingok: - if (Lflag && (st.st_mode&S_IFMT) == S_IFLNK) { - if (stat(np, &st) < 0) { - emsg(2, "Cannot follow \"%s\"", np); - errcnt++; - continue; - } - } - /* - * These file types are essentially useless in an archive - * since they are recreated by any process that needs them. - * We thus ignore them and do not even issue a warning, - * because that would only displace more important messages - * on a terminal and confuse people who just want to copy - * directory hierarchies.--But for pax, POSIX.1-2001 requires - * us to fail! - */ - if ((st.st_mode&S_IFMT) == S_IFSOCK || - (st.st_mode&S_IFMT) == S_IFDOOR) { - if (pax >= PAX_TYPE_PAX2001) { - msg(2, 0, "Cannot handle %s \"%s\".\n", - (st.st_mode&S_IFMT) == S_IFSOCK ? - "socket" : "door", np); - errcnt++; - } - continue; - } - if (Pflag) { - if (pt.pt_spec & PT_TYPE) - if ((st.st_mode&S_IFMT) != (pt.pt_mode&S_IFMT)) - msg(4, 0, "line %lld: types " - "do not match\n", lineno); - if (pt.pt_spec & PT_OWNER) - st.st_uid = pt.pt_uid; - if (pt.pt_spec & PT_GROUP) - st.st_gid = pt.pt_gid; - if (pt.pt_spec & PT_MODE) { - st.st_mode &= ~(mode_t)07777; - st.st_mode |= pt.pt_mode; - } - if (pt.pt_spec & PT_ATIME) - st.st_atime = pt.pt_atime; - if (pt.pt_spec & PT_MTIME) - st.st_mtime = pt.pt_mtime; - if (pt.pt_spec & PT_RDEV) { - if ((st.st_mode&S_IFMT) != S_IFBLK && - (st.st_mode&S_IFMT) != S_IFCHR) - msg(4, 0, "line %lld: device type " - "specified for non-device " - "file\n", lineno); - st.st_rdev = pt.pt_rdev; - } - } - if (pax_track(np, st.st_mtime) == 0) - continue; - if ((fmttype == FMT_ZIP || - fmttype & TYP_BAR || - fmttype == FMT_GNUTAR) - && (st.st_mode&S_IFMT) == S_IFDIR && - name[namlen-1] != '/') { - if (namlen+2 >= namsiz) { - size_t diff = np - name; - name = srealloc(name, namsiz = namlen+2); - np = &name[diff]; - } - name[namlen++] = '/'; - name[namlen] = '\0'; - } - errcnt += copyfn(np, &st); - } -} - -/* - * Execution for -o. - */ -static void -dooutp(void) -{ - if (Oflag) { - if ((mt = Aflag ? open(Oflag, O_RDWR, 0666) : - creat(Oflag, 0666)) < 0) { - if (sysv3) { - emsg(013, "Cannot open <%s> for %s.", Oflag, - Aflag ? "append" : "output"); - done(1); - } else - msg(3, -2, "Cannot open \"%s\" for %s\n", Oflag, - Aflag ? "append" : "output"); - } - } else - mt = dup(1); - mstat(); - blkbuf = svalloc(blksiz, 1); - if (Aflag) { - if (totrailer() != 0) - return; - } else if (fmttype == FMT_NONE) - fmttype = bigendian() ? FMT_BINBE : FMT_BINLE; - if (fmttype & TYP_BINARY) { - maxino = 0177777; - fakeino = 0177777; - maxpath = 256; - if (fmttype & TYP_SGI) { - maxsize = 0x7FFFFFFFFFFFFFFFLL; - maxmajor = 037777; - maxminor = 0777777; - } else { - maxsize = 0x7FFFFFFFLL; - maxrdev = 0177777; - } - maxuid = 0177777; - maxgid = 0177777; - maxnlink = 0177777; - } else if (fmttype == FMT_ODC) { - maxino = 0777777; - fakeino = 0777777; - maxpath = 256; - maxsize = 077777777777LL; - maxrdev = 0777777; - maxuid = 0777777; - maxgid = 0777777; - maxnlink = 0777777; - } else if (fmttype == FMT_DEC) { - maxino = 0777777; - fakeino = 0777777; - maxpath = 256; - maxsize = 077777777777LL; - maxmajor = 077777777; - maxminor = 077777777; - maxuid = 0777777; - maxgid = 0777777; - maxnlink = 0777777; - } else if (fmttype & TYP_NCPIO) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = 1024; - maxsize = fmttype&TYP_SCO ? 0x7FFFFFFFFFFFFFFFLL : 0xFFFFFFFFUL; - maxmajor = 0xFFFFFFFFUL; - maxminor = 0xFFFFFFFFUL; - maxuid = 0xFFFFFFFFUL; - maxgid = 0xFFFFFFFFUL; - maxnlink = 0xFFFFFFFFUL; - } else if (fmttype & TYP_CRAY) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = SANELIMIT; - maxsize = 0x7FFFFFFFFFFFFFFFLL; - maxrdev = 0x7FFFFFFFFFFFFFFFLL; - maxuid = 0x7FFFFFFFFFFFFFFFLL; - maxgid = 0x7FFFFFFFFFFFFFFFLL; - maxnlink = 0x7FFFFFFFFFFFFFFFLL; - } else if (fmttype == FMT_GNUTAR) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = SANELIMIT; - maxsize = 0x7FFFFFFFFFFFFFFFLL; - maxmajor = 0x7FFFFFFFFFFFFFFFLL; - maxminor = 0x7FFFFFFFFFFFFFFFLL; - maxuid = 0x7FFFFFFFFFFFFFFFLL; - maxgid = 0x7FFFFFFFFFFFFFFFLL; - maxnlink = 0x7FFFFFFFFFFFFFFFLL; - } else if (fmttype & TYP_PAX) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = SANELIMIT; - maxsize = 0x7FFFFFFFFFFFFFFFLL; - maxmajor = fmttype==FMT_SUN ? 0x7FFFFFFFFFFFFFFFLL : 07777777; - maxminor = fmttype==FMT_SUN ? 0x7FFFFFFFFFFFFFFFLL : 07777777; - maxuid = 0x7FFFFFFFFFFFFFFFLL; - maxgid = 0x7FFFFFFFFFFFFFFFLL; - maxnlink = 0x7FFFFFFFFFFFFFFFLL; - if (pax_oflag & PO_TIMES) - globrec |= PR_ATIME|PR_MTIME; - } else if (fmttype & TYP_BAR) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = 512 - SIZEOF_bar_header - 1; - maxsize = 077777777777LL; - maxrdev = 07777777; - maxuid = 07777777; - maxgid = 07777777; - maxnlink = 0x7FFFFFFFFFFFFFFFLL; - if (nwritten == 0) - dump_barhdr(); - } else if (fmttype & TYP_USTAR) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = 256; - maxsize = 077777777777LL; - maxmajor = 07777777; - maxminor = 07777777; - maxuid = 07777777; - maxgid = 07777777; - maxnlink = 0x7FFFFFFFFFFFFFFFLL; - } else if (fmttype & TYP_OTAR) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = 99; - maxsize = 077777777777LL; - maxuid = 07777777; - maxgid = 07777777; - maxnlink = 0x7FFFFFFFFFFFFFFFLL; - } else if (fmttype == FMT_ZIP) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = 60000; - maxsize = 0x7FFFFFFFFFFFFFFFLL; - maxrdev = 0xFFFFFFFFUL; - maxuid = 0xFFFFFFFFUL; - maxgid = 0xFFFFFFFFUL; - maxnlink = 0xFFFFFFFFUL; - } else - abort(); - fakedev = 0177777; - harddev = 1; - copyout(outfile); - if (fmttype & TYP_NCPIO) - lflush(); - if (fmttype & TYP_CPIO) { - struct stat st; - - memset(&st, 0, sizeof st); - st.st_nlink = 1; - outfile(trailer, &st); - } - if (fmttype & TYP_TAR) { - char b[512]; - - memset(b, 0, sizeof b); - bwrite(b, sizeof b); - bwrite(b, sizeof b); - } - if (fmttype == FMT_ZIP) - ziptrailer(); - bflush(); -} - -/* - * Handle a single file for -o, do sanity checks and detect hard links. - */ -static int -outfile(const char *file, struct stat *st) -{ - uint32_t dev, ino; - size_t pathsz; - - if ((st->st_mode&S_IFMT) == S_IFREG) - if (mtst.st_dev == st->st_dev && mtst.st_ino == st->st_ino) - return 0; - if (st->st_size > maxsize) { - msg(2, 0, "Size of %c%s%c >%lluGB. Not dumped\n", - sysv3 ? '<' : '"', - file, - sysv3 ? '>' : '"', - (maxsize+1) / (1024*1024*1024)); - return 1; - } - if (((st->st_mode&S_IFMT)==S_IFBLK||(st->st_mode&S_IFMT)==S_IFCHR) && - (maxrdev && - (unsigned long long)st->st_rdev > maxrdev || - maxmajor && - (unsigned long long)major(st->st_rdev) > maxmajor || - maxminor && - (unsigned long long)minor(st->st_rdev) > maxminor)) { - cantsup(1, file); - return 1; - } - if ((unsigned long long)st->st_uid > maxuid) { - if (cray_eflag) { - cantsup(1, file); - return 1; - } - cantsup(0, file); - st->st_uid = 60001; - if ((st->st_mode&S_IFMT) == S_IFREG && st->st_mode & 0111) - st->st_mode &= ~(mode_t)S_ISUID; - if ((unsigned long long)st->st_gid > maxgid) { - st->st_gid = 60001; - if ((st->st_mode&S_IFMT)==S_IFREG && st->st_mode&0010) - st->st_mode &= ~(mode_t)S_ISGID; - } - } else if ((unsigned long long)st->st_gid > maxgid) { - if (cray_eflag) { - cantsup(1, file); - return 1; - } - cantsup(0, file); - st->st_gid = 60001; - if ((st->st_mode&S_IFMT) == S_IFREG && st->st_mode & 0010) - st->st_mode &= ~(mode_t)S_ISGID; - } - if ((pathsz = strlen(file)) > maxpath) { - msg(2, 0, "%s: file name too long\n", file); - return 1; - } - /* - * Detect hard links and compute fake inode counts. The mechanism - * is as follows: If a file has more than one link, a fake device - * number starting at one is used for its device, and a fake inode - * number is used starting at one too. - * - * The information on links of directories is useless, so it is - * dropped and handled like a file with a single link only: Fake - * devices are allocated just below the format's limit, fake - * i-nodes the same. - * - * This way even the binary cpio format can have up to ~4G files. - */ - if (maxino && st->st_nlink > 1 && (st->st_mode&S_IFMT) != S_IFDIR) { - struct dslot *ds, *dp; - struct islot *ip; - - dev = 1; - ds = devices; - dp = NULL; -nextdev: - for (; ds; dp = ds, ds = ds->d_nxt, dev++ /* see below! */) - if (ds->d_dev == st->st_dev) - break; - if (markeddevs && marked(dev)) { - dev++; - goto nextdev; - } - if (dev >= fakedev) - msg(4, 1, "Too many devices in archive, exiting\n"); - if (ds == NULL) { - ds = scalloc(1, sizeof *ds); - ds->d_dev = st->st_dev; - ds->d_fake = dev; - if (devices == NULL) - devices = ds; - else - dp->d_nxt = ds; - } - harddev = dev; - if ((ip = ifind(st->st_ino, &ds->d_isl)) == NULL) { - if (ds->d_cnt >= maxino) { - /* corresponds to for loop above */ - dev++, dp = ds, ds = ds->d_nxt; - goto nextdev; - } - ip = scalloc(1, sizeof *ip); - ip->i_ino = st->st_ino; - ip->i_fino = ++ds->d_cnt; - ip->i_nlk = st->st_nlink; - if (fmttype & TYP_TAR) - ip->i_name = sstrdup(file); - if (fmttype & TYP_NCPIO) { - ip->i_st = smalloc(sizeof *ip->i_st); - *ip->i_st = *st; - } - iput(ip, &ds->d_isl); - } - ino = ip->i_fino; - if (fmttype & TYP_NCPIO) { - /* - * In SVR4 ascii cpio format, files with multiple - * links are stored with a zero size except for the - * last link, which contains the actual file content. - * As one cannot know which is the last link in - * advance since some links may be outside the - * archive content, all links have to be collected - * and written out at once. - */ - struct ilink *il, *ik; - - switch (ip->i_nlk) { - case 1: - /* - * This was the last link to a file. Write - * all previous links and break to write - * the actual file content. Free the pointers - * in islot; islot remains within the tree - * with a remaining link count of zero. - */ - ip->i_nlk--; - free(ip->i_st); - ip->i_st = NULL; - for (il = ip->i_lnk, ik = NULL; il; - ik = il, il = il->l_nxt, - ik ? free(ik), 0 : 0) { - errcnt += addfile(il->l_nam, st, - dev, ino, 1, 0); - free(il->l_nam); - } - break; - case 0: - /* - * This file got a link during operation, or - * -L was specified and we encountered a link - * more than once. Start with a fresh link - * count again. - */ - ip->i_nlk = st->st_nlink; - ip->i_lnk = NULL; - ip->i_st = smalloc(sizeof *ip->i_st); - *ip->i_st = *st; - /*FALLTHRU*/ - default: - /* - * There are more links to this file. Store - * only the name and return. - */ - ip->i_nlk--; - if (ip->i_lnk) { - for (il = ip->i_lnk; il->l_nxt; - il = il->l_nxt); - il->l_nxt = scalloc(1,sizeof*il->l_nxt); - il = il->l_nxt; - } else { - ip->i_lnk = scalloc(1,sizeof*ip->i_lnk); - il = ip->i_lnk; - } - il->l_nam = smalloc(pathsz + 1); - strcpy(il->l_nam, file); - return 0; - } - } else if (fmttype & TYP_TAR) { - if (strcmp(ip->i_name, file)) - return addfile(file, st, dev, ino, 1, - ip->i_name); - } - } else { /* single-linked or directory */ - dev = fakedev; - while (markeddevs && marked(dev)) - dev--; - if ((ino = fakeino--) == 0) { - if (--dev <= harddev) - msg(4, 1, "Too many devices in archive, " - "exiting\n"); - fakedev = dev; - ino = maxino; - fakeino = ino - 1; - } - } - return addfile(file, st, dev, ino, 0, 0); -} - -/* - * Add a single file to the archive with -o. - */ -static int -addfile(const char *realfile, struct stat *st, - uint32_t dev, uint32_t ino, int zerolink, const char *linkname) -{ - union bincpio bc; - int fd = -1; - long long size; - int pad, i; - ssize_t rsz = 0, wsz = 0, hsz, fsz, psz; - long long remsz, relative, nlink; - long long Kbase = 0, Krest = 0, Ksize = 0; - struct hdr_cpio K2hdr; - uint32_t crc = 0; - long long csize = 0; - char *file; - char *symblink = NULL; - int failure = 1; - - file = sstrdup(realfile); - if (pax != PAX_TYPE_CPIO && strcmp(file, trailer)) { - size_t junk = 0; - if (pax_sflag && pax_sname(&file, &junk) == 0) - goto cleanup; - if (rflag && rname(&file, &junk) == 0) - goto cleanup; - } - fsz = strlen(file); - relative = nwritten; - memset(bc.data, 0, sizeof bc.data); - if (fmttype == FMT_PAX && pax_oflag & PO_LINKDATA && - (st->st_mode&S_IFMT) == S_IFREG) - size = st->st_size; - else if (zerolink) - size = 0; - else if ((st->st_mode&S_IFMT) == S_IFREG) - size = st->st_size; - else if ((st->st_mode&S_IFMT) == S_IFLNK) { - i = st->st_size ? st->st_size : PATH_MAX; - symblink = smalloc(i+1); - if ((size = readlink(realfile, symblink, i)) < 0) { - emsg(3, "Cannot read symbolic link \"%s\"", realfile); - goto cleanup; - } - symblink[size] = '\0'; - } else - size = 0; - nlink = ((unsigned long long)st->st_nlink>maxnlink ? - maxnlink : st->st_nlink); - if (fmttype & TYP_NCPIO) { - long size1; - if (fmttype & TYP_SCO && size >= mag_sco) { - char *ofile = file; - size1 = mag_sco; - fsz += 22; - file = smalloc(fsz + 1); - snprintf(file, fsz + 1, "%s%csize=%016llx", - ofile, 0, size); - free(ofile); - } else - size1 = size; - pad = 4; - sprintf(bc.data, "%*.*s%08lx%08lx%08lx%08lx%08lx%08lx" - "%08lx%08lx%08lx%08lx%08lx%08lx%08lx", - (int)(fmttype&TYP_CRC? sizeof mag_crc:sizeof mag_asc), - (int)(fmttype&TYP_CRC? sizeof mag_crc:sizeof mag_asc), - fmttype & TYP_CRC ? mag_crc : mag_asc, - (long)ino & ECUT, - (long)st->st_mode & ECUT, - (long)st->st_uid & ECUT, - (long)st->st_gid & ECUT, - (long)nlink & ECUT, - (long)st->st_mtime & ECUT, - (long)size1 & ECUT, - (long)major(dev) & ECUT, - (long)minor(dev) & ECUT, - (long)major(st->st_rdev) & ECUT, - (long)minor(st->st_rdev) & ECUT, - (long)++fsz, - 0L); - hsz = SIZEOF_Exp_cpio_hdr; - if ((psz = (hsz + fsz) % pad) != 0) - psz = pad - psz; - } else if (fmttype == FMT_ODC) { - pad = 1; - sprintf(bc.data, "%*.*s%06lo%06lo%06lo%06lo%06lo%06lo%06lo" - "%011lo%06lo%011lo", - (int)sizeof mag_odc, (int)sizeof mag_odc, mag_odc, - (long)dev & OCUT, - (long)ino & OCUT, - (long)st->st_mode & OCUT, - (long)st->st_uid & OCUT, - (long)st->st_gid & OCUT, - (long)nlink & OCUT, - (long)st->st_rdev & OCUT, - (long)st->st_mtime, - (long)++fsz, - (long)size); - hsz = SIZEOF_c_hdr; - if ((psz = (hsz + fsz) % pad) != 0) - psz = pad - psz; - } else if (fmttype == FMT_DEC) { - pad = 1; - sprintf(bc.data, "%*.*s%06lo%06lo%06lo%06lo%06lo%06lo" - "%08lo%08lo%011lo%06lo%011lo", - (int)sizeof mag_odc, (int)sizeof mag_odc, mag_odc, - (long)dev & OCUT, - (long)ino & OCUT, - (long)st->st_mode & OCUT, - (long)st->st_uid & OCUT, - (long)st->st_gid & OCUT, - (long)nlink & OCUT, - (long)major(st->st_rdev) & 077777777, - (long)minor(st->st_rdev) & 077777777, - (long)st->st_mtime, - (long)++fsz, - (long)size); - hsz = SIZEOF_d_hdr; - if ((psz = (hsz + fsz) % pad) != 0) - psz = pad - psz; - } else if (fmttype & TYP_BINARY) { - /* - * To avoid gcc's stupid 'comparison is always false due to - * limited range of data type' warning. - */ - unsigned long long gcccrap; - pad = 2; - if (fmttype & TYP_BE) { - be16p(mag_bin, bc.Hdr.c_magic); - be16p(dev, bc.Hdr.c_dev); - be16p(ino, bc.Hdr.c_ino); - be16p(st->st_mode, bc.Hdr.c_mode); - be16p(st->st_uid, bc.Hdr.c_uid); - be16p(st->st_gid, bc.Hdr.c_gid); - be16p(nlink, bc.Hdr.c_nlink); - be16p(st->st_rdev, bc.Hdr.c_rdev); - be32p(st->st_mtime, bc.Hdr.c_mtime); - be16p(++fsz, bc.Hdr.c_namesize); - } else { - le16p(mag_bin, bc.Hdr.c_magic); - le16p(dev, bc.Hdr.c_dev); - le16p(ino, bc.Hdr.c_ino); - le16p(st->st_mode, bc.Hdr.c_mode); - le16p(st->st_uid, bc.Hdr.c_uid); - le16p(st->st_gid, bc.Hdr.c_gid); - le16p(nlink, bc.Hdr.c_nlink); - le16p(st->st_rdev, bc.Hdr.c_rdev); - me32p(st->st_mtime, bc.Hdr.c_mtime); - le16p(++fsz, bc.Hdr.c_namesize); - } - if (fmttype & TYP_SGI && size > 0x7FFFFFFFLL) { - Krest = size & 0x7FFFFFFFLL; - Kbase = size - Krest; - Ksize = 0x100000000LL - (Kbase >> 31); - if (fmttype & TYP_BE) - be32p(Ksize, bc.Hdr.c_filesize); - else - me32p(Ksize, bc.Hdr.c_filesize); - K2hdr = bc.Hdr; - if (fmttype & TYP_BE) - be32p(Krest, K2hdr.c_filesize); - else - me32p(Krest, K2hdr.c_filesize); - } else { - if (fmttype & TYP_BE) - be32p(size, bc.Hdr.c_filesize); - else - me32p(size, bc.Hdr.c_filesize); - } - if (fmttype & TYP_SGI && - (((st->st_mode&S_IFMT) == S_IFBLK || - (st->st_mode&S_IFMT) == S_IFCHR) && - ((unsigned long long)major(st->st_rdev)>0xFF || - (unsigned long long)minor(st->st_rdev)>0xFF) || - (gcccrap = st->st_rdev) > 0177777)) { - uint32_t rdev; - rdev = (minor(st->st_rdev) & 0x0003FFFF) + - ((major(st->st_rdev)<<18) & 0xFFFC0000); - if (fmttype & TYP_BE) { - be16p(0xFFFF, bc.Hdr.c_rdev); - be32p(rdev, bc.Hdr.c_filesize); - } else { - le16p(0xFFFF, bc.Hdr.c_rdev); - me32p(rdev, bc.Hdr.c_filesize); - } - } - hsz = SIZEOF_hdr_cpio; - psz = (hsz + fsz) % 2; - } else if (fmttype & TYP_CRAY) { - int diff5 = fmttype==FMT_CRAY5 ? CRAY_PARAMSZ : 0; - mode_t mo; - pad = 1; - be64p(mag_bin, bc.Crayhdr.C_magic); - be64p(dev, bc.Crayhdr.C_dev); - be64p(ino, bc.Crayhdr.C_ino); - if ((st->st_mode&S_IFMT) == S_IFLNK) /* non-standard */ - mo = st->st_mode&07777|0130000; /* S_IFLNK on Cray */ - else - mo = st->st_mode; - be64p(mo, bc.Crayhdr.C_mode); - be64p(st->st_uid, bc.Crayhdr.C_uid); - be64p(st->st_gid, bc.Crayhdr.C_gid); - be64p(nlink, bc.Crayhdr.C_nlink); - be64p(st->st_rdev, bc.Crayhdr.C_rdev); - be64p(st->st_mtime, bc.Crayhdr.C_mtime - diff5); - be64p(++fsz, bc.Crayhdr.C_namesize - diff5); - be64p(size, bc.Crayhdr.C_filesize - diff5); - hsz = SIZEOF_cray_hdr - diff5; - psz = 0; - } else if (fmttype & TYP_BAR) { - int c, n = 0; - pad = 512; - sprintf(bc.Bdr.b_mode, "%7.7o",(int)st->st_mode&(07777|S_IFMT)); - sprintf(bc.Bdr.b_uid, "%7.7lo", (long)st->st_uid); - sprintf(bc.Bdr.b_gid, "%7.7lo", (long)st->st_gid); - sprintf(bc.Bdr.b_size, "%11.11llo", - (st->st_mode&S_IFMT) == S_IFREG && !zerolink ? - (long long)st->st_size&077777777777LL : 0LL); - sprintf(bc.Bdr.b_mtime, "%11.11lo", (long)st->st_mtime); - sprintf(bc.Bdr.b_rdev, "%7.7lo", (long)st->st_rdev); - strcpy(&bc.data[SIZEOF_bar_header], file); - c = tlflag(st); - if (zerolink == 0) { - bc.Bdr.b_linkflag = c; - if (c == '2') { - strncpy(&bc.data[SIZEOF_bar_header+fsz+1], - symblink, - 512-SIZEOF_bar_header-fsz); - n = size; - } - } else { - bc.Bdr.b_linkflag = '1'; - strncpy(&bc.data[SIZEOF_bar_header+fsz+1], linkname, - 512-SIZEOF_bar_header-fsz-1); - n = strlen(linkname); - } - if (n > 512-SIZEOF_bar_header-fsz-1) { - msg(3, 0, "%s: linked name too long\n", realfile); - goto cleanup; - } - bchksum(&bc); - hsz = 512; - psz = 0; - fsz = 0; - } else if (fmttype & TYP_TAR) { - const char *cp; - int c; - /* - * Many SVR4 cpio derivatives expect the mode field - * to contain S_IFMT bits. The meaning of these bits - * in the mode field of the ustar header is left - * unspecified by IEEE Std 1003.1, 1996, 10.1.1. - */ - int mmask = fmttype == FMT_USTAR || fmttype == FMT_PAX ? - 07777 : 07777|S_IFMT; - - paxrec = globrec; - pad = 512; - if (tmkname(&bc.Tdr, file) != 0) - goto cleanup; - sprintf(bc.Tdr.t_mode, "%7.7o", (int)st->st_mode & mmask); - if (fmttype == FMT_GNUTAR && st->st_uid > 07777777) { - be64p(st->st_uid, bc.Tdr.t_uid); - bc.Tdr.t_uid[0] |= 0200; - } else { - sprintf(bc.Tdr.t_uid, "%7.7lo", - (long)st->st_uid&07777777); - if (fmttype & TYP_PAX && st->st_uid > 07777777) - paxrec |= PR_UID; - } - if (fmttype == FMT_GNUTAR && st->st_gid > 07777777) { - be64p(st->st_gid, bc.Tdr.t_gid); - bc.Tdr.t_gid[0] |= 0200; - } else { - sprintf(bc.Tdr.t_gid, "%7.7lo", - (long)st->st_gid&07777777); - if (fmttype & TYP_PAX && st->st_gid > 07777777) - paxrec |= PR_GID; - } - if (fmttype == FMT_GNUTAR && (st->st_mode&S_IFMT) == S_IFREG && - st->st_size > 077777777777LL && !zerolink) { - bc.Tdr.t_size[0] = '\200'; - be64p(st->st_size, &bc.Tdr.t_size[4]); - } else { - sprintf(bc.Tdr.t_size, "%11.11llo", - (st->st_mode&S_IFMT) == S_IFREG && - (!zerolink || fmttype == FMT_PAX && - pax_oflag & PO_LINKDATA) ? - (long long)st->st_size&077777777777LL : 0LL); - if (fmttype & TYP_PAX && - (st->st_mode&S_IFMT) == S_IFREG && - st->st_size > 077777777777LL && - (!zerolink || fmttype == FMT_PAX && - pax_oflag & PO_LINKDATA)) - paxrec |= PR_SIZE; - } - sprintf(bc.Tdr.t_mtime, "%11.11lo", (long)st->st_mtime); - if ((c = tlflag(st)) < 0) { - if ((st->st_mode&S_IFMT) != S_IFDIR) { - msg(2, 0, "%s is not a file. Not dumped\n", - realfile); - errcnt++; - } else - failure = 0; - goto cleanup; - } - if (zerolink == 0) { - bc.Tdr.t_linkflag = c; - if (c == '2') { - if (tmklink(&bc.Tdr, symblink) != 0) - goto cleanup; - } - } else { - bc.Tdr.t_linkflag = '1'; - if (tmklink(&bc.Tdr, linkname) != 0) - goto cleanup; - } - if (fmttype & TYP_USTAR) { - if (fmttype == FMT_GNUTAR) - strcpy(bc.Tdr.t_magic, mag_gnutar); - else { - strcpy(bc.Tdr.t_magic, mag_ustar); - bc.Tdr.t_version[0] = bc.Tdr.t_version[1] = '0'; - } - if ((cp = getuser(st->st_uid)) != NULL) - sprintf(bc.Tdr.t_uname, "%.31s", cp); - if ((cp = getgroup(st->st_gid)) != NULL) - sprintf(bc.Tdr.t_gname, "%.31s", cp); - else - msg(1, 0, "could not get group information " - "for %s\n", realfile); - if (fmttype == FMT_GNUTAR && - (unsigned long long)major(st->st_rdev) - > 077777777) { - be64p(major(st->st_rdev), bc.Tdr.t_devmajor); - bc.Tdr.t_devmajor[0] |= 0200; - } else { - if (fmttype == FMT_SUN && - (unsigned long long)major(st->st_rdev) - > 077777777 && - ((st->st_mode&S_IFMT)==S_IFBLK|| - (st->st_mode&S_IFMT)==S_IFCHR)) - paxrec |= PR_SUN_DEVMAJOR; - sprintf(bc.Tdr.t_devmajor, "%7.7o", - (int)major(st->st_rdev)&07777777); - } - if (fmttype == FMT_GNUTAR && - (unsigned long long)minor(st->st_rdev) - > 077777777) { - be64p(minor(st->st_rdev), bc.Tdr.t_devminor); - bc.Tdr.t_devminor[0] |= 0200; - } else { - if (fmttype == FMT_SUN && - (unsigned long long)minor(st->st_rdev) - > 077777777 && - ((st->st_mode&S_IFMT)==S_IFBLK|| - (st->st_mode&S_IFMT)==S_IFCHR)) - paxrec |= PR_SUN_DEVMINOR; - sprintf(bc.Tdr.t_devminor, "%7.7o", - (int)minor(st->st_rdev)&07777777); - } - } - tchksum(&bc); - hsz = 512; - psz = 0; - fsz = 0; - } else if (fmttype == FMT_ZIP) { - pad = 1; - memcpy(bc.Zdr.z_signature, mag_zipsig, sizeof mag_zipsig); - bc.Zdr.z_version[0] = 10; - mkdostime(st->st_mtime, bc.Zdr.z_modtime, bc.Zdr.z_moddate); - if ((st->st_mode&S_IFMT) == S_IFREG || - (st->st_mode&S_IFMT) == S_IFLNK) { - le32p(size, bc.Zdr.z_csize); - le32p(size, bc.Zdr.z_nsize); - csize = size; - } - le16p(fsz, bc.Zdr.z_namelen); - le16p(SIZEOF_zextra_cp, bc.Zdr.z_extralen); - hsz = SIZEOF_zip_header; - psz = 0; - } else - abort(); - /* - * Start writing the file to the archive. - */ - if ((st->st_mode&S_IFMT) == S_IFREG && st->st_size != 0 && - (zerolink == 0 || fmttype == FMT_PAX && - pax_oflag & PO_LINKDATA)) { - char *buf; - size_t bufsize; - int readerr = 0; - - if ((fd = open(realfile, O_RDONLY)) < 0) { - if (sysv3 < 0) - msg(0, 0, "< %s > ?\n", realfile); - else if (sysv3 > 0) - fprintf(stderr, "<%s> ?\n", realfile); - else - msg(0, 0, "\"%s\" ?\n", realfile); - goto cleanup; - } - if (fmttype == FMT_ZIP) { - if (zipwrite(fd, file, st, &bc, fsz, dev, ino, - &crc, &csize) < 0) - goto cleanup2; - goto done; - } - if (fmttype & TYP_CRC) - if (sum(fd, realfile, st, bc.Edr.E_chksum) < 0) - goto cleanup2; - if (fmttype & TYP_PAX && paxrec != PR_NONE) - wrpax(file, symblink?symblink:linkname, st); - bwrite(bc.data, hsz); - if (fsz) - bwrite(file, fsz); - if (psz) - bwrite(&bc.data[hsz], psz); - if (Kbase) - remsz = Kbase; - else - remsz = st->st_size; - getbuf(&buf, &bufsize, st->st_blksize); - again: while (remsz > 0) { - if (fd < 0 || (rsz = read(fd, &buf[wsz], - bufsize - wsz)) < 0) { - if (readerr == 0) { - emsg(3, "Cannot read \"%s\"", realfile); - if (fd >= 0) - errcnt++; - readerr = 1; - } - if (fd >= 0 && lseek(fd, bufsize - wsz, - SEEK_CUR) < 0) { - close(fd); - fd = -1; - } - rsz = bufsize - wsz; - if (rsz > remsz) - rsz = remsz; - memset(&buf[wsz], 0, rsz); - } - if (rsz > remsz) - rsz = remsz; - wsz += rsz; - remsz -= rsz; - bwrite(buf, wsz); - memset(buf, 0, wsz); - size = wsz; - wsz = 0; - } - wsz = size; - if (Kbase) { - if ((i = Ksize % pad) != 0) - bwrite(&bc.data[hsz], i); - bwrite((char *)&K2hdr, hsz); - if (fsz) - bwrite(file, fsz); - if (psz) - bwrite(&bc.data[hsz], psz); - remsz = Krest; - Kbase = 0; - wsz = 0; - goto again; - } else if (Ksize) - wsz = Krest; - } else if ((fmttype == FMT_ZIP || fmttype & TYP_CPIO) && - (st->st_mode&S_IFMT) == S_IFLNK) { - wsz = size; - if (fmttype == FMT_ZIP) { - crc = zipcrc(0, (unsigned char *)symblink, wsz); - le32p(crc, bc.Zdr.z_crc32); - bwrite(bc.data, SIZEOF_zip_header); - bwrite(file, fsz); - zipwxtra(file, st, dev, ino); - bwrite(symblink, wsz); - } else { - bwrite(bc.data, hsz); - if (fsz) - bwrite(file, fsz); - if (psz) - bwrite(&bc.data[hsz], psz); - bwrite(symblink, wsz); - } - } else { - if (fmttype & TYP_PAX && paxrec != PR_NONE) - wrpax(file, symblink?symblink:linkname, st); - bwrite(bc.data, hsz); - if (fsz) - bwrite(file, fsz); - if (psz) - bwrite(&bc.data[hsz], psz); - if (fmttype == FMT_ZIP) - zipwxtra(file, st, dev, ino); - } -done: if (fmttype == FMT_ZIP) { - zipdefer(file, st, relative, crc, csize, &bc.Zdr); - } - if ((i = wsz % pad) != 0) - bwrite(&bc.data[hsz], pad - i); - if (vflag && strcmp(file, trailer)) - fprintf(stderr, "%s\n", file); - else if (Vflag) - prdot(0); - failure = 0; -cleanup2: - if ((st->st_mode&S_IFMT) == S_IFREG) { - if (fd >= 0) - close(fd); - if (aflag) - errcnt += rstime(realfile, st, "access"); - } -cleanup: - free(file); - free(symblink); - return failure; -} - -/* - * Flush a SVR4 cpio format inode tree for -o. - */ -static void -iflush(struct islot *ip, uint32_t dev) -{ - if (ip == inull) - return; - iflush(ip->i_lln, dev); - iflush(ip->i_rln, dev); - if (ip->i_nlk > 0 && ip->i_st) { - struct ilink *il; - - for (il = ip->i_lnk; il->l_nxt; il = il->l_nxt) - errcnt += addfile(il->l_nam, ip->i_st, - dev, ip->i_fino, 1, 0); - errcnt += addfile(il->l_nam, ip->i_st, dev, ip->i_fino, 0, 0); - } -} - -/* - * Flush the SVR4 cpio link forest for -o. - */ -static void -lflush(void) -{ - struct dslot *ds; - - for (ds = devices; ds; ds = ds->d_nxt) - iflush(ds->d_isl, ds->d_fake); -} - -int -setfmt(char *s) -{ - int i, j; - - struct { - const char *ucs; - const char *lcs; - int type; - int bits; - } fs[] = { - { "NEWC", "newc", FMT_ASC, 00 }, - { "SCO", "sco", FMT_SCOASC, 00 }, - { "CRC", "crc", FMT_CRC, 00 }, - { "SCOCRC", "scocrc", FMT_SCOCRC, 00 }, - { "ODC", "odc", FMT_ODC, 00 }, - { "DEC", "dec", FMT_DEC, 00 }, - { "BIN", "bin", FMT_NONE, 00 }, - { "BBS", "bbs", TYP_BE, 00 }, - { "SGI", "sgi", FMT_SGIBE, 00 }, - { "CRAY", "cray", FMT_CRAY, 00 }, - { "CRAY5", "cray5", FMT_CRAY5, 00 }, - { "TAR", "tar", FMT_TAR, 00 }, - { "USTAR", "ustar", FMT_USTAR, 00 }, - { "PAX:", "pax:", FMT_PAX, 00 }, - { "SUN", "sun", FMT_SUN, 00 }, - { "GNU", "gnu", FMT_GNUTAR, 00 }, - { "OTAR", "otar", FMT_OTAR, 00 }, - { "BAR", "bar", FMT_BAR, 00 }, - { "ZIP:", "zip:", FMT_ZIP, 00 }, - { NULL, NULL, 0, 00 } - }; - for (i = 0; fs[i].ucs; i++) { - for (j = 0; s[j] && - (s[j] == fs[i].ucs[j] || s[j] == fs[i].lcs[j]); - j++) - if (fs[i].ucs[j] == ':') - break; - if (s[j] == '\0' && - (fs[i].ucs[j] == '\0' || fs[i].ucs[j] == ':') || - s[j] == ':' && fs[i].ucs[j] == ':') { - fmttype = fs[i].type; - if (fmttype == FMT_ZIP && s[j] == ':') { -#if USE_ZLIB - if (strcmp(&s[j+1], "en") == 0) - zipclevel = 00; - else if (strcmp(&s[j+1], "ex") == 0) - zipclevel = 01; - else if (strcmp(&s[j+1], "ef") == 0) - zipclevel = 02; - else if (strcmp(&s[j+1], "es") == 0) - zipclevel = 03; - else -#endif /* USE_ZLIB */ - if (strcmp(&s[j+1], "e0") == 0) - zipclevel = 04; - else -#if USE_BZLIB - if (strcmp(&s[j+1], "bz2") == 0) - zipclevel = 07; - else -#endif /* USE_BZLIB */ - continue; - } else if (fmttype == FMT_NONE) - fmttype = bigendian() ? FMT_BINBE : FMT_BINLE; - else if (fmttype == TYP_BE) - fmttype = bigendian() ? FMT_BINLE : FMT_BINBE; - else if (fmttype == FMT_PAX && s[j] == ':') { - if (pax_options(&s[j+1], 0) < 0) - continue; - } - return 0; - } - } - msg(3, 0, "Invalid header \"%s\" specified.\n", s); - return -1; -} - -static int -bigendian(void) -{ - union { - char u_c[2]; - int16_t u_i; - } u; - u.u_i = 1; - return u.u_c[1] == 1; -} - -int -setreassign(const char *s) -{ - struct passwd *pwd; - int val = 0; - - if (myuid != 0) { - msg(3, 0, "R option only valid for super-user.\n"); - val = -1; - } - if ((pwd = getpwnam(s)) == NULL) { - msg(3, 0, "\"%s\" is not a valid user id\n", s); - val = -1; - } else { - Ruid = pwd->pw_uid; - Rgid = pwd->pw_gid; - } - return val; -} - -void * -srealloc(void *m, size_t n) -{ - if ((m = realloc(m, n)) == NULL) { - write(2, "Out of memory.\n", 15); - _exit(sysv3 ? 2 : 3); - } - return m; -} - -void * -smalloc(size_t n) -{ - return srealloc(NULL, n); -} - -void * -scalloc(size_t nmemb, size_t size) -{ - void *vp; - - if ((vp = calloc(nmemb, size)) == NULL) { - write(2, "Out of memory.\n", 15); - _exit(sysv3 ? 2 : 3); - } - return vp; -} - -void * -svalloc(size_t n, int force) -{ - static long pagesize; - void *vp; - - if (pagesize == 0) - if ((pagesize = sysconf(_SC_PAGESIZE)) < 0) - pagesize = 4096; - if ((vp = memalign(pagesize, n)) == NULL && force) { - write(2, "Out of memory.\n", 15); - _exit(sysv3 ? 2 : 3); - } - return vp; -} - -/* - * A single static buffer is used for intermediate copying from file - * data to the tape buffer and vice versa, for creating checksums, and - * for data transfer with -p. - */ -static void -getbuf(char **bufp, size_t *sizep, size_t best) -{ - static char *buf; - static size_t size; - - if (size != best) { - if (buf) - free(buf); - size = best; - if (size == 0 || (buf = svalloc(size, 0)) == NULL) - buf = svalloc(size = 512, 1); - } - *bufp = buf; - *sizep = size; -} - -static void -sevprnt(int sev) -{ - if (printsev) switch (sev) { - case 1: - fprintf(stderr, "INFORM: "); - break; - case 2: - fprintf(stderr, "WARNING: "); - break; - case 3: - fprintf(stderr, "ERROR: "); - break; - case 4: - fprintf(stderr, "HALT: "); - break; - } -} - -void -msg(int sev, int err, const char *fmt, ...) -{ - va_list ap; - - /* - * The error message should appear near the file it refers to. - */ - if (tflag) - fflush(stdout); - else if (Vflag) - prdot(1); - if (sysv3 >= 0 && sev >= (printsev ? 0 : -1)) - fprintf(stderr, "%s: ", progname); - sevprnt(sev); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - if (err > 0) - done(err); - else if (err == -2) { - if (sysv3) - done(1); - usage(); - } -} - -void -emsg(int sev, const char *fmt, ...) -{ - char _fmt[60]; - int i, fl = sev & 030, n; - va_list ap; - - sev &= ~030; - i = errno; - if (tflag) - fflush(stdout); - else if (Vflag) - prdot(1); - fprintf(stderr, "%s: ", progname); - sevprnt(sev); - va_start(ap, fmt); - if (sysv3) { - if (fmt[(n=strlen(fmt))-1] == '"' && fmt[n-2] == 's' && - fmt[n-3] == '%' && fmt[n-4] == '"' && - n < sizeof _fmt) { - strcpy(_fmt, fmt); - _fmt[n-1] = '>'; - _fmt[n-4] = '<'; - fmt = _fmt; - } - } - vfprintf(stderr, fmt, ap); - va_end(ap); - if (sysv3 > 0 && sev >= 0 && fl & 010) - fprintf(stderr, "\n\t%s\n", strerror(i)); - else if (sysv3 < 0) { - if (fl & 020) - putc('\n', stderr); - else - fprintf(stderr, " (errno:%d)\n", i); - } else - fprintf(stderr, ", errno %d, %s\n", i, strerror(i)); -} - -static void -prdot(int flush) -{ - static int column; - - if (flush && column != 0 || column >= 50) { - write(action == 'o' && !Oflag ? 2 : 1, "\n", 1); - column = 0; - } - if (!flush) { - write(action == 'o' && !Oflag ? 2 : 1, ".", 1); - column++; - } -} - -/* - * Ask the user for new media if applicable, or exit. - */ -static void -newmedia(int err) -{ - static int mediacnt = 1; - static char answer[PATH_MAX+1]; - const char *mesf = action == 'i' ? - (Iflag && !sysv3 ? Iflag : "input") : - (Oflag && !sysv3 ? Oflag : "output"); - char c; - int i, j; - - if (mfl == 0 && close(mt) < 0) { - emsg(3, "Close error on \"%s\"", mesf); - errcnt++; - } - mfl = -1; - if ((mtst.st_mode&S_IFMT)!=S_IFCHR && (mtst.st_mode&S_IFMT)!=S_IFBLK || - Dflag) { - if (action == 'o') { - switch (err) { - case 0: - break; - case EFBIG: - msg(3, 0, "ulimit reached for output file.\n"); - break; - case ENOSPC: - msg(3, 0, "No space left for output file.\n"); - break; - default: - msg(3, 0, "I/O error - cannot continue, " - "errno %d, %s\n", - err, strerror(err)); - } - } - return; - } - if (err == ENOSPC || err == ENXIO || err == 0) - msg(-2, 0, sysv3 ? "Reached end of medium on %s.\a\n" : - "End of medium on \"%s\".\a\n", mesf); - else - msg(3, 0, "I/O error on \"%s\", errno %d, %s\a\n", mesf, - err, strerror(err)); - mediacnt++; - while (mfl < 0) { - if (Iflag || Oflag) - msg(-2, 0, Mflag ? Mflag : - "Change to part %d and press " - "RETURN key. [q] ", mediacnt); - else - msg(-2, 0, sysv3 ? "If you want to go on, " - "type device/file name when ready.\n" : - "To continue, type device/file name " - "when ready.\n"); - if (tty == 0) - if ((tty = open("/dev/tty", O_RDWR)) < 0 || - fcntl(tty, F_SETFD, FD_CLOEXEC) < 0) { - cantrt: errcnt++; - msg(4, 1, "Cannot read tty.\n"); - } - i = 0; - while ((j = read(tty, &c, 1)) == 1 && c != '\n') - if (i < sizeof answer - 1) - answer[i++] = c; - if (j != 1) - goto cantrt; - answer[i] = 0; - if (Iflag || Oflag) { - if (answer[0] == '\0') - snprintf(answer, sizeof answer, Iflag ? Iflag : - Oflag); - else if (answer[0] == 'q') - exit(errcnt != 0 ? sysv3 ? 1 : 2 : 0); - else if (Iflag) - Iflag = sstrdup(answer); - else if (Oflag) - Oflag = sstrdup(answer); - } else if (answer[0] == '\0') - return; - if ((mt = action == 'i' ? open(answer, O_RDONLY) : - creat(answer, 0666)) < 0) { - if (sysv3) - msg(-2, 0, "That didn't work, " - "cannot open \"%s\"\n%s\n", - answer, strerror(errno)); - else - emsg(3, "Cannot open \"%s\"", answer); - } - else - mfl = 0; - } - mstat(); -} - -static void -mclose(void) -{ - if (action == 'o' && mt >= 0 && close(mt) < 0) { - emsg(3, "Close error on \"%s\"", - Oflag && !sysv3 ? Oflag : "output"); - errcnt++; - } -} - -/* - * Write the archive buffer to tape. - */ -static ssize_t -mwrite(int max) -{ - ssize_t wo, wt = 0; - - do { - if ((wo = write(mt, blkbuf + wt, (max?max:blksiz) - wt)) < 0) { - if (errno == EINTR) { - continue; - } else { - newmedia(errno); - if (mfl == 0) { - if (fmttype & TYP_BAR) - dump_barhdr(); - continue; - } - else - done(1); - } - } - poffs += wo; - wt += wo; - } while (wt < (max?max:blksiz)); - blocks += wt >> 9; - bytes += wt & 0777; - return wt; -} - -/* - * Buffered writes to tape. - */ -static void -bwrite(const char *data, size_t sz) -{ - size_t di; - - nwritten += sz; - while (curpos + sz > blksiz) { - di = blksiz - curpos; - sz -= di; - memcpy(&blkbuf[curpos], data, di); - mwrite(0); - data += di; - curpos = 0; - } - memcpy(&blkbuf[curpos], data, sz); - curpos += sz; -} - -/* - * Flush the tape write buffer. - */ -static void -bflush(void) -{ - if (curpos) { - memset(&blkbuf[curpos], 0, blksiz - curpos); - mwrite(fmttype==FMT_ZIP && (mtst.st_mode&S_IFMT) == S_IFREG ? - curpos : 0); - } - curpos = 0; -} - -/* - * CRC format checksum calculation with -i. - */ -static int -sum(int fd, const char *fn, struct stat *sp, char *tg) -{ - char *buf; - size_t bufsize; - uint32_t size = sp->st_size, sum = 0; - ssize_t rd; - char c; - - getbuf(&buf, &bufsize, sp->st_blksize); - /* - * Unfortunately, SVR4 cpio derivatives (as on Solaris 8 and - * UnixWare 2.1) compute the checksum of signed char values, - * whereas GNU cpio and the pax implementations of AT&T and - * BSD use unsigned chars. Since there is no 'open' standard - * for the SVR4 CRC format, the SVR4 implementation should be - * taken as a de facto reference and we thus create SVR4 type - * checksums. - */ - while ((rd = read(fd, buf, size>bufsize ? bufsize : size )) > 0) { - size -= rd; - do - sum += ((signed char *)buf)[--rd]; - while (rd); - } - if (rd < 0) { - msg(3, 0, "Error computing checksum\n"); - return 1; - } - if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { - emsg(3, "Cannot reset file after checksum"); - return 1; - } - c = tg[8]; - sprintf(tg, "%08lx", (long)sum); - tg[8] = c; - return 0; -} - -static int -rstime(const char *fn, struct stat *st, const char *which) -{ - struct utimbuf utb; - - utb.actime = st->st_atime; - utb.modtime = st->st_mtime; - if (pax != PAX_TYPE_CPIO && - (pax_preserve&(PAX_P_ATIME|PAX_P_MTIME)) != 0 && - (pax_preserve&PAX_P_EVERY) == 0) { - struct stat xst; - if (stat(fn, &xst) < 0) - goto fail; - if (pax_preserve&PAX_P_ATIME) - utb.actime = xst.st_atime; - if (pax_preserve&PAX_P_MTIME) - utb.modtime = xst.st_mtime; - } - if (utime(fn, &utb) < 0) { - fail: emsg(2, "Unable to reset %s time for \"%s\"", which, fn); - return 1; - } - return 0; -} - -/* - * Top-down splay function for inode tree. - */ -static struct islot * -isplay(ino_t ino, struct islot *x) -{ - struct islot hdr; - struct islot *leftmax, *rightmin; - struct islot *y; - - hdr.i_lln = hdr.i_rln = inull; - leftmax = rightmin = &hdr; - inull->i_ino = ino; - while (ino != x->i_ino) { - if (ino < x->i_ino) { - if (ino < x->i_lln->i_ino) { - y = x->i_lln; - x->i_lln = y->i_rln; - y->i_rln = x; - x = y; - } - if (x->i_lln == inull) - break; - rightmin->i_lln = x; - rightmin = x; - x = x->i_lln; - } else { - if (ino > x->i_rln->i_ino) { - y = x->i_rln; - x->i_rln = y->i_lln; - y->i_lln = x; - x = y; - } - if (x->i_rln == inull) - break; - leftmax->i_rln = x; - leftmax = x; - x = x->i_rln; - } - } - leftmax->i_rln = x->i_lln; - rightmin->i_lln = x->i_rln; - x->i_lln = hdr.i_rln; - x->i_rln = hdr.i_lln; - inull->i_ino = !ino; - return x; -} - -/* - * Find the inode number ino. - */ -static struct islot * -ifind(ino_t ino, struct islot **it) -{ - if (*it == NULL) - return NULL; - *it = isplay(ino, *it); - return (*it)->i_ino == ino ? *it : NULL; -} - -/* - * Put ik into the tree. - */ -static void -iput(struct islot *ik, struct islot **it) -{ - if ((*it) == NULL) { - ik->i_lln = ik->i_rln = inull; - (*it) = ik; - } else { - /* ifind() is always called before */ - /*(*it) = isplay(ik->i_ino, (*it));*/ - if (ik->i_ino < (*it)->i_ino) { - ik->i_lln = (*it)->i_lln; - ik->i_rln = (*it); - (*it)->i_lln = inull; - (*it) = ik; - } else if ((*it)->i_ino < ik->i_ino) { - ik->i_rln = (*it)->i_rln; - ik->i_lln = (*it); - (*it)->i_rln = inull; - (*it) = ik; - } - } -} - -/* - * Find the device dev or add it to the device/inode forest if not - * already present. - */ -static struct dslot * -dfind(struct dslot **root, dev_t dev) -{ - struct dslot *ds, *dp; - - for (ds = *root, dp = NULL; ds; dp = ds, ds = ds->d_nxt) - if (ds->d_dev == dev) - break; - if (ds == NULL) { - ds = scalloc(1, sizeof *ds); - ds->d_dev = dev; - if (*root == NULL) - *root = ds; - else - dp->d_nxt = ds; - } - return ds; -} - -/* - * Exit on fatal error conditions. - */ -static void -done(int i) -{ - if (tflag) - fflush(stdout); - errcnt += i; - mclose(); - if (errcnt && !sysv3) - fprintf(stderr, "%llu errors\n", errcnt); - exit(sysv3 ? 2 : 3); -} - -static char *pcopy, *pcend; -static size_t psz, pslen, pss; - -/* - * Execution for -p. - */ -static void -dopass(const char *target) -{ - struct stat st; - - if (access(target, W_OK) < 0) { - emsg(033, sysv3 ? "cannot write in <%s>" : - "Error during access() of \"%s\"", target); - if (sysv3) - done(1); - usage(); - } - if (stat(target, &st) < 0) { - emsg(023, "Error during stat() of \"%s\"", target); - done(1); - } - if ((st.st_mode&S_IFMT) != S_IFDIR) - msg(3, 1, sysv3 ? "<%s> not a directory.\n" : - "\"%s\" is not a directory\n", target); - getpath(target, &pcopy, &pcend, &psz, &pslen); - copyout(passfile); -} - -/* - * Callback for sfile(). - */ -/*ARGSUSED*/ -void -writerr(void *vp, int count, int written) -{ -} - -/* - * Copy file data of regular files with -p. - */ -static int -passdata(struct file *f, const char *tgt, int tfd) -{ - char *buf; - size_t bufsize; - ssize_t rd = 0; - - if (f->f_fd < 0) /* is a zero-sized unreadable file */ - return 0; -#ifdef __linux__ - if (f->f_st.st_size > 0) { - long long sent; - - sent = sfile(tfd, f->f_fd, f->f_st.st_mode, f->f_st.st_size); - blocks += (sent + 0777) >> 9; - if (sent == f->f_st.st_size) - return 0; - if (sent < 0) - goto rerr; - } -#endif /* __linux__ */ - getbuf(&buf, &bufsize, f->f_st.st_blksize); - while ((rd = read(f->f_fd, buf, bufsize)) > 0) { - blocks += (rd + 0777) >> 9; - if (write(tfd, buf, rd) != rd) { - emsg(3, "Cannot write \"%s\"", tgt); - return -1; - } - } - if (rd < 0) { -#ifdef __linux__ - rerr: -#endif /* __linux__ */ - emsg(3, "Cannot read \"%s\"", f->f_name); - return -1; - } - return 0; -} - -/* - * Handle a single file for -p. - */ -static int -passfile(const char *fn, struct stat *st) -{ - struct file f; - ssize_t sz; - int val; - char *newfn; - size_t newsz = 0; - - newfn = sstrdup(fn); - if (pax != PAX_TYPE_CPIO) { - if (pax_sflag && pax_sname(&newfn, &newsz) == 0) - return 0; - if (rflag && rname(&newfn, &newsz) == 0) - return 0; - } - setpath(newfn, &pcopy, &pcend, pslen, &psz, &pss); - free(newfn); - memset(&f, 0, sizeof f); - f.f_name = sstrdup(fn); - f.f_nsiz = strlen(fn) + 1; - f.f_st = *st; - f.f_fd = -1; - if ((st->st_mode&S_IFMT) == S_IFLNK) { - sz = st->st_size ? st->st_size : PATH_MAX; - f.f_lnam = smalloc(sz+1); - if ((sz = readlink(fn, f.f_lnam, sz+1)) < 0) { - emsg(3, "Cannot read symbolic link \"%s\"", fn); - free(f.f_lnam); - return 1; - } - f.f_lnam[sz] = '\0'; - } else if ((st->st_mode&S_IFMT) == S_IFREG) { - if ((f.f_fd = open(fn, O_RDONLY)) < 0) { - if (sysv3) - msg(2, 0, "Cannot open file \"%s\".\n", fn); - else - emsg(2, "Cannot open \"%s\", skipped", fn); - if (st->st_size != 0) - return 1; - } - } - val = filein(&f, passdata, pcopy); - if (f.f_lnam) - free(f.f_lnam); - free(f.f_name); - if (f.f_fd >= 0) - close(f.f_fd); - if (val <= 1 && aflag && (st->st_mode&S_IFMT) == S_IFREG) - errcnt += rstime(fn, st, "access"); - return val != 0; -} - -/* - * Processing of a single file common to -i and -p. Return value: 0 if - * successful, 1 at failure if data was read, 2 at failure if no data - * was read. - */ -static int -filein(struct file *f, int (*copydata)(struct file *, const char *, int), - char *tgt) -{ - struct stat nst; - char *temp = NULL; - size_t len; - int fd, i, j, new; - int failure = 2; - - if (fmttype == FMT_ZIP && (f->f_st.st_mode&S_IFMT) != S_IFREG && - (f->f_st.st_mode&S_IFMT) != S_IFLNK && - (f->f_csize > 0 || f->f_gflag & FG_DESC)) - skipfile(f); - if ((new = lstat(tgt, &nst)) == 0) { - if (action == 'p' && f->f_st.st_dev == nst.st_dev && - f->f_st.st_ino == nst.st_ino) { - msg(3, 0, sysv3 ? - "Attempt to pass file to self!\n" : - "Attempt to pass a file to itself.\n"); - return 1; - } - if ((f->f_st.st_mode&S_IFMT) == S_IFDIR) { - if ((nst.st_mode&S_IFMT) == S_IFDIR) - return setattr(tgt, &f->f_st); - rmdir(tgt); - } else { - if (pax_kflag) { - failure = 0; - goto skip; - } - if (uflag == 0 && f->f_st.st_mtime <= nst.st_mtime) { - if (pax == PAX_TYPE_CPIO) - msg(-1, 0, sysv3 ? - "current <%s> newer or same age\n" : - "Existing \"%s\" same age or newer\n", - tgt); - else - failure = 0; - goto skip; - } - } - } else { - if (imdir(tgt) < 0) - goto skip; - } - if (Vflag && !vflag) - prdot(0); - if ((f->f_st.st_mode&S_IFMT) != S_IFDIR && lflag) { - if (Lflag) { - char *symblink, *name; - struct stat xst; - name = f->f_name; - for (;;) { - if (lstat(name, &xst) < 0) { - emsg(3, "Cannot lstat \"%s\"", name); - if (name != f->f_name) - free(name); - goto cantlink; - } - if ((xst.st_mode&S_IFMT) != S_IFLNK) - break; - i = xst.st_size ? xst.st_size : PATH_MAX; - symblink = smalloc(i+1); - if ((j = readlink(name, symblink, i)) < 0) { - emsg(3, "Cannot read symbolic link " - "\"%s\"", name); - free(symblink); - if (name != f->f_name) - free(name); - goto cantlink; - } - symblink[j] = '\0'; - symblink = joinpath(name, symblink); - if (name != f->f_name) - free(name); - name = symblink; - } - if (linkunlink(name, tgt) == 0) { - if (vflag) - fprintf(stderr, "%s\n", tgt); - if (name != f->f_name) - free(name); - return 0; - } - if (name != f->f_name) - free(name); - } else if (linkunlink(f->f_name, tgt) == 0) { - if (vflag) - fprintf(stderr, "%s\n", tgt); - return 0; - } -cantlink: errcnt += 1; - } - if ((f->f_st.st_mode&S_IFMT) != S_IFDIR && f->f_st.st_nlink > 1 && - (fmttype & TYP_CPIO || fmttype == FMT_ZIP - || action == 'p') && - (i = canlink(tgt, &f->f_st, 1)) != 0) { - if (i < 0) - goto skip; - /* - * At this point, hard links in SVR4 cpio format have - * been reordered and data is associated with the first - * link; remaining links have st_size == 0 so don't - * overwrite the data here. - */ - if (fmttype & TYP_NCPIO && f->f_st.st_size == 0 || - (f->f_st.st_mode&S_IFMT) != S_IFREG) { - if (vflag) - fprintf(stderr, "%s\n", f->f_name); - return 0; - } - /* - * Make sure we can creat() this file later. - */ - chmod(tgt, 0600); - } else if (fmttype & TYP_TAR && f->f_st.st_nlink > 1) { - if (linkunlink(f->f_lnam, f->f_name) == 0) { - if (fmttype & TYP_USTAR && f->f_st.st_size > 0) - chmod(tgt, 0600); - else { - if (vflag) - fprintf(stderr, "%s\n", f->f_name); - return 0; - } - } else { - goto restore; - } - } else if (new == 0 && (f->f_st.st_mode&S_IFMT) != S_IFDIR) { - len = strlen(tgt); - temp = smalloc(len + 7); - strcpy(temp, tgt); - strcpy(&temp[len], "XXXXXX"); - if ((fd = mkstemp(temp)) < 0 || close(fd) < 0) { - emsg(3, "Cannot create temporary file"); - if (fd < 0) { - free(temp); - temp = NULL; - } - goto skip; - } - cur_ofile = tgt; - cur_tfile = temp; - if (rename(tgt, temp) < 0) { - emsg(3, "Cannot rename current \"%s\"", tgt); - tunlink(&temp); - goto skip; - } - } - switch (f->f_st.st_mode & S_IFMT) { - case S_IFDIR: - if (!dflag) { - if (action == 'p') - msg(-1, 0, "Use -d option to copy \"%s\"\n", - f->f_name); - goto restore; - } - if (mkdir(tgt, 0777) < 0 && errno != EEXIST) { - emsg(-1, "Cannot create directory \"%s\"", tgt); - goto restore; - } - break; - case S_IFLNK: - if (symlink(f->f_lnam, tgt) < 0) { - emsg(3, "Cannot create \"%s\"", tgt); - goto restore; - } - break; - case S_IFREG: - if (temp && f->f_fd < 0) - goto restore; - cur_ofile = tgt; - if ((fd = (compressed_bar ? zcreat : creat)(tgt, - f->f_st.st_mode & 0777)) < 0) { - emsg(3, "Cannot create \"%s\"", tgt); - goto skip; - } - failure = 1; - if (copydata(f, tgt, fd) != 0) { - close(fd); - goto restore; - } - if ((compressed_bar ? zclose : close)(fd) < 0) { - emsg(3, "Close error on \"%s\"", tgt); - goto restore; - } - break; - case S_IFBLK: - case S_IFCHR: - case S_IFIFO: - case S_IFNAM: - case S_IFNWK: - if (mknod(tgt, f->f_st.st_mode&(S_IFMT|0777), - f->f_st.st_rdev) < 0) { - emsg(3, "Cannot mknod() \"%s\"", tgt); - goto restore; - } - break; - default: - msg(-1, 0, "Impossible file type\n"); - goto skip; - } - if (vflag) - fprintf(stderr, "%s\n", f->f_name); - tunlink(&temp); - return setattr(tgt, &f->f_st); -skip: if (copydata == indata) - skipdata(f, copydata); -restore: - if (temp) { - if (rename(temp, tgt) < 0) { - emsg(3, "Cannot recover original version of \"%s\"", - tgt); - tunlink(&temp); - } else - fprintf(stderr, "Restoring existing \"%s\"\n", tgt); - cur_tfile = cur_ofile = NULL; - } - return failure; -} - -static int -linkunlink(const char *path1, const char *path2) -{ - int twice = 0; - - do { - if (link(path1, path2) == 0) { - if (vflag && pax == PAX_TYPE_CPIO) - printf("%s linked to %s\n", path1, path2); - return 0; - } - if (errno == EEXIST && unlink(path2) < 0) - emsg(3, sysv3 ? "cannot unlink <%s>" : - "Error cannot unlink \"%s\"", path2); - } while (twice++ == 0); - emsg(023, sysv3 ? "Cannot link <%s> & <%s>" : - "Cannot link \"%s\" and \"%s\"", path1, path2); - return -1; -} - -static void -tunlink(char **fn) -{ - cur_tfile = cur_ofile = NULL; - if (*fn) { - if (unlink(*fn) < 0) - emsg(3, "Cannot unlink() temp file \"%s\"", *fn); - free(*fn); - *fn = NULL; - } -} - -/* - * For -it[v] option. - */ -static int -filet(struct file *f, int (*copydata)(struct file *, const char *, int)) -{ - if (vflag && ( - (fmttype == FMT_ZIP && f->f_gflag & FG_DESC && - (f->f_cmethod == C_DEFLATED || f->f_cmethod == C_ENHDEFLD) && - (f->f_gflag & FG_CRYPT) == 0) || - f->f_Kbase)) { - /* - * Need to read zip data descriptor located after the - * file contents in order to know the file size. Or - * need to read second header of -K archive. - */ - int i; - i = skipdata(f, copydata); - filev(f); - return i; - } - if (vflag) - filev(f); - else - puts(f->f_name); - return skipdata(f, copydata); -} - -static void -filev(struct file *f) -{ - const char *cp; - long c; - - if (pax == PAX_TYPE_CPIO && fmttype & TYP_TAR && f->f_st.st_nlink > 1) - printf("%s linked to %s\n", f->f_lnam, f->f_name); - if (sysv3) - printf("%-6o", (int)f->f_st.st_mode&(07777|S_IFMT)); - else { - c = typec(&f->f_st); - putchar(c); - permbits(f->f_st.st_mode); - } - if (fmttype == FMT_ZIP && vflag > 1) - zipinfo(f); - else { - if (sysv3 == 0) - printf(" %3d", fmttype&TYP_TAR && - (f->f_st.st_mode&S_IFMT) == S_IFLNK ? - 2 : (int)f->f_st.st_nlink); - if ((cp = getuser(f->f_st.st_uid)) != NULL) - printf(sysv3 ? " %-6s" : " %-8s", cp); - else - printf(sysv3 ? " %-6lu" : " %-8lu", - (long)f->f_st.st_uid); - if (sysv3 == 0) { - if ((cp = getgroup(f->f_st.st_gid)) != NULL) - printf(" %-8s", cp); - else - printf(" %-8lu", (long)f->f_st.st_gid); - } - } - if (sysv3 || (f->f_st.st_mode&S_IFMT)!=S_IFCHR && - (f->f_st.st_mode&S_IFMT)!=S_IFBLK && - (f->f_st.st_mode&S_IFMT)!=S_IFNAM && - (f->f_st.st_mode&S_IFMT)!=S_IFNWK) - printf(pax != PAX_TYPE_CPIO ? "%8llu" : - sysv3 ? "%7llu" : " %-7llu", f->f_dsize); - else - printf(" %3lu,%3lu", (long)f->f_rmajor, (long)f->f_rminor); - prtime(f->f_st.st_mtime); - printf("%s", f->f_name); - if ((f->f_st.st_mode&S_IFMT) == S_IFLNK) - printf(" -> %s", f->f_lnam); - if (pax != PAX_TYPE_CPIO && (f->f_st.st_mode&S_IFMT) != S_IFDIR && - f->f_st.st_nlink>1) { - if (fmttype & TYP_TAR) - printf(" == %s", f->f_lnam); - else - canlink(f->f_name, &f->f_st, 0); - } - putchar('\n'); -} - -static int -typec(struct stat *st) -{ - switch (st->st_mode&S_IFMT) { - case S_IFREG: - return '-'; - case S_IFDIR: - return 'd'; - case S_IFLNK: - return 'l'; - case S_IFCHR: - return 'c'; - case S_IFBLK: - return 'b'; - case S_IFIFO: - return 'p'; - case S_IFNWK: - return 'n'; - case S_IFNAM: - switch (st->st_rdev) { - case S_INSEM: - return 's'; - case S_INSHD: - return 'm'; - } - /*FALLTHRU*/ - default: - msg(-1, 0, "Impossible file type\n"); - errcnt++; - return '-'; - } -} - -static void -permbits(mode_t mode) -{ - mode_t mask = 0700, shft = 6; - - while (mask) { - if (((mode & mask) >> shft) & 04) - putchar('r'); - else - putchar('-'); - if (((mode & mask) >> shft) & 02) - putchar('w'); - else - putchar('-'); - if (mask == 0700 && mode & 04000) - putchar('s'); - else if (mask == 0070 && (mode & 02010) == 02010) - putchar('s'); - else if (mask == 0070 && mode & 02000) - putchar('l'); - else if (mask == 0007 && mode & 01000) - putchar('t'); - else if (((mode & mask) >> shft) & 01) - putchar('x'); - else - putchar('-'); - mask >>= 3; - shft -= 3; - } -} - -static void -prtime_cpio(time_t t) -{ - char b[30]; - - strftime(b, sizeof b, sysv3 ? "%b %e %H:%M:%S %Y" : "%b %e %H:%M %Y", - localtime(&t)); - printf(sysv3 ? " %s " : " %s, ", b); -} - -/* - * Prepare path to add names of files below it later. - */ -static void -getpath(const char *path, char **file, char **filend, size_t *sz, size_t *slen) -{ - *sz = 14 + strlen(path) + 2; - *file = smalloc(*sz); - *filend = *file; - if (path[0] == '/' && path[1] == '\0') - *(*filend)++ = '/'; - else { - const char *cp = path; - while ((*(*filend)++ = *cp++) != '\0'); - (*filend)[-1] = '/'; - } - *slen = *filend - *file; -} - -/* - * Concatenate base (prepared with getpath()) and file. - */ -static void -setpath(const char *base, char **file, char **filend, - size_t slen, size_t *sz, size_t *ss) -{ - if (slen + (*ss = strlen(base)) >= *sz) { - *sz += slen + *ss + 15; - *file = srealloc(*file, *sz); - *filend = &(*file)[slen]; - } - strcpy(*filend, base); -} - -/* - * Create intermediate directories with -m. - */ -static int -imdir(char *fn) -{ - struct stat st; - char *cp; - int dfl = dflag != 0; - - for (cp = fn; *cp == '/'; cp++); - do { - while (*cp && *cp != '/') - cp++; - if (*cp == '/') { - *cp = '\0'; - if (stat(fn, &st) < 0) { - if (dfl) { - if (mkdir(fn, 0777) < 0) { - *cp = '/'; - emsg(-1, "Cannot create " - "directory for \"%s\"", - fn); - return -1; - } - } else { - msg(-1, 0, sysv3 ? - "missing 'd' option\n" : - "Missing -d option\n"); - dfl = 2; - } - } - *cp = '/'; - while (*cp == '/') - cp++; - } - } while (*cp); - return 0; -} - -/* - * Set file attributes and make sure that suid/sgid bits are only restored - * if the owner is the same as on the tape. - */ -static int -setattr(const char *fn, struct stat *st) -{ - mode_t mode = st->st_mode & 07777; - uid_t uid = Rflag ? Ruid : myuid; - gid_t gid = Rflag ? Rgid : mygid; - - if ((pax != PAX_TYPE_CPIO || myuid == 0) && - (pax == PAX_TYPE_CPIO || - pax_preserve&(PAX_P_OWNER|PAX_P_EVERY))) { - if (setowner(fn, st) != 0) - return 1; - } - if (pax != PAX_TYPE_CPIO && - (pax_preserve&(PAX_P_OWNER|PAX_P_EVERY)) == 0) - mode &= ~(mode_t)(S_ISUID|S_ISGID); - if (myuid != 0 || Rflag) { - if (st->st_uid != uid || st->st_gid != gid) { - mode &= ~(mode_t)S_ISUID; - if ((st->st_mode&S_IFMT) != S_IFDIR && mode & 0010) - mode &= ~(mode_t)S_ISGID; - if ((st->st_mode&S_IFMT) == S_IFDIR && st->st_gid!=gid) - mode &= ~(mode_t)S_ISGID; - } - } - if ((st->st_mode&S_IFMT) == S_IFLNK) - return 0; - if (hp_Uflag) - mode &= ~umsk|S_IFMT; - if (pax != PAX_TYPE_CPIO && - (pax_preserve&(PAX_P_MODE|PAX_P_OWNER|PAX_P_EVERY))==0) - mode &= 01777|S_IFMT; - if ((pax == PAX_TYPE_CPIO || pax_preserve&(PAX_P_MODE|PAX_P_EVERY)) && - chmod(fn, mode) < 0) { - emsg(2, "Cannot chmod() \"%s\"", fn); - return 1; - } - if (pax != PAX_TYPE_CPIO ? - (pax_preserve&(PAX_P_ATIME|PAX_P_MTIME|PAX_P_EVERY)) != - (PAX_P_ATIME|PAX_P_MTIME) : mflag) - return rstime(fn, st, "modification"); - else - return 0; -} - -static int -setowner(const char *fn, struct stat *st) -{ - uid_t uid = Rflag ? Ruid : myuid ? myuid : st->st_uid; - gid_t gid = Rflag ? Rgid : st->st_gid; - - if (((st->st_mode&S_IFMT)==S_IFLNK?lchown:chown)(fn, uid, gid) < 0) { - emsg(2, "Cannot chown() \"%s\"", fn); - return 1; - } - if (pax >= PAX_TYPE_PAX2001 && myuid && myuid != st->st_uid && - pax_preserve & (PAX_P_OWNER|PAX_P_EVERY)) { - /* - * Do not even try to preserve user ownership in this case. - * It would either fail, or, without _POSIX_CHOWN_RESTRICTED, - * leave us with a file we do not own and which we thus could - * not chmod() later. - */ - errno = EPERM; - emsg(2, "Cannot chown() \"%s\"", fn); - return 1; - } - return 0; -} - -/* - * For -i and -p: Check if device/inode have been created already and - * if so, link path (or print the link name). - */ -static int -canlink(const char *path, struct stat *st, int really) -{ - struct dslot *ds; - struct islot *ip; - - ds = dfind(&devices, st->st_dev); - if ((ip = ifind(st->st_ino, &ds->d_isl)) == NULL || - ip->i_name == NULL) { - if (ip == NULL) { - ip = scalloc(1, sizeof *ip); - ip->i_ino = st->st_ino; - if ((fmttype&(TYP_NCPIO|TYP_TAR)) == 0) - ip->i_nlk = st->st_nlink; - iput(ip, &ds->d_isl); - } - ip->i_name = sstrdup(path); - } else { - if ((fmttype&(TYP_NCPIO|TYP_TAR)) == 0) { - /* - * If an archive inode has more links than given in - * st_nlink, write a new disk inode. See the comments - * to storelink() for the rationale. - */ - if (--ip->i_nlk == 0) { - free(ip->i_name); - ip->i_name = sstrdup(path); - ip->i_nlk = st->st_nlink; - return 0; - } - } - if (really) { - /* - * If there was file data before the last link with - * SVR4 cpio formats, do not create a hard link. - */ - if (fmttype & TYP_NCPIO && ip->i_nlk == 0) - return 0; - if (linkunlink(ip->i_name, path) == 0) - return 1; - else - return -1; - } else { - printf(" == %s", ip->i_name); - return 1; - } - } - return 0; -} - -/* - * Execution for -i. - */ -static void -doinp(void) -{ - union bincpio bc; - struct file f; - int n; - - memset(&f, 0, sizeof f); - if (Eflag) - patfile(); - if (Iflag) { - if ((mt = open(Iflag, O_RDONLY)) < 0) { - if (sysv3) { - emsg(3, "Cannot open <%s> for input.", Iflag); - done(1); - } - else - msg(3, -2, "Cannot open \"%s\" for input\n", - Iflag); - } - } else - mt = dup(0); - mstat(); - blkbuf = svalloc(blksiz, 1); - if ((n = mread()) == 0) - unexeoa(); - else if (n < 0) { - emsg(3, "Read error on \"%s\"", - Iflag && !sysv3 ? Iflag : "input"); - done(1); - } - if (kflag == 0 && sixflag == 0) - fmttype = FMT_NONE; - if (fmttype == FMT_NONE) - whathdr(); - else - formatforced = 1; - while (readhdr(&f, &bc) == 0) { - if (fmttype & TYP_NCPIO && f.f_st.st_nlink > 1 && - (f.f_st.st_mode&S_IFMT) != S_IFDIR) { - if (f.f_st.st_size != 0) - flushlinks(&f); - else - storelink(&f); - } else - inpone(&f, 1); - f.f_Kbase = f.f_Krest = f.f_Ksize = 0; - f.f_oflag = 0; - } - if (fmttype & TYP_NCPIO) - flushrest(f.f_pad); -} - -/* - * SVR4 cpio link handling with -i; called if we assume that more links - * to this file will follow. - */ -static void -storelink(struct file *f) -{ - struct dslot *ds; - struct islot *ip; - struct ilink *il, *iz; - - ds = dfind(&devices, f->f_st.st_dev); - if ((ip = ifind(f->f_st.st_ino, &ds->d_isl)) == NULL) { - ip = scalloc(1, sizeof *ip); - ip->i_ino = f->f_st.st_ino; - ip->i_nlk = f->f_st.st_nlink; - ip->i_st = smalloc(sizeof *ip->i_st); - *ip->i_st = f->f_st; - iput(ip, &ds->d_isl); - } else { - if (ip->i_nlk == 0) { - /* - * More links to an inode than given in the first - * st_nlink occurence are found within this archive. - * This happens if -L was specified and soft links - * point to a file with multiple hard links. We do - * the same as SVR4 cpio implementations here and - * associate these links with a new inode, since it - * is related to the way a file with a single hard - * link but referenced by soft links is unpacked. - */ - ip->i_nlk = f->f_st.st_nlink; - if (ip->i_name) - free(ip->i_name); - ip->i_name = NULL; - ip->i_st = smalloc(sizeof *ip->i_st); - *ip->i_st = f->f_st; - } else if (ip->i_nlk <= 2) { - /* - * We get here if - * - a file with multiple links is empty; - * - a broken implementation has stored file data - * before the last link; - * - a linked file has been added to the archive later - * again (does not happen with our implementation). - */ - flushnode(ip, f); - return; - } else - ip->i_nlk--; - } - for (il = ip->i_lnk, iz = NULL; il; il = il->l_nxt) - iz = il; - il = scalloc(1, sizeof *il); - il->l_siz = strlen(f->f_name) + 1; - il->l_nam = smalloc(il->l_siz); - strcpy(il->l_nam, f->f_name); - if (iz) - iz->l_nxt = il; - else - ip->i_lnk = il; -} - -/* - * Flush all links of a file with SVR4 cpio format and -i. - */ -static void -flushlinks(struct file *f) -{ - struct dslot *ds; - struct islot *ip; - - ds = dfind(&devices, f->f_st.st_dev); - ip = ifind(f->f_st.st_ino, &ds->d_isl); - flushnode(ip, f); -} - -/* - * Data of a multi-linked file shall be transferred now for SVR4 cpio - * format and -i. - */ -static void -flushnode(struct islot *ip, struct file *f) -{ - struct file nf; - struct ilink *il, *iz; - - f->f_dsize = f->f_st.st_size; - if (ip && ip->i_nlk > 0) { - /* - * Write out the file data with the first link the user - * wants to be extracted, but show the same display size - * for all links. - */ - for (il = ip->i_lnk, iz = NULL; il; - iz = il, il = il->l_nxt, iz ? free(iz), 0 : 0) { - memset(&nf, 0, sizeof nf); - nf.f_name = il->l_nam; - nf.f_nsiz = il->l_siz; - nf.f_st = f->f_st; - nf.f_chksum = f->f_chksum; - nf.f_pad = f->f_pad; - nf.f_dsize = f->f_dsize; - if (inpone(&nf, 0) == 0) { - f->f_chksum = 0; - f->f_st.st_size = 0; - } - free(il->l_nam); - } - ip->i_lnk = NULL; - if (ip->i_st) - free(ip->i_st); - ip->i_st = NULL; - } - if (f->f_name) - inpone(f, 1); - if (ip) { - if (ip->i_nlk <= 2 && ip->i_name) { - free(ip->i_name); - ip->i_name = NULL; - } - ip->i_nlk = 0; - } -} - -/* - * This writes all remaining multiply linked files, i. e. those with - * st_size == 0 and st_nlink > number of links within the archive. - */ -static void -flushrest(int pad) -{ - struct dslot *ds; - - for (ds = devices; ds; ds = ds->d_nxt) - if (ds->d_isl != NULL) - flushtree(ds->d_isl, pad); -} - -static void -flushtree(struct islot *ip, int pad) -{ - struct file f; - - if (ip == inull) - return; - flushtree(ip->i_lln, pad); - flushtree(ip->i_rln, pad); - if (ip->i_nlk > 0 && ip->i_st) { - memset(&f, 0, sizeof f); - f.f_st = *ip->i_st; - f.f_pad = pad; - flushnode(ip, &f); - } -} - -/* - * See if the user wants to have this file with -i, and extract it or - * skip its data on the tape. - */ -static int -inpone(struct file *f, int shallskip) -{ - struct glist *gp = NULL, *gb = NULL; - int val = -1, selected = 0; - - if ((patterns == NULL || (gp = want(f, &gb)) != NULL ^ fflag) && - pax_track(f->f_name, f->f_st.st_mtime)) { - selected = 1; - if ((pax_sflag == 0 || pax_sname(&f->f_name, &f->f_nsiz)) && - (rflag == 0 || rname(&f->f_name, &f->f_nsiz))) { - errcnt += infile(f); - val = 0; - } - } else if (shallskip) - errcnt += skipfile(f); - if (gp != NULL && selected) { - gp->g_gotcha = 1; - if (gp->g_nxt && gp->g_nxt->g_art) - gp->g_nxt->g_gotcha = 1; - else if (gp->g_art && gb) - gb->g_gotcha = 1; - } - return val; -} - -/* - * Read the header for a file with -i. Return values: 0 okay, 1 end of - * archive, -1 failure. - */ -static int -readhdr(struct file *f, union bincpio *bp) -{ - long namlen, l1, l2, rd, hsz; - static long attempts; - long long skipped = 0; - - if (fmttype & TYP_TAR) { - if (f->f_name) - f->f_name[0] = '\0'; - if (f->f_lnam) - f->f_lnam[0] = '\0'; - } - paxrec = globrec; -retry: f->f_st = globst; -retry2: if (fmttype & TYP_BINARY) { - hsz = SIZEOF_hdr_cpio; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if ((fmttype&TYP_BE ? pbe16(bp->Hdr.c_magic) : - ple16(bp->Hdr.c_magic)) != mag_bin) - goto badhdr; - if (fmttype & TYP_BE) { - f->f_st.st_dev = pbe16(bp->Hdr.c_dev)&0177777; - f->f_st.st_ino = pbe16(bp->Hdr.c_ino)&0177777; - f->f_st.st_mode = pbe16(bp->Hdr.c_mode); - } else { - f->f_st.st_dev = ple16(bp->Hdr.c_dev)&0177777; - f->f_st.st_ino = ple16(bp->Hdr.c_ino)&0177777; - f->f_st.st_mode = ple16(bp->Hdr.c_mode); - } - if (sixflag) { - /* - * relevant Unix 6th Edition style mode bits - * (according to /usr/sys/inode.h, untested:) - * - * 060000 IFMT type of file - * 040000 IFDIR directory - * 020000 IFCHR character special - * 060000 IFBLK block special, 0 is regular - * 007777 permission bits as today - */ - f->f_st.st_mode &= 067777; - if ((f->f_st.st_mode & 060000) == 0) - f->f_st.st_mode |= S_IFREG; - } - if (fmttype & TYP_BE) { - f->f_st.st_uid = pbe16(bp->Hdr.c_uid)&0177777; - f->f_st.st_gid = pbe16(bp->Hdr.c_gid)&0177777; - f->f_st.st_nlink = pbe16(bp->Hdr.c_nlink)&0177777; - f->f_st.st_mtime = pbe32(bp->Hdr.c_mtime); - f->f_st.st_rdev = pbe16(bp->Hdr.c_rdev); - namlen = pbe16(bp->Hdr.c_namesize); - f->f_st.st_size = pbe32(bp->Hdr.c_filesize)&0xFFFFFFFF; - } else { - f->f_st.st_uid = ple16(bp->Hdr.c_uid)&0177777; - f->f_st.st_gid = ple16(bp->Hdr.c_gid)&0177777; - f->f_st.st_nlink = ple16(bp->Hdr.c_nlink)&0177777; - f->f_st.st_mtime = pme32(bp->Hdr.c_mtime); - f->f_st.st_rdev = ple16(bp->Hdr.c_rdev); - namlen = ple16(bp->Hdr.c_namesize); - f->f_st.st_size = pme32(bp->Hdr.c_filesize)&0xFFFFFFFF; - } - f->f_rmajor = major(f->f_st.st_rdev); - f->f_rminor = minor(f->f_st.st_rdev); - if ((f->f_st.st_rdev&0xFFFF) == 0xFFFF && - f->f_st.st_size > 0 && - ((f->f_st.st_mode&S_IFMT) == S_IFBLK || - (f->f_st.st_mode&S_IFMT) == S_IFCHR && - (!formatforced || fmttype & TYP_SGI))) { - fmttype |= TYP_SGI; - f->f_rmajor = (f->f_st.st_size&0xFFFC0000)>>18; - f->f_rminor = f->f_st.st_size&0x0003FFFF; - f->f_st.st_rdev = makedev(f->f_rmajor, f->f_rminor); - f->f_st.st_size = 0; - } - if ((f->f_st.st_mode&S_IFMT) == S_IFREG && - f->f_st.st_size&0x80000000 && - (!formatforced || fmttype & TYP_SGI)) { - fmttype |= TYP_SGI; - f->f_Ksize = f->f_st.st_size&0xFFFFFFFF; - f->f_Kbase = (0x100000000LL-f->f_st.st_size) * - 0x80000000; - f->f_st.st_size = 0; - } - f->f_pad = 2; - rd = SIZEOF_hdr_cpio; - } else if (fmttype == FMT_ODC) { - hsz = SIZEOF_c_hdr; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if(memcmp(bp->Cdr.c_magic, mag_odc, sizeof mag_odc)) - goto badhdr; - f->f_st.st_dev = rdoct(bp->Cdr.c_dev, 6); - f->f_st.st_ino = rdoct(bp->Cdr.c_ino, 6); - f->f_st.st_mode = rdoct(bp->Cdr.c_mode, 6); - f->f_st.st_uid = rdoct(bp->Cdr.c_uid, 6); - f->f_st.st_gid = rdoct(bp->Cdr.c_gid, 6); - f->f_st.st_nlink = rdoct(bp->Cdr.c_nlink, 6); - f->f_st.st_rdev = rdoct(bp->Cdr.c_rdev, 6); - f->f_rmajor = major(f->f_st.st_rdev); - f->f_rminor = minor(f->f_st.st_rdev); - f->f_st.st_mtime = rdoct(bp->Cdr.c_mtime, 11); - namlen = rdoct(bp->Cdr.c_namesz, 6); - f->f_st.st_size = rdoct(bp->Cdr.c_filesz, 11); - f->f_pad = 1; - rd = SIZEOF_c_hdr; - } else if (fmttype == FMT_DEC) { - hsz = SIZEOF_d_hdr; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if(memcmp(bp->Ddr.d_magic, mag_odc, sizeof mag_odc)) - goto badhdr; - f->f_st.st_dev = rdoct(bp->Ddr.d_dev, 6); - f->f_st.st_ino = rdoct(bp->Ddr.d_ino, 6); - f->f_st.st_mode = rdoct(bp->Ddr.d_mode, 6); - f->f_st.st_uid = rdoct(bp->Ddr.d_uid, 6); - f->f_st.st_gid = rdoct(bp->Ddr.d_gid, 6); - f->f_st.st_nlink = rdoct(bp->Ddr.d_nlink, 6); - f->f_rmajor = rdoct(bp->Ddr.d_rmaj, 8); - f->f_rminor = rdoct(bp->Ddr.d_rmin, 8); - f->f_st.st_rdev = makedev(f->f_rmajor, f->f_rminor); - f->f_st.st_mtime = rdoct(bp->Ddr.d_mtime, 11); - namlen = rdoct(bp->Ddr.d_namesz, 6); - f->f_st.st_size = rdoct(bp->Ddr.d_filesz, 11); - f->f_pad = 1; - rd = SIZEOF_d_hdr; - } else if (fmttype & TYP_NCPIO) { - hsz = SIZEOF_Exp_cpio_hdr; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if (memcmp(bp->Edr.E_magic, mag_asc, sizeof mag_asc) && - memcmp(bp->Edr.E_magic, mag_crc, sizeof mag_crc)) - goto badhdr; - f->f_st.st_ino = rdhex(bp->Edr.E_ino, 8); - f->f_st.st_mode = rdhex(bp->Edr.E_mode, 8); - f->f_st.st_uid = rdhex(bp->Edr.E_uid, 8); - f->f_st.st_gid = rdhex(bp->Edr.E_gid, 8); - f->f_st.st_nlink = rdhex(bp->Edr.E_nlink, 8); - f->f_st.st_mtime = rdhex(bp->Edr.E_mtime, 8); - f->f_st.st_size = rdhex(bp->Edr.E_filesize, 8); - l1 = rdhex(bp->Edr.E_maj, 8); - l2 = rdhex(bp->Edr.E_min, 8); - f->f_st.st_dev = makedev(l1, l2); - f->f_rmajor = rdhex(bp->Edr.E_rmaj, 8); - f->f_rminor = rdhex(bp->Edr.E_rmin, 8); - f->f_st.st_rdev = makedev(f->f_rmajor, f->f_rminor); - namlen = rdhex(bp->Edr.E_namesize, 8); - f->f_chksum = rdhex(bp->Edr.E_chksum, 8); - f->f_pad = 4; - rd = SIZEOF_Exp_cpio_hdr; - } else if (fmttype & TYP_CRAY) { - int diff5 = fmttype==FMT_CRAY5 ? CRAY_PARAMSZ : 0; - hsz = SIZEOF_cray_hdr - diff5; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if (pbe64(bp->Crayhdr.C_magic) != mag_bin) - goto badhdr; - f->f_st.st_dev = pbe64(bp->Crayhdr.C_dev); - f->f_st.st_ino = pbe64(bp->Crayhdr.C_ino); - f->f_st.st_mode = pbe64(bp->Crayhdr.C_mode); - /* - * Some of the S_IFMT bits on Cray UNICOS 9 differ from - * the common Unix values, namely: - * - * S_IFLNK 0130000 symbolic link - * S_IFOFD 0110000 off line, with data - * S_IFOFL 0120000 off line, with no data - * - * We treat the latter ones as regular files. - */ - if ((f->f_st.st_mode&S_IFMT) == 0130000) - f->f_st.st_mode = f->f_st.st_mode&07777|S_IFLNK; - else if ((f->f_st.st_mode&S_IFMT) == 0110000 || - (f->f_st.st_mode&S_IFMT) == 0120000) - f->f_st.st_mode = f->f_st.st_mode&07777|S_IFREG; - f->f_st.st_uid = pbe64(bp->Crayhdr.C_uid); - f->f_st.st_gid = pbe64(bp->Crayhdr.C_gid); - f->f_st.st_nlink = pbe64(bp->Crayhdr.C_nlink); - f->f_st.st_mtime = pbe64(bp->Crayhdr.C_mtime - diff5); - f->f_st.st_rdev = pbe64(bp->Crayhdr.C_rdev); - f->f_rmajor = major(f->f_st.st_rdev); - f->f_rminor = minor(f->f_st.st_rdev); - f->f_st.st_size = pbe64(bp->Crayhdr.C_filesize - diff5); - namlen = pbe64(bp->Crayhdr.C_namesize - diff5); - f->f_pad = 1; - rd = SIZEOF_cray_hdr - diff5; - } else if (fmttype & TYP_BAR) { - hsz = 512; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if (bp->data[SIZEOF_bar_header] == '\0') { - if (kflag && !allzero(bp->data, hsz)) - goto badhdr; - return 1; - } - if (trdsum(bp) != 0 && kflag == 0) - goto badhdr; - bp->data[512] = bp->data[513] = '\0'; - if (f->f_name == NULL || f->f_name[0] == '\0') { - if (f->f_nsiz < 512) { - free(f->f_name); - f->f_name = smalloc(f->f_nsiz = 512); - } - strcpy(f->f_name, &bp->data[SIZEOF_bar_header]); - } - namlen = strlen(f->f_name) + 1; - f->f_st.st_mode = rdoct(bp->Bdr.b_mode, 8); - f->f_st.st_uid = rdoct(bp->Bdr.b_uid, 8); - f->f_st.st_gid = rdoct(bp->Bdr.b_gid, 8); - f->f_st.st_size = rdoct(bp->Bdr.b_size, 12); - f->f_st.st_mtime = rdoct(bp->Bdr.b_mtime, 12); - f->f_st.st_rdev = rdoct(bp->Bdr.b_rdev, 8); - f->f_rmajor = major(f->f_st.st_rdev); - f->f_rminor = minor(f->f_st.st_rdev); - switch (bp->Bdr.b_linkflag) { - case '0': - f->f_st.st_mode &= 07777; - if (f->f_name[namlen-2] == '/') - f->f_st.st_mode |= S_IFDIR; - else - f->f_st.st_mode |= S_IFREG; - break; - case '1': - if (f->f_lnam == NULL || f->f_lnam[0] == '\0') - blinkof(bp->data, f, namlen); - f->f_st.st_nlink = 2; - if ((f->f_st.st_mode&S_IFMT) == 0) - f->f_st.st_mode |= S_IFREG; - break; - case '2': - if (f->f_lnam == NULL || f->f_lnam[0] == '\0') - blinkof(bp->data, f, namlen); - f->f_st.st_mode &= 07777; - f->f_st.st_mode |= S_IFLNK; - } - f->f_pad = 512; - rd = 512; - } else if (fmttype & TYP_TAR) { - hsz = 512; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if (bp->Tdr.t_name[0] == '\0') { - if (kflag && !allzero(bp->data, hsz)) - goto badhdr; - return 1; - } - if (fmttype == FMT_GNUTAR) { - if (memcmp(bp->Tdr.t_magic, mag_gnutar, 8)) - goto badhdr; - } else if (fmttype & TYP_USTAR) { - if (memcmp(bp->Tdr.t_magic, mag_ustar, 6)) - goto badhdr; - } - if (trdsum(bp) != 0 && kflag == 0) - goto badhdr; - if ((fmttype & TYP_PAX) == 0 && (fmttype == FMT_GNUTAR || - strcmp(bp->Tdr.t_name, "././@LongLink") == 0)) { - switch (bp->Tdr.t_linkflag) { - case 'L': - if (readgnuname(&f->f_name, &f->f_nsiz, - rdoct(bp->Tdr.t_size, 12)) < 0) - goto badhdr; - goto retry; - case 'K': - if (readgnuname(&f->f_lnam, &f->f_lsiz, - rdoct(bp->Tdr.t_size, 12)) < 0) - goto badhdr; - goto retry; - } - } - if (fmttype & TYP_USTAR && fmttype != FMT_GNUTAR) { - switch (bp->Tdr.t_linkflag) { - case 'g': - case 'x': - if (formatforced && fmttype != FMT_PAX) - break; - fmttype = FMT_PAX; - tgetpax(&bp->Tdr, f); - goto retry2; - case 'X': - if (formatforced && fmttype != FMT_SUN) - break; - fmttype = FMT_SUN; - tgetpax(&bp->Tdr, f); - goto retry2; - } - } - if (f->f_name == NULL || f->f_name[0] == '\0') { - if (f->f_nsiz < TNAMSIZ+TPFXSIZ+2) { - free(f->f_name); - f->f_name= smalloc(f->f_nsiz=TNAMSIZ+TPFXSIZ+2); - } - tnameof(&bp->Tdr, f->f_name); - } - namlen = strlen(f->f_name) + 1; - f->f_st.st_mode = rdoct(bp->Tdr.t_mode, 8) & 07777; - if (paxrec & PR_UID) - /*EMPTY*/; - else if (fmttype == FMT_GNUTAR && bp->Tdr.t_uid[0] & 0200) - f->f_st.st_uid = pbe64(bp->Tdr.t_uid) & - 0x7FFFFFFFFFFFFFFFLL; - else - f->f_st.st_uid = rdoct(bp->Tdr.t_uid, 8); - if (paxrec & PR_GID) - /*EMPTY*/; - else if (fmttype == FMT_GNUTAR && bp->Tdr.t_gid[0] & 0200) - f->f_st.st_gid = pbe64(bp->Tdr.t_gid) & - 0x7FFFFFFFFFFFFFFFLL; - else - f->f_st.st_gid = rdoct(bp->Tdr.t_gid, 8); - if (paxrec & PR_SIZE) - /*EMPTY*/; - else if (fmttype == FMT_GNUTAR && bp->Tdr.t_size[0] == '\200') - f->f_st.st_size = pbe64(&bp->Tdr.t_size[4]); - else - f->f_st.st_size = rdoct(bp->Tdr.t_size, 12); - if ((paxrec & PR_MTIME) == 0) - f->f_st.st_mtime = rdoct(bp->Tdr.t_mtime, TTIMSIZ); - if (bp->Tdr.t_linkflag == '1') { - if (f->f_lnam == NULL || f->f_lnam[0] == '\0') - tlinkof(&bp->Tdr, f); - f->f_st.st_mode |= S_IFREG; /* for -tv */ - f->f_st.st_nlink = 2; - } else if (bp->Tdr.t_linkflag == '2') { - if (f->f_lnam == NULL || f->f_lnam[0] == '\0') - tlinkof(&bp->Tdr, f); - f->f_st.st_mode |= S_IFLNK; - } else if (tflag == 0 && (f->f_name)[namlen-2] == '/') - f->f_st.st_mode |= S_IFDIR; - else - f->f_st.st_mode |= tifmt(bp->Tdr.t_linkflag); - if (paxrec & PR_SUN_DEVMAJOR) - /*EMPTY*/; - else if (fmttype == FMT_GNUTAR && bp->Tdr.t_devmajor[0] & 0200) - f->f_rmajor = pbe64(bp->Tdr.t_devmajor) & - 0x7FFFFFFFFFFFFFFFLL; - else - f->f_rmajor = rdoct(bp->Tdr.t_devmajor, 8); - if (paxrec & PR_SUN_DEVMINOR) - /*EMPTY*/; - else if (fmttype == FMT_GNUTAR && bp->Tdr.t_devminor[0] & 0200) - f->f_rminor = pbe64(bp->Tdr.t_devminor) & - 0x7FFFFFFFFFFFFFFFLL; - else - f->f_rminor = rdoct(bp->Tdr.t_devminor, 8); - f->f_st.st_rdev = makedev(f->f_rmajor, f->f_rminor); - f->f_pad = 512; - rd = 512; - } else if (fmttype == FMT_ZIP) { - hsz = SIZEOF_zip_header; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if (memcmp(bp->Zdr.z_signature, mag_zipctr, - sizeof mag_zipctr) == 0 || - memcmp(bp->Zdr.z_signature, mag_zipend, - sizeof mag_zipend) == 0 || - memcmp(bp->Zdr.z_signature, mag_zip64e, - sizeof mag_zip64e) == 0 || - memcmp(bp->Zdr.z_signature, mag_zip64l, - sizeof mag_zip64l) == 0) - return 1; - if (memcmp(bp->Zdr.z_signature, mag_zipsig, sizeof mag_zipsig)) - goto badhdr; - f->f_st.st_uid = myuid; - f->f_st.st_gid = mygid; - f->f_st.st_nlink = 1; - f->f_st.st_mtime = - gdostime(bp->Zdr.z_modtime, bp->Zdr.z_moddate); - f->f_st.st_size = ple32(bp->Zdr.z_nsize); - f->f_csize = ple32(bp->Zdr.z_csize); - f->f_cmethod = ple16(bp->Zdr.z_cmethod); - f->f_chksum = ple32(bp->Zdr.z_crc32); - f->f_gflag = ple16(bp->Zdr.z_gflag); - rd = SIZEOF_zip_header; - namlen = ple16(bp->Zdr.z_namelen)&0177777; - if (f->f_nsiz < namlen+1) { - free(f->f_name); - f->f_name = smalloc(f->f_nsiz = namlen+1); - } - if (bread(f->f_name, namlen) != namlen) - goto corrupt; - (f->f_name)[namlen] = '\0'; - if (f->f_name[namlen-1] == '/') - f->f_st.st_mode = 0777&~(mode_t)umsk|S_IFDIR; - else - f->f_st.st_mode = 0666&~(mode_t)umsk|S_IFREG; - rd += namlen; - if ((l1 = ziprxtra(f, &bp->Zdr)) < 0) - goto corrupt; - rd += l1; - f->f_pad = 1; - } else - abort(); - if (fmttype & TYP_CPIO) { - if (f->f_st.st_nlink <= 0 || namlen <= 0 || namlen >= SANELIMIT) - goto corrupt; - if (namlen > f->f_nsiz) { - if (f->f_name) - free(f->f_name); - f->f_name = smalloc(f->f_nsiz = namlen); - } - if (bread(f->f_name, namlen) != namlen) - unexeoa(); - if (f->f_name[namlen-1] != '\0') - goto corrupt; - rd += namlen; - skippad(rd, f->f_pad); - if (fmttype & TYP_NCPIO && - (!formatforced || fmttype & TYP_SCO)) { - /* - * The UnixWare format is a hack, but not a bad - * one. It is backwards compatible as far as - * possible; old implementations can use the -k - * option and will then get only the beginning - * of a large file, but all other files in the - * archive. - */ - if (namlen >= 24 && memcmp(&f->f_name[namlen-23], - "\0size=", 6) == 0) { - fmttype |= TYP_SCO; - f->f_st.st_size = rdhex(&f->f_name[namlen-17], - 16); - } - } - } - if (attempts) { - if (tflag) - fflush(stdout); - msg(0, 0, sysv3 < 0 ? - "Re-synced after skipping %lld bytes.\n" : - "Re-synchronized on magic number/header.\n", - skipped); - } - attempts = 0; - if (f->f_st.st_atime == 0 || (pax_preserve&(PAX_P_ATIME|PAX_P_EVERY)) == - PAX_P_ATIME) - f->f_st.st_atime = f->f_st.st_mtime; - if ((f->f_dsize = f->f_st.st_size) < 0) - goto badhdr; - if (fmttype & TYP_CPIO && strcmp(f->f_name, trailer) == 0) - return 1; - return 0; -corrupt: - if (kflag) { - if (tflag) - fflush(stdout); - msg(3, 0, "Corrupt header, file(s) may be lost.\n"); - } -badhdr: - if (kflag) { - int next = fmttype & TYP_TAR ? 512 : 1; - if (attempts++ == 0) { - if (tflag) - fflush(stdout); - msg(1, 0, sysv3 < 0 ? "Out of phase; resyncing.\n" : - "Searching for magic number/header.\n"); - errcnt++; - } - for (l1 = next; l1 < hsz; l1++) - bp->data[l1-next] = bp->data[l1]; - if (bread(&bp->data[l1-next], next) != next) - unexeoa(); - skipped++; - goto retry; - } - if (tflag) - fflush(stdout); - msg(3, 1, sysv3 < 0 ? "Out of phase--get help\n" : - sysv3 > 0 ? "Out of sync, bad magic number/header.\n" : - "Bad magic number/header.\n"); - /*NOTREACHED*/ - return -1; -} - -/* - * Determine the kind of archive on tape. - */ -static void -whathdr(void) -{ -again: if (blktop >= SIZEOF_hdr_cpio && - ple16(blkbuf) == mag_bin) { - fmttype = FMT_BINLE; - } else if (blktop >= SIZEOF_hdr_cpio && - pbe16(blkbuf) == mag_bin) { - fmttype = FMT_BINBE; - } else if (blktop >= SIZEOF_c_hdr && - memcmp(blkbuf, mag_odc, sizeof mag_odc) == 0) { - /* - * The DEC format is rubbish. Instead of introducing a new - * archive magic, its engineers reused the POSIX/odc magic - * and changed the fields. But there's a workaround: For a - * real odc archive, the byte following the file name is a - * \0 byte (unless the archive is damaged, of course). If - * it is not a \0 byte, but a \0 byte appears at the - * corresponding location for the DEC format, this is - * treated as a DEC archive. It must be noted that the - * Tru64 UNIX 5.1 cpio command is too stupid even for - * doing that - it will spill out a list of complaints - * if an extended archive is read but -e is not given. - */ - int ns1, ns2; - ns1 = rdoct(((struct c_hdr *)blkbuf)->c_namesz, 6); - ns2 = rdoct(((struct d_hdr *)blkbuf)->d_namesz, 6); - if (blktop >= SIZEOF_d_hdr && - (ns1 >= blktop - SIZEOF_c_hdr || - blkbuf[SIZEOF_c_hdr+ns1-1] != '\0') && - ns2 <= blktop - SIZEOF_d_hdr && - blkbuf[SIZEOF_d_hdr+ns2-1] == '\0') - fmttype = FMT_DEC; - else - fmttype = FMT_ODC; - } else if (blktop >= SIZEOF_Exp_cpio_hdr && - memcmp(blkbuf, mag_asc, sizeof mag_asc) == 0) { - fmttype = FMT_ASC; - } else if (blktop >= SIZEOF_Exp_cpio_hdr && - memcmp(blkbuf, mag_crc, sizeof mag_crc) == 0) { - fmttype = FMT_CRC; - } else if (blktop >= SIZEOF_cray_hdr && - pbe64(blkbuf) == mag_bin) { - /* - * Old and new Cray headers are identical in the first - * 64 header bytes (including the magic). cpio(5) on - * UNICOS does not describe what the new param field - * is for. - * - * An archive is treated as old format if the mtime - * and namesize fields make sense and all characters - * of the name are non-null. - */ - struct cray_hdr *Cp = (struct cray_hdr *)blkbuf; - long long mtime, namesize; - fmttype = FMT_CRAY; - mtime = pbe64(Cp->C_mtime - CRAY_PARAMSZ); - namesize = pbe64(Cp->C_namesize - CRAY_PARAMSZ); - if (mtime > 0 && mtime < (1LL<<31) && - namesize > 0 && namesize < 2048 && - blktop > SIZEOF_cray_hdr- - CRAY_PARAMSZ+namesize+1) { - int i; - for (i = 0; i < namesize; i++) - if (blkbuf[SIZEOF_cray_hdr- - CRAY_PARAMSZ+i] == '\0') - break; - if (i == namesize-1) - fmttype = FMT_CRAY5; - } - } else if (blktop >= 512 && - memcmp(&blkbuf[257], mag_ustar, 6) == 0 && - tcssum((union bincpio *)blkbuf, 1) == 0) { - fmttype = FMT_USTAR; - } else if (blktop >= 512 && - memcmp(&blkbuf[257], mag_gnutar, 8) == 0 && - tcssum((union bincpio *)blkbuf, 1) == 0) { - fmttype = FMT_GNUTAR; - } else if (blktop >= 512 && blkbuf[0] && /* require filename - to avoid match on - /dev/zero etc. */ - memcmp(&blkbuf[257], "\0\0\0\0\0", 5) == 0 && - tcssum((union bincpio *)blkbuf, 0) == 0) { - fmttype = FMT_OTAR; - } else if (blktop >= SIZEOF_zip_header && - (memcmp(blkbuf, mag_zipctr, sizeof mag_zipctr) == 0 || - memcmp(blkbuf, mag_zipsig, sizeof mag_zipsig) == 0 || - memcmp(blkbuf, mag_zipend, sizeof mag_zipend) == 0 || - memcmp(blkbuf, mag_zip64e, sizeof mag_zip64e) == 0 || - memcmp(blkbuf, mag_zip64l, sizeof mag_zip64l) == 0)) { - fmttype = FMT_ZIP; - } else if (blktop >= 512 && memcmp(blkbuf,"\0\0\0\0\0\0\0\0",8) == 0 && - memcmp(&blkbuf[65], mag_bar, sizeof mag_bar) == 0 && - bcssum((union bincpio *)blkbuf) == 0) { - fmttype = FMT_BAR; - compressed_bar = blkbuf[71] == '1'; - curpos = 512; - } else if (!Aflag && blktop > 3 && memcmp(blkbuf, "BZh", 3) == 0 && - redirect("bzip2", "-cd") == 0) { - goto zip; - } else if (!Aflag && blktop > 2 && memcmp(blkbuf, "\37\235", 2) == 0 && - redirect("zcat", NULL) == 0) { - goto zip; - } else if (!Aflag && blktop > 2 && memcmp(blkbuf, "\37\213", 2) == 0 && - redirect("gzip", "-cd") == 0) { - goto zip; - } else if (!Aflag && blktop > 4 && - memcmp(blkbuf, "\355\253\356\333", 4) == 0 && - redirect("rpm2cpio", "-") == 0) { - goto zip; - } else { - msg(3, 0, sysv3 ? "This is not a cpio file, bad header.\n" : - "Not a cpio file, bad header.\n"); - done(1); - } - return; -zip: - blktop = curpos = 0; - blocks = 0; - bytes = 0; - mfl = 0; - mstat(); - if (mread() == 0) - unexeoa(); - goto again; -} - -/* - * Processing of a single file with -i. - */ -static int -infile(struct file *f) -{ - int val; - - if ((fmttype & TYP_CPIO || fmttype == FMT_ZIP && f->f_st.st_size) && - (f->f_st.st_mode&S_IFMT) == S_IFLNK) { - if (f->f_lsiz < f->f_st.st_size+1) - f->f_lnam = srealloc(f->f_lnam, - f->f_lsiz = f->f_st.st_size+1); - if (bread(f->f_lnam, f->f_st.st_size) != f->f_st.st_size) - unexeoa(); - f->f_lnam[f->f_st.st_size] = '\0'; - skippad(f->f_st.st_size, f->f_pad); - } - if (tflag) - val = filet(f, indata); - else - val = filein(f, indata, f->f_name); - return val != 0; -} - -/* - * Fetch the data of regular files from tape and write it to tfd or, if - * tfd < 0, discard it. - */ -static int -indata(struct file *f, const char *tgt, int tfd) -{ - char *buf; - size_t bufsize; - struct stat ts; - long long size; - ssize_t rd; - uint32_t ssum = 0, usum = 0; - int val = 0; - int doswap = 0; - - size = fmttype == FMT_ZIP ? f->f_csize : - f->f_Kbase ? f->f_Kbase : f->f_st.st_size; - doswap = ((bflag|sflag) == 0 || - ckodd(size, 2, "bytes", f->f_name) == 0) & - ((bflag|Sflag) == 0 || - ckodd(size, 4, "halfwords", f->f_name) == 0) & - (bflag|sflag|Sflag); - if (fmttype == FMT_ZIP && f->f_cmethod != C_STORED) - return zipread(f, tgt, tfd, doswap); - if (tfd < 0 || fstat(tfd, &ts) < 0) - ts.st_blksize = 4096; - getbuf(&buf, &bufsize, ts.st_blksize); -again: while (size) { - if ((rd = bread(buf, size > bufsize ? bufsize : size)) <= 0) - unexeoa(); - if (doswap) - swap(buf, rd, bflag || sflag, bflag || Sflag); - if (tfd >= 0 && write(tfd, buf, rd) != rd) { - emsg(3, "Cannot write \"%s\"", tgt); - tfd = -1; - val = -1; - } - size -= rd; - if (fmttype & TYP_CRC) - do { - rd--; - ssum += ((signed char *)buf)[rd]; - usum += ((unsigned char *)buf)[rd]; - } while (rd); - } - if (f->f_Kbase) { - skippad(f->f_Ksize, f->f_pad); - readK2hdr(f); - size = f->f_Krest; - goto again; - } - skippad(fmttype==FMT_ZIP ? f->f_csize : - f->f_Ksize ? f->f_Krest : f->f_st.st_size, f->f_pad); - if (fmttype & TYP_CRC) { - if (f->f_chksum != ssum && f->f_chksum != usum) { - msg(3, 0, "\"%s\" - checksum error\n", f->f_name); - if (kflag) - errcnt++; - else - val = -1; - } - } - return val; -} - -/* - * Skip the data for a file on tape. - */ -static int -skipfile(struct file *f) -{ - char b[4096]; - long long size; - ssize_t rd; - - if (fmttype & TYP_TAR && ((f->f_st.st_mode&S_IFMT) == S_IFLNK || - f->f_st.st_nlink > 1)) { - if (fmttype & TYP_USTAR && (!formatforced || - fmttype == FMT_PAX) && - f->f_st.st_nlink > 1 && - f->f_st.st_size > 0) - /*EMPTY*/; - else - return 0; - } - /* - * SVR4 cpio derivatives always ignore the size of these, - * even if not reading tar formats. We do the same for now, - * although POSIX (for -H odc format) says the contrary. - */ - if (fmttype != FMT_ZIP && ((f->f_st.st_mode&S_IFMT) == S_IFDIR || - (f->f_st.st_mode&S_IFMT) == S_IFCHR || - (f->f_st.st_mode&S_IFMT) == S_IFBLK || - (f->f_st.st_mode&S_IFMT) == S_IFIFO || - (f->f_st.st_mode&S_IFMT) == S_IFNAM || - (f->f_st.st_mode&S_IFMT) == S_IFNWK)) - return 0; - if (fmttype == FMT_ZIP && f->f_gflag & FG_DESC) - return zipread(f, f->f_name, -1, 0); - size = fmttype == FMT_ZIP ? f->f_csize : - f->f_Kbase ? f->f_Kbase : f->f_st.st_size; -again: while (size) { - if ((rd = bread(b, size > sizeof b ? sizeof b : size)) <= 0) - unexeoa(); - size -= rd; - } - if (f->f_Kbase) { - skippad(f->f_Ksize, f->f_pad); - readK2hdr(f); - size = f->f_Krest; - goto again; - } - skippad(fmttype==FMT_ZIP ? f->f_csize : - f->f_Ksize ? f->f_Krest : f->f_st.st_size, f->f_pad); - return 0; -} - -/* - * Skip data also, but perform checks as if copying. - */ -static int -skipdata(struct file *f, int (*copydata)(struct file *, const char *, int)) -{ - switch (f->f_st.st_mode&S_IFMT) { - case S_IFLNK: - break; - case S_IFDIR: - case S_IFBLK: - case S_IFCHR: - case S_IFIFO: - case S_IFNAM: - case S_IFNWK: - if (fmttype != FMT_ZIP) - break; - /*FALLTHRU*/ - case S_IFREG: - default: - if (fmttype & TYP_TAR && f->f_st.st_nlink > 1 && - ((fmttype & TYP_USTAR) == 0 || - formatforced && fmttype != FMT_PAX)) - break; - if (copydata(f, f->f_name, -1) != 0) - return 1; - } - return 0; -} - -/* - * Seek to a position in the archive measured from the begin of - * operation. Handle media-dependent seeks. n must be a multiple - * of the tape device's physical block size. - */ -static int -tseek(off_t n) -{ - int fault; - - if (tapeblock > 0) { - int i = (n - poffs) / tapeblock; -#if defined (__linux__) || defined (__sun) || defined (__FreeBSD__) || \ - defined (__hpux) || defined (_AIX) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || \ - defined (__CYGWIN__) - struct mtop mo; - mo.mt_op = i > 0 ? MTFSR : MTBSR; - mo.mt_count = i > 0 ? i : -i; - fault = ioctl(mt, MTIOCTOP, &mo); -#endif - } else - fault = lseek(mt, n - poffs, SEEK_CUR) == (off_t)-1 ? -1 : 0; - if (fault == 0) - poffs = n; - return fault; -} - -/* - * Advance to the trailer on the tape (for -A). - */ -static int -totrailer(void) -{ - union bincpio bc; - struct file f; - off_t ooffs, noffs, diff; - int i; - - if (mread() == 0) - unexeoa(); - if (fmttype == FMT_NONE) - whathdr(); - memset(&f, 0, sizeof f); - for (;;) { - ooffs = aoffs; - if ((i = readhdr(&f, &bc)) < 0) - goto fail; - if (i > 0) - break; - markdev(f.f_st.st_dev); - if (skipfile(&f) != 0) - goto fail; - if (fmttype == FMT_ZIP) - zipdefer(f.f_name, &f.f_st, ooffs, - f.f_chksum, f.f_csize, &bc.Zdr); - pax_track(f.f_name, f.f_st.st_mtime); - } - /* - * Now seek to the position of the trailer, but retain the - * block alignment. - */ - diff = ooffs % blksiz; - noffs = ooffs - diff; - if (diff ? tseek(noffs) == 0 && mread() >= diff && tseek(noffs) == 0 - : tseek(ooffs) == 0) { - free(f.f_name); - free(f.f_lnam); - nwritten = ooffs; - curpos = diff; - return 0; - } -fail: msg(4, 1, "Unable to append to this archive\n"); - /*NOTREACHED*/ - return 1; -} - -static long long -rdoct(const char *data, int len) -{ - int i; - long long val = 0; - - for (i = 0; i < len && data[i] == ' '; i++); - for ( ; i < len && data[i] && data[i] != ' '; i++) { - val <<= 3; - val += data[i] - '0'; - } - return val; -} - -static long long -rdhex(const char *data, int len) -{ - int i; - long long val = 0; - - for (i = 0; i < len && data[i] == ' '; i++); - for ( ; i < len && data[i] && data[i] != ' '; i++) { - val <<= 4; - val += data[i] > '9' ? data[i] > 'F' ? data[i] - 'a' + 10 : - data[i] - 'A' + 10 : data[i] - '0'; - } - return val; -} - -void -unexeoa(void) -{ - if (sysv3) { - fprintf(stderr, - "Can't read input: end of file encountered " - "prior to expected end of archive.\n"); - done(1); - } - else - msg(3, 1, "Unexpected end-of-archive encountered.\n"); -} - -static char *peekdata; -static size_t peekbot, peektop, peeksize; - -void -bunread(const char *data, size_t sz) -{ - peekdata = srealloc(peekdata, peeksize += sz); - memcpy(&peekdata[peekbot], data, sz); - peektop += sz; - aoffs -= sz; -} - -/* - * Buffered read of data from tape. sz is the amount of data required - * by the archive format; if it cannot be retrieved, processing fails. - */ -ssize_t -bread(char *data, size_t sz) -{ - ssize_t rd = 0; - - if (peekdata) { - rd = sz>peektop-peekbot ? peektop-peekbot : sz; - memcpy(&data[0], &peekdata[peekbot], rd); - sz -= rd; - peekbot += rd; - if (peekbot == peektop) { - free(peekdata); - peekdata = 0; - peeksize = 0; - peekbot = peektop = 0; - } - } - while (sz) { - if (blktop - curpos >= sz) { - memcpy(&data[rd], &blkbuf[curpos], sz); - curpos += sz; - rd += sz; - aoffs += rd; - return rd; - } - if (blktop > curpos) { - memcpy(&data[rd], &blkbuf[curpos], blktop - curpos); - rd += blktop - curpos; - sz -= blktop - curpos; - curpos = blktop; - } - if (mfl < 0) { - if (mfl == -1) { - emsg(3, "I/O error on \"%s\"", - Iflag ? Iflag : "input"); - if (kflag == 0) - break; - if (tapeblock < 0 && ( - (mtst.st_mode&S_IFMT)==S_IFBLK|| - (mtst.st_mode&S_IFMT)==S_IFCHR|| - (mtst.st_mode&S_IFMT)==S_IFREG - ) && lseek(mt, blksiz, SEEK_CUR) - == (off_t)-1) { - emsg(3, "Cannot lseek()"); - done(1); - } - } - if (kflag == 0 || mfl == -2) { - if ((mtst.st_mode&S_IFMT)!=S_IFCHR && - (mtst.st_mode&S_IFMT)!=S_IFBLK) - break; - newmedia(mfl == -1 ? errno : 0); - if (mfl == -1) { - mfl = -2; - break; - } - if (fmttype & TYP_BAR) - curpos = 512; - } - } - mread(); - } - aoffs += rd; - return rd; -} - -/* - * Read a block of data from tape. - */ -static ssize_t -mread(void) -{ - ssize_t ro, rt = 0; - - do { - if ((ro = read(mt, blkbuf + rt, blksiz - rt)) <= 0) { - if (ro < 0) { - if (errno == EINTR) - continue; - mfl = -1; - } else - mfl = -2; - if (rt > 0) { - rt += ro; - break; - } - curpos = blktop = 0; - return ro; - } - rt += ro; - poffs += ro; - if (tapeblock == 0) { - tapeblock = ro; - if (!Bflag && !Cflag) - blksiz = ro; - } - } while (rt < blksiz); - curpos = 0; - blocks += rt >> 9; - bytes += rt & 0777; - blktop = rt; - return rt; -} - -/* - * Look what kind of tape or other archive media we are working on and - * set the buffer size appropriately (if not specified by the user). - */ -static void -mstat(void) -{ - if (fstat(mt, &mtst) < 0) { - emsg(3, "Error during stat() of archive"); - done(1); - } -#if defined (__linux__) - if ((mtst.st_mode&S_IFMT) == S_IFCHR) { - struct mtget mg; - if (ioctl(mt, MTIOCGET, &mg) == 0) - tapeblock = (mg.mt_dsreg&MT_ST_BLKSIZE_MASK) >> - MT_ST_BLKSIZE_SHIFT; - } else if ((mtst.st_mode&S_IFMT) == S_IFBLK) { - /* - * If using a block device, write blocks of the floppy - * disk sector with direct i/o. This enables signals - * after each block is written instead of being ~40 - * seconds in uninterruptible sleep when calling close() - * later. For block devices other than floppies, use the - * kernel defined i/o block size. For floppies, use direct - * i/o even when reading since it is faster. - */ - struct floppy_struct fs; - int floppy = -1; - int blkbsz; - - if (blksiz == 0) { - if ((floppy = ioctl(mt, FDGETPRM, &fs)) == 0) - blksiz = fs.sect * FD_SECTSIZE(&fs); -#ifdef BLKBSZGET - else if (ioctl(mt, BLKBSZGET, &blkbsz) == 0) - blksiz = blkbsz; -#endif /* BLKBSZGET */ - } -#ifdef O_DIRECT - if ((action == 'o' || floppy == 0) && blksiz != 0) { - int flags; - if ((flags = fcntl(mt, F_GETFL)) != -1) - fcntl(mt, F_SETFL, flags | O_DIRECT); - } - } -#endif /* O_DIRECT */ -#elif defined (__sun) - if ((mtst.st_mode&S_IFMT) == S_IFCHR) { - struct mtdrivetype_request mr; - static struct mtdrivetype md; - mr.size = sizeof md; - mr.mtdtp = &md; - if (ioctl(mt, MTIOCGETDRIVETYPE, &mr) == 0) - tapeblock = md.bsize; - } -#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) \ - || defined (__DragonFly__) - if ((mtst.st_mode&S_IFMT) == S_IFCHR) { - struct mtget mg; - if (ioctl(mt, MTIOCGET, &mg) == 0) - tapeblock = mg.mt_blksiz; - } -#elif defined (__CYGWIN__) - if ((mtst.st_mode&S_IFMT) == S_IFCHR) { - struct mtget mg; - if (ioctl(mt, MTIOCGET, &mg) == 0) - tapeblock = (mg.mt_dsreg&MT_ST_BLKSIZE_MASK) >> - MT_ST_BLKSIZE_SHIFT; - } -#elif defined (__hpux) || defined (_AIX) -#endif /* SVR4.2MP */ - if (blksiz == 0) - switch (mtst.st_mode&S_IFMT) { - case S_IFREG: - case S_IFBLK: - blksiz = 4096; - break; - case S_IFCHR: - if (action == 'o' && !Aflag) { - if (pax != PAX_TYPE_CPIO) { - if (fmttype & TYP_PAX) - blksiz = 5120; - else if (fmttype & TYP_TAR) - blksiz = 10240; - else if (fmttype & TYP_CPIO) - blksiz = 5120; - else - blksiz = 512; - } else - blksiz = tapeblock>0 ? tapeblock : 512; - } else - blksiz = tapeblock > 0 && tapeblock % 1024 ? - tapeblock : tapeblock > 10240 ? - tapeblock : 10240; - break; - default: - blksiz = 512; - } -} - -/* - * Skip tape data such that size becomes aligned to pad. - */ -static int -skippad(unsigned long long size, int pad) -{ - char b[512]; - int to; - - if ((to = size % pad) != 0) { - if (bread(b, pad - to) != pad - to) - unexeoa(); - } - return 0; -} - -static int -allzero(const char *bp, int n) -{ - int i; - - for (i = 0; i < n; i++) - if (bp[i] != '\0') - return 0; - return 1; -} - -#define CACHESIZE 16 - -static const char * -getuser(uid_t uid) -{ - static struct { - char *name; - uid_t uid; - } cache[CACHESIZE]; - static int last; - int i; - struct passwd *pwd; - const char *name; - - for (i = 0; i < CACHESIZE && cache[i].name; i++) - if (cache[i].uid == uid) - goto found; - if ((pwd = getpwuid(uid)) != NULL) - name = pwd->pw_name; - else - name = ""; - if (i >= CACHESIZE) { - if (last >= CACHESIZE) - last = 0; - i = last++; - } - if (cache[i].name) - free(cache[i].name); - cache[i].name = sstrdup(name); - cache[i].uid = uid; -found: return cache[i].name[0] ? cache[i].name : NULL; -} - -static const char * -getgroup(gid_t gid) -{ - static struct { - char *name; - gid_t gid; - } cache[CACHESIZE]; - static int last; - int i; - struct group *grp; - const char *name; - - for (i = 0; i < CACHESIZE && cache[i].name; i++) - if (cache[i].gid == gid) - goto found; - if ((grp = getgrgid(gid)) != NULL) - name = grp->gr_name; - else - name = ""; - if (i >= CACHESIZE) { - if (last >= CACHESIZE) - last = 0; - i = last++; - } - if (cache[i].name) - free(cache[i].name); - cache[i].name = sstrdup(name); - cache[i].gid = gid; -found: return cache[i].name[0] ? cache[i].name : NULL; -} - -/* - * Return a version of the passed string that contains at most one '%d' - * and no other printf formats. - */ -char * -oneintfmt(const char *op) -{ - char *new, *np; - int no = 0; - - np = new = smalloc(2 * strlen(op) + 1); - do { - if (*op == '%') { - *np++ = *op++; - if (*op != '%') - if (*op != 'd' || no++) - *np++ = '%'; - } - *np++ = *op; - } while (*op++); - return new; -} - -char * -sstrdup(const char *op) -{ - char *np; - - np = smalloc(strlen(op) + 1); - strcpy(np, op); - return np; -} - -/* - * Add this pattern to the extraction list with -i. - */ -void -addg(const char *pattern, int art) -{ - struct glist *gp; - - gp = scalloc(1, sizeof *gp); - if (pax == PAX_TYPE_CPIO && pattern[0] == '!') { - gp->g_not = 1; - pattern++; - } - gp->g_pat = sstrdup(pattern); - gp->g_art = art; - if (pax != PAX_TYPE_CPIO) { - struct glist *gb = NULL, *gc; - for (gc = patterns; gc; gc = gc->g_nxt) - gb = gc; - if (gb) - gb->g_nxt = gp; - else - patterns = gp; - } else { - gp->g_nxt = patterns; - patterns = gp; - } -} - -/* - * Check if the file name s matches any of the given patterns. - */ -static struct glist * -want(struct file *f, struct glist **gb) -{ - extern int gmatch(const char *, const char *); - struct glist *gp; - - for (gp = patterns; gp; gp = gp->g_nxt) { - if ((gmatch(f->f_name, gp->g_pat) != 0) ^ gp->g_not && - (pax_nflag == 0 || gp->g_gotcha == 0)) { - return gp; - } - *gb = gp; - } - return NULL; -} - -static void -patfile(void) -{ - struct iblok *ip; - char *name = NULL; - size_t namsiz = 0, namlen; - - if ((ip = ib_open(Eflag, 0)) == NULL) - msg(3, -2, "Cannot open \"%s\" to read patterns\n", Eflag); - while ((namlen = ib_getlin(ip, &name, &namsiz, srealloc)) != 0) { - if (name[namlen-1] == '\n') - name[--namlen] = '\0'; - addg(name, 0); - } - ib_close(ip); -} - -void -swap(char *b, size_t sz, int s8, int s16) -{ - uint8_t u8; - uint16_t u16; - union types2 *t2; - union types4 *t4; - int i; - - if (s8) { - for (i = 0; i < (sz >> 1); i++) { - t2 = &((union types2 *)b)[i]; - u8 = t2->byte[0]; - t2->byte[0] = t2->byte[1]; - t2->byte[1] = u8; - } - } - if (s16) { - for (i = 0; i < (sz >> 2); i++) { - t4 = &((union types4 *)b)[i]; - u16 = t4->sword[0]; - t4->sword[0] = t4->sword[1]; - t4->sword[1] = u16; - } - } -} - -static int -ckodd(long long size, int mod, const char *str, const char *fn) -{ - if (size % mod) { - msg(3, 0, "Cannot swap %s of \"%s\", odd number of %s\n", - str, fn, str); - errcnt++; - return 1; - } - return 0; -} - -/* - * Interactive rename (-r option). - */ -static int -rname(char **oldp, size_t *olds) -{ - char *new = NULL; - size_t newsize = 0; - int i, r; - char c; - - fprintf(stderr, "Rename \"%s\"? ", *oldp); - if (tty == 0) - if ((tty = open("/dev/tty", O_RDWR)) < 0 || - fcntl(tty, F_SETFD, FD_CLOEXEC) < 0) - err: msg(3, 1, "Cannot read tty.\n"); - i = 0; - while ((r = read(tty, &c, 1)) == 1 && c != '\n') { - if (i+1 >= newsize) - new = srealloc(new, newsize += 32); - new[i++] = c; - } - if (r <= 0) - goto err; - if (new == NULL) - return 0; - new[i] = '\0'; - if (new[0] == '.' && new[1] == '\0') { - free(new); - } else { - free(*oldp); - *oldp = new; - *olds = newsize; - } - return 1; -} - -/* - * Filter data from tape through the commands given in arg?. - */ -static int -redirect(const char *arg0, const char *arg1) -{ - int pd[2]; - - if (pipe(pd) < 0) - return -1; - switch (fork()) { - case 0: - if (tapeblock>=0 || lseek(mt, -blktop, SEEK_CUR) == (off_t)-1) { - int xpd[2]; - if (pipe(xpd) == 0 && fork() == 0) { - ssize_t rd, wo, wt; - close(xpd[0]); - do { - wo = wt = 0; - do { - if ((wo = write(xpd[1], - blkbuf + wt, - blktop - wt)) - <= 0) { - if (errno == EINTR) - continue; - _exit(0); - } - wt += wo; - } while (wt < blktop); - } while ((rd = mread()) >= 0); - if (rd < 0) { - emsg(3, "Read error on \"%s\"", - Iflag && !sysv3 ? - Iflag : "input"); - } - _exit(0); - } else { - close(xpd[1]); - dup2(xpd[0], 0); - close(xpd[0]); - } - } else { - dup2(mt, 0); - } - close(mt); - dup2(pd[1], 1); - close(pd[0]); - close(pd[1]); - execlp(arg0, arg0, arg1, NULL); - fprintf(stderr, "%s: could not exec %s: %s\n", - progname, arg0, strerror(errno)); - _exit(0177); - /*NOTREACHED*/ - default: - dup2(pd[0], mt); - close(pd[0]); - close(pd[1]); - tapeblock = -1; - break; - case -1: - return -1; - } - return 0; -} - -/* - * Get the name stored in a tar header. buf is expected to be at least - * TPFXSIZ+TNAMSIZ+2 bytes. - */ -static char * -tnameof(struct tar_header *hp, char *buf) -{ - const char *cp; - char *bp = buf; - - if (fmttype & TYP_USTAR && fmttype != FMT_GNUTAR && - hp->t_prefix[0] != '\0') { - cp = hp->t_prefix; - while (cp < &hp->t_prefix[TPFXSIZ] && *cp) - *bp++ = *cp++; - if (bp > buf) - *bp++ = '/'; - } - cp = hp->t_name; - while (cp < &hp->t_name[TNAMSIZ] && *cp) - *bp++ = *cp++; - *bp = '\0'; - return buf; -} - -/* - * Store fn as file name in a tar header. - */ -static int -tmkname(struct tar_header *hp, const char *fn) -{ - const char *cp, *cs = NULL; - - for (cp = fn; *cp; cp++) { - if (fmttype & TYP_USTAR && *cp == '/' && cp[1] != '\0' && - cp > fn && cp-fn <= TPFXSIZ) - cs = cp; - } - if (fmttype == FMT_GNUTAR && cp - fn > 99) { - writegnuname(fn, cp - fn + 1, 'L'); - cp = &fn[99]; - } else if (cp - (cs ? &cs[1] : fn) > TNAMSIZ) { - if (fmttype & TYP_PAX && utf8(fn)) { - paxrec |= PR_PATH; - strcpy(hp->t_name, sequence()); - return 0; - } - msg(3, 0, "%s: file name too long\n", fn); - return -1; - } - if (cs && cp - fn > TNAMSIZ) { - memcpy(hp->t_prefix, fn, cs - fn); - if (cs - fn < TPFXSIZ) - hp->t_prefix[cs - fn] = '\0'; - memcpy(hp->t_name, &cs[1], cp - &cs[1]); - if (cp - &cs[1] < TNAMSIZ) - hp->t_name[cp - &cs[1]] = '\0'; - } else { - memcpy(hp->t_name, fn, cp - fn); - if (cp - fn < TNAMSIZ) - hp->t_name[cp - fn] = '\0'; - } - return 0; -} - -/* - * Get the link name of a tar header. - */ -static void -tlinkof(struct tar_header *hp, struct file *f) -{ - const char *cp; - char *bp; - - - if (f->f_lsiz < TNAMSIZ+1) - f->f_lnam = srealloc(f->f_lnam, f->f_lsiz = TNAMSIZ+1); - cp = hp->t_linkname; - bp = f->f_lnam; - while (cp < &hp->t_linkname[TNAMSIZ] && *cp) - *bp++ = *cp++; - *bp = '\0'; -} - -/* - * Create the link name in a tar header. - */ -static int -tmklink(struct tar_header *hp, const char *fn) -{ - const char *cp; - - for (cp = fn; *cp; cp++); - if (fmttype == FMT_GNUTAR && cp - fn > 99) { - writegnuname(fn, cp - fn + 1, 'K'); - cp = &fn[99]; - } else if (cp - fn > TNAMSIZ) { - if (fmttype & TYP_PAX && utf8(fn)) { - paxrec |= PR_LINKPATH; - strcpy(hp->t_linkname, sequence()); - return 0; - } - msg(3, 0, "%s: linked name too long\n", fn); - return -1; - } - memcpy(hp->t_linkname, fn, cp - fn); - if (cp - fn < TNAMSIZ) - hp->t_linkname[cp - fn] = '\0'; - return 0; -} - -static int -tlflag(struct stat *st) -{ - if (fmttype & TYP_BAR) { - switch (st->st_mode & S_IFMT) { - case S_IFREG: - case S_IFDIR: - return '0'; - case S_IFLNK: - return '2'; - default: - return '3'; - } - } else if (fmttype & TYP_USTAR) { - switch (st->st_mode & S_IFMT) { - case S_IFREG: - return '0'; - case S_IFLNK: - return '2'; - case S_IFCHR: - return '3'; - case S_IFBLK: - return '4'; - case S_IFDIR: - return '5'; - case S_IFIFO: - return '6'; - default: - return -1; - } - } else { - switch (st->st_mode & S_IFMT) { - case S_IFREG: - return '\0'; - case S_IFLNK: - return '2'; - default: - return -1; - } - } -} - -/* - * Ustar checksums are created using unsigned chars, as specified by - * POSIX. Traditional tar implementations use signed chars. Some - * implementations (notably SVR4 cpio derivatives) use signed chars - * even for ustar archives, but this is clearly an implementation bug. - */ -static void -tchksum(union bincpio *bp) -{ - uint32_t sum; - char *cp; - - memset(bp->Tdr.t_chksum, ' ', sizeof bp->Tdr.t_chksum); - sum = 0; - if (fmttype & TYP_USTAR) - for (cp = bp->data; cp < &bp->data[512]; cp++) - sum += *((unsigned char *)cp); - else - for (cp = bp->data; cp < &bp->data[512]; cp++) - sum += *((signed char *)cp); - sprintf(bp->Tdr.t_chksum, "%7.7o", sum); -} - -static int -tcssum(union bincpio *bp, int ustar) -{ - uint32_t ssum = 0, usum = 0, osum; - char ochk[sizeof bp->Tdr.t_chksum]; - char *cp; - - osum = rdoct(bp->Tdr.t_chksum, 8); - memcpy(ochk, bp->Tdr.t_chksum, sizeof ochk); - memset(bp->Tdr.t_chksum, ' ', sizeof bp->Tdr.t_chksum); - for (cp = bp->data; cp < &bp->data[512]; cp++) { - ssum += *((signed char *)cp); - usum += *((unsigned char *)cp); - } - memcpy(bp->Tdr.t_chksum, ochk, sizeof bp->Tdr.t_chksum); - return ssum != osum && usum != osum; -} - -static int -trdsum(union bincpio *bp) -{ - int i; - - if (fmttype & TYP_BAR) - i = bcssum(bp); - else - i = tcssum(bp, fmttype & TYP_USTAR); - if (i) - msg(3, 0, "Bad header - checksum error.\n"); - return i; -} - -static mode_t -tifmt(int c) -{ - switch (c) { - default: - case '\0': - case '0': - return S_IFREG; - case '2': - return S_IFLNK; - case '3': - return S_IFCHR; - case '4': - return S_IFBLK; - case '5': - return S_IFDIR; - case '6': - return S_IFIFO; - } -} - -/* - * bar format support functions. - */ -static void -bchksum(union bincpio *bp) -{ - uint32_t sum; - char *cp; - - memset(bp->Bdr.b_chksum, ' ', sizeof bp->Bdr.b_chksum); - sum = 0; - for (cp = bp->data; cp < &bp->data[512]; cp++) - sum += *((signed char *)cp); - sprintf(bp->Bdr.b_chksum, "%7.7o", sum); -} - -static int -bcssum(union bincpio *bp) -{ - uint32_t sum, osum; - char ochk[sizeof bp->Bdr.b_chksum]; - char *cp; - - osum = rdoct(bp->Bdr.b_chksum, 8); - memcpy(ochk, bp->Bdr.b_chksum, sizeof ochk); - memset(bp->Bdr.b_chksum, ' ', sizeof bp->Bdr.b_chksum); - sum = 0; - for (cp = bp->data; cp < &bp->data[512]; cp++) - sum += *((signed char *)cp); - memcpy(bp->Bdr.b_chksum, ochk, sizeof bp->Bdr.b_chksum); - return sum != osum; -} - -static void -blinkof(const char *cp, struct file *f, int namlen) -{ - if (f->f_lsiz < 512) - f->f_lnam = srealloc(f->f_lnam, f->f_lsiz = 512); - strcpy(f->f_lnam, &cp[SIZEOF_bar_header + namlen]); -} - -static void -dump_barhdr(void) -{ - union bincpio bc; - static int volno; - static time_t now = -1; - - memset(&bc, 0, 512); - sprintf(bc.Bdr.b_uid, "%d", myuid & 07777777); - sprintf(bc.Bdr.b_gid, "%d", mygid & 07777777); - bc.Bdr.b_size[0] = '0'; - memcpy(bc.Bdr.b_bar_magic, mag_bar, sizeof bc.Bdr.b_bar_magic); - sprintf(bc.Bdr.b_volume_num, "%d", ++volno & 0777); - bc.Bdr.b_compressed = '0'; - if (now == (time_t)-1) - time(&now); - sprintf(bc.Bdr.b_date, "%llo", now & 077777777777LL); - bchksum(&bc); - bwrite(bc.data, 512); -} - -/* - * Support for compressed bar format (any regular file is piped through zcat). - */ -static pid_t zpid; - -static int -zcreat(const char *name, mode_t mode) -{ - int pd[2]; - int fd; - - if (pipe(pd) < 0) - return -1; - if ((fd = creat(name, mode)) < 0) { - fd = errno; - close(pd[0]); - close(pd[1]); - errno = fd; - return -1; - } - switch (zpid = fork()) { - case -1: - return -1; - case 0: - dup2(pd[0], 0); - dup2(fd, 1); - close(pd[0]); - close(pd[1]); - close(fd); - execlp("zcat", "zcat", NULL); - _exit(0177); - /*NOTREACHED*/ - } - close(pd[0]); - close(fd); - sigset(SIGPIPE, SIG_IGN); - return pd[1]; -} - -static int -zclose(int fd) -{ - int c, s; - - c = close(fd); - while (waitpid(zpid, &s, 0) != zpid); - return c != 0 || s != 0 ? -1 : 0; -} - -/* - * If using the -A option, device numbers that appear in the archive - * are not reused for appended files. This avoids wrong hardlink - * connections on extraction. - * - * In fact, this should be done even if we did not fake device and - * inode numbers, since it is not guaranteed that the archive was - * created on the same machine, or even on the same machine, inode - * number could have changed after a file was unlinked. - */ -static void -markdev(dev_t dev) -{ - struct dslot *dp, *dq = NULL;; - - for (dp = markeddevs; dp; dp = dp->d_nxt) { - if (dp->d_dev == dev) - return; - dq = dp; - } - dp = scalloc(1, sizeof *dp); - dp->d_dev = dev; - if (markeddevs == NULL) - markeddevs = dp; - else - dq->d_nxt = dp; -} - -static int -marked(dev_t dev) -{ - struct dslot *dp; - - for (dp = markeddevs; dp; dp = dp->d_nxt) - if (dp->d_dev == dev) - return 1; - return 0; -} - -static void -cantsup(int err, const char *file) -{ - if (sysv3) - msg(err ? 3 : 2, 0, - "format can't support expanded types on %s\n", - file); - else - msg(0, 0, "%s format can't support expanded types on %s\n", - err ? "Error" : "Warning", file); - errcnt++; -} - -static void -onint(int signo) -{ - if (cur_ofile && cur_tfile && rename(cur_tfile, cur_ofile) < 0) - emsg(3, "Cannot recover original \"%s\"", cur_ofile); - if (cur_ofile && cur_tfile == NULL && unlink(cur_ofile) < 0) - emsg(3, "Cannot remove incomplete \"%s\"", cur_ofile); - exit(signo | 0200); -} - -/* - * Read the compressed zip data part for a file. - */ -static int -zipread(struct file *f, const char *tgt, int tfd, int doswap) -{ - int val = 0; - uint32_t crc = 0; - - if (f->f_gflag & FG_DESC) { - if (f->f_cmethod != C_DEFLATED && f->f_cmethod != C_ENHDEFLD || - f->f_gflag & FG_CRYPT) - msg(4, 1, "Cannot handle zip data descriptor\n"); - f->f_csize = 0x7FFFFFFFFFFFFFFFLL; - f->f_st.st_size = 0x7FFFFFFFFFFFFFFFLL; - } else if (tfd < 0) - return skipfile(f); - if (f->f_gflag & FG_CRYPT) - return cantunzip(f, "encrypted"); - switch (f->f_cmethod) { - case C_DEFLATED: - case C_ENHDEFLD: - val = zipinflate(f, tgt, tfd, doswap, &crc); - break; - case C_SHRUNK: - val = zipunshrink(f, tgt, tfd, doswap, &crc); - break; - case C_IMPLODED: - val = zipexplode(f, tgt, tfd, doswap, &crc); - break; - case C_REDUCED1: - case C_REDUCED2: - case C_REDUCED3: - case C_REDUCED4: - val = zipexpand(f, tgt, tfd, doswap, &crc); - break; - case C_TOKENIZED: - return cantunzip(f, "tokenized"); - case C_DCLIMPLODED: - val = zipblast(f, tgt, tfd, doswap, &crc); - break; - case C_BZIP2: -#if USE_BZLIB - val = zipunbz2(f, tgt, tfd, doswap, &crc); - break; -#else /* !USE_BZLIB */ - return cantunzip(f, "bzip2 compressed"); -#endif /* !USE_BZLIB */ - default: - return cantunzip(f, "compressed"); - } - if (f->f_gflag & FG_DESC) - zipreaddesc(f); - if (val == 0 && crc != f->f_chksum) { - msg(3, 0, "\"%s\" - checksum error\n", f->f_name); - return -1; - } - return val; -} - -/* - * Read a zip data descriptor (i. e. a field after the compressed data - * that contains the actual values for sizes and crc). - */ -static void -zipreaddesc(struct file *f) -{ - if (f->f_oflag & OF_ZIP64) { - struct zipddesc64 zd64; - bread((char *)&zd64, SIZEOF_zipddesc64); - if (memcmp(zd64.zd_signature, mag_zipdds, sizeof mag_zipdds)) - msg(4, 1, "Invalid zip data descriptor\n"); - f->f_chksum = ple32(zd64.zd_crc32); - f->f_dsize = f->f_st.st_size = ple64(zd64.zd_nsize) & - 0xFFFFFFFFFFFFFFFFULL; - f->f_csize = ple64(zd64.zd_csize) & - 0xFFFFFFFFFFFFFFFFULL; - } else { - struct zipddesc zd; - bread((char *)&zd, SIZEOF_zipddesc); - if (memcmp(zd.zd_signature, mag_zipdds, sizeof mag_zipdds)) - msg(4, 1, "Invalid zip data descriptor\n"); - f->f_chksum = ple32(zd.zd_crc32); - f->f_dsize = f->f_st.st_size = ple32(zd.zd_nsize)&0xFFFFFFFFUL; - f->f_csize = ple32(zd.zd_csize)&0xFFFFFFFFUL; - } -} - -static int -cantunzip(struct file *f, const char *method) -{ - msg(3, 0, "Cannot unzip %s file \"%s\"\n", method, f->f_name); - errcnt++; - return skipfile(f); -} - -/* - * PC-DOS time format: - * - * 31 24 20 15 10 4 0 - * | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - * | | | | | - * |year |months |days |hours |minutes |biseconds| - * - * refers to local time on the machine it was created on. - */ - -static time_t -gdostime(const char *tp, const char *dp) -{ - uint32_t v; - struct tm tm; - - v = (int)(tp[0]&0377) + - ((int)(tp[1]&0377) << 8) + - ((int)(dp[0]&0377) << 16) + - ((int)(dp[1]&0377) << 24); - memset(&tm, 0, sizeof tm); - tm.tm_sec = (v&0x1F) << 1; - tm.tm_min = (v&0x7E0) >> 5; - tm.tm_hour = (v&0xF800) >> 11; - tm.tm_mday = ((v&0x1F0000) >> 16); - tm.tm_mon = ((v&0x1E00000) >> 21) - 1; - tm.tm_year = ((v&0xFE000000) >> 25) + 80; - tm.tm_isdst = -1; - return mktime(&tm); -} - -static void -mkdostime(time_t t, char *tp, char *dp) -{ - uint32_t v; - struct tm *tm; - - tm = localtime(&t); - v = (tm->tm_sec >> 1) + (tm->tm_sec&1) + (tm->tm_min << 5) + - (tm->tm_hour << 11) + (tm->tm_mday << 16) + - ((tm->tm_mon+1) << 21) + ((tm->tm_year - 80) << 25); - le16p(v&0x0000ffff, tp); - le16p((v&0xffff0000) >> 16, dp); -} - -/* - * Read and interpret the zip extra field for a file. - */ -static ssize_t -ziprxtra(struct file *f, struct zip_header *z) -{ - union zextra *x, *xp; - short tag, size; - ssize_t len; - - len = ple16(z->z_extralen)&0177777; - if (len > 0) { - x = smalloc(len); - if (bread((char *)x, len) != len) - return -1; - if (len < 4) - return len; - xp = x; - while (len > 0) { - if (len < 4) - return -1; - tag = ple16(xp->Ze_gn.ze_gn_tag); - size = (ple16(xp->Ze_gn.ze_gn_tsize)&0177777) + 4; - switch (tag) { - case mag_zip64f: /* ZIP64 extended information */ - if (size != SIZEOF_zextra_64 && - size != SIZEOF_zextra_64_a && - size != SIZEOF_zextra_64_b) - break; - if (f->f_st.st_size == 0xffffffff) - f->f_st.st_size = - ple64(xp->Ze_64.ze_64_nsize); - if (f->f_csize == 0xffffffff) - f->f_csize = - ple64(xp->Ze_64.ze_64_csize); - f->f_oflag |= OF_ZIP64; - break; - case 0x000d: /* PKWARE Unix Extra Field */ - if (size != SIZEOF_zextra_pk) - break; - f->f_st.st_atime = ple32(xp->Ze_pk.ze_pk_atime); - f->f_st.st_mtime = ple32(xp->Ze_pk.ze_pk_mtime); - f->f_st.st_uid = ple16(xp->Ze_pk.ze_pk_uid) & - 0177777; - f->f_st.st_gid = ple16(xp->Ze_pk.ze_pk_gid) & - 0177777; - break; - case 0x5455: /* Extended Timestamp Extra Field */ - if (xp->Ze_et.ze_et_flags[0] & 1) - f->f_st.st_atime = - ple32(xp->Ze_et.ze_et_atime); - if (xp->Ze_et.ze_et_flags[0] & 2) - f->f_st.st_mtime = - ple32(xp->Ze_et.ze_et_mtime); - if (xp->Ze_et.ze_et_flags[0] & 3) - f->f_st.st_ctime = - ple32(xp->Ze_et.ze_et_ctime); - break; - case 0x5855: /* Info-ZIP Unix Extra Field #1 */ - if (size != SIZEOF_zextra_i1) - break; - f->f_st.st_atime = ple32(xp->Ze_i1.ze_i1_atime); - f->f_st.st_mtime = ple32(xp->Ze_i1.ze_i1_mtime); - f->f_st.st_uid = ple16(xp->Ze_i1.ze_i1_uid) & - 0177777; - f->f_st.st_gid = ple16(xp->Ze_i1.ze_i1_gid) & - 0177777; - break; - case 0x7855: /* Info-ZIP Unix Extra Field #2 */ - if (size != SIZEOF_zextra_i2) - break; - f->f_st.st_uid = ple16(xp->Ze_i2.ze_i2_uid) & - 0177777; - f->f_st.st_gid = ple16(xp->Ze_i2.ze_i2_gid) & - 0177777; - break; - case 0x756e: /* ASi Unix Extra Field */ - if (size < SIZEOF_zextra_as) - break; - f->f_st.st_mode = ple16(xp->Ze_as.ze_as_mode); - f->f_st.st_uid = ple16(xp->Ze_as.ze_as_uid) & - 0177777; - f->f_st.st_gid = ple16(xp->Ze_as.ze_as_gid) & - 0177777; - if ((f->f_st.st_mode&S_IFMT) == S_IFLNK) { - if (f->f_lsiz < size-14+1) - f->f_lnam = srealloc(f->f_lnam, - f->f_lsiz = - size-18+1); - memcpy(f->f_lnam, &((char *)xp)[18], - size-18); - f->f_lnam[size-18] = '\0'; - f->f_st.st_size = size-18; - } else { - f->f_st.st_rdev = - ple32(xp->Ze_as.ze_as_sizdev); - f->f_rmajor = major(f->f_st.st_rdev); - f->f_rminor = minor(f->f_st.st_rdev); - } - break; - case mag_zipcpio: - if (size != SIZEOF_zextra_cp) - break; - f->f_st.st_dev = ple32(xp->Ze_cp.ze_cp_dev); - f->f_st.st_ino = ple32(xp->Ze_cp.ze_cp_ino); - f->f_st.st_mode = ple32(xp->Ze_cp.ze_cp_mode); - f->f_st.st_uid = ple32(xp->Ze_cp.ze_cp_uid) & - 0xFFFFFFFFUL; - f->f_st.st_gid = ple32(xp->Ze_cp.ze_cp_gid) & - 0xFFFFFFFFUL; - f->f_st.st_nlink = ple32(xp->Ze_cp.ze_cp_nlink)& - 0xFFFFFFFFUL; - f->f_st.st_rdev = ple32(xp->Ze_cp.ze_cp_rdev); - f->f_rmajor = major(f->f_st.st_rdev); - f->f_rminor = minor(f->f_st.st_rdev); - f->f_st.st_mtime = ple32(xp->Ze_cp.ze_cp_mtime); - f->f_st.st_atime = ple32(xp->Ze_cp.ze_cp_atime); - break; - } - xp = (union zextra *)&((char *)xp)[size]; - len -= size; - } - free(x); - } - return len; -} - -/* - * Write the central directory and the end of a zip file. - */ -static void -ziptrailer(void) -{ - struct zipstuff *zs; - struct zipcentral zc; - struct zipend ze; - long long cpstart, cpend, entries = 0; - size_t sz; - - cpstart = nwritten; - for (zs = zipbulk; zs; zs = zs->zs_next) { - entries++; - memset(&zc, 0, SIZEOF_zipcentral); - memcpy(zc.zc_signature, mag_zipctr, 4); - zc.zc_versionmade[0] = 20; - zc.zc_versionextr[0] = zs->zs_cmethod == 8 ? 20 : 10; - mkdostime(zs->zs_mtime, zc.zc_modtime, zc.zc_moddate); - le32p(zs->zs_crc32, zc.zc_crc32); - le16p(zs->zs_cmethod, zc.zc_cmethod); - le16p(zs->zs_gflag, zc.zc_gflag); - /* - * We flag files as created on PC-DOS / FAT filesystem - * and thus set PC-DOS attributes here. - */ - if ((zs->zs_mode&0222) == 0) - zc.zc_external[0] |= 0x01; /* readonly attribute */ - if ((zs->zs_mode&S_IFMT) == S_IFDIR) - zc.zc_external[0] |= 0x10; /* directory attr. */ - sz = strlen(zs->zs_name); - le16p(sz, zc.zc_namelen); - if (zs->zs_size >= 0xffffffff || zs->zs_csize >= 0xffffffff || - zs->zs_relative >= 0xffffffff) { - struct zextra_64 zf; - - memset(&zf, 0, SIZEOF_zextra_64); - le16p(mag_zip64f, zf.ze_64_tag); - le16p(SIZEOF_zextra_64 - 4, zf.ze_64_tsize); - if ((zs->zs_mode&S_IFMT) == S_IFREG || - (zs->zs_mode&S_IFMT) == S_IFLNK) { - le32p(0xffffffff, zc.zc_csize); - le32p(0xffffffff, zc.zc_nsize); - le64p(zs->zs_csize, zf.ze_64_csize); - le64p(zs->zs_size, zf.ze_64_nsize); - } - le64p(zs->zs_relative, zf.ze_64_reloff); - le32p(0xffffffff, zc.zc_relative); - le16p(SIZEOF_zextra_64, zc.zc_extralen); - bwrite((char *)&zc, SIZEOF_zipcentral); - bwrite(zs->zs_name, sz); - bwrite((char *)&zf, SIZEOF_zextra_64); - } else { - if ((zs->zs_mode&S_IFMT) == S_IFREG || - (zs->zs_mode&S_IFMT) == S_IFLNK) { - le32p(zs->zs_csize, zc.zc_csize); - le32p(zs->zs_size, zc.zc_nsize); - } - le32p(zs->zs_relative, zc.zc_relative); - bwrite((char *)&zc, SIZEOF_zipcentral); - bwrite(zs->zs_name, sz); - } - } - cpend = nwritten; - memset(&ze, 0, SIZEOF_zipend); - memcpy(ze.ze_signature, mag_zipend, 4); - if (cpend >= 0xffffffff || entries >= 0xffff) { - struct zip64end z6; - struct zip64loc z4; - - memset(&z6, 0, SIZEOF_zip64end); - memcpy(z6.z6_signature, mag_zip64e, 4); - le64p(SIZEOF_zip64end - 12, z6.z6_recsize); - z6.z6_versionmade[0] = 20; - z6.z6_versionextr[0] = 20; - le64p(entries, z6.z6_thisentries); - le64p(entries, z6.z6_allentries); - le64p(cpend - cpstart, z6.z6_dirsize); - le64p(cpstart, z6.z6_startsize); - bwrite((char *)&z6, SIZEOF_zip64end); - memset(&z4, 0, SIZEOF_zip64loc); - memcpy(z4.z4_signature, mag_zip64l, 4); - le64p(cpend, z4.z4_reloff); - le32p(1, z4.z4_alldiskn); - bwrite((char *)&z4, SIZEOF_zip64loc); - le16p(0xffff, ze.ze_thisentries); - le16p(0xffff, ze.ze_allentries); - le32p(0xffffffff, ze.ze_dirsize); - le32p(0xffffffff, ze.ze_startsize); - } else { - le16p(entries, ze.ze_thisentries); - le16p(entries, ze.ze_allentries); - le32p(cpend - cpstart, ze.ze_dirsize); - le32p(cpstart, ze.ze_startsize); - } - bwrite((char *)&ze, SIZEOF_zipend); -} - -/* - * Store the data later needed for the central directory. - */ -static void -zipdefer(const char *fn, struct stat *st, long long relative, - uint32_t crc, long long csize, const struct zip_header *zh) -{ - struct zipstuff *zp; - - zp = scalloc(1, sizeof *zp); - zp->zs_name = sstrdup(fn); - zp->zs_size = st->st_size; - zp->zs_mtime = st->st_mtime; - zp->zs_mode = st->st_mode; - zp->zs_relative = relative; - zp->zs_cmethod = ple16(zh->z_cmethod); - zp->zs_gflag = ple16(zh->z_gflag); - zp->zs_csize = csize; - zp->zs_crc32 = crc; - zp->zs_next = zipbulk; - zipbulk = zp; -} - -#define ziptrlevel() ( \ - zipclevel == 01 ? 9 : /* maximum */ \ - zipclevel == 02 ? 3 : /* fast */ \ - zipclevel == 03 ? 1 : /* super fast */\ - /*zipclevel==00*/ 6 /* normal */ \ -) - -/* - * Write (and compress) data for a regular file to a zip archive. - */ -static int -zipwrite(int fd, const char *fn, struct stat *st, union bincpio *bp, size_t sz, - uint32_t dev, uint32_t ino, uint32_t *crc, long long *csize) -{ -#if USE_ZLIB - struct z_stream_s z; - int i; - size_t osize = 0; -#endif /* USE_ZLIB */ - char *ibuf, *obuf = 0; - - if (st->st_size > 196608 || (ibuf = malloc(st->st_size)) == 0) { -#if USE_ZLIB - if (zipclevel < 04) - return zipwdesc(fd, fn, st, bp, sz, dev, ino, - crc, csize); -#endif /* USE_ZLIB */ - return zipwtemp(fd, fn, st, bp, sz, dev, ino, crc, csize); - } - *csize = 0; - if (read(fd, ibuf, st->st_size) != st->st_size) { - free(ibuf); - emsg(3, "Cannot read \"%s\"", fn); - close(fd); - return -1; - } - *crc = zipcrc(0, (unsigned char *)ibuf, st->st_size); -#if USE_BZLIB - if (zipclevel == 07) { - unsigned int sb; - if ((obuf = malloc(sb = st->st_size)) == 0) - goto store; - if (BZ2_bzBuffToBuffCompress(obuf, &sb, ibuf, st->st_size, - 9, 0, 0) != BZ_OK) - goto store; - *csize = sb; - bp->Zdr.z_cmethod[0] = C_BZIP2; - bp->Zdr.z_version[0] = 0x2e; - goto out; - } -#endif /* USE_BZLIB */ - if (zipclevel > 03) - goto store; -#if USE_ZLIB - memset(&z, 0, sizeof z); - if (deflateInit2(&z, ziptrlevel(), Z_DEFLATED, -15, - 8, Z_DEFAULT_STRATEGY) < 0) - goto store; - z.next_in = (unsigned char *)ibuf; - z.avail_in = z.total_in = st->st_size; - do { - if (z.avail_out == 0) { - if ((obuf = realloc(obuf, osize += 4096)) == 0) { - deflateEnd(&z); - goto store; - } - z.next_out = (unsigned char *)&obuf[*csize]; - z.avail_out = osize - *csize; - } - if ((i = deflate(&z, z.avail_in ? Z_NO_FLUSH : Z_FINISH)) < 0) { - deflateEnd(&z); - goto store; - } - *csize = osize - z.avail_out; - } while (z.avail_in || i != Z_STREAM_END); - deflateEnd(&z); - if (*csize < st->st_size) { - bp->Zdr.z_cmethod[0] = C_DEFLATED; - bp->Zdr.z_gflag[0] |= zipclevel << 1; - bp->Zdr.z_version[0] = 20; - } else -#endif /* USE_ZLIB */ - store: *csize = st->st_size; -#if USE_BZLIB -out: -#endif /* USE_BZLIB */ - le32p(*crc, bp->Zdr.z_crc32); - le32p(*csize, bp->Zdr.z_csize); - bwrite((char *)bp, SIZEOF_zip_header); - bwrite(fn, sz); - zipwxtra(fn, st, dev, ino); - switch (bp->Zdr.z_cmethod[0]) { - case C_DEFLATED: - case C_BZIP2: - bwrite(obuf, *csize); - break; - default: - bwrite(ibuf, *csize); - } - free(ibuf); - free(obuf); - close(fd); - return 0; -} - -/* - * Write and compress data to a zip archive for a file that is to large - * too be kept in memory. If there is an error with the temporary file - * (e. g. no space left on device), the file is stored in uncompressed - * form. - */ -static int -zipwtemp(int fd, const char *fn, struct stat *st, union bincpio *bp, size_t sz, - uint32_t dev, uint32_t ino, uint32_t *crc, long long *csize) -{ - static int tf = -1; - static char tlate[] = "/var/tmp/cpioXXXXXX"; - char ibuf[32768]; -#if USE_ZLIB || USE_BZLIB - char obuf[32768]; -#endif /* USE_ZLIB || USE_BZLIB */ - struct zextra_64 zf; - struct zextra_64 *zfp = 0; - long long size = st->st_size; - const char *sname; - int cuse, sf; - ssize_t rd; - - *csize = 0; - *crc = 0; -#if USE_ZLIB || USE_BZLIB - if (tf < 0) { - if ((tf = mkstemp(tlate)) >= 0) - unlink(tlate); - } else if (lseek(tf, 0, SEEK_SET) != 0) { - close(tf); - tf = -1; - } -#endif /* USE_ZLIB || USE_BZLIB */ -#if USE_ZLIB - if (zipclevel < 04) { - struct z_stream_s z; - memset(&z, 0, sizeof z); - if ((cuse = deflateInit2(&z, ziptrlevel(), Z_DEFLATED, - -15, 8, Z_DEFAULT_STRATEGY)) < 0) - goto store; - do { - if (z.avail_in == 0 && size > 0) { - if ((rd = read(fd, ibuf, sizeof ibuf)) <= 0) { - emsg(3, "Cannot read \"%s\"", fn); - close(fd); - ftruncate(tf, 0); - return -1; - } - z.next_in = (unsigned char *)ibuf; - z.avail_in = z.total_in = rd; - size -= rd; - *crc = zipcrc(*crc, (unsigned char *)ibuf, rd); - } - if (z.next_out == NULL || (char *)z.next_out > obuf) { - if (z.next_out && tf >= 0) { - if (write(tf, obuf, - (char *)z.next_out-obuf) != - (char *)z.next_out-obuf) { - close(tf); - tf = -1; - } - *csize += (char *)z.next_out - obuf; - } - z.next_out = (unsigned char *)obuf; - z.avail_out = sizeof obuf; - } - if (cuse >= 0 && cuse != Z_STREAM_END) - cuse = deflate(&z, - z.avail_in?Z_NO_FLUSH:Z_FINISH); - else - z.avail_in = 0; - } while (size>0 || (char *)z.next_out>obuf || - cuse>=0 && cuse!=Z_STREAM_END); - deflateEnd(&z); - goto out; - } -#endif /* USE_ZLIB */ -#if USE_BZLIB - if (zipclevel == 07) { - bz_stream bs; - int ok, on; - memset(&bs, sizeof bs, 0); - if ((ok = BZ2_bzCompressInit(&bs, 9, 0, 0)) != BZ_OK) - goto store; - cuse = 1; - do { - if (bs.avail_in == 0 && size > 0) { - if ((rd = read(fd, ibuf, sizeof ibuf)) <= 0) { - emsg(3, "Cannot read \"%s\"", fn); - close(fd); - ftruncate(tf, 0); - return -1; - } - bs.next_in = ibuf; - bs.avail_in = rd; - size -= rd; - *crc = zipcrc(*crc, (unsigned char *)ibuf, rd); - } - if (bs.next_out == NULL || bs.next_out > obuf) { - if (bs.next_out && tf >= 0) { - on = bs.next_out - obuf; - if (write(tf, obuf, on) != on) { - close(tf); - tf = -1; - } - *csize += on; - } - bs.next_out = obuf; - bs.avail_out = sizeof obuf; - } - if (ok != BZ_STREAM_END) { - switch (ok = BZ2_bzCompress(&bs, - bs.avail_in?BZ_RUN:BZ_FINISH)) { - case BZ_RUN_OK: - case BZ_FINISH_OK: - case BZ_STREAM_END: - break; - default: - msg(3, 1, "Compression error %d " - "on \"%s\"\n", ok, fn); - close(fd); - return -1; - } - } - } while (size > 0 || bs.next_out > obuf || ok != BZ_STREAM_END); - BZ2_bzCompressEnd(&bs); - goto out; - } -#endif /* USE_BZLIB */ -store: cuse = -1; - while (size > 0) { - if ((rd = read(fd, ibuf, sizeof ibuf)) <= 0) { - emsg(3, "Cannot read \"%s\"", fn); - close(fd); - return -1; - } - size -= rd; - *crc = zipcrc(*crc, (unsigned char *)ibuf, rd); - } -out: if (tf >= 0 && cuse >= 0 && *csize < st->st_size) { - if (zipclevel == 07) { - bp->Zdr.z_cmethod[0] = C_BZIP2; - bp->Zdr.z_version[0] = 0x2e; - } else { - bp->Zdr.z_cmethod[0] = C_DEFLATED; - bp->Zdr.z_gflag[0] |= zipclevel << 1; - bp->Zdr.z_version[0] = 20; - } - sf = tf; - sname = tlate; - } else { - *csize = st->st_size; - sf = fd; - sname = fn; - } - if ((lseek(sf, 0, SEEK_SET)) != 0) { - emsg(3, "Cannot rewind \"%s\"", sname); - errcnt++; - close(fd); - ftruncate(tf, 0); - return -1; - } - le32p(*crc, bp->Zdr.z_crc32); - if (st->st_size >= 0xffffffff || *csize >= 0xffffffff) { - int n; - zfp = &zf; - memset(&zf, 0, SIZEOF_zextra_64); - le16p(mag_zip64f, zf.ze_64_tag); - le16p(SIZEOF_zextra_64 - 4, zf.ze_64_tsize); - le64p(st->st_size, zf.ze_64_nsize); - le64p(*csize, zf.ze_64_csize); - le32p(0xffffffff, bp->Zdr.z_csize); - le32p(0xffffffff, bp->Zdr.z_nsize); - n = (ple16(bp->Zdr.z_extralen)&0177777) + SIZEOF_zextra_64; - le16p(n, bp->Zdr.z_extralen); - } else - le32p(*csize, bp->Zdr.z_csize); - bwrite((char *)bp, SIZEOF_zip_header); - bwrite(fn, sz); - if (zfp) - bwrite((char *)zfp, SIZEOF_zextra_64); - zipwxtra(fn, st, dev, ino); - size = *csize; - while (size) { - if ((rd=read(sf, ibuf, size>sizeof ibuf?sizeof ibuf:size)) <= 0) - msg(3, 1, "Cannot read \"%s\"\n", sname); - bwrite(ibuf, rd); - size -= rd; - } - ftruncate(tf, 0); - close(fd); - return 0; -} - -#if USE_ZLIB -/* - * Write a zip archive entry using the data descriptor structure. - */ -static int -zipwdesc(int fd, const char *fn, struct stat *st, union bincpio *bp, size_t sz, - uint32_t dev, uint32_t ino, uint32_t *crc, long long *csize) -{ - struct zextra_64 zf; - struct zextra_64 *zfp = 0; - char ibuf[32768], obuf[32768]; - long long size = st->st_size; - ssize_t rd; - struct z_stream_s z; - int cuse; - - *csize = 0; - *crc = 0; - memset(&z, 0, sizeof z); - if ((cuse = deflateInit2(&z, ziptrlevel(), Z_DEFLATED, - -15, 8, Z_DEFAULT_STRATEGY)) < 0) - return zipwtemp(fd, fn, st, bp, sz, dev, ino, crc, csize); - bp->Zdr.z_cmethod[0] = C_DEFLATED; - bp->Zdr.z_gflag[0] |= zipclevel << 1 | FG_DESC; - bp->Zdr.z_version[0] = 20; - /* - * RFC 1951 states that deflate compression needs 5 bytes additional - * space per 32k block in the worst case. Thus a compressed size - * greater than 4G-1 can be reached if at least 131052 blocks are - * used. - */ - if (st->st_size >= 131052LL*32768) { - int n; - zfp = &zf; - memset(&zf, 0, SIZEOF_zextra_64); - le16p(mag_zip64f, zf.ze_64_tag); - le16p(SIZEOF_zextra_64 - 4, zf.ze_64_tsize); - le32p(0xffffffff, bp->Zdr.z_csize); - le32p(0xffffffff, bp->Zdr.z_nsize); - n = (ple16(bp->Zdr.z_extralen)&0177777) + SIZEOF_zextra_64; - le16p(n, bp->Zdr.z_extralen); - } - bwrite((char *)bp, SIZEOF_zip_header); - bwrite(fn, sz); - if (zfp) - bwrite((char *)zfp, SIZEOF_zextra_64); - zipwxtra(fn, st, dev, ino); - do { - if (z.avail_in == 0 && size > 0) { - if ((rd = read(fd, ibuf, sizeof ibuf)) <= 0) { - emsg(3, "Cannot read \"%s\"", fn); - st->st_size -= size; - size = 0; /* can't simply stop here */ - rd = 0; /* no data */ - } - z.next_in = (unsigned char *)ibuf; - z.avail_in = z.total_in = rd; - size -= rd; - *crc = zipcrc(*crc, (unsigned char *)ibuf, rd); - } - if (z.next_out == NULL || (char *)z.next_out > obuf) { - if (z.next_out) { - bwrite(obuf, (char *)z.next_out - obuf); - *csize += (char *)z.next_out - obuf; - } - z.next_out = (unsigned char *)obuf; - z.avail_out = sizeof obuf; - } - if (cuse >= 0 && cuse != Z_STREAM_END) - cuse = deflate(&z, z.avail_in?Z_NO_FLUSH:Z_FINISH); - else - z.avail_in = 0; - } while (size > 0 || (char *)z.next_out > obuf || - cuse >= 0 && cuse != Z_STREAM_END); - deflateEnd(&z); - if (zfp) { - struct zipddesc64 zd64; - memcpy(zd64.zd_signature, mag_zipdds, sizeof mag_zipdds); - le32p(*crc, zd64.zd_crc32); - le64p(st->st_size, zd64.zd_nsize); - le64p(*csize, zd64.zd_csize); - bwrite((char *)&zd64, SIZEOF_zipddesc64); - } else { - struct zipddesc zd; - memcpy(zd.zd_signature, mag_zipdds, sizeof mag_zipdds); - le32p(*crc, zd.zd_crc32); - le32p(st->st_size, zd.zd_nsize); - le32p(*csize, zd.zd_csize); - bwrite((char *)&zd, SIZEOF_zipddesc); - } - close(fd); - return 0; -} -#endif /* USE_ZLIB */ - -/* - * Write the extra fields for a file to a zip archive (currently - * our own field type). Note that the z_extralen field in the file - * header must correspond to the size of the data written here. - */ -static int -zipwxtra(const char *fn, struct stat *st, uint32_t dev, uint32_t ino) -{ - struct zextra_cp z; - - memset(&z, 0, SIZEOF_zextra_cp); - le16p(mag_zipcpio, z.ze_cp_tag); - le16p(SIZEOF_zextra_cp - 4, z.ze_cp_tsize); - le32p(dev, z.ze_cp_mode); - le32p(ino, z.ze_cp_ino); - le32p(st->st_mode&(S_IFMT|07777), z.ze_cp_mode); - le32p(st->st_uid, z.ze_cp_uid); - le32p(st->st_gid, z.ze_cp_gid); - le32p(st->st_nlink, z.ze_cp_nlink); - le32p(st->st_rdev, z.ze_cp_rdev); - le32p(st->st_mtime, z.ze_cp_mtime); - le32p(st->st_atime, z.ze_cp_atime); - bwrite((char *)&z, SIZEOF_zextra_cp); - return SIZEOF_zextra_cp; -} - -static void -zipinfo(struct file *f) -{ - const char *cp; - char b[5]; - int i; - - printf(" %7llu", f->f_csize); - if (f->f_dsize) { - i = f->f_csize*100 / f->f_dsize; - i += f->f_csize*200 / f->f_dsize & 1; - i = 100 - i; - } else - i = 0; - printf(" %3d%%", i); - switch (f->f_cmethod) { - case C_STORED: - cp = "stor"; - break; - case C_SHRUNK: - cp = "shrk"; - break; - case C_REDUCED1: - cp = "re:1"; - break; - case C_REDUCED2: - cp = "re:2"; - break; - case C_REDUCED3: - cp = "re:3"; - break; - case C_REDUCED4: - cp = "re:4"; - break; - case C_IMPLODED: - b[0] = 'i'; - b[1] = f->f_gflag & FG_BIT1 ? '8' : '4'; - b[2] = ':'; - b[3] = f->f_gflag & FG_BIT2 ? '3' : '2'; - b[4] = '\0'; - cp = b; - break; - case C_TOKENIZED: - cp = "tokn"; - break; - case C_DEFLATED: - b[0] = 'd', b[1] = 'e', b[2] = 'f', b[4] = '\0'; - if (f->f_gflag & FG_BIT2) - b[3] = f->f_gflag & FG_BIT1 ? 'S' : 'F'; - else - b[3] = f->f_gflag & FG_BIT1 ? 'X' : 'N'; - cp = b; - break; - case C_ENHDEFLD: - cp = "edef"; - break; - case C_DCLIMPLODED: - cp = "dcli"; - break; - case C_BZIP2: - cp = "bz2 "; - break; - default: - snprintf(b, sizeof b, "%4.4X", f->f_cmethod); - cp = b; - } - printf(" %s", cp); -} - -#if USE_BZLIB -int -zipunbz2(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) -{ - bz_stream bs; - long long isize = f->f_csize; - char ibuf[4096], obuf[8192]; - int in, on, val = 0, ok; - - memset(&bs, 0, sizeof bs); - - if ((ok = BZ2_bzDecompressInit(&bs, 0, 0)) != BZ_OK) { - msg(3, 0, "bzip2 initialization error %d on \"%s\"\n", - ok, f->f_name); - errcnt++; - return skipfile(f); - } - while (isize > 0 || ok == BZ_OK) { - if (bs.avail_in == 0 && isize > 0) { - in = sizeof ibuf < isize ? sizeof ibuf : isize; - isize -= in; - if (bread(ibuf, in) != in) - unexeoa(); - if (doswap) - swap(ibuf, in, bflag || sflag, bflag || Sflag); - bs.next_in = ibuf; - bs.avail_in = in; - } - if (ok == BZ_OK) { - bs.next_out = obuf; - bs.avail_out = sizeof obuf; - switch (ok = BZ2_bzDecompress(&bs)) { - case BZ_OK: - case BZ_STREAM_END: - on = sizeof obuf - bs.avail_out; - if (tfd >= 0 && write(tfd, obuf, on) != on) { - emsg(3, "Cannot write \"%s\"", tgt); - tfd = -1; - val = 1; - } - *crc = zipcrc(*crc, (unsigned char *)obuf, on); - break; - default: - msg(3, 0, "compression error %d on \"%s\"\n", - ok, f->f_name); - errcnt++; - val = 1; - } - } - } - BZ2_bzDecompressEnd(&bs); - return val; -} -#endif /* USE_BZLIB */ - -struct blasthow { - struct file *bh_f; - const char *bh_tgt; - long long bh_isize; - uint32_t *bh_crc; - int bh_tfd; - int bh_doswap; - int bh_val; -}; - -static unsigned -blastin(void *how, unsigned char **buf) -{ - const int chunk = 16384; - static unsigned char *hold; - struct blasthow *bp = how; - unsigned sz; - - if (bp->bh_isize <= 0) - return 0; - if (hold == NULL) - hold = smalloc(chunk); - sz = bp->bh_isize > chunk ? chunk : bp->bh_isize; - bp->bh_isize -= sz; - if (bread((char *)hold, sz) != sz) - unexeoa(); - if (bp->bh_doswap) - swap((char *)hold, sz, bflag || sflag, bflag || Sflag); - *buf = hold; - return sz; -} - -static int -blastout(void *how, unsigned char *buf, unsigned len) -{ - struct blasthow *bp = how; - - if (bp->bh_tfd >= 0 && write(bp->bh_tfd, buf, len) != len) { - emsg(3, "Cannot write \"%s\"", bp->bh_tgt); - bp->bh_tfd = -1; - bp->bh_val = 1; - } - *bp->bh_crc = zipcrc(*bp->bh_crc, buf, len); - return 0; -} - -int -zipblast(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) -{ - struct blasthow bh; - int n; - - bh.bh_f = f; - bh.bh_tgt = tgt; - bh.bh_isize = f->f_csize; - bh.bh_crc = crc; - bh.bh_tfd = tfd; - bh.bh_doswap = doswap; - bh.bh_val = 0; - switch (n = blast(blastin, &bh, blastout, &bh)) { - case 0: - break; - default: - msg(3, 0, "compression error %d on \"%s\"\n", n, f->f_name); - errcnt++; - bh.bh_val = 1; - } - while (bh.bh_isize) { - char buf[4096]; - unsigned n; - n = bh.bh_isize > sizeof buf ? sizeof buf : bh.bh_isize; - if (bread(buf, n) != n) - unexeoa(); - bh.bh_isize -= n; - } - return bh.bh_val; -} - -/* - * The SGI -K format was introduced with SGI's IRIX 5.X. It is essentially - * a slightly extended binary format. The known additions are: - * - * - If the major or minor st_rdev device number exceeds the limit of - * 255 imposed by the 16-bit c_rdev field, this field is set to 0xFFFF - * and st_rdev is stored in the c_filesize 32-bit field. The first 14 - * bits of this field compose the major device number, the minor is - * stored in the remaining 18 bits. This enables implementations to - * read the modified format without special support if they ignore - * the size of device files; otherwise they will try to read a lot - * of archive data and fail. - * - * - If the file is larger than 2 GB - 1 byte, two nearly identical - * archive headers are stored for it. The only difference is in - * the c_filesize field: - * - * [first header: file size X times 2 GB] - * [first data part: X times 2 GB] - * [second header: file size modulo 2 GB] - * [second data part: rest of data] - * - * The first header can be recognized by a negative c_filesize. A - * value of 0xFFFFFFFF means that 2 GB follow, 0xFFFFFFFE -> 4 GB - * 0xFFFFFFFD -> 6 GB, 0xFFFFFFFC -> 8 GB, and so forth. The second - * is a standard binary cpio header, although the following data is - * meant to be appended to the preceding file. - * - * It is important to note that padding follows the number in - * c_filesize, not the amount of data written; thus all data parts - * with odd c_filesize fields (0xFFFFFFFF = 2+ GB, 0xFFFFFFFD = 6+ GB - * etc.) cause the following archive entries to be aligned on an odd - * offset. This seems to be an implementation artifact but has to be - * followed for compatibility. - * - * This extension seems a bit weird since no known cpio implementation - * is able to read these archive entries without special support. Thus - * a more straightforward extension (such as storing the size just past - * the file name) would well have had the same effect. Nevertheless, - * the cpio -K format is useful, so it is implemented here. - * - * --Note that IRIX 6.X tar also has a -K option. This option extends - * the tar format in essentially the same way as the second extension - * to cpio described above. Unfortunately, the result is definitively - * broken. Contrasting to the binary cpio format, the standard POSIX - * tar format is well able to hold files of size 0xFFFFFFFF and below - * in a regular manner. Thus, a tar -K archive entry is _exactly_ the - * same as two regular POSIX tar entries for the same file. And this - * situation even occurs on a regular basis with tar -r! For this - * reason, we do not implement the IRIX tar -K format and will probably - * never do so unless it is changed (the tar format really has a lot - * of options to indicate extensions that might be used for this). - * - * Many thanks to Sven Mascheck who made archiving tests on the IRIX - * machine. - */ -/* - * This function reads the second header of a SGI -K format archive. - */ -static void -readK2hdr(struct file *f) -{ - struct file n; - union bincpio bc; - - n.f_name = n.f_lnam = NULL; - n.f_nsiz = n.f_lsiz = 0; - readhdr(&n, &bc); - f->f_Krest = n.f_st.st_size; - f->f_dsize = f->f_st.st_size = n.f_st.st_size + f->f_Kbase; - f->f_Kbase = 0; - free(n.f_name); - free(n.f_lnam); -} - -/* - * Read the data of a GNU filename extra header. - */ -static int -readgnuname(char **np, size_t *sp, long length) -{ - if (length > SANELIMIT) - return -1; - if (*sp == 0 || *sp <= length) - *np = srealloc(*np, *sp = length+1); - bread(*np, length); - (*np)[length] = '\0'; - skippad(length, 512); - return 0; -} - -/* - * Write a GNU filename extra header and its data. - */ -static void -writegnuname(const char *fn, long length, int flag) -{ - union bincpio bc; - - memset(bc.data, 0, 512); - strcpy(bc.Tdr.t_name, "././@LongLink"); - sprintf(bc.Tdr.t_mode, "%7.7o", 0); - sprintf(bc.Tdr.t_uid, "%7.7o", 0); - sprintf(bc.Tdr.t_gid, "%7.7o", 0); - sprintf(bc.Tdr.t_size, "%11.11lo", length); - sprintf(bc.Tdr.t_mtime, "%11.11lo", 0L); - bc.Tdr.t_linkflag = flag; - memcpy(bc.Tdr.t_magic, mag_gnutar, 8); - strcpy(bc.Tdr.t_uname, "root"); - strcpy(bc.Tdr.t_gname, "root"); - tchksum(&bc); - bwrite(bc.data, 512); - bwrite(fn, length); - length %= 512; - memset(bc.data, 0, 512 - length); - bwrite(bc.data, 512 - length); -} - -/* - * POSIX.1-2001 pax format support. - */ -static void -tgetpax(struct tar_header *tp, struct file *f) -{ - char *keyword, *value; - char *block, *bp; - long long n; - enum paxrec pr; - - n = rdoct(tp->t_size, 12); - bp = block = smalloc(n+1); - bread(block, n); - skippad(n, 512); - block[n] = '\0'; - while (bp < &block[n]) { - int c; - pr = tgetrec(&bp, &keyword, &value); - switch (pr) { - case PR_ATIME: - f->f_st.st_atime = strtoll(value, NULL, 10); - break; - case PR_GID: - f->f_st.st_gid = strtoll(value, NULL, 10); - break; - case PR_LINKPATH: - c = strlen(value); - if (f->f_lnam == NULL || f->f_lsiz < c+1) { - f->f_lsiz = c+1; - f->f_lnam = srealloc(f->f_lnam, c+1); - } - strcpy(f->f_lnam, value); - break; - case PR_MTIME: - f->f_st.st_mtime = strtoll(value, NULL, 10); - break; - case PR_PATH: - c = strlen(value); - if (f->f_name == NULL || f->f_nsiz < c+1) { - f->f_nsiz = c+1; - f->f_name = srealloc(f->f_name, c+1); - } - strcpy(f->f_name, value); - break; - case PR_SIZE: - f->f_st.st_size = strtoll(value, NULL, 10); - break; - case PR_UID: - f->f_st.st_uid = strtoll(value, NULL, 10); - break; - case PR_SUN_DEVMAJOR: - f->f_rmajor = strtoll(value, NULL, 10); - break; - case PR_SUN_DEVMINOR: - f->f_rminor = strtoll(value, NULL, 10); - break; - } - paxrec |= pr; - } - if (tp->t_linkflag == 'g') { - globrec = paxrec & ~(PR_LINKPATH|PR_PATH|PR_SIZE); - globst = f->f_st; - } - free(block); -} - -static enum paxrec -tgetrec(char **bp, char **keyword, char **value) -{ - char *x; - long n = 0; - enum paxrec pr; - - *keyword = ""; - *value = ""; - while (**bp && (n = strtol(*bp, &x, 10)) <= 0 && (*x!=' ' || *x!='\t')) - do - (*bp)++; - while (**bp && **bp != '\n'); - if (*x == '\0' || **bp == '\0') { - (*bp)++; - return PR_NONE; - } - while (x < &(*bp)[n] && (*x == ' ' || *x == '\t')) - x++; - if (x == &(*bp)[n] || *x == '=') - goto out; - *keyword = x; - while (x < &(*bp)[n] && *x != '=') - x++; - if (x == &(*bp)[n]) - goto out; - *x = '\0'; - if (&x[1] < &(*bp)[n]) - *value = &x[1]; - (*bp)[n-1] = '\0'; -out: *bp = &(*bp)[n]; - if (strcmp(*keyword, "atime") == 0) - pr = PR_ATIME; - else if (strcmp(*keyword, "gid") == 0) - pr = PR_GID; - else if (strcmp(*keyword, "linkpath") == 0) - pr = PR_LINKPATH; - else if (strcmp(*keyword, "mtime") == 0) - pr = PR_MTIME; - else if (strcmp(*keyword, "path") == 0) - pr = PR_PATH; - else if (strcmp(*keyword, "size") == 0) - pr = PR_SIZE; - else if (strcmp(*keyword, "uid") == 0) - pr = PR_UID; - else if (strcmp(*keyword, "SUN.devmajor") == 0) - pr = PR_SUN_DEVMAJOR; - else if (strcmp(*keyword, "SUN.devminor") == 0) - pr = PR_SUN_DEVMINOR; - else - pr = PR_NONE; - return pr; -} - -static void -wrpax(const char *longname, const char *linkname, struct stat *sp) -{ - union bincpio bc; - char *pdata = NULL; - long psize = 0, pcur = 0; - long long blocks; - - memset(bc.data, 0, 512); - if (paxrec & PR_ATIME) - addrec(&pdata, &psize, &pcur, "atime", NULL, sp->st_atime); - if (paxrec & PR_GID) - addrec(&pdata, &psize, &pcur, "gid", NULL, sp->st_gid); - if (paxrec & PR_LINKPATH) - addrec(&pdata, &psize, &pcur, "linkpath", linkname, 0); - if (paxrec & PR_MTIME) - addrec(&pdata, &psize, &pcur, "mtime", NULL, sp->st_mtime); - if (paxrec & PR_PATH) - addrec(&pdata, &psize, &pcur, "path", longname, 0); - if (paxrec & PR_SIZE) - addrec(&pdata, &psize, &pcur, "size", NULL, sp->st_size); - if (paxrec & PR_UID) - addrec(&pdata, &psize, &pcur, "uid", NULL, sp->st_uid); - if (paxrec & PR_SUN_DEVMAJOR) - addrec(&pdata, &psize, &pcur, "SUN.devmajor", NULL, - major(sp->st_rdev)); - if (paxrec & PR_SUN_DEVMINOR) - addrec(&pdata, &psize, &pcur, "SUN.devminor", NULL, - minor(sp->st_rdev)); - paxnam(&bc.Tdr, longname); - sprintf(bc.Tdr.t_mode, "%7.7o", fmttype==FMT_SUN ? 0444|S_IFREG : 0444); - sprintf(bc.Tdr.t_uid, "%7.7o", 0); - sprintf(bc.Tdr.t_gid, "%7.7o", 0); - sprintf(bc.Tdr.t_size, "%11.11lo", pcur); - sprintf(bc.Tdr.t_mtime, "%11.11o", 0); - strcpy(bc.Tdr.t_magic, "ustar"); - bc.Tdr.t_version[0] = bc.Tdr.t_version[1] = '0'; - strcpy(bc.Tdr.t_uname, "root"); - strcpy(bc.Tdr.t_gname, "root"); - bc.Tdr.t_linkflag = fmttype==FMT_SUN ? 'X' : 'x'; - tchksum(&bc); - bwrite(bc.data, 512); - memset(&pdata[pcur], 0, psize - pcur); - blocks = (pcur + (512-1)) / 512; - bwrite(pdata, blocks * 512); - free(pdata); -} - -static void -addrec(char **pdata, long *psize, long *pcur, - const char *keyword, const char *sval, long long lval) -{ - char dval[25], xval[25]; - long od, d, r; - - if (sval == 0) { - sprintf(xval, "%lld", lval); - sval = xval; - } - r = strlen(keyword) + strlen(sval) + 3; - d = 0; - do { - od = d; - d = sprintf(dval, "%ld", od + r); - } while (d != od); - *psize += d + r + 1 + 512; - *pdata = srealloc(*pdata, *psize); - sprintf(&(*pdata)[*pcur], "%s %s=%s\n", dval, keyword, sval); - *pcur += d + r; -} - -static void -paxnam(struct tar_header *hp, const char *name) -{ - char buf[257], *bp; - const char *cp, *np; - int bl = 0; - static int pid; - - if (pid == 0) - pid = getpid(); - for (np = name; *np; np++); - while (np > name && *np != '/') { - np--; - bl++; - } - if ((np > name || *name == '/') && np-name <= 120) - for (bp = buf, cp = name; cp < np; bp++, cp++) - *bp = *cp; - else { - *buf = '.'; - bp = &buf[1]; - } - snprintf(bp, sizeof buf - (bp - buf), "/PaxHeaders.%d/%s", - pid, bl < 100 ? np>name?&np[1]:name : sequence()); - tmkname(hp, buf); -} - -static char * -sequence(void) -{ - static char buf[25]; - static long long d; - - sprintf(buf, "%10.10lld", ++d); - return buf; -} - -static int -pax_oneopt(const char *s, int warn) -{ - if (strcmp(s, "linkdata") == 0) - pax_oflag |= PO_LINKDATA; - else if (strcmp(s, "times") == 0) - pax_oflag |= PO_TIMES; - else { - if (warn) - msg(2, 0, "Unknown flag \"-o %s\"\n", s); - return -1; - } - return 0; -} - -int -pax_options(char *s, int warn) -{ - char *o = s, c; - int val = 0, word = 0; - - do { - if (word == 0) { - if (isspace(*s&0377)) - o = &s[1]; - else - word = 1; - } - if (*s == ',' || *s == '\0') { - c = *s; - *s = '\0'; - val |= pax_oneopt(o, warn); - *s = c; - o = &s[1]; - word = 0; - } - } while (*s++); - return val; -} - -/* - * Given a symbolic link "base" and the result of readlink "name", form - * a valid path name for the link target. - */ -static char * -joinpath(const char *base, char *name) -{ - const char *bp = NULL, *cp; - char *new, *np; - - if (*name == '/') - return name; - for (cp = base; *cp; cp++) - if (*cp == '/') - bp = cp; - if (bp == NULL) - return name; - np = new = smalloc(bp - base + strlen(name) + 2); - for (cp = base; cp < bp; cp++) - *np++ = *cp; - *np++ = '/'; - for (cp = name; *cp; cp++) - *np++ = *cp; - *np = '\0'; - free(name); - return new; -} - -static int -utf8(const char *cp) -{ - int c, n; - - while (*cp) if ((c = *cp++ & 0377) & 0200) { - if (c == (c & 037 | 0300)) - n = 1; - else if (c == (c & 017 | 0340)) - n = 2; - else if (c == (c & 07 | 0360)) - n = 3; - else if (c == (c & 03 | 0370)) - n = 4; - else if (c == (c & 01 | 0374)) - n = 5; - else - return 0; - while (n--) { - c = *cp++ & 0377; - if (c != (c & 077 | 0200)) - return 0; - } - } - return 1; -} - -static time_t -fetchtime(const char *cp) -{ - struct tm tm; - time_t t; - char *xp; - int n; - - t = strtoll(cp, &xp, 10); - if (*xp == '\0') - return t; - memset(&tm, 0, sizeof tm); - n = sscanf(cp, "%4d%2d%2dT%2d%2d%2d", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec); - tm.tm_year -= 1900; - tm.tm_mon--; - tm.tm_isdst = -1; - t = mktime(&tm); - if (n < 3 || t == (time_t)-1) - msg(4, 1, "line %lld: illegal time \"%s\"\n", - lineno, cp); - return t; -} - -static char * -nextfield(char *cp, const char *fieldname) -{ - while (*cp && *cp != ':') - cp++; - if (*cp == 0) - msg(4, 1, "line %lld: unterminated \"%s\" field\n", - lineno, fieldname); - *cp++ = 0; - return cp; -} - -static char * -getproto(char *np, struct prototype *pp) -{ - char *tp, *xp; - long long t, u; - - memset(pp, 0, sizeof *pp); - if (*np == ':') - np++; - else { - tp = nextfield(np, "type"); - if (np[1]) - goto notype; - switch (np[0]) { - case 'b': - pp->pt_mode |= S_IFBLK; - break; - case 'c': - pp->pt_mode |= S_IFCHR; - break; - case 'd': - pp->pt_mode |= S_IFDIR; - break; - case 'f': - pp->pt_mode |= S_IFREG; - break; - case 'p': - pp->pt_mode |= S_IFIFO; - break; - case 's': - pp->pt_mode |= S_IFLNK; - break; - default: - notype: - msg(4, 1, "line %lld: unknown type \"%s\"\n", - lineno, np); - } - pp->pt_spec |= PT_TYPE; - np = tp; - } - if (*np == ':') - np++; - else { - struct passwd *pwd; - tp = nextfield(np, "owner"); - t = strtoll(np, &xp, 10); - if (*xp == '\0') - pp->pt_uid = t; - else { - if ((pwd = getpwnam(np)) == NULL) - msg(4, 1, "line %lld: unknown user \"%s\"\n", - lineno, np); - pp->pt_uid = pwd->pw_uid; - } - pp->pt_spec |= PT_OWNER; - np = tp; - } - if (*np == ':') - np++; - else { - struct group *grp; - tp = nextfield(np, "group"); - t = strtoll(np, &xp, 10); - if (*xp == '\0') - pp->pt_gid = t; - else { - if ((grp = getgrnam(np)) == NULL) - msg(4, 1, "line %lld: unknown group \"%s\"\n", - lineno, np); - pp->pt_gid = grp->gr_gid; - } - pp->pt_spec |= PT_GROUP; - np = tp; - } - if (*np == ':') - np++; - else { - tp = nextfield(np, "mode"); - t = strtol(np, &xp, 8); - if (t & ~07777 || *xp) - msg(4, 1, "line %lld: illegal mode \"%s\"\n", - lineno, np); - pp->pt_mode |= t; - pp->pt_spec |= PT_MODE; - np = tp; - } - if (*np == ':') - np++; - else { - tp = nextfield(np, "access time"); - pp->pt_atime = fetchtime(np); - pp->pt_spec |= PT_ATIME; - np = tp; - } - if (*np == ':') - np++; - else { - tp = nextfield(np, "modification time"); - pp->pt_mtime = fetchtime(np); - pp->pt_spec |= PT_MTIME; - np = tp; - } - if (*np == ':') { - np++; - if (*np++ != ':') - majmin: msg(4, 1, "line %lld: need either both major and " - "minor or none\n", - lineno); - } else { - tp = nextfield(np, "major"); - t = strtoll(np, &xp, 10); - if (*xp) - msg(4, 1, "line %lld: illegal major \"%s\"\n", - lineno, np); - np = tp; - if (*np == ':') - goto majmin; - tp = nextfield(np, "minor"); - u = strtoll(np, &xp, 10); - if (*xp) - msg(4, 1, "line %lld: illegal minor \"%s\"\n", - lineno, np); - np = tp; - pp->pt_rdev = makedev(t, u); - pp->pt_spec |= PT_RDEV; - } - return np; -} diff --git a/tools/cpio/src/cpio.h b/tools/cpio/src/cpio.h deleted file mode 100644 index 131a3d388..000000000 --- a/tools/cpio/src/cpio.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * cpio - copy file archives in and out - * - * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. - */ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ - -/* Sccsid @(#)cpio.h 1.29 (gritter) 3/26/07 */ - -#include -#include -#include - -enum { - FMT_NONE = 00000000, /* no format chosen yet */ - - TYP_PAX = 00000010, /* uses pax-like extended headers */ - TYP_BE = 00000100, /* this binary archive is big-endian */ - TYP_SGI = 00000200, /* SGI cpio -K flag binary archive */ - TYP_SCO = 00000200, /* SCO UnixWare 7.1 extended archive */ - TYP_CRC = 00000400, /* this has a SVR4 'crc' checksum */ - TYP_BINARY = 00001000, /* this is a binary cpio type */ - TYP_OCPIO = 00002000, /* this is an old cpio type */ - TYP_NCPIO = 00004000, /* this is a SVR4 cpio type */ - TYP_CRAY = 00010000, /* this is a Cray cpio archive */ - TYP_CPIO = 00077000, /* this is a cpio type */ - TYP_OTAR = 00100000, /* this is an old tar type */ - TYP_USTAR = 00200000, /* this is a ustar type */ - TYP_BAR = 00400000, /* this is a bar type */ - TYP_TAR = 00700000, /* this is a tar type */ - - FMT_ODC = 00002001, /* POSIX ASCII cpio format */ - FMT_DEC = 00002002, /* DEC extended cpio format */ - FMT_BINLE = 00003001, /* binary (default) cpio format LE */ - FMT_BINBE = 00003101, /* binary (default) cpio format BE */ - FMT_SGILE = 00003201, /* IRIX-style -K binary format LE */ - FMT_SGIBE = 00003301, /* IRIX-style -K binary format BE */ - FMT_ASC = 00004001, /* SVR4 ASCII cpio format */ - FMT_SCOASC = 00004201, /* UnixWare 7.1 ASCII cpio format */ - FMT_CRC = 00004401, /* SVR4 ASCII cpio format w/checksum */ - FMT_SCOCRC = 00004601, /* UnixWare 7.1 ASCII cpio w/checksum */ - FMT_CRAY = 00010001, /* Cray cpio, UNICOS 6 and later */ - FMT_CRAY5 = 00010002, /* Cray cpio, UNICOS 5 and earlier */ - FMT_OTAR = 00100001, /* obsolete tar format */ - FMT_TAR = 00200001, /* our tar format type */ - FMT_USTAR = 00200002, /* ustar format */ - FMT_GNUTAR = 00200003, /* GNU tar format type */ - FMT_PAX = 00200011, /* POSIX.1-2001 pax format type */ - FMT_SUN = 00200012, /* Sun extended tar format type */ - FMT_BAR = 00400001, /* bar format type */ - - FMT_ZIP = 01000000 /* zip format */ -} fmttype; - -/* - * Zip compression method. - */ -enum cmethod { - C_STORED = 0, /* no compression */ - C_SHRUNK = 1, - C_REDUCED1 = 2, - C_REDUCED2 = 3, - C_REDUCED3 = 4, - C_REDUCED4 = 5, - C_IMPLODED = 6, - C_TOKENIZED = 7, - C_DEFLATED = 8, - C_ENHDEFLD = 9, - C_DCLIMPLODED = 10, - C_PKRESERVED = 11, - C_BZIP2 = 12, -}; - -/* - * A collection of the interesting facts about a file in copy-in mode. - */ -struct file { - struct stat f_st; /* file stat */ - long long f_rmajor; /* st_rdev major */ - long long f_rminor; /* st_rdev minor */ - long long f_dsize; /* display size */ - long long f_csize; /* compressed size */ - long long f_Kbase; /* base size for -K */ - long long f_Krest; /* rest size for -K */ - long long f_Ksize; /* faked -K size field */ - char *f_name; /* file name */ - size_t f_nsiz; /* file name size */ - char *f_lnam; /* link name */ - size_t f_lsiz; /* link name size */ - uint32_t f_chksum; /* checksum */ - int f_pad; /* padding size */ - int f_fd; /* file descriptor (for pass mode) */ - enum cmethod f_cmethod; /* zip compression method */ - enum { - FG_CRYPT = 0001, /* encrypted zip file */ - FG_BIT1 = 0002, - FG_BIT2 = 0004, - FG_DESC = 0010 /* zip file with data descriptor */ - } f_gflag; /* zip general flag */ - enum { - OF_ZIP64 = 0001 /* is a zip64 archive entry */ - } f_oflag; /* other flags */ -}; - -/* - * Patterns for gmatch(). - */ -struct glist { - struct glist *g_nxt; - const char *g_pat; - unsigned g_gotcha : 1; - unsigned g_not : 1; - unsigned g_art : 1; -}; - -extern int aflag; -extern int Aflag; -extern int bflag; -extern int Bflag; -extern int cflag; -extern int Cflag; -extern int dflag; -extern int Dflag; -extern int eflag; -extern int cray_eflag; -extern const char *Eflag; -extern int fflag; -extern int Hflag; -extern const char *Iflag; -extern int kflag; -extern int Kflag; -extern int lflag; -extern int Lflag; -extern int mflag; -extern const char *Mflag; -extern const char *Oflag; -extern int Pflag; -extern int rflag; -extern const char *Rflag; -extern int sflag; -extern int Sflag; -extern int tflag; -extern int uflag; -extern int hp_Uflag; -extern int vflag; -extern int Vflag; -extern int sixflag; -extern int action; -extern long long errcnt; -extern int blksiz; -extern int sysv3; -extern int printsev; -extern char *progname; -extern struct glist *patterns; - -enum { /* type of pax command this is */ - PAX_TYPE_CPIO = 0, /* not a pax command */ - PAX_TYPE_PAX1992 = 1, /* POSIX.2 pax command */ - PAX_TYPE_PAX2001 = 2 /* POSIX.1-2001 pax command */ -} pax; -extern int pax_dflag; -extern int pax_kflag; -extern int pax_nflag; -extern int pax_sflag; -extern int pax_uflag; -extern int pax_Xflag; - -enum { - PAX_P_NONE = 0000, - PAX_P_ATIME = 0001, - PAX_P_MTIME = 0004, - PAX_P_OWNER = 0010, - PAX_P_MODE = 0020, - PAX_P_EVERY = 0400 -} pax_preserve; - -extern size_t (*ofiles)(char **, size_t *); -extern void (*prtime)(time_t); - -extern ssize_t bread(char *, size_t); -extern void bunread(const char *, size_t); -extern void swap(char *, size_t, int, int); -extern void msg(int, int, const char *, ...); -extern void emsg(int, const char *, ...); -extern void unexeoa(void); -extern int setfmt(char *); -extern char *oneintfmt(const char *); -extern int setreassign(const char *); -extern void addg(const char *, int); -extern void *srealloc(void *, size_t); -extern void *smalloc(size_t); -extern void *scalloc(size_t, size_t); -extern void *svalloc(size_t, int); -extern char *sstrdup(const char *); -extern int pax_options(char *, int); - -extern int zipunshrink(struct file *, const char *, int, int, uint32_t *); -extern int zipexplode(struct file *, const char *, int, int, uint32_t *); -extern int zipexpand(struct file *, const char *, int, int, uint32_t *); -extern int zipinflate(struct file *, const char *, int, int, uint32_t *); -extern int zipunbz2(struct file *, const char *, int, int, uint32_t *); -extern int zipblast(struct file *, const char *, int, int, uint32_t *); - -extern uint32_t zipcrc(uint32_t, const uint8_t *, size_t); - -extern void flags(int, char **); -extern void usage(void); - -extern int pax_track(const char *, time_t); -extern void pax_prlink(struct file *); -extern int pax_sname(char **, size_t *); -extern void pax_onexit(void); diff --git a/tools/cpio/src/crc32.c b/tools/cpio/src/crc32.c deleted file mode 100644 index 084cb52cf..000000000 --- a/tools/cpio/src/crc32.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. - * - * Derived from zlib 1.1.4 - * - * Sccsid @(#)crc32.c 1.2 (gritter) 5/29/03 - */ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2002 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - - Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. 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. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - */ - -#include "cpio.h" - -/* - * Table of CRC-32's of all single-byte values (made by make_crc_table) - */ -static const uint32_t crc_table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; - -#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); - -/* ========================================================================= */ -uint32_t -zipcrc(uint32_t crc, const uint8_t *buf, size_t len) -{ - if (buf == 0) - return 0L; - crc = crc ^ 0xffffffffL; - while (len >= 8) - { - DO8(buf); - len -= 8; - } - if (len) do { - DO1(buf); - } while (--len); - return crc ^ 0xffffffffL; -} diff --git a/tools/cpio/src/expand.c b/tools/cpio/src/expand.c deleted file mode 100644 index 5a5233f3e..000000000 --- a/tools/cpio/src/expand.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * cpio - copy file archives in and out - * - * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. - */ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ - -/* Sccsid @(#)expand.c 1.6 (gritter) 12/15/03 */ - -#include -#include -#include -#include -#include - -#include "cpio.h" - -#define DLE 144 - -static void -zexread(char *data, size_t size, int doswap) -{ - if (bread(data, size) != size) - unexeoa(); - if (doswap) - swap(data, size, bflag || sflag, bflag || Sflag); -} - -#define nextbyte() ( \ - ipos >= sizeof ibuf && isize > 0 ? ( \ - zexread(ibuf, isize>sizeof ibuf?sizeof ibuf:isize, doswap), \ - ipos = 0 \ - ) : 0, \ - isize--, \ - ibuf[ipos++] & 0377 \ -) - -#define nextbit() ( \ - ibit = ibit >= 7 ? (ibyte = nextbyte(), 0) : ibit + 1, \ - isize < 0 ? (ieof = 1, -1) : (ibyte & (1<> ibit \ -) - -#define sixbits(n) { \ - int t; \ - (n) = 0; \ - for (t = 0; t < 6; t++) \ - (n) |= nextbit() << t; \ -} - -#define eightbits(n) { \ - int t; \ - (n) = 0; \ - for (t = 0; t < 8; t++) \ - (n) |= nextbit() << t; \ -} - -static void -zexwrite(int *tfd, char *data, size_t size, uint32_t *crc, int *val, - const char *tgt, long long *nsize) -{ - if (size) { - if (size > *nsize) - size = *nsize; - if (*tfd >= 0 && write(*tfd, data, size) != size) { - emsg(3, "Cannot write \"%s\"", tgt); - *tfd = -1; - *val = -1; - } - *crc = zipcrc(*crc, (unsigned char *)data, size); - *nsize -= size; - } -} - -#define wadd(c) ( \ - wpos >= sizeof wbuf ? ( \ - zexwrite(&tfd, wbuf, sizeof wbuf, crc, &val, tgt, &nsize), \ - wpos = 0 \ - ) : 0, \ - wsize++, \ - wbuf[wpos++] = (c) \ -) - -#define zex_L(x) ( \ - f->f_cmethod == C_REDUCED1 ? (x) & 0177 : \ - f->f_cmethod == C_REDUCED2 ? (x) & 077 : \ - f->f_cmethod == C_REDUCED3 ? (x) & 037 : \ - /* f->f_cmethod == C_REDUCED4 */ (x) & 017 \ -) - -#define zex_F(x) ( \ - f->f_cmethod == C_REDUCED1 ? (x) == 0177 ? 2 : 3 : \ - f->f_cmethod == C_REDUCED2 ? (x) == 077 ? 2 : 3 : \ - f->f_cmethod == C_REDUCED3 ? (x) == 037 ? 2 : 3 : \ - /* f->f_cmethod == C_REDUCED4 */ (x) == 017 ? 2 : 3 \ -) - -#define zex_D(x, y) ( \ - f->f_cmethod == C_REDUCED1 ? (((x)&0200)>>7) * 0400 + (y) + 1 : \ - f->f_cmethod == C_REDUCED2 ? (((x)&0300)>>6) * 0400 + (y) + 1 : \ - f->f_cmethod == C_REDUCED3 ? (((x)&0340)>>5) * 0400 + (y) + 1 : \ - /* f->f_cmethod == C_REDUCED4 */ (((x)&0360)>>4) * 0400 + (y) + 1 \ -) - -int -zipexpand(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) -{ - char fset[256][33]; - char ibuf[4096], ibyte = 0, wbuf[8192]; - long ipos = sizeof ibuf, wpos = 0, isize = f->f_csize, wsize = 0; - int val = 0, ieof = 0; - int c = 0, i, j, k, n, ibit = 7, lastc, state, v = 0, len = 0; - long long nsize = f->f_st.st_size; - - *crc = 0; - memset(fset, 0, sizeof fset); - for (j = 255; j >= 0; j--) { - sixbits(n); - for (i = 0; i < n; i++) { - eightbits(fset[j][i]); - } - fset[j][32] = n<1?0:n<3?1:n<5?2:n<9?3:n<17?4:n<37?5:n<65?6:7; - } - lastc = 0; - state = 0; - while (ieof == 0) { - if (fset[lastc][32] == 0) { - eightbits(c); - } else { - if (nextbit() != 0) { - eightbits(c); - } else { - i = 0; - for (k = 0; k < fset[lastc][32]; k++) - i |= nextbit() << k; - c = fset[lastc][i] & 0377; - } - } - lastc = c; - switch (state) { - case 0: - if (c != DLE) - wadd(c); - else - state = 1; - break; - case 1: - if (c != 0) { - v = c; - len = zex_L(v); - state = zex_F(len); - } else { - wadd(DLE); - state = 0; - } - break; - case 2: - len += c; - state = 3; - break; - case 3: - n = wsize - zex_D(v, c); - for (i = 0; i < len + 3; i++) { - c = n+i >= 0 ? wbuf[n+i&sizeof wbuf-1]&0377 : 0; - wadd(c); - } - state = 0; - } - } - zexwrite(&tfd, wbuf, wpos, crc, &val, tgt, &nsize); - while (isize >= 0) - nextbyte(); - return val; -} diff --git a/tools/cpio/src/explode.c b/tools/cpio/src/explode.c deleted file mode 100644 index 863dbf672..000000000 --- a/tools/cpio/src/explode.c +++ /dev/null @@ -1,1138 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. - * - * Derived from unzip 5.40. - * - * Sccsid @(#)explode.c 1.6 (gritter) 9/30/03 - */ -/* explode.c -- put in the public domain by Mark Adler - version c15, 6 July 1996 */ - - -/* You can do whatever you like with this source file, though I would - prefer that if you modify it and redistribute it that you include - comments to that effect with your name and the date. Thank you. - - History: - vers date who what - ---- --------- -------------- ------------------------------------ - c1 30 Mar 92 M. Adler explode that uses huft_build from inflate - (this gives over a 70% speed improvement - over the original unimplode.c, which - decoded a bit at a time) - c2 4 Apr 92 M. Adler fixed bug for file sizes a multiple of 32k. - c3 10 Apr 92 M. Adler added a little memory tracking if DEBUG - c4 11 Apr 92 M. Adler added NOMEMCPY do kill use of memcpy() - c5 21 Apr 92 M. Adler added the WSIZE #define to allow reducing - the 32K window size for specialized - applications. - c6 31 May 92 M. Adler added typecasts to eliminate some warnings - c7 27 Jun 92 G. Roelofs added more typecasts. - c8 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch. - c9 19 Jul 93 J. Bush added more typecasts (to return values); - made l[256] array static for Amiga. - c10 8 Oct 93 G. Roelofs added used_csize for diagnostics; added - buf and unshrink arguments to flush(); - undef'd various macros at end for Turbo C; - removed NEXTBYTE macro (now in unzip.h) - and bytebuf variable (not used); changed - memset() to memzero(). - c11 9 Jan 94 M. Adler fixed incorrect used_csize calculation. - c12 9 Apr 94 G. Roelofs fixed split comments on preprocessor lines - to avoid bug in Encore compiler. - c13 25 Aug 94 M. Adler fixed distance-length comment (orig c9 fix) - c14 22 Nov 95 S. Maxwell removed unnecessary "static" on auto array - c15 6 Jul 96 W. Haidinger added ulg typecasts to flush() calls. - c16 8 Feb 98 C. Spieler added ZCONST modifiers to const tables - and #ifdef DEBUG around debugging code. - c16b 25 Mar 98 C. Spieler modified DLL code for slide redirection. - - 23 May 03 Gunnar Ritter use cpio structures; C99 conversion. - */ - - -/* - Explode imploded (PKZIP method 6 compressed) data. This compression - method searches for as much of the current string of bytes (up to a length - of ~320) in the previous 4K or 8K bytes. If it doesn't find any matches - (of at least length 2 or 3), it codes the next byte. Otherwise, it codes - the length of the matched string and its distance backwards from the - current position. Single bytes ("literals") are preceded by a one (a - single bit) and are either uncoded (the eight bits go directly into the - compressed stream for a total of nine bits) or Huffman coded with a - supplied literal code tree. If literals are coded, then the minimum match - length is three, otherwise it is two. - - There are therefore four kinds of imploded streams: 8K search with coded - literals (min match = 3), 4K search with coded literals (min match = 3), - 8K with uncoded literals (min match = 2), and 4K with uncoded literals - (min match = 2). The kind of stream is identified in two bits of a - general purpose bit flag that is outside of the compressed stream. - - Distance-length pairs for matched strings are preceded by a zero bit (to - distinguish them from literals) and are always coded. The distance comes - first and is either the low six (4K) or low seven (8K) bits of the - distance (uncoded), followed by the high six bits of the distance coded. - Then the length is six bits coded (0..63 + min match length), and if the - maximum such length is coded, then it's followed by another eight bits - (uncoded) to be added to the coded length. This gives a match length - range of 2..320 or 3..321 bytes. - - The literal, length, and distance codes are all represented in a slightly - compressed form themselves. What is sent are the lengths of the codes for - each value, which is sufficient to construct the codes. Each byte of the - code representation is the code length (the low four bits representing - 1..16), and the number of values sequentially with that length (the high - four bits also representing 1..16). There are 256 literal code values (if - literals are coded), 64 length code values, and 64 distance code values, - in that order at the beginning of the compressed stream. Each set of code - values is preceded (redundantly) with a byte indicating how many bytes are - in the code description that follows, in the range 1..256. - - The codes themselves are decoded using tables made by huft_build() from - the bit lengths. That routine and its comments are in the inflate.c - module. - */ - -#include -#include -#include -#include - -#include "cpio.h" -#include "unzip.h" /* must supply slide[] (uint8_t) array and NEXTBYTE macro */ - -/* routines here */ -static int get_tree(struct globals *, unsigned *l, unsigned n); -static int explode_lit8(struct globals *, struct huft *tb, struct huft *tl, - struct huft *td, int bb, int bl, int bd); -static int explode_lit4(struct globals *, struct huft *tb, struct huft *tl, - struct huft *td, int bb, int bl, int bd); -static int explode_nolit8(struct globals *, struct huft *tl, struct huft *td, - int bl, int bd); -static int explode_nolit4(struct globals *, struct huft *tl, struct huft *td, - int bl, int bd); - -/* The implode algorithm uses a sliding 4K or 8K byte window on the - uncompressed stream to find repeated byte strings. This is implemented - here as a circular buffer. The index is updated simply by incrementing - and then and'ing with 0x0fff (4K-1) or 0x1fff (8K-1). Here, the 32K - buffer of inflate is used, and it works just as well to always have - a 32K circular buffer, so the index is anded with 0x7fff. This is - done to allow the window to also be used as the output buffer. */ -/* This must be supplied in an external module useable like - "uint8_t slide[8192];" or "uint8_t *slide;", where the latter would - be malloc'ed. In unzip, slide[] is actually a 32K area for use by - inflate, which uses a 32K sliding window. - */ - - -/* Tables for length and distance */ -static const uint16_t cplen2[] = - {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65}; -static const uint16_t cplen3[] = - {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66}; -static const uint8_t extra[] = - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8}; -static const uint16_t cpdist4[] = - {1, 65, 129, 193, 257, 321, 385, 449, 513, 577, 641, 705, - 769, 833, 897, 961, 1025, 1089, 1153, 1217, 1281, 1345, 1409, 1473, - 1537, 1601, 1665, 1729, 1793, 1857, 1921, 1985, 2049, 2113, 2177, - 2241, 2305, 2369, 2433, 2497, 2561, 2625, 2689, 2753, 2817, 2881, - 2945, 3009, 3073, 3137, 3201, 3265, 3329, 3393, 3457, 3521, 3585, - 3649, 3713, 3777, 3841, 3905, 3969, 4033}; -static const uint16_t cpdist8[] = - {1, 129, 257, 385, 513, 641, 769, 897, 1025, 1153, 1281, - 1409, 1537, 1665, 1793, 1921, 2049, 2177, 2305, 2433, 2561, 2689, - 2817, 2945, 3073, 3201, 3329, 3457, 3585, 3713, 3841, 3969, 4097, - 4225, 4353, 4481, 4609, 4737, 4865, 4993, 5121, 5249, 5377, 5505, - 5633, 5761, 5889, 6017, 6145, 6273, 6401, 6529, 6657, 6785, 6913, - 7041, 7169, 7297, 7425, 7553, 7681, 7809, 7937, 8065}; - - -/* Macros for inflate() bit peeking and grabbing. - The usage is: - - NEEDBITS(j) - x = b & mask_bits[j]; - DUMPBITS(j) - - where NEEDBITS makes sure that b has at least j bits in it, and - DUMPBITS removes the bits from b. The macros use the variable k - for the number of bits in b. Normally, b and k are register - variables for speed. - */ - -#define NEEDBITS(n) {while(k<(n)){b|=((uint32_t)NEXTBYTE)<>=(n);k-=(n);} - -#define Bits 16 -#define Nob 16 -#define Eob 15 - -#define G (*Gp) - -static int -get_tree(struct globals *Gp, unsigned *l, unsigned n) -/*unsigned *l;*/ /* bit lengths */ -/*unsigned n;*/ /* number expected */ -/* Get the bit lengths for a code representation from the compressed - stream. If get_tree() returns 4, then there is an error in the data. - Otherwise zero is returned. */ -{ - unsigned i; /* bytes remaining in list */ - unsigned k; /* lengths entered */ - unsigned j; /* number of codes */ - unsigned b; /* bit length for those codes */ - - - /* get bit lengths */ - i = NEXTBYTE + 1; /* length/count pairs to read */ - k = 0; /* next code */ - do { - b = ((j = NEXTBYTE) & 0xf) + 1; /* bits in code (1..16) */ - j = ((j & 0xf0) >> 4) + 1; /* codes with those bits (1..16) */ - if (k + j > n) - return 4; /* don't overflow l[] */ - do { - l[k++] = b; - } while (--j); - } while (--i); - return k != n ? 4 : 0; /* should have read n of them */ -} - - - -static int -explode_lit8(struct globals *Gp, - struct huft *tb, struct huft *tl, struct huft *td, - int bb, int bl, int bd) -/*struct huft *tb, *tl, *td;*/ /* literal, length, and distance tables */ -/*int bb, bl, bd;*/ /* number of bits decoded by those */ -/* Decompress the imploded data using coded literals and an 8K sliding - window. */ -{ - long s; /* bytes to decompress */ - register unsigned e; /* table entry flag/number of extra bits */ - unsigned n, d; /* length and index for copy */ - unsigned w; /* current window position */ - struct huft *t; /* pointer to table entry */ - unsigned mb, ml, md; /* masks for bb, bl, and bd bits */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - unsigned u; /* true if unflushed */ - - - /* explode the coded data */ - b = k = w = 0; /* initialize bit buffer, window */ - u = 1; /* buffer unflushed */ - mb = mask_bits[bb]; /* precompute masks for speed */ - ml = mask_bits[bl]; - md = mask_bits[bd]; - s = G.ucsize; - while (s > 0) /* do until ucsize bytes uncompressed */ - { - NEEDBITS(1) - if (b & 1) /* then literal--decode it */ - { - DUMPBITS(1) - s--; - NEEDBITS((unsigned)bb) /* get coded literal */ - if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - redirSlide[w++] = (uint8_t)t->v.n; - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - } - else /* else distance/length */ - { - DUMPBITS(1) - NEEDBITS(7) /* get distance low bits */ - d = (unsigned)b & 0x7f; - DUMPBITS(7) - NEEDBITS((unsigned)bd) /* get coded distance high bits */ - if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - d = w - d - t->v.n; /* construct offset */ - NEEDBITS((unsigned)bl) /* get coded length */ - if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - n = t->v.n; - if (e) /* get length extra bits */ - { - NEEDBITS(8) - n += (unsigned)b & 0xff; - DUMPBITS(8) - } - - /* do the copy */ - s -= n; - do { - n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); - if (u && w <= d) - { - memset(redirSlide + w, 0, e); - w += e; - d += e; - } - else -#ifndef NOMEMCPY - if (w - d >= e) /* (this test assumes unsigned comparison) */ - { - memcpy(redirSlide + w, redirSlide + d, e); - w += e; - d += e; - } - else /* do it slow to avoid memcpy() overlap */ -#endif /* !NOMEMCPY */ - do { - redirSlide[w++] = redirSlide[d++]; - } while (--e); - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - } while (n); - } - } - - /* flush out redirSlide */ - flush(&G, redirSlide, (uint32_t)w); - if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ - { /* sometimes read one too many: k>>3 compensates */ - /*G.used_csize = G.zsize - G.csize - G.incnt - (k >> 3);*/ - return 5; - } - return 0; -} - - - -static int -explode_lit4(struct globals *Gp, - struct huft *tb, struct huft *tl, struct huft *td, - int bb, int bl, int bd) -/*struct huft *tb, *tl, *td;*/ /* literal, length, and distance tables */ -/*int bb, bl, bd;*/ /* number of bits decoded by those */ -/* Decompress the imploded data using coded literals and a 4K sliding - window. */ -{ - long s; /* bytes to decompress */ - register unsigned e; /* table entry flag/number of extra bits */ - unsigned n, d; /* length and index for copy */ - unsigned w; /* current window position */ - struct huft *t; /* pointer to table entry */ - unsigned mb, ml, md; /* masks for bb, bl, and bd bits */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - unsigned u; /* true if unflushed */ - - - /* explode the coded data */ - b = k = w = 0; /* initialize bit buffer, window */ - u = 1; /* buffer unflushed */ - mb = mask_bits[bb]; /* precompute masks for speed */ - ml = mask_bits[bl]; - md = mask_bits[bd]; - s = G.ucsize; - while (s > 0) /* do until ucsize bytes uncompressed */ - { - NEEDBITS(1) - if (b & 1) /* then literal--decode it */ - { - DUMPBITS(1) - s--; - NEEDBITS((unsigned)bb) /* get coded literal */ - if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - redirSlide[w++] = (uint8_t)t->v.n; - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - } - else /* else distance/length */ - { - DUMPBITS(1) - NEEDBITS(6) /* get distance low bits */ - d = (unsigned)b & 0x3f; - DUMPBITS(6) - NEEDBITS((unsigned)bd) /* get coded distance high bits */ - if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - d = w - d - t->v.n; /* construct offset */ - NEEDBITS((unsigned)bl) /* get coded length */ - if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - n = t->v.n; - if (e) /* get length extra bits */ - { - NEEDBITS(8) - n += (unsigned)b & 0xff; - DUMPBITS(8) - } - - /* do the copy */ - s -= n; - do { - n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); - if (u && w <= d) - { - memset(redirSlide + w, 0, e); - w += e; - d += e; - } - else -#ifndef NOMEMCPY - if (w - d >= e) /* (this test assumes unsigned comparison) */ - { - memcpy(redirSlide + w, redirSlide + d, e); - w += e; - d += e; - } - else /* do it slow to avoid memcpy() overlap */ -#endif /* !NOMEMCPY */ - do { - redirSlide[w++] = redirSlide[d++]; - } while (--e); - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - } while (n); - } - } - - /* flush out redirSlide */ - flush(&G, redirSlide, (uint32_t)w); - if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ - { /* sometimes read one too many: k>>3 compensates */ - /*G.used_csize = G.zsize - G.csize - G.incnt - (k >> 3);*/ - return 5; - } - return 0; -} - - - -static int -explode_nolit8(struct globals *Gp, - struct huft *tl, struct huft *td, int bl, int bd) -/*struct huft *tl, *td;*/ /* length and distance decoder tables */ -/*int bl, bd;*/ /* number of bits decoded by tl[] and td[] */ -/* Decompress the imploded data using uncoded literals and an 8K sliding - window. */ -{ - long s; /* bytes to decompress */ - register unsigned e; /* table entry flag/number of extra bits */ - unsigned n, d; /* length and index for copy */ - unsigned w; /* current window position */ - struct huft *t; /* pointer to table entry */ - unsigned ml, md; /* masks for bl and bd bits */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - unsigned u; /* true if unflushed */ - - - /* explode the coded data */ - b = k = w = 0; /* initialize bit buffer, window */ - u = 1; /* buffer unflushed */ - ml = mask_bits[bl]; /* precompute masks for speed */ - md = mask_bits[bd]; - s = G.ucsize; - while (s > 0) /* do until ucsize bytes uncompressed */ - { - NEEDBITS(1) - if (b & 1) /* then literal--get eight bits */ - { - DUMPBITS(1) - s--; - NEEDBITS(8) - redirSlide[w++] = (uint8_t)b; - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - DUMPBITS(8) - } - else /* else distance/length */ - { - DUMPBITS(1) - NEEDBITS(7) /* get distance low bits */ - d = (unsigned)b & 0x7f; - DUMPBITS(7) - NEEDBITS((unsigned)bd) /* get coded distance high bits */ - if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - d = w - d - t->v.n; /* construct offset */ - NEEDBITS((unsigned)bl) /* get coded length */ - if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - n = t->v.n; - if (e) /* get length extra bits */ - { - NEEDBITS(8) - n += (unsigned)b & 0xff; - DUMPBITS(8) - } - - /* do the copy */ - s -= n; - do { - n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); - if (u && w <= d) - { - memset(redirSlide + w, 0, e); - w += e; - d += e; - } - else -#ifndef NOMEMCPY - if (w - d >= e) /* (this test assumes unsigned comparison) */ - { - memcpy(redirSlide + w, redirSlide + d, e); - w += e; - d += e; - } - else /* do it slow to avoid memcpy() overlap */ -#endif /* !NOMEMCPY */ - do { - redirSlide[w++] = redirSlide[d++]; - } while (--e); - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - } while (n); - } - } - - /* flush out redirSlide */ - flush(&G, redirSlide, (uint32_t)w); - if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ - { /* sometimes read one too many: k>>3 compensates */ - /*G.used_csize = G.zsize - G.csize - G.incnt - (k >> 3);*/ - return 5; - } - return 0; -} - - - -static int -explode_nolit4(struct globals *Gp, - struct huft *tl, struct huft *td, int bl, int bd) -/*struct huft *tl, *td;*/ /* length and distance decoder tables */ -/*int bl, bd;*/ /* number of bits decoded by tl[] and td[] */ -/* Decompress the imploded data using uncoded literals and a 4K sliding - window. */ -{ - long s; /* bytes to decompress */ - register unsigned e; /* table entry flag/number of extra bits */ - unsigned n, d; /* length and index for copy */ - unsigned w; /* current window position */ - struct huft *t; /* pointer to table entry */ - unsigned ml, md; /* masks for bl and bd bits */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - unsigned u; /* true if unflushed */ - - - /* explode the coded data */ - b = k = w = 0; /* initialize bit buffer, window */ - u = 1; /* buffer unflushed */ - ml = mask_bits[bl]; /* precompute masks for speed */ - md = mask_bits[bd]; - s = G.ucsize; - while (s > 0) /* do until ucsize bytes uncompressed */ - { - NEEDBITS(1) - if (b & 1) /* then literal--get eight bits */ - { - DUMPBITS(1) - s--; - NEEDBITS(8) - redirSlide[w++] = (uint8_t)b; - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - DUMPBITS(8) - } - else /* else distance/length */ - { - DUMPBITS(1) - NEEDBITS(6) /* get distance low bits */ - d = (unsigned)b & 0x3f; - DUMPBITS(6) - NEEDBITS((unsigned)bd) /* get coded distance high bits */ - if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - d = w - d - t->v.n; /* construct offset */ - NEEDBITS((unsigned)bl) /* get coded length */ - if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - n = t->v.n; - if (e) /* get length extra bits */ - { - NEEDBITS(8) - n += (unsigned)b & 0xff; - DUMPBITS(8) - } - - /* do the copy */ - s -= n; - do { - n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); - if (u && w <= d) - { - memset(redirSlide + w, 0, e); - w += e; - d += e; - } - else -#ifndef NOMEMCPY - if (w - d >= e) /* (this test assumes unsigned comparison) */ - { - memcpy(redirSlide + w, redirSlide + d, e); - w += e; - d += e; - } - else /* do it slow to avoid memcpy() overlap */ -#endif /* !NOMEMCPY */ - do { - redirSlide[w++] = redirSlide[d++]; - } while (--e); - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - } while (n); - } - } - - /* flush out redirSlide */ - flush(&G, redirSlide, (uint32_t)w); - if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ - { /* sometimes read one too many: k>>3 compensates */ - /*G.used_csize = G.zsize - G.csize - G.incnt - (k >> 3);*/ - return 5; - } - return 0; -} - -#undef G - -int -zipexplode(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) -/* Explode an imploded compressed stream. Based on the general purpose - bit flag, decide on coded or uncoded literals, and an 8K or 4K sliding - window. Construct the literal (if any), length, and distance codes and - the tables needed to decode them (using huft_build() from inflate.c), - and call the appropriate routine for the type of data in the remainder - of the stream. The four routines are nearly identical, differing only - in whether the literal is decoded or simply read in, and in how many - bits are read in, uncoded, for the low distance bits. */ -{ - struct globals G; - unsigned r; /* return codes */ - struct huft *tb; /* literal code table */ - struct huft *tl; /* length code table */ - struct huft *td; /* distance code table */ - int bb; /* bits for tb */ - int bl; /* bits for tl */ - int bd; /* bits for td */ - unsigned l[256]; /* bit lengths for codes */ - - memset(&G, 0, sizeof G); - G.tgt = tgt; - G.tfd = tfd; - G.doswap = doswap; - G.crc = crc; - G.zsize = G.uzsize = f->f_csize; - G.ucsize = f->f_st.st_size; - - /* Tune base table sizes. Note: I thought that to truly optimize speed, - I would have to select different bl, bd, and bb values for different - compressed file sizes. I was surprised to find out that the values of - 7, 7, and 9 worked best over a very wide range of sizes, except that - bd = 8 worked marginally better for large compressed sizes. */ - bl = 7; - bd = (G.csize + G.incnt) > 200000L ? 8 : 7; - - - /* With literal tree--minimum match length is 3 */ -#ifdef DEBUG - G.hufts = 0; /* initialize huft's malloc'ed */ -#endif - if (f->f_gflag & FG_BIT2) - { - bb = 9; /* base table size for literals */ - if ((r = get_tree(&G, l, 256)) != 0) - goto err; - if ((r = huft_build(l, 256, 256, NULL, NULL, &tb, &bb, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(tb); - goto err; - } - if ((r = get_tree(&G, l, 64)) != 0) - goto err; - if ((r = huft_build(l, 64, 0, cplen3, extra, &tl, &bl, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(tl); - huft_free(tb); - goto err; - } - if ((r = get_tree(&G, l, 64)) != 0) - goto err; - if (f->f_gflag & FG_BIT1) /* true if 8K */ - { - if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(td); - huft_free(tl); - huft_free(tb); - goto err; - } - r = explode_lit8(&G, tb, tl, td, bb, bl, bd); - } - else /* else 4K */ - { - if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(td); - huft_free(tl); - huft_free(tb); - goto err; - } - r = explode_lit4(&G, tb, tl, td, bb, bl, bd); - } - huft_free(td); - huft_free(tl); - huft_free(tb); - } - else - - - /* No literal tree--minimum match length is 2 */ - { - if ((r = get_tree(&G, l, 64)) != 0) - goto err; - if ((r = huft_build(l, 64, 0, cplen2, extra, &tl, &bl, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(tl); - goto err; - } - if ((r = get_tree(&G, l, 64)) != 0) - goto err; - if (f->f_gflag & FG_BIT1) /* true if 8K */ - { - if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(td); - huft_free(tl); - goto err; - } - r = explode_nolit8(&G, tl, td, bl, bd); - } - else /* else 4K */ - { - if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(td); - huft_free(tl); - goto err; - } - r = explode_nolit4(&G, tl, td, bl, bd); - } - huft_free(td); - huft_free(tl); - } - Trace((stderr, "<%u > ", G.hufts)); -err: - switch (r) { - case 0: - break; - case 5: - while (G.uzsize > 0) - NEXTBYTE; - /*FALLTHRU*/ - default: - msg(3, 0, "compression error on \"%s\"\n", f->f_name); - } - return r || G.status ? -1 : 0; -} - -/* The following code is derived from: */ - -/* inflate.c -- put in the public domain by Mark Adler - version c16b, 29 March 1998 */ - -/* If BMAX needs to be larger than 16, then h and x[] should be uint32_t. */ -#define BMAX 16 /* maximum bit length of any code (16 for explode) */ -#define N_MAX 288 /* maximum number of codes in any set */ - - -int -huft_build(const unsigned *b, unsigned n, unsigned s, - const uint16_t *d, const uint8_t *e, - struct huft **t, int *m, - int bits, int nob, int eob) -/*const unsigned *b;*/ /* code lengths in bits (all assumed <= BMAX) */ -/*unsigned n;*/ /* number of codes (assumed <= N_MAX) */ -/*unsigned s;*/ /* number of simple-valued codes (0..s-1) */ -/*const uint16_t *d;*/ /* list of base values for non-simple codes */ -/*const uint16_t *e;*/ /* list of extra bits for non-simple codes */ -/*struct huft **t;*/ /* result: starting table */ -/*int *m;*/ /* maximum lookup bits, returns actual */ -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return zero on success, one if - the given code set is incomplete (the tables are still built in this - case), two if the input is invalid (all zero length codes or an - oversubscribed set of lengths), and three if not enough memory. - The code with value 256 is special, and the tables are constructed - so that no bits beyond that code are fetched when that code is - decoded. */ -{ - unsigned a; /* counter for codes of length k */ - unsigned c[BMAX+1]; /* bit length count table */ - unsigned el; /* length of EOB code (value 256) */ - unsigned f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register unsigned i; /* counter, current code */ - register unsigned j; /* counter */ - register int k; /* number of bits in current code */ - int lx[BMAX+1]; /* memory for l[-1..BMAX-1] */ - int *l = lx+1; /* stack of bits per table */ - register unsigned *p; /* pointer into c[], b[], or v[] */ - register struct huft *q; /* points to current table */ - struct huft r; /* table entry for structure assignment */ - struct huft *u[BMAX]; /* table stack */ - unsigned v[N_MAX]; /* values in order of bit length */ - register int w; /* bits before this table == (l * h) */ - unsigned x[BMAX+1]; /* bit offsets, then code stack */ - unsigned *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - unsigned z; /* number of entries in current table */ - - - /* Generate counts for each bit length */ - el = n > 256 ? b[256] : BMAX; /* set length of EOB code, if any */ - memset(c, 0, sizeof c); - p = (unsigned *)b; i = n; - do { - c[*p]++; p++; /* assume all entries <= BMAX */ - } while (--i); - if (c[0] == n) /* null input--all zero length codes */ - { - *t = NULL; - *m = 0; - return 0; - } - - - /* Find minimum and maximum length, bound *m by those */ - for (j = 1; j <= BMAX; j++) - if (c[j]) - break; - k = j; /* minimum code length */ - if ((unsigned)*m < j) - *m = j; - for (i = BMAX; i; i--) - if (c[i]) - break; - g = i; /* maximum code length */ - if ((unsigned)*m > i) - *m = i; - - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return 2; /* bad input: more codes than bits */ - if ((y -= c[i]) < 0) - return 2; - c[i] += y; - - - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - - /* Make a table of values in order of bit lengths */ - memset(v, 0, sizeof v); - p = (unsigned *)b; i = 0; - do { - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); - n = x[g]; /* set n to length of v */ - - - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = l[-1] = 0; /* no bits decoded yet */ - u[0] = NULL; /* just to keep compilers happy */ - q = NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = c[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l[h]) - { - w += l[h++]; /* add bits already decoded */ - - /* compute minimum size table less than or equal to *m bits */ - z = (z = g - w) > (unsigned)*m ? *m : z; /* upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - if ((unsigned)w + j > el && (unsigned)w < el) - j = el - w; /* make EOB code end at table */ - z = 1 << j; /* table entries for j-bit table */ - l[h] = j; /* set table size in stack */ - - /* allocate and link in new table */ - if ((q = malloc((z + 1)*sizeof(struct huft))) == NULL) - { - if (h) - huft_free(u[0]); - return 3; /* not enough memory */ - } -#ifdef DEBUG - G.hufts += z + 1; /* track memory usage */ -#endif - *t = q + 1; /* link to list for huft_free() */ - *(t = &(q->v.t)) = NULL; - u[h] = ++q; /* table starts after link */ - - /* connect to last table, if there is one */ - if (h) - { - x[h] = i; /* save pattern for backing up */ - r.b = (uint8_t)l[h-1]; /* bits to dump before this table */ - r.e = (uint8_t)(bits + j); /* bits in this table */ - r.v.t = q; /* pointer to this table */ - j = (i & ((1 << w) - 1)) >> (w - l[h-1]); - u[h-1][j] = r; /* connect to last table */ - } - } - - /* set up table entry in r */ - r.b = (uint8_t)(k - w); - if (p >= v + n) - r.e = 99; /* out of values--invalid code */ - else if (*p < s) - { - r.e = (uint8_t)(*p < 256 ? nob : eob); /* 256 is end-of-block code */ - r.v.n = (uint16_t)*p++; /* simple code is just the value */ - } - else - { - r.e = (uint8_t)e[*p - s]; /* non-simple--look up in lists */ - r.v.n = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - while ((i & ((1 << w) - 1)) != x[h]) - w -= l[--h]; /* don't need to update q */ - } - } - - - /* return actual size of base table */ - *m = l[0]; - - - /* Return true (1) if we were given an incomplete table */ - return y != 0 && g != 1; -} - - -void -huft_free(struct huft *t) -/*struct huft *t;*/ /* table to free */ -/* Free the malloc'ed tables built by huft_build(), which makes a linked - list of the tables it made, with the links in a dummy first entry of - each table. */ -{ - register struct huft *p, *q; - - - /* Go through linked list, freeing from the malloced (t[-1]) address. */ - p = t; - while (p != NULL) - { - q = (--p)->v.t; - free(p); - p = q; - } -} - -const uint16_t mask_bits[] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - -void -flush(struct globals *Gp, const void *data, size_t size) -{ - if (Gp->tfd>=0 && write(Gp->tfd, data, size) != size) { - emsg(3, "Cannot write \"%s\"", Gp->tgt); - Gp->tfd = -1; - Gp->status = -1; - } - *Gp->crc = zipcrc(*Gp->crc, data, size); -} - -int -readbyte(struct globals *Gp) -{ - if (Gp->uzsize <= 0) - return EOF; - Gp->incnt = bread((char *)Gp->inbuf, - Gp->uzsize>sizeof Gp->inbuf?sizeof Gp->inbuf:Gp->uzsize); - if (Gp->incnt <= 0) - unexeoa(); - if (Gp->doswap) - swap((char *)Gp->inbuf, Gp->incnt, bflag||sflag,bflag||Sflag); - Gp->uzsize -= Gp->incnt; - Gp->incnt--; - Gp->inptr = Gp->inbuf; - return (int)(*Gp->inptr++); -} diff --git a/tools/cpio/src/flags.c b/tools/cpio/src/flags.c deleted file mode 100644 index e06c8e80d..000000000 --- a/tools/cpio/src/flags.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * cpio - copy file archives in and out - * - * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. - */ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ - -/* Sccsid @(#)flags.c 1.6 (gritter) 3/26/07 */ - -#include -#include -#include -#include - -#include "cpio.h" - -void -flags(int ac, char **av) -{ - const char optstring[] = - "iopaAbBcC:dDeE:fH:I:kKlLmM:O:PrR:sStTuvV6"; - int i, illegal = 0; - - if (getenv("SYSV3") != NULL) - sysv3 = printsev = 1; - while ((i = getopt(ac, av, optstring)) != EOF) { - switch (i) { - case 'i': - case 'o': - case 'p': - if (action && action != i) - illegal = 1; - action = i; - break; - case 'a': - aflag = 1; - break; - case 'A': - Aflag = 1; - break; - case 'b': - bflag = 1; - break; - case 'B': - blksiz = 5120; - Bflag = 1; - break; - case 'c': - fmttype = sysv3 ? FMT_ODC : FMT_ASC; - cflag = 1; - break; - case 'C': - if ((blksiz = atol(optarg)) <= 0) - msg(4, -2, - "Illegal size given for -C option.\n"); - Cflag = 1; - break; - case 'd': - dflag = 1; - break; - case 'D': - Dflag = 1; - break; - case 'e': - /* - * This option is accepted for compatibility only, - * -Hdec should be used instead. - */ - fmttype = FMT_DEC; - eflag = 1; - break; - case 'E': - Eflag = optarg; - break; - case 'f': - fflag = 1; - break; - case 'H': - if (setfmt(optarg) < 0) - illegal = 1; - Hflag = 1; - break; - case 'I': - Iflag = optarg; - break; - case 'k': - kflag = 1; - break; - case 'K': - /* - * This option is accepted for compatibility only, - * -Hsgi should be used instead. - */ - fmttype = FMT_SGIBE; - Kflag = 1; - break; - case 'l': - lflag = 1; - break; - case 'L': - Lflag = 1; - break; - case 'm': - mflag = 1; - break; - case 'M': - Mflag = oneintfmt(optarg); - break; - case 'O': - Oflag = optarg; - break; - case 'P': - Pflag = 1; - break; - case 'r': - rflag = 1; - break; - case 'R': - if (setreassign(Rflag = optarg) < 0) - illegal = 1; - break; - case 's': - sflag = 1; - break; - case 'S': - Sflag = 1; - break; - case 't': - tflag = 1; - break; - case 'u': - uflag = 1; - break; - case 'v': - vflag++; - break; - case 'V': - Vflag = 1; - break; - case '6': - sixflag = 1; - fmttype = FMT_BINLE; - break; - default: - if (sysv3) - usage(); - illegal = 1; - } - } - switch (action) { - case 'i': - if (Oflag || Kflag || eflag || Lflag || lflag || aflag || - Aflag || Pflag) - illegal = 1; - for (i = optind; i < ac; i++) - addg(av[i], 0); - break; - case 'o': - if (Iflag || dflag || fflag || kflag || mflag || - rflag || tflag || uflag || - sixflag || Eflag || Rflag) - illegal = 1; - if (optind != ac) - illegal = 1; - break; - case 'p': - if (Iflag || Oflag || blksiz || Eflag || fmttype != FMT_NONE || - Mflag || bflag || fflag || kflag || sflag || - tflag || Sflag || sixflag) - illegal = 1; - if (optind + 1 != ac) - illegal = 1; - break; - default: - if (sysv3 == 0) - msg(3, 0, "One of -i, -o or -p must be specified.\n"); - else if (ac > 1) - msg(3, -2, "Options must include one: -o, -i, -p.\n"); - illegal = 1; - } - /* - * Sanity checks. No check for multiple occurences of options - * since they can make sense, behave as other programs and use - * the latter one. - */ - /*if (aflag && mflag) { - msg(3, 0, "-a and -m are mutually exclusive.\n"); - illegal = 1; - } why? */ - /*if (cflag && (Hflag || Kflag || eflag)) { - msg(3, 0, "-c and -H are mutually exclusive.\n"); - illegal = 1; - } allow overriding -c with -H and vice versa */ - if ((vflag || tflag) && Vflag) { - msg(3, 0, "-v and -V are mutually exclusive.\n"); - illegal = 1; - } - /*if (Bflag && Cflag) { - msg(3, 0, "-B and -C are mutually exclusive.\n"); - illegal = 1; - } allow overriding of block sizes */ - if ((Hflag || cflag || Kflag || eflag) && sixflag) { - msg(3, 0, "-H and -6 are mutually exclusive.\n"); - illegal = 1; - } - if (!sysv3 && Mflag && Oflag == NULL && Iflag == NULL) { - msg(3, 0, "-M not meaningful without -O or -I.\n"); - illegal = 1; - } - if (!sysv3 && Aflag && Oflag == NULL) { - msg(3, 0, "-A requires the -O option\n"); - illegal = 1; - } - if (illegal) - usage(); -} - -void -usage(void) -{ - if (sysv3) - fprintf(stderr, "\ -Usage: %s -o[acvVABL] [-Csize] [-Hhdr] [-Mmsg] collection\n\ -\t%s -o[acvVABL] -Ocollection [-Csize] [-Hhdr] [-Mmsg] SEGV. - */ -#undef _FILE_OFFSET_BITS -#endif /* !__linux__ */ - -#include -#include -#include -#include -#include - -#if defined (__UCLIBC__) -#include -#include -#define getdents(a, b, c) __getdents64(a, b, c) -#define dirent dirent64 -extern int getdents(int, struct dirent *, size_t); -#elif defined (__GLIBC__) || defined (__FreeBSD__) || defined (_AIX) || \ - defined (__NetBSD__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -#include -#define getdents(a, b, c) getdirentries((a), (char *)(b), (c), &(db->g_offs)) -#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -#undef d_ino -#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ - || __APPLE__ */ -#elif defined (__dietlibc__) -#include -#include -#else /* !__GLIBC__, !__dietlibc__ */ -#ifdef __hpux -#define _KERNEL -#endif /* __hpux */ -#include -#ifdef __hpux -#ifndef _INO64_T -typedef unsigned long long uint64_t; -typedef uint64_t ino64_t; -#endif /* !_INO64_T */ -#ifdef __LP64__ -#define dirent __dirent64 -#else /* !__LP64__ */ -#define dirent __dirent32 -#endif /* !__LP64__ */ -#define d_reclen __d_reclen -#define d_name __d_name -#define d_ino __d_ino -#endif /* __hpux */ -#endif /* !__GLIBC__, !__dietlibc__ */ - -#include "getdir.h" - -#define DIBSIZE 5120 - -struct getdb { -#if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \ - && !defined (__DragonFly__) && !defined (__APPLE__) - off_t g_offs; -#else /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - long g_offs; -#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - struct dirent *g_dirp; - const char *g_path; - struct direc g_dic; - union { - char g_dirbuf[DIBSIZE+1]; - struct dirent g_dummy[1]; - } g_u; - int g_num; - int g_fd; -}; - -struct getdb * -getdb_alloc(const char *path, int fd) -{ - struct getdb *db; - - if ((db = malloc(sizeof *db)) == NULL) - return NULL; - db->g_dirp = NULL; - db->g_offs = 0; - db->g_fd = fd; - db->g_path = path; - return db; -} - -void -getdb_free(struct getdb *db) -{ - free(db); -} - -struct direc * -getdir(struct getdb *db, int *err) -{ - int reclen; - - *err = 0; - while (db->g_dirp == NULL) - { - /*LINTED*/ - db->g_num = getdents(db->g_fd, - (struct dirent *)db->g_u.g_dirbuf, - DIBSIZE); - if (db->g_num <= 0) { - if (db->g_num < 0) - *err = errno; - db->g_offs = 0; - return NULL; - } - /*LINTED*/ - db->g_dirp = (struct dirent *)db->g_u.g_dirbuf; - while (db->g_dirp && -#if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \ - && !defined (__DragonFly__) && !defined (__APPLE__) - db->g_dirp->d_ino == 0 -#else /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - (db->g_dirp->d_fileno == 0 -#ifdef DT_WHT - || db->g_dirp->d_type == DT_WHT -#endif - ) -#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - ) - { - next: -#ifndef __DragonFly__ - reclen = db->g_dirp->d_reclen; -#else - reclen = _DIRENT_DIRSIZ(db->g_dirp); -#endif - if ((db->g_num -= reclen) == 0 || reclen == 0) - db->g_dirp = NULL; - else - db->g_dirp = - /*LINTED*/ - (struct dirent *)((char *)db->g_dirp - + reclen); - } - } -#if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \ - && !defined (__DragonFly__) && !defined (__APPLE__) - if (db->g_dirp->d_ino == 0) - goto next; - db->g_dic.d_ino = db->g_dirp->d_ino; -#else /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - if (db->g_dirp->d_fileno == 0 -#ifdef DT_WHT - || db->g_dirp->d_type == DT_WHT -#endif - ) - { - goto next; - } - db->g_dic.d_ino = db->g_dirp->d_fileno; -#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - db->g_dic.d_name = db->g_dirp->d_name; -#ifndef __DragonFly__ - reclen = db->g_dirp->d_reclen; -#else - reclen = _DIRENT_DIRSIZ(db->g_dirp); -#endif - if ((db->g_num -= reclen) == 0 || reclen == 0) - db->g_dirp = NULL; - else - /*LINTED*/ - db->g_dirp = (struct dirent *)((char *)db->g_dirp + reclen); - return &(db->g_dic); -} diff --git a/tools/cpio/src/getdir.h b/tools/cpio/src/getdir.h deleted file mode 100644 index 29d107b6f..000000000 --- a/tools/cpio/src/getdir.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)getdir.h 1.4 (gritter) 10/19/03 */ - -#include - -struct direc { - unsigned long long d_ino; - char *d_name; -}; - -extern struct getdb *getdb_alloc(const char *, int); -extern void getdb_free(struct getdb *); -extern struct direc *getdir(struct getdb *, int *); diff --git a/tools/cpio/src/getopt.c b/tools/cpio/src/getopt.c deleted file mode 100644 index 0a68ac8e9..000000000 --- a/tools/cpio/src/getopt.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * getopt() - command option parsing - * - * Gunnar Ritter, Freiburg i. Br., Germany, March 2002. - */ - -/* Sccsid @(#)getopt.c 1.6 (gritter) 12/16/07 */ - -#include -#include -#include -#include "msgselect.h" - -/* - * One should not think that re-implementing this is necessary, but - * - * - Some libcs print weird messages. - * - * - GNU libc getopt() is totally brain-damaged, as it requires special - * care _not_ to reorder parameters and can't be told to work correctly - * with ':' as first optstring character at all. - */ - -char *optarg = 0; -int optind = 1; -int opterr = 1; -int optopt = 0; -extern char *pfmt_label__; - -static void -error(const char *s, int c) -{ - /* - * Avoid including , in case its getopt() declaration - * conflicts. - */ - extern ssize_t write(int, const void *, size_t); - const char *msg = 0; - char *buf, *bp; - - if (pfmt_label__) - s = pfmt_label__; - switch (c) { - case '?': - msg = ": " msgselect("I","i") "llegal option -- "; - break; - case ':': - msg = ": " msgselect("O","o") "ption requires an argument -- "; - break; - } - bp = buf = alloca(strlen(s) + strlen(msg) + 2); - while (*s) - *bp++ = *s++; - while (*msg) - *bp++ = *msg++; - *bp++ = optopt; - *bp++ = '\n'; - write(2, buf, bp - buf); -} - -int -getopt(int argc, char *const argv[], const char *optstring) -{ - int colon; - static const char *lastp; - const char *curp; - - if (optstring[0] == ':') { - colon = 1; - optstring++; - } else - colon = 0; - if (lastp) { - curp = lastp; - lastp = 0; - } else { - if (optind >= argc || argv[optind] == 0 || - argv[optind][0] != '-' || - argv[optind][1] == '\0') - return -1; - if (argv[optind][1] == '-' && argv[optind][2] == '\0') { - optind++; - return -1; - } - curp = &argv[optind][1]; - } - optopt = curp[0] & 0377; - while (optstring[0]) { - if (optstring[0] == ':') { - optstring++; - continue; - } - if ((optstring[0] & 0377) == optopt) { - if (optstring[1] == ':') { - if (curp[1] != '\0') { - optarg = (char *)&curp[1]; - optind++; - } else { - if ((optind += 2) > argc) { - if (!colon && opterr) - error(argv[0], ':'); - return colon ? ':' : '?'; - } - optarg = argv[optind - 1]; - } - } else { - if (curp[1] != '\0') - lastp = &curp[1]; - else - optind++; - optarg = 0; - } - return optopt; - } - optstring++; - } - if (!colon && opterr) - error(argv[0], '?'); - if (curp[1] != '\0') - lastp = &curp[1]; - else - optind++; - optarg = 0; - return '?'; -} - -#ifdef __APPLE__ -/* - * Starting with Mac OS 10.5 Leopard, turns getopt() - * into getopt$UNIX2003() by default. Consequently, this function - * is called instead of the one defined above. However, optind is - * still taken from this file, so in effect, options are not - * properly handled. Defining an own getopt$UNIX2003() function - * works around this issue. - */ -int -getopt$UNIX2003(int argc, char *const argv[], const char *optstring) -{ - return getopt(argc, argv, optstring); -} -#endif /* __APPLE__ */ diff --git a/tools/cpio/src/gmatch.c b/tools/cpio/src/gmatch.c deleted file mode 100644 index a2c5eb7ba..000000000 --- a/tools/cpio/src/gmatch.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Derived from /usr/src/cmd/sh/expand.c, Unix 7th Edition: - * - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * Redistributions of source code and documentation must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of - * other contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``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 CALDERA INTERNATIONAL, INC. 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. - */ - -#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 -#define USED __attribute__ ((used)) -#elif defined __GNUC__ -#define USED __attribute__ ((unused)) -#else -#define USED -#endif -static const char sccsid[] USED = "@(#)gmatch.sl 1.5 (gritter) 5/29/05"; - -#include -#include -#include - -#include "mbtowi.h" - -#define fetch(wc, s, n) ((mb_cur_max > 1 && *(s) & 0200 ? \ - ((n) = mbtowi(&(wc), (s), mb_cur_max), \ - (n) = ((n) > 0 ? (n) : (n) < 0 ? (wc = WEOF, 1) : 1)) :\ - ((wc) = *(s) & 0377, (n) = 1)), (s) += (n), (wc)) - -int -gmatch(const char *s, const char *p) -{ - const char *bs = s; - int mb_cur_max = MB_CUR_MAX; - wint_t c, scc; - int n; - - if (fetch(scc, s, n) == WEOF) - return (0); - switch (fetch(c, p, n)) { - - case '[': { - int ok = 0, excl; - unsigned long lc = ULONG_MAX; - const char *bp; - - if (*p == '!') { - p++; - excl = 1; - } else - excl = 0; - fetch(c, p, n); - bp = p; - while (c != '\0') { - if (c == ']' && p > bp) - return (ok ^ excl ? gmatch(s, p) : 0); - else if (c == '-' && p > bp && *p != ']') { - if (*p == '\\') - p++; - if (fetch(c, p, n) == '\0') - break; - if (lc <= scc && scc <= c) - ok = 1; - } else { - if (c == '\\') { - if (fetch(c, p, n) == '\0') - break; - } - if (scc == (lc = c)) - ok = 1; - } - fetch(c, p, n); - } - return (0); - } - - case '\\': - fetch(c, p, n); - if (c == '\0') - return (0); - /*FALLTHRU*/ - - default: - if (c != scc) - return (0); - /*FALLTHRU*/ - - case '?': - return (scc ? gmatch(s, p) : 0); - - case '*': - if (*p == '\0') - return (1); - s = bs; - while (*s) { - if (gmatch(s, p)) - return (1); - fetch(scc, s, n); - } - return (0); - - case '\0': - return (scc == '\0'); - - case WEOF: - return (0); - - } -} diff --git a/tools/cpio/src/ib_alloc.c b/tools/cpio/src/ib_alloc.c deleted file mode 100644 index 4020940ce..000000000 --- a/tools/cpio/src/ib_alloc.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_alloc.c 1.5 (gritter) 3/12/05 */ - -#include -#include -#include -#include -#include -#include -#include - -#include "memalign.h" -#include "iblok.h" - -struct iblok * -ib_alloc(int fd, unsigned blksize) -{ - static long pagesize; - struct iblok *ip; - struct stat st; - - if (pagesize == 0) - if ((pagesize = sysconf(_SC_PAGESIZE)) < 0) - pagesize = 4096; - if (blksize == 0) { - if (fstat(fd, &st) < 0) - return NULL; - blksize = st.st_blksize > 0 ? st.st_blksize : 512; - } - if ((ip = calloc(1, sizeof *ip)) == NULL) - return NULL; - if ((ip->ib_blk = memalign(pagesize, blksize)) == NULL) { - free(ip); - return NULL; - } - ip->ib_blksize = blksize; - ip->ib_fd = fd; - ip->ib_mb_cur_max = MB_CUR_MAX; - return ip; -} diff --git a/tools/cpio/src/ib_close.c b/tools/cpio/src/ib_close.c deleted file mode 100644 index 946bb9ef6..000000000 --- a/tools/cpio/src/ib_close.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_close.c 1.2 (gritter) 4/17/03 */ - -#include - -#include "iblok.h" - -int -ib_close(struct iblok *ip) -{ - int fd; - - fd = ip->ib_fd; - ib_free(ip); - return close(fd); -} diff --git a/tools/cpio/src/ib_free.c b/tools/cpio/src/ib_free.c deleted file mode 100644 index 72143afef..000000000 --- a/tools/cpio/src/ib_free.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_free.c 1.2 (gritter) 4/17/03 */ - -#include - -#include "iblok.h" - -void -ib_free(struct iblok *ip) -{ - free(ip->ib_blk); - free(ip); -} diff --git a/tools/cpio/src/ib_getlin.c b/tools/cpio/src/ib_getlin.c deleted file mode 100644 index ddee226b4..000000000 --- a/tools/cpio/src/ib_getlin.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_getlin.c 1.2 (gritter) 4/17/03 */ - -#include -#include -#include "iblok.h" - -size_t -ib_getlin(struct iblok *ip, char **line, size_t *alcd, - void *(*reallc)(void *, size_t)) -{ - char *nl; - size_t sz, llen = 0, nllen; - - for (;;) { - if (ip->ib_cur >= ip->ib_end) { - if (ip->ib_incompl) { - ip->ib_incompl = 0; - return 0; - } - if (ib_read(ip) == EOF) { - if (llen) { - ip->ib_incompl++; - (*line)[llen] = '\0'; - return llen; - } else - return 0; - } - /* - * ib_read() advances ib_cur since *ib_cur++ gives - * better performance than *++ib_cur for ib_get(). - * Go back again. - */ - ip->ib_cur--; - } - sz = ip->ib_end - ip->ib_cur; - if ((nl = memchr(ip->ib_cur, '\n', sz)) != NULL) { - sz = nl - ip->ib_cur + 1; - if ((nllen = llen + sz + 1) > *alcd) { - *line = reallc(*line, nllen); - *alcd = nllen; - } - memcpy(&(*line)[llen], ip->ib_cur, sz); - (*line)[llen + sz] = '\0'; - ip->ib_cur = nl + 1; - return llen + sz; - } - if ((nllen = llen + sz + 1) > *alcd) { - *line = reallc(*line, nllen); - *alcd = nllen; - } - memcpy(&(*line)[llen], ip->ib_cur, sz); - llen += sz; - ip->ib_cur = ip->ib_end; - } - /*NOTREACHED*/ - return 0; -} diff --git a/tools/cpio/src/ib_getw.c b/tools/cpio/src/ib_getw.c deleted file mode 100644 index b7f2e6762..000000000 --- a/tools/cpio/src/ib_getw.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_getw.c 1.5 (gritter) 7/16/04 */ - -#include -#include -#include "iblok.h" -#include "mbtowi.h" - -char * -ib_getw(struct iblok *ip, wint_t *wc, int *len) -{ - size_t rest; - int c, i, n; - - i = 0; - rest = ip->ib_mend - ip->ib_mcur; - if (rest && ip->ib_mcur > ip->ib_mbuf) { - do - ip->ib_mbuf[i] = ip->ib_mcur[i]; - while (i++, --rest); - } else if (ip->ib_incompl) { - ip->ib_incompl = 0; - *wc = WEOF; - ip->ib_mend = ip->ib_mcur = NULL; - return NULL; - } - if (i == 0) { - c = ib_get(ip); - if (c == EOF) { - *wc = WEOF; - ip->ib_mend = ip->ib_mcur = NULL; - return NULL; - } - ip->ib_mbuf[i++] = (char)c; - } - if (ip->ib_mbuf[0] & 0200) { - while (ip->ib_mbuf[i-1] != '\n' && i < ip->ib_mb_cur_max && - ip->ib_incompl == 0) { - c = ib_get(ip); - if (c != EOF) - ip->ib_mbuf[i++] = (char)c; - else - ip->ib_incompl = 1; - } - n = mbtowi(wc, ip->ib_mbuf, i); - if (n < 0) { - *len = 1; - *wc = WEOF; - } else if (n == 0) { - *len = 1; - *wc = '\0'; - } else - *len = n; - } else { - *wc = ip->ib_mbuf[0]; - *len = n = 1; - } - ip->ib_mcur = &ip->ib_mbuf[*len]; - ip->ib_mend = &ip->ib_mcur[i - *len]; - return ip->ib_mbuf; -} diff --git a/tools/cpio/src/ib_open.c b/tools/cpio/src/ib_open.c deleted file mode 100644 index 18e09c776..000000000 --- a/tools/cpio/src/ib_open.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_open.c 1.2 (gritter) 4/17/03 */ - -#include -#include -#include -#include -#include -#include -#include - -#include "iblok.h" - -struct iblok * -ib_open(const char *name, unsigned blksize) -{ - struct iblok *ip; - int fd, err; - - if ((fd = open(name, O_RDONLY)) < 0) - return NULL; - if ((ip = ib_alloc(fd, blksize)) == NULL) { - err = errno; - close(fd); - errno = err; - } - return ip; -} diff --git a/tools/cpio/src/ib_popen.c b/tools/cpio/src/ib_popen.c deleted file mode 100644 index 9aa873042..000000000 --- a/tools/cpio/src/ib_popen.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_popen.c 1.2 (gritter) 4/17/03 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iblok.h" - -struct iblok * -ib_popen(const char *cmd, unsigned blksize) -{ - struct iblok *ip; - int fd[2], err; - pid_t pid; - char *shell; - - if (pipe(fd) < 0) - return NULL; - switch (pid = fork()) { - case -1: - return NULL; - case 0: - close(fd[0]); - dup2(fd[1], 1); - close(fd[1]); - if ((shell = getenv("SHELL")) == NULL) - shell = "/bin/sh"; - execl(shell, shell, "-c", cmd, NULL); - _exit(0177); - /*NOTREACHED*/ - } - close(fd[1]); - if ((ip = ib_alloc(fd[0], blksize)) == NULL) { - err = errno; - close(fd[0]); - errno = err; - } - ip->ib_pid = pid; - return ip; -} - -int -ib_pclose(struct iblok *ip) -{ - struct sigaction oldhup, oldint, oldquit, act; - int status; - - close(ip->ib_fd); - act.sa_handler = SIG_IGN; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - sigaction(SIGHUP, &act, &oldhup); - sigaction(SIGINT, &act, &oldint); - sigaction(SIGQUIT, &act, &oldquit); - while (waitpid(ip->ib_pid, &status, 0) < 0 && errno == EINTR); - sigaction(SIGHUP, &oldhup, NULL); - sigaction(SIGINT, &oldint, NULL); - sigaction(SIGQUIT, &oldquit, NULL); - return status; -} diff --git a/tools/cpio/src/ib_read.c b/tools/cpio/src/ib_read.c deleted file mode 100644 index 3794f3e95..000000000 --- a/tools/cpio/src/ib_read.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_read.c 1.2 (gritter) 4/17/03 */ - -#include -#include -#include -#include -#include -#include -#include - -#include "iblok.h" - -int -ib_read(struct iblok *ip) -{ - ssize_t sz; - - do { - if ((sz = read(ip->ib_fd, ip->ib_blk, ip->ib_blksize)) > 0) { - ip->ib_endoff += sz; - ip->ib_cur = ip->ib_blk; - ip->ib_end = &ip->ib_blk[sz]; - return *ip->ib_cur++ & 0377; - } - } while (sz < 0 && errno == EINTR); - if (sz < 0) - ip->ib_errno = errno; - ip->ib_cur = ip->ib_end = NULL; - return EOF; -} diff --git a/tools/cpio/src/ib_seek.c b/tools/cpio/src/ib_seek.c deleted file mode 100644 index 48b2f99bc..000000000 --- a/tools/cpio/src/ib_seek.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_seek.c 1.4 (gritter) 5/8/03 */ - -#include -#include -#include -#include -#include -#include -#include - -#include "iblok.h" - -off_t -ib_seek(struct iblok *ip, off_t off, int whence) -{ - if (whence == SEEK_CUR) { - off = ip->ib_endoff - (ip->ib_end - ip->ib_cur); - whence = SEEK_SET; - } - if (ip->ib_seekable && whence == SEEK_SET && ip->ib_cur && ip->ib_end && - off < ip->ib_endoff && - off >= ip->ib_endoff - (ip->ib_end - ip->ib_blk)) { - ip->ib_cur = ip->ib_end - (ip->ib_endoff - off); - return off; - } - if ((off = lseek(ip->ib_fd, off, whence)) == (off_t)-1) - return -1; - ip->ib_cur = ip->ib_end = NULL; - ip->ib_endoff = off; - ip->ib_seekable = 1; - return off; -} diff --git a/tools/cpio/src/iblok.h b/tools/cpio/src/iblok.h deleted file mode 100644 index 66964627f..000000000 --- a/tools/cpio/src/iblok.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)iblok.h 1.5 (gritter) 7/16/04 */ - -/* - * Functions to read a file sequentially. - */ - -#include /* for off_t, pid_t */ -#include /* for EOF */ -#include /* for wchar_t */ -#include /* for MB_LEN_MAX */ - -struct iblok { - long long ib_endoff; /* offset of endc from start of file */ - char ib_mbuf[MB_LEN_MAX+1]; /* multibyte overflow buffer */ - char *ib_mcur; /* next byte to read in ib_mbuf */ - char *ib_mend; /* one beyond last byte in ib_mbuf */ - char *ib_blk; /* buffered data */ - char *ib_cur; /* next character in ib_blk */ - char *ib_end; /* one beyond last byte in ib_blk */ - int ib_fd; /* input file descriptor */ - int ib_errno; /* errno on error, or 0 */ - int ib_incompl; /* had an incomplete last line */ - int ib_mb_cur_max; /* MB_CUR_MAX at time of ib_alloc() */ - int ib_seekable; /* had a successful lseek() */ - pid_t ib_pid; /* child from ib_popen() */ - unsigned ib_blksize; /* buffer size */ -}; - -/* - * Allocate an input buffer with file descriptor fd. blksize may be - * either the size of a buffer to allocate in ib_blk, or 0 if the - * size is determined automatically. On error, NULL is returned and - * errno indicates the offending error. - */ -extern struct iblok *ib_alloc(int fd, unsigned blksize); - -/* - * Deallocate the passed input buffer. The file descriptor is not - * closed. - */ -extern void ib_free(struct iblok *ip); - -/* - * Open file name and do ib_alloc() on the descriptor. - */ -extern struct iblok *ib_open(const char *name, unsigned blksize); - -/* - * Close the file descriptor in ip and do ib_free(). Return value is - * the result of close(). - */ -extern int ib_close(struct iblok *ip); - -/* - * A workalike of popen(cmd, "r") using iblok facilities. - */ -extern struct iblok *ib_popen(const char *cmd, unsigned blksize); - -/* - * Close an iblok opened with ib_popen(). - */ -extern int ib_pclose(struct iblok *ip); - -/* - * Read new input buffer. Returns the next character (or EOF) and advances - * ib_cur by one above the bottom of the buffer. - */ -extern int ib_read(struct iblok *ip); - -/* - * Get next character. Return EOF at end-of-file or read error. - */ -#define ib_get(ip) ((ip)->ib_cur < (ip)->ib_end ? *(ip)->ib_cur++ & 0377 :\ - ib_read(ip)) - -/* - * Unget a character. Note that this implementation alters the read buffer. - * Caution: Calling this macro more than once might underflow ib_blk. - */ -#define ib_unget(c, ip) (*(--(ip)->ib_cur) = (char)(c)) - -/* - * Get file offset of last read character. - */ -#define ib_offs(ip) ((ip)->ib_endoff - ((ip)->ib_end - (ip)->ib_cur - 1)) - -/* - * Read a wide character using ib_get() facilities. *wc is used to store - * the wide character, or WEOF if an invalid byte sequence was found. - * The number of bytes consumed is stored in *len. Return value is the - * corresponding byte sequence, or NULL at end-of-file in input. - * - * Note that it is not possible to mix calls to ib_getw() with calls to - * ib_get(), ib_unget() or ib_seek() unless the last character read by - * ib_getw() was L'\n'. - */ -extern char *ib_getw(struct iblok *ip, wint_t *wc, int *len); - -/* - * Get a line from ip, returning the line length. Further arguments are either - * the pointer to a malloc()ed buffer and a pointer to its size, or (NULL, 0) - * if ib_getlin() shall allocate the buffer itselves. ib_getlin() will use - * the realloc-style function reallc() to increase the buffer if necessary; - * this function is expected never to fail (i. e., it must longjmp() or abort - * if it cannot allocate a buffer of the demanded size). - * On end-of-file or error, 0 is returned. - */ -extern size_t ib_getlin(struct iblok *ip, char **line, size_t *alcd, - void *(*reallc)(void *, size_t)); - -/* - * Like lseek(). - */ -extern off_t ib_seek(struct iblok *ip, off_t off, int whence); diff --git a/tools/cpio/src/inflate.c b/tools/cpio/src/inflate.c deleted file mode 100644 index 2c6d3e59f..000000000 --- a/tools/cpio/src/inflate.c +++ /dev/null @@ -1,991 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. - * - * Derived from Info-ZIP 5.50. - * - * Sccsid @(#)inflate.c 1.6 (gritter) 10/13/04 - */ -/* -This is version 2002-Feb-16 of the Info-ZIP copyright and license. -The definitive version of this document should be available at -ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely. - - -Copyright (c) 1990-2002 Info-ZIP. All rights reserved. - -For the purposes of this copyright and license, "Info-ZIP" is defined as -the following set of individuals: - - Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois, - Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris Herborth, Dirk Haase, - Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, David Kirschbaum, - Johnny Lee, Onno van der Linden, Igor Mandrichenko, Steve P. Miller, - Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, Kai Uwe Rommel, - Steve Salisbury, Dave Smith, Christian Spieler, Antoine Verheijen, - Paul von Behren, Rich Wales, Mike White - -This software is provided "as is," without warranty of any kind, express -or implied. In no event shall Info-ZIP or its contributors be held liable -for any direct, indirect, incidental, special or consequential damages -arising out of the use of or inability to use this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. Redistributions of source code must retain the above copyright notice, - definition, disclaimer, and this list of conditions. - - 2. Redistributions in binary form (compiled executables) must reproduce - the above copyright notice, definition, disclaimer, and this list of - conditions in documentation and/or other materials provided with the - distribution. The sole exception to this condition is redistribution - of a standard UnZipSFX binary as part of a self-extracting archive; - that is permitted without inclusion of this license, as long as the - normal UnZipSFX banner has not been removed from the binary or disabled. - - 3. Altered versions--including, but not limited to, ports to new operating - systems, existing ports with new graphical interfaces, and dynamic, - shared, or static library versions--must be plainly marked as such - and must not be misrepresented as being the original source. Such - altered versions also must not be misrepresented as being Info-ZIP - releases--including, but not limited to, labeling of the altered - versions with the names "Info-ZIP" (or any variation thereof, including, - but not limited to, different capitalizations), "Pocket UnZip," "WiZ" - or "MacZip" without the explicit permission of Info-ZIP. Such altered - versions are further prohibited from misrepresentative use of the - Zip-Bugs or Info-ZIP e-mail addresses or of the Info-ZIP URL(s). - - 4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip," - "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its - own source and binary releases. -*/ -/* - Copyright (c) 1990-2002 Info-ZIP. All rights reserved. - - See the accompanying file LICENSE, version 2000-Apr-09 or later - (the contents of which are also included in unzip.h) for terms of use. - If, for some reason, all these files are missing, the Info-ZIP license - also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html -*/ -/* inflate.c -- by Mark Adler - version c17a, 04 Feb 2001 */ - - -/* Copyright history: - - Starting with UnZip 5.41 of 16-April-2000, this source file - is covered by the Info-Zip LICENSE cited above. - - Prior versions of this source file, found in UnZip source packages - up to UnZip 5.40, were put in the public domain. - The original copyright note by Mark Adler was: - "You can do whatever you like with this source file, - though I would prefer that if you modify it and - redistribute it that you include comments to that effect - with your name and the date. Thank you." - - History: - vers date who what - ---- --------- -------------- ------------------------------------ - a ~~ Feb 92 M. Adler used full (large, one-step) lookup table - b1 21 Mar 92 M. Adler first version with partial lookup tables - b2 21 Mar 92 M. Adler fixed bug in fixed-code blocks - b3 22 Mar 92 M. Adler sped up match copies, cleaned up some - b4 25 Mar 92 M. Adler added prototypes; removed window[] (now - is the responsibility of unzip.h--also - changed name to slide[]), so needs diffs - for unzip.c and unzip.h (this allows - compiling in the small model on MSDOS); - fixed cast of q in huft_build(); - b5 26 Mar 92 M. Adler got rid of unintended macro recursion. - b6 27 Mar 92 M. Adler got rid of nextbyte() routine. fixed - bug in inflate_fixed(). - c1 30 Mar 92 M. Adler removed lbits, dbits environment variables. - changed BMAX to 16 for explode. Removed - OUTB usage, and replaced it with flush()-- - this was a 20% speed improvement! Added - an explode.c (to replace unimplod.c) that - uses the huft routines here. Removed - register union. - c2 4 Apr 92 M. Adler fixed bug for file sizes a multiple of 32k. - c3 10 Apr 92 M. Adler reduced memory of code tables made by - huft_build significantly (factor of two to - three). - c4 15 Apr 92 M. Adler added NOMEMCPY do kill use of memcpy(). - worked around a Turbo C optimization bug. - c5 21 Apr 92 M. Adler added the WSIZE #define to allow reducing - the 32K window size for specialized - applications. - c6 31 May 92 M. Adler added some typecasts to eliminate warnings - c7 27 Jun 92 G. Roelofs added some more typecasts (444: MSC bug). - c8 5 Oct 92 J-l. Gailly added ifdef'd code to deal with PKZIP bug. - c9 9 Oct 92 M. Adler removed a memory error message (~line 416). - c10 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch, - removed old inflate, renamed inflate_entry - to inflate, added Mark's fix to a comment. - c10.5 14 Dec 92 M. Adler fix up error messages for incomplete trees. - c11 2 Jan 93 M. Adler fixed bug in detection of incomplete - tables, and removed assumption that EOB is - the longest code (bad assumption). - c12 3 Jan 93 M. Adler make tables for fixed blocks only once. - c13 5 Jan 93 M. Adler allow all zero length codes (pkzip 2.04c - outputs one zero length code for an empty - distance tree). - c14 12 Mar 93 M. Adler made inflate.c standalone with the - introduction of inflate.h. - c14b 16 Jul 93 G. Roelofs added (unsigned) typecast to w at 470. - c14c 19 Jul 93 J. Bush changed v[N_MAX], l[288], ll[28x+3x] arrays - to static for Amiga. - c14d 13 Aug 93 J-l. Gailly de-complicatified Mark's c[*p++]++ thing. - c14e 8 Oct 93 G. Roelofs changed memset() to memzero(). - c14f 22 Oct 93 G. Roelofs renamed quietflg to qflag; made Trace() - conditional; added inflate_free(). - c14g 28 Oct 93 G. Roelofs changed l/(lx+1) macro to pointer (Cray bug) - c14h 7 Dec 93 C. Ghisler huft_build() optimizations. - c14i 9 Jan 94 A. Verheijen set fixed_t{d,l} to NULL after freeing; - G. Roelofs check NEXTBYTE macro for EOF. - c14j 23 Jan 94 G. Roelofs removed Ghisler "optimizations"; ifdef'd - EOF check. - c14k 27 Feb 94 G. Roelofs added some typecasts to avoid warnings. - c14l 9 Apr 94 G. Roelofs fixed split comments on preprocessor lines - to avoid bug in Encore compiler. - c14m 7 Jul 94 P. Kienitz modified to allow assembler version of - inflate_codes() (define ASM_INFLATECODES) - c14n 22 Jul 94 G. Roelofs changed fprintf to macro for DLL versions - c14o 23 Aug 94 C. Spieler added a newline to a debug statement; - G. Roelofs added another typecast to avoid MSC warning - c14p 4 Oct 94 G. Roelofs added (voidp *) cast to free() argument - c14q 30 Oct 94 G. Roelofs changed fprintf macro to MESSAGE() - c14r 1 Nov 94 G. Roelofs fixed possible redefinition of CHECK_EOF - c14s 7 May 95 S. Maxwell OS/2 DLL globals stuff incorporated; - P. Kienitz "fixed" ASM_INFLATECODES macro/prototype - c14t 18 Aug 95 G. Roelofs added UZinflate() to use zlib functions; - changed voidp to zvoid; moved huft_build() - and huft_free() to end of file - c14u 1 Oct 95 G. Roelofs moved G into definition of MESSAGE macro - c14v 8 Nov 95 P. Kienitz changed ASM_INFLATECODES to use a regular - call with __G__ instead of a macro - c15 3 Aug 96 M. Adler fixed bomb-bug on random input data (Adobe) - c15b 24 Aug 96 M. Adler more fixes for random input data - c15c 28 Mar 97 G. Roelofs changed USE_ZLIB fatal exit code from - PK_MEM2 to PK_MEM3 - c16 20 Apr 97 J. Altman added memzero(v[]) in huft_build() - c16b 29 Mar 98 C. Spieler modified DLL code for slide redirection - c16c 04 Apr 99 C. Spieler fixed memory leaks when processing gets - stopped because of input data errors - c16d 05 Jul 99 C. Spieler take care of FLUSH() return values and - stop processing in case of errors - c17 31 Dec 00 C. Spieler added preliminary support for Deflate64 - c17a 04 Feb 01 C. Spieler complete integration of Deflate64 support - c17b 16 Feb 02 C. Spieler changed type of "extra bits" arrays and - corresponding huft_buid() parameter e from - ush into uch, to save space - */ - - -/* - Inflate deflated (PKZIP's method 8 compressed) data. The compression - method searches for as much of the current string of bytes (up to a - length of 258) in the previous 32K bytes. If it doesn't find any - matches (of at least length 3), it codes the next byte. Otherwise, it - codes the length of the matched string and its distance backwards from - the current position. There is a single Huffman code that codes both - single bytes (called "literals") and match lengths. A second Huffman - code codes the distance information, which follows a length code. Each - length or distance code actually represents a base value and a number - of "extra" (sometimes zero) bits to get to add to the base value. At - the end of each deflated block is a special end-of-block (EOB) literal/ - length code. The decoding process is basically: get a literal/length - code; if EOB then done; if a literal, emit the decoded byte; if a - length then get the distance and emit the referred-to bytes from the - sliding window of previously emitted data. - - There are (currently) three kinds of inflate blocks: stored, fixed, and - dynamic. The compressor outputs a chunk of data at a time and decides - which method to use on a chunk-by-chunk basis. A chunk might typically - be 32K to 64K, uncompressed. If the chunk is uncompressible, then the - "stored" method is used. In this case, the bytes are simply stored as - is, eight bits per byte, with none of the above coding. The bytes are - preceded by a count, since there is no longer an EOB code. - - If the data are compressible, then either the fixed or dynamic methods - are used. In the dynamic method, the compressed data are preceded by - an encoding of the literal/length and distance Huffman codes that are - to be used to decode this block. The representation is itself Huffman - coded, and so is preceded by a description of that code. These code - descriptions take up a little space, and so for small blocks, there is - a predefined set of codes, called the fixed codes. The fixed method is - used if the block ends up smaller that way (usually for quite small - chunks); otherwise the dynamic method is used. In the latter case, the - codes are customized to the probabilities in the current block and so - can code it much better than the pre-determined fixed codes can. - - The Huffman codes themselves are decoded using a multi-level table - lookup, in order to maximize the speed of decoding plus the speed of - building the decoding tables. See the comments below that precede the - lbits and dbits tuning parameters. - - GRR: return values(?) - 0 OK - 1 incomplete table - 2 bad input - 3 not enough memory - the following return codes are passed through from FLUSH() errors - 50 (PK_DISK) "overflow of output space" - 80 (IZ_CTRLC) "canceled by user's request" - */ - - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - 14. The Deflate64 (PKZIP method 9) variant of the compression algorithm - differs from "classic" deflate in the following 3 aspect: - a) The size of the sliding history window is expanded to 64 kByte. - b) The previously unused distance codes #30 and #31 code distances - from 32769 to 49152 and 49153 to 65536. Both codes take 14 bits - of extra data to determine the exact position in their 16 kByte - range. - c) The last lit/length code #285 gets a different meaning. Instead - of coding a fixed maximum match length of 258, it is used as a - "generic" match length code, capable of coding any length from - 3 (min match length + 0) to 65538 (min match length + 65535). - This means that the length code #285 takes 16 bits (!) of uncoded - extra data, added to a fixed min length of 3. - Changes a) and b) would have been transparent for valid deflated - data, but change c) requires to switch decoder configurations between - Deflate and Deflate64 modes. - */ - -#include -#include -#include -#include "cpio.h" -#include "unzip.h" - -/* - inflate.h must supply the uch slide[WSIZE] array, the zvoid typedef - (void if (void *) is accepted, else char) and the NEXTBYTE, - FLUSH() and memzero macros. If the window size is not 32K, it - should also define WSIZE. If INFMOD is defined, it can include - compiled functions to support the NEXTBYTE and/or FLUSH() macros. - There are defaults for NEXTBYTE and FLUSH() below for use as - examples of what those functions need to do. Normally, you would - also want FLUSH() to compute a crc on the data. inflate.h also - needs to provide these typedefs: - - typedef unsigned char uch; - typedef unsigned short ush; - typedef unsigned long ulg; - - This module uses the external functions malloc() and free() (and - probably memset() or bzero() in the memzero() macro). Their - prototypes are normally found in and . - */ - -/* marker for "unused" huft code, and corresponding check macro */ -#define INVALID_CODE 99 -#define IS_INVALID_CODE(c) ((c) == INVALID_CODE) - -static int inflate_codes(struct globals *Gp, - struct huft *tl, struct huft *td, - int bl, int bd); -static int inflate_stored(struct globals *Gp); -static int inflate_fixed(struct globals *Gp); -static int inflate_dynamic(struct globals *Gp); -static int inflate_block(struct globals *Gp, int *e); - -#define FLUSH(n) (flush(&G, redirSlide, (n)), 0) - -/* The inflate algorithm uses a sliding 32K byte window on the uncompressed - stream to find repeated byte strings. This is implemented here as a - circular buffer. The index is updated simply by incrementing and then - and'ing with 0x7fff (32K-1). */ -/* It is left to other modules to supply the 32K area. It is assumed - to be usable as if it were declared "uch slide[32768];" or as just - "uch *slide;" and then malloc'ed in the latter case. The definition - must be in unzip.h, included above. */ - - -/* Tables for deflate from PKZIP's appnote.txt. */ -/* - Order of the bit length code lengths */ -static const unsigned border[] = { - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* - Copy lengths for literal codes 257..285 */ -static const uint16_t cplens64[] = { - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 3, 0, 0}; - /* For Deflate64, the code 285 is defined differently. */ -static const uint16_t cplens32[] = { - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* note: see note #13 above about the 258 in this list. */ -/* - Extra bits for literal codes 257..285 */ -static const uint8_t cplext64[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16, INVALID_CODE, INVALID_CODE}; -static const uint8_t cplext32[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, INVALID_CODE, INVALID_CODE}; - -/* - Copy offsets for distance codes 0..29 (0..31 for Deflate64) */ -static const uint16_t cpdist[] = { - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 32769, 49153}; - -/* - Extra bits for distance codes 0..29 (0..31 for Deflate64) */ -static const uint8_t cpdext64[] = { - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13, 14, 14}; -static const uint8_t cpdext32[] = { - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13, INVALID_CODE, INVALID_CODE}; - -# define MAXLITLENS 288 -# define MAXDISTS 32 - -/* Macros for inflate() bit peeking and grabbing. - The usage is: - - NEEDBITS(j) - x = b & mask_bits[j]; - DUMPBITS(j) - - where NEEDBITS makes sure that b has at least j bits in it, and - DUMPBITS removes the bits from b. The macros use the variable k - for the number of bits in b. Normally, b and k are register - variables for speed and are initialized at the begining of a - routine that uses these macros from a global bit buffer and count. - - In order to not ask for more bits than there are in the compressed - stream, the Huffman tables are constructed to only ask for just - enough bits to make up the end-of-block code (value 256). Then no - bytes need to be "returned" to the buffer at the end of the last - block. See the huft_build() routine. - */ - -# define NEEDBITS(n) {while(k<(n)){int c=NEXTBYTE;\ - if(c==EOF){retval=1;goto cleanup_and_exit;}\ - b|=((uint32_t)c)<>=(n);k-=(n);} - -#define Bits 32 -#define Nob 32 -#define Eob 31 - -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - are not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ - - -static const int lbits = 9; /* bits in base literal/length lookup table */ -static const int dbits = 6; /* bits in base distance lookup table */ - -#define G (*Gp) - -static int -inflate_codes(struct globals *Gp, - struct huft *tl, struct huft *td, int bl, int bd) -/*struct huft *tl, *td;*/ /* literal/length and distance decoder tables */ -/*int bl, bd;*/ /* number of bits decoded by tl[] and td[] */ -/* inflate (decompress) the codes in a deflated (compressed) block. - Return an error code or zero if it all goes ok. */ -{ - register unsigned e; /* table entry flag/number of extra bits */ - unsigned d; /* index for copy */ - uint32_t n; /* length for copy (deflate64: might be 64k+2) */ - uint32_t w; /* current window position (deflate64: up to 64k) */ - struct huft *t; /* pointer to table entry */ - unsigned ml, md; /* masks for bl and bd bits */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - int retval = 0; /* error code returned: initialized to "no error" */ - - - /* make local copies of globals */ - b = G.bb; /* initialize bit buffer */ - k = G.bk; - w = G.wp; /* initialize window position */ - - - /* inflate the coded data */ - ml = mask_bits[bl]; /* precompute masks for speed */ - md = mask_bits[bd]; - while (1) /* do until end of block */ - { - NEEDBITS((unsigned)bl) - t = tl + ((unsigned)b & ml); - while (1) { - DUMPBITS(t->b) - - if ((e = t->e) == 32) /* then it's a literal */ - { - redirSlide[w++] = (uint8_t)t->v.n; - if (w == WSIZE) - { - if ((retval = FLUSH(w)) != 0) goto cleanup_and_exit; - w = 0; - } - break; - } - - if (e < 31) /* then it's a length */ - { - /* get length of block to copy */ - NEEDBITS(e) - n = t->v.n + ((unsigned)b & mask_bits[e]); - DUMPBITS(e) - - /* decode distance of block to copy */ - NEEDBITS((unsigned)bd) - t = td + ((unsigned)b & md); - while (1) { - DUMPBITS(t->b) - if ((e = t->e) < 32) - break; - if (IS_INVALID_CODE(e)) - return 1; - e &= 31; - NEEDBITS(e) - t = t->v.t + ((unsigned)b & mask_bits[e]); - } - NEEDBITS(e) - d = (unsigned)w - t->v.n - ((unsigned)b & mask_bits[e]); - DUMPBITS(e) - - /* do the copy */ - do { - e = (unsigned)(WSIZE - - ((d &= (unsigned)(WSIZE-1)) > (unsigned)w ? - (uint32_t)d : w)); - if ((uint32_t)e > n) e = (unsigned)n; - n -= e; -#ifndef NOMEMCPY - if ((unsigned)w - d >= e) - /* (this test assumes unsigned comparison) */ - { - memcpy(redirSlide + (unsigned)w, redirSlide + d, e); - w += e; - d += e; - } - else /* do it slowly to avoid memcpy() overlap */ -#endif /* !NOMEMCPY */ - do { - redirSlide[w++] = redirSlide[d++]; - } while (--e); - if (w == WSIZE) - { - if ((retval = FLUSH(w)) != 0) goto cleanup_and_exit; - w = 0; - } - } while (n); - break; - } - - if (e == 31) /* it's the EOB signal */ - { - /* sorry for this goto, but we have to exit two loops at once */ - goto cleanup_decode; - } - - if (IS_INVALID_CODE(e)) - return 1; - - e &= 31; - NEEDBITS(e) - t = t->v.t + ((unsigned)b & mask_bits[e]); - } - } -cleanup_decode: - - /* restore the globals from the locals */ - G.wp = (unsigned)w; /* restore global window pointer */ - G.bb = b; /* restore global bit buffer */ - G.bk = k; - - -cleanup_and_exit: - /* done */ - return retval; -} - -static int -inflate_stored(struct globals *Gp) -/* "decompress" an inflated type 0 (stored) block. */ -{ - uint32_t w; /* current window position (deflate64: up to 64k!) */ - unsigned n; /* number of bytes in block */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - int retval = 0; /* error code returned: initialized to "no error" */ - - - /* make local copies of globals */ - Trace((stderr, "\nstored block")); - b = G.bb; /* initialize bit buffer */ - k = G.bk; - w = G.wp; /* initialize window position */ - - - /* go to byte boundary */ - n = k & 7; - DUMPBITS(n); - - - /* get the length and its complement */ - NEEDBITS(16) - n = ((unsigned)b & 0xffff); - DUMPBITS(16) - NEEDBITS(16) - if (n != (unsigned)((~b) & 0xffff)) - return 1; /* error in compressed data */ - DUMPBITS(16) - - - /* read and output the compressed data */ - while (n--) - { - NEEDBITS(8) - redirSlide[w++] = (uint8_t)b; - if (w == WSIZE) - { - if ((retval = FLUSH(w)) != 0) goto cleanup_and_exit; - w = 0; - } - DUMPBITS(8) - } - - - /* restore the globals from the locals */ - G.wp = (unsigned)w; /* restore global window pointer */ - G.bb = b; /* restore global bit buffer */ - G.bk = k; - -cleanup_and_exit: - return retval; -} - - -static int -inflate_fixed(struct globals *Gp) -/* decompress an inflated type 1 (fixed Huffman codes) block. We should - either replace this with a custom decoder, or at least precompute the - Huffman tables. */ -{ - /* if first time, set up tables for fixed blocks */ - Trace((stderr, "\nliteral block")); - if (G.fixed_tl == NULL) - { - int i; /* temporary variable */ - unsigned l[288]; /* length list for huft_build */ - - /* literal table */ - for (i = 0; i < 144; i++) - l[i] = 8; - for (; i < 256; i++) - l[i] = 9; - for (; i < 280; i++) - l[i] = 7; - for (; i < 288; i++) /* make a complete, but wrong code set */ - l[i] = 8; - G.fixed_bl = 7; - if ((i = huft_build(l, 288, 257, G.cplens, G.cplext, - &G.fixed_tl, &G.fixed_bl, - Bits, Nob, Eob)) != 0) - { - G.fixed_tl = NULL; - return i; - } - - /* distance table */ - for (i = 0; i < MAXDISTS; i++) /* make an incomplete code set */ - l[i] = 5; - G.fixed_bd = 5; - if ((i = huft_build(l, MAXDISTS, 0, cpdist, G.cpdext, - &G.fixed_td, &G.fixed_bd, - Bits, Nob, Eob)) > 1) - { - huft_free(G.fixed_tl); - G.fixed_td = G.fixed_tl = NULL; - return i; - } - } - - /* decompress until an end-of-block code */ - return inflate_codes(&G, G.fixed_tl, G.fixed_td, - G.fixed_bl, G.fixed_bd); -} - - - -static int inflate_dynamic(struct globals *Gp) -/* decompress an inflated type 2 (dynamic Huffman codes) block. */ -{ - int i; /* temporary variables */ - unsigned j; - unsigned l; /* last length */ - unsigned m; /* mask for bit lengths table */ - unsigned n; /* number of lengths to get */ - struct huft *tl; /* literal/length code table */ - struct huft *td; /* distance code table */ - int bl; /* lookup bits for tl */ - int bd; /* lookup bits for td */ - unsigned nb; /* number of bit length codes */ - unsigned nl; /* number of literal/length codes */ - unsigned nd; /* number of distance codes */ - unsigned ll[MAXLITLENS+MAXDISTS]; /* lit./length and distance code lengths */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - int retval = 0; /* error code returned: initialized to "no error" */ - - - /* make local bit buffer */ - Trace((stderr, "\ndynamic block")); - b = G.bb; - k = G.bk; - - - /* read in table lengths */ - NEEDBITS(5) - nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */ - DUMPBITS(5) - NEEDBITS(5) - nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */ - DUMPBITS(5) - NEEDBITS(4) - nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */ - DUMPBITS(4) - if (nl > MAXLITLENS || nd > MAXDISTS) - return 1; /* bad lengths */ - - - /* read in bit-length-code lengths */ - for (j = 0; j < nb; j++) - { - NEEDBITS(3) - ll[border[j]] = (unsigned)b & 7; - DUMPBITS(3) - } - for (; j < 19; j++) - ll[border[j]] = 0; - - - /* build decoding table for trees--single level, 7 bit lookup */ - bl = 7; - retval = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl, - Bits, Nob, Eob); - if (bl == 0) /* no bit lengths */ - retval = 1; - if (retval) - { - if (retval == 1) - huft_free(tl); - return retval; /* incomplete code set */ - } - - - /* read in literal and distance code lengths */ - n = nl + nd; - m = mask_bits[bl]; - i = l = 0; - while ((unsigned)i < n) - { - NEEDBITS((unsigned)bl) - j = (td = tl + ((unsigned)b & m))->b; - DUMPBITS(j) - j = td->v.n; - if (j < 16) /* length of code in bits (0..15) */ - ll[i++] = l = j; /* save last length in l */ - else if (j == 16) /* repeat last length 3 to 6 times */ - { - NEEDBITS(2) - j = 3 + ((unsigned)b & 3); - DUMPBITS(2) - if ((unsigned)i + j > n) - return 1; - while (j--) - ll[i++] = l; - } - else if (j == 17) /* 3 to 10 zero length codes */ - { - NEEDBITS(3) - j = 3 + ((unsigned)b & 7); - DUMPBITS(3) - if ((unsigned)i + j > n) - return 1; - while (j--) - ll[i++] = 0; - l = 0; - } - else /* j == 18: 11 to 138 zero length codes */ - { - NEEDBITS(7) - j = 11 + ((unsigned)b & 0x7f); - DUMPBITS(7) - if ((unsigned)i + j > n) - return 1; - while (j--) - ll[i++] = 0; - l = 0; - } - } - - - /* free decoding table for trees */ - huft_free(tl); - - - /* restore the global bit buffer */ - G.bb = b; - G.bk = k; - - - /* build the decoding tables for literal/length and distance codes */ - bl = lbits; - retval = huft_build(ll, nl, 257, G.cplens, G.cplext, &tl, &bl, - Bits, Nob, Eob); - if (bl == 0) /* no literals or lengths */ - retval = 1; - if (retval) - { - if (retval == 1) { - /*if (!uO.qflag) - MESSAGE((uint8_t *)"(incomplete l-tree) ", 21L, 1);*/ - huft_free(tl); - } - return retval; /* incomplete code set */ - } - bd = dbits; - retval = huft_build(ll + nl, nd, 0, cpdist, G.cpdext, &td, &bd, - Bits, Nob, Eob); - if (retval == 1) - retval = 0; - if (bd == 0 && nl > 257) /* lengths but no distances */ - retval = 1; - if (retval) - { - if (retval == 1) { - /*if (!uO.qflag) - MESSAGE((uint8_t *)"(incomplete d-tree) ", 21L, 1);*/ - huft_free(td); - } - huft_free(tl); - return retval; - } - - /* decompress until an end-of-block code */ - retval = inflate_codes(&G, tl, td, bl, bd); - -cleanup_and_exit: - /* free the decoding tables, return */ - huft_free(tl); - huft_free(td); - return retval; -} - - - -static int inflate_block(struct globals *Gp, int *e) -/*int *e;*/ /* last block flag */ -/* decompress an inflated block */ -{ - unsigned t; /* block type */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - int retval = 0; /* error code returned: initialized to "no error" */ - - - /* make local bit buffer */ - b = G.bb; - k = G.bk; - - - /* read in last block bit */ - NEEDBITS(1) - *e = (int)b & 1; - DUMPBITS(1) - - - /* read in block type */ - NEEDBITS(2) - t = (unsigned)b & 3; - DUMPBITS(2) - - - /* restore the global bit buffer */ - G.bb = b; - G.bk = k; - - - /* inflate that block type */ - if (t == 2) - return inflate_dynamic(&G); - if (t == 0) - return inflate_stored(&G); - if (t == 1) - return inflate_fixed(&G); - - - /* bad block type */ - retval = 2; - -cleanup_and_exit: - return retval; -} - -#undef G - -int -zipinflate(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) -/* decompress an inflated entry */ -{ - struct globals G; - int e = 0; /* last block flag */ - int r; /* result code */ - int is_defl64; -#ifdef DEBUG - unsigned h = 0; /* maximum struct huft's malloc'ed */ -#endif - - is_defl64 = f->f_cmethod == C_ENHDEFLD; - memset(&G, 0, sizeof G); - G.tgt = tgt; - G.tfd = tfd; - G.doswap = doswap; - G.crc = crc; - G.zsize = G.uzsize = f->f_csize; - G.ucsize = f->f_st.st_size; - /* initialize window, bit buffer */ - G.wp = 0; - G.bk = 0; - G.bb = 0; - - if (is_defl64) { - G.cplens = cplens64; - G.cplext = cplext64; - G.cpdext = cpdext64; - G.fixed_tl = G.fixed_tl64; - G.fixed_bl = G.fixed_bl64; - G.fixed_td = G.fixed_td64; - G.fixed_bd = G.fixed_bd64; - } else { - G.cplens = cplens32; - G.cplext = cplext32; - G.cpdext = cpdext32; - G.fixed_tl = G.fixed_tl32; - G.fixed_bl = G.fixed_bl32; - G.fixed_td = G.fixed_td32; - G.fixed_bd = G.fixed_bd32; - } - - /* decompress until the last block */ - do { -#ifdef DEBUG - G.hufts = 0; -#endif - if ((r = inflate_block(&G, &e)) != 0) { - if ((f->f_gflag & FG_DESC) == 0) - while (G.uzsize > 0) - NEXTBYTE; - msg(3, 0, "compression error on \"%s\"\n", f->f_name); - return -1; - } -#ifdef DEBUG - if (G.hufts > h) - h = G.hufts; -#endif - } while (!e); - - Trace((stderr, "\n%u bytes in Huffman tables (%u/entry)\n", - h * (unsigned)sizeof(struct huft), (unsigned)sizeof(struct huft))); - - if (is_defl64) { - G.fixed_tl64 = G.fixed_tl; - G.fixed_bl64 = G.fixed_bl; - G.fixed_td64 = G.fixed_td; - G.fixed_bd64 = G.fixed_bd; - } else { - G.fixed_tl32 = G.fixed_tl; - G.fixed_bl32 = G.fixed_bl; - G.fixed_td32 = G.fixed_td; - G.fixed_bd32 = G.fixed_bd; - } - - /* flush out redirSlide and return (success, unless final FLUSH failed) */ - (FLUSH(G.wp)); - if (f->f_gflag & FG_DESC) - bunread((char *)G.inptr, G.incnt); - return G.status; -} diff --git a/tools/cpio/src/mbtowi.h b/tools/cpio/src/mbtowi.h deleted file mode 100644 index 525ad08d1..000000000 --- a/tools/cpio/src/mbtowi.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Sccsid @(#)mbtowi.h 1.2 (gritter) 7/16/04 */ - -#ifndef LIBCOMMON_MBTOWI_H -#define LIBCOMMON_MBTOWI_H - -static -#if defined (__GNUC__) || defined (__USLC__) || defined (__INTEL_COMPILER) || \ - defined (__IBMC__) || defined (__SUNPRO_C) - inline -#endif - int -mbtowi(wint_t *pwi, const char *s, size_t n) -{ - wchar_t wc; - int i; - - i = mbtowc(&wc, s, n); - *pwi = wc; - return i; -} - -#endif /* !LIBCOMMON_MBTOWI_H */ diff --git a/tools/cpio/src/memalign.c b/tools/cpio/src/memalign.c deleted file mode 100644 index 268949b20..000000000 --- a/tools/cpio/src/memalign.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)memalign.c 1.7 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (_AIX) || \ - defined (__NetBSD__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -/* - * FreeBSD malloc(3) promises to page-align the return of malloc() calls - * if size is at least a page. This serves for a poor man's memalign() - * implementation that matches our needs. - */ -#include -#include - -#include "memalign.h" - -void * -memalign(size_t alignment, size_t size) -{ - static long pagesize; - - if (pagesize == 0) - pagesize = sysconf(_SC_PAGESIZE); - if (alignment != pagesize) - return NULL; - if (size < pagesize) - size = pagesize; - return malloc(size); -} -#endif /* __FreeBSD__ || __dietlibc__ || _AIX || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ */ diff --git a/tools/cpio/src/memalign.h b/tools/cpio/src/memalign.h deleted file mode 100644 index edaef031b..000000000 --- a/tools/cpio/src/memalign.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)memalign.h 1.7 (gritter) 1/22/06 */ - -#ifndef LIBCOMMON_MEMALIGN_H -#define LIBCOMMON_MEMALIGN_H - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (_AIX) || \ - defined (__NetBSD__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -#include - -extern void *memalign(size_t, size_t); -#endif /* __FreeBSD__ || __dietlibc__ || _AIX || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ */ -#endif /* !LIBCOMMON_MEMALIGN_H */ diff --git a/tools/cpio/src/msgselect.h b/tools/cpio/src/msgselect.h deleted file mode 100644 index 94a5daa9f..000000000 --- a/tools/cpio/src/msgselect.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)msgselect.h 1.2 (gritter) 9/21/03 */ - -#define MSG_LEVEL 0 - -#if MSG_LEVEL == 1 -#define msgselect(a, b) a -#else -#define msgselect(a, b) b -#endif diff --git a/tools/cpio/src/nonpax.c b/tools/cpio/src/nonpax.c deleted file mode 100644 index d0eb585b7..000000000 --- a/tools/cpio/src/nonpax.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * cpio - copy file archives in and out - * - * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. - */ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ - -/* Sccsid @(#)nonpax.c 1.1 (gritter) 2/24/04 */ - -#include "cpio.h" - -/*ARGSUSED*/ -int -pax_track(const char *name, time_t mtime) -{ - return 1; -} - -/*ARGSUSED*/ -void -pax_prlink(struct file *f) -{ -} - -/*ARGSUSED*/ -int -pax_sname(char **oldp, size_t *olds) -{ - return 1; -} - -void -pax_onexit(void) -{ -} diff --git a/tools/cpio/src/oblok.c b/tools/cpio/src/oblok.c deleted file mode 100644 index 38859ba6d..000000000 --- a/tools/cpio/src/oblok.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)oblok.c 1.7 (gritter) 7/16/04 */ - -#include -#include -#include -#include -#include -#include -#include - -#include "memalign.h" -#include "oblok.h" - -struct list { - struct list *l_nxt; - struct oblok *l_op; -}; - -static struct list *bloks; -static int exitset; - -int -ob_clear(void) -{ - struct list *lp; - int val = 0; - - for (lp = bloks; lp; lp = lp->l_nxt) { - if (ob_flush(lp->l_op) < 0) - val = -1; - else if (val >= 0) - val++; - } - return val; -} - -static void -add(struct oblok *op) -{ - struct list *lp, *lq; - - if ((lp = calloc(1, sizeof *lp)) != NULL) { - lp->l_nxt = NULL; - lp->l_op = op; - if (bloks) { - for (lq = bloks; lq->l_nxt; lq = lq->l_nxt); - lq->l_nxt = lp; - } else - bloks = lp; - if (exitset == 0) { - exitset = 1; - atexit((void (*)(void))ob_clear); - } - } -} - -static void -del(struct oblok *op) -{ - struct list *lp, *lq = NULL; - - if (bloks) { - for (lp = bloks; lp && lp->l_op != op; lp = lp->l_nxt) - lq = lp; - if (lp) { - if (lq) - lq->l_nxt = lp->l_nxt; - if (lp == bloks) - bloks = bloks->l_nxt; - free(lp); - } - } -} - -struct oblok * -ob_alloc(int fd, enum ob_mode bf) -{ - static long pagesize; - struct oblok *op; - - if (pagesize == 0) - if ((pagesize = sysconf(_SC_PAGESIZE)) < 0) - pagesize = 4096; - if ((op = memalign(pagesize, sizeof *op)) == NULL) - return NULL; - memset(op, 0, sizeof *op); - op->ob_fd = fd; - switch (bf) { - case OB_EBF: - op->ob_bf = isatty(fd) ? OB_LBF : OB_FBF; - break; - default: - op->ob_bf = bf; - } - add(op); - return op; -} - -ssize_t -ob_free(struct oblok *op) -{ - ssize_t wrt; - - wrt = ob_flush(op); - del(op); - free(op); - return wrt; -} - -static ssize_t -swrite(int fd, const char *data, size_t sz) -{ - ssize_t wo, wt = 0; - - do { - if ((wo = write(fd, data + wt, sz - wt)) < 0) { - if (errno == EINTR) - continue; - else - return wt; - } - wt += wo; - } while (wt < sz); - return sz; -} - -ssize_t -ob_write(struct oblok *op, const char *data, size_t sz) -{ - ssize_t wrt; - size_t di, isz; - - switch (op->ob_bf) { - case OB_NBF: - wrt = swrite(op->ob_fd, data, sz); - op->ob_wrt += wrt; - if (wrt != sz) { - op->ob_bf = OB_EBF; - writerr(op, sz, wrt>0?wrt:0); - return -1; - } - return wrt; - case OB_LBF: - case OB_FBF: - isz = sz; - while (op->ob_pos + sz > (OBLOK)) { - di = (OBLOK) - op->ob_pos; - sz -= di; - if (op->ob_pos > 0) { - memcpy(&op->ob_blk[op->ob_pos], data, di); - wrt = swrite(op->ob_fd, op->ob_blk, (OBLOK)); - } else - wrt = swrite(op->ob_fd, data, (OBLOK)); - op->ob_wrt += wrt; - if (wrt != (OBLOK)) { - op->ob_bf = OB_EBF; - writerr(op, (OBLOK), wrt>0?wrt:0); - return -1; - } - data += di; - op->ob_pos = 0; - } - if (op->ob_bf == OB_LBF) { - const char *cp; - - cp = data; - while (cp < &data[sz]) { - if (*cp == '\n') { - di = cp - data + 1; - sz -= di; - if (op->ob_pos > 0) { - memcpy(&op->ob_blk[op->ob_pos], - data, di); - wrt = swrite(op->ob_fd, - op->ob_blk, - op->ob_pos + di); - } else - wrt = swrite(op->ob_fd, - data, di); - op->ob_wrt += wrt; - if (wrt != op->ob_pos + di) { - op->ob_bf = OB_EBF; - writerr(op, di, wrt>0?wrt:0); - return -1; - } - op->ob_pos = 0; - data += di; - cp = data; - } - cp++; - } - } - if (sz == (OBLOK)) { - wrt = swrite(op->ob_fd, data, sz); - op->ob_wrt += wrt; - if (wrt != sz) { - op->ob_bf = OB_EBF; - writerr(op, sz, wrt>0?wrt:0); - return -1; - } - } else if (sz) { - memcpy(&op->ob_blk[op->ob_pos], data, sz); - op->ob_pos += sz; - } - return isz; - case OB_EBF: - ; - } - return -1; -} - -ssize_t -ob_flush(struct oblok *op) -{ - ssize_t wrt = 0; - - if (op->ob_pos) { - wrt = swrite(op->ob_fd, op->ob_blk, op->ob_pos); - op->ob_wrt += wrt; - if (wrt != op->ob_pos) { - op->ob_bf = OB_EBF; - writerr(op, op->ob_pos, wrt>0?wrt:0); - wrt = -1; - } - op->ob_pos = 0; - } - return wrt; -} - -int -ob_chr(int c, struct oblok *op) -{ - char b; - ssize_t wrt; - - b = (char)c; - wrt = ob_write(op, &b, 1); - return wrt < 0 ? EOF : c; -} diff --git a/tools/cpio/src/oblok.h b/tools/cpio/src/oblok.h deleted file mode 100644 index 1ee91b1c5..000000000 --- a/tools/cpio/src/oblok.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)oblok.h 1.3 (gritter) 4/17/03 */ - -#include - -#ifndef OBLOK -enum { - OBLOK = 4096 -}; -#endif /* !OBLOK */ - -enum ob_mode { - OB_EBF = 0, /* error or mode unset */ - OB_NBF = 1, /* not buffered */ - OB_LBF = 2, /* line buffered */ - OB_FBF = 3 /* fully buffered */ -}; - -struct oblok { - char ob_blk[OBLOK]; /* buffered data */ - long long ob_wrt; /* amount of data written */ - int ob_pos; /* position of first empty date byte */ - int ob_fd; /* file descriptor to write to */ - enum ob_mode ob_bf; /* buffering mode */ -}; - -/* - * Allocate an output buffer with file descriptor fd and buffer mode bf. - * If bf is OB_EBF, the choice is made dependant upon the file type. - * NULL is returned if no memory is available. - */ -extern struct oblok *ob_alloc(int fd, enum ob_mode bf); - -/* - * Deallocate the passed output buffer, flushing all data. The file - * descriptor is not closed. Returns -1 if flushing fails. - */ -extern ssize_t ob_free(struct oblok *op); - -/* - * Write data of length sz to the passed output buffer. Returns -1 on - * error or the amount of data written. - */ -extern ssize_t ob_write(struct oblok *op, const char *data, size_t sz); - -/* - * Flush all data in the passed output buffer. Returns -1 on error or - * the amount of data written; 0 is success and means 'nothing to flush'. - * The underlying device is not flushed (i. e. no fsync() is performed). - */ -extern ssize_t ob_flush(struct oblok *op); - -/* - * Flush all output buffers. Called automatically using atexit(). Returns - * -1 on error or the number of buffers flushed; 0 is success. - */ -extern int ob_clear(void); - -/* - * putc() workalike. - */ -#define ob_put(c, op) ((op)->ob_bf != OB_FBF || (op)->ob_pos >= (OBLOK) - 1 ?\ - ob_chr((c), (op)) : \ - (int)((op)->ob_blk[(op)->ob_pos++] = (char)(c))) - - -/* - * fputc() workalike. - */ -extern int ob_chr(int c, struct oblok *op); - -/* - * This function must be supplied by the calling code; it is called on - * write error. - */ -extern void writerr(struct oblok *op, int count, int written); diff --git a/tools/cpio/src/pathconf.c b/tools/cpio/src/pathconf.c deleted file mode 100644 index a6b91ef86..000000000 --- a/tools/cpio/src/pathconf.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)pathconf.c 1.2 (gritter) 5/1/04 */ - -#ifdef __dietlibc__ -#include -#include "pathconf.h" - -static long -pc(int name) -{ - switch (name) { - case _PC_PATH_MAX: - return 1024; - case _PC_VDISABLE: - return 0; - default: - return -1; - } -} - -long -fpathconf(int fildes, int name) -{ - return pc(name); -} - -long -pathconf(const char *path, int name) { - return pc(name); -} -#endif /* __dietlibc__ */ diff --git a/tools/cpio/src/pathconf.h b/tools/cpio/src/pathconf.h deleted file mode 100644 index 79696b6da..000000000 --- a/tools/cpio/src/pathconf.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)pathconf.h 1.2 (gritter) 5/1/04 */ - -#ifdef __dietlibc__ -#include - -extern long fpathconf(int, int); -extern long pathconf(const char *, int); -#endif /* __dietlibc__ */ diff --git a/tools/cpio/src/pax.1 b/tools/cpio/src/pax.1 deleted file mode 100644 index 4fb9206f9..000000000 --- a/tools/cpio/src/pax.1 +++ /dev/null @@ -1,919 +0,0 @@ -'\" t -.\" Copyright (c) 2004 Gunnar Ritter -.\" -.\" This software is provided 'as-is', without any express or implied -.\" warranty. In no event will the authors be held liable for any damages -.\" arising from the use of this software. -.\" -.\" Permission is granted to anyone to use this software for any purpose, -.\" including commercial applications, and to alter it and redistribute -.\" it freely, subject to the following restrictions: -.\" -.\" 1. 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. -.\" -.\" 2. Altered source versions must be plainly marked as such, and must not be -.\" misrepresented as being the original software. -.\" -.\" 3. This notice may not be removed or altered from any source distribution. -.\" Sccsid @(#)pax.1 1.38 (gritter) 8/13/09 -.TH PAX 1 "8/13/09" "Heirloom Toolchest" "User Commands" -.SH NAME -pax \- portable archive interchange -.SH SYNOPSIS -.PD 0 -.HP -.nh -.ad l -\fBpax\fR [\fB\-cdnvK\fR] [\fB\-b\ \fIsize\fR] -[\fB\-f\ \fIfile\fR] [\fB\-s\ \fIreplstr\fR] -[\fB\-x\ \fIhdr\fR] [\fIpatterns\fR] -.HP -.ad l -\fBpax\fR \fB\-r\fR[\fBcdiknuvK\fR] [\fB\-b\ \fIsize\fR] -[\fB\-f\ \fIfile\fR] -[\fB\-o\ \fIoptions\fR] -[\fB\-p\ \fIpriv\fR] [\fB\-s\ \fIreplstr\fR] -[\fB\-x\ \fIhdr\fR] [\fIpatterns\fR] -.HP -.ad l -\fBpax\fR \fB\-w\fR[\fBadiHtuvLX\fR] [\fB\-b\ \fIsize\fR] -[\fB\-f\ \fIfile\fR] -[\fB\-o\ \fIoptions\fR] -[\fB\-s\ \fIreplstr\fR] -[\fB\-x\ \fIhdr\fR] [\fIfiles\fR] -.HP -.ad l -\fBpax\fR \fB\-rw\fR[\fBdiHklntuvLX\fR] -[\fB\-p\ \fIpriv\fR] [\fB\-s\ \fIreplstr\fR] -[\fIfiles\fR] \fIdirectory\fR -.br -.ad b -.hy 1 -.PD -.SH DESCRIPTION -.I Pax -creates and extracts file archives and copies files. -.PP -If neither the -.I \-r -or -.I \-w -options are given, -.I pax -works in -.I list -mode -and prints the contents of the archive. -.PP -With the -.B \-r -option, -.I pax -works in -.RI ` read ' -mode and extracts files from a file archive. -By default, -the archive is read from standard input. -Optional arguments are interpreted as -.I patterns -and restrict the set of extracted files -to those matching any of the -.IR patterns . -The syntax is identical to that described in -.IR glob (7), -except that the slash character -.RB ` / ' -is matched by -meta-character constructs with -.RB ` * ', -.RB ` ? ' -and -.RB ` [ '. -Care must be taken to quote meta-characters appropriately from the shell. -If a pattern matches the prefix name of a directory in the archive, -all files below that directory are also extracted. -File permissions are set to those in the archive; -if the caller is the super-user, -ownerships are restored as well. -options are specified. -Archives compressed with -.IR bzip2 (1), -.IR compress (1), -.IR gzip (1), -or -.IR rpm (1) -are transparently de\%compressed on input. -.PP -With -.BR \-w , -.I pax -works in -.RI ` write ' -mode, -creates archives -and writes them to standard output per default. -A list of filenames to be included in the archive is -read from standard input; -if the name of a directory appears, -all its members and the directory itself are recursively -included in the archive. -The -.IR find (1) -utility is useful to generate a list of files -(see also its -.I \-cpio -and -.I \-ncpio -operators). -When producing a filename list for -.IR pax , -find should always be invoked with -.I \-depth -since this makes it possible to extract write-protected directories -for users other than the super-user. -If -.I files -are given on the command line, -they are included in the archive -in the same manner as described above -and standard input is not read. -.PP -The -.B \-rw -options selects -.RI ` copy ' -mode; -a list of -.I files -is read from standard input -or taken from the command line -as described for -.IR \-w ; -files are copied to the specified -.IR directory , -preserving attributes as described for -.IR \-r . -Special files are re-created in the target hierarchy, -and hard links between copied files are preserved. -.PP -When a premature end-of-file is detected with -.I \-r -and -.I \-w -and the archive is a block or character special file, -the user is prompted for new media. -.PP -The following options alter the behavior of -.IR pax : -.TP -.B \-a -Append files to the archive. -The archive must be seekable, -such as a regular file or a block device, -or a tape device capable of writing between filemarks. -.TP -\fB\-b\fI size\fR[\fBw\fR|\fBb\fR|\fBk\fR|\fBm\fR] -Blocks input and output archives at -.I size -byte records. -The optional suffix multiplies -.I size -by 2 for -.BR w , -512 for -.BR b , -1024 for -.BR k , -and 1048576 for -.BR m . -.TP -.B \-c -Reverses the sense of patterns -such that a file that does not match any of the patterns -is selected. -.TP -.B \-d -Causes -.I pax -to ignore files below directories. -In read mode, -patterns matching directories -cause only the directory itself to extracted, -files below will be ignored -unless another pattern applies to them. -In write mode, -arguments or standard input lines referring to directories -do not cause files below the respective directory -to be archived. -.TP -\fB\-f\fI\ file\fR -Selects a -.I file -that is read with the -.I \-r -option instead of standard input -or written with the -.I \-w -option instead of standard output. -.TP -.B \-H -Follow symbolic links given on the command line when reading files with -.I \-w -or -.IR \-rw , -but do not follow symbolic links encountered during directory traversal. -.TP -.B \-i -Rename files interactively. -Before a file is extracted from the archive, -its file name is printed on standard error -and the user is prompted to specify a substitute file name. -If the line read from the terminal is empty, -the file is skipped; -if the line consists of a single dot, -the name is retained; -otherwise, -the line forms the new file name. -.TP -.B \-k -Causes existing files not to be overwritten. -.TP -.B \-K -Try to continue operation on read errors and invalid headers. -If an archive contains another archive, -files from either archive may be chosen. -.TP -.B \-l -Link files instead of copying them with -.I \-rw -if possible. -.TP -.B \-L -Follow symbolic links when reading files with -.I \-w -or -.IR \-rw . -.B /usr/posix2001/bin/pax -terminates immediately when it -detects a symbolic link loop with this option. -.TP -.B \-n -If any -.I pattern -arguments are present, -each pattern can match exactly one archive member; -further members that could match the particular pattern are ignored. -Without -.I pattern -arguments, -only the first occurence of -a file that occurs more than once in the archive -is selected, the following are ignored. -.TP -\fB\-o\ \fIoption\fB,\fR[\fIoption\fB,\fR\|...] -Specifies options as described for \fI\-x pax\fR. -.TP -\fB\-p\ \fIstring\fR -Specifies which file modes are to be preserved or ignored. -.I string -may contain one or more of -.RS -.TP -.B a -Inhibits preservation of file access times. -.TP -.B e -Causes preservation of every possible mode, ownership and time. -.TP -.B m -Inhibits preservation of file modification times. -.TP -.B o -Causes preservation of owner and group IDs. -.TP -.B p -Causes preservation of file mode bits -regardless of the umask -(see -.IR umask (2)). -.RE -.IP -If file ownership is preserved, -.I pax -tries to set the group ownerships to those specified in the archive -or the original hierarchy, respectively, -regardless of the privilegues of the invoking user. -.BR /usr/5bin/pax , -.BR /usr/5bin/s42/pax , -and -.B /usr/5bin/posix/pax -try to set the user ownerships only if invoked by the super-user; -if invoked by regular users, -.B /usr/5bin/posix2001/pax -will produce an error for any file that is not owned by the invoking user. -.TP -\fB\-s\ /\fIregular expression\fB/\fIreplacement\fB/\fR[\fBgp\fR] -Modifies file names in a manner similar to that described in -.IR ed (1). -The -.I p -flag causes each modified file name to printed. -Any character can be used as delimiter instead of -.RI ` / '. -If a file name is empty after the replacement is done, -the file is ignored. -This option can be specified multiple times -to execute multiple substitutions in the order specified. -.TP -.B \-t -Resets the access times of files -that were included in the archive with -.IR \-r . -.TP -.B \-u -In read mode, -.I pax -will not overwrite existing target files -that were modified more recently than the file in the archive -when this option is given. -In write mode, -.I pax -will read the archive first. -It will then only append those files to the archive -that are not already included -or were more recently modified. -.TP -.B \-v -Prints the file names of archived or extracted files with -.I \-r -and -.I \-w -and a verbose output format -if neither of them is given. -.TP -\fB\-x\fI header\fR -Specifies the archive header format to be one of: -.sp -.in +6 -.TS -lfB l. -\fBnewc\fR SVR4 ASCII cpio format;\ -\fBcrc\fR SVR4 ASCII cpio format with checksum;\ -\fBsco\fR T{ -SCO UnixWare 7.1 ASCII cpio format; -T} -\fBscocrc\fR T{ -SCO UnixWare 7.1 ASCII cpio format with checksum; -T} -\fBodc\fR T{ -traditional ASCII cpio format, as standardized in IEEE Std. 1003.1, 1996; -T} -\fBcpio\fR T{ -same as \fIodc\fR; -T} -\fBbin\fR binary cpio format; -\fBbbs\fR byte-swapped binary cpio format; -\fBsgi\fR T{ -SGI IRIX extended binary cpio format; -T} -\fBcray\fR T{ -Cray UNICOS 9 cpio format; -T} -\fBcray5\fR T{ -Cray UNICOS 5 cpio format; -T} -\fBdec\fR T{ -Digital UNIX extended cpio format; -T} -\fBtar\fR tar format; -\fBotar\fR old tar format; -\fBustar\fR T{ -IEEE Std. 1003.1, 1996 tar format; -T} -.T& -l s. -\fBpax\fR[\fB:\fIoption\fB,\fR[\fIoption\fB,\fR\|...]] -.T& -l l. -\& T{ -IEEE Std. 1003.1, 2001 pax format. -Format-specific \fIoptions\fR are: -.in +2n -.ti 0 -.br -\fBlinkdata\fR -.br -For a regular file which has multiple hard links, -the file data is stored once for each link in the archive, -instead of being stored for the first entry only. -This option must be used with care -since many implementations are unable -to read the resulting archive. -.ti 0 -.br -\fBtimes\fR -.br -Causes the times of last access and last modification -of each archived file -to be stored in an extended \fIpax\fR header. -This in particular allows the time of last access -to be restored when the archive is read. -.br -.in -2n -T} -\fBsun\fR T{ -Sun Solaris 7 extended tar format; -T} -\fBbar\fR T{ -SunOS 4 bar format; -T} -\fBgnu\fR T{ -GNU tar format; -T} -\fBzip\fR[\fB:\fIcc\fR] T{ -zip format with optional compression method. -If \fIcc\fR is one of -\fBen\fR (normal, default), -\fBex\fR (extra), -\fBef\fR (fast), -or -\fBes\fR (super fast), -the standard \fIdeflate\fR compression is used. -\fBe0\fR selects no compression, -and -\fBbz2\fR selects \fIbzip2\fR compression. -T} -.TE -.in -6 -.sp -This option is ignored with -.I \-r -unless the -.I \-K -option is also present. -The default for -.I \-w -is traditional ASCII cpio -.I (odc) -format. -.PP -.ne 38 -Characteristics of archive formats are as follows: -.sp -.TS -allbox; -l r r r l -l1fB r2 n2 r2 c. - T{ -.ad l -maximum user/\%group id -T} T{ -.ad l -maximum file size -T} T{ -.ad l -maximum pathname length -T} T{ -.ad l -bits in dev_t (major/minor) -T} -\-x\ bin 65535 2 GB\ 256 \ 16 -\-x\ sgi 65535 9 EB\ 256 \ 14/18 -T{ -\-x\ odc -T} 262143 8 GB\ 256 \ 18 -\-x\ dec 262143 8 GB\ 256 \ 24/24 -T{ -\-x\ newc, -\-x\ crc -T} 4.3e9 4 GB\ 1024 \ 32/32 -T{ -\-x\ sco, \-x\ scocrc -T} 4.3e9 9 EB\ 1024 \ 32/32 -T{ -\-x\ cray, \-x\ cray5 -T} 1.8e19 9 EB\ 65535 \ 64 -\-x\ otar 2097151 8 GB\ 99 \ n/a -T{ -\-x\ tar, -\-x\ ustar -T} 2097151 8 GB\ 256 (99) \ 21/21 -\-x\ pax 1.8e19 9 EB\ 65535 \ 21/21 -\-x\ sun 1.8e19 9 EB\ 65535 \ 63/63 -\-x\ gnu 1.8e19 9 EB\ 65535 \ 63/63 -\-x\ bar 2097151 8 GB\ 427 \ 21 -\-x\ zip 4.3e9 9 EB\ 60000 \ 32 -.TE -.sp -.PP -The byte order of -.B binary -cpio archives -depends on the machine -on which the archive is created. -Unlike some other implementations, -.I pax -fully supports -archives of either byte order. -.I \-x\ bbs -can be used to create an archive -with the byte order opposed to that of the current machine. -.PP -The -.B sgi -format extends the binary format -to handle larger files and more device bits. -If an archive does not contain any entries -that actually need the extensions, -it is identical to a binary archive. -.I \-x\ sgi -archives are always created in MSB order. -.PP -The -.B odc -format was introduced with System\ III -and standardized with IEEE Std. 1003.1. -All known -.I cpio -and -.I pax -implementations since around 1980 can read this format. -.PP -The -.B dec -format extends the -.I odc -format -to support more device bits. -Archives in this format are generally incompatible with -.I odc -archives -and need special implementation support to be read. -.PP -The -.B \-x\ newc -format was introduced with System\ V Release\ 4. -Except for the file size, -it imposes no practical limitations -on files archived. -The original SVR4 implementation -stores the contents of hard linked files -only once and with the last archived link. -This -.I pax -ensures compatibility with SVR4. -With archives created by implementations that employ other methods -for storing hard linked files, -each file is extracted as a single link, -and some of these files may be empty. -Implementations that expect methods other than the original SVR4 one -may extract no data for hard linked files at all. -.PP -The -.B crc -format is essentially the same as the -.I \-x\ newc -format -but adds a simple checksum (not a CRC, despite its name) -for the data of regular files. -The checksum requires the implementation to read each file twice, -which can considerably increase running time and system overhead. -As not all implementations claiming to support this format -handle the checksum correctly, -it is of limited use. -.PP -The -.B sco -and -.B scocrc -formats are variants of the -.I \-x\ newc -and -.I \-x\ crc -formats, respectively, -with extensions to support larger files. -The extensions result in a different archive format -only if files larger than slightly below 2\ GB occur. -.PP -The -.B cray -format extends all header fields to 64 bits. -It thus imposes no practical limitations of any kind -on archived files, -but requires special implementation support -to be read. -Although it is originally a binary format, -the byte order is always MSB as on Cray machines. -The -.B cray5 -format is an older variant -that was used with UNICOS 5 and earlier. -.PP -The -.B otar -format was introduced with the Unix 7th Edition -.I tar -utility. -Archives in this format -can be read on all Unix systems since about 1980. -It can only hold regular files -(and, on more recent systems, symbolic links). -For file names that contain characters with the most significant bit set -(non-ASCII characters), -implementations differ in the interpretation of the header checksum. -.PP -The -.B ustar -format was introduced with IEEE Std. 1003.1. -It extends the old -.I tar -format -with support for directories, device files, -and longer file names. -Pathnames of single-linked files can consist of up to 256 characters, -dependent on the position of slashes. -Files with multiple links can only be archived -if the first link encountered is no longer than 100 characters. -Due to implementation errors, -file names longer than 99 characters -can not considered to be generally portable. -Another addition of the -.I ustar -format -are fields for the symbolic user and group IDs. -These fields are created by -.IR pax , -but ignored when reading such archives. -.PP -With -.BR "\-x tar" , -a variant of the -.I ustar -format is selected -which stores file type bits in the mode field -to work around common implementation problems. -These bits are ignored by -.I pax -when reading archives. -.PP -The -.B pax -format is an extension to the -.I ustar -format. -If attributes cannot be archived with -.IR ustar , -an extended header is written. -Unless the size of an entry is greater than 8\ GB, -a -.I pax -archive should be readable by any implementation -capable of reading -.I ustar -archives, -although files may be extracted under wrong names -and extended headers may be extracted as separate files. -If a file name contains non-UTF-8 characters, -it may not be archived or extracted correctly -because of a problem of the -.I pax -format specification. -.PP -The -.B sun -format extends the -.I ustar -format similar as the -.I pax -format does. -The extended headers in -.I sun -format archives are not understood -by implementations that support only the -.I pax -format and vice-versa. -The -.I sun -format has also problems with non-UTF-8 characters in file names. -.PP -The -.B GNU -.I tar -format is mostly compatible with the other -.I tar -formats, -unless an archive entry actually uses its extended features. -There are no practical limitations on files archived with this format. -The implementation of -.I pax -is limited to expanded numerical fields -and long file names; -in particular, -there is no support for sparse files or incremental backups. -If -.I pax -creates a multi-volume -.I GNU -archive, -it just splits a single-volume archive in multiple parts, -as with the other formats; -.I GNU -multi-volume archives are not supported. -.PP -The -.B bar -format is similar to the -.I tar -format, but can store longer file names. -It requires special implementation support to be read. -.PP -The -.B zip -format can be read in many non-Unix environments. -There are several restrictions on archives -intended for data exchange: -only regular files should be stored; -file times, permissions and ownerships -might be ignored by other implementations; -there should be no more than 65536 files in the archive; -the total archive size should not exceed 2 GB; -only -.I deflate -compression should be used. -Otherwise, -.I pax -stores all information available with other archive formats -in extended -.I zip -file headers, -so if archive portability is of no concern, -the -.I zip -implementation in -.I pax -can archive complete Unix file hierarchies. -.I Pax -supports the -.I zip64 -format extension for large files; -it automatically writes -.I zip64 -entries if necessary. -.I Pax -can extract all known -.I zip -format compression codes. -It does not support -.I zip -encryption. -Multi-volume -.I zip -archives are created as splitted single-volume archives, -as with the other formats written by -.IR pax ; -generic multi-volume -.I zip -archives are not supported. -.SH EXAMPLES -Extract all files named -.I Makefile -or -.I makefile -from the archive stored on -.IR /dev/rmt/c0s0 , -overwriting recent files: -.RS 2 -.sp -pax \-r \-f /dev/rmt/c0s0 \'[Mm]akefile\' \'*/[Mm]akefile\' -.RE -.PP -List the files contained in a software distribution archive: -.RS 2 -.sp -pax \-v \-f distribution.tar.gz -.RE -.PP -Write a -.IR gzip (1) -compressed -.I ustar -archive containing all files below the directory -.I \%project -to the file -.IR \%project.tar.gz , -excluding all directories named -.I CVS -or -.I SCCS -and their contents: -.RS 2 -.sp -find project \-depth \-print | egrep \-v \'/(CVS|SCCS)(/|$)\' | -.br - pax \-wd \-x ustar | gzip \-c > project.tar.gz -.RE -.PP -Copy the directory -.I work -and its contents -to the directory -.IR \%savedfiles , -preserving all file attributes: -.RS 2 -.sp -pax \-rw \-pe work savedfiles -.RE -.PP -Self-extracting zip archives are not automatically recognized, -but can normally be read using the -.I \-K -option, as with -.RS 2 -.sp -pax \-rK \-x zip \-f archive.exe -.sp -.RE -.SH "ENVIRONMENT VARIABLES" -.TP -.BR LANG ", " LC_ALL -See -.IR locale (7). -.TP -.B LC_CTYPE -Selects the mapping of bytes to characters -used for matching patterns -and regular expressions. -.TP -.B LC_TIME -Sets the month names printed in list mode. -.SH "SEE ALSO" -cpio(1), -find(1), -tar(1) -.SH DIAGNOSTICS -.I Pax -exits with -.sp -.TS -l8fB l. -0 after successful operation; -1 on usage errors; -2 when operation was continued after minor errors; -3 on fatal error conditions. -.TE -.SH NOTES -Device and inode numbers -are used for hard link recognition -with the various cpio formats. -Since the header space cannot hold -large numbers present in current file systems, -devices and inode numbers are set on a per-archive basis. -This enables hard link recognition with all cpio formats, -but the link connection to files appended with -.I \-a -is not preserved. -.PP -If a numeric user or group id does not fit -within the size of the header field in the selected format, -files are stored with the user id (or group id, respectively) -set to 60001. -.PP -Use of the -.I \-a -option with a -.I zip -format archive may cause data loss -if the archive was not previously created by -.I cpio -or -.I pax -itself. -.PP -If the file names passed to -.I "pax -w" -begin with a slash character, -absolute path names are stored in the archive -and will be extracted to these path names later -regardless of the current working directory. -This is normally not advisable, -and relative path names should be passed to -.I pax -only. -The -.I \-s -option can be used to substitute relative for absolute path names -and vice-versa. -.PP -.I Pax -does not currently accept the -\fB\-o delete\fR, -\fB\-o exthdr.name\fR, -\fB\-o globexthdr.name\fR, -\fB\-o invalid\fR, -\fB\-o listopt\fR, -and -\fB\-o keyword\fR -options from POSIX.1-2001. diff --git a/tools/cpio/src/pax.c b/tools/cpio/src/pax.c deleted file mode 100644 index 50632b6b1..000000000 --- a/tools/cpio/src/pax.c +++ /dev/null @@ -1,757 +0,0 @@ -/* - * cpio - copy file archives in and out - * - * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. - */ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ - -#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 -#define USED __attribute__ ((used)) -#elif defined __GNUC__ -#define USED __attribute__ ((unused)) -#else -#define USED -#endif -#if defined (SU3) -static const char sccsid[] USED = "@(#)pax_su3.sl 1.26 (gritter) 6/26/05"; -#else -static const char sccsid[] USED = "@(#)pax.sl 1.26 (gritter) 6/26/05"; -#endif -/* Sccsid @(#)pax.c 1.26 (gritter) 6/26/05 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iblok.h" -#include "cpio.h" - -static char **files; -static int filec; -static struct iblok *filinp; -static char *path; -static size_t pathsz; -static int pax_Hflag; - -static void setpres(const char *); -static size_t ofiles_pax(char **, size_t *); -static void prtime_pax(time_t); -static void parsesub(char *); - -void -flags(int ac, char **av) -{ - const char optstring[] = "rwab:cdf:HikKlLno:p:s:tuvx:X"; - int i; - int illegal = 0; - char *x; - -#if defined (SU3) - pax = PAX_TYPE_PAX2001; -#else - pax = PAX_TYPE_PAX1992; -#endif - dflag = 1; - uflag = 1; - ofiles = ofiles_pax; - prtime = prtime_pax; - while ((i = getopt(ac, av, optstring)) != EOF) { - switch (i) { - case 'r': - if (action && action != 'i') - action = 'p'; - else - action = 'i'; - break; - case 'w': - if (action && action != 'o') - action = 'p'; - else - action = 'o'; - break; - case 'a': - Aflag = 1; - break; - case 'b': - blksiz = strtol(optarg, &x, 10); - switch (*x) { - case 'b': - blksiz *= 512; - break; - case 'k': - blksiz *= 1024; - break; - case 'm': - blksiz *= 1048576; - break; - case 'w': - blksiz *= 2; - break; - } - if (blksiz <= 0) - msg(4, -2, - "Illegal size given for -b option.\n"); - Cflag = 1; - break; - case 'c': - fflag = 1; - break; - case 'd': - pax_dflag = 1; - break; - case 'f': - Oflag = Iflag = optarg; - break; - case 'H': - pax_Hflag = 1; - break; - case 'i': - rflag = 1; - break; - case 'k': - pax_kflag = 1; - break; - case 'K': - kflag = 1; - break; - case 'l': - lflag = 1; - break; - case 'L': - Lflag = 1; - break; - case 'n': - pax_nflag = 1; - break; - case 'o': - pax_options(optarg, 1); - break; - case 'p': - setpres(optarg); - break; - case 's': - pax_sflag = 1; - parsesub(optarg); - break; - case 't': - aflag = 1; - break; - case 'u': - uflag = 0; - pax_uflag = 1; - break; - case 'v': - vflag = 1; - break; - case 'x': - if (strcmp(optarg, "cpio") == 0) - fmttype = FMT_ODC; - else { - if (setfmt(optarg) < 0) - illegal = 1; - } - break; - case 'X': - pax_Xflag = 1; - break; - default: - illegal = 1; - } - } - switch (action) { - case 0: - if (rflag || pax_kflag || pax_uflag || pax_preserve) - illegal = 1; - action = 'i'; - tflag = 1; - setvbuf(stdout, NULL, _IOLBF, 0); - /*FALLTHRU*/ - case 'i': - if (aflag || pax_Xflag || lflag) - illegal = 1; - for (i = optind; i < ac; i++) { - addg(av[i], 0); - if (pax_dflag == 0) { - char *da; - int j; - - da = smalloc(strlen(av[i]) + 2); - for (j = 0; av[i][j]; j++) - da[j] = av[i][j]; - da[j++] = '/'; - da[j++] = '*'; - da[j] = 0; - addg(da, 1); - free(da); - } - } - break; - case 'o': - if (fflag || pax_kflag || pax_nflag || kflag) - illegal = 1; - if (Aflag && Oflag == NULL) { - msg(3, 0, "-a requires the -f option\n"); - illegal = 1; - } - if (optind != ac) { - files = &av[optind]; - filec = ac - optind; - } else - filinp = ib_alloc(0, 0); - if (pax_uflag) - Aflag = 1; - if (Aflag == 0 && fmttype == FMT_NONE) - fmttype = FMT_ODC; - break; - case 'p': - if (fflag || blksiz || Oflag || Iflag || fmttype != FMT_NONE || - kflag) - illegal = 1; - if (optind == ac) - illegal = 1; - else if (optind+1 != ac) { - files = &av[optind]; - filec = ac - optind - 1; - optind = ac - 1; - } else - filinp = ib_alloc(0, 0); - break; - } - if (illegal) - usage(); -} - -void -usage(void) -{ - fprintf(stderr, "USAGE:\n\ -\t%s [-cdnvK] [-b size] [-f file] [-s replstr] [-x hdr] [patterns]\n\ -\t%s -r[cdiknuvK] [-b size] [-f file] [-p priv] [-s replstr] [-x hdr] [patterns]\n\ -\t%s -w[adituvLX] [-b size] [-f file] [-s replstr] [-x hdr] [files]\n\ -\t%s -rw[diklntuvLX] [-p priv] [-s replstr] [files] directory\n", - progname, progname, progname, progname); - exit(1); -} - -static void -setpres(const char *s) -{ - s--; - while (*++s) { - pax_preserve &= ~PAX_P_EVERY; - switch (*s) { - case 'a': - pax_preserve |= PAX_P_ATIME; - break; - case 'e': - pax_preserve |= PAX_P_EVERY; - break; - case 'm': - pax_preserve |= PAX_P_MTIME; - break; - case 'o': - pax_preserve |= PAX_P_OWNER; - break; - case 'p': - pax_preserve |= PAX_P_MODE; - break; - default: - msg(2, 0, "ignoring unknown option \"-p%c\"\n", - *s&0377); - } - } - if (pax_preserve & PAX_P_EVERY) - pax_preserve |= PAX_P_OWNER|PAX_P_MODE; -} - -int -gmatch(const char *s, const char *p) -{ - int val; -#ifdef __GLIBC__ - /* avoid glibc's broken [^...] */ - extern char **environ; - char **savenv = environ; - char *newenv[] = { "POSIXLY_CORRECT=", NULL }; - environ = newenv; -#endif /* __GLIBC__ */ - val = fnmatch(p, s, 0) == 0; -#ifdef __GLIBC__ - environ = savenv; -#endif /* __GLIBC__ */ - return val; -} - -static const char * -nextfile(void) -{ - char *line = NULL; - size_t linsiz = 0, linlen; - - if (filinp) { - pax_Hflag = 0; - if ((linlen=ib_getlin(filinp, &line, &linsiz, srealloc)) == 0) { - filinp = NULL; - return NULL; - } - if (line[linlen-1] == '\n') - line[--linlen] = '\0'; - return line; - } else if (filec > 0) { - filec--; - return *files++; - } else - return NULL; -} - -static size_t -catpath(size_t pend, const char *base) -{ - size_t blen = strlen(base); - - if (pend + blen + 2 >= pathsz) - path = srealloc(path, pathsz = pend + blen + 16); - if (pend == 0 || path[pend-1] != '/') - path[pend++] = '/'; - strcpy(&path[pend], base); - return pend + blen; -} - -/* - * Descend the directory hierarchies given using stdin or arguments - * and return file names one per one. - */ -static size_t -ofiles_pax(char **name, size_t *namsiz) -{ - static DIR **dt; - static int dti, dts; - static int *pend; - static dev_t *curdev; - static ino_t *curino; - struct stat st; - struct dirent *dp; - const char *nf; - int i; - - if (dt == NULL) { - dt = scalloc(dts = 1, sizeof *dt); - pend = scalloc(dts, sizeof *pend); - curdev = scalloc(dts, sizeof *curdev); - curino = scalloc(dts, sizeof *curino); - } - for (;;) { - if (dti >= 0 && dt[dti] != NULL) { - if ((dp = readdir(dt[dti])) != NULL) { - if (dp->d_name[0] == '.' && - (dp->d_name[1] == '\0' || - dp->d_name[1] == '.' && - dp->d_name[2] == '\0')) - continue; - if (dti+1 <= dts) { - dt = srealloc(dt, sizeof *dt * ++dts); - pend = srealloc(pend, sizeof *pend*dts); - curdev = srealloc(curdev, sizeof *curdev - * dts); - curino = srealloc(curino, sizeof *curino - * dts); - } - pend[dti+1] = catpath(pend[dti], dp->d_name); - if (pax_Hflag) - Lflag = dti < 0; - if ((Lflag ? stat : lstat)(path, &st) < 0) { - emsg(2, "Error with %s of \"%s\"", - lflag? "stat" : "lstat", - path); - errcnt++; - } else if ((st.st_mode&S_IFMT) == S_IFDIR && - (pax_Xflag == 0 || - curdev[0] == st.st_dev)) { - if (Lflag) { - for (i = 0; i <= dti; i++) - if (st.st_dev == - curdev[i] && - st.st_ino == - curino[i]) { - if (pax == - PAX_TYPE_PAX2001) - msg(4, 1, - "Symbolic link " - "loop at " - "\"%s\"\n", - path); - break; - } - if (i <= dti) - break; - } - if ((dt[dti+1]=opendir(path)) == NULL) { - emsg(2, "Cannot open directory " - "\"%s\"", path); - errcnt++; - } else { - dti++; - curdev[dti] = st.st_dev; - curino[dti] = st.st_ino; - continue; - } - } else - break; - } else { - path[pend[dti]] = '\0'; - closedir(dt[dti]); - dt[dti--] = NULL; - if (pax_Hflag) - Lflag = dti < 0; - break; - } - } else { - if (pax_Hflag) - Lflag = 1; - while ((nf = nextfile()) != NULL && - (Lflag ? stat : lstat)(nf, &st) < 0) { - emsg(2, "Error with stat of \"%s\"", nf); - errcnt++; - } - if (nf == NULL) - return 0; - dti = 0; - if (path) - free(path); - pend[dti] = strlen(nf); - strcpy(path = smalloc(pathsz = pend[dti]+1), nf); - if (pax_dflag || (st.st_mode&S_IFMT) != S_IFDIR) { - dti = -1; - break; - } - curdev[dti] = st.st_dev; - curino[dti] = st.st_ino; - if ((dt[dti] = opendir(path)) == NULL) { - emsg(2, "Cannot open directory \"%s\"", path); - errcnt++; - } - } - } - if (*name == NULL || *namsiz < pathsz) { - free(*name); - *name = smalloc(*namsiz=pathsz); - } - strcpy(*name, path); - return pend[dti+1]; -} - -struct pax_had { - struct pax_had *p_next; - const char *p_name; - time_t p_mtime; -}; - -static int pprime = 7919; - -static int -phash(const char *s) -{ - uint32_t h = 0, g; - - s--; - while (*++s) { - h = (h << 4) + (*s & 0377); - if (g = h & 0xf0000000) { - h = h ^ (g >> 24); - h = h ^ g; - } - } - return h % pprime; -} - -static int -plook(const char *name, struct pax_had **pp) -{ - static struct pax_had **pt; - uint32_t h, had; - - if (pt == NULL) - pt = scalloc(pprime, sizeof *pt); - (*pp) = pt[h = phash(name)]; - while (*pp != NULL) { - if (strcmp((*pp)->p_name, name) == 0) - break; - *pp = (*pp)->p_next; - } - had = *pp != NULL; - if (*pp == NULL) { - *pp = scalloc(1, sizeof **pp); - (*pp)->p_name = sstrdup(name); - (*pp)->p_next = pt[h]; - pt[h] = *pp; - } - return had; -} - -int -pax_track(const char *name, time_t mtime) -{ - struct pax_had *pp; - struct stat st; - - if (pax_uflag == 0 && (pax_nflag == 0 || patterns)) - return 1; - if (action == 'i' && pax_uflag) { - if (lstat(name, &st) == 0 && mtime < st.st_mtime) - return 0; - } - if (action != 'i' || pax_nflag) { - if (plook(name, &pp) != 0) { - if (action != 'i' && pax_uflag == 0) - return 0; - if (mtime > pp->p_mtime) { - pp->p_mtime = mtime; - return 1; - } - return 0; - } else - pp->p_mtime = mtime; - } - return 1; -} - -static void -prtime_pax(time_t t) -{ - char b[30]; - time_t now; - - time(&now); - if (t > now || t < now - (6*30*86400)) - strftime(b, sizeof b, "%b %e %Y", localtime(&t)); - else - strftime(b, sizeof b, "%b %e %H:%M", localtime(&t)); - printf(" %s ", b); -} - -struct replacement { - regex_t r_re; - const char *r_rhs; - int r_nbra; - enum { - REPL_0 = 0, - REPL_G = 1, - REPL_P = 2 - } r_flags; -} *rep; - -#define NBRA 9 -static int ren, res; -static int mb_cur_max; - -static wchar_t -nextc(char **sc, int *np) -{ - char *p = *sc; - wchar_t wcbuf; - int len; - - if (**sc == '\0') { - *np = 0; - return 0; - } - if (mb_cur_max == 1 || (**sc&0200) == 0) { - *np = 1; - return *(*sc)++ & 0377; - } - if ((len = mbtowc(&wcbuf, p, mb_cur_max)) < 0) - msg(3, -2, "Invalid multibyte character for \"-s\" option\n"); - *np = len; - *sc += len; - return wcbuf; -} - -static void -parsesub(char *s) -{ - int len; - char *ps = NULL; - wchar_t seof = nextc(&s, &len); - wint_t c, d; - int nbra = 0; - int reflags; - - if (seof == 0) - goto unt; - mb_cur_max = MB_CUR_MAX; - ps = s; - do { - if ((c = nextc(&s, &len)) == seof) - break; - if (c == '\\') { - if ((c = nextc(&s, &len)) == '(') - nbra++; - continue; - } else if (c == '[') { - d = WEOF; - do { - if ((c = nextc(&s, &len)) == '\0') - continue; - if (d == '[' && (c == ':' || c == '.' || - c == '=')) { - d = c; - do { - if ((c=nextc(&s, &len)) == '\0') - continue; - } while (c != d || *s != ']'); - nextc(&s, &len); - c = WEOF; /* reset d and continue */ - } - d = c; - } while (c != ']'); - } - } while (*s != '\0'); - if (c != seof) - unt: msg(3, -2, "Unterminated argument for \"-s\" option.\n"); - s[-len] = '\0'; - if (ren <= res) - rep = srealloc(rep, ++res * sizeof *rep); - reflags = REG_ANGLES; - if (pax >= PAX_TYPE_PAX2001) - reflags |= REG_AVOIDNULL; - if (regcomp(&rep[ren].r_re, ps, reflags) != 0) - msg(3, -2, "Regular expression error in \"-s\" option\n"); - rep[ren].r_rhs = s; - rep[ren].r_nbra = nbra; - while ((c = nextc(&s, &len)) != 0) { - if (c == '\\') - c = nextc(&s, &len); - else if (c == seof) - break; - } - rep[ren].r_flags = 0; - if (c == seof) { - s[-len] = '\0'; - while ((c = nextc(&s, &len)) != '\0') { - switch (c) { - case 'g': - rep[ren].r_flags |= REPL_G; - break; - case 'p': - rep[ren].r_flags |= REPL_P; - break; - default: - msg(2, 0, "Ignoring unknown -s flag \"%c\"\n", - c); - } - } - } - ren++; -} - -#define put(c) ((new = innew+1>=newsize ? srealloc(new, newsize+=32) : new), \ - new[innew++] = (c)) - -int -pax_sname(char **oldp, size_t *olds) -{ - char *new = NULL; - size_t newsize = 0; - regmatch_t bralist[NBRA+1]; - int c, i, k, l, y, z; - int innew = 0, ef = 0; - char *inp = *oldp; - - for (z = 0; z < ren; z++) { - in: if (regexec(&rep[z].r_re, inp, NBRA+1, bralist, ef) != 0) { - if (ef == 0) - continue; - goto out; - } - for (i = 0; i < bralist[0].rm_so; i++) - put(inp[i]); - k = 0; - while (c = rep[z].r_rhs[k++] & 0377) { - y = -1; - if (c == '&') - y = 0; - else if (c == '\\') { - c = rep[z].r_rhs[k++] & 0377; - if (c >= '1' && c < rep[z].r_nbra+'1') - y = c - '0'; - } - if (y >= 0) - for (l = bralist[y].rm_so; l < bralist[y].rm_eo; - l++) - put(inp[l]); - else - put(c); - } - k = innew; - for (i = bralist[0].rm_eo; inp[i]; i++) - put(inp[i]); - put('\0'); - if (rep[z].r_flags & REPL_G) { - ef = REG_NOTBOL; - inp = &inp[bralist[0].rm_eo]; - innew = k; - if (bralist[0].rm_so == bralist[0].rm_eo) { - if (inp[0] && (nextc(&inp, &l), inp[0])) - innew++; - else - goto out; - } - goto in; - } - out: if (rep[z].r_flags & REPL_P) - fprintf(stderr, "%s >> %s\n", *oldp, new); - free(*oldp); - *oldp = new; - *olds = newsize; - return *new != '\0'; - } - return 1; -} - -void -pax_onexit(void) -{ - struct glist *gp; - - for (gp = patterns; gp; gp = gp->g_nxt) { - if (gp->g_art) - continue; - if (gp->g_gotcha == 0 && (gp->g_nxt == NULL || - gp->g_nxt->g_art == 0 || - gp->g_gotcha == 0)) { - msg(3, 0, "Pattern not matched: \"%s\"\n", gp->g_pat); - errcnt++; - } - } -} diff --git a/tools/cpio/src/pfmt.c b/tools/cpio/src/pfmt.c deleted file mode 100644 index 8adc22f23..000000000 --- a/tools/cpio/src/pfmt.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)pfmt.c 1.2 (gritter) 9/21/03 */ - -#include -#include - -#include "pfmt.h" - -int -pfmt(FILE *stream, long flags, const char *fmt, ...) -{ - va_list ap; - int i; - - va_start(ap, fmt); - i = vpfmt(stream, flags, fmt, ap); - va_end(ap); - return i; -} diff --git a/tools/cpio/src/pfmt.h b/tools/cpio/src/pfmt.h deleted file mode 100644 index 012667b0b..000000000 --- a/tools/cpio/src/pfmt.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)pfmt.h 1.2 (gritter) 9/21/03 */ - -#include - -extern int pfmt(FILE *stream, long flags, const char *format, ...); - -#include - -extern int vpfmt(FILE *stream, long flags, const char *format, va_list ap); - -#define MM_HALT 0x00000001 -#define MM_ERROR 0x00000000 -#define MM_WARNING 0x00000002 -#define MM_INFO 0x00000004 -#define MM_ACTION 0x00000100 -#define MM_NOSTD 0x00000200 -#define MM_STD 0x00000000 -#define MM_NOGET 0x00000400 -#define MM_GET 0x00000000 - -extern int setlabel(const char *label); -extern int setuxlabel(const char *label); - -#define setcat(s) (s) -#define gettxt(n, s) (s) diff --git a/tools/cpio/src/pfmt_label.c b/tools/cpio/src/pfmt_label.c deleted file mode 100644 index 5b1a53f0a..000000000 --- a/tools/cpio/src/pfmt_label.c +++ /dev/null @@ -1 +0,0 @@ -char *pfmt_label__; diff --git a/tools/cpio/src/regexp.h b/tools/cpio/src/regexp.h deleted file mode 100644 index 5b1fee5e6..000000000 --- a/tools/cpio/src/regexp.h +++ /dev/null @@ -1,1211 +0,0 @@ -/* - * Simple Regular Expression functions. Derived from Unix 7th Edition, - * /usr/src/cmd/expr.y - * - * Modified by Gunnar Ritter, Freiburg i. Br., Germany, February 2002. - * - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * Redistributions of source code and documentation must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of - * other contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``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 CALDERA INTERNATIONAL, INC. 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. - */ - -#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 -#define REGEXP_H_USED __attribute__ ((used)) -#elif defined __GNUC__ -#define REGEXP_H_USED __attribute__ ((unused)) -#else -#define REGEXP_H_USED -#endif -static const char regexp_h_sccsid[] REGEXP_H_USED = - "@(#)regexp.sl 1.56 (gritter) 5/29/05"; - -#if !defined (REGEXP_H_USED_FROM_VI) && !defined (__dietlibc__) -#define REGEXP_H_WCHARS -#endif - -#define CBRA 2 -#define CCHR 4 -#define CDOT 8 -#define CCL 12 -/* CLNUM 14 used in sed */ -/* CEND 16 used in sed */ -#define CDOL 20 -#define CCEOF 22 -#define CKET 24 -#define CBACK 36 -#define CNCL 40 -#define CBRC 44 -#define CLET 48 -#define CCH1 52 -#define CCH2 56 -#define CCH3 60 - -#define STAR 01 -#define RNGE 03 -#define REGEXP_H_LEAST 0100 - -#ifdef REGEXP_H_WCHARS -#define CMB 0200 -#else /* !REGEXP_H_WCHARS */ -#define CMB 0 -#endif /* !REGEXP_H_WCHARS */ - -#define NBRA 9 - -#define PLACE(c) ep[c >> 3] |= bittab[c & 07] -#define ISTHERE(c) (ep[c >> 3] & bittab[c & 07]) - -#ifdef REGEXP_H_WCHARS -#define REGEXP_H_IS_THERE(ep, c) ((ep)[c >> 3] & bittab[c & 07]) -#endif - -#include -#include -#include -#ifdef REGEXP_H_WCHARS -#include -#include -#include -#endif /* REGEXP_H_WCHARS */ - -#define regexp_h_uletter(c) (isalpha(c) || (c) == '_') -#ifdef REGEXP_H_WCHARS -#define regexp_h_wuletter(c) (iswalpha(c) || (c) == L'_') - -/* - * Used to allocate memory for the multibyte star algorithm. - */ -#ifndef regexp_h_malloc -#define regexp_h_malloc(n) malloc(n) -#endif -#ifndef regexp_h_free -#define regexp_h_free(p) free(p) -#endif - -/* - * Can be predefined to 'inline' to inline some multibyte functions; - * may improve performance for files that contain many multibyte - * sequences. - */ -#ifndef regexp_h_inline -#define regexp_h_inline -#endif - -/* - * Mask to determine whether the first byte of a sequence possibly - * starts a multibyte character. Set to 0377 to force mbtowc() for - * any byte sequence (except 0). - */ -#ifndef REGEXP_H_MASK -#define REGEXP_H_MASK 0200 -#endif -#endif /* REGEXP_H_WCHARS */ - -/* - * For regexpr.h. - */ -#ifndef regexp_h_static -#define regexp_h_static -#endif -#ifndef REGEXP_H_STEP_INIT -#define REGEXP_H_STEP_INIT -#endif -#ifndef REGEXP_H_ADVANCE_INIT -#define REGEXP_H_ADVANCE_INIT -#endif - -char *braslist[NBRA]; -char *braelist[NBRA]; -int nbra; -char *loc1, *loc2, *locs; -int sed; -int nodelim; - -regexp_h_static int circf; -regexp_h_static int low; -regexp_h_static int size; - -regexp_h_static unsigned char bittab[] = { - 1, - 2, - 4, - 8, - 16, - 32, - 64, - 128 -}; -static int regexp_h_advance(register const char *lp, - register const char *ep); -static void regexp_h_getrnge(register const char *str, int least); - -static const char *regexp_h_bol; /* beginning of input line (for \<) */ - -#ifdef REGEXP_H_WCHARS -static int regexp_h_wchars; -static int regexp_h_mbcurmax; - -static const char *regexp_h_firstwc; /* location of first - multibyte character - on input line */ - -#define regexp_h_getwc(c) { \ - if (regexp_h_wchars) { \ - char mbbuf[MB_LEN_MAX + 1], *mbptr; \ - wchar_t wcbuf; \ - int mb, len; \ - mbptr = mbbuf; \ - do { \ - mb = GETC(); \ - *mbptr++ = mb; \ - *mbptr = '\0'; \ - } while ((len = mbtowc(&wcbuf, mbbuf, regexp_h_mbcurmax)) < 0 \ - && mb != eof && mbptr < mbbuf + MB_LEN_MAX); \ - if (len == -1) \ - ERROR(67); \ - c = wcbuf; \ - } else { \ - c = GETC(); \ - } \ -} - -#define regexp_h_store(wc, mb, me) { \ - int len; \ - if (wc == WEOF) \ - ERROR(67); \ - if ((len = me - mb) <= regexp_h_mbcurmax) { \ - char mt[MB_LEN_MAX]; \ - if (wctomb(mt, wc) >= len) \ - ERROR(50); \ - } \ - switch (len = wctomb(mb, wc)) { \ - case -1: \ - ERROR(67); \ - case 0: \ - mb++; \ - break; \ - default: \ - mb += len; \ - } \ -} - -static regexp_h_inline wint_t -regexp_h_fetchwc(const char **mb, int islp) -{ - wchar_t wc; - int len; - - if ((len = mbtowc(&wc, *mb, regexp_h_mbcurmax)) < 0) { - (*mb)++; - return WEOF; - } - if (islp && regexp_h_firstwc == NULL) - regexp_h_firstwc = *mb; - /*if (len == 0) { - (*mb)++; - return L'\0'; - } handled in singlebyte code */ - *mb += len; - return wc; -} - -#define regexp_h_fetch(mb, islp) ((*(mb) & REGEXP_H_MASK) == 0 ? \ - (*(mb)++&0377): \ - regexp_h_fetchwc(&(mb), islp)) - -static regexp_h_inline wint_t -regexp_h_showwc(const char *mb) -{ - wchar_t wc; - - if (mbtowc(&wc, mb, regexp_h_mbcurmax) < 0) - return WEOF; - return wc; -} - -#define regexp_h_show(mb) ((*(mb) & REGEXP_H_MASK) == 0 ? (*(mb)&0377): \ - regexp_h_showwc(mb)) - -/* - * Return the character immediately preceding mb. Since no byte is - * required to be the first byte of a character, the longest multibyte - * character ending at &[mb-1] is searched. - */ -static regexp_h_inline wint_t -regexp_h_previous(const char *mb) -{ - const char *p = mb; - wchar_t wc, lastwc = WEOF; - int len, max = 0; - - if (regexp_h_firstwc == NULL || mb <= regexp_h_firstwc) - return (mb > regexp_h_bol ? (mb[-1] & 0377) : WEOF); - while (p-- > regexp_h_bol) { - mbtowc(NULL, NULL, 0); - if ((len = mbtowc(&wc, p, mb - p)) >= 0) { - if (len < max || len < mb - p) - break; - max = len; - lastwc = wc; - } else if (len < 0 && max > 0) - break; - } - return lastwc; -} - -#define regexp_h_cclass(set, c, af) \ - ((c) == 0 || (c) == WEOF ? 0 : ( \ - ((c) > 0177) ? \ - regexp_h_cclass_wc(set, c, af) : ( \ - REGEXP_H_IS_THERE((set)+1, (c)) ? (af) : !(af) \ - ) \ - ) \ - ) - -static regexp_h_inline int -regexp_h_cclass_wc(const char *set, register wint_t c, int af) -{ - register wint_t wc, wl = WEOF; - const char *end; - - end = &set[18] + set[0] - 1; - set += 17; - while (set < end) { - wc = regexp_h_fetch(set, 0); -#ifdef REGEXP_H_VI_BACKSLASH - if (wc == '\\' && set < end && - (*set == ']' || *set == '-' || - *set == '^' || *set == '\\')) { - wc = regexp_h_fetch(set, 0); - } else -#endif /* REGEXP_H_VI_BACKSLASH */ - if (wc == '-' && wl != WEOF && set < end) { - wc = regexp_h_fetch(set, 0); -#ifdef REGEXP_H_VI_BACKSLASH - if (wc == '\\' && set < end && - (*set == ']' || *set == '-' || - *set == '^' || *set == '\\')) { - wc = regexp_h_fetch(set, 0); - } -#endif /* REGEXP_H_VI_BACKSLASH */ - if (c > wl && c < wc) - return af; - } - if (c == wc) - return af; - wl = wc; - } - return !af; -} -#else /* !REGEXP_H_WCHARS */ -#define regexp_h_wchars 0 -#define regexp_h_getwc(c) { c = GETC(); } -#endif /* !REGEXP_H_WCHARS */ - -regexp_h_static char * -compile(char *instring, char *ep, const char *endbuf, int seof) -{ - INIT /* Dependent declarations and initializations */ - register int c; - register int eof = seof; - char *lastep = instring; - int cclcnt; - char bracket[NBRA], *bracketp; - int closed; - char neg; - int lc; - int i, cflg; - -#ifdef REGEXP_H_WCHARS - char *eq; - regexp_h_mbcurmax = MB_CUR_MAX; - regexp_h_wchars = regexp_h_mbcurmax > 1 ? CMB : 0; -#endif - lastep = 0; - bracketp = bracket; - if((c = GETC()) == eof || c == '\n') { - if (c == '\n') { - UNGETC(c); - nodelim = 1; - } - if(*ep == 0 && !sed) - ERROR(41); - if (bracketp > bracket) - ERROR(42); - RETURN(ep); - } - circf = closed = nbra = 0; - if (c == '^') - circf++; - else - UNGETC(c); - for (;;) { - if (ep >= endbuf) - ERROR(50); - regexp_h_getwc(c); - if(c != '*' && ((c != '\\') || (PEEKC() != '{'))) - lastep = ep; - if (c == eof) { - *ep++ = CCEOF; - if (bracketp > bracket) - ERROR(42); - RETURN(ep); - } - switch (c) { - - case '.': - *ep++ = CDOT|regexp_h_wchars; - continue; - - case '\n': - if (sed == 0) { - UNGETC(c); - *ep++ = CCEOF; - nodelim = 1; - RETURN(ep); - } - ERROR(36); - case '*': - if (lastep==0 || *lastep==CBRA || *lastep==CKET || - *lastep==(CBRC|regexp_h_wchars) || - *lastep==(CLET|regexp_h_wchars)) - goto defchar; - *lastep |= STAR; - continue; - - case '$': - if(PEEKC() != eof) - goto defchar; - *ep++ = CDOL; - continue; - - case '[': -#ifdef REGEXP_H_WCHARS - if (regexp_h_wchars == 0) { -#endif - if(&ep[33] >= endbuf) - ERROR(50); - - *ep++ = CCL; - lc = 0; - for(i = 0; i < 32; i++) - ep[i] = 0; - - neg = 0; - if((c = GETC()) == '^') { - neg = 1; - c = GETC(); - } - - do { - c &= 0377; - if(c == '\0' || c == '\n') - ERROR(49); -#ifdef REGEXP_H_VI_BACKSLASH - if(c == '\\' && ((c = PEEKC()) == ']' || - c == '-' || c == '^' || - c == '\\')) { - c = GETC(); - c &= 0377; - } else -#endif /* REGEXP_H_VI_BACKSLASH */ - if(c == '-' && lc != 0) { - if ((c = GETC()) == ']') { - PLACE('-'); - break; - } -#ifdef REGEXP_H_VI_BACKSLASH - if(c == '\\' && - ((c = PEEKC()) == ']' || - c == '-' || - c == '^' || - c == '\\')) - c = GETC(); -#endif /* REGEXP_H_VI_BACKSLASH */ - c &= 0377; - while(lc < c) { - PLACE(lc); - lc++; - } - } - lc = c; - PLACE(c); - } while((c = GETC()) != ']'); - if(neg) { - for(cclcnt = 0; cclcnt < 32; cclcnt++) - ep[cclcnt] ^= 0377; - ep[0] &= 0376; - } - - ep += 32; -#ifdef REGEXP_H_WCHARS - } else { - if (&ep[18] >= endbuf) - ERROR(50); - *ep++ = CCL|CMB; - *ep++ = 0; - lc = 0; - for (i = 0; i < 16; i++) - ep[i] = 0; - eq = &ep[16]; - regexp_h_getwc(c); - if (c == L'^') { - regexp_h_getwc(c); - ep[-2] = CNCL|CMB; - } - do { - if (c == '\0' || c == '\n') - ERROR(49); -#ifdef REGEXP_H_VI_BACKSLASH - if(c == '\\' && ((c = PEEKC()) == ']' || - c == '-' || c == '^' || - c == '\\')) { - regexp_h_store(c, eq, endbuf); - regexp_h_getwc(c); - } else -#endif /* REGEXP_H_VI_BACKSLASH */ - if (c == '-' && lc != 0 && lc <= 0177) { - regexp_h_store(c, eq, endbuf); - regexp_h_getwc(c); - if (c == ']') { - PLACE('-'); - break; - } -#ifdef REGEXP_H_VI_BACKSLASH - if(c == '\\' && - ((c = PEEKC()) == ']' || - c == '-' || - c == '^' || - c == '\\')) { - regexp_h_store(c, eq, - endbuf); - regexp_h_getwc(c); - } -#endif /* REGEXP_H_VI_BACKSLASH */ - while (lc < (c & 0177)) { - PLACE(lc); - lc++; - } - } - lc = c; - if (c <= 0177) - PLACE(c); - regexp_h_store(c, eq, endbuf); - regexp_h_getwc(c); - } while (c != L']'); - if ((i = eq - &ep[16]) > 255) - ERROR(50); - lastep[1] = i; - ep = eq; - } -#endif /* REGEXP_H_WCHARS */ - - continue; - - case '\\': - regexp_h_getwc(c); - switch(c) { - - case '(': - if(nbra >= NBRA) - ERROR(43); - *bracketp++ = nbra; - *ep++ = CBRA; - *ep++ = nbra++; - continue; - - case ')': - if(bracketp <= bracket) - ERROR(42); - *ep++ = CKET; - *ep++ = *--bracketp; - closed++; - continue; - - case '<': - *ep++ = CBRC|regexp_h_wchars; - continue; - - case '>': - *ep++ = CLET|regexp_h_wchars; - continue; - - case '{': - if(lastep == (char *) (0)) - goto defchar; - *lastep |= RNGE; - cflg = 0; - nlim: - c = GETC(); - i = 0; - do { - if ('0' <= c && c <= '9') - i = 10 * i + c - '0'; - else - ERROR(16); - } while(((c = GETC()) != '\\') && (c != ',')); - if (i > 255) - ERROR(11); - *ep++ = i; - if (c == ',') { - if(cflg++) - ERROR(44); - if((c = GETC()) == '\\') { - *ep++ = (char)255; - *lastep |= REGEXP_H_LEAST; - } else { - UNGETC(c); - goto nlim; /* get 2'nd number */ - } - } - if(GETC() != '}') - ERROR(45); - if(!cflg) /* one number */ - *ep++ = i; - else if((ep[-1] & 0377) < (ep[-2] & 0377)) - ERROR(46); - continue; - - case '\n': - ERROR(36); - - case 'n': - c = '\n'; - goto defchar; - - default: - if(c >= '1' && c <= '9') { - if((c -= '1') >= closed) - ERROR(25); - *ep++ = CBACK; - *ep++ = c; - continue; - } - } - /* Drop through to default to use \ to turn off special chars */ - - defchar: - default: - lastep = ep; -#ifdef REGEXP_H_WCHARS - if (regexp_h_wchars == 0) { -#endif - *ep++ = CCHR; - *ep++ = c; -#ifdef REGEXP_H_WCHARS - } else { - char mbbuf[MB_LEN_MAX]; - - switch (wctomb(mbbuf, c)) { - case 1: *ep++ = CCH1; - break; - case 2: *ep++ = CCH2; - break; - case 3: *ep++ = CCH3; - break; - default: - *ep++ = CCHR|CMB; - } - regexp_h_store(c, ep, endbuf); - } -#endif /* REGEXP_H_WCHARS */ - } - } -} - -int -step(const char *p1, const char *p2) -{ - register int c; -#ifdef REGEXP_H_WCHARS - register int d; -#endif /* REGEXP_H_WCHARS */ - - REGEXP_H_STEP_INIT /* get circf */ - regexp_h_bol = p1; -#ifdef REGEXP_H_WCHARS - regexp_h_firstwc = NULL; -#endif /* REGEXP_H_WCHARS */ - if (circf) { - loc1 = (char *)p1; - return(regexp_h_advance(p1, p2)); - } - /* fast check for first character */ - if (*p2==CCHR) { - c = p2[1] & 0377; - do { - if ((*p1 & 0377) != c) - continue; - if (regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - } while (*p1++); - return(0); - } -#ifdef REGEXP_H_WCHARS - else if (*p2==CCH1) { - do { - if (p1[0] == p2[1] && regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - c = regexp_h_fetch(p1, 1); - } while (c); - return(0); - } else if (*p2==CCH2) { - do { - if (p1[0] == p2[1] && p1[1] == p2[2] && - regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - c = regexp_h_fetch(p1, 1); - } while (c); - return(0); - } else if (*p2==CCH3) { - do { - if (p1[0] == p2[1] && p1[1] == p2[2] && p1[2] == p2[3]&& - regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - c = regexp_h_fetch(p1, 1); - } while (c); - return(0); - } else if ((*p2&0377)==(CCHR|CMB)) { - d = regexp_h_fetch(p2, 0); - do { - c = regexp_h_fetch(p1, 1); - if (c == d && regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - } while(c); - return(0); - } - /* regular algorithm */ - if (regexp_h_wchars) - do { - if (regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - c = regexp_h_fetch(p1, 1); - } while (c); - else -#endif /* REGEXP_H_WCHARS */ - do { - if (regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - } while (*p1++); - return(0); -} - -#ifdef REGEXP_H_WCHARS -/* - * It is painfully slow to read character-wise backwards in a - * multibyte string (see regexp_h_previous() above). For the star - * algorithm, we therefore keep track of every character as it is - * read in forward direction. - * - * Don't use alloca() for stack blocks since there is no measurable - * speedup and huge amounts of memory are used up for long input - * lines. - */ -#ifndef REGEXP_H_STAKBLOK -#define REGEXP_H_STAKBLOK 1000 -#endif - -struct regexp_h_stack { - struct regexp_h_stack *s_nxt; - struct regexp_h_stack *s_prv; - const char *s_ptr[REGEXP_H_STAKBLOK]; -}; - -#define regexp_h_push(sb, sp, sc, lp) (regexp_h_wchars ? \ - regexp_h_pushwc(sb, sp, sc, lp) : (void)0) - -static regexp_h_inline void -regexp_h_pushwc(struct regexp_h_stack **sb, - struct regexp_h_stack **sp, - const char ***sc, const char *lp) -{ - if (regexp_h_firstwc == NULL || lp < regexp_h_firstwc) - return; - if (*sb == NULL) { - if ((*sb = regexp_h_malloc(sizeof **sb)) == NULL) - return; - (*sb)->s_nxt = (*sb)->s_prv = NULL; - *sp = *sb; - *sc = &(*sb)->s_ptr[0]; - } else if (*sc >= &(*sp)->s_ptr[REGEXP_H_STAKBLOK]) { - if ((*sp)->s_nxt == NULL) { - struct regexp_h_stack *bq; - - if ((bq = regexp_h_malloc(sizeof *bq)) == NULL) - return; - bq->s_nxt = NULL; - bq->s_prv = *sp; - (*sp)->s_nxt = bq; - *sp = bq; - } else - *sp = (*sp)->s_nxt; - *sc = &(*sp)->s_ptr[0]; - } - *(*sc)++ = lp; -} - -static regexp_h_inline const char * -regexp_h_pop(struct regexp_h_stack **sb, struct regexp_h_stack **sp, - const char ***sc, const char *lp) -{ - if (regexp_h_firstwc == NULL || lp <= regexp_h_firstwc) - return &lp[-1]; - if (*sp == NULL) - return regexp_h_firstwc; - if (*sc == &(*sp)->s_ptr[0]) { - if ((*sp)->s_prv == NULL) { - regexp_h_free(*sp); - *sp = NULL; - *sb = NULL; - return regexp_h_firstwc; - } - *sp = (*sp)->s_prv; - regexp_h_free((*sp)->s_nxt); - (*sp)->s_nxt = NULL ; - *sc = &(*sp)->s_ptr[REGEXP_H_STAKBLOK]; - } - return *(--(*sc)); -} - -static void -regexp_h_zerostak(struct regexp_h_stack **sb, struct regexp_h_stack **sp) -{ - for (*sp = *sb; *sp && (*sp)->s_nxt; *sp = (*sp)->s_nxt) - if ((*sp)->s_prv) - regexp_h_free((*sp)->s_prv); - if (*sp) { - if ((*sp)->s_prv) - regexp_h_free((*sp)->s_prv); - regexp_h_free(*sp); - } - *sp = *sb = NULL; -} -#else /* !REGEXP_H_WCHARS */ -#define regexp_h_push(sb, sp, sc, lp) -#endif /* !REGEXP_H_WCHARS */ - -static int -regexp_h_advance(const char *lp, const char *ep) -{ - register const char *curlp; - int c, least; -#ifdef REGEXP_H_WCHARS - int d; - struct regexp_h_stack *sb = NULL, *sp = NULL; - const char **sc; -#endif /* REGEXP_H_WCHARS */ - char *bbeg; - int ct; - - for (;;) switch (least = *ep++ & 0377, least & ~REGEXP_H_LEAST) { - - case CCHR: -#ifdef REGEXP_H_WCHARS - case CCH1: -#endif - if (*ep++ == *lp++) - continue; - return(0); - -#ifdef REGEXP_H_WCHARS - case CCHR|CMB: - if (regexp_h_fetch(ep, 0) == regexp_h_fetch(lp, 1)) - continue; - return(0); - - case CCH2: - if (ep[0] == lp[0] && ep[1] == lp[1]) { - ep += 2, lp += 2; - continue; - } - return(0); - - case CCH3: - if (ep[0] == lp[0] && ep[1] == lp[1] && ep[2] == lp[2]) { - ep += 3, lp += 3; - continue; - } - return(0); -#endif /* REGEXP_H_WCHARS */ - - case CDOT: - if (*lp++) - continue; - return(0); -#ifdef REGEXP_H_WCHARS - case CDOT|CMB: - if ((c = regexp_h_fetch(lp, 1)) != L'\0' && c != WEOF) - continue; - return(0); -#endif /* REGEXP_H_WCHARS */ - - case CDOL: - if (*lp==0) - continue; - return(0); - - case CCEOF: - loc2 = (char *)lp; - return(1); - - case CCL: - c = *lp++ & 0377; - if(ISTHERE(c)) { - ep += 32; - continue; - } - return(0); - -#ifdef REGEXP_H_WCHARS - case CCL|CMB: - case CNCL|CMB: - c = regexp_h_fetch(lp, 1); - if (regexp_h_cclass(ep, c, (ep[-1] & 0377) == (CCL|CMB))) { - ep += (*ep & 0377) + 17; - continue; - } - return 0; -#endif /* REGEXP_H_WCHARS */ - - case CBRA: - braslist[*ep++ & 0377] = (char *)lp; - continue; - - case CKET: - braelist[*ep++ & 0377] = (char *)lp; - continue; - - case CBRC: - if (lp == regexp_h_bol && locs == NULL) - continue; - if ((isdigit(lp[0] & 0377) || regexp_h_uletter(lp[0] & 0377)) - && !regexp_h_uletter(lp[-1] & 0377) - && !isdigit(lp[-1] & 0377)) - continue; - return(0); - -#ifdef REGEXP_H_WCHARS - case CBRC|CMB: - c = regexp_h_show(lp); - d = regexp_h_previous(lp); - if ((iswdigit(c) || regexp_h_wuletter(c)) - && !regexp_h_wuletter(d) - && !iswdigit(d)) - continue; - return(0); -#endif /* REGEXP_H_WCHARS */ - - case CLET: - if (!regexp_h_uletter(lp[0] & 0377) && !isdigit(lp[0] & 0377)) - continue; - return(0); - -#ifdef REGEXP_H_WCHARS - case CLET|CMB: - c = regexp_h_show(lp); - if (!regexp_h_wuletter(c) && !iswdigit(c)) - continue; - return(0); -#endif /* REGEXP_H_WCHARS */ - - case CCHR|RNGE: - c = *ep++; - regexp_h_getrnge(ep, least); - while(low--) - if(*lp++ != c) - return(0); - curlp = lp; - while(size--) { - regexp_h_push(&sb, &sp, &sc, lp); - if(*lp++ != c) - break; - } - if(size < 0) { - regexp_h_push(&sb, &sp, &sc, lp); - lp++; - } - ep += 2; - goto star; - -#ifdef REGEXP_H_WCHARS - case CCHR|RNGE|CMB: - case CCH1|RNGE: - case CCH2|RNGE: - case CCH3|RNGE: - c = regexp_h_fetch(ep, 0); - regexp_h_getrnge(ep, least); - while (low--) - if (regexp_h_fetch(lp, 1) != c) - return 0; - curlp = lp; - while (size--) { - regexp_h_push(&sb, &sp, &sc, lp); - if (regexp_h_fetch(lp, 1) != c) - break; - } - if(size < 0) { - regexp_h_push(&sb, &sp, &sc, lp); - regexp_h_fetch(lp, 1); - } - ep += 2; - goto star; -#endif /* REGEXP_H_WCHARS */ - - case CDOT|RNGE: - regexp_h_getrnge(ep, least); - while(low--) - if(*lp++ == '\0') - return(0); - curlp = lp; - while(size--) { - regexp_h_push(&sb, &sp, &sc, lp); - if(*lp++ == '\0') - break; - } - if(size < 0) { - regexp_h_push(&sb, &sp, &sc, lp); - lp++; - } - ep += 2; - goto star; - -#ifdef REGEXP_H_WCHARS - case CDOT|RNGE|CMB: - regexp_h_getrnge(ep, least); - while (low--) - if ((c = regexp_h_fetch(lp, 1)) == L'\0' || c == WEOF) - return 0; - curlp = lp; - while (size--) { - regexp_h_push(&sb, &sp, &sc, lp); - if ((c = regexp_h_fetch(lp, 1)) == L'\0' || c == WEOF) - break; - } - if (size < 0) { - regexp_h_push(&sb, &sp, &sc, lp); - regexp_h_fetch(lp, 1); - } - ep += 2; - goto star; -#endif /* REGEXP_H_WCHARS */ - - case CCL|RNGE: - regexp_h_getrnge(ep + 32, least); - while(low--) { - c = *lp++ & 0377; - if(!ISTHERE(c)) - return(0); - } - curlp = lp; - while(size--) { - regexp_h_push(&sb, &sp, &sc, lp); - c = *lp++ & 0377; - if(!ISTHERE(c)) - break; - } - if(size < 0) { - regexp_h_push(&sb, &sp, &sc, lp); - lp++; - } - ep += 34; /* 32 + 2 */ - goto star; - -#ifdef REGEXP_H_WCHARS - case CCL|RNGE|CMB: - case CNCL|RNGE|CMB: - regexp_h_getrnge(ep + (*ep & 0377) + 17, least); - while (low--) { - c = regexp_h_fetch(lp, 1); - if (!regexp_h_cclass(ep, c, - (ep[-1] & 0377 & ~REGEXP_H_LEAST) - == (CCL|RNGE|CMB))) - return 0; - } - curlp = lp; - while (size--) { - regexp_h_push(&sb, &sp, &sc, lp); - c = regexp_h_fetch(lp, 1); - if (!regexp_h_cclass(ep, c, - (ep[-1] & 0377 & ~REGEXP_H_LEAST) - == (CCL|RNGE|CMB))) - break; - } - if (size < 0) { - regexp_h_push(&sb, &sp, &sc, lp); - regexp_h_fetch(lp, 1); - } - ep += (*ep & 0377) + 19; - goto star; -#endif /* REGEXP_H_WCHARS */ - - case CBACK: - bbeg = braslist[*ep & 0377]; - ct = braelist[*ep++ & 0377] - bbeg; - - if(strncmp(bbeg, lp, ct) == 0) { - lp += ct; - continue; - } - return(0); - - case CBACK|STAR: - bbeg = braslist[*ep & 0377]; - ct = braelist[*ep++ & 0377] - bbeg; - curlp = lp; - while(strncmp(bbeg, lp, ct) == 0) - lp += ct; - - while(lp >= curlp) { - if(regexp_h_advance(lp, ep)) return(1); - lp -= ct; - } - return(0); - - - case CDOT|STAR: - curlp = lp; - do - regexp_h_push(&sb, &sp, &sc, lp); - while (*lp++); - goto star; - -#ifdef REGEXP_H_WCHARS - case CDOT|STAR|CMB: - curlp = lp; - do - regexp_h_push(&sb, &sp, &sc, lp); - while ((c = regexp_h_fetch(lp, 1)) != L'\0' && c != WEOF); - goto star; -#endif /* REGEXP_H_WCHARS */ - - case CCHR|STAR: - curlp = lp; - do - regexp_h_push(&sb, &sp, &sc, lp); - while (*lp++ == *ep); - ep++; - goto star; - -#ifdef REGEXP_H_WCHARS - case CCHR|STAR|CMB: - case CCH1|STAR: - case CCH2|STAR: - case CCH3|STAR: - curlp = lp; - d = regexp_h_fetch(ep, 0); - do - regexp_h_push(&sb, &sp, &sc, lp); - while (regexp_h_fetch(lp, 1) == d); - goto star; -#endif /* REGEXP_H_WCHARS */ - - case CCL|STAR: - curlp = lp; - do { - regexp_h_push(&sb, &sp, &sc, lp); - c = *lp++ & 0377; - } while(ISTHERE(c)); - ep += 32; - goto star; - -#ifdef REGEXP_H_WCHARS - case CCL|STAR|CMB: - case CNCL|STAR|CMB: - curlp = lp; - do { - regexp_h_push(&sb, &sp, &sc, lp); - c = regexp_h_fetch(lp, 1); - } while (regexp_h_cclass(ep, c, (ep[-1] & 0377) - == (CCL|STAR|CMB))); - ep += (*ep & 0377) + 17; - goto star; -#endif /* REGEXP_H_WCHARS */ - - star: -#ifdef REGEXP_H_WCHARS - if (regexp_h_wchars == 0) { -#endif - do { - if(--lp == locs) - break; - if (regexp_h_advance(lp, ep)) - return(1); - } while (lp > curlp); -#ifdef REGEXP_H_WCHARS - } else { - do { - lp = regexp_h_pop(&sb, &sp, &sc, lp); - if (lp <= locs) - break; - if (regexp_h_advance(lp, ep)) { - regexp_h_zerostak(&sb, &sp); - return(1); - } - } while (lp > curlp); - regexp_h_zerostak(&sb, &sp); - } -#endif /* REGEXP_H_WCHARS */ - return(0); - - } -} - -static void -regexp_h_getrnge(register const char *str, int least) -{ - low = *str++ & 0377; - size = least & REGEXP_H_LEAST ? /*20000*/INT_MAX : (*str & 0377) - low; -} - -int -advance(const char *lp, const char *ep) -{ - REGEXP_H_ADVANCE_INIT /* skip past circf */ - regexp_h_bol = lp; -#ifdef REGEXP_H_WCHARS - regexp_h_firstwc = NULL; -#endif /* REGEXP_H_WCHARS */ - return regexp_h_advance(lp, ep); -} diff --git a/tools/cpio/src/regexpr.c b/tools/cpio/src/regexpr.c deleted file mode 100644 index 40dceb525..000000000 --- a/tools/cpio/src/regexpr.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Simple Regular Expression functions. Derived from Unix 7th Edition, - * /usr/src/cmd/expr.y - * - * Modified by Gunnar Ritter, Freiburg i. Br., Germany, January 2003. - * - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * Redistributions of source code and documentation must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of - * other contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``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 CALDERA INTERNATIONAL, INC. 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. - */ - -/* Sccsid @(#)regexpr.c 1.8 (gritter) 10/13/04 */ - -#include -#include "regexpr.h" - -int regerrno, reglength; -static int circf; - -static char *regexpr_compile(char *, char *, const char *, int); - -char * -compile(const char *instring, char *ep, char *endbuf) -{ - char *cp; - int sz = 0; - - if (ep == 0) { - for (cp = (char *)instring; *cp != '\0'; cp++) - if (*cp == '[') - sz += 32; - sz += 2 * (cp - instring) + 5; - if ((ep = malloc(sz)) == 0) { - regerrno = 11; - return 0; - } - endbuf = &ep[sz]; - ep[1] = '\0'; - } - if ((cp=regexpr_compile((char *)instring, &ep[1], endbuf, '\0')) == 0) { - if (sz) - free(ep); - return 0; - } - ep[0] = circf; - reglength = cp - ep; - return sz ? ep : cp; -} - -#define INIT register char *sp = instring; -#define GETC() (*sp++) -#define PEEKC() (*sp) -#define UNGETC(c) (--sp) -#define RETURN(c) return (c); -#define ERROR(c) { regerrno = c; return 0; } - -#define compile(a, b, c, d) regexpr_compile(a, b, c, d) -#define regexp_h_static static -#define REGEXP_H_STEP_INIT circf = *p2++; -#define REGEXP_H_ADVANCE_INIT circf = *ep++; - -#include "regexp.h" diff --git a/tools/cpio/src/regexpr.h b/tools/cpio/src/regexpr.h deleted file mode 100644 index 74f4a1426..000000000 --- a/tools/cpio/src/regexpr.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Simple Regular Expression functions. Derived from Unix 7th Edition, - * /usr/src/cmd/expr.y - * - * Modified by Gunnar Ritter, Freiburg i. Br., Germany, January 2003. - * - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * Redistributions of source code and documentation must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of - * other contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``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 CALDERA INTERNATIONAL, INC. 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. - */ - -/* Sccsid @(#)regexpr.h 1.2 (gritter) 1/11/03 */ - -#define NBRA 9 - -extern char *braslist[NBRA]; -extern char *braelist[NBRA]; -extern int nbra; -extern int regerrno, reglength; -extern char *loc1, *loc2, *locs; -extern int sed; - -extern char *compile(const char *, char *, char *); -extern int step(const char *, const char *); -extern int advance(const char *, const char *); diff --git a/tools/cpio/src/setlabel.c b/tools/cpio/src/setlabel.c deleted file mode 100644 index a1db0646e..000000000 --- a/tools/cpio/src/setlabel.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)setlabel.c 1.1 (gritter) 9/21/03 */ - -extern char *pfmt_label__; - -int -setlabel(const char *s) -{ - static char lbuf[26]; - char *lp; - - if (s && s[0]) { - for (lp = lbuf; *s && lp < &lbuf[sizeof lbuf-1]; s++, lp++) - *lp = *s; - *lp = '\0'; - pfmt_label__ = lbuf; - } else - pfmt_label__ = 0; - return 0; -} diff --git a/tools/cpio/src/setuxlabel.c b/tools/cpio/src/setuxlabel.c deleted file mode 100644 index 9d304869e..000000000 --- a/tools/cpio/src/setuxlabel.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)setuxlabel.c 1.1 (gritter) 9/21/03 */ - -#include "msgselect.h" - -extern char *pfmt_label__; - -int -setuxlabel(const char *s) -{ - static char lbuf[msgselect(29,26)]; - char *lp, *mp; - - if (s && s[0]) { - lp = lbuf; - mp = msgselect("UX:",""); - while (*mp) - *lp++ = *mp++; - lbuf[0] = 'U', lbuf[1] = 'X', lbuf[2] = ':'; - while (*s && lp < &lbuf[sizeof lbuf-1]) - *lp++ = *s++; - *lp = '\0'; - pfmt_label__ = lbuf; - } else - pfmt_label__ = 0; - return 0; -} diff --git a/tools/cpio/src/sfile.c b/tools/cpio/src/sfile.c deleted file mode 100644 index 089d85fdf..000000000 --- a/tools/cpio/src/sfile.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sfile.c 1.9 (gritter) 6/7/04 */ - -#ifdef __linux__ -#undef _FILE_OFFSET_BITS - -#include -#include -#include -#include -#include -#include -#include "sfile.h" - -long long -sfile(int dfd, int sfd, mode_t mode, long long count) -{ - static int enosys, einval, success; - off_t offset; - ssize_t sent, total; - extern void writerr(void *, int, int); - /* - * A process is not interruptible while executing a sendfile() - * system call. So it is not advisable to to send an entire - * file with one call; it is sent in parts so signals can - * be delivered in between. - */ - const ssize_t chunk = 196608; - - /* - * If a previous call returned ENOSYS, the operating system does - * not support sendfile() at all and it makes no sense to try it - * again. - * - * If a previous call returned EINVAL and there was no successful - * call yet, it is very likely that this is a permanent error - * condition (on Linux 2.6.0-test4, sendfile() may be used for - * socket targets only; older versions don't support tmpfs as - * source file system etc.). - */ - if (enosys || !success && einval || - (mode&S_IFMT) != S_IFREG || count > SSIZE_MAX) - return 0; - offset = lseek(sfd, 0, SEEK_CUR); - sent = 0, total = 0; - while (count > 0 && (sent = sendfile(dfd, sfd, &offset, - count > chunk ? chunk : count)) > 0) { - count -= sent, total += sent; - } - if (total && lseek(sfd, offset, SEEK_SET) == (off_t)-1) - return -1; - if (count == 0 || sent == 0) { - success = 1; - return total; - } - switch (errno) { - case ENOSYS: - enosys = 1; - return 0; - case EINVAL: - einval = 1; - return 0; - case ENOMEM: - return 0; - default: - writerr(NULL, count > chunk ? chunk : count, 0); - return -1; - } -} -#else /* !__linux__ */ -#include - -/*ARGSUSED*/ -long long -sfile(int dfd, int sfd, mode_t mode, long long count) -{ - return 0; -} -#endif /* __linux__ */ diff --git a/tools/cpio/src/sfile.h b/tools/cpio/src/sfile.h deleted file mode 100644 index 53d832a6f..000000000 --- a/tools/cpio/src/sfile.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sfile.h 1.4 (gritter) 4/17/03 */ - -/* - * Return values: - * - * src_size The entire range has been copied. The file offset of both - * dst_fd and src_fd have been set to this position. The - * operation has been completed successfully. - * - * >0 Number of bytes written. The file offset of both dst_fd - * and src_fd have been set to this position. The operation - * may continue using read()/write(). - * - * 0 No data was written; operation may continue. - * - * -1 An error occured; operation may not continue. - */ -extern long long sfile(int dst_fd, int src_fd, mode_t src_mode, - long long src_size); diff --git a/tools/cpio/src/sighold.c b/tools/cpio/src/sighold.c deleted file mode 100644 index bae3bc393..000000000 --- a/tools/cpio/src/sighold.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sighold.c 1.7 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ - defined (__UCLIBC__) -#include -#include "sigset.h" - -int -sighold(int sig) -{ - sigset_t set, oset; - - if (sig <= 0) - return -1; - sigemptyset(&set); - sigaddset(&set, sig); - return sigprocmask(SIG_BLOCK, &set, &oset); -} -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/tools/cpio/src/sigignore.c b/tools/cpio/src/sigignore.c deleted file mode 100644 index 6938ef676..000000000 --- a/tools/cpio/src/sigignore.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sigignore.c 1.6 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) -#include -#include "sigset.h" - -int -sigignore(int sig) -{ - struct sigaction act; - - if (sig <= 0) - return -1; - act.sa_handler = SIG_IGN; - act.sa_flags = 0; - if (sig == SIGCHLD) - act.sa_flags |= SA_NOCLDSTOP|SA_NOCLDWAIT; - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask, sig); - return sigaction(sig, &act, (struct sigaction *)0); -} -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ */ diff --git a/tools/cpio/src/signal.c b/tools/cpio/src/signal.c deleted file mode 100644 index 1f9d51cb7..000000000 --- a/tools/cpio/src/signal.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)signal.c 1.6 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ - defined (__UCLIBC__) -#include -#include "sigset.h" - -void (*signal(int sig, void (*func)(int)))(int) -{ - struct sigaction nact, oact; - - if (sig <= 0) - return SIG_ERR; - nact.sa_handler = func; - nact.sa_flags = SA_RESETHAND|SA_NODEFER; - if (sig == SIGCHLD && func == SIG_IGN) - nact.sa_flags |= SA_NOCLDSTOP|SA_NOCLDWAIT; - sigemptyset(&nact.sa_mask); - if (sigaction(sig, &nact, &oact) == -1) - return SIG_ERR; - return oact.sa_handler; -} -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/tools/cpio/src/sigpause.c b/tools/cpio/src/sigpause.c deleted file mode 100644 index 504a5ed4d..000000000 --- a/tools/cpio/src/sigpause.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sigpause.c 1.6 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) -#include -#include "sigset.h" - -int -sigpause(int sig) -{ - sigset_t nset, oset; - int ret; - - if (sig <= 0) - return -1; - sigemptyset(&nset); - sigaddset(&nset, sig); - if (sigprocmask(SIG_UNBLOCK, &nset, &oset) < 0) - return -1; - sigemptyset(&nset); - ret = sigsuspend(&nset); - if (sigprocmask(SIG_SETMASK, &oset, (sigset_t *)0) < 0) - ret = -1; - return ret; -} -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ */ diff --git a/tools/cpio/src/sigrelse.c b/tools/cpio/src/sigrelse.c deleted file mode 100644 index d74de74bf..000000000 --- a/tools/cpio/src/sigrelse.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sigrelse.c 1.8 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ - defined (__UCLIBC__) -#include -#include "sigset.h" - -int -sigrelse(int sig) -{ - sigset_t set, oset; - - if (sig <= 0) - return -1; - sigemptyset(&set); - sigaddset(&set, sig); - return sigprocmask(SIG_UNBLOCK, &set, &oset); -} -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/tools/cpio/src/sigset.c b/tools/cpio/src/sigset.c deleted file mode 100644 index d561d541d..000000000 --- a/tools/cpio/src/sigset.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sigset.c 1.7 (gritter) 1/22/06 */ - -#include -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ - defined (__UCLIBC__) -#include -#include "sigset.h" - -void (*sigset(int sig, void (*func)(int)))(int) -{ - struct sigaction nact, oact; - sigset_t nset, oset; - - if (sig <= 0) - return SIG_ERR; - sigemptyset(&nset); - sigaddset(&nset, sig); - if (sigprocmask(func==SIG_HOLD?SIG_BLOCK:SIG_UNBLOCK, &nset, &oset) < 0) - return SIG_ERR; - nact.sa_handler = func; - nact.sa_flags = 0; - if (sig == SIGCHLD && func == SIG_IGN) - nact.sa_flags |= SA_NOCLDSTOP|SA_NOCLDWAIT; - sigemptyset(&nact.sa_mask); - sigaddset(&nact.sa_mask, sig); - if (sigaction(sig, func==SIG_HOLD?(struct sigaction *)0:&nact, &oact) - == -1) - return SIG_ERR; - if (sigismember(&oset, sig)) - return SIG_HOLD; - else - return (oact.sa_handler); -} -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/tools/cpio/src/sigset.h b/tools/cpio/src/sigset.h deleted file mode 100644 index ada73a884..000000000 --- a/tools/cpio/src/sigset.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sigset.h 1.9 (gritter) 1/22/06 */ - -#include -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ - defined (__UCLIBC__) - -#ifndef SIG_HOLD -#define SIG_HOLD ((void (*)(int))2) -#endif /* !SIG_HOLD */ - -extern int sighold(int); -extern int sigignore(int); -//extern int sigpause(int); -extern int sigrelse(int); -extern void (*sigset(int, void (*)(int)))(int); -extern void (*signal(int, void (*)(int)))(int); -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/tools/cpio/src/strtol.c b/tools/cpio/src/strtol.c deleted file mode 100644 index cd8ecfe7a..000000000 --- a/tools/cpio/src/strtol.c +++ /dev/null @@ -1,117 +0,0 @@ -/* Sccsid @(#)strtol.c 1.6 (gritter) 7/18/04 */ - -#if defined (__hpux) || defined (_AIX) || \ - defined (__FreeBSD__) && (__FreeBSD__) < 5 - -#include -#include -#include - -#include "atoll.h" - -#ifdef __hpux -#ifndef _INCLUDE__STDC_A1_SOURCE -#error You must use cc -D_INCLUDE__STDC_A1_SOURCE on HP-UX -#endif -#endif /* __hpux */ - -static long long -internal(const char *nptr, char **endptr, int base, int flags) -{ - const char *pp = nptr, *bptr; - long long v = 0, ov; - int sign = 1; - int c; - int valid = 1; - - /* XXX - * iswspace() should be used. - */ - for (bptr = nptr; isspace(*bptr&0377); bptr++); - if (*bptr == '-') { - sign = -1; - bptr++; - } else if (*bptr == '+') - bptr++; - if (base == 0) { - if (*bptr >= '1' && *bptr <= '9') - base = 10; - else if (*bptr == '0') { - if (bptr[1] == 'x' || bptr[1] == 'X') - base = 16; - else - base = 8; - } else { - if (flags&1) - errno = EINVAL; - goto out; - } - } - if (base < 2 || base > 36) { - if (flags&1) - errno = EINVAL; - goto out; - } - if (base == 16 && bptr[0] == '0' && - (bptr[1] == 'x' || bptr[1] == 'X')) - bptr += 2; - pp = bptr; - for (;;) { - if (*pp >= '0' && *pp <= '9') - c = *pp - '0'; - else if (*pp >= 'a' && *pp <= 'z') - c = *pp - 'a' + 10; - else if (*pp >= 'A' && *pp <= 'A') - c = *pp - 'A' + 10; - else - break; - if (c >= base) - break; - pp++; - if (valid) { - ov = v; - v = v * base + c; - if (flags&1) { - if (flags&2 && (unsigned long long)v < - (unsigned long long)ov || - v < ov) { - sign = 1; - errno = ERANGE; - v = -1; - if ((flags&2)==0) - v = (unsigned long long)v >> 1; - valid = 0; - } - } - } - } -out: if (pp <= bptr) { - if (flags&1) - errno = EINVAL; - if (endptr) - *endptr = (char *)nptr; - } else { - if (endptr) - *endptr = (char *)pp; - } - return v * sign; -} - -long long -strtoll(const char *nptr, char **endptr, int base) -{ - return internal(nptr, endptr, base, 1); -} - -unsigned long long -strtoull(const char *nptr, char **endptr, int base) -{ - return (unsigned long long)internal(nptr, endptr, base, 3); -} - -long long -atoll(const char *nptr) -{ - return internal(nptr, NULL, 10, 0); -} -#endif /* __hpux || _AIX || __FreeBSD__ < 5 */ diff --git a/tools/cpio/src/unshrink.c b/tools/cpio/src/unshrink.c deleted file mode 100644 index 61f5c507c..000000000 --- a/tools/cpio/src/unshrink.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. - * - * Derived from unzip 5.40. - * - * Sccsid @(#)unshrink.c 1.4 (gritter) 6/18/04 - */ -/*--------------------------------------------------------------------------- - - unshrink.c version 1.21 23 Nov 95 - - - NOTE: This code may or may not infringe on the so-called "Welch - patent" owned by Unisys. (From reading the patent, it appears - that a pure LZW decompressor is *not* covered, but this claim has - not been tested in court, and Unisys is reported to believe other- - wise.) It is therefore the responsibility of the user to acquire - whatever license(s) may be required for legal use of this code. - - THE INFO-ZIP GROUP DISCLAIMS ALL LIABILITY FOR USE OF THIS CODE - IN VIOLATION OF APPLICABLE PATENT LAW. - - - Shrinking is basically a dynamic LZW algorithm with allowed code sizes of - up to 13 bits; in addition, there is provision for partial clearing of - leaf nodes. PKWARE uses the special code 256 (decimal) to indicate a - change in code size or a partial clear of the code tree: 256,1 for the - former and 256,2 for the latter. [Note that partial clearing can "orphan" - nodes: the parent-to-be can be cleared before its new child is added, - but the child is added anyway (as an orphan, as though the parent still - existed). When the tree fills up to the point where the parent node is - reused, the orphan is effectively "adopted." Versions prior to 1.05 were - affected more due to greater use of pointers (to children and siblings - as well as parents).] - - This replacement version of unshrink.c was written from scratch. It is - based only on the algorithms described in Mark Nelson's _The Data Compres- - sion Book_ and in Terry Welch's original paper in the June 1984 issue of - IEEE _Computer_; no existing source code, including any in Nelson's book, - was used. - - Memory requirements have been reduced in this version and are now no more - than the original Sam Smith code. This is still larger than any of the - other algorithms: at a minimum, 8K+8K+16K (stack+values+parents) assuming - 16-bit short ints, and this does not even include the output buffer (the - other algorithms leave the uncompressed data in the work area, typically - called slide[]). For machines with a 64KB data space this is a problem, - particularly when text conversion is required and line endings have more - than one character. UnZip's solution is to use two roughly equal halves - of outbuf for the ASCII conversion in such a case; the "unshrink" argument - to flush() signals that this is the case. - - For large-memory machines, a second outbuf is allocated for translations, - but only if unshrinking and only if translations are required. - - | binary mode | text mode - --------------------------------------------------- - big mem | big outbuf | big outbuf + big outbuf2 <- malloc'd here - small mem | small outbuf | half + half small outbuf - - Copyright 1994, 1995 Greg Roelofs. See the accompanying file "COPYING" - in UnZip 5.20 (or later) source or binary distributions. - - From "COPYING": - - The following copyright applies to the new version of unshrink.c, - distributed with UnZip version 5.2 and later: - - * Copyright (c) 1994 Greg Roelofs. - * Permission is granted to any individual/institution/corporate - * entity to use, copy, redistribute or modify this software for - * any purpose whatsoever, subject to the conditions noted in the - * Frequently Asked Questions section below, plus one additional - * condition: namely, that my name not be removed from the source - * code. (Other names may, of course, be added as modifications - * are made.) Corporate legal staff (like at IBM :-) ) who have - * problems understanding this can contact me through Zip-Bugs... - - - Q. Can I use the source code of Zip and UnZip in my commercial - application? - - A. Yes, so long as you include in your product an acknowledgment; a - pointer to the original, free compression sources; and a statement - making it clear that there are no extra or hidden charges resulting - from the use of our compression code in your product (see below for - an example). The acknowledgment should appear in at least one piece - of human-readable documentation (e.g., a README file or man page), - although additionally putting it in the executable(s) is OK, too. - In other words, you are allowed to sell only your own work, not ours, - and we'd like a little credit. (Note the additional restrictions - above on the code in unreduce.c, unshrink.c, vms.c, time_lib.c, and - everything in the wince and windll subdirectories.) Contact us at - Zip-Bugs@lists.wku.edu if you have special requirements. We also - like to hear when our code is being used, but we don't require that. - - incorporates compression code from the Info-ZIP group. - There are no extra charges or costs due to the use of this code, - and the original compression sources are freely available from - http://www.cdrom.com/pub/infozip/ or ftp://ftp.cdrom.com/pub/infozip/ - on the Internet. - - If you only need compression capability, not full zipfile support, - you might want to look at zlib instead; it has fewer restrictions - on commercial use. See http://www.cdrom.com/pub/infozip/zlib/ . - - ---------------------------------------------------------------------------*/ - -#include -#include - -#include "cpio.h" -#include "unzip.h" - -static void partial_clear(struct globals *); - -#define trace() - -/* HSIZE is defined as 2^13 (8192) in unzip.h */ -#define BOGUSCODE 256 -#define FLAG_BITS parent /* upper bits of parent[] used as flag bits */ -#define CODE_MASK (HSIZE - 1) /* 0x1fff (lower bits are parent's index) */ -#define FREE_CODE HSIZE /* 0x2000 (code is unused or was cleared) */ -#define HAS_CHILD (HSIZE << 1) /* 0x4000 (code has a child--do not clear) */ - -#define parent G.area.shrink.Parent -#define Value G.area.shrink.value /* "value" conflicts with Pyramid ioctl.h */ -#define stack G.area.shrink.Stack - -/***********************/ -/* Function unshrink() */ -/***********************/ - -int -zipunshrink(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) -{ - struct globals G; - int offset = (HSIZE - 1); - uint8_t *stacktop = stack + offset; - register uint8_t *newstr; - int codesize=9, len, KwKwK; - int16_t code, oldcode, freecode, curcode; - int16_t lastfreecode; - unsigned int outbufsiz; - -/*--------------------------------------------------------------------------- - Initialize various variables. - ---------------------------------------------------------------------------*/ - - memset(&G, 0, sizeof G); - G.tgt = tgt; - G.tfd = tfd; - G.doswap = doswap; - G.crc = crc; - G.zsize = G.uzsize = f->f_csize; - lastfreecode = BOGUSCODE; - - for (code = 0; code < BOGUSCODE; ++code) { - Value[code] = (uint8_t)code; - parent[code] = BOGUSCODE; - } - for (code = BOGUSCODE+1; code < HSIZE; ++code) - parent[code] = FREE_CODE; - - outbufsiz = OUTBUFSIZ; - G.outptr = G.outbuf; - G.outcnt = 0L; - -/*--------------------------------------------------------------------------- - Get and output first code, then loop over remaining ones. - ---------------------------------------------------------------------------*/ - - READBITS(codesize, oldcode) - if (!G.zipeof) { - *G.outptr++ = (uint8_t)oldcode; - ++G.outcnt; - } - - do { - READBITS(codesize, code) - if (G.zipeof) - break; - if (code == BOGUSCODE) { /* possible to have consecutive escapes? */ - READBITS(codesize, code) - if (code == 1) { - ++codesize; - Trace((stderr, " (codesize now %d bits)\n", codesize)); - } else if (code == 2) { - Trace((stderr, " (partial clear code)\n")); - partial_clear(&G); /* clear leafs (nodes with no children) */ - Trace((stderr, " (done with partial clear)\n")); - lastfreecode = BOGUSCODE; /* reset start of free-node search */ - } - continue; - } - - /*----------------------------------------------------------------------- - Translate code: traverse tree from leaf back to root. - -----------------------------------------------------------------------*/ - - newstr = stacktop; - curcode = code; - - if (parent[curcode] == FREE_CODE) { - /* or (FLAG_BITS[curcode] & FREE_CODE)? */ - KwKwK = TRUE; - Trace((stderr, " (found a KwKwK code %d; oldcode = %d)\n", code, - oldcode)); - --newstr; /* last character will be same as first character */ - curcode = oldcode; - } else - KwKwK = FALSE; - - do { - *newstr-- = Value[curcode]; - curcode = (int16_t)(parent[curcode] & CODE_MASK); - } while (curcode != BOGUSCODE); - - len = (int)(stacktop - newstr++); - if (KwKwK) - *stacktop = *newstr; - - /*----------------------------------------------------------------------- - Write expanded string in reverse order to output buffer. - -----------------------------------------------------------------------*/ - - Trace((stderr, "code %4d; oldcode %4d; char %3d (%c); string [", code, - oldcode, (int)(*newstr), (*newstr<32 || *newstr>=127)? ' ':*newstr)); - - { - register uint8_t *p; - - for (p = newstr; p < newstr+len; ++p) { - *G.outptr++ = *p; - if (++G.outcnt == outbufsiz) { - flush(&G, G.outbuf, G.outcnt); - G.outptr = G.outbuf; - G.outcnt = 0L; - } - } - } - - /*----------------------------------------------------------------------- - Add new leaf (first character of newstr) to tree as child of oldcode. - -----------------------------------------------------------------------*/ - - /* search for freecode */ - freecode = (int16_t)(lastfreecode + 1); - /* add if-test before loop for speed? */ - while (parent[freecode] != FREE_CODE) - ++freecode; - lastfreecode = freecode; - Trace((stderr, "]; newcode %d\n", freecode)); - - Value[freecode] = *newstr; - parent[freecode] = oldcode; - oldcode = code; - - } while (!G.zipeof); - -/*--------------------------------------------------------------------------- - Flush any remaining data and return to sender... - ---------------------------------------------------------------------------*/ - - if (G.outcnt > 0L) - flush(&G, G.outbuf, G.outcnt); - - return G.status; - -} /* end function unshrink() */ - - - - - -/****************************/ -/* Function partial_clear() */ /* no longer recursive... */ -/****************************/ - -static void -partial_clear(struct globals *Gp) -{ -#define G (*Gp) - register int16_t code; - - /* clear all nodes which have no children (i.e., leaf nodes only) */ - - /* first loop: mark each parent as such */ - for (code = BOGUSCODE+1; code < HSIZE; ++code) { - register int16_t cparent = (int16_t)(parent[code] & CODE_MASK); - - if (cparent > BOGUSCODE && cparent != FREE_CODE) - FLAG_BITS[cparent] |= HAS_CHILD; /* set parent's child-bit */ - } - - /* second loop: clear all nodes *not* marked as parents; reset flag bits */ - for (code = BOGUSCODE+1; code < HSIZE; ++code) { - if (FLAG_BITS[code] & HAS_CHILD) /* just clear child-bit */ - FLAG_BITS[code] &= ~HAS_CHILD; - else { /* leaf: lose it */ - Trace((stderr, "%d\n", code)); - parent[code] = FREE_CODE; - } - } - - return; -} diff --git a/tools/cpio/src/unzip.h b/tools/cpio/src/unzip.h deleted file mode 100644 index d53f81024..000000000 --- a/tools/cpio/src/unzip.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. - * - * Derived from unzip 5.40. - * - * Sccsid @(#)unzip.h 1.5 (gritter) 7/16/04 - */ - -#include - -#define Trace(a) - -#define MAX_BITS 13 -#define HSIZE (1 << MAX_BITS) -#define WSIZE 65536L /* at least 64K for enhanced deflate */ - -#define redirSlide G.area.Slide - -#define NEXTBYTE (--G.incnt >= 0 ? (int)(*G.inptr++) : readbyte(&G)) - -#define READBITS(nbits, zdest) { \ - if (nbits > G.bits_left) { \ - int temp; \ - G.zipeof = 1; \ - while (G.bits_left <= 8 * (int)(sizeof G.bitbuf - 1) && \ - (temp = NEXTBYTE) != EOF) { \ - G.bitbuf |= (uint32_t)temp << G.bits_left; \ - G.bits_left += 8; \ - G.zipeof = 0; \ - } \ - } \ - zdest = (int16_t)((uint16_t)G.bitbuf & mask_bits[nbits]); \ - G.bitbuf >>= nbits; \ - G.bits_left -= nbits; \ -} - -#undef FALSE -#undef TRUE -enum { - FALSE = 0, - TRUE = 1 -}; - -union work { - struct { - int16_t Parent[HSIZE]; - uint8_t value[HSIZE]; - uint8_t Stack[HSIZE]; - } shrink; - uint8_t Slide[WSIZE]; -}; - -#define OUTBUFSIZ 4096 - -struct globals { - union work area; - uint8_t inbuf[4096]; - long long zsize; - long long uzsize; - uint8_t *inptr; - const char *tgt; - struct huft *fixed_tl; - struct huft *fixed_td; - struct huft *fixed_tl64; - struct huft *fixed_td64; - struct huft *fixed_tl32; - struct huft *fixed_td32; - const uint16_t *cplens; - const uint8_t *cplext; - const uint8_t *cpdext; - long csize; - long ucsize; - uint8_t outbuf[OUTBUFSIZ]; - uint8_t *outptr; - uint32_t *crc; - uint32_t bitbuf; - uint32_t wp; - uint32_t bb; - uint32_t bk; - unsigned outcnt; - int tfd; - int doswap; - int incnt; - int bits_left; - int zipeof; - int fixed_bl; - int fixed_bd; - int fixed_bl64; - int fixed_bd64; - int fixed_bl32; - int fixed_bd32; - int status; -}; - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). - Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 - means that v is a literal, 16 < e < 32 means that v is a pointer to - the next table, which codes e - 16 bits, and lastly e == 99 indicates - an unused code. If a code with e == 99 is looked up, this implies an - error in the data. */ - -struct huft { - uint8_t e; /* number of extra bits or operation */ - uint8_t b; /* number of bits in this code or subcode */ - union { - uint16_t n; /* literal, length base, or distance base */ - struct huft *t; /* pointer to next level of table */ - } v; -}; - -extern const uint16_t mask_bits[]; - -extern void flush(struct globals *, const void *, size_t); -extern int readbyte(struct globals *); - -extern int huft_build(const unsigned *b, unsigned n, unsigned s, - const uint16_t *d, const uint8_t *e, - struct huft **t, int *m, - int bits, int nob, int eob); -extern void huft_free(struct huft *); diff --git a/tools/cpio/src/utmpx.c b/tools/cpio/src/utmpx.c deleted file mode 100644 index d88a627a7..000000000 --- a/tools/cpio/src/utmpx.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)utmpx.c 1.13 (gritter) 12/16/07 */ - -#include - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__UCLIBC__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || \ - defined (__APPLE__) && \ - (__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_OS_X_VERSION_10_5) -#include -#include -#include -#include - -#include "utmpx.h" - -static FILE *utfp; -static struct utmpx utx; -static const char *utmpfile = _PATH_UTMP; - -static FILE * -init(void) -{ - if (utfp == NULL && (utfp = fopen(utmpfile, "r+")) == NULL) - if ((utfp = fopen(utmpfile, "r")) == NULL) - return NULL; - return utfp; -} - -static struct utmpx * -utmp2utmpx(struct utmpx *ux, const struct utmp *up) -{ -#ifndef __dietlibc__ - memset(ux, 0, sizeof *ux); - ux->ut_tv.tv_sec = up->ut_time; - memcpy(ux->ut_line, up->ut_line, UT_LINESIZE); - memcpy(ux->ut_user, up->ut_name, UT_NAMESIZE); - memcpy(ux->ut_host, up->ut_host, UT_HOSTSIZE); - if (strcmp(up->ut_line, "~") == 0) - ux->ut_type = BOOT_TIME; - else if (strcmp(up->ut_line, "|") == 0) - ux->ut_type = OLD_TIME; - else if (strcmp(up->ut_line, "}") == 0) - ux->ut_type = NEW_TIME; - else if (*up->ut_name == 0) - ux->ut_type = DEAD_PROCESS; - else - ux->ut_type = USER_PROCESS; -#else /* __dietlibc__ */ - *ux = *up; -#endif /* __dietlibc__ */ - return ux; -} - -static struct utmp * -utmpx2utmp(struct utmp *up, const struct utmpx *ux) -{ -#ifndef __dietlibc__ - memset(up, 0, sizeof *up); - up->ut_time = ux->ut_tv.tv_sec; - switch (ux->ut_type) { - case DEAD_PROCESS: - memcpy(up->ut_line, ux->ut_line, UT_LINESIZE); - break; - default: - case EMPTY: - case INIT_PROCESS: - case LOGIN_PROCESS: - case RUN_LVL: - case ACCOUNTING: - return NULL; - case BOOT_TIME: - strcpy(up->ut_name, "reboot"); - strcpy(up->ut_line, "~"); - break; - case OLD_TIME: - strcpy(up->ut_name, "date"); - strcpy(up->ut_line, "|"); - break; - case NEW_TIME: - strcpy(up->ut_name, "date"); - strcpy(up->ut_line, "{"); - break; - case USER_PROCESS: - memcpy(up->ut_line, ux->ut_line, UT_LINESIZE); - memcpy(up->ut_name, ux->ut_user, UT_NAMESIZE); - memcpy(up->ut_host, ux->ut_host, UT_HOSTSIZE); - } -#else /* __dietlibc__ */ - *up = *ux; -#endif /* __dietlibc__ */ - return up; -} - -struct utmpx * -getutxent(void) -{ - static struct utmp zero; - struct utmp ut; - - if (init() == NULL) - return NULL; - do { - if (fread(&ut, sizeof ut, 1, utfp) != 1) - return NULL; - } while (memcmp(&ut, &zero, sizeof ut) == 0); - return utmp2utmpx(&utx, &ut); -} - -struct utmpx * -getutxline(const struct utmpx *ux) -{ - struct utmp ut; - - if (init() == NULL) - return NULL; - fseek(utfp, 0, SEEK_SET); - while (fread(&ut, sizeof ut, 1, utfp) == 1) { - utmp2utmpx(&utx, &ut); - if ((utx.ut_type == LOGIN_PROCESS || - utx.ut_type == USER_PROCESS) && - strcmp(ut.ut_line, utx.ut_line) == 0) - return &utx; - } - return NULL; -} - -struct utmpx * -getutxid(const struct utmpx *ux) -{ -#ifdef __dietlibc__ - struct utmp ut; -#endif - - if (init() == NULL) - return NULL; -#ifdef __dietlibc__ - fseek(utfp, 0, SEEK_SET); - while (fread(&ut, sizeof ut, 1, utfp) == 1) { - utmp2utmpx(&utx, &ut); - switch (ux->ut_type) { - case BOOT_TIME: - case OLD_TIME: - case NEW_TIME: - if (ux->ut_type == utx.ut_type) - return &utx; - break; - case INIT_PROCESS: - case LOGIN_PROCESS: - case USER_PROCESS: - case DEAD_PROCESS: - if (ux->ut_type == utx.ut_type && - ux->ut_id == utx.ut_id) - return &utx; - break; - } - } -#endif /* __dietlibc__ */ - return NULL; -} - -void -setutxent(void) -{ - if (init() == NULL) - return; - fseek(utfp, 0, SEEK_SET); -} - -void -endutxent(void) -{ - FILE *fp; - - if (init() == NULL) - return; - fp = utfp; - utfp = NULL; - fclose(fp); -} - -int -utmpxname(const char *name) -{ - utmpfile = strdup(name); - return 0; -} - -extern struct utmpx * -pututxline(const struct utmpx *up) -{ - struct utmp ut; - struct utmpx *rp; - - if (init() == NULL) - return NULL; - /* - * Cannot use getutxid() because there is no id field. Use - * the equivalent of getutxline() instead. - */ - while (fread(&ut, sizeof ut, 1, utfp) == 1) { - if (strncmp(ut.ut_line, up->ut_line, UT_LINESIZE) == 0) { - fseek(utfp, -sizeof ut, SEEK_CUR); - break; - } - } - fflush(utfp); - if (utmpx2utmp(&ut, up) == NULL) - rp = NULL; - else if (fwrite(&ut, sizeof ut, 1, utfp) == 1) { - utx = *up; - rp = &utx; - } else - rp = NULL; - fflush(utfp); - return rp; -} - -extern void -updwtmpx(const char *name, const struct utmpx *up) -{ - FILE *fp; - - if ((fp = fopen(name, "a")) == NULL) - return; - fwrite(up, sizeof *up, 1, fp); - fclose(fp); -} - -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __UCLIBC__ || - __OpenBSD__ || __DragonFly__ || __APPLE__ */ diff --git a/tools/cpio/src/version.c b/tools/cpio/src/version.c deleted file mode 100644 index a9d4a4681..000000000 --- a/tools/cpio/src/version.c +++ /dev/null @@ -1,26 +0,0 @@ -#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 -#define USED __attribute__ ((used)) -#elif defined __GNUC__ -#define USED __attribute__ ((unused)) -#else -#define USED -#endif -static const char sccsid[] USED = "@(#)cpio.sl 2.9 (gritter) 8/14/09"; -/* SLIST */ -/* -blast.c: * Sccsid @(#)blast.c 1.2 (gritter) 2/17/04 -blast.h: * Sccsid @(#)blast.h 1.2 (gritter) 2/17/04 -cpio.c: * Sccsid @(#)cpio.c 1.305 (gritter) 8/14/09 -cpio.h: Sccsid @(#)cpio.h 1.29 (gritter) 3/26/07 -crc32.c: * Sccsid @(#)crc32.c 1.2 (gritter) 5/29/03 -expand.c: Sccsid @(#)expand.c 1.6 (gritter) 12/15/03 -explode.c: * Sccsid @(#)explode.c 1.6 (gritter) 9/30/03 -flags.c: Sccsid @(#)flags.c 1.6 (gritter) 3/26/07 -inflate.c: * Sccsid @(#)inflate.c 1.6 (gritter) 10/13/04 -nonpax.c: Sccsid @(#)nonpax.c 1.1 (gritter) 2/24/04 -pax.c:static const char sccsid[] USED = "@(#)pax_su3.sl 1.26 (gritter) 6/26/05"; -pax.c:static const char sccsid[] USED = "@(#)pax.sl 1.26 (gritter) 6/26/05"; -pax.c: Sccsid @(#)pax.c 1.26 (gritter) 6/26/05 -unshrink.c: * Sccsid @(#)unshrink.c 1.4 (gritter) 6/18/04 -unzip.h: * Sccsid @(#)unzip.h 1.5 (gritter) 7/16/04 -*/ diff --git a/tools/cpio/src/vpfmt.c b/tools/cpio/src/vpfmt.c deleted file mode 100644 index fdbb4ccb0..000000000 --- a/tools/cpio/src/vpfmt.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. 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. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)vpfmt.c 1.2 (gritter) 9/21/03 */ - -#include -#include - -#include "pfmt.h" - -extern char *pfmt_label__; - -/* - * Strip catalog and msgnum from s, but only if they actually appear. - */ -static const char * -begin(const char *s, long flags) -{ - const char *sp; - - if (flags & MM_NOGET) - return s; - sp = s; - if (*sp && *sp != ':') { - sp++; - while (*sp && *sp != '/' && *sp != ':' && sp - s < 14) - sp++; - } - if (*sp++ != ':') - return s; - while (*sp >= '0' && *sp <= '9') - sp++; - if (*sp++ != ':' || *sp == '\0') - return s; - return sp; -} - -int -vpfmt(FILE *stream, long flags, const char *fmt, va_list ap) -{ - int n = 0; - const char *severity = NULL; - char sevbuf[25]; - - if ((flags&MM_NOSTD) == 0) { - if (flags & MM_ACTION) - severity = "TO FIX"; - else switch (flags & 0377) { - case MM_HALT: - severity = "HALT"; - break; - case MM_WARNING: - severity = "WARNING"; - break; - case MM_INFO: - severity = "INFO"; - break; - case MM_ERROR: - severity = "ERROR"; - break; - default: - snprintf(sevbuf, sizeof sevbuf, "SEV=%ld", flags&0377); - severity = sevbuf; - } - if (pfmt_label__) - n = fprintf(stream, "%s: ", pfmt_label__); - if (severity) - n += fprintf(stream, "%s: ", severity); - } - n += vfprintf(stream, begin(fmt, flags), ap); - return n; -} diff --git a/tools/flex/Makefile b/tools/flex/Makefile deleted file mode 100644 index 235f785b4..000000000 --- a/tools/flex/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= flex -PKG_VERSION:= 2.5.35 -PKG_RELEASE:= 1 -PKG_MD5SUM:= 201d3f38758d95436cbc64903386de0b -PKG_SITES:= ${MASTER_SITE_SOURCEFORGE:=${PKG_NAME}/} - -include ../rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/flex - -$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared - (cd ${WRKBUILD}; PATH="$(STAGING_HOST_DIR)/usr/bin:$$PATH" ./configure) - ${MAKE} -C ${WRKBUILD} CC='${CC_FOR_BUILD}' - touch $@ - -${STAGING_HOST_DIR}/usr/bin/flex: $(WRKBUILD)/.compiled - $(INSTALL_BIN) $(WRKBUILD)/flex \ - ${STAGING_HOST_DIR}/usr/bin - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/genext2fs/Makefile b/tools/genext2fs/Makefile deleted file mode 100644 index 07e24d028..000000000 --- a/tools/genext2fs/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= genext2fs -PKG_VERSION:= 1.4.1 -PKG_RELEASE:= 1 -PKG_MD5SUM:= b7b6361bcce2cedff1ae437fadafe53b -PKG_SITES:= ${MASTER_SITE_SOURCEFORGE:=genext2fs/} - -include ../rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/genext2fs - -$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared - (cd ${WRKBUILD}; ./configure) - ${MAKE} -C ${WRKBUILD} CC='${CC_FOR_BUILD}' - touch $@ - -${STAGING_HOST_DIR}/usr/bin/genext2fs: $(WRKBUILD)/.compiled - $(INSTALL_BIN) $(WRKBUILD)/genext2fs \ - ${STAGING_HOST_DIR}/usr/bin - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/lzma/Makefile b/tools/lzma/Makefile deleted file mode 100644 index 3544aaca2..000000000 --- a/tools/lzma/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= lzma -PKG_VERSION:= 4.32.7 -PKG_RELEASE:= 1 -PKG_MD5SUM:= 434e51a018b4c8ef377bf81520a53af0 -PKG_SITES:= http://tukaani.org/lzma/ - -include ../rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/lzma - -$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared - (cd ${WRKBUILD}; PATH="$(STAGING_HOST_DIR)/usr/bin:$$PATH" ./configure) - ${MAKE} -C ${WRKBUILD} CC='${CC_FOR_BUILD}' - touch $@ - -${STAGING_HOST_DIR}/usr/bin/lzma: $(WRKBUILD)/.compiled - $(INSTALL_BIN) $(WRKBUILD)/src/lzma/lzma \ - $(STAGING_HOST_DIR)/usr/bin/lzma - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/lzo/Makefile b/tools/lzo/Makefile deleted file mode 100644 index 8f965d7ea..000000000 --- a/tools/lzo/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= lzo -PKG_VERSION:= 2.06 -PKG_RELEASE:= 1 -PKG_MD5SUM:= 95380bd4081f85ef08c5209f4107e9f8 -PKG_SITES:= http://www.oberhumer.com/opensource/lzo/download/ - -include ../rules.mk - -install: $(WRKBUILD)/.installed - -$(WRKBUILD)/.configured: ${WRKDIST}/.prepared - (cd ${WRKBUILD}; ./configure --prefix=$(STAGING_HOST_DIR)/usr) - @touch $@ - -$(WRKBUILD)/.compiled: $(WRKBUILD)/.configured - ${MAKE} -C ${WRKBUILD} - @touch $@ - -$(WRKBUILD)/.installed: $(WRKBUILD)/.compiled - ${MAKE} -C ${WRKBUILD} install - @touch $@ - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/lzop/Makefile b/tools/lzop/Makefile deleted file mode 100644 index af08536c4..000000000 --- a/tools/lzop/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= lzop -PKG_VERSION:= 1.03 -PKG_RELEASE:= 1 -PKG_MD5SUM:= 006c5e27fb78cdd14a628fdfa5aa1905 -PKG_SITES:= http://www.lzop.org/download/ - -include ../rules.mk - -install: $(WRKBUILD)/.installed - -$(WRKBUILD)/.configured: ${WRKDIST}/.prepared - (cd ${WRKBUILD}; CPPFLAGS='$(CPPFLAGS_FOR_BUILD)' \ - LDFLAGS='$(LDFLAGS_FOR_BUILD)' \ - ./configure --prefix=$(STAGING_HOST_DIR)/usr) - @touch $@ - -$(WRKBUILD)/.compiled: $(WRKBUILD)/.configured - ${MAKE} -C ${WRKBUILD} - @touch $@ - -$(WRKBUILD)/.installed: $(WRKBUILD)/.compiled - ${MAKE} -C ${WRKBUILD} install - @touch $@ - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/m4/Makefile b/tools/m4/Makefile deleted file mode 100644 index f4a1bae1a..000000000 --- a/tools/m4/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= m4 -PKG_VERSION:= 1.4.17 -PKG_RELEASE:= 1 -PKG_MD5SUM:= a5e9954b1dae036762f7b13673a2cf76 -PKG_SITES:= ${MASTER_SITE_GNU:=m4/} - -include ../rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/m4 - -$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared - (cd ${WRKBUILD}; ./configure --prefix=$(STAGING_HOST_DIR)/usr) - ${MAKE} -C ${WRKBUILD} CC='${CC_FOR_BUILD}' - touch $@ - -${STAGING_HOST_DIR}/usr/bin/m4: $(WRKBUILD)/.compiled - $(INSTALL_BIN) $(WRKBUILD)/src/m4 \ - ${STAGING_HOST_DIR}/usr/bin - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/mkcrypt/Makefile b/tools/mkcrypt/Makefile deleted file mode 100644 index 089c6ad7b..000000000 --- a/tools/mkcrypt/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/mkcrypt - -${STAGING_HOST_DIR}/usr/bin/mkcrypt: - $(CC_FOR_BUILD) ${FLAGS_FOR_BUILD} -o $@ mkcrypt.c - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/mkcrypt/mkcrypt.c b/tools/mkcrypt/mkcrypt.c deleted file mode 100644 index a856759df..000000000 --- a/tools/mkcrypt/mkcrypt.c +++ /dev/null @@ -1,441 +0,0 @@ -/*- - * Copyright (c) 2007 - * Thorsten Glaser - * - * Provided that these terms and disclaimer and all copyright notices - * are retained or reproduced in an accompanying document, permission - * is granted to deal in this work without restriction, including un- - * limited rights to use, publicly perform, distribute, sell, modify, - * merge, give away, or sublicence. - * - * Advertising materials mentioning features or use of this work must - * display the following acknowledgement: - * This product includes material provided by Thorsten Glaser. - * This product includes software developed by Niels Provos. - * - * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to - * the utmost extent permitted by applicable law, neither express nor - * implied; without malicious intent or gross negligence. In no event - * may a licensor, author or contributor be held liable for indirect, - * direct, other damage, loss, or other issues arising in any way out - * of dealing in the work, even if advised of the possibility of such - * damage or existence of a defect, except proven that it results out - * of said person's immediate fault when using the work as intended. - */ - -#include -#include -#include -#include -#include - -#define MD5_BLOCK_LENGTH 64 -#define MD5_DIGEST_LENGTH 16 -#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1) - -typedef struct MD5Context { - u_int32_t state[4]; - u_int64_t count; - u_int8_t buffer[MD5_BLOCK_LENGTH]; -} MD5_CTX; - -/* low-level MD5 functions from md5c.c */ -void MD5Init(MD5_CTX *); -void MD5Update(MD5_CTX *, const u_int8_t *, size_t); -void MD5Pad(MD5_CTX *); -void MD5Final(u_int8_t [MD5_DIGEST_LENGTH], MD5_CTX *); -void MD5Transform(u_int32_t [4], const u_int8_t [MD5_BLOCK_LENGTH]); - -/* high-level functions from mdXhl.c */ -char *MD5End(MD5_CTX *, char *); -char *MD5File(const char *, char *); -char *MD5FileChunk(const char *, char *, off_t, off_t); -char *MD5Data(const u_int8_t *, size_t, char *); - -void to64(char *, u_int32_t, int); -char *md5crypt(const char *pw, const char *salt); -int pwd_gensalt(char *, int); - -static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -void -to64(char *s, u_int32_t v, int n) -{ - while (--n >= 0) { - *s++ = itoa64[v&0x3f]; - v >>= 6; - } -} - -#define PUT_64BIT_LE(cp, value) do { \ - (cp)[7] = (value) >> 56; \ - (cp)[6] = (value) >> 48; \ - (cp)[5] = (value) >> 40; \ - (cp)[4] = (value) >> 32; \ - (cp)[3] = (value) >> 24; \ - (cp)[2] = (value) >> 16; \ - (cp)[1] = (value) >> 8; \ - (cp)[0] = (value); } while (0) - -#define PUT_32BIT_LE(cp, value) do { \ - (cp)[3] = (value) >> 24; \ - (cp)[2] = (value) >> 16; \ - (cp)[1] = (value) >> 8; \ - (cp)[0] = (value); } while (0) - -static u_int8_t PADDING[MD5_BLOCK_LENGTH] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void -MD5Init(MD5_CTX *ctx) -{ - ctx->count = 0; - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xefcdab89; - ctx->state[2] = 0x98badcfe; - ctx->state[3] = 0x10325476; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void -MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len) -{ - size_t have, need; - - /* Check how many bytes we already have and how many more we need. */ - have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); - need = MD5_BLOCK_LENGTH - have; - - /* Update bitcount */ - ctx->count += (u_int64_t)len << 3; - - if (len >= need) { - if (have != 0) { - memcpy(ctx->buffer + have, input, need); - MD5Transform(ctx->state, ctx->buffer); - input += need; - len -= need; - have = 0; - } - - /* Process data in MD5_BLOCK_LENGTH-byte chunks. */ - while (len >= MD5_BLOCK_LENGTH) { - MD5Transform(ctx->state, input); - input += MD5_BLOCK_LENGTH; - len -= MD5_BLOCK_LENGTH; - } - } - - /* Handle any remaining bytes of data. */ - if (len != 0) - memcpy(ctx->buffer + have, input, len); -} - -/* - * Pad pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void -MD5Pad(MD5_CTX *ctx) -{ - u_int8_t count[8]; - size_t padlen; - - /* Convert count to 8 bytes in little endian order. */ - PUT_64BIT_LE(count, ctx->count); - - /* Pad out to 56 mod 64. */ - padlen = MD5_BLOCK_LENGTH - - ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); - if (padlen < 1 + 8) - padlen += MD5_BLOCK_LENGTH; - MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ - MD5Update(ctx, count, 8); -} - -/* - * Final wrapup--call MD5Pad, fill in digest and zero out ctx. - */ -void -MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx) -{ - int i; - - MD5Pad(ctx); - if (digest != NULL) { - for (i = 0; i < 4; i++) - PUT_32BIT_LE(digest + i * 4, ctx->state[i]); - memset(ctx, 0, sizeof(*ctx)); - } -} - - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -void -MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH]) -{ - u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4]; - -#if BYTE_ORDER == LITTLE_ENDIAN - memcpy(in, block, sizeof(in)); -#else - for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) { - in[a] = (u_int32_t)( - (u_int32_t)(block[a * 4 + 0]) | - (u_int32_t)(block[a * 4 + 1]) << 8 | - (u_int32_t)(block[a * 4 + 2]) << 16 | - (u_int32_t)(block[a * 4 + 3]) << 24); - } -#endif - - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - - MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21); - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; -} - -/* - * UNIX password - * - * Use MD5 for what it is best at... - */ - -char * -md5crypt(const char *pw, const char *salt) -{ - /* - * This string is magic for this algorithm. Having - * it this way, we can get get better later on - */ - static const unsigned char *magic = (const unsigned char *)"$1$"; - - static char passwd[120], *p; - static const unsigned char *sp,*ep; - unsigned char final[16]; - int sl,pl,i; - MD5_CTX ctx,ctx1; - u_int32_t l; - - /* Refine the Salt first */ - sp = (const unsigned char *)salt; - - /* If it starts with the magic string, then skip that */ - if(!strncmp((const char *)sp,(const char *)magic,strlen((const char *)magic))) - sp += strlen((const char *)magic); - - /* It stops at the first '$', max 8 chars */ - for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++) - continue; - - /* get the length of the true salt */ - sl = ep - sp; - - MD5Init(&ctx); - - /* The password first, since that is what is most unknown */ - MD5Update(&ctx,(const unsigned char *)pw,strlen(pw)); - - /* Then our magic string */ - MD5Update(&ctx,magic,strlen((const char *)magic)); - - /* Then the raw salt */ - MD5Update(&ctx,sp,sl); - - /* Then just as many characters of the MD5(pw,salt,pw) */ - MD5Init(&ctx1); - MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); - MD5Update(&ctx1,sp,sl); - MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); - MD5Final(final,&ctx1); - for(pl = strlen(pw); pl > 0; pl -= 16) - MD5Update(&ctx,final,pl>16 ? 16 : pl); - - /* Don't leave anything around in vm they could use. */ - memset(final,0,sizeof final); - - /* Then something really weird... */ - for (i = strlen(pw); i ; i >>= 1) - if(i&1) - MD5Update(&ctx, final, 1); - else - MD5Update(&ctx, (const unsigned char *)pw, 1); - - /* Now make the output string */ - snprintf(passwd, sizeof(passwd), "%s%.*s$", magic, - sl, (const char *)sp); - - MD5Final(final,&ctx); - - /* - * and now, just to make sure things don't run too fast - * On a 60 Mhz Pentium this takes 34 msec, so you would - * need 30 seconds to build a 1000 entry dictionary... - */ - for(i=0;i<1000;i++) { - MD5Init(&ctx1); - if(i & 1) - MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); - else - MD5Update(&ctx1,final,16); - - if(i % 3) - MD5Update(&ctx1,sp,sl); - - if(i % 7) - MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); - - if(i & 1) - MD5Update(&ctx1,final,16); - else - MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw)); - MD5Final(final,&ctx1); - } - - p = passwd + strlen(passwd); - - l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4; - l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4; - l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4; - l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4; - l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4; - l = final[11] ; to64(p,l,2); p += 2; - *p = '\0'; - - /* Don't leave anything around in vm they could use. */ - memset(final, 0, sizeof final); - - return passwd; -} - -int pwd_gensalt(char *salt, int saltlen) { - - *salt = '\0'; - - if (saltlen < 13) { /* $1$8salt$\0 */ - return 0; - } - - strcpy(salt, "$1$"); - to64(&salt[3], random(), 4); - to64(&salt[7], random(), 4); - strcpy(&salt[11], "$"); - return 1; -} - -int main(int argc, char *argv[]) { - char salt[16]; - char *pw; - - if (!argv[1]) { - fprintf(stderr, "Syntax Error!\n"); - return (1); - } - if (!pwd_gensalt(salt, sizeof (salt))) - return (255); - if ((pw = md5crypt(argv[1], salt)) == NULL) { - fprintf(stderr, "Error generating password!\n"); - return (1); - } - printf("%s\n", pw); - return (0); -} diff --git a/tools/mkfimage/Makefile b/tools/mkfimage/Makefile deleted file mode 100644 index 195614f2b..000000000 --- a/tools/mkfimage/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -include $(TOPDIR)/rules.mk - -all: mkfimage.c - $(CC_FOR_BUILD) ${FLAGS_FOR_BUILD} -o ${STAGING_HOST_DIR}/usr/bin/mkfimage mkfimage.c $(MAKE_TRACE) diff --git a/tools/mkfimage/mkfimage.c b/tools/mkfimage/mkfimage.c deleted file mode 100644 index b1897fbd7..000000000 --- a/tools/mkfimage/mkfimage.c +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include -#include -#include -#include -#include - -int main(int argc, char **argv){ - unsigned char *buffer = malloc(64 * 1024); - struct stat s; - unsigned int size_vmlinux = 0, real_size_vmlinux = 0; - const unsigned char *magic_str = "ACME_PART_MAGIC"; - unsigned int loop; - unsigned char *magic; - - if(argc != 3){ - printf("%s in out\n", argv[0]); - return 1; - } - - printf("Generating image\n"); - - FILE *vmlinux = fopen(argv[1], "r"); - FILE *vmlinux_out = fopen(argv[2], "w"); - if((!vmlinux) || (!vmlinux_out)){ - printf("Error opening a file\n"); - return 1; - } - - stat(argv[1], &s); - size_vmlinux = s.st_size; - real_size_vmlinux = (size_vmlinux & 0xffff0000) + 0x10000; - - printf("vmlinux = 0x%.08X / 0x%.08X\n", size_vmlinux, real_size_vmlinux); - - unsigned int t = fread(buffer, 1, 64 * 1024, vmlinux); - for(loop = 0; loop < (64 * 1024) - sizeof(magic_str); loop++){ - if(buffer[loop] == magic_str[0]){ - if((magic = strstr(&buffer[loop], magic_str))){ - //printf("Magic at 0x%.08X %p %p\n", magic - buffer, magic, buffer); - printf("Found Magic %X%X%X%X\n", - buffer[loop + strlen(magic_str)], - buffer[loop + strlen(magic_str) + 2], - buffer[loop + strlen(magic_str) + 1], - buffer[loop + strlen(magic_str) + 3]); - - buffer[loop + strlen(magic_str)] = real_size_vmlinux >> 24; - buffer[loop + strlen(magic_str) + 2] = (real_size_vmlinux >> 16) & 0xff; - buffer[loop + strlen(magic_str) + 1] = (real_size_vmlinux >> 8) & 0xff; - buffer[loop + strlen(magic_str) + 3] = (real_size_vmlinux) & 0xff; - - printf("Replaced with %.02X%.02X%.02X%.02X\n", - buffer[loop + strlen(magic_str)], - buffer[loop + strlen(magic_str) + 2], - buffer[loop + strlen(magic_str) + 1], - buffer[loop + strlen(magic_str) + 3]); - - } - } - } - - fwrite(buffer, 1, 64 * 1024, vmlinux_out); - real_size_vmlinux -= 64 * 1024; - do { - real_size_vmlinux -= 64 * 1024; - memset(buffer, 0, 64 * 1024); - fread(buffer, 1, 64 * 1024, vmlinux); - fwrite(buffer, 1, 64 * 1024, vmlinux_out); - } while (real_size_vmlinux); - - return 0; -} diff --git a/tools/mkimage/Makefile b/tools/mkimage/Makefile deleted file mode 100644 index db2e42c3f..000000000 --- a/tools/mkimage/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/mkimage - -${STAGING_HOST_DIR}/usr/bin/mkimage: mkimage.c crc32.c - $(CC_FOR_BUILD) ${FLAGS_FOR_BUILD} -o $@ mkimage.c crc32.c - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/mkimage/crc32.c b/tools/mkimage/crc32.c deleted file mode 100644 index 067b3106c..000000000 --- a/tools/mkimage/crc32.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * This file is derived from crc32.c from the zlib-1.1.3 distribution - * by Jean-loup Gailly and Mark Adler. - */ - -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#define USE_HOSTCC - -#ifndef USE_HOSTCC /* Shut down "ANSI does not permit..." warnings */ -#include /* to get command definitions like CFG_CMD_JFFS2 */ -#endif - -#include "zlib.h" - -#define local static -#define ZEXPORT /* empty */ -unsigned long crc32 (unsigned long, const unsigned char *, unsigned int); - -#ifdef DYNAMIC_CRC_TABLE - -local int crc_table_empty = 1; -local uLongf crc_table[256]; -local void make_crc_table OF((void)); - -/* - Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The table is simply the CRC of all possible eight bit values. This is all - the information needed to generate CRC's on data a byte at a time for all - combinations of CRC register values and incoming bytes. -*/ -local void make_crc_table() -{ - uLong c; - int n, k; - uLong poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* make exclusive-or pattern from polynomial (0xedb88320L) */ - poly = 0L; - for (n = 0; n < sizeof(p)/sizeof(Byte); n++) - poly |= 1L << (31 - p[n]); - - for (n = 0; n < 256; n++) - { - c = (uLong)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[n] = c; - } - crc_table_empty = 0; -} -#else -/* ======================================================================== - * Table of CRC-32's of all single-byte values (made by make_crc_table) - */ -local const uLongf crc_table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; -#endif - -#if 0 -/* ========================================================================= - * This function can be used by asm versions of crc32() - */ -const uLongf * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) make_crc_table(); -#endif - return (const uLongf *)crc_table; -} -#endif - -/* ========================================================================= */ -#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); - -/* ========================================================================= */ -uLong ZEXPORT crc32(crc, buf, len) - uLong crc; - const Bytef *buf; - uInt len; -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif - crc = crc ^ 0xffffffffL; - while (len >= 8) - { - DO8(buf); - len -= 8; - } - if (len) do { - DO1(buf); - } while (--len); - return crc ^ 0xffffffffL; -} - -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) || \ - ((CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)) - -/* No ones complement version. JFFS2 (and other things ?) - * don't use ones compliment in their CRC calculations. - */ -uLong ZEXPORT crc32_no_comp(uLong crc, const Bytef *buf, uInt len) -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif - while (len >= 8) - { - DO8(buf); - len -= 8; - } - if (len) do { - DO1(buf); - } while (--len); - - return crc; -} - -#endif /* CFG_CMD_JFFS2 */ diff --git a/tools/mkimage/image.h b/tools/mkimage/image.h deleted file mode 100644 index cb62cde5b..000000000 --- a/tools/mkimage/image.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * (C) Copyright 2000-2005 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - ******************************************************************** - * NOTE: This header file defines an interface to U-Boot. Including - * this (unmodified) header file in another file is considered normal - * use of U-Boot, and does *not* fall under the heading of "derived - * work". - ******************************************************************** - */ - -#ifndef __IMAGE_H__ -#define __IMAGE_H__ - -/* - * Operating System Codes - */ -#define IH_OS_INVALID 0 /* Invalid OS */ -#define IH_OS_OPENBSD 1 /* OpenBSD */ -#define IH_OS_NETBSD 2 /* NetBSD */ -#define IH_OS_FREEBSD 3 /* FreeBSD */ -#define IH_OS_4_4BSD 4 /* 4.4BSD */ -#define IH_OS_LINUX 5 /* Linux */ -#define IH_OS_SVR4 6 /* SVR4 */ -#define IH_OS_ESIX 7 /* Esix */ -#define IH_OS_SOLARIS 8 /* Solaris */ -#define IH_OS_IRIX 9 /* Irix */ -#define IH_OS_SCO 10 /* SCO */ -#define IH_OS_DELL 11 /* Dell */ -#define IH_OS_NCR 12 /* NCR */ -#define IH_OS_LYNXOS 13 /* LynxOS */ -#define IH_OS_VXWORKS 14 /* VxWorks */ -#define IH_OS_PSOS 15 /* pSOS */ -#define IH_OS_QNX 16 /* QNX */ -#define IH_OS_U_BOOT 17 /* Firmware */ -#define IH_OS_RTEMS 18 /* RTEMS */ -#define IH_OS_ARTOS 19 /* ARTOS */ -#define IH_OS_UNITY 20 /* Unity OS */ - -/* - * CPU Architecture Codes (supported by Linux) - */ -#define IH_CPU_INVALID 0 /* Invalid CPU */ -#define IH_CPU_ALPHA 1 /* Alpha */ -#define IH_CPU_ARM 2 /* ARM */ -#define IH_CPU_I386 3 /* Intel x86 */ -#define IH_CPU_IA64 4 /* IA64 */ -#define IH_CPU_MIPS 5 /* MIPS */ -#define IH_CPU_MIPS64 6 /* MIPS 64 Bit */ -#define IH_CPU_PPC 7 /* PowerPC */ -#define IH_CPU_S390 8 /* IBM S390 */ -#define IH_CPU_SH 9 /* SuperH */ -#define IH_CPU_SPARC 10 /* Sparc */ -#define IH_CPU_SPARC64 11 /* Sparc 64 Bit */ -#define IH_CPU_M68K 12 /* M68K */ -#define IH_CPU_NIOS 13 /* Nios-32 */ -#define IH_CPU_MICROBLAZE 14 /* MicroBlaze */ -#define IH_CPU_NIOS2 15 /* Nios-II */ -#define IH_CPU_BLACKFIN 16 /* Blackfin */ -#define IH_CPU_AVR32 17 /* AVR32 */ - -/* - * Image Types - * - * "Standalone Programs" are directly runnable in the environment - * provided by U-Boot; it is expected that (if they behave - * well) you can continue to work in U-Boot after return from - * the Standalone Program. - * "OS Kernel Images" are usually images of some Embedded OS which - * will take over control completely. Usually these programs - * will install their own set of exception handlers, device - * drivers, set up the MMU, etc. - this means, that you cannot - * expect to re-enter U-Boot except by resetting the CPU. - * "RAMDisk Images" are more or less just data blocks, and their - * parameters (address, size) are passed to an OS kernel that is - * being started. - * "Multi-File Images" contain several images, typically an OS - * (Linux) kernel image and one or more data images like - * RAMDisks. This construct is useful for instance when you want - * to boot over the network using BOOTP etc., where the boot - * server provides just a single image file, but you want to get - * for instance an OS kernel and a RAMDisk image. - * - * "Multi-File Images" start with a list of image sizes, each - * image size (in bytes) specified by an "uint32_t" in network - * byte order. This list is terminated by an "(uint32_t)0". - * Immediately after the terminating 0 follow the images, one by - * one, all aligned on "uint32_t" boundaries (size rounded up to - * a multiple of 4 bytes - except for the last file). - * - * "Firmware Images" are binary images containing firmware (like - * U-Boot or FPGA images) which usually will be programmed to - * flash memory. - * - * "Script files" are command sequences that will be executed by - * U-Boot's command interpreter; this feature is especially - * useful when you configure U-Boot to use a real shell (hush) - * as command interpreter (=> Shell Scripts). - */ - -#define IH_TYPE_INVALID 0 /* Invalid Image */ -#define IH_TYPE_STANDALONE 1 /* Standalone Program */ -#define IH_TYPE_KERNEL 2 /* OS Kernel Image */ -#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */ -#define IH_TYPE_MULTI 4 /* Multi-File Image */ -#define IH_TYPE_FIRMWARE 5 /* Firmware Image */ -#define IH_TYPE_SCRIPT 6 /* Script file */ -#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */ -#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */ - -/* - * Compression Types - */ -#define IH_COMP_NONE 0 /* No Compression Used */ -#define IH_COMP_GZIP 1 /* gzip Compression Used */ -#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */ -#define IH_COMP_LZMA 3 /* lzma Compression Used */ - -#define IH_MAGIC 0x27051956 /* Image Magic Number */ -#define IH_NMLEN 32 /* Image Name Length */ - -/* - * all data in network byte order (aka natural aka bigendian) - */ - -typedef struct image_header { - uint32_t ih_magic; /* Image Header Magic Number */ - uint32_t ih_hcrc; /* Image Header CRC Checksum */ - uint32_t ih_time; /* Image Creation Timestamp */ - uint32_t ih_size; /* Image Data Size */ - uint32_t ih_load; /* Data Load Address */ - uint32_t ih_ep; /* Entry Point Address */ - uint32_t ih_dcrc; /* Image Data CRC Checksum */ - uint8_t ih_os; /* Operating System */ - uint8_t ih_arch; /* CPU architecture */ - uint8_t ih_type; /* Image Type */ - uint8_t ih_comp; /* Compression Type */ - uint8_t ih_name[IH_NMLEN]; /* Image Name */ -} image_header_t; - - -#endif /* __IMAGE_H__ */ diff --git a/tools/mkimage/mkimage b/tools/mkimage/mkimage deleted file mode 100755 index 87ed9a473..000000000 Binary files a/tools/mkimage/mkimage and /dev/null differ diff --git a/tools/mkimage/mkimage.c b/tools/mkimage/mkimage.c deleted file mode 100644 index 7c0432bad..000000000 --- a/tools/mkimage/mkimage.c +++ /dev/null @@ -1,755 +0,0 @@ -/* - * (C) Copyright 2000-2004 - * DENX Software Engineering - * Wolfgang Denk, wd@denx.de - * All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#ifdef __APPLE__ -#define __FreeBSD__ 10 -#endif - -#include -#include -#include -#include -#include -#ifndef __WIN32__ -#include /* for host / network byte order conversions */ -#endif -#include -#include -#include -#include - -#if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__) -#include -#include -#endif -#ifdef __WIN32__ -typedef unsigned int __u32; - -#define SWAP_LONG(x) \ - ((__u32)( \ - (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ - (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ - (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ - (((__u32)(x) & (__u32)0xff000000UL) >> 24) )) -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; - -#define ntohl(a) SWAP_LONG(a) -#define htonl(a) SWAP_LONG(a) -#endif /* __WIN32__ */ - -#ifndef O_BINARY /* should be define'd on __WIN32__ */ -#define O_BINARY 0 -#endif - -#include "image.h" - -extern int errno; - -#ifndef MAP_FAILED -#define MAP_FAILED (-1) -#endif - -char *cmdname; - -extern unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len); - -typedef struct table_entry { - int val; /* as defined in image.h */ - char *sname; /* short (input) name */ - char *lname; /* long (output) name */ -} table_entry_t; - -table_entry_t arch_name[] = { - { IH_CPU_INVALID, NULL, "Invalid CPU", }, - { IH_CPU_ALPHA, "alpha", "Alpha", }, - { IH_CPU_ARM, "arm", "ARM", }, - { IH_CPU_I386, "x86", "Intel x86", }, - { IH_CPU_IA64, "ia64", "IA64", }, - { IH_CPU_M68K, "m68k", "MC68000", }, - { IH_CPU_MICROBLAZE, "microblaze", "MicroBlaze", }, - { IH_CPU_MIPS, "mips", "MIPS", }, - { IH_CPU_MIPS64, "mips64", "MIPS 64 Bit", }, - { IH_CPU_NIOS, "nios", "NIOS", }, - { IH_CPU_NIOS2, "nios2", "NIOS II", }, - { IH_CPU_PPC, "ppc", "PowerPC", }, - { IH_CPU_S390, "s390", "IBM S390", }, - { IH_CPU_SH, "sh", "SuperH", }, - { IH_CPU_SPARC, "sparc", "SPARC", }, - { IH_CPU_SPARC64, "sparc64", "SPARC 64 Bit", }, - { IH_CPU_BLACKFIN, "blackfin", "Blackfin", }, - { IH_CPU_AVR32, "avr32", "AVR32", }, - { -1, "", "", }, -}; - -table_entry_t os_name[] = { - { IH_OS_INVALID, NULL, "Invalid OS", }, - { IH_OS_4_4BSD, "4_4bsd", "4_4BSD", }, - { IH_OS_ARTOS, "artos", "ARTOS", }, - { IH_OS_DELL, "dell", "Dell", }, - { IH_OS_ESIX, "esix", "Esix", }, - { IH_OS_FREEBSD, "freebsd", "FreeBSD", }, - { IH_OS_IRIX, "irix", "Irix", }, - { IH_OS_LINUX, "linux", "Linux", }, - { IH_OS_LYNXOS, "lynxos", "LynxOS", }, - { IH_OS_NCR, "ncr", "NCR", }, - { IH_OS_NETBSD, "netbsd", "NetBSD", }, - { IH_OS_OPENBSD, "openbsd", "OpenBSD", }, - { IH_OS_PSOS, "psos", "pSOS", }, - { IH_OS_QNX, "qnx", "QNX", }, - { IH_OS_RTEMS, "rtems", "RTEMS", }, - { IH_OS_SCO, "sco", "SCO", }, - { IH_OS_SOLARIS, "solaris", "Solaris", }, - { IH_OS_SVR4, "svr4", "SVR4", }, - { IH_OS_U_BOOT, "u-boot", "U-Boot", }, - { IH_OS_VXWORKS, "vxworks", "VxWorks", }, - { -1, "", "", }, -}; - -table_entry_t type_name[] = { - { IH_TYPE_INVALID, NULL, "Invalid Image", }, - { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", }, - { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, - { IH_TYPE_KERNEL, "kernel", "Kernel Image", }, - { IH_TYPE_MULTI, "multi", "Multi-File Image", }, - { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, - { IH_TYPE_SCRIPT, "script", "Script", }, - { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, - { IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", }, - { -1, "", "", }, -}; - -table_entry_t comp_name[] = { - { IH_COMP_NONE, "none", "uncompressed", }, - { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", }, - { IH_COMP_GZIP, "gzip", "gzip compressed", }, - { IH_COMP_LZMA, "lzma", "lzma compressed", }, - { -1, "", "", }, -}; - -static void copy_file (int, const char *, int); -static void usage (void); -static void print_header (image_header_t *); -static void print_type (image_header_t *); -static char *put_table_entry (table_entry_t *, char *, int); -static char *put_arch (int); -static char *put_type (int); -static char *put_os (int); -static char *put_comp (int); -static int get_table_entry (table_entry_t *, char *, char *); -static int get_arch(char *); -static int get_comp(char *); -static int get_os (char *); -static int get_type(char *); - - -char *datafile; -char *imagefile; - -int dflag = 0; -int eflag = 0; -int lflag = 0; -int vflag = 0; -int xflag = 0; -int opt_os = IH_OS_LINUX; -int opt_arch = IH_CPU_PPC; -int opt_type = IH_TYPE_KERNEL; -int opt_comp = IH_COMP_GZIP; - -image_header_t header; -image_header_t *hdr = &header; - -int -main (int argc, char **argv) -{ - int ifd; - uint32_t checksum; - uint32_t addr; - uint32_t ep; - struct stat sbuf; - unsigned char *ptr; - char *name = ""; - - cmdname = *argv; - - addr = ep = 0; - - while (--argc > 0 && **++argv == '-') { - while (*++*argv) { - switch (**argv) { - case 'l': - lflag = 1; - break; - case 'A': - if ((--argc <= 0) || - (opt_arch = get_arch(*++argv)) < 0) - usage (); - goto NXTARG; - case 'C': - if ((--argc <= 0) || - (opt_comp = get_comp(*++argv)) < 0) - usage (); - goto NXTARG; - case 'O': - if ((--argc <= 0) || - (opt_os = get_os(*++argv)) < 0) - usage (); - goto NXTARG; - case 'T': - if ((--argc <= 0) || - (opt_type = get_type(*++argv)) < 0) - usage (); - goto NXTARG; - - case 'a': - if (--argc <= 0) - usage (); - addr = strtoul (*++argv, (char **)&ptr, 16); - if (*ptr) { - fprintf (stderr, - "%s: invalid load address %s\n", - cmdname, *argv); - exit (EXIT_FAILURE); - } - goto NXTARG; - case 'd': - if (--argc <= 0) - usage (); - datafile = *++argv; - dflag = 1; - goto NXTARG; - case 'e': - if (--argc <= 0) - usage (); - ep = strtoul (*++argv, (char **)&ptr, 16); - if (*ptr) { - fprintf (stderr, - "%s: invalid entry point %s\n", - cmdname, *argv); - exit (EXIT_FAILURE); - } - eflag = 1; - goto NXTARG; - case 'n': - if (--argc <= 0) - usage (); - name = *++argv; - goto NXTARG; - case 'v': - vflag++; - break; - case 'x': - xflag++; - break; - default: - usage (); - } - } -NXTARG: ; - } - - if ((argc != 1) || ((lflag ^ dflag) == 0)) - usage(); - - if (!eflag) { - ep = addr; - /* If XIP, entry point must be after the U-Boot header */ - if (xflag) - ep += sizeof(image_header_t); - } - - /* - * If XIP, ensure the entry point is equal to the load address plus - * the size of the U-Boot header. - */ - if (xflag) { - if (ep != addr + sizeof(image_header_t)) { - fprintf (stderr, - "%s: For XIP, the entry point must be the load addr + %lu\n", - cmdname, - (unsigned long)sizeof(image_header_t)); - exit (EXIT_FAILURE); - } - } - - imagefile = *argv; - - if (lflag) { - ifd = open(imagefile, O_RDONLY|O_BINARY); - } else { - ifd = open(imagefile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666); - } - - if (ifd < 0) { - fprintf (stderr, "%s: Can't open %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); - } - - if (lflag) { - int len; - char *data; - /* - * list header information of existing image - */ - if (fstat(ifd, &sbuf) < 0) { - fprintf (stderr, "%s: Can't stat %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); - } - - if ((unsigned)sbuf.st_size < sizeof(image_header_t)) { - fprintf (stderr, - "%s: Bad size: \"%s\" is no valid image\n", - cmdname, imagefile); - exit (EXIT_FAILURE); - } - - ptr = (unsigned char *)mmap(0, sbuf.st_size, - PROT_READ, MAP_SHARED, ifd, 0); - if ((caddr_t)ptr == (caddr_t)-1) { - fprintf (stderr, "%s: Can't read %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); - } - - /* - * create copy of header so that we can blank out the - * checksum field for checking - this can't be done - * on the PROT_READ mapped data. - */ - memcpy (hdr, ptr, sizeof(image_header_t)); - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - fprintf (stderr, - "%s: Bad Magic Number: \"%s\" is no valid image\n", - cmdname, imagefile); - exit (EXIT_FAILURE); - } - - data = (char *)hdr; - len = sizeof(image_header_t); - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = htonl(0); /* clear for re-calculation */ - - if (crc32 (0, data, len) != checksum) { - fprintf (stderr, - "%s: ERROR: \"%s\" has bad header checksum!\n", - cmdname, imagefile); - exit (EXIT_FAILURE); - } - - data = (char *)(ptr + sizeof(image_header_t)); - len = sbuf.st_size - sizeof(image_header_t) ; - - if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) { - fprintf (stderr, - "%s: ERROR: \"%s\" has corrupted data!\n", - cmdname, imagefile); - exit (EXIT_FAILURE); - } - - /* for multi-file images we need the data part, too */ - print_header ((image_header_t *)ptr); - - (void) munmap((void *)ptr, sbuf.st_size); - (void) close (ifd); - - exit (EXIT_SUCCESS); - } - - /* - * Must be -w then: - * - * write dummy header, to be fixed later - */ - memset (hdr, 0, sizeof(image_header_t)); - - if (write(ifd, hdr, sizeof(image_header_t)) != sizeof(image_header_t)) { - fprintf (stderr, "%s: Write error on %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); - } - - if (opt_type == IH_TYPE_MULTI || opt_type == IH_TYPE_SCRIPT) { - char *file = datafile; - uint32_t size; - - for (;;) { - char *sep = NULL; - - if (file) { - if ((sep = strchr(file, ':')) != NULL) { - *sep = '\0'; - } - - if (stat (file, &sbuf) < 0) { - fprintf (stderr, "%s: Can't stat %s: %s\n", - cmdname, file, strerror(errno)); - exit (EXIT_FAILURE); - } - size = htonl(sbuf.st_size); - } else { - size = 0; - } - - if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) { - fprintf (stderr, "%s: Write error on %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); - } - - if (!file) { - break; - } - - if (sep) { - *sep = ':'; - file = sep + 1; - } else { - file = NULL; - } - } - - file = datafile; - - for (;;) { - char *sep = strchr(file, ':'); - if (sep) { - *sep = '\0'; - copy_file (ifd, file, 1); - *sep++ = ':'; - file = sep; - } else { - copy_file (ifd, file, 0); - break; - } - } - } else { - copy_file (ifd, datafile, 0); - } - - /* We're a bit of paranoid */ -#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) - (void) fdatasync (ifd); -#else - (void) fsync (ifd); -#endif - - if (fstat(ifd, &sbuf) < 0) { - fprintf (stderr, "%s: Can't stat %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); - } - - ptr = (unsigned char *)mmap(0, sbuf.st_size, - PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0); - if (ptr == (unsigned char *)MAP_FAILED) { - fprintf (stderr, "%s: Can't map %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); - } - - hdr = (image_header_t *)ptr; - - checksum = crc32 (0, - (const char *)(ptr + sizeof(image_header_t)), - sbuf.st_size - sizeof(image_header_t) - ); - - /* Build new header */ - hdr->ih_magic = htonl(IH_MAGIC); - hdr->ih_time = htonl(sbuf.st_mtime); - hdr->ih_size = htonl(sbuf.st_size - sizeof(image_header_t)); - hdr->ih_load = htonl(addr); - hdr->ih_ep = htonl(ep); - hdr->ih_dcrc = htonl(checksum); - hdr->ih_os = opt_os; - hdr->ih_arch = opt_arch; - hdr->ih_type = opt_type; - hdr->ih_comp = opt_comp; - - strncpy((char *)hdr->ih_name, name, IH_NMLEN); - - checksum = crc32(0,(const char *)hdr,sizeof(image_header_t)); - - hdr->ih_hcrc = htonl(checksum); - - print_header (hdr); - - (void) munmap((void *)ptr, sbuf.st_size); - - /* We're a bit of paranoid */ -#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) - (void) fdatasync (ifd); -#else - (void) fsync (ifd); -#endif - - if (close(ifd)) { - fprintf (stderr, "%s: Write error on %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); - } - - exit (EXIT_SUCCESS); -} - -static void -copy_file (int ifd, const char *datafile, int pad) -{ - int dfd; - struct stat sbuf; - unsigned char *ptr; - int tail; - int zero = 0; - int offset = 0; - int size; - - if (vflag) { - fprintf (stderr, "Adding Image %s\n", datafile); - } - - if ((dfd = open(datafile, O_RDONLY|O_BINARY)) < 0) { - fprintf (stderr, "%s: Can't open %s: %s\n", - cmdname, datafile, strerror(errno)); - exit (EXIT_FAILURE); - } - - if (fstat(dfd, &sbuf) < 0) { - fprintf (stderr, "%s: Can't stat %s: %s\n", - cmdname, datafile, strerror(errno)); - exit (EXIT_FAILURE); - } - - ptr = (unsigned char *)mmap(0, sbuf.st_size, - PROT_READ, MAP_SHARED, dfd, 0); - if (ptr == (unsigned char *)MAP_FAILED) { - fprintf (stderr, "%s: Can't read %s: %s\n", - cmdname, datafile, strerror(errno)); - exit (EXIT_FAILURE); - } - - if (xflag) { - unsigned char *p = NULL; - /* - * XIP: do not append the image_header_t at the - * beginning of the file, but consume the space - * reserved for it. - */ - - if ((unsigned)sbuf.st_size < sizeof(image_header_t)) { - fprintf (stderr, - "%s: Bad size: \"%s\" is too small for XIP\n", - cmdname, datafile); - exit (EXIT_FAILURE); - } - - for (p=ptr; p < ptr+sizeof(image_header_t); p++) { - if ( *p != 0xff ) { - fprintf (stderr, - "%s: Bad file: \"%s\" has invalid buffer for XIP\n", - cmdname, datafile); - exit (EXIT_FAILURE); - } - } - - offset = sizeof(image_header_t); - } - - size = sbuf.st_size - offset; - if (write(ifd, ptr + offset, size) != size) { - fprintf (stderr, "%s: Write error on %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); - } - - if (pad && ((tail = size % 4) != 0)) { - - if (write(ifd, (char *)&zero, 4-tail) != 4-tail) { - fprintf (stderr, "%s: Write error on %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); - } - } - - (void) munmap((void *)ptr, sbuf.st_size); - (void) close (dfd); -} - -void -usage () -{ - fprintf (stderr, "Usage: %s -l image\n" - " -l ==> list image header information\n" - " %s [-x] -A arch -O os -T type -C comp " - "-a addr -e ep -n name -d data_file[:data_file...] image\n", - cmdname, cmdname); - fprintf (stderr, " -A ==> set architecture to 'arch'\n" - " -O ==> set operating system to 'os'\n" - " -T ==> set image type to 'type'\n" - " -C ==> set compression type 'comp'\n" - " -a ==> set load address to 'addr' (hex)\n" - " -e ==> set entry point to 'ep' (hex)\n" - " -n ==> set image name to 'name'\n" - " -d ==> use image data from 'datafile'\n" - " -x ==> set XIP (execute in place)\n" - ); - exit (EXIT_FAILURE); -} - -static void -print_header (image_header_t *hdr) -{ - time_t timestamp; - uint32_t size; - - timestamp = (time_t)ntohl(hdr->ih_time); - size = ntohl(hdr->ih_size); - - printf ("Image Name: %.*s\n", IH_NMLEN, hdr->ih_name); - printf ("Created: %s", ctime(×tamp)); - printf ("Image Type: "); print_type(hdr); - printf ("Data Size: %d Bytes = %.2f kB = %.2f MB\n", - size, (double)size / 1.024e3, (double)size / 1.048576e6 ); - printf ("Load Address: 0x%08X\n", ntohl(hdr->ih_load)); - printf ("Entry Point: 0x%08X\n", ntohl(hdr->ih_ep)); - - if (hdr->ih_type == IH_TYPE_MULTI || hdr->ih_type == IH_TYPE_SCRIPT) { - int i, ptrs; - uint32_t pos; - uint32_t *len_ptr = (uint32_t *) ( - (unsigned long)hdr + sizeof(image_header_t) - ); - - /* determine number of images first (to calculate image offsets) */ - for (i=0; len_ptr[i]; ++i) /* null pointer terminates list */ - ; - ptrs = i; /* null pointer terminates list */ - - pos = sizeof(image_header_t) + ptrs * sizeof(long); - printf ("Contents:\n"); - for (i=0; len_ptr[i]; ++i) { - size = ntohl(len_ptr[i]); - - printf (" Image %d: %8d Bytes = %4d kB = %d MB\n", - i, size, size>>10, size>>20); - if (hdr->ih_type == IH_TYPE_SCRIPT && i > 0) { - /* - * the user may need to know offsets - * if planning to do something with - * multiple files - */ - printf (" Offset = %08X\n", pos); - } - /* copy_file() will pad the first files to even word align */ - size += 3; - size &= ~3; - pos += size; - } - } -} - - -static void -print_type (image_header_t *hdr) -{ - printf ("%s %s %s (%s)\n", - put_arch (hdr->ih_arch), - put_os (hdr->ih_os ), - put_type (hdr->ih_type), - put_comp (hdr->ih_comp) - ); -} - -static char *put_arch (int arch) -{ - return (put_table_entry(arch_name, "Unknown Architecture", arch)); -} - -static char *put_os (int os) -{ - return (put_table_entry(os_name, "Unknown OS", os)); -} - -static char *put_type (int type) -{ - return (put_table_entry(type_name, "Unknown Image", type)); -} - -static char *put_comp (int comp) -{ - return (put_table_entry(comp_name, "Unknown Compression", comp)); -} - -static char *put_table_entry (table_entry_t *table, char *msg, int type) -{ - for (; table->val>=0; ++table) { - if (table->val == type) - return (table->lname); - } - return (msg); -} - -static int get_arch(char *name) -{ - return (get_table_entry(arch_name, "CPU", name)); -} - - -static int get_comp(char *name) -{ - return (get_table_entry(comp_name, "Compression", name)); -} - - -static int get_os (char *name) -{ - return (get_table_entry(os_name, "OS", name)); -} - - -static int get_type(char *name) -{ - return (get_table_entry(type_name, "Image", name)); -} - -static int get_table_entry (table_entry_t *table, char *msg, char *name) -{ - table_entry_t *t; - int first = 1; - - for (t=table; t->val>=0; ++t) { - if (t->sname && strcasecmp(t->sname, name)==0) - return (t->val); - } - fprintf (stderr, "\nInvalid %s Type - valid names are", msg); - for (t=table; t->val>=0; ++t) { - if (t->sname == NULL) - continue; - fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname); - first = 0; - } - fprintf (stderr, "\n"); - return (-1); -} diff --git a/tools/mksh/Makefile b/tools/mksh/Makefile deleted file mode 100644 index 2c912e52b..000000000 --- a/tools/mksh/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= mksh -PKG_VERSION:= 49 -PKG_RELEASE:= 1 -PKG_MD5SUM:= e8c205cac72c3dc8540bbc3897421422 -PKG_SITES:= ${MASTER_SITE_MIRBSD:distfiles/=dist/mir/mksh/} - -DISTFILES= ${PKG_NAME}-R${PKG_VERSION}.tgz -WRKDIST= ${WRKDIR}/${PKG_NAME} - -include ../rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/mksh - -$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared - cd ${WRKBUILD} && CC='${CC_FOR_BUILD}' CFLAGS='${CFLAGS_FOR_BUILD}' \ - HAVE_CAN_FSTACKPROTECTORALL=0 \ - TARGET_OS=Linux ${BASH} ${WRKSRC}/Build.sh -Q -r -c lto - touch $@ - -${STAGING_HOST_DIR}/usr/bin/mksh: $(WRKBUILD)/.compiled - ${INSTALL_BIN} ${WRKBUILD}/mksh \ - ${STAGING_HOST_DIR}/usr/bin - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/mtd-utils/Makefile b/tools/mtd-utils/Makefile deleted file mode 100644 index 0152a41ac..000000000 --- a/tools/mtd-utils/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= mtd-utils -PKG_VERSION:= 1.5.0 -PKG_RELEASE:= 1 -PKG_MD5SUM:= a4df1ad29684be79b0fa699bdae01faf -PKG_SITES:= http://openadk.org/distfiles/ - -include ../rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/mkfs.jffs2 - -$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared - ${MAKE} -C ${WRKBUILD} CC='${CC_FOR_BUILD}' CPPFLAGS='-DWITHOUT_XATTR=1 -I./include' - touch $@ - -${STAGING_HOST_DIR}/usr/bin/mkfs.jffs2: $(WRKBUILD)/.compiled - $(INSTALL_BIN) $(WRKBUILD)/mkfs.jffs2 \ - ${STAGING_HOST_DIR}/usr/bin - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/mtd-utils/patches/darwin.patch b/tools/mtd-utils/patches/darwin.patch deleted file mode 100644 index 1df2ccba2..000000000 --- a/tools/mtd-utils/patches/darwin.patch +++ /dev/null @@ -1,261 +0,0 @@ -diff -Nur mtd-utils-1.5.0.orig/common.mk mtd-utils-1.5.0/common.mk ---- mtd-utils-1.5.0.orig/common.mk 2012-05-07 09:19:39.000000000 +0200 -+++ mtd-utils-1.5.0/common.mk 2014-03-22 11:25:31.000000000 +0100 -@@ -13,8 +13,6 @@ - $(call cc-option,-Wwrite-strings) \ - $(call cc-option,-Wno-sign-compare) - CFLAGS += $(WFLAGS) --SECTION_CFLAGS := $(call cc-option,-ffunction-sections -fdata-sections -Wl$(comma)--gc-sections) --CFLAGS += $(SECTION_CFLAGS) - - ifneq ($(WITHOUT_LARGEFILE), 1) - CPPFLAGS += -D_FILE_OFFSET_BITS=64 -diff -Nur mtd-utils-1.5.0.orig/compr_lzo.c mtd-utils-1.5.0/compr_lzo.c ---- mtd-utils-1.5.0.orig/compr_lzo.c 2012-05-07 09:19:39.000000000 +0200 -+++ mtd-utils-1.5.0/compr_lzo.c 2014-03-22 11:12:06.000000000 +0100 -@@ -26,7 +26,6 @@ - #include - - #ifndef WITHOUT_LZO --#include - #include - #include - #include "compr.h" -diff -Nur mtd-utils-1.5.0.orig/compr_zlib.c mtd-utils-1.5.0/compr_zlib.c ---- mtd-utils-1.5.0.orig/compr_zlib.c 2012-05-07 09:19:39.000000000 +0200 -+++ mtd-utils-1.5.0/compr_zlib.c 2014-03-22 11:11:57.000000000 +0100 -@@ -39,7 +39,6 @@ - #include - #undef crc32 - #include --#include - #include - #include "common.h" - #include "compr.h" -diff -Nur mtd-utils-1.5.0.orig/include/byteswap.h mtd-utils-1.5.0/include/byteswap.h ---- mtd-utils-1.5.0.orig/include/byteswap.h 1970-01-01 01:00:00.000000000 +0100 -+++ mtd-utils-1.5.0/include/byteswap.h 2014-03-22 10:52:15.000000000 +0100 -@@ -0,0 +1,25 @@ -+#ifndef _BYTESWAP_H -+#define _BYTESWAP_H -+ -+#include -+ -+static __inline uint16_t __bswap_16(uint16_t __x) -+{ -+ return __x<<8 | __x>>8; -+} -+ -+static __inline uint32_t __bswap_32(uint32_t __x) -+{ -+ return __x>>24 | __x>>8&0xff00 | __x<<8&0xff0000 | __x<<24; -+} -+ -+static __inline uint64_t __bswap_64(uint64_t __x) -+{ -+ return __bswap_32(__x)+0ULL<<32 | __bswap_32(__x>>32); -+} -+ -+#define bswap_16(x) __bswap_16(x) -+#define bswap_32(x) __bswap_32(x) -+#define bswap_64(x) __bswap_64(x) -+ -+#endif -diff -Nur mtd-utils-1.5.0.orig/include/endian.h mtd-utils-1.5.0/include/endian.h ---- mtd-utils-1.5.0.orig/include/endian.h 1970-01-01 01:00:00.000000000 +0100 -+++ mtd-utils-1.5.0/include/endian.h 2014-03-22 11:09:57.000000000 +0100 -@@ -0,0 +1,20 @@ -+#ifndef _ENDIAN_H -+#define _ENDIAN_H -+ -+#ifndef __BIG_ENDIAN -+#define __BIG_ENDIAN 4321 -+#endif -+ -+ #ifndef __LITTLE_ENDIAN -+ #define __LITTLE_ENDIAN 1234 -+ #endif -+ -+#ifndef __BYTE_ORDER -+#define __BYTE_ORDER __LITTLE_ENDIAN -+#endif -+ -+#ifndef BYTE_ORDER -+#define BYTE_ORDER __LITTLE_ENDIAN -+#endif -+ -+#endif -diff -Nur mtd-utils-1.5.0.orig/include/linux/types.h mtd-utils-1.5.0/include/linux/types.h ---- mtd-utils-1.5.0.orig/include/linux/types.h 1970-01-01 01:00:00.000000000 +0100 -+++ mtd-utils-1.5.0/include/linux/types.h 2014-03-22 11:17:12.000000000 +0100 -@@ -0,0 +1,18 @@ -+#ifndef _LINUX_TYPES_H -+#define _LINUX_TYPES_H -+ -+#include -+ -+typedef uint16_t __u16; -+typedef uint32_t __u32; -+typedef uint64_t __u64; -+ -+typedef __u16 __le16; -+typedef __u32 __le32; -+typedef __u64 __le64; -+typedef __u64 off64_t; -+ -+typedef __u16 __sum16; -+typedef __u32 __wsum; -+ -+#endif /* _LINUX_TYPES_H */ -diff -Nur mtd-utils-1.5.0.orig/include/mtd/jffs2-user.h mtd-utils-1.5.0/include/mtd/jffs2-user.h ---- mtd-utils-1.5.0.orig/include/mtd/jffs2-user.h 2012-05-07 09:19:39.000000000 +0200 -+++ mtd-utils-1.5.0/include/mtd/jffs2-user.h 2014-03-22 11:01:37.000000000 +0100 -@@ -9,8 +9,13 @@ - - /* This file is blessed for inclusion by userspace */ - #include -+#if defined(__APPLE__) -+#include "endian.h" -+#include "byteswap.h" -+#else - #include - #include -+#endif - - #undef cpu_to_je16 - #undef cpu_to_je32 -diff -Nur mtd-utils-1.5.0.orig/include/mtd/mtd-abi.h mtd-utils-1.5.0/include/mtd/mtd-abi.h ---- mtd-utils-1.5.0.orig/include/mtd/mtd-abi.h 2012-05-07 09:19:39.000000000 +0200 -+++ mtd-utils-1.5.0/include/mtd/mtd-abi.h 2014-03-22 11:21:06.000000000 +0100 -@@ -171,9 +171,9 @@ - /* Get info about OOB modes (e.g., RAW, PLACE, AUTO) - legacy interface */ - #define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo) - /* Check if an eraseblock is bad */ --#define MEMGETBADBLOCK _IOW('M', 11, __kernel_loff_t) -+#define MEMGETBADBLOCK _IOW('M', 11, off_t) - /* Mark an eraseblock as bad */ --#define MEMSETBADBLOCK _IOW('M', 12, __kernel_loff_t) -+#define MEMSETBADBLOCK _IOW('M', 12, off_t) - /* Set OTP (One-Time Programmable) mode (factory vs. user) */ - #define OTPSELECT _IOR('M', 13, int) - /* Get number of OTP (One-Time Programmable) regions */ -diff -Nur mtd-utils-1.5.0.orig/include/mtd/ubi-media.h mtd-utils-1.5.0/include/mtd/ubi-media.h ---- mtd-utils-1.5.0.orig/include/mtd/ubi-media.h 2012-05-07 09:19:39.000000000 +0200 -+++ mtd-utils-1.5.0/include/mtd/ubi-media.h 2014-03-22 11:18:03.000000000 +0100 -@@ -30,7 +30,15 @@ - #ifndef __UBI_MEDIA_H__ - #define __UBI_MEDIA_H__ - -+#ifdef __linux__ - #include -+#else -+#include -+typedef uint8_t __u8; -+typedef uint16_t __be16; -+typedef uint32_t __be32; -+typedef uint64_t __be64; -+#endif - - /* The version of UBI images supported by this implementation */ - #define UBI_VERSION 1 -diff -Nur mtd-utils-1.5.0.orig/lib/libfec.c mtd-utils-1.5.0/lib/libfec.c ---- mtd-utils-1.5.0.orig/lib/libfec.c 2012-05-07 09:19:39.000000000 +0200 -+++ mtd-utils-1.5.0/lib/libfec.c 2014-03-22 11:24:15.000000000 +0100 -@@ -61,8 +61,6 @@ - }; - #define gettimeofday(x, dummy) { (x)->ticks = clock() ; } - #define DIFF_T(a,b) (1+ 1000000*(a.ticks - b.ticks) / CLOCKS_PER_SEC ) --typedef unsigned long u_long ; --typedef unsigned short u_short ; - #else /* typically, unix systems */ - #include - #define DIFF_T(a,b) \ -@@ -625,7 +623,7 @@ - #define FEC_MAGIC 0xFECC0DEC - - struct fec_parms { -- u_long magic ; -+ unsigned long magic ; - int k, n ; /* parameters of the code */ - gf *enc_matrix ; - } ; -diff -Nur mtd-utils-1.5.0.orig/lib/libmtd.c mtd-utils-1.5.0/lib/libmtd.c ---- mtd-utils-1.5.0.orig/lib/libmtd.c 2012-05-07 09:19:39.000000000 +0200 -+++ mtd-utils-1.5.0/lib/libmtd.c 2014-03-22 11:15:49.000000000 +0100 -@@ -1006,7 +1006,7 @@ - int mtd_is_bad(const struct mtd_dev_info *mtd, int fd, int eb) - { - int ret; -- loff_t seek; -+ off_t seek; - - ret = mtd_valid_erase_block(mtd, eb); - if (ret) -@@ -1015,7 +1015,7 @@ - if (!mtd->bb_allowed) - return 0; - -- seek = (loff_t)eb * mtd->eb_size; -+ seek = (off_t)eb * mtd->eb_size; - ret = ioctl(fd, MEMGETBADBLOCK, &seek); - if (ret == -1) - return mtd_ioctl_error(mtd, eb, "MEMGETBADBLOCK"); -@@ -1025,7 +1025,7 @@ - int mtd_mark_bad(const struct mtd_dev_info *mtd, int fd, int eb) - { - int ret; -- loff_t seek; -+ off_t seek; - - if (!mtd->bb_allowed) { - errno = EINVAL; -@@ -1036,7 +1036,7 @@ - if (ret) - return ret; - -- seek = (loff_t)eb * mtd->eb_size; -+ seek = (off_t)eb * mtd->eb_size; - ret = ioctl(fd, MEMSETBADBLOCK, &seek); - if (ret == -1) - return mtd_ioctl_error(mtd, eb, "MEMSETBADBLOCK"); -diff -Nur mtd-utils-1.5.0.orig/lib/libmtd_legacy.c mtd-utils-1.5.0/lib/libmtd_legacy.c ---- mtd-utils-1.5.0.orig/lib/libmtd_legacy.c 2012-05-07 09:19:39.000000000 +0200 -+++ mtd-utils-1.5.0/lib/libmtd_legacy.c 2014-03-22 11:22:18.000000000 +0100 -@@ -234,7 +234,7 @@ - struct stat st; - struct mtd_info_user ui; - int fd, ret; -- loff_t offs = 0; -+ off_t offs = 0; - struct proc_parse_info pi; - - if (stat(node, &st)) { -diff -Nur mtd-utils-1.5.0.orig/mkfs.jffs2.c mtd-utils-1.5.0/mkfs.jffs2.c ---- mtd-utils-1.5.0.orig/mkfs.jffs2.c 2012-05-07 09:19:39.000000000 +0200 -+++ mtd-utils-1.5.0/mkfs.jffs2.c 2014-03-22 11:11:15.000000000 +0100 -@@ -70,7 +70,12 @@ - #include - #include - #endif -+#if defined(__APPLE__) -+#include "endian.h" -+#include "byteswap.h" -+#else - #include -+#endif - #include - #include - -diff -Nur mtd-utils-1.5.0.orig/rbtree.h mtd-utils-1.5.0/rbtree.h ---- mtd-utils-1.5.0.orig/rbtree.h 2012-05-07 09:19:39.000000000 +0200 -+++ mtd-utils-1.5.0/rbtree.h 2014-03-22 11:07:58.000000000 +0100 -@@ -94,8 +94,7 @@ - #ifndef _LINUX_RBTREE_H - #define _LINUX_RBTREE_H - --#include --#include -+#include - - struct rb_node - { diff --git a/tools/mtd-utils/patches/lzo.patch b/tools/mtd-utils/patches/lzo.patch deleted file mode 100644 index 52f16146c..000000000 --- a/tools/mtd-utils/patches/lzo.patch +++ /dev/null @@ -1,88 +0,0 @@ -diff -Nur mtd-utils-1.5.0.orig/compr.c mtd-utils-1.5.0/compr.c ---- mtd-utils-1.5.0.orig/compr.c 2012-05-07 09:19:39.000000000 +0200 -+++ mtd-utils-1.5.0/compr.c 2014-02-25 21:05:20.000000000 +0100 -@@ -517,9 +517,6 @@ - #ifdef CONFIG_JFFS2_RTIME - jffs2_rtime_init(); - #endif --#ifdef CONFIG_JFFS2_LZO -- jffs2_lzo_init(); --#endif - return 0; - } - -@@ -531,8 +528,5 @@ - #ifdef CONFIG_JFFS2_ZLIB - jffs2_zlib_exit(); - #endif --#ifdef CONFIG_JFFS2_LZO -- jffs2_lzo_exit(); --#endif - return 0; - } -diff -Nur mtd-utils-1.5.0.orig/Makefile mtd-utils-1.5.0/Makefile ---- mtd-utils-1.5.0.orig/Makefile 2012-05-07 09:19:39.000000000 +0200 -+++ mtd-utils-1.5.0/Makefile 2014-02-25 21:13:03.000000000 +0100 -@@ -16,27 +16,13 @@ - - TESTS = tests - --MTD_BINS = \ -- ftl_format flash_erase nanddump doc_loadbios \ -- ftl_check mkfs.jffs2 flash_lock flash_unlock \ -- flash_otp_info flash_otp_dump mtd_debug flashcp nandwrite nandtest \ -- jffs2dump \ -- nftldump nftl_format docfdisk \ -- rfddump rfdformat \ -- serve_image recv_image \ -- sumtool jffs2reader --UBI_BINS = \ -- ubiupdatevol ubimkvol ubirmvol ubicrc32 ubinfo ubiattach \ -- ubidetach ubinize ubiformat ubirename mtdinfo ubirsvol -+MTD_BINS = mkfs.jffs2 - - BINS = $(MTD_BINS) --BINS += mkfs.ubifs/mkfs.ubifs --BINS += $(addprefix ubi-utils/,$(UBI_BINS)) - SCRIPTS = flash_eraseall - - TARGETS = $(BINS) - TARGETS += lib/libmtd.a --TARGETS += ubi-utils/libubi.a - - OBJDEPS = $(BUILDDIR)/include/version.h - -@@ -83,12 +69,12 @@ - # - # Utils in top level - # --obj-mkfs.jffs2 = compr_rtime.o compr_zlib.o compr_lzo.o compr.o rbtree.o --LDFLAGS_mkfs.jffs2 = $(ZLIBLDFLAGS) $(LZOLDFLAGS) --LDLIBS_mkfs.jffs2 = -lz $(LZOLDLIBS) -+obj-mkfs.jffs2 = compr_rtime.o compr_zlib.o compr.o rbtree.o -+LDFLAGS_mkfs.jffs2 = $(ZLIBLDFLAGS) -+LDLIBS_mkfs.jffs2 = -lz - --LDFLAGS_jffs2reader = $(ZLIBLDFLAGS) $(LZOLDFLAGS) --LDLIBS_jffs2reader = -lz $(LZOLDLIBS) -+LDFLAGS_jffs2reader = $(ZLIBLDFLAGS) -+LDLIBS_jffs2reader = -lz - - $(foreach v,$(MTD_BINS),$(eval $(call mkdep,,$(v)))) - -@@ -103,7 +89,7 @@ - # - obj-mkfs.ubifs = crc16.o lpt.o compr.o devtable.o \ - hashtable/hashtable.o hashtable/hashtable_itr.o --LDLIBS_mkfs.ubifs = -lz -llzo2 -lm -luuid -+LDLIBS_mkfs.ubifs = -lz -lm -luuid - $(call mkdep,mkfs.ubifs/,mkfs.ubifs,,ubi-utils/libubi.a) - - # -@@ -117,6 +103,3 @@ - obj-mtdinfo = libubigen.a - obj-ubinize = libubigen.a libiniparser.a - obj-ubiformat = libubigen.a libscan.a -- --$(foreach v,libubi.a libubigen.a libiniparser.a libscan.a,$(eval $(call _mkdep,ubi-utils/,$(v)))) --$(foreach v,$(UBI_BINS),$(eval $(call mkdep,ubi-utils/,$(v),libubi.a ubiutils-common.o))) diff --git a/tools/pcre/Makefile b/tools/pcre/Makefile deleted file mode 100644 index f88fe230a..000000000 --- a/tools/pcre/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= pcre -PKG_VERSION:= 8.34 -PKG_RELEASE:= 1 -PKG_MD5SUM:= 006c5e27fb78cdd14a628fdfa5aa1905 -PKG_SITES:= ${MASTER_SITE_SOURCEFORGE:=pcre/} - -include ../rules.mk - -install: $(WRKBUILD)/.installed - -$(WRKBUILD)/.configured: ${WRKDIST}/.prepared - (cd ${WRKBUILD}; CPPFLAGS='$(CPPFLAGS_FOR_BUILD)' \ - LDFLAGS='$(LDFLAGS_FOR_BUILD)' \ - ./configure --prefix=$(STAGING_HOST_DIR)/usr) - @touch $@ - -$(WRKBUILD)/.compiled: $(WRKBUILD)/.configured - ${MAKE} -C ${WRKBUILD} - @touch $@ - -$(WRKBUILD)/.installed: $(WRKBUILD)/.compiled - ${MAKE} -C ${WRKBUILD} install - @touch $@ - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/rules.mk b/tools/rules.mk deleted file mode 100644 index a6a3684ac..000000000 --- a/tools/rules.mk +++ /dev/null @@ -1,7 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -WRKDIR_BASE= ${TOOLS_BUILD_DIR} -WRKDIR= ${WRKDIR_BASE} - -include ${TOPDIR}/mk/buildhlp.mk diff --git a/tools/squashfs/Makefile b/tools/squashfs/Makefile deleted file mode 100644 index 06e4215b7..000000000 --- a/tools/squashfs/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= squashfs -PKG_VERSION:= 4.2 -PKG_RELEASE:= 1 -PKG_MD5SUM:= 1b7a781fb4cf8938842279bd3e8ee852 -PKG_SITES:= ${MASTER_SITE_SOURCEFORGE:=squashfs/} - -DISTFILES:= ${PKG_NAME}${PKG_VERSION}.tar.gz -WRKDIST= ${WRKDIR}/$(PKG_NAME)${PKG_VERSION} - -include ../rules.mk - -install: ${STAGING_HOST_DIR}/usr/bin/mksquashfs - -$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared - ${MAKE} -C ${WRKBUILD}/squashfs-tools CC='${CC_FOR_BUILD}' \ - XATTR_SUPPORT=0 XZ_SUPPORT=1 CPPFLAGS_FOR_BUILD=$(CPPFLAGS_FOR_BUILD) \ - EXTRA_LDFLAGS=$(LDFLAGS_FOR_BUILD) - @touch $@ - -${STAGING_HOST_DIR}/usr/bin/mksquashfs: $(WRKBUILD)/.compiled - $(INSTALL_BIN) $(WRKBUILD)/squashfs-tools/mksquashfs \ - ${STAGING_HOST_DIR}/usr/bin - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/squashfs/patches/cppflags.patch b/tools/squashfs/patches/cppflags.patch deleted file mode 100644 index 1432ea3cf..000000000 --- a/tools/squashfs/patches/cppflags.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Nur squashfs4.2.orig/squashfs-tools/Makefile squashfs4.2/squashfs-tools/Makefile ---- squashfs4.2.orig/squashfs-tools/Makefile 2011-02-28 21:04:15.000000000 +0100 -+++ squashfs4.2/squashfs-tools/Makefile 2013-12-27 13:49:22.000000000 +0100 -@@ -93,7 +93,7 @@ - # End of BUILD options section # - ############################################### - --INCLUDEDIR = -I. -+INCLUDEDIR = -I. $(CPPFLAGS_FOR_BUILD) - INSTALL_DIR = /usr/local/bin - - MKSQUASHFS_OBJS = mksquashfs.o read_fs.o sort.o swap.o pseudo.o compressor.o diff --git a/tools/squashfs/patches/darwin.patch b/tools/squashfs/patches/darwin.patch deleted file mode 100644 index b1d2ebd2e..000000000 --- a/tools/squashfs/patches/darwin.patch +++ /dev/null @@ -1,88 +0,0 @@ -diff -Nur squashfs4.2.orig/squashfs-tools/mksquashfs.c squashfs4.2/squashfs-tools/mksquashfs.c ---- squashfs4.2.orig/squashfs-tools/mksquashfs.c 2011-02-28 23:24:09.000000000 +0100 -+++ squashfs4.2/squashfs-tools/mksquashfs.c 2014-03-22 11:32:00.000000000 +0100 -@@ -60,6 +60,10 @@ - #include - #endif - -+#ifndef FNM_EXTMATCH -+#define FNM_EXTMATCH 0 -+#endif -+ - #ifdef SQUASHFS_TRACE - #define TRACE(s, args...) \ - do { \ -@@ -721,13 +725,13 @@ - + (((char *)A) - data_cache))) - - --inline void inc_progress_bar() -+static inline void inc_progress_bar() - { - cur_uncompressed ++; - } - - --inline void update_progress_bar() -+static inline void update_progress_bar() - { - pthread_mutex_lock(&progress_mutex); - pthread_cond_signal(&progress_wait); -@@ -735,7 +739,7 @@ - } - - --inline void waitforthread(int i) -+static inline void waitforthread(int i) - { - TRACE("Waiting for thread %d\n", i); - while(thread[i] != 0) -@@ -3340,7 +3344,7 @@ - } - - --inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, -+static inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, - struct inode_info *inode_info, struct dir_info *dir) - { - if((dir->count % DIR_ENTRIES) == 0) { -diff -Nur squashfs4.2.orig/squashfs-tools/unsquashfs.c squashfs4.2/squashfs-tools/unsquashfs.c ---- squashfs4.2.orig/squashfs-tools/unsquashfs.c 2011-02-28 23:27:06.000000000 +0100 -+++ squashfs4.2/squashfs-tools/unsquashfs.c 2014-03-22 11:36:27.000000000 +0100 -@@ -29,7 +29,13 @@ - #include "compressor.h" - #include "xattr.h" - -+#ifndef FNM_EXTMATCH -+#define FNM_EXTMATCH 0 -+#endif -+ -+#ifdef __linux__ - #include -+#endif - #include - - struct cache *fragment_cache, *data_cache; -@@ -1810,7 +1816,7 @@ - "\n"); - - if(processors == -1) { --#ifndef linux -+#if 0 - int mib[2]; - size_t len = sizeof(processors); - -@@ -1821,11 +1827,13 @@ - mib[1] = HW_NCPU; - #endif - -+#ifdef __linux__ - if(sysctl(mib, 2, &processors, &len, NULL, 0) == -1) { - ERROR("Failed to get number of available processors. " - "Defaulting to 1\n"); - processors = 1; - } -+#endif - #else - processors = sysconf(_SC_NPROCESSORS_ONLN); - #endif diff --git a/tools/srec2bin/Makefile b/tools/srec2bin/Makefile deleted file mode 100644 index 01021c8ff..000000000 --- a/tools/srec2bin/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -include $(TOPDIR)/rules.mk - -all: srec2bin.c - $(CC_FOR_BUILD) $(FLAGS_FOR_BUILD) -o ${STAGING_HOST_DIR}/usr/bin/srec2bin srec2bin.c diff --git a/tools/srec2bin/srec2bin.c b/tools/srec2bin/srec2bin.c deleted file mode 100644 index 8ba4387e6..000000000 --- a/tools/srec2bin/srec2bin.c +++ /dev/null @@ -1,521 +0,0 @@ -#include -#include -#include - -//Rev 0.1 Original -// 8 Jan 2001 MJH Added code to write data to Binary file -// note: outputfile is name.bin, where name is first part -// of input file. ie tmp.rec -> tmp.bin -// -// srec2bin -// -// TAG -// bit32u TAG_BIG = 0xDEADBE42; -// bit32u TAG_LITTLE = 0xFEEDFA42; -// -// File Structure -// -// TAG : 32 Bits -// [DATA RECORDS] -// -// Data Records Structure -// -// LENGTH : 32 Bits <- Length of DATA, excludes ADDRESS and CHECKSUM -// ADDRESS : 32 Bits -// DATA : 8 Bits * LENGTH -// CHECKSUM: 32 Bits <- 0 - (Sum of Length --> End of Data) -// -// Note : If Length == 0, Address will be Program Start -// -// -// -// -// - -#define MajRevNum 0 -#define MinRevNum 2 - - -#define EndianSwitch(x) ((x >> 24) | (x << 24) | ((x << 8) & (0x00FF0000)) | ((x >> 8) & (0x0000FF00)) ) - -typedef unsigned char bit8u; -typedef unsigned int bit32u; -typedef int bit32; - -#define FALSE 0 -#define TRUE (!FALSE) - - -bit32u CheckSum; -int RecStart; -int debug; -int verbose; - -FILE *OpenOutputFile( char *Name ); -FILE *fOut; -bit32u RecLength=0; - -bit32u AddressCurrent; - -bit32u gh(char *cp,int nibs); - -int BigEndian; - -int inputline; - -// char buf[16*1024]; - -char buffer[2048]; -char *cur_ptr; -int cur_line=0; -int cur_len=0; - -int s1s2s3_total=0; - -bit32u PBVal; -int PBValid; -bit32u PBAdr; - - -void dumpfTell(char *s, bit32u Value) -{ - int Length; - Length = (int) RecLength; - if (debug) - printf("[%s ] ftell()[0x%08lX] Length[0x%4X] Length[%4d] Value[0x%08x]\n", - s, ftell(fOut), Length, Length, Value); -} - -void DispHex(bit32u Hex) -{ -// printf("%X", Hex); -} - -void WaitDisplay(void) -{ - static int Count=0; - static int Index=0; - char iline[]={"-\\|/"}; - - Count++; - if ((Count % 32)==0) - { - if (verbose) - printf("%c%c",iline[Index++],8); - Index &= 3; - } -} - - -void binOut32 ( bit32u Data ) -{ -// On UNIX machine all 32bit writes need ENDIAN switched -// Data = EndianSwitch(Data); -// fwrite( &Data, sizeof(bit32u), 1, fOut); - - char sdat[4]; - int i; - - for(i=0;i<4;i++) - sdat[i]=(char)(Data>>(i*8)); - fwrite( sdat, 1, 4, fOut); - dumpfTell("Out32" , Data); -} - -// Only update RecLength on Byte Writes -// All 32 bit writes will be for Length etc - -void binOut8 ( bit8u Data ) -{ - int n; - dumpfTell("B4Data" , (bit32u) (Data & 0xFF) ); - n = fwrite( &Data, sizeof(bit8u), 1, fOut); - if (n != 1) - printf("Error in writing %X for Address 0x%8X\n", Data, AddressCurrent); - RecLength += 1; -} - -// Currently ONLY used for outputting Program Start - -void binRecStart(bit32u Address) -{ - RecLength = 0; - CheckSum = Address; - RecStart = TRUE; - - if (debug) - printf("[RecStart] CheckSum[0x%08X] Length[%4d] Address[0x%08X]\n", - CheckSum, RecLength, Address); - - - dumpfTell("RecLength", RecLength); - binOut32( RecLength ); - dumpfTell("Address", Address); - binOut32( Address ); -} - -void binRecEnd(void) -{ - long RecEnd; - - if (!RecStart) // if no record started, do not end it - { - return; - } - - RecStart = FALSE; - - - RecEnd = ftell(fOut); // Save Current position - - if (debug) - printf("[RecEnd ] CheckSum[0x%08X] Length[%4d] Length[0x%X] RecEnd[0x%08lX]\n", - CheckSum, RecLength, RecLength, RecEnd); - - fseek( fOut, -((long) RecLength), SEEK_CUR); // move back Start Of Data - - dumpfTell("Data ", -1); - - fseek( fOut, -4, SEEK_CUR); // move back Start Of Address - - dumpfTell("Address ", -1); - - fseek( fOut, -4, SEEK_CUR); // move back Start Of Length - - dumpfTell("Length ", -1); - - binOut32( RecLength ); - - fseek( fOut, RecEnd, SEEK_SET); // move to end of Record - - CheckSum += RecLength; - - CheckSum = ~CheckSum + 1; // Two's complement - - binOut32( CheckSum ); - - if (verbose) - printf("[Created Record of %d Bytes with CheckSum [0x%8X]\n", RecLength, CheckSum); -} - -void binRecOutProgramStart(bit32u Address) -{ - if (Address != (AddressCurrent+1)) - { - binRecEnd(); - binRecStart(Address); - } - AddressCurrent = Address; -} -void binRecOutByte(bit32u Address, bit8u Data) -{ - // If Address is one after Current Address, output Byte - // If not, close out last record, update Length, write checksum - // Then Start New Record, updating Current Address - - if (Address != (AddressCurrent+1)) - { - binRecEnd(); - binRecStart(Address); - } - AddressCurrent = Address; - CheckSum += Data; - binOut8( Data ); -} - -//============================================================================= -// SUPPORT FUNCTIONS -//============================================================================= -int readline(FILE *fil,char *buf,int len) -{ - int rlen; - - rlen=0; - if (len==0) return(0); - while(1) - { - if (cur_len==0) - { - cur_len=fread(buffer, 1, sizeof(buffer), fil); - if (cur_len==0) - { - if (rlen) - { - *buf=0; - return(rlen); - } - return(-1); - } - cur_ptr=buffer; - } - if (cur_len) - { - if (*cur_ptr=='\n') - { - *buf=0; - cur_ptr++; - cur_len--; - return(rlen); - } - else - { - if ((len>1)&&(*cur_ptr!='\r')) - { - *buf++=*cur_ptr++; - len--; - } - else - cur_ptr++; - - rlen++; - cur_len--; - } - } - else - { - *buf=0; - cur_ptr++; - cur_len--; - return(rlen); - } - } -} - - -int SRLerrorout(char *c1,char *c2) -{ - printf("\nERROR: %s - '%s'.",c1,c2); - return(FALSE); -} - - -int checksum(char *cp,int count) -{ - char *scp; - int cksum; - int dum; - - scp=cp; - while(*scp) - { - if (!isxdigit(*scp++)) - return(SRLerrorout("Invalid hex digits",cp)); - } - scp=cp; - - cksum=count; - - while(count) - { - cksum += gh(scp,2); - if (count == 2) - dum = ~cksum; - scp += 2; - count--; - } - cksum&=0x0ff; - // printf("\nCk:%02x",cksum); - return(cksum==0x0ff); -} - -bit32u gh(char *cp,int nibs) -{ - int i; - bit32u j; - - j=0; - - for(i=0;i='a')&&(*cp<='z')) *cp &= 0x5f; - if ((*cp>='0')&&(*cp<='9')) - j += (*cp-0x30); - else - if ((*cp>='A')&&(*cp<='F')) - j += (*cp-0x37); - else - SRLerrorout("Bad Hex char", cp); - cp++; - } - return(j); -} - - -//============================================================================= -// PROCESS SREC LINE -//============================================================================= - -int srecLine(char *pSrecLine) -{ - char *scp,ch; - int itmp,count,dat; - bit32u adr; - static bit32u RecordCounter=0; - - cur_line++; - scp=pSrecLine; - - if (*pSrecLine!='S') - return(SRLerrorout("Not an Srecord file",scp)); - pSrecLine++; - if (strlen(pSrecLine)<4) - return(SRLerrorout("Srecord too short",scp)); - - ch=*pSrecLine++; - - count=gh(pSrecLine,2); - - pSrecLine += 2; - - // if(debug) - // printf("count %d, strlen(pSrecLine) = %d, pSrecLine =[%s]\n", count, strlen(pSrecLine), pSrecLine); - RecordCounter++; - DispHex(RecordCounter); - - if ((count*2) != strlen(pSrecLine)) return(SRLerrorout("Count field larger than record",scp)); - - if (!checksum(pSrecLine, count)) return(SRLerrorout("Bad Checksum",scp)); - - switch(ch) - { - case '0': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp)); - itmp=gh(pSrecLine,4); pSrecLine+=4; count-=2; - if (itmp) return(SRLerrorout("Srecord 1 address not zero",scp)); - break; - case '1': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp)); - return(SRLerrorout("Srecord Not valid for MIPS",scp)); - break; - case '2': if (count<4) return(SRLerrorout("Invalid Srecord count field",scp)); - return(SRLerrorout("Srecord Not valid for MIPS",scp)); - break; - case '3': if (count<5) return(SRLerrorout("Invalid Srecord count field",scp)); - adr=gh(pSrecLine,8); pSrecLine+=8; count-=4; - count--; - while(count) - { - dat=gh(pSrecLine,2); pSrecLine+=2; count--; - binRecOutByte(adr, (char) (dat & 0xFF)); - adr++; - } - s1s2s3_total++; - break; - case '4': return(SRLerrorout("Invalid Srecord type",scp)); - break; - case '5': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp)); - itmp=gh(pSrecLine,4); pSrecLine+=4; count-=2; - if (itmp|=s1s2s3_total) return(SRLerrorout("Incorrect number of S3 Record processed",scp)); - break; - case '6': return(SRLerrorout("Invalid Srecord type",scp)); - break; - case '7': // PROGRAM START - if (count<5) return(SRLerrorout("Invalid Srecord count field",scp)); - adr=gh(pSrecLine,8); pSrecLine+=8; count-=4; - if (count!=1) return(SRLerrorout("Invalid Srecord count field",scp)); - binRecOutProgramStart(adr); - break; - case '8': if (count<4) return(SRLerrorout("Invalid Srecord count field",scp)); - return(SRLerrorout("Srecord Not valid for MIPS",scp)); - break; - case '9': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp)); - return(SRLerrorout("Srecord Not valid for MIPS",scp)); - break; - default: - break; - } - return(TRUE); -} - - -//============================================================================= -// MAIN LOGIC, READS IN LINE AND OUTPUTS BINARY -//============================================================================= - -int srec2bin(int argc,char *argv[],int verbose) -{ - int rlen,sts; - FILE *fp; - char buff[256]; - bit32u TAG_BIG = 0xDEADBE42; - bit32u TAG_LITTLE = 0xFEEDFA42; - - bit32u Tag; - - - if(argc < 3) - { - printf("\nError: \n\n"); - return(0); - } - - if (argc > 3) BigEndian=TRUE; else BigEndian=FALSE; - - if (BigEndian) - Tag = TAG_BIG; - else - Tag = TAG_LITTLE; - - if (verbose) - printf("\nEndian: %s, Tag is 0x%8X\n",(BigEndian)?"BIG":"LITTLE", Tag); - - fp = fopen(argv[1],"rt"); - - if (fp==NULL) - { - printf("\nError: Opening input file, %s.", argv[1]); - return(0); - } - - fOut = fopen( argv[2], "wb"); - - if (fOut==NULL) - { - printf("\nError: Opening Output file, %s.", argv[2]); - if(fp) fclose(fp); - return(0); - } - - RecStart = FALSE; - - AddressCurrent = 0xFFFFFFFFL; - - // Setup Tag - - dumpfTell("Tag", Tag); - - binOut32(Tag); - - - inputline=0; - sts=TRUE; - - rlen = readline(fp,buff,sizeof buff); - - while( (sts) && (rlen != -1)) - { - if (strlen(buff)) - { - sts &= srecLine(buff); - WaitDisplay(); - } - rlen = readline(fp,buff,sizeof buff); - } - - - // printf("PC: 0x%08X, Length 0x%08X, Tag 0x%08X\n", ProgramStart, RecLength, TAG_LITTLE); - - binRecEnd(); - - if(fp) fclose(fp); - if(fOut) fclose(fOut); - - return(1); -} - -int main(int argc, char *argv[]) -{ - debug = FALSE; - verbose = FALSE; - srec2bin(argc,argv,verbose); - return 0; -} diff --git a/tools/syslinux/Makefile b/tools/syslinux/Makefile deleted file mode 100644 index 1344538d1..000000000 --- a/tools/syslinux/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= syslinux -PKG_VERSION:= 6.02 -PKG_RELEASE:= 1 -PKG_MD5SUM:= 086ac1c569d226a5e2ae3d605de09a1d -PKG_SITES:= http://www.kernel.org/pub/linux/utils/boot/syslinux/ - -include ../rules.mk -WRKINST:= ${WRKBUILD}/openadk_installroot - -install: ${STAGING_HOST_DIR}/usr/bin/extlinux ${STAGING_HOST_DIR}/usr/share/syslinux/.installed - -$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared - ${MAKE} -C ${WRKBUILD} CC='${CC_FOR_BUILD}' bios installer - @touch $@ - -$(WRKBUILD)/.installed: ${WRKBUILD}/.compiled - mkdir -p ${WRKINST} - ${MAKE} -C ${WRKBUILD} CC='${CC_FOR_BUILD}' \ - INSTALLROOT='${WRKINST}' \ - bios install - @touch $@ - -${STAGING_HOST_DIR}/usr/bin/extlinux: $(WRKBUILD)/.installed - $(INSTALL_BIN) ${WRKINST}/sbin/extlinux \ - ${STAGING_HOST_DIR}/usr/bin - -${STAGING_HOST_DIR}/usr/share/syslinux/.installed: ${WRKBUILD}/.installed - mkdir -p ${STAGING_HOST_DIR}/usr/share - ${CP} ${WRKINST}/usr/share/syslinux ${STAGING_HOST_DIR}/usr/share - @touch ${STAGING_HOST_DIR}/usr/share/syslinux/.installed - -include $(TOPDIR)/mk/tools.mk diff --git a/tools/trx/Makefile b/tools/trx/Makefile deleted file mode 100644 index 25e2b02db..000000000 --- a/tools/trx/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -include $(TOPDIR)/rules.mk - -all: trx.c - $(CC_FOR_BUILD) $(FLAGS_FOR_BUILD) -o ${STAGING_HOST_DIR}/usr/bin/trx trx.c diff --git a/tools/trx/trx.c b/tools/trx/trx.c deleted file mode 100644 index 9e4d521ca..000000000 --- a/tools/trx/trx.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (C) 2004 Manuel Novoa III - * Copyright (C) 2005 Konstantin A. Klubnichkin and Oleg I. Vdovikin - * Copyright (C) 2006 OpenWrt developers - * Copyright (C) 2011 Waldemar Brodkorb - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include -#include -#include -#include -#include -#include -#include - -uint32_t crc32buf(char *buf, size_t len); - -/**********************************************************************/ -/* from trxhdr.h */ - -#define TRX_MAGIC 0x30524448 /* "HDR0" */ -#define TRX_VERSION 1 -#define TRX_MAX_LEN 0x697800 -#define TRX_NO_HEADER 1 /* Do not write TRX header */ - -struct trx_header { - uint32_t magic; /* "HDR0" */ - uint32_t len; /* Length of file including header */ - uint32_t crc32; /* 32-bit CRC from flag_version to end of file */ - uint32_t flag_version; /* 0:15 flags, 16:31 version */ - uint32_t offsets[3]; /* Offsets of partitions from start of header */ -}; - -/**********************************************************************/ - -void usage(void) __attribute__ (( __noreturn__ )); - -void usage(void) -{ - fprintf(stderr, "Usage: trx [-p product_id] [-v version] [-o outfile] [-m maxlen] [-a align] [-b offset] -f file [-f file [-f file]]\n"); - exit(EXIT_FAILURE); -} - -int main(int argc, char **argv) -{ - FILE *out = stdout; - FILE *in; - char *ofn = NULL; - char *buf; - char *e; - int c, i; - size_t n; - uint32_t cur_len; - unsigned long maxlen = TRX_MAX_LEN; - struct trx_header *p; - - struct { - uint8_t version[4]; /* Firmware version */ - uint8_t prod_id[12]; /* Product Id */ - uint8_t comp_hw[4][4]; /* Compatible hw list maj-min min/maj-min max */ - uint8_t pad[32]; /* Padding */ - } asus = { - .version = { 1, 9, 2, 7 }, /* version is set to 1.9.2.7 by default */ - .comp_hw[0] = { 0, 2, 2, 99 } /* hardcoded hw compat list 0.02 - 2.99 */ - }; - - - if (!(buf = malloc(maxlen))) { - fprintf(stderr, "malloc failed\n"); - return EXIT_FAILURE; - } - - p = (struct trx_header *) buf; - - p->magic = TRX_MAGIC; - cur_len = sizeof(struct trx_header); - p->flag_version = (TRX_VERSION << 16); - - in = NULL; - i = 0; - - while ((c = getopt(argc, argv, "-:o:p:v:m:a:b:f:")) != -1) { - switch (c) { - case 'f': - p->offsets[i++] = cur_len; - - if (!(in = fopen(optarg, "r"))) { - fprintf(stderr, "can not open \"%s\" for reading\n", optarg); - usage(); - } - n = fread(buf + cur_len, 1, maxlen - cur_len, in); - if (!feof(in)) { - fprintf(stderr, "fread failure or file \"%s\" too large\n",optarg); - fclose(in); - return EXIT_FAILURE; - } - fclose(in); -#undef ROUND -#define ROUND 4 - if (n & (ROUND-1)) { - memset(buf + cur_len + n, 0, ROUND - (n & (ROUND-1))); - n += ROUND - (n & (ROUND-1)); - } - cur_len += n; - /* reserve space for asus footer */ - if (asus.prod_id[0]) { - cur_len += sizeof(asus); - } - break; - case 'o': - ofn = optarg; - if (ofn && !(out = fopen(ofn, "w"))) { - fprintf(stderr, "can not open \"%s\" for writing\n", ofn); - usage(); - } - - break; - case 'm': - errno = 0; - maxlen = strtoul(optarg, &e, 0); - if (errno || (e == optarg) || *e) { - fprintf(stderr, "illegal numeric string\n"); - usage(); - } -#undef ROUND -#define ROUND 0x1000 - if (maxlen & (ROUND-1)) { - maxlen += (ROUND - (maxlen & (ROUND-1))); - } - if (maxlen < ROUND) { - fprintf(stderr, "maxlen too small (or wrapped)\n"); - usage(); - } - if (maxlen > TRX_MAX_LEN) { - fprintf(stderr, "WARNING: maxlen exceeds default maximum! Beware of overwriting nvram!\n"); - } - if (!(buf = realloc(buf,maxlen))) { - fprintf(stderr, "realloc failed"); - return EXIT_FAILURE; - } - break; - case 'a': - errno = 0; - n = strtoul(optarg, &e, 0); - if (errno || (e == optarg) || *e) { - fprintf(stderr, "illegal numeric string\n"); - usage(); - } - if (cur_len & (n-1)) { - n = n - (cur_len & (n-1)); - memset(buf + cur_len, 0, n); - cur_len += n; - } - break; - case 'b': - errno = 0; - n = strtoul(optarg, &e, 0); - if (errno || (e == optarg) || *e) { - fprintf(stderr, "illegal numeric string\n"); - usage(); - } - if (n < cur_len) { - fprintf(stderr, "WARNING: current length exceeds -b %d offset\n",(int)n); - } else { - memset(buf + cur_len, 0, n - cur_len); - cur_len = n; - } - break; - case 'p': - if ((n = strlen(optarg)) > sizeof(asus.prod_id)) { - fprintf(stderr, "product id too long\n"); - usage(); - } - memset(asus.prod_id, ' ', sizeof(asus.prod_id)); - memcpy(asus.prod_id, optarg, n); - break; - case 'v': - for (n = 0; n < sizeof(asus.version) / sizeof(asus.version[0]); n++) - { - if (n != 0 && optarg[0] == '.' && optarg[1]) optarg++; - else if (n != 0) break; - - asus.version[n] = strtoul(optarg, &optarg, 10); - } - if (*optarg) - { - fprintf(stderr, "invalid version string\n"); - usage(); - } - break; - default: - usage(); - } - } - - if (!in) { - fprintf(stderr, "we require at least one filename\n"); - usage(); - } - -#undef ROUND -#define ROUND 0x1000 - n = cur_len & (ROUND-1); - if (n) { - memset(buf + cur_len, 0, ROUND - n); - cur_len += ROUND - n; - } - /* add asus footer */ - if (asus.prod_id[0]) { - memcpy(buf + cur_len - sizeof(asus), &asus, sizeof(asus)); - } - - p->crc32 = crc32buf((char *) &p->flag_version, - cur_len - offsetof(struct trx_header, flag_version)); - p->crc32 = p->crc32; - - p->len = cur_len; - - if (!fwrite(buf, cur_len, 1, out) || fflush(out)) { - fprintf(stderr, "fwrite failed\n"); - return EXIT_FAILURE; - } - - fclose(out); - - return EXIT_SUCCESS; -} - -/**********************************************************************/ -/* The following was grabbed and tweaked from the old snippets collection - * of public domain C code. */ - -/**********************************************************************\ -|* Demonstration program to compute the 32-bit CRC used as the frame *| -|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *| -|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *| -|* protocol). The 32-bit FCS was added via the Federal Register, *| -|* 1 June 1982, p.23798. I presume but don't know for certain that *| -|* this polynomial is or will be included in CCITT V.41, which *| -|* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *| -|* PUB 78 says that the 32-bit FCS reduces otherwise undetected *| -|* errors by a factor of 10^-5 over 16-bit FCS. *| -\**********************************************************************/ - -/* Copyright (C) 1986 Gary S. Brown. You may use this program, or - code or tables extracted from it, as desired without restriction.*/ - -/* First, the polynomial itself and its table of feedback terms. The */ -/* polynomial is */ -/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ -/* Note that we take it "backwards" and put the highest-order term in */ -/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ -/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ -/* the MSB being 1. */ - -/* Note that the usual hardware shift register implementation, which */ -/* is what we're using (we're merely optimizing it by doing eight-bit */ -/* chunks at a time) shifts bits into the lowest-order term. In our */ -/* implementation, that means shifting towards the right. Why do we */ -/* do it this way? Because the calculated CRC must be transmitted in */ -/* order from highest-order term to lowest-order term. UARTs transmit */ -/* characters in order from LSB to MSB. By storing the CRC this way, */ -/* we hand it to the UART in the order low-byte to high-byte; the UART */ -/* sends each low-bit to hight-bit; and the result is transmission bit */ -/* by bit from highest- to lowest-order term without requiring any bit */ -/* shuffling on our part. Reception works similarly. */ - -/* The feedback terms table consists of 256, 32-bit entries. Notes: */ -/* */ -/* 1. The table can be generated at runtime if desired; code to do so */ -/* is shown later. It might not be obvious, but the feedback */ -/* terms simply represent the results of eight shift/xor opera- */ -/* tions for all combinations of data and CRC register values. */ -/* */ -/* 2. The CRC accumulation logic is the same for all CRC polynomials, */ -/* be they sixteen or thirty-two bits wide. You simply choose the */ -/* appropriate table. Alternatively, because the table can be */ -/* generated at runtime, you can start by generating the table for */ -/* the polynomial in question and use exactly the same "updcrc", */ -/* if your application needn't simultaneously handle two CRC */ -/* polynomials. (Note, however, that XMODEM is strange.) */ -/* */ -/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */ -/* of course, 32-bit entries work OK if the high 16 bits are zero. */ -/* */ -/* 4. The values must be right-shifted by eight bits by the "updcrc" */ -/* logic; the shift must be unsigned (bring in zeroes). On some */ -/* hardware you could probably optimize the shift in assembler by */ -/* using byte-swap instructions. */ - -static const uint32_t crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ -0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, -0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, -0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, -0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, -0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, -0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, -0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, -0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, -0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, -0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, -0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, -0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, -0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, -0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, -0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, -0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, -0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, -0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, -0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, -0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, -0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, -0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, -0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, -0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, -0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, -0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, -0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, -0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, -0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, -0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, -0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, -0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, -0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, -0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, -0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, -0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, -0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, -0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, -0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, -0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, -0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, -0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, -0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - -#define UPDC32(octet,crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8)) - -uint32_t crc32buf(char *buf, size_t len) -{ - uint32_t crc; - - crc = 0xFFFFFFFF; - - for ( ; len; --len, ++buf) - { - crc = UPDC32(*buf, crc); - } - - return crc; -} diff --git a/tools/xz/Makefile b/tools/xz/Makefile deleted file mode 100644 index fa4c51f92..000000000 --- a/tools/xz/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# This file is part of the OpenADK project. OpenADK is copyrighted -# material, please see the LICENCE file in the top-level directory. - -include $(TOPDIR)/rules.mk - -PKG_NAME:= xz -PKG_VERSION:= 5.0.5 -PKG_RELEASE:= 1 -PKG_MD5SUM:= 1b7a781fb4cf8938842279bd3e8ee852 -PKG_SITES:= http://tukaani.org/xz/ - -include ../rules.mk - -install: $(WRKBUILD)/.installed - -$(WRKBUILD)/.configured: ${WRKDIST}/.prepared - (cd ${WRKBUILD}; ./configure --prefix=$(STAGING_HOST_DIR)/usr) - @touch $@ - -$(WRKBUILD)/.compiled: $(WRKBUILD)/.configured - ${MAKE} -C ${WRKBUILD} - @touch $@ - -$(WRKBUILD)/.installed: $(WRKBUILD)/.compiled - ${MAKE} -C ${WRKBUILD} install - @touch $@ - -include $(TOPDIR)/mk/tools.mk -- cgit v1.2.3