subtree-merge https://github.com/hannob/bashcheck plus my bash 2.05b patch
authorThorsten Glaser <t.glaser@tarent.de>
Tue, 7 Jul 2015 13:15:17 +0000 (15:15 +0200)
committerThorsten Glaser <t.glaser@tarent.de>
Tue, 7 Jul 2015 13:15:17 +0000 (15:15 +0200)
129 files changed:
0-README [new file with mode: 0644]
1-NOT-SH [new file with mode: 0644]
LICENCES/AGPLv3 [new file with mode: 0644]
LICENCES/GPLv1 [new file with mode: 0644]
LICENCES/GPLv2 [new file with mode: 0644]
LICENCES/LGPLv2 [new file with mode: 0644]
LICENCES/LGPLv2.1 [new file with mode: 0644]
bash-ksh/0-README [new file with mode: 0644]
bash-ksh/L365 [new file with mode: 0644]
bash-ksh/generate-pgpkey-for-at-home [new file with mode: 0644]
bash-ksh/generate-pgpkey-for-at-work [new file with mode: 0644]
bash-ksh/profile-funcs [new file with mode: 0644]
bash/0-README [new file with mode: 0644]
bash/bashcheck/LICENSE [moved from LICENSE with 100% similarity]
bash/bashcheck/README.md [moved from README.md with 100% similarity]
bash/bashcheck/bashcheck [moved from bashcheck with 100% similarity]
bash/clock [new file with mode: 0644]
ksh/0-README [new file with mode: 0644]
ksh/permute [new file with mode: 0644]
ksh/prompt-tg [new file with mode: 0644]
ksh/svg-path-abs2rel [new file with mode: 0644]
ksh93/0-README [new file with mode: 0644]
mksh/0-README [new file with mode: 0644]
mksh/_remfor [new file with mode: 0644]
mksh/annex.cgi [new file with mode: 0644]
mksh/any2utf8 [new file with mode: 0644]
mksh/assockit.ksh [new file with mode: 0644]
mksh/assoldap.ksh [new file with mode: 0644]
mksh/assotest [new file with mode: 0644]
mksh/base64 [new file with mode: 0644]
mksh/bdfctool.1 [new file with mode: 0644]
mksh/bdfctool.sh [new file with mode: 0644]
mksh/bin2print [new file with mode: 0644]
mksh/clock [new file with mode: 0644]
mksh/conninfo.cgi [new file with mode: 0644]
mksh/csrgen.cgi [new file with mode: 0644]
mksh/cvs-switchroot [new file with mode: 0644]
mksh/cvs-switchroot.1 [new file with mode: 0644]
mksh/debian-dev/BuildDSC.sh [new file with mode: 0644]
mksh/debian-dev/c [new file with mode: 0644]
mksh/debian-dev/debextract [new file with mode: 0644]
mksh/debian-dev/debrepack [new file with mode: 0644]
mksh/debian-dev/dot.quiltrc [new file with mode: 0644]
mksh/debian-dev/dscls [new file with mode: 0644]
mksh/debian-dev/mkdebidx.sh [new file with mode: 0644]
mksh/debian-dev/quinn-ls.sh [new file with mode: 0644]
mksh/depgp [new file with mode: 0644]
mksh/dumpargs [new file with mode: 0644]
mksh/editdiff [new file with mode: 0644]
mksh/fccombine [new file with mode: 0644]
mksh/findups [new file with mode: 0644]
mksh/flacplay [new file with mode: 0644]
mksh/g [new file with mode: 0644]
mksh/gened2k [new file with mode: 0644]
mksh/getarticle [new file with mode: 0644]
mksh/hash-bafh [new file with mode: 0644]
mksh/hash-cdb [new file with mode: 0644]
mksh/hash-jenkins [new file with mode: 0644]
mksh/hash-nzat [new file with mode: 0644]
mksh/hd [new file with mode: 0644]
mksh/hexdump [new file with mode: 0644]
mksh/hexnump [new file with mode: 0644]
mksh/hexpad.sh [new file with mode: 0644]
mksh/hexudump [new file with mode: 0644]
mksh/hexunump [new file with mode: 0644]
mksh/ldap_user_info.cgi [new file with mode: 0644]
mksh/ldapshow [new file with mode: 0644]
mksh/maidenhead [new file with mode: 0644]
mksh/more [new file with mode: 0644]
mksh/mpcabber [new file with mode: 0644]
mksh/profile-funcs [new file with mode: 0644]
mksh/ps2pdfmir [new file with mode: 0644]
mksh/pushd-popd-dirs [new file with mode: 0644]
mksh/rcp [new file with mode: 0644]
mksh/rechte-mock.shar [new file with mode: 0644]
mksh/roff2htm [new file with mode: 0644]
mksh/series [new file with mode: 0644]
mksh/shuffle [new file with mode: 0644]
mksh/strip-comments [new file with mode: 0644]
mksh/svn2cvs [new file with mode: 0644]
mksh/sysadmin/agus [new file with mode: 0644]
mksh/sysadmin/agus.1 [new file with mode: 0644]
mksh/sysadmin/dmppgsql.sh [new file with mode: 0644]
mksh/sysadmin/getjpics.cgi [new file with mode: 0644]
mksh/sysadmin/jboss-management.shar [new file with mode: 0644]
mksh/sysadmin/kuhbauer [new file with mode: 0644]
mksh/sysadmin/loadenv.sh [new file with mode: 0644]
mksh/sysadmin/mkhosts [new file with mode: 0644]
mksh/sysadmin/mkhosts.1 [new file with mode: 0644]
mksh/sysadmin/mvndebri.sh [new file with mode: 0644]
mksh/sysadmin/mvndput.sh [new file with mode: 0644]
mksh/sysadmin/vcs2deb [new file with mode: 0644]
mksh/timefns [new file with mode: 0644]
mksh/tpmrx [new file with mode: 0644]
mksh/uhr [new file with mode: 0644]
mksh/uhr-preR41 [new file with mode: 0644]
mksh/unepub [new file with mode: 0644]
mksh/unsort [new file with mode: 0644]
mksh/uri-grabber [new file with mode: 0644]
mksh/utf8-select [new file with mode: 0644]
mksh/verscmp [new file with mode: 0644]
mksh/website.shar [new file with mode: 0644]
mksh/wtf [new file with mode: 0644]
other/getshver [new file with mode: 0644]
posix/0-README [new file with mode: 0644]
posix/apt-get [new file with mode: 0644]
posix/cleanenv [new file with mode: 0644]
posix/cleanenv.1 [new file with mode: 0644]
posix/nestX [new file with mode: 0644]
posix/pbuilder-hooks/A50wait [new file with mode: 0644]
posix/pbuilder-hooks/B20lintian [new file with mode: 0644]
posix/pbuilder-hooks/C80shell-joe [new file with mode: 0644]
posix/pbuilder-hooks/C80shell-jupp [new file with mode: 0644]
posix/pbuilder-hooks/D02debhelper [new file with mode: 0644]
posix/pbuilder-hooks/D05agu [new file with mode: 0644]
posix/pbuilder-hooks/D06agdu [new file with mode: 0644]
posix/pbuilder-hooks/D10wtfrepo [new file with mode: 0644]
posix/pbuilder-hooks/D10wtfrepo-etch [new file with mode: 0644]
posix/pbuilder-hooks/D10wtfrepo-lenny [new file with mode: 0644]
posix/pbuilder-hooks/pbuild [new file with mode: 0644]
posix/pbuilder-hooks/pbuildetch [new file with mode: 0644]
posix/profile-cygwin [new file with mode: 0644]
posix/profile-funcs [new file with mode: 0644]
posix/ste [new file with mode: 0644]
posix/sysadmin/agents.sh [new file with mode: 0644]
posix/sysadmin/policy-rc.d [new file with mode: 0644]
posix/wcdiff [new file with mode: 0644]
zsh/0-README [new file with mode: 0644]
zsh/vcsupinit [new file with mode: 0644]

diff --git a/0-README b/0-README
new file mode 100644 (file)
index 0000000..8bbacff
--- /dev/null
+++ b/0-README
@@ -0,0 +1,16 @@
+Shell snippets of random value. Not intended to be packaged,
+more like aid to developers, training purposes or a code library.
+Each of the snippets is separate and may have separate authors.
+Some are private, some company-provided.
+
+All of them MUST have an OSI approved licence, if copyright
+law applies. (Otherwise, they’re obviously Public Domain.)
+For licencing conditions, look into each file separately.
+Things marked as not complicated enough for copyright are
+assumed to not achieve the threshold of originality required
+for such protection; as a fallback, all such files are also
+available under any OSI approved licence, should they not be
+in the Public Domain in your legislation.
+
+Group home: https://evolvis.org/projects/shellsnippets/
+gitweb:     https://evolvis.org/plugins/scmgit/cgi-bin/gitweb.cgi?p=shellsnippets/shellsnippets.git
diff --git a/1-NOT-SH b/1-NOT-SH
new file mode 100644 (file)
index 0000000..0be87a8
--- /dev/null
+++ b/1-NOT-SH
@@ -0,0 +1,30 @@
+This repository is dedicated to POSIX (and compatible) shell
+scripts. Bourne shell may be admissible, but C Shell and not
+shell isn't.
+
+Why not csh? => http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/
+
+Developers have written lots of code and accompanying data that,
+by these rules, is not admissible in this repository. However to
+strengthen the spirit of learning-by-example as by the mission
+statement of this repository, here is a collection of links to
+other repositories which may contain code in other programming
+and/or scripting languages, and accompanying data, and websites
+with useful information:
+
+https://www.mirbsd.org/ksh-chan.htm
+       Homepage of the #ksh IRC channel on Freenode, with lots
+       of (mostly Korn Shell related) links and book references
+
+http://users.softlab.ece.ntua.gr/~ttsiod/tricks.html
+       UNIX/Linux tips (potpourri)
+
+https://www.mirbsd.org/cvs.cgi/contrib/code/Snippets/
+https://www.mirbsd.org/cvs.cgi/contrib/hosted/tg/
+       Collection of (shell and other) scripts, programmes,
+       data, pbuilderrc, and other things by mirabilos
+
+https://evolvis.org/projects/useful-scripts/
+https://evolvis.org/plugins/scmgit/cgi-bin/gitweb.cgi?p=useful-scripts/useful-scripts.git
+       Similar collection, focus on just publishing internal
+       tools without quality review, also not limited to sh.
diff --git a/LICENCES/AGPLv3 b/LICENCES/AGPLv3
new file mode 100644 (file)
index 0000000..dba13ed
--- /dev/null
@@ -0,0 +1,661 @@
+                    GNU AFFERO GENERAL PUBLIC LICENSE
+                       Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+  A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate.  Many developers of free software are heartened and
+encouraged by the resulting cooperation.  However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+  The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community.  It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server.  Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+  An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals.  This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU Affero General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Remote Network Interaction; Use with the GNU General Public License.
+
+  Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software.  This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero 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
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source.  For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code.  There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<http://www.gnu.org/licenses/>.
diff --git a/LICENCES/GPLv1 b/LICENCES/GPLv1
new file mode 100644 (file)
index 0000000..1be0f25
--- /dev/null
@@ -0,0 +1,249 @@
+                    GNU GENERAL PUBLIC LICENSE
+                     Version 1, February 1989
+
+ Copyright (C) 1989 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The license agreements of most software companies try to keep users
+at the mercy of those companies.  By contrast, our General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  The
+General Public License applies to the Free Software Foundation's
+software and to any other program whose authors commit to using it.
+You can use it for your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Specifically, the General Public License is designed to make
+sure that you have the freedom to give away or sell copies of free
+software, that you receive source code or can get it if you want it,
+that you can change the software or use pieces of it in new free
+programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of a such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must tell them their rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any program or other work which
+contains a notice placed by the copyright holder saying it may be
+distributed under the terms of this General Public License.  The
+"Program", below, refers to any such program or work, and a "work based
+on the Program" means either the Program or any work containing the
+Program or a portion of it, either verbatim or with modifications.  Each
+licensee is addressed as "you".
+
+  1. You may copy and distribute verbatim copies of the Program's source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this
+General Public License and to the absence of any warranty; and give any
+other recipients of the Program a copy of this General Public License
+along with the Program.  You may charge a fee for the physical act of
+transferring a copy.
+
+  2. You may modify your copy or copies of the Program or any portion of
+it, and copy and distribute such modifications under the terms of Paragraph
+1 above, provided that you also do the following:
+
+    a) cause the modified files to carry prominent notices stating that
+    you changed the files and the date of any change; and
+
+    b) cause the whole of any work that you distribute or publish, that
+    in whole or in part contains the Program or any part thereof, either
+    with or without modifications, to be licensed at no charge to all
+    third parties under the terms of this General Public License (except
+    that you may choose to grant warranty protection to some or all
+    third parties, at your option).
+
+    c) If the modified program normally reads commands interactively when
+    run, you must cause it, when started running for such interactive use
+    in the simplest and most usual way, to print or display an
+    announcement including an appropriate copyright notice and a notice
+    that there is no warranty (or else, saying that you provide a
+    warranty) and that users may redistribute the program under these
+    conditions, and telling the user how to view a copy of this General
+    Public License.
+
+    d) You may charge a fee for the physical act of transferring a
+    copy, and you may at your option offer warranty protection in
+    exchange for a fee.
+
+Mere aggregation of another independent work with the Program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other work under the scope of these terms.
+\f
+  3. You may copy and distribute the Program (or a portion or derivative of
+it, under Paragraph 2) in object code or executable form under the terms of
+Paragraphs 1 and 2 above provided that you also do one of the following:
+
+    a) accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    b) accompany it with a written offer, valid for at least three
+    years, to give any third party free (except for a nominal charge
+    for the cost of distribution) a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    c) accompany it with the information you received as to where the
+    corresponding source code may be obtained.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form alone.)
+
+Source code for a work means the preferred form of the work for making
+modifications to it.  For an executable file, complete source code means
+all the source code for all modules it contains; but, as a special
+exception, it need not include source code for modules which are standard
+libraries that accompany the operating system on which the executable
+file runs, or for standard header files or definitions files that
+accompany that operating system.
+
+  4. You may not copy, modify, sublicense, distribute or transfer the
+Program except as expressly provided under this General Public License.
+Any attempt otherwise to copy, modify, sublicense, distribute or transfer
+the Program is void, and will automatically terminate your rights to use
+the Program under this License.  However, parties who have received
+copies, or rights to use copies, from you under this General Public
+License will not have their licenses terminated so long as such parties
+remain in full compliance.
+
+  5. By copying, distributing or modifying the Program (or any work based
+on the Program) you indicate your acceptance of this license to do so,
+and all its terms and conditions.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these
+terms and conditions.  You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein.
+\f
+  7. The Free Software Foundation may publish revised and/or new versions
+of the 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 Program
+specifies a version number of the license which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+the license, you may choose any version ever published by the Free Software
+Foundation.
+
+  8. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+\f
+        Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to humanity, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+  To do so, attach the following notices to the program.  It is safest to
+attach them to the start of each source file to most effectively convey
+the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    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 1, 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19xx name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License.  Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  program `Gnomovision' (a program to direct compilers to make passes
+  at assemblers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/LICENCES/GPLv2 b/LICENCES/GPLv2
new file mode 100644 (file)
index 0000000..d159169
--- /dev/null
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the 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 Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/LICENCES/LGPLv2 b/LICENCES/LGPLv2
new file mode 100644 (file)
index 0000000..12735e6
--- /dev/null
@@ -0,0 +1,481 @@
+                  GNU LIBRARY GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+\f
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+\f
+                  GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License").  Each licensee is
+addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    c) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    d) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. 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 not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Library 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
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/LICENCES/LGPLv2.1 b/LICENCES/LGPLv2.1
new file mode 100644 (file)
index 0000000..4362b49
--- /dev/null
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. 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 not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the 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
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library 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 2.1 of the License, or (at your option) any later version.
+
+    This library 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 this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/bash-ksh/0-README b/bash-ksh/0-README
new file mode 100644 (file)
index 0000000..7e8de4f
--- /dev/null
@@ -0,0 +1,2 @@
+Shell snippets that run with GNU bash and/or a Korn Shell (ksh93, mksh, pdksh).
+Please document exact requirements / restrictions.
diff --git a/bash-ksh/L365 b/bash-ksh/L365
new file mode 100644 (file)
index 0000000..3754294
--- /dev/null
@@ -0,0 +1,43 @@
+#!/bin/mksh
+# $MirOS: contrib/hosted/tg/L365,v 1.2 2012/08/23 17:39:59 tg Exp $
+#-
+# Player for music streams from live365.com (not affiliated).
+
+# Inline-edit this script to define your credentials:
+USERID='myusername'
+PASSWD='my!secret!'
+
+# Code follows.
+
+# disabled as mpg123 with live365 is too unreliable (lack of caching)
+#if [[ $1 = -m ]]; then
+       player='mplayer -cache 128'
+#      shift
+#else
+#      player=mpg123
+#fi
+
+STATION=$1
+
+cd /
+if ! T=$(mktemp -d /tmp/L365.XXXXXXXXXX) || [[ ! -d $T/. ]]; then
+       print -u2 Error creating temporary directory.
+       exit 255
+fi
+
+cd "$T"
+if ! curl --cookie-jar curlcookies --output curldump --location-trusted \
+    "http://www.live365.com/cgi-bin/login.cgi?url=http://www.live365.com/index.live&membername=${USERID}&password=${PASSWD}"; then
+       cd /
+       rm -rf "$T"
+       print -u2 Error logging in.
+       exit 2
+fi
+
+SANE=$(fgrep SaneID curlcookies | cut -f7)
+SESS=$(fgrep sessionid curlcookies | cut -f7 | sed "s/${USERID}%3A//")
+
+cd /
+rm -rf "$T"
+
+exec $player "http://www.live365.com/play/${STATION}?SaneID=${SANE}&membername=${USERID}&session=${SESS}"
diff --git a/bash-ksh/generate-pgpkey-for-at-home b/bash-ksh/generate-pgpkey-for-at-home
new file mode 100644 (file)
index 0000000..b532080
--- /dev/null
@@ -0,0 +1,365 @@
+#!/bin/sh
+# $Id: genkey-privatgebrauch.sh 3857 2013-11-04 12:26:56Z tglase $
+#-
+# Copyright © 2010, 2011, 2013
+#      Thorsten Glaser <t.glaser@tarent.de>
+# All rights reserved.
+#
+# Licenced under the GNU AGPLv3.
+#-
+# Generate a new GnuPG (PGP) key, for private use.
+
+# check if we're called with mksh or bash; fix if not
+if test -z "$shell_tried"; then
+       if test -z "$KSH_VERSION"; then
+               if mksh -c true >/dev/null 2>&1; then
+                       shell_tried=1
+                       export shell_tried
+                       exec mksh "$0" "$@"
+               fi
+               if test -z "$BASH_VERSION"; then
+                       if bash -c true >/dev/null 2>&1; then
+                               shell_tried=1
+                               export shell_tried
+                               exec bash "$0" "$@"
+                       fi
+               fi
+       fi
+fi
+if test -z "$KSH_VERSION$BASH_VERSION"; then
+       echo >&2 "I've tried but couldn't find mksh or GNU bash."
+       echo >&2 "Please call me with one of these shells."
+       exit 1
+fi
+unset shell_tried
+
+# set up some basic environment
+export LC_ALL=C
+unset LANG LANGUAGE
+test -z "$BASH_VERSION" || shopt -s extglob
+# we can now use Korn Shell extensions common to mksh and GNU bash
+unset GPG_AGENT_INFO GPG_TTY
+nl='
+'
+if ! tilde=$(cd && pwd) || [[ -z $tilde ]]; then
+       tilde=$HOME
+       if ! tilde=$(cd && pwd) || [[ -z $tilde ]]; then
+               echo >&2 Eek, what\'s your home directory?
+               exit 1
+       fi
+fi
+
+# initiate logging
+cd "$(dirname "$0")"
+log="$(basename "$0").log"
+cat >>"$log" <<-EOF
+
+       New key generation started (Privatgebrauch)
+       $(date)
+       ===========================================
+EOF
+test -z "$KSH_VERSION" || echo ksh >>"$log"
+test -z "$BASH_VERSION" || echo bash >>"$log"
+
+# check for existence of prerequisite tools
+for tool in gpg wget; do
+       $tool --version >/dev/null 2>&1 && continue
+       echo >&2 You must install $tool to continue.
+       exit 1
+done
+
+# subroutine for converting a string into an array
+# taking into account Korn Shell vs GNU bash syntax
+str2arr() {
+       local _a _b _s _vn=$1
+
+       eval _s=\$$_vn
+       if [[ -n $KSH_VERSION ]]; then
+               _a="set -A $_vn -- "
+               _b=
+       else
+               _a="${_vn}=("
+               _b=")"
+       fi
+       eval $_a$_s$_b
+}
+
+# subroutines for converting array elements into hex,
+# printing with escapes honoured/ignored
+# taking into account Korn Shell vs GNU bash syntax
+if [[ -n $KSH_VERSION ]]; then
+       alias arr2hex='typeset -i16 '
+       alias eprint='print -n'
+       alias nprint='print -nr -- '
+else
+       arr2hex() {
+               local _vn=$1 _i _n _v
+
+               _i=0
+               eval _n='${#'$_vn'[*]}'
+               while (( _i < _n )); do
+                       eval _v='${'$_vn'[_i]}'
+                       _v=$(printf '16#%x' $_v)
+                       eval $_vn'[_i++]=$_v'
+               done
+       }
+       eprint() {
+               printf "$@"
+       }
+       nprint() {
+               printf '%s' "$*"
+       }
+fi
+
+### BEGIN imported code {{{
+# Copyright (c) 2008
+#      Thorsten Glaser <tg@mirbsd.org>
+#
+# 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.
+
+# read a password without echoing
+askpass() {
+       set -o noglob
+       stty -echo
+       echo -n "$1 "
+       read resp
+       stty echo
+       set +o noglob
+       echo
+}
+
+# convert a string from UTF-8 or ISO-8859-1 to UTF-8
+str2utf8() {
+       local _s="$*" _z _c _i _hv _wc _n
+
+       _c=$(nprint "$_s" | hexdump -ve '1/1 "16#%x "')
+       _c="$_c 0"
+       str2arr _c
+       _s=
+       _z=0
+       _i=0
+       while (( _c[_i] )); do
+               (( _hv = _c[_i] ))
+               if (( (_hv < 16#C2) || (_hv >= 16#F0) )); then
+                       _n=1
+               elif (( _hv < 16#E0 )); then
+                       _n=2
+               else
+                       _n=3
+               fi
+               if (( _n > 1 )); then
+                       (( (_c[_i + 1] & 16#C0) == 16#80 )) || _n=1
+                       (( _hv == 16#E0 )) && \
+                           (( _c[_i + 1] < 16#A0 )) && _n=1
+               fi
+               if (( _n > 2 )); then
+                       (( (_c[_i + 2] & 16#C0) == 16#80 )) || _n=1
+                       (( _hv == 16#EF && _c[_i + 1] == 16#EF && \
+                           _c[_i + 2] > 16#BD )) && _n=1
+               fi
+               case $_n in
+               (1)
+                       if (( (_wc = _c[_i]) < 16#80 )); then
+                               (( _s[_z++] = _wc ))
+                       else
+                               (( _s[_z++] = 16#C0 | (_wc >> 6) ))
+                               (( _s[_z++] = 16#80 | (_wc & 16#3F) ))
+                       fi
+                       ;;
+               (2)
+                       (( _s[_z++] = _c[_i] ))
+                       (( _s[_z++] = _c[_i + 1] ))
+                       ;;
+               (3)
+                       (( _s[_z++] = _c[_i] ))
+                       (( _s[_z++] = _c[_i + 1] ))
+                       (( _s[_z++] = _c[_i + 2] ))
+                       ;;
+               esac
+               (( _i += _n ))
+       done
+       arr2hex _s
+       eprint "$(echo ${_s[*]} | sed -e 's/16#/\\x/g' -e 's/ //g')"
+}
+
+### END imported code }}}
+
+# create a temporary directory in /dev/shm (Linux tmpfs) or /tmp (otherwise)
+if [[ ! -d /dev/shm/. ]] || ! T=$(mktemp -d /dev/shm/genkey.XXXXXXXXXX); then
+       if ! T=$(mktemp -d /tmp/genkey.XXXXXXXXXX); then
+               echo >&2 Cannot create temporary directory.
+               exit 1
+       fi
+fi
+
+cleanup() {
+       trap - 0 1 2 3 13 15
+       # files to overwrite before removing
+       for wipefiles in resp wgetrc; do
+               for x in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
+                       echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+               done >"$T/$wipefiles"
+       done
+       sync
+       rm -rf "$T"
+       exit $1
+}
+
+# make sure the temporary files are removed if we are interrupted
+trap "cleanup 1" 1 2 3 13 15
+trap "cleanup 0" 0
+
+
+# gpg2, as opposed to gnupg, doesn’t want to not use the agent
+vsn=$(gpg --version 2>&1 | head -n 1)
+isgpg2=0
+if [[ $vsn = 'gpg (GnuPG) 1.4.'* ]]; then
+       : okay
+elif [[ $vsn = 'gpg (GnuPG) 1.'* ]]; then
+       echo 'WARNING: Obsolete GnuPG 1.x version, you SHALL update!'
+elif [[ $vsn = 'gpg (GnuPG) 2.0.'* ]]; then
+       isgpg2=1
+else
+       echo "WARNING: Unknown GnuPG version '$vsn', tell tglase!"
+fi
+
+
+# request and record user/pass
+echo -n "Vor- und Zuname: "
+read i_name
+[[ -n $i_name ]] || cleanup 0
+echo -n "eMail-Adresse: "
+read i_mail
+echo -n "Kommentarfeld: "
+read i_comm
+echo "Generiere für: '$i_name${i_comm:+ "($i_comm)"}${i_mail:+ "<$i_mail>"}' (^C wenn falsch)"
+askpass "Password:"
+[[ -n $resp ]] || cleanup 0
+pw1=$resp
+askpass "Password (nochmal):"
+[[ -n $resp ]] || cleanup 0
+if [[ $pw1 != $resp ]]; then
+       echo Sind nicht gleich.
+       cleanup 1
+fi
+
+echo "userdata: $i_name ($i_comm) <$i_mail>" >>"$log"
+
+# add entropy from CGIs to that pool (magic code ;) {{{
+if [[ ! -s ${tilde}/.gnupg/random_seed ]]; then
+       # create and fill if it didn't exist
+       :>"${tilde}"/.gnupg/random_seed
+       chmod 0600 "${tilde}"/.gnupg/random_seed
+       dd if=/dev/urandom of="${tilde}"/.gnupg/random_seed bs=600 count=1 2>/dev/null
+fi
+entropy=$(wget -O - -T 10 --no-check-certificate \
+    https://call.mirbsd.org/lb.cgi?genkey.sh,1=$(hostname -f 2>/dev/null || hostname),seed=$RANDOM$RANDOM$RANDOM$RANDOM$RANDOM 2>/dev/null | \
+    hexdump -ve '1/1 "16#%x "')$x
+poolfile=$(hexdump -ve '1/1 "16#%x "' <"${tilde}"/.gnupg/random_seed)
+str2arr entropy
+str2arr poolfile
+(( n = ${#poolfile[*]} < ${#entropy[*]} ? ${#entropy[*]} : ${#poolfile[*]} ))
+i=0
+# XOR poolfile with new entropy (from CGIs)
+while (( i < n )); do
+       (( poolfile[i % ${#poolfile[*]}] ^= entropy[i % ${#entropy[*]}] ))
+       let i++
+done
+# write back into the pool file
+arr2hex poolfile
+eprint "$(echo ${poolfile[*]} | sed -e 's/16#/\\x/g' -e 's/ //g')" | \
+    dd of="${tilde}"/.gnupg/random_seed conv=notrunc 2>/dev/null
+# }}} end of magic code block ;)
+
+# create response file for gpg
+# NOTE:        Key-Length can go up to 8192 (not more!) but please no lower
+#      than 2048 (although more than 4096 may be incompatible *AND*
+#      TERRIBLY SLOW)
+cat >"$T/resp" <<-EOF
+       %echo Generating the key for $i_name ($i_mail) $i_comm
+       Key-Type: RSA
+       Key-Length: 3072
+       Key-Usage: auth,encrypt,sign
+       Passphrase: $(str2utf8 "$resp")
+       Name-Real: $(str2utf8 "$i_name")
+       ${i_comm:+Name-Comment: $(str2utf8 "$i_comm")}
+       ${i_mail:+Name-Email: $(str2utf8 "$i_mail")}
+       Expire-Date: 3y
+       Preferences: H8 H3 S8 S4 Z2 Z0 H9 H10 S9 S7
+       Keyserver: hkp://pgp.uni-mainz.de
+       %commit
+       %echo done
+EOF
+
+# really generate the key
+echo
+(gpg --no-use-agent --batch --gen-key "$T/resp"; echo $? >"$T/rc") 2>&1 | \
+    tee "$T/gen.out"
+echo
+(echo "create key {"; sed 's/^/        /' <"$T/gen.out"; echo "}") >>"$log"
+# check for error exit
+if (( $(<"$T/rc") > 0 )); then
+       echo >&2 Key generation failed.
+       cleanup 1
+fi
+# scan the gpg log for keyid of keypair just created
+pkid=$(sed -n \
+    's/^gpg: key \([0-9A-F]*\) marked as ultimately trusted.*$/\1/p' \
+    "$T/gen.out")
+if [[ $pkid != +([0-9A-F]) ]] || ! gpg -K $pkid; then
+       echo >&2 '┌─────────────────────────────────────────────────────────┐'
+       echo >&2 '│ Finding the key failed. YOU CAN USE THE KEY, BUT YOU    │'
+       echo >&2 '│ *MUST* CONTACT THE ADMINS with this error message.      │'
+       echo >&2 '│ Kann den neuen Schlüssel nicht finden. DU KANNST DIESES │'
+       echo >&2 '│ SCHLÜSSELPAAR BENUTZEN, ABER DU *MUẞT* DIE ADMINS mit   │'
+       echo >&2 '│ dieser Fehlernachricht KONTAKTIEREN.                    │'
+       echo >&2 '└─────────────────────────────────────────────────────────┘'
+       echo
+       echo >&2 Cannot find the key just generated.
+       cleanup 1
+fi
+
+# apply preference settings to our newly generated key
+if [[ $isgpg2 = 0 ]]; then
+       usepw="$nl$(str2utf8 "$resp")"
+else
+       usepw=""
+fi
+gpg --no-use-agent -q -u $pkid --command-fd 4 --edit-key $pkid \
+    >>"$T/edit.log" 2>&1 4<<-EOF
+       notation preferred-email-encoding@pgp.com=partitioned,pgpmime$usepw
+       trust
+       5
+       y
+       save
+EOF
+echo "=> $?" >>"$T/edit.log"
+
+       cat >&2 <<'EOF'
+┌─────────────────────────────────────────┐
+│ Key generation finished with no errors. │
+│ Schlüsselerzeugung fehlerfrei erledigt. │
+└─────────────────────────────────────────┘
+
+╔═════════════════════════════════════════════════════════════════════╗
+║ You are responsible for backing up your PGP secret key BY YOURSELF! ║
+║ Du mußt SELBER für Sicherungskopiën des privaten Schlüssels sorgen! ║
+╚═════════════════════════════════════════════════════════════════════╝
+EOF
+(echo "finished:"; gpg -k $pkid | sed 's/^/|   /'; echo) >>"$log"
+echo >&2
+gpg -k $pkid || echo gpg ERROR -k: $?
+cleanup 0
diff --git a/bash-ksh/generate-pgpkey-for-at-work b/bash-ksh/generate-pgpkey-for-at-work
new file mode 100644 (file)
index 0000000..db1c5bc
--- /dev/null
@@ -0,0 +1,571 @@
+#!/bin/sh
+# $Id: genkey-firmengebrauch.sh 3856 2013-11-04 12:15:25Z tglase $
+#-
+# Copyright © 2010, 2011, 2012, 2013
+#      Thorsten Glaser <t.glaser@tarent.de>
+# All rights reserved.
+#
+# Licenced under the GNU AGPLv3.
+#-
+# Generate a new GnuPG (PGP) key, for company use.
+# The keys are revokable by the company key and use LDAP user/password.
+
+# check if we're called with mksh or bash; fix if not
+if test -z "$shell_tried"; then
+       if test -z "$KSH_VERSION"; then
+               if mksh -c true >/dev/null 2>&1; then
+                       shell_tried=1
+                       export shell_tried
+                       exec mksh "$0" "$@"
+               fi
+               if test -z "$BASH_VERSION"; then
+                       if bash -c true >/dev/null 2>&1; then
+                               shell_tried=1
+                               export shell_tried
+                               exec bash "$0" "$@"
+                       fi
+               fi
+       fi
+fi
+if test -z "$KSH_VERSION$BASH_VERSION"; then
+       echo >&2 "I've tried but couldn't find mksh or GNU bash."
+       echo >&2 "Please call me with one of these shells."
+       exit 1
+fi
+unset shell_tried
+
+# set up some basic environment
+export LC_ALL=C
+unset LANG LANGUAGE
+test -z "$BASH_VERSION" || shopt -s extglob
+# we can now use Korn Shell extensions common to mksh and GNU bash
+unset GPG_AGENT_INFO GPG_TTY
+nl='
+'
+if ! tilde=$(cd && pwd) || [[ -z $tilde ]]; then
+       tilde=$HOME
+       if ! tilde=$(cd && pwd) || [[ -z $tilde ]]; then
+               echo >&2 Eek, what\'s your home directory?
+               exit 1
+       fi
+fi
+
+# initiate logging
+cd "$(dirname "$0")"
+log="$(basename "$0").log"
+cat >>"$log" <<-EOF
+
+       New key generation started (Firmengebrauch)
+       $(date)
+       ===========================================
+EOF
+test -z "$KSH_VERSION" || echo ksh >>"$log"
+test -z "$BASH_VERSION" || echo bash >>"$log"
+
+# check for existence of prerequisite tools
+for tool in gpg wget; do
+       $tool --version >/dev/null 2>&1 && continue
+       echo >&2 You must install $tool to continue.
+       exit 1
+done
+
+# subroutine for converting a string into an array
+# taking into account Korn Shell vs GNU bash syntax
+str2arr() {
+       local _a _b _s _vn=$1
+
+       eval _s=\$$_vn
+       if [[ -n $KSH_VERSION ]]; then
+               _a="set -A $_vn -- "
+               _b=
+       else
+               _a="${_vn}=("
+               _b=")"
+       fi
+       eval $_a$_s$_b
+}
+
+# subroutines for converting array elements into hex,
+# printing with escapes honoured/ignored
+# taking into account Korn Shell vs GNU bash syntax
+if [[ -n $KSH_VERSION ]]; then
+       alias arr2hex='typeset -i16 '
+       alias eprint='print -n'
+       alias nprint='print -nr -- '
+else
+       arr2hex() {
+               local _vn=$1 _i _n _v
+
+               _i=0
+               eval _n='${#'$_vn'[*]}'
+               while (( _i < _n )); do
+                       eval _v='${'$_vn'[_i]}'
+                       _v=$(printf '16#%x' $_v)
+                       eval $_vn'[_i++]=$_v'
+               done
+       }
+       eprint() {
+               printf "$@"
+       }
+       nprint() {
+               printf '%s' "$*"
+       }
+fi
+
+### BEGIN imported code {{{
+# Copyright (c) 2008
+#      Thorsten Glaser <tg@mirbsd.org>
+#
+# 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.
+
+# read a password without echoing
+askpass() {
+       set -o noglob
+       stty -echo
+       echo -n "$1 "
+       read resp
+       stty echo
+       set +o noglob
+       echo
+}
+
+# convert a string from UTF-8 or ISO-8859-1 to UTF-8
+str2utf8() {
+       local _s="$*" _z _c _i _hv _wc _n
+
+       _c=$(nprint "$_s" | hexdump -ve '1/1 "16#%x "')
+       _c="$_c 0"
+       str2arr _c
+       _s=
+       _z=0
+       _i=0
+       while (( _c[_i] )); do
+               (( _hv = _c[_i] ))
+               if (( (_hv < 16#C2) || (_hv >= 16#F0) )); then
+                       _n=1
+               elif (( _hv < 16#E0 )); then
+                       _n=2
+               else
+                       _n=3
+               fi
+               if (( _n > 1 )); then
+                       (( (_c[_i + 1] & 16#C0) == 16#80 )) || _n=1
+                       (( _hv == 16#E0 )) && \
+                           (( _c[_i + 1] < 16#A0 )) && _n=1
+               fi
+               if (( _n > 2 )); then
+                       (( (_c[_i + 2] & 16#C0) == 16#80 )) || _n=1
+                       (( _hv == 16#EF && _c[_i + 1] == 16#EF && \
+                           _c[_i + 2] > 16#BD )) && _n=1
+               fi
+               case $_n in
+               (1)
+                       if (( (_wc = _c[_i]) < 16#80 )); then
+                               (( _s[_z++] = _wc ))
+                       else
+                               (( _s[_z++] = 16#C0 | (_wc >> 6) ))
+                               (( _s[_z++] = 16#80 | (_wc & 16#3F) ))
+                       fi
+                       ;;
+               (2)
+                       (( _s[_z++] = _c[_i] ))
+                       (( _s[_z++] = _c[_i + 1] ))
+                       ;;
+               (3)
+                       (( _s[_z++] = _c[_i] ))
+                       (( _s[_z++] = _c[_i + 1] ))
+                       (( _s[_z++] = _c[_i + 2] ))
+                       ;;
+               esac
+               (( _i += _n ))
+       done
+       arr2hex _s
+       eprint "$(echo ${_s[*]} | sed -e 's/16#/\\x/g' -e 's/ //g')"
+}
+
+### END imported code }}}
+
+# create a temporary directory in /dev/shm (Linux tmpfs) or /tmp (otherwise)
+if [[ ! -d /dev/shm/. ]] || ! T=$(mktemp -d /dev/shm/genkey.XXXXXXXXXX); then
+       if ! T=$(mktemp -d /tmp/genkey.XXXXXXXXXX); then
+               echo >&2 Cannot create temporary directory.
+               exit 1
+       fi
+fi
+
+cleanup() {
+       trap - 0 1 2 3 13 15
+       # files to overwrite before removing
+       for wipefiles in resp wgetrc; do
+               for x in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
+                       echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+               done >"$T/$wipefiles"
+       done
+       sync
+       rm -rf "$T"
+       exit $1
+}
+
+# make sure the temporary files are removed if we are interrupted
+trap "cleanup 1" 1 2 3 13 15
+trap "cleanup 0" 0
+
+
+# import company key (delete first, just in case)
+ckid=3166EA4AF24EFF313803A739EEABC048D0620C0F
+gpg --batch --delete-key $ckid
+gpg --import --batch <<'EOF'
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.9 (MirBSD)
+
+mQMNBEqKwgoBGADCNH/pmQhli6LJYH174E3A8lSQmMnakZImLzvZfcITStmz722a
+BNqv9nmtvcNjEKlpUVUFUIEvycatLiAm8/81lPW9jtw0SrW1mqnAdqkUT6pfckS1
+ELcx5WDsQ2HfFe5bKFSyBpvvaE7T0QRlSksGBB0kgpfGPR21qtPXo4QaXNu/V/LI
+BNT6af82d8buy8oIZP4NXLMTyLYHJbwgWR7j79qnnRKdSnr1O2EG2FBDdFjEc7zG
+rotqT1qra94G+rE/1wqh+m5KeKaHVg5ROodHe5Wl4ZNyD0IMYXa64b+52j4/C4/C
+Dy2jrmTWMRmm1InqNMU/jEv7KLexsco5dS7TGcFssmp+3LyX53i0GWtbrU+Sw2aL
+Kkd+9cUabfBso+hZf5L3VMRc4nDTbLMyYa6mFsmXagenuMKXOrbQTvR14+wwaOhq
+h/LW9cVsgbxnUzPZ9+U7cPrbGSm57wcSnD9orfZ5LfQr3kuZ1VWFsCCFrWKsiAFm
+sCrh01vvEJ3lcgkCqr+VSptuNbB5KC41BAZjSfi32SyM1WJV6dSRG4mquV23dczj
+JznP7p8FBw0FtKmFJQeo5j2fn8zryUY1v1oMi5tmi67yq10pr7BUn74ruX+l6vUZ
+VkVYU46G8s69Zm4iVPYmUD7O6nMtwesMWPgnCtOvFti64HFPorX/fy4gBIRqCr71
+QoO116x+lVszIsNVZzgHZj1cGzU+OHnFCiFgkZg3WnS5COcscx7FliqQOg1wCb3C
+hL2StHUbl/qU2XvTJ1VkGrPc8qAvEbB0OJ8Fkq6sxuUHzb/hYTLgL1ywqzq2Zimm
+SPMn5a5/sfj/bDe7Ec8LQbHE24u51ysqlbz18JJThoEdC3Nj7kLYlkiEjU+96jj5
+tCMjoZ0A+dzFI25rK22IibXKL/iaAPI/P3EHgqm082k807TjfoSuAoL24Ra+UhK4
+L+axVFUKQ25S8jZWCfzrKnpyOEotMGkzgPPYQnUA3vu/4kf2eKhyAjTKXCWfp56t
+eeeYd5FFGmapFJ8AEQEAAbQSdGFyZW50IEdtYkggQ0Ega2V5iQNVBBMBAgA/BQJK
+isIKAhsvBQkPCZwABQsIBAkHBRUKCAMJAxYCAAIeAQIXgBkYaGtwOi8vcGdwa2V5
+cy5wY2EuZGZuLmRlAAoJEO6rwEjQYgwPzgoX/RUtv6M/87eP2Lj5qrv8WhdYzqZw
+OUh/II566flbgUY0VdCU79JY3+Ik8Kc3K23tnIJUWGMCCwgmZ4m6SP9zZxtVkIoK
+kYHy7x+pbEhORCYk/yJf/JyzRpMUaGVUsKD73G2KJF1v8a3U6RUfxDqW8kYFfwZo
+gFyEnUEGUjIYYDQcVX7oQswyrTVlGg2cjdarwOwN6A2qXdwmNdvQuz5H08lowVBs
+INt8vZBoLfuAWvyxybRZl7Yrl37/Yb7icDjOJwD0Jfu92OJekG/Qj7eLl9Ha8F+N
+bZ+lsY9Dck+t2pNW5hcXc8ShR6xGQB/szDaoMQ0u7/PLtGP8T7eIVS+FBOqNLanQ
+2ML5LNe4FMMsnPiaQ8aY2XHdQowmOTSPAPUqmHmWqF7sRNfmQdQK0Vy/aWvpJQcW
+Qtu/0y3nUYel5Oi/lVMCEP2XOW19hyWxPyM5iIGjZrC1qGobbf6pXxh8hB5eG/HC
+yyntpr9HcuRk+RtknY3TPmMkfVmu4UtTQomlygY+4Xljv70mC2D9F5i+YSq+9rYX
+FkF8b1pP1Blh3yHAhUhBhhHq6vR9oVtkraotOEwXtAQjMlTQt+Ugn3TGg1fQ02Pe
+WiO+ratNWglW1j+YORh2jA1vULtWwyLMYa0sMLe+rI6h1huUpfTdfOXWaLws/+Az
+GVDDwlLK1KZMWEti6RgLLkl/qRgHY40OEBYoG8mJYWrcbJ+TVexJHcVA/MNQARnO
+BmZyVbmAhqDTYIgEMM1+bLgpN7UgHk5vO9b9lJ/wooFBH25I2Vx0EKPxu8yOBg9r
+0kll7bT48ez5golV3MHohjxSSZ6JcwCQcYoc0u6GEuTn2rdRTxsidmjx/tvVIPku
+Nc8PotIfOnGzWaHghnnu7fv556XocfQO7w48zlyG632KAeodLj3OjwKpzNnRQ+wk
+D2z3JhUEscRFBVURbyc+5yEcHAT33kx+thUrrXd6+kHq6lbMaMl3QSpjEemygTQo
+4wBQF+0/W2exE5FX3pCwrYUmYe/ItsnAZKY5RA==
+=tDFz
+-----END PGP PUBLIC KEY BLOCK-----
+EOF
+
+
+# gpg2, as opposed to gnupg, doesn’t want to not use the agent
+vsn=$(gpg --version 2>&1 | head -n 1)
+isgpg2=0
+if [[ $vsn = 'gpg (GnuPG) 1.4.'* ]]; then
+       : okay
+elif [[ $vsn = 'gpg (GnuPG) 1.'* ]]; then
+       echo 'WARNING: Obsolete GnuPG 1.x version, you SHALL update!'
+elif [[ $vsn = 'gpg (GnuPG) 2.0.'* ]]; then
+       isgpg2=1
+else
+       echo "WARNING: Unknown GnuPG version '$vsn', tell tglase!"
+fi
+
+
+# show introduction
+echo "
+tarent solutions GmbH - PGP Key Generation
+==========================================
+
+[de] Ein PGP-Schlüsselpaar wird jetzt erstellt und der öffentliche Teil
+     an den tarent-Server übertragen, sodaß die Admins diesen signieren
+     und veröffentlichen können. Außerdem wird mit diesem Schlüssel der
+     Firmenschlüssel unterschrieben; diese Signatur wird ebenfalls ver-
+     öffentlicht. Dein Name und eMail-Adresse wird aus dem LDAP bezogen
+     und das LDAP-Paßwort auch für den privaten Schlüssel verwendet.
+
+[en] We will now generate a PGP keypair; the public key will be submit-
+     ted to the tarent server for being signed and published by the ad-
+     mins. The freshly generated key will also be used to sign and pub-
+     lish the company key. Your name and eMail address information will
+     be taken from the LDAP; the LDAP password will be used as password
+     for the secret key.
+"
+
+# request and record user/pass
+echo -n "LDAP login Username: "
+read un
+[[ -n $un ]] || cleanup 0
+askpass "LDAP login Password:"
+[[ -n $resp ]] || cleanup 0
+
+echo "login: $un" >>"$log"
+
+# create wgetrc(5) to use for HTTP Basic Authentication
+export WGETRC="$T/wgetrc"
+cat >"$WGETRC" <<EOF
+password = $resp
+user = $un
+EOF
+
+# create CA “bundle”
+cat >"$T/ca.cer" <<'EOF'
+-----BEGIN CERTIFICATE-----
+MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
+IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
+BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
+aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
+9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
+NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
+azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
+YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
+Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
+cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
+dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
+WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
+v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
+UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
+IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
+W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
+-----END CERTIFICATE-----
+EOF
+
+# get user information from LDAP
+x=$(wget -O "$T/ui" --ca-certificate="$T/ca.cer" -S https://tarentpgp.tarent.de/ui.cgi 2>&1 | \
+    if md5sum --version >/dev/null 2>&1; then
+       md5sum | sed 's/ .*$//'
+else
+       md5
+fi | sed 's/../16#& /g')
+(echo "got user info {"; sed 's/^/     /' <"$T/ui"; echo "}") >>"$log"
+
+# add entropy from CGIs to that pool (magic code ;) {{{
+if [[ ! -s ${tilde}/.gnupg/random_seed ]]; then
+       # create and fill if it didn't exist
+       :>"${tilde}"/.gnupg/random_seed
+       chmod 0600 "${tilde}"/.gnupg/random_seed
+       dd if=/dev/urandom of="${tilde}"/.gnupg/random_seed bs=600 count=1 2>/dev/null
+fi
+entropy=$(wget -O - -T 10 --ca-certificate="$T/ca.cer" \
+    https://call.mirbsd.org/lb.cgi?genkey.sh,1=$(hostname -f 2>/dev/null || hostname),seed=$RANDOM$RANDOM$RANDOM$RANDOM$RANDOM 2>/dev/null | \
+    hexdump -ve '1/1 "16#%x "')$x
+poolfile=$(hexdump -ve '1/1 "16#%x "' <"${tilde}"/.gnupg/random_seed)
+str2arr entropy
+str2arr poolfile
+(( n = ${#poolfile[*]} < ${#entropy[*]} ? ${#entropy[*]} : ${#poolfile[*]} ))
+i=0
+# XOR poolfile with new entropy (from CGIs)
+while (( i < n )); do
+       (( poolfile[i % ${#poolfile[*]}] ^= entropy[i % ${#entropy[*]}] ))
+       let i++
+done
+# write back into the pool file
+arr2hex poolfile
+eprint "$(echo ${poolfile[*]} | sed -e 's/16#/\\x/g' -e 's/ //g')" | \
+    dd of="${tilde}"/.gnupg/random_seed conv=notrunc 2>/dev/null
+# }}} end of magic code block ;)
+
+# check the user information
+status=bad
+i_name=
+i_mail=
+i_comm=
+while read key value; do
+       case x$key in
+       (xstatus)
+               [[ $value = ok ]] || break
+               [[ $status = bad ]] && status=good
+               ;;
+       (xname|xmail|xcomm)
+               eval i_$key=\$value
+               ;;
+       (x)
+               ;;
+       (*)
+               echo >&2 "Invalid server response '$key $value'"
+               status=invalid
+               ;;
+       esac
+done <"$T/ui"
+if [[ $status != good || -z $i_name || -z $i_mail ]]; then
+       echo >&2 "Cannot process further (status: $status)"
+       [[ $status = bad ]] && echo >&2 Maybe wrong password.
+       cleanup 1
+fi
+
+# create response file for gpg
+# NOTE:        Key-Length can go up to 8192 (not more!) but please no lower
+#      than 2048 (although more than 4096 may be incompatible *AND*
+#      TERRIBLY SLOW)
+cat >"$T/resp" <<-EOF
+       %echo Generating the key for $i_name ($i_mail) $i_comm
+       Key-Type: RSA
+       Key-Length: 3072
+       Key-Usage: auth,encrypt,sign
+       Passphrase: $(str2utf8 "$resp")
+       Name-Real: $(str2utf8 "$i_name")
+       ${i_comm:+Name-Comment: $(str2utf8 "$i_comm")}
+       Name-Email: $(str2utf8 "$i_mail")
+       Expire-Date: 3y
+       Preferences: H8 H3 S8 S4 Z2 Z0 H9 H10 S9 S7
+       Revoker: 1:$ckid
+       Keyserver: hkp://tarentpgp.tarent.de
+       %commit
+       %echo done
+EOF
+
+# really generate the key
+echo
+(gpg --no-use-agent --batch --gen-key "$T/resp"; echo $? >"$T/rc") 2>&1 | \
+    tee "$T/gen.out"
+echo
+(echo "create key {"; sed 's/^/        /' <"$T/gen.out"; echo "}") >>"$log"
+# check for error exit
+if (( $(<"$T/rc") > 0 )); then
+       echo >&2 Key generation failed.
+       cleanup 1
+fi
+# scan the gpg log for keyid of keypair just created
+pkid=$(sed -n \
+    's/^gpg: key \([0-9A-F]*\) marked as ultimately trusted.*$/\1/p' \
+    "$T/gen.out")
+if [[ $pkid != +([0-9A-F]) ]] || ! gpg -K $pkid; then
+       echo >&2 '┌─────────────────────────────────────────────────────────┐'
+       echo >&2 '│ Finding the key failed. YOU CAN USE THE KEY, BUT YOU    │'
+       echo >&2 '│ *MUST* CONTACT THE ADMINS with this error message.      │'
+       echo >&2 '│ Kann den neuen Schlüssel nicht finden. DU KANNST DIESES │'
+       echo >&2 '│ SCHLÜSSELPAAR BENUTZEN, ABER DU *MUẞT* DIE ADMINS mit   │'
+       echo >&2 '│ dieser Fehlernachricht KONTAKTIEREN.                    │'
+       echo >&2 '└─────────────────────────────────────────────────────────┘'
+       echo
+       echo >&2 Cannot find the key just generated.
+       cleanup 1
+fi
+
+# apply preference settings to our newly generated key
+if [[ $isgpg2 = 0 ]]; then
+       usepw="$nl$(str2utf8 "$resp")"
+else
+       usepw=""
+fi
+gpg --no-use-agent -q -u $pkid --command-fd 4 --edit-key $pkid \
+    >>"$T/edit.log" 2>&1 4<<-EOF
+       notation preferred-email-encoding@pgp.com=partitioned,pgpmime$usepw
+       trust
+       5
+       y
+       uid 1
+       primary$usepw
+       adduid
+       $(str2utf8 "$i_name")
+       $(str2utf8 "$un")@info.tarent.de
+       Jabber/XMPP$usepw
+       uid 1
+       uid 2
+       setpref H8 H3 S8 S4 Z2 Z0 Z1 H9 H10 S9 S7
+       y$usepw
+       keyserver hkp://tarentpgp.tarent.de$usepw
+       save
+EOF
+echo "=> $?" >>"$T/edit.log"
+
+# sign the company key with that key
+# XXX if the key has >1 UID, there must be an extra line
+#      y
+# after the line saying "tsign"!
+gpg --no-ask-cert-level --no-expert --no-use-agent -q -u $pkid --command-fd 4 --edit-key $ckid \
+    >>"$T/edit.log" 2>&1 4<<-EOF
+       tsign
+       2
+       2
+
+       y$usepw
+       trust
+       4
+       save
+EOF
+echo "=> $?" >>"$T/edit.log"
+sed 's/^/│/' "$T/edit.log" >>"$log"
+
+if [[ $GENKEY_DONTRUN = aye ]]; then
+       echo >&2 Meh, okay. $vsn
+       gpg -K
+       exit 0
+fi
+
+# export our own public key and the signed company key into a keyring
+rc=0
+gpg --export-options no-export-attributes,export-clean \
+    --export $ckid >"$T/exp.c" 2>>"$log" || rc=$?
+gpg --export-options no-export-attributes,export-clean,export-minimal \
+    --export $pkid >"$T/exp.p" 2>>"$log" || rc=$?
+rm -f "$T/exp.kr"
+GNUPGHOME="$T/.gnupg" gpg --no-default-keyring --primary-keyring "$T/exp.kr" \
+    --import "$T/exp.c" 2>>"$log" || rc=$?
+GNUPGHOME="$T/.gnupg" gpg --no-default-keyring --primary-keyring "$T/exp.kr" \
+    --import "$T/exp.p" 2>>"$log" || rc=$?
+echo >>"$log"
+if (( rc )); then
+       (echo "export error $rc"; gpg -k $pkid; echo "=> $?") >>"$log"
+       echo >&2 '┌────────────────────────────────────────────────────────┐'
+       echo >&2 '│ Exporting the key failed. YOU CAN USE THE KEY, BUT YOU │'
+       echo >&2 '│ *MUST* CONTACT THE ADMINS with this error message.     │'
+       echo >&2 '│ Export des Schlüssels fehlgeschlagen. DU KANNST DIESES │'
+       echo >&2 '│ SCHLÜSSELPAAR BENUTZEN, ABER DU *MUẞT* DIE ADMINS mit  │'
+       echo >&2 '│ dieser Fehlernachricht KONTAKTIEREN.                   │'
+       echo >&2 '└────────────────────────────────────────────────────────┘'
+       echo
+       gpg -k $pkid || echo gpg ERROR -k: $?
+       cleanup 0
+fi
+echo "export ok" >>"$log"
+GNUPGHOME="$T/.gnupg" gpg --no-default-keyring --primary-keyring "$T/exp.kr" \
+    --list-sigs >>"$log" 2>&1
+
+# upload the exported keyring
+wget -O "$T/upload" \
+    --header="Content-type: application/octet-stream" \
+    --post-file="$T/exp.kr" \
+    --ca-certificate="$T/ca.cer" \
+    https://tarentpgp.tarent.de/fu.cgi >"$T/upload.log" 2>&1
+(echo "upload keyring {"; sed 's/^/[   /' <"$T/upload.log"; \
+    sed 's/^/] /' <"$T/upload"; echo "}") >>"$log"
+echo
+if [[ $(head -1 "$T/upload") != "upload ok" ]]; then
+       echo >&2 '┌────────────────────────────────────────────────────────┐'
+       echo >&2 '│ Uploading the key failed. YOU CAN USE THE KEY, BUT YOU │'
+       echo >&2 '│ *MUST* CONTACT THE ADMINS with this error message.     │'
+       echo >&2 '│ Upload des Schlüssels fehlgeschlagen. DU KANNST DIESES │'
+       echo >&2 '│ SCHLÜSSELPAAR BENUTZEN, ABER DU *MUẞT* DIE ADMINS mit  │'
+       echo >&2 '│ dieser Fehlernachricht KONTAKTIEREN.                   │'
+       echo >&2 '└────────────────────────────────────────────────────────┘'
+else
+       cat >&2 <<'EOF'
+┌─────────────────────────────────────────┐
+│ Key generation finished with no errors. │
+│ Schlüsselerzeugung fehlerfrei erledigt. │
+└─────────────────────────────────────────┘
+
+╔═════════════════════════════════════════════════════════════════════╗
+║ You are responsible for backing up your PGP secret key BY YOURSELF! ║
+║ Du mußt SELBER für Sicherungskopiën des privaten Schlüssels sorgen! ║
+╚═════════════════════════════════════════════════════════════════════╝
+EOF
+fi
+(echo "finished:"; gpg -k $pkid | sed 's/^/|   /'; echo) >>"$log"
+echo >&2
+gpg -k $pkid || echo gpg ERROR -k: $?
+cleanup 0
diff --git a/bash-ksh/profile-funcs b/bash-ksh/profile-funcs
new file mode 100644 (file)
index 0000000..6bae04e
--- /dev/null
@@ -0,0 +1,46 @@
+# Debian Bug Tracking System
+bts() {
+       if [[ $1 = +([0-9]) ]]; then
+               ${BROWSER:-lynx} "https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=$1"
+       elif [[ $1 = lp:+([0-9]) ]]; then
+               ${BROWSER:-lynx} "https://bugs.launchpad.net/bugs/${1#lp:}"
+       else
+               ${BROWSER:-lynx} "http://bugs.debian.org/${1%%_*}"
+       fi
+}
+# Debian Package Tracking System, QA, buildd logs Debian, buildd logs D-Ports
+pts() {
+       local p=${1%%_*} not_slash_bksls=$'[!/\t\n\f\r ]' r=''
+
+       if [[ $p = src:* ]]; then
+               ${BROWSER:-lynx} "https://packages.debian.org/source/sid/${p#src:}"
+       elif [[ $p = qa:lib${not_slash_bksls}${not_slash_bksls}* ]]; then
+               ${BROWSER:-lynx} "http://packages.qa.debian.org/${p:3:4}/${p#qa:}.html"
+       elif [[ $p = qa:* ]]; then
+               ${BROWSER:-lynx} "http://packages.qa.debian.org/${p:3:1}/${p#qa:}.html"
+       elif [[ $p = bd:* ]]; then
+               ${BROWSER:-lynx} "https://buildd.debian.org/status/package.php?p=${p#bd:}"
+       elif [[ $p = bp:* ]]; then
+               ${BROWSER:-lynx} "http://buildd.debian-ports.org/status/package.php?p=${p#bp:}"
+       elif [[ $p = f:* ]]; then
+               ${BROWSER:-lynx} "https://packages.debian.org/search?searchon=contents&keywords=${1#f:}&mode=path&suite=unstable&arch=any"
+       elif [[ $p = p:* ]]; then
+               ${BROWSER:-lynx} "https://packages.debian.org/${p#p:}"
+       elif [[ $p = ap:* ]]; then
+               ${BROWSER:-lynx} "http://archive.debian.net/${p#ap:}"
+       elif [[ $p = up:* ]]; then
+               ${BROWSER:-lynx} "http://packages.ubuntu.com/${p#up:}"
+       elif [[ $p = ab:* ]]; then
+               ${BROWSER:-lynx} "http://snapshot.debian.org/binary/${p#ab:}/"
+       elif [[ $p = as:* ]]; then
+               if [[ $1 = *_* ]]; then
+                       r=${1#*_}
+                       r=${r%%_*}/
+               fi
+               ${BROWSER:-lynx} "http://snapshot.debian.org/package/${p#as:}/$r"
+       else
+               ${BROWSER:-lynx} "https://packages.debian.org/sid/$p"
+       fi
+}
+
+alias doch='sudo mksh -c "$(fc -ln -1)"'
diff --git a/bash/0-README b/bash/0-README
new file mode 100644 (file)
index 0000000..9bb380c
--- /dev/null
@@ -0,0 +1,4 @@
+Shell snippets that require GNU bash.
+
+More examples in the ’net:
+• https://github.com/izabera/libash
similarity index 100%
rename from LICENSE
rename to bash/bashcheck/LICENSE
similarity index 100%
rename from README.md
rename to bash/bashcheck/README.md
similarity index 100%
rename from bashcheck
rename to bash/bashcheck/bashcheck
diff --git a/bash/clock b/bash/clock
new file mode 100644 (file)
index 0000000..62acb81
--- /dev/null
@@ -0,0 +1,223 @@
+#!/bin/bash
+#-
+# Copyright © 2009, 2013
+#      Dominik George <nik@naturalnet.de>
+#      Felix Falk <felix@b9d.de>
+#
+# 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.
+
+# Config
+
+CONFIG_DIGITAL=true
+
+# Check dependencies
+if [ ! -x $(which bc) ]; then
+       echo "bc not found, install bc!"
+
+       exit 1
+fi
+
+if [ ! -x $(which tput) ]; then
+
+       echo "tput not found, install ncurses!"
+       exit 1
+fi
+
+# Definitions
+PI=$(echo "4*a(1)" | bc -l)
+
+# Library
+function deg2rad {
+       local x=$1
+       echo $(echo "${x}/180*${PI}" | bc -l)
+
+}
+
+function sine {
+       local x=$(deg2rad $1)
+
+       echo $(echo "s(${x})" | bc -l)
+}
+
+function cosine {
+       local x=$(deg2rad $1)
+
+       echo $(echo "c(${x})" | bc -l)
+}
+
+function round {
+       local x=$1
+       local pre=$(echo ${x} | cut -d. -f1)
+
+       local post=$(echo ${x} | cut -d. -f2)
+
+       local postone=${post:1:1}
+
+       if [ "${pre}" = "-" ]; then
+
+               pre=$(echo ${pre} | sed "s/^-\$/0/")
+
+       fi
+
+       if [ -n ${postone} ]; then
+               echo ${pre}
+
+       else
+               echo $((pre + 1))
+       fi
+
+}
+
+function drawpoint {
+       local deg=$1
+       local percent=$2
+
+       local char=$3
+       local mirror=$4
+
+       radx=$(echo "${RADIUSX} * ${percent} / 100" | bc)
+
+       rady=$(echo "${RADIUSY} * ${percent} / 100" | bc)
+
+       xoff=$(round $(echo "$(sine ${deg}) * ${radx}" | bc -l))
+
+       yoff=$(round $(echo "$(cosine ${deg}) * ${rady}" | bc -l))
+
+       tput cup $((MIDDLEY + yoff)) $((MIDDLEX + xoff))
+
+       echo -n ${char}
+
+       if [ ${mirror} = true ]; then
+
+               tput cup $((MIDDLEY - yoff)) $((MIDDLEX + xoff))
+
+               echo -n ${char}
+               tput cup $((MIDDLEY + yoff)) $((MIDDLEX - xoff))
+
+               echo -n ${char}
+               tput cup $((MIDDLEY - yoff)) $((MIDDLEX - xoff))
+
+               echo -n ${char}
+       fi
+}
+
+# Clear terminal
+clear
+
+# Get terminal caps
+
+COLS=$(tput cols)
+LINES=$(tput lines)
+
+echo ${COLS}
+
+echo ${LINES}
+
+# Determine clock size from terminal size
+if [ ${COLS} -ge $((LINES * 2)) ]; then
+
+       HEIGHT=$((LINES - 2))
+       WIDTH=$((HEIGHT * 2))
+
+else
+       echo abcdefghijklmnopqrstuvwxyz
+       WIDTH=$((COLS - 2))
+       HEIGHT=$((WIDTH / 2))
+
+fi
+
+# Determine clock position
+TOP=$(((LINES - HEIGHT)/2))
+
+LEFT=$(((COLS - WIDTH)/2))
+MIDDLEX=$((COLS/2))
+
+MIDDLEY=$((LINES/2))
+RADIUSX=$((MIDDLEX - LEFT))
+
+RADIUSY=$((MIDDLEY - TOP))
+
+# Print digital clock if requested
+if [ ${CONFIG_DIGITAL} = true ]; then
+
+       tput cup $((MIDDLEY + (HEIGHT / 4))) $((MIDDLEX - 4))
+
+       date "+%H:%M:%S"
+fi
+
+# Draw border
+for deg in $(seq 0 1 90); do
+
+       if [ ${deg} -ge 0 -a ${deg} -le 5 -o ${deg} -ge 25 -a ${deg} -le 35 -o ${deg} -ge 55 -a ${deg} -le 65 -o ${deg} -ge 83 -a ${deg} -le 90 ]; then
+
+               char=x
+       else
+               char=.
+       fi
+
+       drawpoint ${deg} 100 ${char} true
+
+done
+
+# Get time
+hour=$(date "+%H" | sed "s/^0//")
+
+min=$(date "+%M" | sed "s/^0//")
+sec=$(date "+%S" | sed "s/^0//")
+
+# Hours
+for percent in $(seq 0 1 60); do
+       deg=$((180 - (((hour * 60 + min) % 720) / 2)))
+
+       if [ ${deg} -lt 0 ]; then
+               deg=$((360 + deg))
+
+       fi
+       drawpoint ${deg} ${percent} x false
+done
+
+# Minutes
+for percent in $(seq 0 1 85); do
+
+       deg=$((180 - (min * 6)))
+       if [ ${deg} -lt 0 ]; then
+
+               deg=$((360 + deg))
+       fi
+       drawpoint ${deg} ${percent} + false
+
+done
+
+# Seconds
+for percent in $(seq 0 1 85); do
+
+       deg=$((180 - (sec * 6)))
+       if [ ${deg} -lt 0 ]; then
+
+               deg=$((360 + deg))
+       fi
+       drawpoint ${deg} ${percent} . false
+
+done
+
+# Draw center
+tput cup ${MIDDLEY} ${MIDDLEX}
+echo X
+
+# Set cursor to bottom left corner
+tput cup ${LINES} 0
+
+exit 0
diff --git a/ksh/0-README b/ksh/0-README
new file mode 100644 (file)
index 0000000..9e127e2
--- /dev/null
@@ -0,0 +1,3 @@
+Shell snippets that require a modern Korn Shell (AT&T ksh93, mksh).
+Some may work with pdksh.
+Even fewer may work with AT&T ksh88.
diff --git a/ksh/permute b/ksh/permute
new file mode 100644 (file)
index 0000000..b5b18ea
--- /dev/null
@@ -0,0 +1,58 @@
+#!/bin/mksh
+# $MirOS: contrib/code/Snippets/permute,v 1.4 2008/05/03 01:09:24 tg Exp $
+#-
+# Copyright (c) 2006
+#      Thorsten Glaser <tg@mirbsd.de>
+#
+# 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.
+#-
+# Achtung: dieses Skript gibt n! Zeilen (n = $#) aus! (n-Fakultät)
+
+function permute
+{
+       integer i=0
+       integer num
+
+       set -A all $*
+       num=${#all[*]}
+       if (( num == 2 )); then
+               print $1 $2
+               print $2 $1
+               return 0
+       fi
+       if (( num == 1 )); then
+               print $1
+               return 0
+       fi
+       while (( i < num )); do
+               local x= y sp=
+               integer j=0
+               while (( j < num )); do
+                       if (( j == i )); then
+                               y=${all[j]}
+                       else
+                               x=$x$sp${all[j]}
+                               sp=" "
+                       fi
+                       let j++
+               done
+               permute $x | sed "s\ 1^\ 1$y \ 1"
+               let i++
+       done
+}
+
+(( $# > 0 )) || return 0
+permute $*
diff --git a/ksh/prompt-tg b/ksh/prompt-tg
new file mode 100644 (file)
index 0000000..0a0645f
--- /dev/null
@@ -0,0 +1,37 @@
+# $MirOS: src/bin/mksh/dot.mkshrc,v 1.68 2011/11/25 23:58:04 tg Exp $
+#-
+# Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011
+#      Thorsten Glaser <tg@mirbsd.org>
+#
+# 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.
+
+: ${USER_ID:=$(ulimit -c 0; id -u)}
+: ${HOSTNAME:=$(ulimit -c 0; hostname -s 2>/dev/null)}
+[[ $HOSTNAME = @(localhost|*([  ])) ]] && \
+    HOSTNAME=$(ulimit -c 0; hostname 2>/dev/null)
+: ${HOSTNAME:=nil}; if (( USER_ID )); then PS1='$'; else PS1='#'; fi
+
+function precmd {
+       typeset e=$?
+
+       (( e )) && print -n "$e|"
+}
+PS1='\ 1\r$(precmd)${USER:=$(ulimit -c 0; id -un 2>/dev/null || echo \?
+       )}@${HOSTNAME%%.*}:$(typeset d=${PWD:-?} n p=~; [[ $p = ?(*/) ]] || {
+               [[ $d = "$p"* ]] && d=\~${d#"$p"}
+       }; (( ${#d} > (n = (COLUMNS/3 < 7 ? 7 : COLUMNS/3)) )) && {
+               while (( n >= 5 )); do d=${d#?????}; (( n -= 5 )); done; p=...
+       } || p=; print -nr -- "$p$d") '"$PS1 "
diff --git a/ksh/svg-path-abs2rel b/ksh/svg-path-abs2rel
new file mode 100644 (file)
index 0000000..5710837
--- /dev/null
@@ -0,0 +1,77 @@
+# $Id: svg-path-abs2rel 2081 2011-06-09 20:21:16Z tglase $
+#-
+# Copyright © 2010
+#      Thorsten Glaser <t.glaser@tarent.de>
+# Licenced under the AGPLv3
+
+eval $(cat)
+set -A in -- $d
+out=
+i=0
+
+function iscoor {
+       [[ $1 = @([1-9])*([0-9])?(.+([0-9])),@([1-9])*([0-9])?(.+([0-9])) ]]
+}
+curx=0
+cury=0
+basex=-245.93941
+basey=-435.44425
+function fixbc {
+       local x=$(bc)
+       if [[ $x = .* ]]; then
+               print 0$x
+       elif [[ $x = -.* ]]; then
+               print -- -0${x#-}
+       else
+               print -- $x
+       fi
+}
+function trans {
+       local px py
+
+       nx=${1%,*}
+       ny=${1#*,}
+       px=$(print -- "$nx+$basex-$curx" | fixbc)
+       py=$(print -- "$ny+$basey-$cury" | fixbc)
+       pos=$px,$py
+}
+function transet {
+       trans "$1"
+       curx=$(print -- "$nx+$basex" | fixbc)
+       cury=$(print -- "$ny+$basey" | fixbc)
+}
+
+while (( i < ${#in[*]} )); do
+       if (( !i )); then
+               [[ ${in[0]} = M ]] || exit 1
+               iscoor "${in[1]}" || exit 1
+               transet "${in[1]}"
+               out="M $pos"
+               i=2
+               continue
+       fi
+       case ${in[i]} {
+       ([Zz])  out="$out ${in[i++]}" ;;
+       (M)     iscoor "${in[i+1]}" || exit 1
+               transet "${in[i+1]}"
+               out="$out m $pos"
+               let i+=2 ;;
+       (L)     iscoor "${in[i+1]}" || exit 1
+               transet "${in[i+1]}"
+               out="$out l $pos"
+               let i+=2 ;;
+       (C)     out="$out c"
+               iscoor "${in[i+1]}" || exit 1
+               iscoor "${in[i+2]}" || exit 1
+               iscoor "${in[i+3]}" || exit 1
+               trans "${in[i+1]}"
+               out="$out $pos"
+               trans "${in[i+2]}"
+               out="$out $pos"
+               transet "${in[i+3]}"
+               out="$out $pos"
+               let i+=4 ;;
+       (*)     exit 1 ;;
+       }
+done
+print "       d=\"$out\""
diff --git a/ksh93/0-README b/ksh93/0-README
new file mode 100644 (file)
index 0000000..725b8a5
--- /dev/null
@@ -0,0 +1 @@
+Shell snippets that require AT&T ksh93.
diff --git a/mksh/0-README b/mksh/0-README
new file mode 100644 (file)
index 0000000..33a45e4
--- /dev/null
@@ -0,0 +1,6 @@
+Shell snippets that require mksh.
+
+See also:
+
+https://www.mirbsd.org/kwalletcli.htm
+       Three useful mksh scripts included.
diff --git a/mksh/_remfor b/mksh/_remfor
new file mode 100644 (file)
index 0000000..72b83c0
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/mksh
+
+local _i _fm=$2 _h=$1
+shift; shift
+
+trap "" INT
+ssh "$_h" find "${_fm@Q}" -type f -print0 | sort -R "" | \
+    while IFS= read -r -d "" _i; do
+       print -r "◖${_i}◗"
+       ssh -n "$_h" cat "${_i@Q}" | "$@"
+done
diff --git a/mksh/annex.cgi b/mksh/annex.cgi
new file mode 100644 (file)
index 0000000..9339f17
--- /dev/null
@@ -0,0 +1,211 @@
+#!/bin/mksh
+# $MirOS: src/share/misc/licence.template,v 1.28 2008/11/14 15:33:44 tg Rel $
+#-
+# Copyright © 2012
+#      Thorsten Glaser <tg@mirbsd.org>
+#
+# 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.
+
+export LC_ALL=C.UTF-8
+unset LANGUAGE
+
+[[ $1 = -s ]] || if [[ $REQUEST_METHOD = GET && $HTTPS = on && \
+    -n $REMOTE_USER && $REMOTE_USER = "$AUTHENTICATE_UID" ]]; then
+       [[ $PATH_INFO = /* ]] && \
+           exec sudo -u "$REMOTE_USER" "$(realpath "$0")" -s "$PATH_INFO" \
+           "$QUERY_STRING"
+       print Status: 301 Redirect
+       print Location: $SCRIPT_NAME/
+       print
+       print Please add the trailing slash after the .cgi
+       exit 1
+else
+       print Content-type: text/plain\; charset=UTF-8
+       print
+       print Error in request arguments.
+       exit 1
+fi
+
+me=$(realpath "$0")
+cd $(dirname "$(dirname "$me")")
+basedir=$(realpath .)
+shift
+pi=$1
+QUERY_STRING=$2
+
+function qsdecode {
+       local _x=$1
+
+       _x=${_x//\\/\\\\}
+       print -- "${_x//[%]/\\x}"
+}
+
+function qsparse {
+       local _saveIFS _q _s _k _v _a
+
+       # no 'key=value' at all: make q be everything
+       if [[ $QUERY_STRING != *=* ]]; then
+               qs_q=$(qsdecode "$QUERY_STRING")
+               qskeys=(q)
+               return
+       fi
+
+       _saveIFS=$IFS
+       IFS=';&'
+       set -A _q -- $QUERY_STRING
+       IFS=$_saveIFS
+
+       set -A qskeys
+       for _s in "${_q[@]}"; do
+               # skip not 'key=value' parts
+               [[ $_s = *=* ]] || continue
+
+               _k=$(qsdecode "${_s%%=*}")
+               _v=$(qsdecode "${_s#*=}")
+
+               if [[ $_k = *'[]' ]]; then
+                       _a=1
+                       _k=${_k%??}
+               else
+                       _a=0
+               fi
+
+               # limit keys to alphanumeric and underscore
+               # as they must fit as part of an mksh variable
+               [[ $_k = +([0-9A-Za-z_]) ]] || continue
+
+               if (( _a )); then
+                       in_array qskeys $_k || eval set -A qs_$k
+                       nameref _A=qs_$_k
+                       _A+=("$_v")
+               else
+                       # eval is evil, but… as long as we don’t have
+                       # associative arrays in mksh… this works
+                       eval qs_$_k=\$_v
+               fi
+               in_array qskeys $_k || qskeys+=("$_k")
+       done
+}
+
+function in_array {
+       nameref _arr=$1
+       local _val=$2 _x
+
+       for _x in "${_arr[@]}"; do
+               [[ $_x = "$_val" ]] && return 0
+       done
+       return 1
+}
+
+qsparse
+
+pi=${pi##*(/)}
+pi=${pi%%*(/)}
+
+function e403 {
+       print Status: 403 Forbidden
+       print Content-type: text/plain\; charset=UTF-8
+       print
+       print Du kumms hier nisch rein!
+       exit 1
+}
+
+if [[ -n $pi ]]; then
+       i=$(realpath "$pi")
+       [[ -n $i && $i = "$basedir"/* ]] || e403
+fi
+
+[[ -e ${pi:-.} && -r ${pi:-.} ]] || e403
+
+[[ -n $pi ]] && if [[ ! -d $pi ]]; then
+       if in_array qskeys type; then
+               ct=$qs_type
+       else
+               ct=$(file -biL "$pi")
+       fi
+       print -r Content-type: "$ct"
+       print
+       cat "$pi"
+       exit 0
+fi
+
+[[ -n $pi ]] && cd "$pi"
+set -A dirs
+set -A files
+for i in *; do
+       [[ -e $i && -r $i ]] || continue
+       if [[ -d $i ]]; then
+               dirs+=("$i")
+       else
+               files+=("$i")
+       fi
+done
+
+function h {
+       typeset x="$*"
+
+       x=${x//'&'/"&amp;"}
+       x=${x//'<'/"&lt;"}
+       x=${x//'>'/"&gt;"}
+
+       print -r -- "$x"
+}
+
+cat <<EOF
+Content-type: text/html; charset=UTF-8
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+ <title>$pi/ – Index for nik’s Annex</title>
+</head><body>
+<h1>Index of $pi/ in nik’s Annex</h1>
+EOF
+
+if (( !${#dirs[*]} && !${#files[*]} )); then
+       print '<p>No content found.</p>'
+else
+       print '<table width="100%" border="0">'
+       for i in "${dirs[@]}"; do
+               print "<tr><td align=\"right\" style=\"width:20;\">[DIR]</td><td><a href=\"$(h "$i")/\">$(h "$i")/</a></td></tr>"
+       done
+       for i in "${files[@]}"; do
+               sz=$(stat -Lc '%s' "$i")
+               if (( ${#sz} < 10 )); then
+                       if (( sz >= 1048576 )); then
+                               if (( sz > 210000000 )); then
+                                       sz=$(( (sz + 524288) / 1048576)) MiB
+                               else
+                                       (( sz = (sz * 10 + 524288) / 1048576 ))
+                                       x=${sz%?}
+                                       sz=$x.${sz#$x} MiB
+                               fi
+                       elif (( sz >= 1024 )); then
+                               sz=$(( (sz * 100 + 512) / 1024))
+                               x=${sz%??}
+                               sz=$x.${sz#$x} KiB
+                       fi
+               else
+                       sz=$(bc -q <<<$'scale=2\n'"$sz/1073741824") GiB
+               fi
+               print "<tr><td align=\"right\" style=\"width:20;\">$sz</td><td><a href=\"$(h "$i")\">$(h "$i")</a> (<a href=\"$(h "$i")?type=application/octet-stream\">download</a>)</td></tr>"
+       done
+       print '</table>'
+fi
+
+print '</body></html>'
+exit 0
diff --git a/mksh/any2utf8 b/mksh/any2utf8
new file mode 100644 (file)
index 0000000..493e5a1
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/mksh
+# $Id: any2utf8.sh 624 2009-09-03 09:47:20Z tglase $
+#-
+# Derived from code with the following licence:
+# Copyright (c) 2008
+#      Thorsten Glaser <tg@mirbsd.org>
+#
+# 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.
+#
+# The author reserves the right to steward the OPTU encoding forms.
+
+x=${KSH_VERSION}
+x=${x##*MIRBSD KSH R}
+x=${x%% *}
+if (( x < 38 )); then
+       print -u2 Error: your mksh is too old, you need R38 or up.
+       exit 1
+fi
+
+set -U
+
+set -A vistable \
+       0x20AC 0x278A 0x201A 0x0192 0x201E 0x2026 0x2020 0x2021 \
+       0x02C6 0x2030 0x0160 0x2039 0x0152 0x278B 0x017D 0x278C \
+       0x278D 0x2018 0x2019 0x201C 0x201D 0x2022 0x2013 0x2014 \
+       0x02DC 0x2122 0x0161 0x203A 0x0153 0x278E 0x017E 0x0178
+
+typeset -i1 wc
+typeset -i lpos
+
+while IFS= read -r line; do
+       lpos=0
+       outs=
+       while (( lpos < ${#line} )); do
+               wc=1#${line:(lpos++):1}
+               (( (wc & 0xFF80) == 0xEF80 )) && (( wc &= 0x00FF ))
+               (( wc > 0x7F && wc < 0xA0 )) && (( wc = vistable[wc & 0x1F] ))
+               outs=$outs${wc#1#}
+       done
+       print -r -- "$outs"
+done
+exit 0
diff --git a/mksh/assockit.ksh b/mksh/assockit.ksh
new file mode 100644 (file)
index 0000000..15be7aa
--- /dev/null
@@ -0,0 +1,504 @@
+# $MirOS: contrib/hosted/tg/assockit.ksh,v 1.4 2013/04/26 17:20:33 tg Exp $
+#-
+# Copyright © 2011, 2013
+#      Thorsten “mirabilos” Glaser <tg@mirbsd.org>
+# Copyright © 2013
+#      Thorsten Glaser <t.glaser@tarent.de>
+#
+# 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.
+#-
+# Associative, multi-dimensional arrays in Pure mksh™ (no exec!)
+#-
+# An item in an assockit array has the following properties:
+# – the base-identifier of the shell array it’s in
+# – the index into the shell array it’s in
+# – an entry called flags
+#   • data type: ASSO_{VAL,STR,INT,REAL,BOOL,NULL,AIDX,AASS}
+# – an entry called key
+# – an entry called value, unless NULL/AIDX/AASS
+# Shell array paths are constructed like this:
+# { 'foo': [ { 'baz': 123 } ] } named 'test' becomes:
+# ‣ root-level lookup
+#   – Asso__f[16#AE0C1A48] = ASSO_AASS | ASSO_ISSET|ASSO_ALLOC
+#   – Asso__k[16#AE0C1A48] = 'test' (hash: AE0C1A48)
+# ‣ Asso_AE0C1A48 = top-level
+#   – Asso_AE0C1A48_f[16#BF959A6E] = ASSO_AIDX | ASSO_ISSET|ASSO_ALLOC
+#   – Asso_AE0C1A48_k[16#BF959A6E] = 'foo' (hash: BF959A6E)
+# ‣ Asso_AE0C1A48BF959A6E = next-level
+#   – Asso_AE0C1A48BF959A6E_f[0] = ASSO_AASS | ASSO_ISSET|ASSO_ALLOC
+#   – Asso_AE0C1A48BF959A6E_k[0] = 0
+# ‣ Asso_AE0C1A48BF959A6E00000000 = last-level (below FOO)
+#   – FOO_f[16#57F1BA9A] = ASSO_INT | ASSO_ISSET|ASSO_ALLOC
+#   – FOO_k[16#57F1BA9A] = 'baz' (hash: 57F1BA9A)
+#   – FOO_v[16#57F1BA9A] = 123
+# When assigning a value, by default, the type of the
+# intermediates is set to ASSO_AASS unless it already
+# is ASSO_AIDX; the type of the terminals is ASSO_VAL
+# unless it’s ASSO_{STR,INT,REAL,BOOL,NULL} before.
+
+# check prerequisites
+asso_x=${KSH_VERSION#????MIRBSD KSH R}
+asso_x=${asso_x%% *}
+if [[ $asso_x != +([0-9]) ]] || (( asso_x < 40 )); then
+       print -u2 'assockit.ksh: need at least mksh R40'
+       exit 1
+fi
+
+# set up variables
+typeset -Uui16 -Z11 asso_h=0 asso_f=0 asso_k=0
+typeset asso_b=""
+set -A asso_y
+set -A Asso__f
+set -A Asso__k
+
+# define constants
+typeset -Uui16 -Z11 -r ASSO_VAL=2#000          # type: any Korn Shell scalar
+typeset -Uui16 -Z11 -r ASSO_STR=2#001          # type: string
+typeset -Uui16 -Z11 -r ASSO_INT=2#010          # type: integral
+typeset -Uui16 -Z11 -r ASSO_REAL=2#011         # type: JSON float (string)
+typeset -Uui16 -Z11 -r ASSO_BOOL=2#100         # type: JSON "true" / "false"
+typeset -Uui16 -Z11 -r ASSO_NULL=2#101         # type: JSON "null"
+typeset -Uui16 -Z11 -r ASSO_AIDX=2#110         # type: indexed array
+typeset -Uui16 -Z11 -r ASSO_AASS=2#111         # type: associative array
+typeset -Uui16 -Z11 -r ASSO_MASK_ARR=2#110     # bitmask for array type
+typeset -Uui16 -Z11 -r ASSO_MASK_TYPE=2#111    # bitmask for type
+typeset -Uui16 -Z11 -r ASSO_ISSET=16#40000000  # element is set
+typeset -Uui16 -Z11 -r ASSO_ALLOC=16#80000000  # ksh element is set
+
+# notes:
+# – the code assumes ASSO_VAL=0 < all scalar types with value \
+#   < ASSO_NULL < all array types
+
+# public functions
+
+# set a value
+# example: asso_setv 123 'test' 'foo' 0 'baz'
+function asso_setv {
+       if (( $# < 2 )); then
+               print -u2 'assockit.ksh: syntax: asso_setv value key [key ...]'
+               return 2
+       fi
+       local _v=$1 _f _i
+       shift
+
+       # look up the item, creating paths as needed
+       asso__lookup 1 "$@"
+       # if it’s an array, free that recursively
+       if (( (_f = asso_f) & ASSO_MASK_ARR )); then
+               asso__r_free 1
+               (( _f &= ~ASSO_MASK_TYPE ))
+       fi
+       # if it’s got a type, check for a match
+       if (( _i = (_f & ASSO_MASK_TYPE) )); then
+               asso__typeck $_i "$_v" || (( _f &= ~ASSO_MASK_TYPE ))
+       fi
+       # set the new flags and value
+       asso__r_setfv $_f "$_v"
+}
+
+# get the flags of an item, or return 1 if not set
+# result is in the global variable asso_f
+function asso_isset {
+       if (( $# < 1 )); then
+               print -u2 'assockit.ksh: syntax: asso_isset key [key ...]'
+               return 2
+       fi
+
+       asso__lookup 0 "$@"
+}
+
+# get the type of an item (return 1 if unset, 2 if error)
+# example: x=$(asso_gett 'test' 'foo' 0 'baz') => $((ASSO_VAL))
+function asso_gett {
+       asso_isset "$@" || return
+       print -n -- $((asso_f & ASSO_MASK_TYPE))
+}
+
+# get the value of an item (return 1 if unset, 2 if error)
+# example: x=$(asso_getv 'test' 'foo' 0 'baz') => 123
+function asso_getv {
+       asso_loadv "$@" || return
+       print -nr -- "$asso_x"
+}
+
+# get the value of an item, but result is in the global variable asso_x
+function asso_loadv {
+       if (( $# < 1 )); then
+               print -u2 'assockit.ksh: syntax: asso_loadv key [key ...]'
+               return 2
+       fi
+
+       asso__lookup 0 "$@" || return 1
+       if (( (asso_f & ASSO_MASK_TYPE) < ASSO_NULL )); then
+               nameref _Av=${asso_b}_v
+               asso_x=${_Av[asso_k]}
+       else
+               asso_x=""
+       fi
+}
+
+# get all set keys of an item of array type (return 1 if no array)
+# result is in the global variable asso_y
+function asso_loadk {
+       if (( $# < 1 )); then
+               print -u2 'assockit.ksh: syntax: asso_loadk key [key ...]'
+               return 2
+       fi
+
+       asso__lookup 0 "$@" || return 1
+       (( asso_f & ASSO_MASK_ARR )) || return 1
+       nameref _keys=${asso_b}${asso_k#16#}_k
+       set -A asso_y -- "${_keys[@]}"
+}
+
+# set a string value
+# example: asso_sets 'abc' 'test' 'foo' 0 'baz'
+function asso_sets {
+       if (( $# < 2 )); then
+               print -u2 'assockit.ksh: syntax: asso_sets value key [key ...]'
+               return 2
+       fi
+
+       asso__settv $ASSO_STR "$@"
+}
+
+# set an integral value
+# example: asso_seti 123 'test' 'foo' 0 'baz'
+function asso_seti {
+       if (( $# < 2 )); then
+               print -u2 'assockit.ksh: syntax: asso_seti value key [key ...]'
+               return 2
+       fi
+
+       if ! asso__typeck $ASSO_INT "$1"; then
+               print -u2 "assockit.ksh: not an integer: '$1'"
+               return 1
+       fi
+       asso__settv $ASSO_INT "$@"
+}
+
+# set a floating point (real) value
+# example: asso_setr -123.45e+67 'test' 'foo' 0 'baz'
+function asso_setr {
+       if (( $# < 2 )); then
+               print -u2 'assockit.ksh: syntax: asso_setr value key [key ...]'
+               return 2
+       fi
+
+       if ! asso__typeck $ASSO_REAL "$1"; then
+               print -u2 "assockit.ksh: not a real: '$1'"
+               return 1
+       fi
+       asso__settv $ASSO_REAL "$@"
+}
+
+# set a boolean value
+# example: asso_setb t 'test' 'foo' 0 'baz'
+function asso_setb {
+       if (( $# < 2 )); then
+               print -u2 'assockit.ksh: syntax: asso_setb value key [key ...]'
+               return 2
+       fi
+
+       if ! asso__typeck $ASSO_BOOL "$1"; then
+               print -u2 "assockit.ksh: not a truth value: '$1'"
+               return 1
+       fi
+       asso__settv $ASSO_BOOL "$@"
+}
+
+# set value to null
+# example: asso_setnull 'test' 'foo' 0 'baz'
+function asso_setnull {
+       if (( $# < 1 )); then
+               print -u2 'assockit.ksh: syntax: asso_setnull key [key ...]'
+               return 2
+       fi
+
+       asso__settv $ASSO_NULL 0 "$@"
+}
+
+# set type and scalar value
+# example: asso_settv $ASSO_INT 123 'test' 'foo' 0 'baz'
+function asso_settv {
+       if (( $# < 3 )) || ! asso__intck "$1" || \
+           (( $1 != ($1 & ASSO_MASK_TYPE) )); then
+               print -u2 'assockit.ksh: syntax: asso_settv type value key...'
+               return 2
+       fi
+
+       if ! asso__typeck $1 "$2"; then
+               print -u2 "assockit.ksh: wrong type scalar: '$2'"
+               return 1
+       fi
+       asso__settv "$@"
+}
+
+# unset value
+# example: asso_unset 'test' 'foo' 0 'baz'
+function asso_unset {
+       if (( $# < 1 )); then
+               print -u2 'assockit.ksh: syntax: asso_unset key [key ...]'
+               return 2
+       fi
+
+       # look up the item, not creating paths
+       if asso__lookup 0 "$@"; then
+               # free the item recursively
+               asso__r_free 0
+       fi
+       return 0
+}
+
+# make an entry into an indexed array
+# from scalar => data into [0]
+# from associative array => data lost
+function asso_setidx {
+       if (( $# < 1 )); then
+               print -u2 'assockit.ksh: syntax: asso_setidx key [key ...]'
+               return 2
+       fi
+
+       local _f _v
+
+       asso__lookup 1 "$@"
+       if (( !((_f = asso_f) & ASSO_MASK_ARR) )); then
+               nameref _Av=${asso_b}_v
+               _v=${_Av[asso_k]}
+       elif (( (_f & ASSO_MASK_TYPE) == ASSO_AIDX )); then
+               return 0
+       fi
+       asso__r_free 1
+       asso__r_setf $ASSO_AIDX
+       if (( !(_f & ASSO_MASK_ARR) )); then
+               asso__lookup 1 "$@" 0
+               asso__r_setfv $_f "$_v"
+       fi
+}
+
+# make an entry into an associative array
+# from scalar => data lost
+# from indexed array => data converted
+function asso_setasso {
+       if (( $# < 1 )); then
+               print -u2 'assockit.ksh: syntax: asso_setasso key [key ...]'
+               return 2
+       fi
+
+       local _f
+
+       asso__lookup 1 "$@"
+       if (( !((_f = asso_f) & ASSO_MASK_ARR) )); then
+               asso__r_free 1
+               asso__r_setf $ASSO_AASS
+       elif (( (_f & ASSO_MASK_TYPE) == ASSO_AIDX )); then
+               asso__r_idx2ass
+       fi
+       return 0
+}
+
+# private functions
+
+# set type and scalar value, unchecked
+function asso__settv {
+       local _t=$1 _v=$2 _f
+       shift; shift
+
+       # look up the item, creating paths as needed
+       asso__lookup 1 "$@"
+       # if it’s an array, free that recursively
+       if (( (_f = asso_f) & ASSO_MASK_ARR )); then
+               asso__r_free 1
+       fi
+       (( _f = (_f & ~ASSO_MASK_TYPE) | _t ))
+       # set the new flags and value
+       asso__r_setfv $_f "$_v"
+}
+
+# check if this is a numeric (integral) value (0=ok 1=error)
+function asso__intck {
+       local _v=$1
+
+       [[ $_v = ?(+([0-9])'#')+([0-9a-zA-Z]) ]] || return 2
+       { : $((_v)) ; } 2>&-
+}
+
+# map a boolean value (0=false 1=true 2=error)
+function asso__boolmap {
+       local _v=$1
+
+       if asso__intck "$_v"; then
+               (( _v == 0 ))
+               return
+       fi
+       case $_v {
+       ([Tt]?([Rr][Uu][Ee])|[Yy]?([Ee][Ss])|[Oo][NnKk])
+               return 1 ;;
+       ([Ff]?([Aa][Ll][Ss][Ee])|[Nn]?([Oo])|[Oo][Ff][Ff])
+               return 0 ;;
+       }
+       return 2
+}
+
+# check if the type matches the value (0=ok 1=error)
+function asso__typeck {
+       if (( $# != 2 )); then
+               print -u2 'assockit.ksh: syntax: asso__typeck type value'
+               return 2
+       fi
+       local _t=$1 _v=$2
+       (( _t == ASSO_VAL || _t == ASSO_STR || _t == ASSO_NULL )) && return 0
+       if (( _t == ASSO_INT )); then
+               asso__intck "$_v"
+               return
+       fi
+       if (( _t == ASSO_BOOL )); then
+               asso__boolmap "$_v"
+               (( $? < 2 ))
+               return
+       fi
+       (( _t & ASSO_MASK_ARR )) && return 1
+       # ASSO_REAL
+       [[ $_v = ?(-)@(0|[1-9]*([0-9]))?(.+([0-9]))?([Ee]?([+-])+([0-9])) ]]
+}
+
+# look up an item ($1=1: create paths as necessary)
+function asso__lookup {
+       local _c=$1 _k _n _r
+       shift
+
+       _n=Asso_
+       _r=0
+       asso_f=$ASSO_AASS
+       for _k in "$@"; do
+               if (( _r || !(asso_f & ASSO_MASK_ARR) )); then
+                       (( _r )) || asso__r_free 1
+                       asso__r_setf $ASSO_AASS
+               elif (( (asso_f & ASSO_MASK_TYPE) == ASSO_AIDX )); then
+                       asso__intck "$_k" || asso__r_idx2ass
+               fi
+               asso_b=$_n
+               asso__lookup_once "$_k"
+               if (( _r = $? )); then
+                       # not found. not create?
+                       (( _c )) || return 1
+                       asso__r_setk "$_k"
+               fi
+               _n=$_n${asso_k#16#}
+       done
+       return 0
+}
+
+# set flags for asso_b[asso_k] and update asso_f
+function asso__r_setf {
+       nameref _Af=${asso_b}_f
+
+       asso_f=$(($1 | ASSO_ISSET | ASSO_ALLOC))
+       _Af[asso_k]=$asso_f
+}
+
+# set flags and value for asso_b[asso_k] and update asso_f
+function asso__r_setfv {
+       nameref _Af=${asso_b}_f
+       nameref _Av=${asso_b}_v
+
+       _Av[asso_k]=$2
+       asso_f=$(($1 | ASSO_ISSET | ASSO_ALLOC))
+       _Af[asso_k]=$asso_f
+}
+
+# set key for not yet existing asso_b[asso_k] and update asso_f
+function asso__r_setk {
+       nameref _Af=${asso_b}_f
+       nameref _Ak=${asso_b}_k
+
+       _Ak[asso_k]=$1
+       asso_f=$((ASSO_ALLOC))
+       _Af[asso_k]=$asso_f
+}
+
+# in asso_b of type asso_f look up element $1
+# set its asso_f and asso_k or return 1 when not found
+function asso__lookup_once {
+       local _e=$1 _seth=0
+       nameref _Af=${asso_b}_f
+       nameref _Ak=${asso_b}_k
+
+       if (( (asso_f & ASSO_MASK_TYPE) == ASSO_AIDX )); then
+               asso_k=$((_e))
+       else
+               asso_k=16#${_e@#}
+#              asso_k=$(somehash "$_e")
+               while :; do
+                       asso_f=${_Af[asso_k]}
+                       (( asso_f & ASSO_ALLOC )) || break
+                       if (( !(asso_f & ASSO_ISSET) )); then
+                               if (( !_seth )); then
+                                       # save index
+                                       asso_h=$asso_k
+                                       _seth=1
+                               fi
+                               (( --asso_k ))
+                               continue
+                       fi
+                       [[ ${_Ak[asso_k]} = "$_e" ]] && break
+                       # iterate
+                       (( --asso_k ))
+               done
+       fi
+       asso_f=${_Af[asso_k]}
+       # found?
+       (( asso_f & ASSO_ISSET )) && return 0
+       # not found.
+       if (( _seth )); then
+               # when allocating, use this one instead
+               asso_k=$asso_h
+       fi
+       return 1
+}
+
+# free the currently selected asso_b[asso_k] recursively
+function asso__r_free {
+       local _keepkey=$1
+       nameref _Af=${asso_b}_f
+
+       asso_f=${_Af[asso_k]}
+       (( asso_f & ASSO_ALLOC )) || return
+       if (( asso_f & ASSO_ISSET )); then
+               if (( asso_f & ASSO_MASK_ARR )); then
+                       local _ob=$asso_b _ok=$asso_k
+                       asso_b=$asso_b${asso_k#16#}
+                       nameref _s=${asso_b}_f
+                       for asso_k in "${!_s[@]}"; do
+                               asso__r_free
+                       done
+                       eval unset ${asso_b}_f ${asso_b}_k ${asso_b}_v
+                       asso_b=$_ob asso_k=$_ok
+               fi
+               eval unset $asso_b'_v[asso_k]'
+               (( _keepkey )) || eval unset $asso_b'_k[asso_k]'
+       fi
+       asso_f=$((ASSO_ALLOC))
+       _Af[asso_k]=$asso_f
+}
+
+# make indexed asso_b[asso_k] into associative array
+function asso__r_idx2ass {
+       print -u2 'assockit.ksh: warning: asso__r_idx2ass not implemented'
+       print -u2 'assockit.ksh: warning: data will be lost'
+       asso__r_free
+       asso__r_setf $ASSO_AASS
+}
diff --git a/mksh/assoldap.ksh b/mksh/assoldap.ksh
new file mode 100644 (file)
index 0000000..aa788a0
--- /dev/null
@@ -0,0 +1,128 @@
+#-
+# Copyright © 2013
+#      Thorsten Glaser <t.glaser@tarent.de>
+#
+# 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.
+#-
+# Generic LDAP (LDIF) parser into associative arrays.
+
+# include assockit and pure-mksh base64 decoder, unless already done
+mydir=$(realpath "$(dirname "$0")")
+[[ -n $ASSO_VAL ]] || PATH="$mydir:$mydir/..:$PATH" . assockit.ksh
+typeset -f Lb64decode >/dev/null || PATH="$mydir:$mydir/..:$PATH" . base64
+
+# Syntax: asso_setldap arrayname index ... -- ldapsearch-options
+function asso_setldap {
+       # parse options
+       local arrpath ldapopts x i=0 T dn line value
+       set -A arrpath
+       while (( $# )); do
+               [[ $1 = -- ]] && break
+               arrpath[i++]=$1
+               shift
+       done
+       if [[ $1 != -- ]]; then
+               print -u2 'assoldap.ksh: syntax: asso_setldap arraypath -- ldappath'
+               return 255
+       fi
+       shift
+       set -A ldapopts -- "$@"
+
+       # just in case, unset the target array and create it as associative
+       asso__lookup 1 "${arrpath[@]}"
+       asso__r_free
+       asso__r_setf $ASSO_AASS
+
+       # call ldapsearch with decent output format
+       if ! T=$(mktemp -d /tmp/assoldap.XXXXXXXXXX); then
+               print -u2 'assoldap.ksh: could not create temporary directory'
+               return 255
+       fi
+       (ldapsearch -xLLL "${ldapopts[@]}"; echo $? >"$T/err") | \
+           tr '\n' $'\a' | sed -e $'s/\a //g' >"$T/out"
+       i=$(<"$T/err")
+       if (( i )); then
+               print -u2 'assoldap.ksh: ldapsearch returned error'
+               rm -rf "$T"
+               return $i
+       fi
+       if [[ ! -s $T/out ]]; then
+               # empty output
+               rm -rf "$T"
+               return 0
+       fi
+
+       # parse LDIF (without linewraps)
+       while IFS= read -d $'\a' -r line; do
+               if [[ -z $line ]]; then
+                       dn=
+                       continue
+               fi
+               value=${line##+([!:]):?(:)*( )}
+               if [[ $value = "$line" ]]; then
+                       print -ru2 "assoldap.ksh: malformed line: $line"
+                       rm -rf "$T"
+                       return 255
+               fi
+               x=${line%%*( )"$value"}
+               if [[ $x = "$line" ]]; then
+                       print -ru2 "assoldap.ksh: malformed line: $line"
+                       rm -rf "$T"
+                       return 255
+               fi
+               [[ $x = *:: ]] && value=$(Lb64decode "$value")
+               x=${x%%+(:)}
+               if [[ -z $dn ]]; then
+                       if [[ $x = dn ]]; then
+                               dn=$value
+                       else
+                               print -ru2 "assoldap.ksh: not dn: $line"
+                               rm -rf "$T"
+                               return 255
+                       fi
+               elif [[ $x = dn ]]; then
+                       print -ru2 "assoldap.ksh: unexpected dn ($dn): $line"
+                       rm -rf "$T"
+                       return 255
+               fi
+               asso_sets "$value" "${arrpath[@]}" "$dn" "$x"
+       done <"$T/out"
+       rm -rf "$T"
+       if [[ -n $dn ]]; then
+               print -u2 'assoldap.ksh: missing empty line at EOT'
+               return 255
+       fi
+       return 0
+}
+
+:||\
+{
+       # for testing
+       LDAPTLS_CACERT=/etc/ssl/certs/dc.lan.tarent.de.cer \
+           asso_setldap users -- \
+           -H ldaps://dc.lan.tarent.de -b cn=users,dc=tarent,dc=de -s one \
+           isJabberAccount=1 cn uid
+       if (( $? )); then
+               print -u2 An error occurred: $?
+               exit 1
+       fi
+       print "uid (dn) = cn"
+       asso_loadk users
+       for user_dn in "${asso_y[@]}"; do
+               print -r -- "$(asso_getv users "$user_dn" uid)" \
+                   "($user_dn) = $(asso_getv users "$user_dn" cn)"
+       done | sort
+}
diff --git a/mksh/assotest b/mksh/assotest
new file mode 100644 (file)
index 0000000..28a7fc0
--- /dev/null
@@ -0,0 +1,69 @@
+# $MirOS: contrib/hosted/tg/historic/assotest,v 1.3 2013/11/30 13:45:20 tg Exp $
+#-
+# some number of interactive tests for asso-kit
+
+if [[ $1 != x ]]; then
+       dn="$(dirname "$0")"
+       bn="$(basename "$0")"
+       cd "$dn"
+       env -i HOME=/ SHELL=/bin/mksh /bin/mksh "$bn" x "$@" | \
+           egrep -ve '^PIPESTATUS\[' -e '^ASSO_' \
+           -e  '^(BASHPID|COLUMNS|EPOCHREALTIME|HOME|IFS|KSHE*[UG]ID|KSH_VERSION|LINES|OPTIND|PATH|PGRP|PIPESTATUS|PPID|PS[1234]|PWD|RANDOM|SECONDS|SHELL|TMOUT|USER_ID)(=|$)'
+       exit
+fi
+shift
+
+typeset -Z11 -Uui16 ASSO_Lcdbhash_result
+function Lcdbhash_add {
+        [[ -o utf8-mode ]]; typeset u=$?
+        set +U
+        typeset s="$*"
+        [[ -n $s ]] || { s=$(cat;print x); s=${s%x}; }
+        typeset -i i=0 n=${#s}
+
+        while (( i < n )); do
+               ((# ASSO_Lcdbhash_result += 1#${s:(i++):1} ))
+        done
+
+        (( u )) || set -U
+}
+function somehash {
+        ASSO_Lcdbhash_result=5381
+        Lcdbhash_add "$@"
+        print $ASSO_Lcdbhash_result
+}
+
+mydir=$(dirname "$(realpath "$0")")
+PATH="$mydir:$mydir/..:$PATH" . assockit.ksh
+
+#asso_setidx 'test' 'foo'
+#asso_seti 123 'test' 'foo' 0
+#asso_seti 456 'test' 'foo' 1
+##asso_unset test foo 0
+#IFS=
+#set
+#exit
+
+# { 'foo': [ { 'baz': 123 } ] } named 'test' becomes:
+
+asso_setidx 'test' 'foo'
+asso_setidx 'test' 'oof'
+asso_seti 123 'test' 'foo' 0 'baz'
+asso_seti 456 'test' 'oof' 0 'baz'
+
+print "v=$(asso_getv 'test' 'foo' 0 'baz')/$(asso_getv 'test' 'oof' 0 'baz')"
+print "t=$(asso_gett 'test' 'foo' 0 'baz')/$(asso_gett 'test' 'oof' 0 'baz')"
+
+IFS=
+set
+IFS=$' \t\n'
+
+print now unsetting
+asso_unset test foo
+#asso_setidx 'test' 'foo'
+#asso_seti 789 'test' 'foo' 0 'baz'
+#print "v=$(asso_getv 'test' 'foo' 0 'baz')/$(asso_getv 'test' 'oof' 0 'baz')"
+#print "t=$(asso_gett 'test' 'foo' 0 'baz')/$(asso_gett 'test' 'oof' 0 'baz')"
+IFS=
+set
+IFS=$' \t\n'
diff --git a/mksh/base64 b/mksh/base64
new file mode 100644 (file)
index 0000000..16c3650
--- /dev/null
@@ -0,0 +1,133 @@
+# $MirOS: src/bin/mksh/dot.mkshrc,v 1.68 2011/11/25 23:58:04 tg Exp $
+#-
+# Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011
+#      Thorsten Glaser <tg@mirbsd.org>
+#
+# 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.
+#-
+# RFC compliant base64 encoder and decoder
+
+# NUL safe base64 decoder
+function Lb64decode {
+       [[ -o utf8-mode ]]; local u=$?
+       set +U
+       local c s="$*" t=
+       [[ -n $s ]] || { s=$(cat;print x); s=${s%x}; }
+       local -i i=0 j=0 n=${#s} p=0 v x
+       local -i16 o
+
+       while (( i < n )); do
+               c=${s:(i++):1}
+               case $c {
+               (=)     break ;;
+               ([A-Z]) (( v = 1#$c - 65 )) ;;
+               ([a-z]) (( v = 1#$c - 71 )) ;;
+               ([0-9]) (( v = 1#$c + 4 )) ;;
+               (+)     v=62 ;;
+               (/)     v=63 ;;
+               (*)     continue ;;
+               }
+               (( x = (x << 6) | v ))
+               case $((p++)) {
+               (0)     continue ;;
+               (1)     (( o = (x >> 4) & 255 )) ;;
+               (2)     (( o = (x >> 2) & 255 )) ;;
+               (3)     (( o = x & 255 ))
+                       p=0
+                       ;;
+               }
+               t=$t\\x${o#16#}
+               (( ++j & 4095 )) && continue
+               print -n $t
+               t=
+       done
+       print -n $t
+       (( u )) || set -U
+}
+
+set -A Lb64encode_code -- A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
+    a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 + /
+if true; then
+# not NUL safe base64 encoder
+function Lb64encode {
+       [[ -o utf8-mode ]]; typeset u=$?
+       set +U
+       typeset c s="$*" t
+       [[ -n $s ]] || { s=$(cat;print x); s=${s%x}; }
+       typeset -i i=0 n=${#s} j v
+
+       while (( i < n )); do
+               c=${s:(i++):1}
+               (( v = 1#$c << 16 ))
+               c=${s:(i++):1}
+               (( j = ${#c} ? 1#$c : 0 ))
+               (( v |= j << 8 ))
+               c=${s:(i++):1}
+               (( j = ${#c} ? 1#$c : 0 ))
+               (( v |= j ))
+               t=$t${Lb64encode_code[v >> 18]}${Lb64encode_code[v >> 12 & 63]}
+               c=${Lb64encode_code[v >> 6 & 63]}
+               if (( i <= n )); then
+                       t=$t$c${Lb64encode_code[v & 63]}
+               elif (( i == n + 1 )); then
+                       t=$t$c=
+               else
+                       t=$t==
+               fi
+               if (( ${#t} == 76 || i >= n )); then
+                       print $t
+                       t=
+               fi
+       done
+       (( u )) || set -U
+}
+else
+# NUL safe base64 encoder, needs mksh R40
+function Lb64encode {
+       [[ -o utf8-mode ]]; local u=$?
+       set +U
+       local c s t
+       if (( $# )); then
+               read -raN-1 s <<<"$*"
+               unset s[${#s[*]}-1]
+       else
+               read -raN-1 s
+       fi
+       local -i i=0 n=${#s[*]} j v
+
+       while (( i < n )); do
+               (( v = s[i++] << 16 ))
+               (( j = i < n ? s[i++] : 0 ))
+               (( v |= j << 8 ))
+               (( j = i < n ? s[i++] : 0 ))
+               (( v |= j ))
+               t+=${Lb64encode_code[v >> 18]}${Lb64encode_code[v >> 12 & 63]}
+               c=${Lb64encode_code[v >> 6 & 63]}
+               if (( i <= n )); then
+                       t+=$c${Lb64encode_code[v & 63]}
+               elif (( i == n + 1 )); then
+                       t+=$c=
+               else
+                       t+===
+               fi
+               if (( ${#t} == 76 || i >= n )); then
+                       print $t
+                       t=
+               fi
+       done
+       (( u )) || set -U
+}
+fi
diff --git a/mksh/bdfctool.1 b/mksh/bdfctool.1
new file mode 100644 (file)
index 0000000..8e4552f
--- /dev/null
@@ -0,0 +1,398 @@
+.\" $MirOS: X11/extras/bdfctool/bdfctool.1,v 1.10 2013/05/17 21:51:40 tg Exp $
+.\"-
+.\" Copyright © 2012, 2013
+.\"    Thorsten “mirabilos” Glaser <tg@mirbsd.org>
+.\"-
+.\" Try to make GNU groff and AT&T nroff more compatible
+.\" * ` generates ‘ in gnroff, so use \`
+.\" * ' generates ’ in gnroff, \' generates ´, so use \*(aq
+.\" * - generates ‐ in gnroff, \- generates −, so .tr it to -
+.\"   thus use - for hyphens and \- for minus signs and option dashes
+.\" * ~ is size-reduced and placed atop in groff, so use \*(TI
+.\" * ^ is size-reduced and placed atop in groff, so use \*(ha
+.\" * \(en does not work in nroff, so use \*(en
+.\" * <>| are problematic, so redefine and use \*(Lt\*(Gt\*(Ba
+.\" Also make sure to use \& especially with two-letter words.
+.\" The section after the "doc" macropackage has been loaded contains
+.\" additional code to convene between the UCB mdoc macropackage (and
+.\" its variant as BSD mdoc in groff) and the GNU mdoc macropackage.
+.\"
+.ie \n(.g \{\
+.      if \ 1\*[.T]\ 1ascii\ 1 .tr \-\N'45'
+.      if \ 1\*[.T]\ 1latin1\ 1 .tr \-\N'45'
+.      if \ 1\*[.T]\ 1utf8\ 1 .tr \-\N'45'
+.      ds <= \[<=]
+.      ds >= \[>=]
+.      ds Rq \[rq]
+.      ds Lq \[lq]
+.      ds sL \(aq
+.      ds sR \(aq
+.      if \ 1\*[.T]\ 1utf8\ 1 .ds sL `
+.      if \ 1\*[.T]\ 1ps\ 1 .ds sL `
+.      if \ 1\*[.T]\ 1utf8\ 1 .ds sR '
+.      if \ 1\*[.T]\ 1ps\ 1 .ds sR '
+.      ds aq \(aq
+.      ds TI \(ti
+.      ds ha \(ha
+.      ds en \(en
+.\}
+.el \{\
+.      ds aq '
+.      ds TI ~
+.      ds ha ^
+.      ds en \(em
+.\}
+.\"
+.\" Implement .Dd with the Mdocdate RCS keyword
+.\"
+.rn Dd xD
+.de Dd
+.ie \a\\$1\a$Mdocdate:\a \{\
+.      xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
+.\"
+.\" .Dd must come before definition of .Mx, because when called
+.\" with -mandoc, it might implement .Mx itself, but we want to
+.\" use our own definition. And .Dd must come *first*, always.
+.\"
+.Dd $Mdocdate: May 17 2013 $
+.\"
+.\" Check which macro package we use, and do other -mdoc setup.
+.\"
+.ie \n(.g \{\
+.      if \ 1\*[.T]\ 1utf8\ 1 .tr \[la]\*(Lt
+.      if \ 1\*[.T]\ 1utf8\ 1 .tr \[ra]\*(Gt
+.      ie d volume-ds-1 .ds tT gnu
+.      el .ds tT bsd
+.\}
+.el .ds tT ucb
+.\"
+.\" Implement .Mx (MirBSD)
+.\"
+.ie "\*(tT"gnu" \{\
+.      eo
+.      de Mx
+.      nr curr-font \n[.f]
+.      nr curr-size \n[.ps]
+.      ds str-Mx \f[\n[curr-font]]\s[\n[curr-size]u]
+.      ds str-Mx1 \*[Tn-font-size]\%MirOS\*[str-Mx]
+.      if !\n[arg-limit] \
+.      if \n[.$] \{\
+.      ds macro-name Mx
+.      parse-args \$@
+.      \}
+.      if (\n[arg-limit] > \n[arg-ptr]) \{\
+.      nr arg-ptr +1
+.      ie (\n[type\n[arg-ptr]] == 2) \
+.      as str-Mx1 \~\*[arg\n[arg-ptr]]
+.      el \
+.      nr arg-ptr -1
+.      \}
+.      ds arg\n[arg-ptr] "\*[str-Mx1]
+.      nr type\n[arg-ptr] 2
+.      ds space\n[arg-ptr] "\*[space]
+.      nr num-args (\n[arg-limit] - \n[arg-ptr])
+.      nr arg-limit \n[arg-ptr]
+.      if \n[num-args] \
+.      parse-space-vector
+.      print-recursive
+..
+.      ec
+.      ds sP \s0
+.      ds tN \*[Tn-font-size]
+.\}
+.el \{\
+.      de Mx
+.      nr cF \\n(.f
+.      nr cZ \\n(.s
+.      ds aa \&\f\\n(cF\s\\n(cZ
+.      if \\n(aC==0 \{\
+.              ie \\n(.$==0 \&MirOS\\*(aa
+.              el .aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
+.      \}
+.      if \\n(aC>\\n(aP \{\
+.              nr aP \\n(aP+1
+.              ie \\n(C\\n(aP==2 \{\
+.                      as b1 \&MirOS\ #\&\\*(A\\n(aP\\*(aa
+.                      ie \\n(aC>\\n(aP \{\
+.                              nr aP \\n(aP+1
+.                              nR
+.                      \}
+.                      el .aZ
+.              \}
+.              el \{\
+.                      as b1 \&MirOS\\*(aa
+.                      nR
+.              \}
+.      \}
+..
+.\}
+.\"-
+.Dt BDFCTOOL 1
+.Os MirBSD
+.Sh NAME
+.Nm bdfctool
+.Nd convert BDF and bdfc font files
+.Sh SYNOPSIS
+.Nm
+.Fl c
+.Nm
+.Fl d
+.Op Fl F
+.Nm
+.Fl e
+.Op Fl a
+.Nm
+.Ic +e
+.Sh DESCRIPTION
+The
+.Nm
+utility converts (mostly) fixed-width bitmap fonts between the
+.Tn BDF
+file format as used by
+.Tn XFree86\(rg
+and the
+.Ic bdfc
+format as specified below.
+It operates as a filter, i.e. takes its input from the standard
+input stream and writes data to standard output.
+.Pp
+The options are as follows:
+.Bl -tag -width XXX
+.It Fl a
+In edit mode, emit ASCII (1:2) encoding for an unset bit
+.Pq Sq Li \&. ,
+a set bit
+.Pq Sq Li \&#
+and the line end separator
+.Pq Sq Li \&\*(Ba .
+.It Ic +a
+In edit mode, emit Unicode (1:1) encoding (default).
+.It Fl d
+Decompress the font from bdfc into
+.Tn BDF .
+.It Fl c
+Compress the font from
+.Tn BDF
+or the bdfc edit form to bdfc, also sorting and weeding out
+any duplicates (later occurrence wins).
+.It Fl e
+Expand selected glyphs inside the bdfc file into the edit form,
+which uses U+3000 and U+4DC0 to represent unset and set bits,
+respectively, so they can be visually edited.
+This mode operates on glyphs and does not need to be passed the
+whole file, e.g. using \*(haK/ in the jupp text editor.
+.It Ic +e
+Revert selected glyphs from edit form back to compressed form
+.Pq without whole-file validation .
+.It Fl F
+Do a fast decompression with no error checking.
+Run this on files passed through
+.Nm
+.Fl c
+.Em only .
+Used by the
+.Mx
+.Tn XFree86\(rg
+build process.
+.El
+.Sh BDFC FORMAT DESCRIPTION
+A
+.Ic \&.bdfc
+file is a compressed, editable representation of a subset of the
+.Ic Bitmap Distribution Format Pq BDF
+as used for fixed-width fonts in the
+.Tn XFree86\(rg
+windowing system.
+.Pp
+Every file starts with a line consisting of
+.Dq Li "=bdfc 1" ,
+where
+.Ql \&1
+is the version number.
+The format is line-oriented and only somewhat stateful.
+It is optimised for being operated on using the jupp text editor and
+.Nm mksh
+shell scripts.
+Lines starting with an apostrophe U+0027 and a space U+0020, or
+consisting of only an apostrophe before the newline, can be
+used anywhere inside the file, except within the trailing-data lines
+of an edit block (see below), to denote a comment, which is retained
+(tacked on to the following character).
+.Pp
+Next comes a block of font header information that are just
+passed through, prefixed with a
+.Dq Li h .
+After that, list the font properties, prefixed with a
+.Dq Li p
+each, and followed by a
+.Dq Li C
+on a line by itself, which will deal with emitting the
+.Li STARTPROPERTIES
+number, the properties and
+.Li ENDPROPERTIES
+and marks the place where
+.Li CHARS
+is put in
+.Tn BDF .
+.Pp
+Finally, there is the character block, which is somewhat stateless.
+There are two types of entries for that block, glyph defaults and glyph data.
+The block is ended with a period
+.Pq Dq Li .\&
+on a line by itself.
+.Pp
+Glyphs are sorted by their font encoding / Unicode code point, and each
+glyph occurs only once, although the
+.Nm
+tool in the
+.Fl c
+operation mode is able to take glyphs in any order and weed out duplicates.
+The character name can be omitted if it matches the form
+.Dq Li uni Ns Ar 20AC
+where
+.Dq Ar 20AC
+is the four-nibble uppercase Unicode codepoint of the glyph, in this
+example the Euro sign.
+.Pp
+Glyph defaults are lines in the format
+.Dl d 540 0 9 0 0 \-4
+where the first
+.Dq Li d
+is the line type, and the next values are, in order, the arguments to the
+.Li SWIDTH
+and
+.Li DWIDTH
+and the third and fourth argument to the
+.Li BBX
+.Tn BDF
+commands.
+(The first and second arguments of
+.Li BBX
+are derived from the glyph data line instead.)
+.Pp
+The glyph defaults are used in encoding every subsequent glyph for
+.Tn BDF
+and are valid until the next glyph default line, which means that
+a character block must start with one, and that sorting may need
+to duplicate or move such lines, as handled by
+.Nm
+.Fl c .
+.Pp
+Finally, let's talk about the glyph data lines.
+The standard (condensed) form looks like
+.Dl c 0020 6 00:00:00:00:00:00:00:00 space
+which are, in this order, the type of the line, the encoding of
+the glyph, the width (in bit) of the glyph (first argument of
+.Li BBX ) ,
+the glyph data (in whole bytes, uppercase nibbles, as in
+.Tn BDF ,
+but colon-separated; the number of which yields the second argument to
+.Li BBX )
+and the glyph name (which, as explained above, is optional)
+consisting of up to 14 alphanumeric characters.
+.Pp
+The editing form is a multi-line form and
+.Em must not
+be used in persistent storage, revision control or transmission.
+Its first line looks like
+.Dl e 0020 6 8 space
+which is basically the same as the standard form, except that the
+number of lines replaces the bitmap data.
+This is followed by (in this case eight) lines that comprise of
+(in this case six) occurrences of either U+3000 (to denote an unset
+pixel) or U+4DC0 (to denote a set pixel), followed by U+258C (to
+denote, as a visual help, the next character).
+The compression script also accepts a dot U+002E or a space U+0020
+as null-bit, a hash U+0023 or an asterisk U+002A as set bit, and a
+pipe sign / bar U+007C as line end marker.
+You should use the regular form if your display font has an 1:2
+ratio (e.g. 8x16, 9x18) and the alternative form if it has an 1:1
+ratio (e.g. 8x8 pixels), and switch fonts if it has a different
+ratio altogether.
+.Pp
+The trailing dot does not denote the end of file for the
+.Fl c
+operation, as it can handle concatenated files, but is used
+to have an easy way to switch between the file and glyph sections,
+since the former does not use a structured line format.
+.Sh RETURN VALUES
+The
+.Nm
+utility exits with one of the following values:
+.Pp
+.Bl -tag -width XXX -compact
+.It Li 0
+No error occurred.
+.It Li 1
+Wrong usage.
+.It Li 2
+An error during processing occurred, e.g. invalid input.
+.It Li 3
+A strict mode
+.Pq Fl d
+error occurred, e.g. invalid input.
+.It Li 4
+An error in an external program, such as
+.Xr mktemp 1 ,
+occurred.
+.El
+.Sh EXAMPLES
+The following example should be a minimal valid font demonstrating
+all features of the bdfc format:
+.Bd -literal
+=bdfc 1
+\&' $ucs\-fonts: 4x6.bdf,v 1.5 2002\-08\-26 18:05:49+01 mgk25 Rel $
+hFONT \-Misc\-Fixed\-Medium\-R\-Normal\-\-6\-60\-75\-75\-C\-40\-ISO10646\-1
+hSIZE 6 75 75
+hFONTBOUNDINGBOX 4 6 0 \-1
+pFONT_ASCENT 5
+pFONT_DESCENT 1
+pDEFAULT_CHAR 0
+C
+d 640 0 4 0 0 \-1
+e 0000 4 6 char0
+#.#.\*(Ba
+\&....\*(Ba
+#.#.\*(Ba
+\&....\*(Ba
+#.#.\*(Ba
+\&....\*(Ba
+c 0020 4 00:00:00:00:00:00 space
+c 018F 4 00:C0:60:A0:40:00
+\&.
+.Ed
+.Sh SEE ALSO
+.Xr bdftopcf 1 ,
+.Xr fstobdf 1
+.Pp
+The
+.Tn XFree86\(rg
+.Ic Bitmap Distribution Format ,
+version 2.1, specification
+.Sh AUTHORS
+.An Thorsten Glaser Aq tg@mirbsd.org
+wrote this tool because
+.Xr cvs 1
+does not scale for multi-thousand-line files,
+to have a one-line-per-glyph format that matches
+.Tn BDF .
+.Sh CAVEATS
+.Nm
+has its own ideas of how a
+.Tn BDF
+font file should look like, and if you deviate from that,
+you might get an error; although, support for more features
+can surely be added.
+.Pp
+.Dq Li ENCODING \-1
+support is missing.
+The glyph encoding is currently treated as the primary key;
+values from 0000 to FFFF inclusive are valid, the zero-padding
+is mandatory.
+.Pp
+The current practical limit on glyph width is 32.
+0-bit wide glyphs cause an error; those with height 0 are
+silently converted to an unset 1x1 bitmap.
diff --git a/mksh/bdfctool.sh b/mksh/bdfctool.sh
new file mode 100644 (file)
index 0000000..28fdd35
--- /dev/null
@@ -0,0 +1,729 @@
+#!/bin/mksh
+# $MirOS: X11/extras/bdfctool/bdfctool.sh,v 1.12 2013/05/17 21:51:40 tg Exp $
+#-
+# Copyright © 2012, 2013
+#      Thorsten Glaser <tg@mirbsd.org>
+#
+# 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.
+
+set -o noglob
+
+uascii=-1
+ufast=0
+while getopts "acdeFh" ch; do
+       case $ch {
+       (a) uascii=1 ;;
+       (+a) uascii=0 ;;
+       (c|d|e|+e) mode=$ch ;;
+       (F) ufast=1 ;;
+       (+F) ufast=0 ;;
+       (h) mode=$ch ;;
+       (*) mode= ;;
+       }
+done
+shift $((OPTIND - 1))
+(( $# )) && mode=
+
+if [[ $mode = ?(h) ]] || [[ $mode != e && $uascii != -1 ]] || \
+    [[ $mode != d && $ufast != 0 ]]; then
+       print -ru2 "Usage: ${0##*/} -c | -d [-F] | -e [-a] | +e"
+       [[ $mode = h ]]; exit $?
+fi
+
+lno=0
+if [[ $mode = e ]]; then
+       if (( uascii == 1 )); then
+               set -A BITv -- '.' '#' '|'
+       else
+               set -A BITv -- ' ' '䷀' '▌'
+       fi
+       while IFS= read -r line; do
+               (( ++lno ))
+               if [[ $line = 'e '* ]]; then
+                       set -A f -- $line
+                       i=${f[3]}
+                       print -r -- "$line"
+                       while (( i-- )); do
+                               if IFS= read -r line; then
+                                       print -r -- "$line"
+                                       continue
+                               fi
+                               print -ru2 "E: Unexpected end of 'e' command" \
+                                   "at line $lno"
+                               exit 2
+                       done
+                       (( lno += f[3] ))
+                       continue
+               fi
+               if [[ $line != 'c '* ]]; then
+                       print -r -- "$line"
+                       continue
+               fi
+               set -A f -- $line
+               if (( (w = f[2]) > 32 || w < 1 )); then
+                       print -ru2 "E: width ${f[2]} not in 1‥32 at line $lno"
+                       exit 2
+               fi
+               if (( w <= 8 )); then
+                       adds=000000
+               elif (( w <= 16 )); then
+                       adds=0000
+               elif (( w <= 24 )); then
+                       adds=00
+               else
+                       adds=
+               fi
+               (( shiftbits = 32 - w ))
+               (( uw = 2 + w ))
+               IFS=:
+               set -A bmp -- ${f[3]}
+               IFS=$' \t\n'
+               f[0]=e
+               f[3]=${#bmp[*]}
+               print -r -- "${f[*]}"
+               chl=0
+               for ch in "${bmp[@]}"; do
+                       (( ++chl ))
+                       if [[ $ch != +([0-9A-F]) ]]; then
+                               print -ru2 "E: char '$ch' at #$chl in line $lno not hex"
+                               exit 2
+                       fi
+                       ch=$ch$adds
+                       if (( ${#ch} != 8 )); then
+                               print -ru2 "E: char '$ch' at #$chl in line $lno not valid"
+                               exit 2
+                       fi
+                       typeset -Uui2 -Z$uw bbin=16#$ch
+                       (( bbin >>= shiftbits ))
+                       b=${bbin#2#}
+                       b=${b//0/${BITv[0]}}
+                       b=${b//1/${BITv[1]}}
+                       print -r -- $b${BITv[2]}
+               done
+       done
+       exit 0
+fi
+
+Fdef=          # currently valid 'd' line
+set -A Fhead   # lines of file header, including comments intersparsed
+set -A Fprop   # lines of file properties, same
+set -A Gprop   # glyph property line (from Fdef), per glyph
+set -A Gdata   # glyph data line, per glyph
+set -A Gcomm   # glyph comments (if any) as string, per glyph
+set -A Fcomm   # lines of comments at end of file
+
+state=0
+
+function parse_bdfc_file {
+       local last
+
+       set -A last
+       while IFS= read -r line; do
+               (( ++lno ))
+               if [[ $line = C ]]; then
+                       Fprop+=("${last[@]}")
+                       state=1
+                       return
+               elif [[ $line = '=bdfc 1' ]]; then
+                       continue
+               fi
+               last+=("$line")
+               [[ $line = \' || $line = "' "* ]] && continue
+               if [[ $line = h* ]]; then
+                       Fhead+=("${last[@]}")
+               elif [[ $line = p* ]]; then
+                       Fprop+=("${last[@]}")
+               else
+                       print -ru2 "E: invalid line #$lno: '$line'"
+                       exit 2
+               fi
+               set -A last
+       done
+       Fprop+=("${last[@]}")
+       state=2
+}
+
+function parse_bdfc_edit {
+       local w shiftbits uw line r i
+
+       if (( (w = f[2]) <= 8 )); then
+               (( shiftbits = 8 - w ))
+               (( uw = 5 ))
+       elif (( w <= 16 )); then
+               (( shiftbits = 16 - w ))
+               (( uw = 7 ))
+       elif (( w <= 24 )); then
+               (( shiftbits = 24 - w ))
+               (( uw = 9 ))
+       else
+               (( shiftbits = 32 - w ))
+               (( uw = 11 ))
+       fi
+
+       if (( (i = f[3]) < 1 || i > 999 )); then
+               print -ru2 "E: nonsensical number of lines '${f[3]}' in" \
+                   "line $lno, U+${ch#16#}"
+               exit 2
+       fi
+
+       while (( i-- )); do
+               if ! IFS= read -r line; then
+                       print -ru2 "E: Unexpected end of 'e' command" \
+                           "at line $lno, U+${ch#16#}"
+                       exit 2
+               fi
+               (( ++lno ))
+               linx=${line// /.}
+               linx=${linx//䷀/#}
+               linx=${linx//▌/|}
+               linx=${linx//[ .]/0}
+               linx=${linx//[#*]/1}
+               if [[ $linx != +([01])'|' || ${#linx} != $((w + 1)) ]]; then
+                       print -ru2 "E: U+${ch#16#} (line #$lno) bitmap line" \
+                           $((f[3] - i)) "invalid: '$line'"
+                       exit 2
+               fi
+               linx=${linx%'|'}
+               typeset -Uui16 -Z$uw bhex=2#$linx
+               (( bhex <<= shiftbits ))
+               r+=${bhex#16#}:
+       done
+       f[3]=${r%:}
+       f[0]=c
+}
+
+function parse_bdfc_glyph {
+       local last
+
+       set -A last
+       while IFS= read -r line; do
+               (( ++lno ))
+               if [[ $line = . ]]; then
+                       Fcomm+=("${last[@]}")
+                       state=0
+                       return
+               fi
+               if [[ $line = \' || $line = "' "* ]]; then
+                       last+=("$line")
+                       continue
+               fi
+               set -A f -- $line
+               if [[ ${f[0]} = d ]]; then
+                       Fdef="${f[*]}"
+                       continue
+               fi
+               if [[ ${f[0]} != [ce] ]]; then
+                       print -ru2 "E: invalid line #$lno: '$line'"
+                       exit 2
+               fi
+               if [[ $Fdef != 'd '* ]]; then
+                       print -ru2 "E: char at line $lno without defaults set"
+                       exit 2
+               fi
+               if [[ ${f[1]} != [0-9A-F][0-9A-F][0-9A-F][0-9A-F] ]]; then
+                       print -ru2 "E: invalid encoding '${f[1]}' at line $lno"
+                       exit 2
+               fi
+               typeset -Uui16 -Z7 ch=16#${f[1]}
+               if (( ${#f[*]} < 4 || ${#f[*]} > 5 )); then
+                       print -ru2 "E: invalid number of fields on line $lno" \
+                           "at U+${ch#16#}: ${#f[*]}: '$line'"
+                       exit 2
+               fi
+               if (( f[2] < 1 || f[2] > 32 )); then
+                       print -ru2 "E: width ${f[2]} not in 1‥32 at line $lno"
+                       exit 2
+               fi
+               [[ ${f[4]} = "uni${ch#16#}" ]] && unset f[4]
+               if [[ ${f[0]} = e ]]; then
+                       parse_bdfc_edit
+               else
+                       if (( f[2] <= 8 )); then
+                               x='+([0-9A-F][0-9A-F]:)'
+                       elif (( f[2] <= 16 )); then
+                               x='+([0-9A-F][0-9A-F][0-9A-F][0-9A-F]:)'
+                       elif (( f[2] <= 24 )); then
+                               x='+([0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]:)'
+                       else
+                               x='+([0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]:)'
+                       fi
+                       if eval [[ '${f[3]}:' != "$x" ]]; then
+                               print -ru2 "E: invalid hex encoding for" \
+                                   "U+${ch#16#}, line $lno: '${f[3]}'"
+                               exit 2
+                       fi
+               fi
+               Gdata[ch]="${f[*]}"
+               for line in "${last[@]}"; do
+                       Gcomm[ch]+=$line$'\n'
+               done
+               set -A last
+               Gprop[ch]=$Fdef
+       done
+       Fcomm+=("${last[@]}")
+       state=2
+}
+
+function parse_bdfc {
+       while :; do
+               case $state {
+               (0) parse_bdfc_file ;;
+               (1) parse_bdfc_glyph ;;
+               (2) return 0 ;;
+               }
+       done
+       print -ru2 "E: internal error (at line $lno), shouldn't happen"
+       exit 255
+}
+
+function parse_bdf {
+       while IFS= read -r line; do
+               (( ++lno ))
+               case $line {
+               (COMMENT)
+                       Fhead+=("'")
+                       ;;
+               (COMMENT@([      ])*)
+                       Fhead+=("' ${line#COMMENT[       ]}")
+                       ;;
+               (STARTPROPERTIES\ +([0-9]))
+                       break
+                       ;;
+               (*)
+                       Fhead+=("h$line")
+                       ;;
+               }
+       done
+       set -A f -- $line
+       numprop=${f[1]}
+       while IFS= read -r line; do
+               (( ++lno ))
+               case $line {
+               (COMMENT)
+                       Fprop+=("'")
+                       ;;
+               (COMMENT@([      ])*)
+                       Fprop+=("' ${line#COMMENT[       ]}")
+                       ;;
+               (ENDPROPERTIES)
+                       break
+                       ;;
+               (*)
+                       Fprop+=("p$line")
+                       let --numprop
+                       ;;
+               }
+       done
+       if (( numprop )); then
+               print -ru2 "E: expected ${f[1]} properties, got" \
+                   "$((f[1] - numprop)) in line $lno"
+               exit 2
+       fi
+       while IFS= read -r line; do
+               (( ++lno ))
+               case $line {
+               (COMMENT)
+                       Fprop+=("'")
+                       ;;
+               (COMMENT@([      ])*)
+                       Fprop+=("' ${line#COMMENT[       ]}")
+                       ;;
+               (CHARS\ +([0-9]))
+                       break
+                       ;;
+               (*)
+                       print -ru2 "E: expected CHARS not '$line' in line $lno"
+                       exit 2
+                       ;;
+               }
+       done
+       set -A f -- $line
+       numchar=${f[1]}
+       set -A cc
+       set -A cn
+       set -A ce
+       set -A cs
+       set -A cd
+       set -A cb
+       while IFS= read -r line; do
+               (( ++lno ))
+               case $line {
+               (COMMENT)
+                       cc+=("'")
+                       ;;
+               (COMMENT@([      ])*)
+                       cc+=("' ${line#COMMENT[  ]}")
+                       ;;
+               (STARTCHAR\ *)
+                       set -A cn -- $line
+                       ;;
+               (ENCODING\ +([0-9]))
+                       set -A ce -- $line
+                       ;;
+               (SWIDTH\ +([0-9-])\ +([0-9-]))
+                       set -A cs -- $line
+                       ;;
+               (DWIDTH\ +([0-9-])\ +([0-9-]))
+                       set -A cd -- $line
+                       ;;
+               (BBX\ +([0-9])\ +([0-9])\ +([0-9-])\ +([0-9-]))
+                       set -A cb -- $line
+                       ;;
+               (BITMAP)
+                       if [[ -z $cn ]]; then
+                               print -ru2 "E: missing STARTCHAR in line $lno"
+                               exit 2
+                       fi
+                       if [[ -z $ce ]]; then
+                               print -ru2 "E: missing ENCODING in line $lno"
+                               exit 2
+                       fi
+                       if [[ -z $cs ]]; then
+                               print -ru2 "E: missing SWIDTH in line $lno"
+                               exit 2
+                       fi
+                       if [[ -z $cd ]]; then
+                               print -ru2 "E: missing DWIDTH in line $lno"
+                               exit 2
+                       fi
+                       if [[ -z $cb ]]; then
+                               print -ru2 "E: missing BBX in line $lno"
+                               exit 2
+                       fi
+                       typeset -Uui16 -Z7 ch=10#${ce[1]}
+                       if (( ch < 0 || ch > 0xFFFF )); then
+                               print -ru2 "E: encoding ${ce[1]} out of" \
+                                   "bounds in line $lno"
+                               exit 2
+                       fi
+                       Gprop[ch]="d ${cs[1]} ${cs[2]} ${cd[1]} ${cd[2]} ${cb[3]} ${cb[4]}"
+                       set -A f c ${ch#16#} ${cb[1]} - ${cn[1]}
+                       [[ ${f[4]} = "uni${ch#16#}" ]] && unset f[4]
+                       if (( f[2] <= 8 )); then
+                               ck='[0-9A-F][0-9A-F]'
+                       elif (( f[2] <= 16 )); then
+                               ck='[0-9A-F][0-9A-F][0-9A-F][0-9A-F]'
+                       elif (( f[2] <= 24 )); then
+                               ck='[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]'
+                       else
+                               ck='[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]'
+                       fi
+                       if (( (numlines = cb[2]) )); then
+                               bmps=
+                               typeset -u linu
+                               while IFS= read -r linu; do
+                                       (( ++lno ))
+                                       if eval [[ '$linu' != "$ck" ]]; then
+                                               print -ru2 "E: invalid hex encoding" \
+                                                   "for U+${ch#16#} (dec. $((ch)))" \
+                                                   "on line $lno: '$linu'"
+                                               exit 2
+                                       fi
+                                       bmps+=$linu:
+                                       (( --numlines )) || break
+                               done
+                               f[3]=${bmps%:}
+                       else
+                               f[2]=1
+                               f[3]=00
+                       fi
+                       if ! IFS= read -r line || [[ $line != ENDCHAR ]]; then
+                               print -ru2 "E: expected ENDCHAR after line $lno"
+                               exit 2
+                       fi
+                       (( ++lno ))
+                       Gdata[ch]="${f[*]}"
+                       [[ -n $cc ]] && for line in "${cc[@]}"; do
+                               Gcomm[ch]+=$line$'\n'
+                       done
+                       set -A cc
+                       set -A cn
+                       set -A ce
+                       set -A cs
+                       set -A cd
+                       set -A cb
+                       ;;
+               (ENDFONT)
+                       break
+                       ;;
+               (*)
+                       print -ru2 "E: unexpected '$line' in line $lno"
+                       exit 2
+                       ;;
+               }
+       done
+       Fcomm+=("${cc[@]}")
+       for line in "${cn[*]}" "${ce[*]}" "${cs[*]}" "${cd[*]}" "${cb[*]}"; do
+               [[ -n $line ]] || continue
+               print -ru2 "E: unexpected '$line' between last char and ENDFONT"
+               exit 2
+       done
+       if (( numchar != ${#Gdata[*]} )); then
+               print -ru2 "E: expected $numchar glyphs, got ${#Gdata[*]}"
+               exit 2
+       fi
+       while IFS= read -r line; do
+               (( ++lno ))
+               case $line {
+               (COMMENT)
+                       Fcomm+=("'")
+                       ;;
+               (COMMENT@([      ])*)
+                       Fcomm+=("' ${line#COMMENT[       ]}")
+                       ;;
+               (*)
+                       print -ru2 "E: unexpected '$line' past ENDFONT" \
+                           "in line $lno"
+                       exit 2
+                       ;;
+               }
+       done
+}
+
+if [[ $mode = c ]]; then
+       if ! IFS= read -r line; then
+               print -ru2 "E: read error at BOF"
+               exit 2
+       fi
+       lno=1
+       if [[ $line = 'STARTFONT 2.1' ]]; then
+               parse_bdf
+       elif [[ $line = '=bdfc 1' ]]; then
+               parse_bdfc
+       else
+               print -ru2 "E: not BDF or bdfc at BOF: '$line'"
+               exit 2
+       fi
+
+       # write .bdfc stream
+
+       for line in '=bdfc 1' "${Fhead[@]}" "${Fprop[@]}"; do
+               print -r -- "$line"
+       done
+       print C
+       Fdef=
+       for x in ${!Gdata[*]}; do
+               if [[ ${Gprop[x]} != "$Fdef" ]]; then
+                       Fdef=${Gprop[x]}
+                       print -r -- $Fdef
+               fi
+               print -r -- "${Gcomm[x]}${Gdata[x]}"
+       done
+       for line in "${Fcomm[@]}"; do
+               print -r -- "$line"
+       done
+       print .
+       exit 0
+fi
+
+if [[ $mode = +e ]]; then
+       while IFS= read -r line; do
+               (( ++lno ))
+               if [[ $line = \' || $line = "' "* ]]; then
+                       print -r -- "$line"
+                       continue
+               fi
+               set -A f -- $line
+               if [[ ${f[0]} != [ce] ]]; then
+                       print -ru2 "E: invalid line #$lno: '$line'"
+                       exit 2
+               fi
+               if [[ ${f[1]} != [0-9A-F][0-9A-F][0-9A-F][0-9A-F] ]]; then
+                       print -ru2 "E: invalid encoding '${f[1]}' at line $lno"
+                       exit 2
+               fi
+               typeset -Uui16 -Z7 ch=16#${f[1]}
+               if (( ${#f[*]} < 4 || ${#f[*]} > 5 )); then
+                       print -ru2 "E: invalid number of fields on line $lno" \
+                           "at U+${ch#16#}: ${#f[*]}: '$line'"
+                       exit 2
+               fi
+               if (( f[2] < 1 || f[2] > 32 )); then
+                       print -ru2 "E: width ${f[2]} not in 1‥32 at line $lno"
+                       exit 2
+               fi
+               [[ ${f[4]} = "uni${ch#16#}" ]] && unset f[4]
+               if [[ ${f[0]} = e ]]; then
+                       parse_bdfc_edit
+               else
+                       if (( f[2] <= 8 )); then
+                               x='+([0-9A-F][0-9A-F]:)'
+                       elif (( f[2] <= 16 )); then
+                               x='+([0-9A-F][0-9A-F][0-9A-F][0-9A-F]:)'
+                       elif (( f[2] <= 24 )); then
+                               x='+([0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]:)'
+                       else
+                               x='+([0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]:)'
+                       fi
+                       if eval [[ '${f[3]}:' != "$x" ]]; then
+                               print -ru2 "E: invalid hex encoding for" \
+                                   "U+${ch#16#}, line $lno: '${f[3]}'"
+                               exit 2
+                       fi
+               fi
+               print -r -- "${f[@]}"
+       done
+       exit 0
+fi
+
+if [[ $mode != d ]]; then
+       print -ru2 "E: cannot happen (control flow issue in ${0##*/}:$LINENO)"
+       exit 255
+fi
+
+if ! IFS= read -r line; then
+       print -ru2 "E: read error at BOF"
+       exit 2
+fi
+lno=1
+if [[ $line != '=bdfc 1' ]]; then
+       print -ru2 "E: not bdfc at BOF: '$line'"
+       exit 2
+fi
+
+if (( ufast )); then
+       if ! T=$(mktemp /tmp/bdfctool.XXXXXXXXXX); then
+               print -u2 E: cannot make temporary file
+               exit 4
+       fi
+       # quickly parse bdfc header
+       set -A last
+       while IFS= read -r line; do
+               [[ $line = C ]] && break
+               last+=("$line")
+               [[ $line = \' || $line = "' "* ]] && continue
+               if [[ $line = h* ]]; then
+                       Fhead+=("${last[@]}")
+               else
+                       Fprop+=("${last[@]}")
+               fi
+               set -A last
+       done
+       Fprop+=("${last[@]}")
+else
+       # parse entire bdfc file into memory
+       parse_bdfc
+fi
+
+# analyse data for BDF
+numprop=0
+for line in "${Fprop[@]}"; do
+       [[ $line = p* ]] && let ++numprop
+done
+(( ufast )) || numchar=${#Gdata[*]}
+
+# write BDF stream
+print 'STARTFONT 2.1'
+for line in "${Fhead[@]}"; do
+       if [[ $line = h* ]]; then
+               print -r -- "${line#h}"
+       else
+               print -r -- "COMMENT${line#\'}"
+       fi
+done
+set -A last
+print STARTPROPERTIES $((numprop))
+for line in "${Fprop[@]}"; do
+       if [[ $line = p* ]]; then
+               last+=("${line#p}")
+       else
+               last+=("COMMENT${line#\'}")
+               continue
+       fi
+       for line in "${last[@]}"; do
+               print -r -- "$line"
+       done
+       set -A last
+done
+print ENDPROPERTIES
+for line in "${last[@]}"; do
+       print -r -- "$line"
+done
+if (( ufast )); then
+       numchar=0
+       # directly transform font data
+       set -A last
+       while IFS= read -r line; do
+               [[ $line = . ]] && break
+               if [[ $line = \' || $line = "' "* ]]; then
+                       last+=("$line")
+                       continue
+               fi
+               set -A f -- $line
+               if [[ ${f[0]} = d ]]; then
+                       set -A xprop -- $line
+                       continue
+               fi
+               typeset -Uui16 -Z7 ch=16#${f[1]}
+               for line in "${last[@]}"; do
+                       print -r -- "COMMENT${line#\'}"
+               done
+               set -A last
+               IFS=:
+               set -A bmp -- ${f[3]}
+               IFS=$' \t\n'
+               cat <<-EOF
+                       STARTCHAR ${f[4]:-uni${ch#16#}}
+                       ENCODING $((ch))
+                       SWIDTH ${xprop[1]} ${xprop[2]}
+                       DWIDTH ${xprop[3]} ${xprop[4]}
+                       BBX ${f[2]} ${#bmp[*]} ${xprop[5]} ${xprop[6]}
+                       BITMAP
+               EOF
+               for line in "${bmp[@]}"; do
+                       print $line
+               done
+               print ENDCHAR
+               let ++numchar
+       done >"$T"
+       Fcomm+=("${last[@]}")
+       print CHARS $((numchar))
+       cat "$T"
+       rm -f "$T"
+else
+       print CHARS $((numchar))
+       for x in ${!Gdata[*]}; do
+               IFS=$'\n'
+               set -A xcomm -- ${Gcomm[x]}
+               IFS=$' \t\n'
+               for line in "${xcomm[@]}"; do
+                       print -r -- "COMMENT${line#\'}"
+               done
+               set -A xprop -- ${Gprop[x]}
+               set -A f -- ${Gdata[x]}
+               IFS=:
+               set -A bmp -- ${f[3]}
+               IFS=$' \t\n'
+               typeset -Uui16 -Z7 ch=16#${f[1]}
+               cat <<-EOF
+                       STARTCHAR ${f[4]:-uni${ch#16#}}
+                       ENCODING $((ch))
+                       SWIDTH ${xprop[1]} ${xprop[2]}
+                       DWIDTH ${xprop[3]} ${xprop[4]}
+                       BBX ${f[2]} ${#bmp[*]} ${xprop[5]} ${xprop[6]}
+                       BITMAP
+               EOF
+               for line in "${bmp[@]}"; do
+                       print $line
+               done
+               print ENDCHAR
+       done
+fi
+for line in "${Fcomm[@]}"; do
+       print -r -- "COMMENT${line#\'}"
+done
+print ENDFONT
+exit 0
diff --git a/mksh/bin2print b/mksh/bin2print
new file mode 100644 (file)
index 0000000..9d838d2
--- /dev/null
@@ -0,0 +1,61 @@
+#!/bin/mksh
+# $MirOS: contrib/hosted/tg/bin2print,v 1.1 2013/04/09 23:02:12 tg Exp $
+#-
+# Copyright © 2013
+#      Thorsten Glaser <tg@mirbsd.org>
+#
+# 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.
+#-
+# Converts stdin to an mksh print statement producing identical, NUL
+# safe, output for embedding (statement is not UTF-8 clean).
+
+set +U
+read -arN -1 line || exit 1
+typeset -Uui16 -Z5 hv
+typeset -i1 ch
+imax=${#line[*]}
+i=0
+s="print -n -- '"
+while (( i < imax )); do
+       hv=${line[i++]}
+       if (( hv == 92 )); then
+               s+='\\'
+       elif (( hv == 39 || hv == 126 )); then
+               s+='\x'${hv#16#}
+       elif (( hv > 31 )); then
+               let ch=hv
+               s+=${ch#1#}
+       elif (( !hv )); then
+               s+='\x00'
+       elif (( hv == 7 )); then
+               s+='\a'
+       elif (( hv == 8 )); then
+               s+='\b'
+       elif (( hv == 12 )); then
+               s+='\f'
+       elif (( hv == 10 )); then
+               s+='\n'
+       elif (( hv == 13 )); then
+               s+='\r'
+       elif (( hv == 9 )); then
+               s+='\t'
+       elif (( hv == 11 )); then
+               s+='\v'
+       else
+               s+='\x'${hv#16#}
+       fi
+done
+print -r -- "$s'" | sed 's/\\x00\([^0-9A-Fa-f]\)/\\0\1/g'
diff --git a/mksh/clock b/mksh/clock
new file mode 100644 (file)
index 0000000..f0c8b90
--- /dev/null
@@ -0,0 +1,179 @@
+#!/bin/mksh
+# Copyright © 2009, 2013
+#      Dominik George <nik@naturalnet.de>
+#      Felix Falk <felix@b9d.de>
+#
+# 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.
+
+# Config
+
+CONFIG_DIGITAL=true
+
+# Check dependencies
+if [ ! -x $(which bc) ]; then
+       echo "bc not found, install bc!"
+       exit 1
+fi
+
+bc -ql |&
+
+# Definitions
+PI=$(echo "4*a(1)" | bc -l)
+
+# Library
+function cobc {
+       print -p -- "${1}"
+       read -p result
+       echo "${result}"
+}
+
+function deg2rad {
+       cobc "${1}/180*${PI}"
+}
+
+function sine {
+       cobc "s($(deg2rad ${1}))"
+}
+
+function cosine {
+       cobc "c($(deg2rad ${1}))"
+}
+
+function round {
+       local x=$1
+       local pre=${x%%.*}
+       local post=${x#*.}
+       local postone=${post:1:1}
+
+       if [ "${pre}" = "-" ]; then
+               pre=${pre/#-\$/0}
+       fi
+
+       if [ -n ${postone} ]; then
+               echo ${pre}
+       else
+               echo $((pre + 1))
+       fi
+}
+
+function drawpoint {
+       local deg=$1
+       local percent=$2
+
+       local char=$3
+       local mirror=$4
+
+       radx=$(cobc "${RADIUSX} * ${percent} / 100")
+       rady=$(cobc "${RADIUSY} * ${percent} / 100")
+
+       xoff=$(round $(cobc "$(sine ${deg}) * ${radx}"))
+       yoff=$(round $(cobc "$(cosine ${deg}) * ${rady}"))
+
+       echo -ne "\033[$((MIDDLEY + yoff));$((MIDDLEX + xoff))H${char}"
+
+       if [ ${mirror} = true ]; then
+               echo -ne "\033[$((MIDDLEY - yoff));$((MIDDLEX + xoff))H${char}"
+               echo -ne "\033[$((MIDDLEY + yoff));$((MIDDLEX - xoff))H${char}"
+               echo -ne "\033[$((MIDDLEY - yoff));$((MIDDLEX - xoff))H${char}"
+       fi
+}
+
+# Clear terminal
+clear
+
+# Determine clock size from terminal size
+if [ ${COLUMNS} -ge $((LINES * 2)) ]; then
+       HEIGHT=$((LINES - 2))
+       WIDTH=$((HEIGHT * 2))
+else
+       WIDTH=$((COLUMNS - 2))
+       HEIGHT=$((WIDTH / 2))
+fi
+
+# Determine clock position
+TOP=$(((LINES - HEIGHT)/2))
+
+LEFT=$(((COLUMNS - WIDTH)/2))
+MIDDLEX=$((COLUMNS/2))
+
+MIDDLEY=$((LINES/2))
+RADIUSX=$((MIDDLEX - LEFT))
+
+RADIUSY=$((MIDDLEY - TOP))
+
+# Draw border
+for deg in $(seq 0 1 90); do
+       if [ ${deg} -ge 0 -a ${deg} -le 5 -o ${deg} -ge 25 -a ${deg} -le 35 -o ${deg} -ge 55 -a ${deg} -le 65 -o ${deg} -ge 83 -a ${deg} -le 90 ]; then
+               char=x
+       else
+               char=.
+       fi
+
+       drawpoint ${deg} 100 ${char} true
+done
+
+# Get time
+hour=$(date +"%H")
+min=$(date +"%M")
+sec=$(date +"%S")
+
+# Hours
+for percent in $(seq 0 1 60); do
+       deg=$((180 - (((hour * 60 + min) % 720) / 2)))
+
+       if [ ${deg} -lt 0 ]; then
+               deg=$((360 + deg))
+       fi
+
+       drawpoint ${deg} ${percent} x false
+done
+
+# Minutes
+for percent in $(seq 0 1 85); do
+       deg=$((180 - (min * 6)))
+
+       if [ ${deg} -lt 0 ]; then
+               deg=$((360 + deg))
+       fi
+
+       drawpoint ${deg} ${percent} + false
+done
+
+# Seconds
+for percent in $(seq 0 1 85); do
+       deg=$((180 - (sec * 6)))
+
+       if [ ${deg} -lt 0 ]; then
+               deg=$((360 + deg))
+       fi
+
+       drawpoint ${deg} ${percent} . false
+done
+
+# Draw center
+echo -ne "\033[${MIDDLEY};${MIDDLEX}HX"
+
+
+# Print digital clock if requested
+if [ ${CONFIG_DIGITAL} = true ]; then
+       echo -ne "\033[$((MIDDLEY + (HEIGHT / 4)));$((MIDDLEX - 4))H${hour}:${min}:${sec}"
+fi
+
+# Set cursor to bottom left corner
+echo -ne "\033[${LINES};1HPress any key to exit"
+read
+
+exit 0
diff --git a/mksh/conninfo.cgi b/mksh/conninfo.cgi
new file mode 100644 (file)
index 0000000..2df02b9
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/mksh
+# $MirOS: contrib/hosted/tg/conninfo.cgi,v 1.4 2008/12/10 15:06:00 tg Exp $
+#-
+# Copyright (c) 2008
+#      Thorsten Glaser <tg@mirbsd.org>
+#
+# 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.
+
+print Content-type: text/plain
+print Entropy: $RANDOM
+print RCSID: '$MirOS: contrib/hosted/tg/conninfo.cgi,v 1.4 2008/12/10 15:06:00 tg Exp $'
+print
+if [[ -z $HTTPS ]]; then
+       print -n "INSECURE (non-SSL) "
+else
+       print -n "SSL "
+       [[ -z $SSL_PROTOCOL ]] || print -nr "($SSL_PROTOCOL"
+       [[ -z $SSL_CIPHER ]] || print -nr ":$SSL_CIPHER"
+       print -n ") "
+fi
+if [[ $REMOTE_ADDR = +([0-9]).+([0-9]).+([0-9]).+([0-9]) ]]; then
+       print -n IPv4
+elif [[ $REMOTE_ADDR = +([0-9a-fA-F:]):+([0-9a-fA-F:]) ]]; then
+       print -n IPv6
+else
+       print -n AF_UNKNOWN
+fi
+print -r " connection from [$REMOTE_ADDR]:$REMOTE_PORT
+$SERVER_PROTOCOL request to [$SERVER_ADDR]:$SERVER_PORT ($SERVER_NAME)"
+[[ ,$QUERY_STRING, = *,ua,* ]] && print "using $HTTP_USER_AGENT"
+exit 0
diff --git a/mksh/csrgen.cgi b/mksh/csrgen.cgi
new file mode 100644 (file)
index 0000000..4d84351
--- /dev/null
@@ -0,0 +1,123 @@
+#!/bin/mksh
+# $Id: csrgen 4043 2014-05-23 09:35:30Z tglase $
+#-
+# Copyright © 2010, 2011, 2014
+#      Thorsten Glaser <t.glaser@tarent.de>
+#
+# 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.
+
+feedback=
+nl='
+'
+saveIFS="      $nl"
+function trytodoit {
+       if [[ $REQUEST_METHOD != GET ]]; then
+               feedback="Not called via HTTP GET."
+               return
+       fi
+       if [[ $HTTPS != on ]]; then
+               feedback="Not called via HTTPS."
+               return
+       fi
+       IFS='&'
+       set -A flds -- $QUERY_STRING
+       IFS=$saveIFS
+       xfqdn=
+       xstrength=
+       xaction=0
+       for fld in "${flds[@]}"; do
+               case ${fld%%=*} {
+               (fqdn) xfqdn=${fld#*=} ;;
+               (strength) xstrength=${fld#*=} ;;
+               (doit) xaction=${fld#*=} ;;
+               (*) feedback="Invalid QUERY_STRING."; return ;;
+               }
+       done
+       [[ $xaction = 0 ]] && return
+       if [[ $xaction != Erstellen ]]; then
+               feedback="Submit button not pressed."
+               return
+       fi
+       if [[ $xstrength != @(2048|3072|4096) ]]; then
+               feedback="Invalid strength given."
+               return
+       fi
+       if [[ $xfqdn != ?('*.')[a-zA-Z0-9]?(*([a-zA-Z0-9-])[a-zA-Z0-9])+(.[a-zA-Z0-9]?(*([a-zA-Z0-9-])[a-zA-Z0-9])) ]]; then
+               feedback="Invalid hostname (FQDN) given."
+               return
+       fi
+       if ! K=$(openssl genrsa $xstrength 2>/dev/null); then
+               feedback="Could not generate $xstrength bit secret key."
+               return
+       fi
+       if ! R=$(print -r -- "$K" | openssl req -batch -new -sha1 \
+           -config /openssl.cnf -subj "/CN=${xfqdn}/" -key /dev/stdin \
+           2>/dev/null); then
+               feedback="Could not generate CSR for ${xfqdn}."
+               return
+       fi
+       cat <<-EOF
+       Content-type: text/plain
+
+       Congratulations, I generated a CSR for ${xfqdn} for you to
+       copy and paste into the CA web form:
+
+       $R
+
+
+       The secret key (for /etc/ssl/private/\$foo.key - chown root:ssl-cert
+       chmod 0640) of ${xstrength} bit length is:
+
+       $K
+
+       I will not save any copies of this, make sure to protect them!
+EOF
+       K=
+       R=
+       exit 0
+}
+trytodoit
+
+cat <<'EOF'
+Content-type: text/html; charset=UTF-8
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head>
+ <title>Generierung eines Certificate Signing Request</title>
+ <style type="text/css"><!--/*--><![CDATA[/*><!--*/
+       strong { background-color:#FF0000; color:#000000; }
+ /*]]>*/--></style>
+</head><body>
+<h1>Generierung eines Certificate Signing Request</h1>
+EOF
+[[ -z $feedback ]] || print -r -- "<p><strong>$feedback</strong></p>"
+if [[ $HTTPS != on ]]; then
+       echo '</body></html>'
+       exit 1
+fi
+cat <<'EOF'
+<form action="csrgen" method="get">
+<p>Hostname: <input name="fqdn" type="text" size="32" maxlength="255" /></p>
+<p>Stärke:<br />
+ <input type="radio" name="strength" value="2048" checked="checked" />2048 Bit<br />
+ <input type="radio" name="strength" value="3072" />3072 Bit<br />
+ <input type="radio" name="strength" value="4096" />4096 Bit
+</p>
+<p><input type="submit" name="doit" value="Erstellen" /></p>
+</form>
+</body></html>
+EOF
diff --git a/mksh/cvs-switchroot b/mksh/cvs-switchroot
new file mode 100644 (file)
index 0000000..934845e
--- /dev/null
@@ -0,0 +1,99 @@
+#!/bin/mksh
+# $MirOS: contrib/hosted/tg/deb/cvs/debian/cvs-switchroot,v 1.1 2011/06/10 23:44:12 tg Exp $
+#-
+# Copyright © 2005, 2008, 2011
+#      Thorsten “mirabilos” Glaser <tg@mirbsd.org>
+#
+# 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.
+#-
+# Change CVSROOT of a checked out tree (and save space with it)
+# With option -T: change Tag instead of Root
+
+me=${0##*/}
+if [[ $1 = -T ]]; then
+       tagmode=-T
+       fn=Tag
+       shift
+else
+       tagmode=
+       fn=Root
+fi
+newroot=$1
+useroot=0
+if [[ $newroot = - ]]; then
+       shift
+       newroot=$(realpath "$1")
+       [[ -d $newroot ]] && if [[ -d $newroot/CVS ]]; then
+               newroot=$newroot/CVS/$fn
+       else
+               newroot=$newroot/$fn
+       fi
+       useroot=1
+fi
+if [[ -z $newroot || $newroot = -? ]]; then
+       print -u2 "Syntax: $me newroot [dir [...]]"
+       print -u2 "\t$me - .../CVS/Root [dir [...]]"
+       print -u2 "\t$me -T - .../CVS/Tag [dir [...]]"
+       exit 1
+fi
+shift
+
+[[ -z $1 ]] && set -- .
+
+# realpath(2)ise arguments
+set -A arg
+let i=0
+for name in "$@"; do
+       arg[i++]=$(realpath "$name")
+done
+
+if ! T="$(mktemp ${arg[0]}/$me.XXXXXXXXXX)"; then
+       print -u2 "$me: fatal: cannot mktemp"
+       exit 1
+fi
+
+if (( useroot )); then
+       rm -f "$T"
+       ln "$newroot" "$T" || cp "$newroot" "$T"
+fi
+
+trap 'rm -f "$T"; exit 0' 0
+trap 'rm -f "$T"; trap - EXIT; exit 1' 1 2 3 5 13 15
+
+if (( !useroot )); then
+       chmod 664 "$T"
+       print -r -- "$newroot" >"$T"
+fi
+
+let rv=0
+find "${arg[@]}" -path \*/CVS/$fn -print0 |&
+while IFS= read -d '' -pr name; do
+       if ! rm "$name"; then
+               print -u2 "$me: error: cannot rm <$name>"
+               exit 1
+       fi
+       ln -f "$T" "$name" || if ! U="$(mktemp ${arg[0]}/$me.XXXXXXXXXX)"; then
+               cp "$T" "$name"
+       elif cat "$T" >"$U" && ln -f "$U" "$name"; then
+               rm -f "$T"
+               T="$U"
+       else
+               rm -f "$U"
+               cp "$T" "$name"
+       fi
+done
+
+exit 0
diff --git a/mksh/cvs-switchroot.1 b/mksh/cvs-switchroot.1
new file mode 100644 (file)
index 0000000..1ffe5b6
--- /dev/null
@@ -0,0 +1,78 @@
+.\" $MirOS: contrib/hosted/tg/deb/cvs/debian/cvs-switchroot.1,v 1.2 2011/06/24 16:16:06 tg Exp $
+.\"
+.Dd June 10, 2011
+.Dt CVS\-SWITCHROOT 1
+.Os
+.Sh NAME
+.Nm cvs\-switchroot
+.Nd change repository or tag in a cvs working copy
+.Sh SYNOPSIS
+.Nm
+.Op Fl T
+.Ar newroot
+.Op Ar
+.Pp
+.Nm
+.Op Fl T
+\-\&
+.Ar srcpath
+.Op Ar
+.Sh DESCRIPTION
+The
+.Nm
+utility manipulates a CVS working copy directly,
+modifying the information stored in the administrative
+subdirectory and saving space by hardlinking if possible.
+.Pp
+If the
+.Fl T
+option is given, the sticky tag is operated on,
+otherwise, the repository path
+.Pq Ev CVSROOT .
+.Pp
+The information (Tag or Root) is set to the same as in
+.Ar srcpath
+if the first non-option argument
+.Ar newroot
+is a sole dash
+.Pq Sq \-\& ,
+the literal value
+.Ar newroot
+otherwise.
+.Sh EXAMPLES
+Change all
+.Pa Root
+information in the current sandbox to 
+.Pa /cvs :
+.Bd -literal -offset ident
+$ cvs-switchroot /cvs .
+.Ed
+.Pp
+Set all roots in the current working directory and all
+its subdirectories to the
+.Pa Root
+of the parent directory:
+.Bd -literal -offset ident
+$ cvs-switchroot \- .. .
+.Ed
+.Pp
+Hardlink the
+.Pa Tag
+information in the current working directory, for example
+.Pa /usr/src ,
+and
+.Pa /usr/ports
+with each other:
+.Bd -literal -offset ident
+$ cvs-switchroot \-T \- . . /usr/ports
+.Ed
+.Sh SEE ALSO
+.Xr cvs 1
+.Sh HISTORY
+.Nm
+has existed in the MirBSD source tree since 2005.
+It was added to Debian's cvs package in 2011.
+.Sh CAVEATS
+.Nm
+depends on
+.Nm mksh .
diff --git a/mksh/debian-dev/BuildDSC.sh b/mksh/debian-dev/BuildDSC.sh
new file mode 100644 (file)
index 0000000..6df0fa8
--- /dev/null
@@ -0,0 +1,141 @@
+#!/bin/mksh
+# $MirOS: contrib/hosted/tg/deb/BuildDSC.sh,v 1.14 2011/11/17 15:27:53 tg Exp $
+#-
+# Copyright (c) 2010, 2011
+#      Thorsten Glaser <t.glaser@tarent.de>
+#
+# 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.
+#-
+# The current working directory, or else the directory in which this
+# script resides, must be the root directory of a (extracted) Debian
+# source package. It will then be renamed to the proper dirname, and
+# a source package (*.dsc + others) will be created, then it will be
+# renamed back.
+# -s arg: make a snapshot with "arg" being the version number suffix
+# -S: build a snapshot with snapshot.YYYYMMDD.HHMMSS (UTC) as suffix
+# Any further arguments will be passed to debian/rules via MAKEFLAGS
+
+# sanitise environment
+unset LANGUAGE
+export LC_ALL=C
+cd "$(realpath .)"
+
+# preload
+sync
+date >/dev/null
+stime_rfc=$(date +"%a, %d %b %Y %H:%M:%S %z")
+stime_vsn=$(date -u +"%Y%m%d.%H%M%S")
+
+snap=0
+ssuf=
+while getopts "Ss:" ch; do
+       case $ch {
+       (S)     snap=1
+               ssuf=snapshot.$stime_vsn
+               ;;
+       (s)     snap=1
+               ssuf=$OPTARG
+               ;;
+       (*)     print -u2 Syntax error.
+               exit 1
+               ;;
+       }
+done
+shift $((OPTIND - 1))
+export MAKEFLAGS="$*"
+
+if (( snap )) && [[ -z $DEBEMAIL ]]; then
+       print -u2 'Please set $DEBEMAIL to "First M. Last <email@domain.com>"'
+       exit 1
+fi
+
+rmc=0
+while :; do
+       echo >&2 "=== trying . = $(pwd)"
+       dh_testdir >/dev/null 2>&1 && break
+       if [[ -s debian/control.in && -s debian/rules && \
+           -x debian/rules && ! -e debian/control ]]; then
+               rmc=1
+               debian/rules debian/control
+       fi
+       dh_testdir >/dev/null 2>&1 && break
+       (( rmc )) && debian/rules remove/control
+       rmc=0
+       cd "$(dirname "$0")"
+       print -u2 "=== trying basedir = $(pwd)"
+       dh_testdir >/dev/null 2>&1 && break
+       if [[ -s debian/control.in && -s debian/rules && \
+           -x debian/rules && ! -e debian/control ]]; then
+               rmc=1
+               debian/rules debian/control
+       fi
+       dh_testdir >/dev/null 2>&1 && break
+       (( rmc )) && debian/rules remove/control
+       print -u2 "FAILED! Please change to the correct directory."
+       exit 1
+done
+mydir=$(pwd)
+pkgstem=$(dpkg-parsechangelog -n1 | sed -n '/^Source: /s///p')
+version=$(dpkg-parsechangelog -n1 | sed -n '/^Version: /s///p')
+if (( snap )); then
+       updir=$(cd ..; pwd)
+       if ! T=$(mktemp "$updir/BuildDSC.tmp.XXXXXXXXXX"); then
+               (( rmc )) && debian/rules remove/control
+               print -u2 Could not create temporary file.
+               exit 1
+       fi
+       cat debian/changelog >"$T"
+       touch -r debian/changelog "$T"
+       dist=$(dpkg-parsechangelog -n1 | sed -n '/^Distribution: /s///p')
+       if [[ $dist = UNRELEASED || $dist = x* ]]; then
+               # we’re at “current” already, reduce
+               version=$version'~'$ssuf
+       else
+               # we’re at an uploaded version, raise
+               version=$version'+'$ssuf
+       fi
+       print "$pkgstem ($version) UNRELEASED; urgency=low\n\n  *" \
+           "Automatically built snapshot (not backport) package.\n\n --" \
+           "$DEBEMAIL  $stime_rfc\n" >debian/changelog
+       cat "$T" >>debian/changelog
+       touch -r "$T" debian/changelog
+       if (( rmc )); then
+               rm -f debian/control
+               debian/rules debian/control
+       fi
+fi
+upstreamversion=${version%%-*([!-])}
+upstreamversion=${upstreamversion#+([0-9]):}
+cd ..
+curname=${mydir##*/}
+newname=$pkgstem-$upstreamversion
+[[ $newname = $curname ]] || mv "$curname" "$newname"
+cd "$newname"
+dpkg-buildpackage -rfakeroot -S -I -i
+rv=$?
+fakeroot debian/rules clean
+cd ..
+[[ $newname = $curname ]] || mv "$newname" "$curname"
+
+cd "$curname"
+if (( snap )); then
+       cat "$T" >debian/changelog
+       touch -r "$T" debian/changelog
+       rm -f "$T"
+fi
+(( rmc )) && debian/rules remove/control
+
+exit $rv
diff --git a/mksh/debian-dev/c b/mksh/debian-dev/c
new file mode 100644 (file)
index 0000000..c7f42d1
--- /dev/null
@@ -0,0 +1,116 @@
+#!/bin/mksh
+#-
+# Copyright © 2013, 2014
+#      Thorsten “mirabilos” Glaser <t.glaser@tarent.de>
+#
+# 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.
+#-
+# Simple-to-use wrapper around eatmydata plus cowbuilder to use with
+# https://www.mirbsd.org/cvs.cgi/contrib/hosted/tg/deb/pbuilderrc to
+# select the proper build chroot.
+#
+# Example:
+# c lenny/i386 DEB_BUILD_OPTIONS=parallel=4 linux32 --build foo*.dsc
+
+unset LANGUAGE
+export LC_ALL=C
+
+if [[ -z $1 ]]; then
+       print -u2 E: No operation specified
+       exit 1
+fi
+DIST=$1
+
+# workaround for supporting old and new eatmydata; cf. #765579
+eatmydata='LD_LIBRARY_PATH=/usr/lib/libeatmydata LD_PRELOAD=libeatmydata.so'
+# disable for some distros without either
+case ${DIST%/*} {
+(sarge|sarge-*|etch|etch-*)
+       eatmydata=LD_PRELOAD=
+       ;;
+}
+if [[ $1 = --keepmydata ]]; then
+       eatmydata=LD_PRELOAD=
+       shift
+fi
+
+# construct command line
+set -A cmd env "DIST=$DIST" LANG=C LC_CTYPE=C LC_NUMERIC=C \
+    LC_TIME=C LC_COLLATE=C LC_MONETARY=C LC_MESSAGES=C LC_PAPER=C \
+    LC_NAME=C LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=C \
+    LC_IDENTIFICATION=C LC_ALL=C $eatmydata
+shift
+while [[ $1 = *=* ]]; do
+       cmd[${#cmd[@]}]=$1
+       shift
+done
+setarch_seen=0
+case $1 {
+(--)
+       shift
+       ;;
+(linux32|linux64)
+       cmd[${#cmd[@]}]=$1
+       shift
+       if [[ $1 = --uname-2.6 ]]; then
+               cmd[${#cmd[@]}]=$1
+               shift
+       fi
+       setarch_seen=1
+       ;;
+}
+#XXX add more architectures
+case $DIST {
+(*/amd64)      setarch_cmd=linux64 ;;
+(*/i386)       setarch_cmd=linux32 ;;
+(*/x32)                setarch_cmd=linux64 ;;
+(*/*)          setarch_cmd= ;;
+(*)            setarch_cmd=- ;;
+}
+case ${DIST%/*} {
+(sarge|sarge-*)                setarch_26=1 ;;
+(etch|etch-*)          setarch_26=1 ;;
+(lenny|lenny-*)                setarch_26=1 ;;
+(squeeze|squeeze-*)    setarch_26=1 ;;
+(dapper|dapper-*)      setarch_26=1 ;;
+(hardy|hardy-*)                setarch_26=1 ;;
+(jaunty|jaunty-*)      setarch_26=1 ;;
+(karmic|karmic-*)      setarch_26=1 ;;
+(lucid|lucid-*)                setarch_26=1 ;;
+(maverick|maverick-*)  setarch_26=1 ;;
+(natty|natty-*)                setarch_26=1 ;;
+(*)                    setarch_26=0 ;;
+}
+(( setarch_seen )) || case x$setarch_cmd {
+(x)
+       print -ru2 "W: no setarch for architecture part of '$DIST'!"
+       ;;
+(x-)
+       if (( setarch_26 )); then
+               cmd[${#cmd[@]}]=setarch
+               cmd[${#cmd[@]}]=uname26
+               cmd[${#cmd[@]}]=--
+       fi
+       ;;
+(*)
+       cmd[${#cmd[@]}]=$setarch_cmd
+       (( setarch_26 )) && cmd[${#cmd[@]}]=--uname-2.6
+       cmd[${#cmd[@]}]=--
+       ;;
+}
+
+set -x
+exec sudo "${cmd[@]}" cowbuilder "$@"
diff --git a/mksh/debian-dev/debextract b/mksh/debian-dev/debextract
new file mode 100644 (file)
index 0000000..98a66f5
--- /dev/null
@@ -0,0 +1,45 @@
+#!/bin/mksh
+#-
+# Copyright © 2014
+#      Thorsten “mirabilos” Glaser <t.glaser@tarent.de>
+#
+# 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.
+
+function die {
+       print -ru2 -- "E: $*"
+       exit 1
+}
+
+[[ -s $1 ]] || die need package to extract
+
+cd "$(realpath "$1/..")" || die cannot cd
+fn=${1##*/}
+
+[[ $fn = *.dsc ]] && exec dpkg-source -x "$fn"
+
+[[ $fn = *.deb ]] || die not a Debian source or binary package
+dn=${fn%.deb}-extracted
+
+set -e
+rm -rf "$dn"
+mkdir "$dn"
+cd "$dn"
+paxtar xapf ../"$fn"
+mkdir c d
+cd c
+paxtar xapf ../control.*
+cd ../d
+paxtar xapf ../data.*
diff --git a/mksh/debian-dev/debrepack b/mksh/debian-dev/debrepack
new file mode 100644 (file)
index 0000000..10eb9e2
--- /dev/null
@@ -0,0 +1,87 @@
+#!/bin/mksh
+#-
+# Copyright © 2015
+#      Thorsten “mirabilos” Glaser <tg@mirbsd.org>
+#
+# 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.
+
+function die {
+       print -ru2 -- "E: $*"
+       exit 1
+}
+
+function chkdir {
+       local i x
+
+       [[ -s debian-binary ]] || return 1
+       [[ $(<debian-binary) = 2.0 ]] || return 1
+       [[ -d c && -d d ]] || return 1
+       i=0; for x in control.*; do
+               [[ $x = *.tar@(|.gz|.xz) ]] || return 1
+               let i++
+       done
+       (( i == 1 )) || return 1
+       i=0; for x in data.*; do
+               [[ $x = *.tar@(|.bz2|.gz|.xz) ]] || return 1
+               let i++
+       done
+       (( i == 1 )) || return 1
+       [[ -s c/control ]]
+}
+
+while ! chkdir; do
+       [[ $(realpath .) = +(/) ]] && die cannot find top-level dir
+       cd ..
+done
+
+for cf in control.*; do
+       case $cf {
+       (*.tar) cc=cat ;;
+       (*.tar.gz) cc='gzip -n9' ;;
+       (*.tar.xz) cc='xz -2' ;;
+       (*) die "huh? control.* = $cf" ;;
+       }
+       break
+done
+for df in data.*; do
+       case $df {
+       (*.tar) dc=cat ;;
+       (*.tar.bz2) dc='bzip2' ;;
+       (*.tar.gz) dc='gzip -n9' ;;
+       (*.tar.xz) dc='xz' ;;
+       (*) die "huh? data.* = $df" ;;
+       }
+       break
+done
+
+fp=$(sed -n '/^Package: /s///p' c/control)
+fv=$(sed -n '/^Version: /s///p' c/control)
+fa=$(sed -n '/^Architecture: /s///p' c/control)
+[[ $fp = +([a-zA-Z0-9.+~:-]) ]] || die "huh? fp $fp"
+[[ $fv = +([a-zA-Z0-9.+~:-]) ]] || die "huh? fv $fv"
+[[ $fa = +([a-zA-Z0-9.+~:-]) ]] || die "huh? fa $fa"
+
+set -o pipefail
+set -ex
+
+(cd d && find . -type f | sed s,^./,, | sort | xargs md5sum --) >c/md5sums
+(cd d && find . | sort | paxcpio -oC512 -Hustar -Minodes -Mlinks -Muidgid -Mgslash) | \
+    $dc >"$df"
+(cd c && chmod 644 *)
+(cd c && find . | sort | paxcpio -oC512 -Hustar -Minodes -Mlinks -Muidgid -Mgslash) | \
+    $cc >"$cf"
+
+paxtar -A -M dist -cf "${fp}_${fv}_${fa}.deb" debian-binary "$cf" "$df"
diff --git a/mksh/debian-dev/dot.quiltrc b/mksh/debian-dev/dot.quiltrc
new file mode 100644 (file)
index 0000000..a80eeab
--- /dev/null
@@ -0,0 +1,44 @@
+# $MirOS: contrib/hosted/tg/deb/dot.quiltrc,v 1.5 2013/12/31 10:17:32 tg Exp $
+#-
+# Configuration options (set to non-empty value to enable):
+# * QUILTRC_ENABLE: generate patches in a standardised format
+#   (enabled by default if QUILT_PATCHES was empty or “-” and
+#   we find ourselves to be in a Debian 3.0 (quilt) package)
+# * QUILTRC_NO_DIFF_P: do not show C function context in diffs
+#
+# If QUILT_PATCHES is empty or a sole hyphen-minus, this ~/.quiltrc
+# checks for Debian 3.0 (quilt) source package and sets QUILT_PATCHES
+# to "debian/patches" if found; otherwise, if it was a hyphen-minus,
+# to "patches".
+
+while test -z "$QUILT_PATCHES" || test x"$QUILT_PATCHES" = x"-"; do
+       d=.
+       while :; do
+               test -d $d/debian && test -x $d/debian/rules && break
+               test x"$(/bin/readlink -e $d)" = x"/" && break
+               d=$d/..
+       done
+       test -x $d/debian/rules || break
+
+       # now in Debian packaging tree with unset $QUILT_PATCHES
+
+       QUILT_PATCHES="debian/patches"
+       test -d $d/debian/patches || mkdir $d/debian/patches
+       QUILTRC_ENABLE=1
+
+       # this is not a real loop, exit it always
+       break
+done
+if test -n "$QUILTRC_ENABLE"; then
+       # enable options to generate standardised patches
+       QUILT_PATCH_OPTS="--reject-format=unified"
+       QUILT_DIFF_OPTS=""
+       test -n "$QUILTRC_NO_DIFF_P" || \
+           QUILT_DIFF_OPTS="$QUILT_DIFF_OPTS --show-c-function"
+       QUILT_DIFF_ARGS="-p ab --no-timestamps --no-index --color=auto"
+       QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index --sort"
+       QUILT_PUSH_ARGS="--color=auto"
+       QUILT_COLORS="diff_hdr=1;32:diff_add=1;34:diff_rem=1;31:diff_hunk=1;33:diff_ctx=35:diff_cctx=33"
+fi
+test x"$QUILT_PATCHES" = x"-" && QUILT_PATCHES=patches
+:
diff --git a/mksh/debian-dev/dscls b/mksh/debian-dev/dscls
new file mode 100644 (file)
index 0000000..fece45f
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/mksh
+# $MirOS: contrib/hosted/tg/deb/dscls,v 1.1 2014/04/07 20:31:31 tg Exp $
+#-
+# Copyright © 2012
+#      Thorsten Glaser <tg@mirbsd.org>
+#
+# 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.
+
+for x in "$@"; do
+       dscname=$x
+       pkgname=${x%%@(.dsc|_+([a-z0-9-]).changes)}
+       if [[ -s $dscname ]]; then
+               y=$(sed -n '/^Source: /s///p' "$dscname" | head -n 1)
+               z=$(sed -n '/^Version: /s///p' "$dscname" | head -n 1)
+               [[ -n $y && -n $z && $x = ?(*/)${y}_* ]] && pkgname=${y}_$z
+       fi
+       print -r -- "$pkgname"
+done
diff --git a/mksh/debian-dev/mkdebidx.sh b/mksh/debian-dev/mkdebidx.sh
new file mode 100644 (file)
index 0000000..8661e8d
--- /dev/null
@@ -0,0 +1,698 @@
+#!/bin/mksh
+rcsid='$MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.61 2014/05/23 09:44:30 tg Exp $'
+#-
+# Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014
+#      Thorsten Glaser <tg@mirbsd.org>
+#
+# 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.
+
+set -A normarchs -- i386
+repo_keyid=0xAA917C6F
+# either '' (locally) or 'remsign user@host.domain.com' (remote ssh)
+gpg_remote=
+repo_origin='The MirOS Project'
+repo_label=wtf
+repo_title='MirDebian “WTF” Repository'
+function repo_description {
+       typeset suite_nick=$1
+
+       print -nr -- "WTF ${suite_nick} Repository"
+}
+
+
+set -A dpkgarchs -- alpha amd64 arm arm64 armel armhf hppa hurd-i386 i386 \
+    ia64 kfreebsd-amd64 kfreebsd-i386 m68k mips mipsel powerpc powerpcspe \
+    ppc64 s390 s390x sh4 sparc sparc64 x32
+
+function remsign {
+       target=$1; shift
+       master=remsign.ctl$$
+       tmpfnm=remsign.tmp$$
+       ssh -fNM -o ControlPath=$tmpfnm "$target"
+       ssh -o ControlPath=$tmpfnm "$target" cat \>$tmpfnm
+       ssh -o ControlPath=$tmpfnm -t "$target" "$* $tmpfnm" 0<&2 1>&2
+       rv=$?
+       ssh -o ControlPath=$tmpfnm "$target" "cat $tmpfnm.asc; rm -f $tmpfnm $tmpfnm.asc"
+       ssh -o ControlPath=$tmpfnm "$target" -O exit
+       return $rv
+}
+
+function putfile {
+       tee $1 | gzip -n9 >$1.gz
+}
+
+function sortlist {
+       typeset x u=$1
+
+       if [[ $u = -u ]]; then
+               shift
+       else
+               u=
+       fi
+
+       for x in "$@"; do
+               print -r -- "$x"
+       done | sort $u
+}
+
+# DJB cdb hash (not via stdio, for speed)
+typeset -Z11 -Uui16 Lcdbhash_result
+function Lcdbhash_add {
+       typeset s="$*"
+       typeset -i i=0 n=${#s}
+
+       while (( i < n )); do
+               ((# Lcdbhash_result = (Lcdbhash_result * 33) ^ 1#${s:(i++):1} ))
+       done
+}
+
+# escape XHTML characters (three mandatory XML ones plus double quotes,
+# the latter in an XML safe fashion numerically though)
+function xhtml_escape {
+       if (( $# )); then
+               print -nr -- "$@"
+       else
+               cat
+       fi | sed \
+           -e 's\ 1&\ 1\&amp;\ 1g' \
+           -e 's\ 1<\ 1\&lt;\ 1g' \
+           -e 's\ 1>\ 1\&gt;\ 1g' \
+           -e 's\ 1"\ 1\&#34;\ 1g'
+}
+
+set +U
+export LC_ALL=C
+unset LANGUAGE
+saveIFS=$IFS
+cd "$(dirname "$0")"
+rm -f dpkg_578162_workaround
+
+IFS=:
+dpkgarchl=:all:"${dpkgarchs[*]}":
+IFS=$saveIFS
+
+suites=:
+for suite in "$@"; do
+       suites=:dists/$suite$suites
+done
+
+allsuites=
+for suite in dists/*; do
+       allsuites="$allsuites${allsuites:+ }${suite##*/}"
+       [[ $suites = : || $suites = *:"$suite":* ]] || continue
+       archs=
+       distribution=
+       debootstrap_compat=0
+       . $suite/distinfo.sh
+       suitearchs=${archs:-${normarchs[*]}}
+       components=Components:
+       for dist in $suite/*; do
+               [[ -d $dist/. ]] || continue
+               rm -rf $dist/binary-* $dist/source
+               ovf= oef= osf= om=-m
+               (( debootstrap_compat )) && om=
+               [[ -s $dist/override.file ]] && ovf=$dist/override.file
+               [[ -s $dist/override.extra ]] && oef="-e $dist/override.extra"
+               [[ -s $dist/override.src ]] && osf="-s $dist/override.src"
+               components="$components ${dist##*/}"
+               archs=
+               [[ -s $dist/distinfo.sh ]] && . $dist/distinfo.sh
+               set -A distarchs -- $(sortlist -u all ${archs:-$suitearchs})
+               IFS=:; distarchl=:"${distarchs[*]}":; IFS=$saveIFS
+               nmds=0
+               for arch in $(sortlist -u ${distarchs[*]} ${dpkgarchs[*]}) /; do
+                       # put "all" last
+                       [[ $arch = all ]] && continue
+                       [[ $arch = / ]] && arch=all
+                       # create index
+                       if [[ $dpkgarchl != *:"$arch":* ]]; then
+                               print -u2 "Invalid arch '$arch' in $dist"
+                               exit 1
+                       elif [[ $distarchl != *:"$arch":* ]]; then
+                               print "\n===> Linking all =>" \
+                                   "${dist#dists/}/$arch/Packages"
+                               ln -s binary-all $dist/binary-$arch
+                       elif [[ $arch = all ]] && (( nmds == 1 )); then
+                               print "\n===> Linking $firstmd =>" \
+                                   "${dist#dists/}/all/Packages"
+                               ln -s binary-$firstmd $dist/binary-all
+                       else
+                               print "\n===> Creating" \
+                                   "${dist#dists/}/$arch/Packages\n"
+                               mkdir -p $dist/binary-$arch
+                               dpkg-scanpackages $oef $om -a $arch \
+                                   $dist $ovf | \
+                                   putfile $dist/binary-$arch/Packages
+                               (( nmds++ )) || firstmd=$arch
+                       fi
+               done
+               print "\n===> Creating ${dist#dists/}/Sources"
+               mkdir -p $dist/source
+               [[ -e dpkg_578162_workaround ]] || (dpkg-scansources $oef $osf \
+                   $dist $ovf || touch dpkg_578162_workaround) | \
+                   putfile $dist/source/Sources
+               [[ -e dpkg_578162_workaround ]] && dpkg-scansources $osf \
+                   $dist $ovf | \
+                   putfile $dist/source/Sources
+               print done.
+       done
+       print "\n===> Creating ${suite#dists/}/Release"
+       rm -f $suite/Release-*
+       (cat <<-EOF
+               Origin: ${repo_origin}
+               Label: ${repo_label}
+               Suite: ${distribution:-${suite##*/}}
+               Codename: ${suite##*/}
+               Date: $(date -u)
+               Architectures: all ${dpkgarchs[*]} source
+               $components
+               Description: $(repo_description "$nick")
+               MD5Sum:
+       EOF
+       exec 4>$suite/Release-sha1
+       exec 5>$suite/Release-sha2
+       print -u4 SHA1:
+       print -u5 SHA256:
+       cd $suite
+       set -A cache_fn
+       set -A cache_md5
+       set -A cache_sha1
+       set -A cache_sha2
+       set -A cache_size
+       for n in Contents-* */{binary-*,source}/{Packag,Sourc}es*; do
+               [[ -f $n ]] || continue
+               # realpath-ise $n and cache the checksum
+               nn=$(realpath "$n")
+               #XXX once mksh can, use associative arrays instead
+               Lcdbhash_result=5381
+               Lcdbhash_add "$nn"
+               # simple hash collision solver by increment
+               nc=${cache_fn[Lcdbhash_result]}
+               while [[ -n $nc && $nc != "$nn" ]]; do
+                       nc=${cache_fn[++Lcdbhash_result]}
+               done
+               if [[ $nc = "$nn" ]]; then
+                       nm=${cache_md5[Lcdbhash_result]}
+                       ns=${cache_size[Lcdbhash_result]}
+                       nsha1=${cache_sha1[Lcdbhash_result]}
+                       nsha2=${cache_sha2[Lcdbhash_result]}
+               else
+                       # GNU *sum tools are horridly inefficient
+                       set -A x -- $(md5sum "$nn")
+                       nm=${x[0]}
+                       set -A x -- $(sha1sum "$nn")
+                       nsha1=${x[0]}
+                       set -A x -- $(sha256sum "$nn")
+                       nsha2=${x[0]}
+                       ns=$(stat -c '%s' "$nn")
+                       cache_md5[Lcdbhash_result]=$nm
+                       cache_size[Lcdbhash_result]=$ns
+                       cache_fn[Lcdbhash_result]=$nn
+                       cache_sha1[Lcdbhash_result]=$nsha1
+                       cache_sha2[Lcdbhash_result]=$nsha2
+               fi
+               print " $nm $ns $n"
+               print -u4 " $nsha1 $ns $n"
+               print -u5 " $nsha2 $ns $n"
+       done) >$suite/Release-tmp
+       cat $suite/Release-sha1 $suite/Release-sha2 >>$suite/Release-tmp
+
+       # note: InRelease files can only be safely used by wheezy
+       # onwards, and oneiric onwards; known to be insecure on
+       # natty, but usable concurrent to detached files on squeeze
+
+       unset release_sign_detached release_sign_inline
+       release_sign_detached=x
+       release_sign_inline=0
+       . $suite/distinfo.sh
+       [[ $release_sign_inline = [01] ]] || release_sign_inline=0
+       [[ $release_sign_detached = [01] ]] || \
+           (( release_sign_detached = release_sign_inline ? 0 : 1 ))
+
+       # Debian's fix for CVE-2013-1051 consists of disabling
+       # support for InRelease files altogether (WTF!)
+       release_sign_detached=1
+       release_sign_inline=0
+
+       (( release_sign_detached )) && $gpg_remote gpg -u $repo_keyid \
+           -sab <$suite/Release-tmp >$suite/Release-sig
+       (( release_sign_inline )) && $gpg_remote gpg -u $repo_keyid \
+           --clearsign <$suite/Release-tmp >$suite/Release-inl
+
+       if (( release_sign_inline )); then
+               mv -f $suite/Release-inl $suite/InRelease
+       else
+               rm -f $suite/InRelease
+       fi
+       if (( release_sign_detached )); then
+               mv -f $suite/Release-tmp $suite/Release
+               mv -f $suite/Release-sig $suite/Release.gpg
+       else
+               rm -f $suite/Release*
+       fi
+       rm -f $suite/Release-*
+done
+
+print "\n===> Creating debidx.htm\n"
+
+set -A preplsrc
+set -A prepldst
+integer nsrc=0 nbin=0 nrpl=0
+br='<br />'
+
+# syntax:      ${suitename}/${distname}/${pN}/${pp} <suite>
+# example:     sid/wtf/openntpd/i386 lenny
+if [[ -s mkdebidx.lnk ]]; then
+       while read pn pd; do
+               [[ $pn = '#'* ]] && continue
+               if [[ $pn != +([a-z0-9_])/+([a-z0-9_-])/+([!/])/@(%|=|+([a-z0-9])) || \
+                   $pd != +([a-z0-9_]) ]]; then
+                       print -u2 "Invalid lnk line '$pn' '$pd'"
+                       continue
+               fi
+               preplsrc[nrpl]=$pn
+               prepldst[nrpl++]=$pd
+       done <mkdebidx.lnk
+fi
+
+for suite in dists/*; do
+       for dist in $suite/*; do
+               [[ -d $dist/. ]] || continue
+               suitename=${suite##*/}
+               if [[ $suitename != +([a-z0-9_]) ]]; then
+                       print -u2 "Invalid suite name '$suitename'"
+                       continue 2
+               fi
+               distname=${dist##*/}
+               if [[ $distname != +([a-z0-9_-]) ]]; then
+                       print -u2 "Invalid dist name '$distname'"
+                       continue
+               fi
+
+               gzip -dc $dist/source/Sources.gz |&
+               pn=; pv=; pd=; pp=; Lf=
+               while IFS= read -pr line; do
+                       case $line {
+                       (" "*)
+                               if [[ -n $Lf ]]; then
+                                       eval x=\$$Lf
+                                       x=$x$line
+                                       eval $Lf=\$x
+                               fi
+                               ;;
+                       ("Package: "*)
+                               pn=${line##Package:*([   ])}
+                               Lf=pn
+                               ;;
+                       ("Version: "*)
+                               pv=${line##Version:*([   ])}
+                               Lf=pv
+                               ;;
+                       ("Binary: "*)
+                               pd=${line##Binary:*([    ])}
+                               Lf=pd
+                               ;;
+                       ("Directory: "*)
+                               pp=${line##Directory:*([         ])}
+                               Lf=pp
+                               ;;
+                       (?*)    # anything else
+                               Lf=
+                               ;;
+                       (*)     # empty line
+                               if [[ -n $pn && -n $pv && -n $pd && -n $pp ]]; then
+                                       i=0
+                                       while (( i < nsrc )); do
+                                               [[ ${sp_name[i]} = "$pn" && \
+                                                   ${sp_dist[i]} = "$distname" ]] && break
+                                               let i++
+                                       done
+                                       if (( i == nsrc )); then
+                                               let nsrc++
+                                               pvo=
+                                               ppo=
+                                       else
+                                               eval pvo=\$\{sp_ver_${suitename}[i]\}
+                                               eval ppo=\$\{sp_dir_${suitename}[i]\}
+                                       fi
+                                       sp_name[i]=$pn
+                                       sp_dist[i]=$distname
+                                       #sp_suites[i]="${sp_suites[i]} $suitename"
+                                       if (( nrpl )); then
+                                               x=${suitename}/${distname}/${pn}/source
+                                               j=0
+                                               while (( j < nrpl )); do
+                                                       [[ ${preplsrc[j]} = "$x" ]] && break
+                                                       let j++
+                                               done
+                                               (( j < nrpl )) && pv="${pv}\1afrom ${prepldst[j]}"
+                                       fi
+                                       eval sp_ver_${suitename}[i]='${pvo:+$pvo,}$pv'
+                                       eval sp_dir_${suitename}[i]='${ppo:+$ppo,}$pp/'
+                                       sp_desc[i]=${sp_desc[i]},$pd
+                               fi
+                               pn=; pv=; pd=; pp=; Lf=
+                               ;;
+                       }
+               done
+
+               gzip -dc $(for f in $dist/binary-*/Packages.gz; do
+                       [[ -e $f ]] || continue
+                       realpath "$f"
+               done | sort -u) |&
+               pn=; pv=; pd=; pp=; pN=; pf=; Lf=
+               while IFS= read -pr line; do
+                       case $line {
+                       (" "*)
+                               if [[ -n $Lf ]]; then
+                                       eval x=\$$Lf
+                                       x=$x$line
+                                       eval $Lf=\$x
+                               fi
+                               ;;
+                       ("Package: "*)
+                               pN=${line##Package:*([   ])}
+                               Lf=pN
+                               ;;
+                       ("Source: "*)
+                               pn=${line##Source:*([    ])}
+                               pn=${pn%% *}
+                               Lf=pn
+                               ;;
+                       ("Version: "*)
+                               pv=${line##Version:*([   ])}
+                               Lf=pv
+                               ;;
+                       ("Description: "*)
+                               pd=${line##Description:*([       ])}
+                               ;;
+                       ("Architecture: "*)
+                               pp=${line##Architecture:*([      ])}
+                               Lf=pp
+                               ;;
+                       ("Filename: "*)
+                               pf=${line##Filename:*([  ])}
+                               Lf=pf
+                               ;;
+                       (?*)    # anything else
+                               Lf=
+                               ;;
+                       (*)     # empty line
+                               if [[ $pf = *:* || $pf = *'%'* ]]; then
+                                       print -u2 Illegal character in $dist \
+                                           packages $pp "'Filename: $pf'"
+                                       exit 1
+                               fi
+