[PATCH 04/11] Rename 'external' to 'helpers'

Artem Bityutskiy dedekind1 at gmail.com
Fri Feb 7 07:28:17 PST 2014


From: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>

I would like to move all the internal tools to a separate directory. Let's call
it 'helpers'. The 'external' directory now contains all the tools which came
from an external project. Probably this is not the best way to lay-out our
files. Let's just re-name it to helpers. Later we'll move more stuff to
'helpers'.

Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
---
 .gitignore                                         |   2 +-
 Makefile                                           |   4 +-
 aiaiai-checker                                     |   2 +-
 aiaiai-concat-mboxes                               |   2 +-
 aiaiai-diff-log                                    |   2 +-
 aiaiai-make-kernel                                 |   2 +-
 aiaiai-match-keywords                              |   2 +-
 aiaiai-test-bisectability                          |   2 +-
 aiaiai-test-patchset                               |   2 +-
 doc/README                                         |  13 +-
 email/aiaiai-email-dispatcher                      |   2 +-
 email/aiaiai-email-dispatcher-helper               |   2 +-
 email/aiaiai-email-lda                             |   2 +-
 email/aiaiai-email-test-patchset                   |   2 +-
 external/Makefile                                  |   7 -
 .../coccinelle/api/alloc/drop_kmalloc_cast.cocci   |  67 ---
 external/coccinelle/api/alloc/kzalloc-simple.cocci |  86 ---
 external/coccinelle/api/d_find_alias.cocci         |  80 ---
 .../coccinelle/api/devm_ioremap_resource.cocci     |  90 ----
 .../coccinelle/api/devm_request_and_ioremap.cocci  | 105 ----
 external/coccinelle/api/err_cast.cocci             |  56 --
 external/coccinelle/api/kstrdup.cocci              | 104 ----
 external/coccinelle/api/memdup.cocci               |  66 ---
 external/coccinelle/api/memdup_user.cocci          |  60 ---
 external/coccinelle/api/ptr_ret.cocci              |  96 ----
 external/coccinelle/api/resource_size.cocci        |  93 ----
 external/coccinelle/api/simple_open.cocci          |  70 ---
 external/coccinelle/free/clk_put.cocci             |  67 ---
 external/coccinelle/free/devm_free.cocci           |  71 ---
 external/coccinelle/free/iounmap.cocci             |  67 ---
 external/coccinelle/free/kfree.cocci               | 121 -----
 external/coccinelle/free/kfreeaddr.cocci           |  32 --
 external/coccinelle/free/pci_free_consistent.cocci |  52 --
 external/coccinelle/iterators/fen.cocci            | 123 -----
 external/coccinelle/iterators/itnull.cocci         |  94 ----
 .../coccinelle/iterators/list_entry_update.cocci   |  62 ---
 external/coccinelle/iterators/use_after_iter.cocci | 147 ------
 external/coccinelle/locks/call_kern.cocci          | 105 ----
 external/coccinelle/locks/double_lock.cocci        |  92 ----
 external/coccinelle/locks/flags.cocci              |  80 ---
 external/coccinelle/locks/mini_lock.cocci          |  96 ----
 external/coccinelle/misc/boolinit.cocci            | 178 -------
 external/coccinelle/misc/boolreturn.cocci          |  58 --
 external/coccinelle/misc/cstptr.cocci              |  41 --
 external/coccinelle/misc/doubleinit.cocci          |  53 --
 external/coccinelle/misc/ifaddr.cocci              |  35 --
 external/coccinelle/misc/ifcol.cocci               |  48 --
 external/coccinelle/misc/irqf_oneshot.cocci        |  65 ---
 external/coccinelle/misc/memcpy-assign.cocci       | 103 ----
 external/coccinelle/misc/noderef.cocci             |  65 ---
 external/coccinelle/misc/orplus.cocci              |  55 --
 external/coccinelle/misc/semicolon.cocci           |  83 ---
 external/coccinelle/misc/warn.cocci                | 109 ----
 external/coccinelle/null/badzero.cocci             | 237 ---------
 external/coccinelle/null/deref_null.cocci          | 282 ----------
 external/coccinelle/null/eno.cocci                 |  48 --
 external/coccinelle/null/kmerr.cocci               |  72 ---
 external/coccinelle/tests/doublebitand.cocci       |  54 --
 external/coccinelle/tests/doubletest.cocci         |  40 --
 external/coccinelle/tests/odd_ptr_err.cocci        |  65 ---
 external/libshell/COPYING                          |  26 -
 external/libshell/LICENSE                          | 340 ------------
 external/libshell/Makefile                         |  29 -
 external/libshell/SYMS                             |  66 ---
 external/libshell/contrib/getoptx_1.0.bash         | 301 -----------
 external/libshell/contrib/getoptx_1.1.bash         | 241 ---------
 external/libshell/contrib/shell-array              |  89 ----
 external/libshell/contrib/shell-crc32              |  73 ---
 external/libshell/contrib/shell-lists              |  72 ---
 external/libshell/contrib/shell-sort               | 105 ----
 external/libshell/contrib/shell-stack              |  68 ---
 external/libshell/docs/libshell.man                | 115 ----
 external/libshell/docs/shell-error.man             |  73 ---
 external/libshell/shell-args                       |  77 ---
 external/libshell/shell-cmdline                    | 118 -----
 external/libshell/shell-config                     |  87 ---
 external/libshell/shell-error                      |  32 --
 external/libshell/shell-getopt                     | 399 --------------
 external/libshell/shell-ini-config                 | 155 ------
 external/libshell/shell-ip-address                 | 166 ------
 external/libshell/shell-mail-address               |  66 ---
 external/libshell/shell-quote                      | 158 ------
 external/libshell/shell-regexp                     |   1 -
 external/libshell/shell-run                        |  40 --
 external/libshell/shell-signal                     |  73 ---
 external/libshell/shell-source                     |  55 --
 external/libshell/shell-string                     |  28 -
 external/libshell/shell-unittest                   | 252 ---------
 external/libshell/shell-var                        |  75 ---
 external/libshell/shell-version                    |  13 -
 external/libshell/tests/cmdline_get                |  59 ---
 .../tests/data/000-quote_shell_args-pattern        |   1 -
 .../tests/data/000-quote_shell_args-result         |   1 -
 .../tests/data/001-quote_shell_args-pattern        |   1 -
 .../tests/data/001-quote_shell_args-result         |   1 -
 .../tests/data/002-quote_shell_args-pattern        |   1 -
 .../tests/data/002-quote_shell_args-result         |   1 -
 .../tests/data/003-quote_shell_args-pattern        |   1 -
 .../tests/data/003-quote_shell_args-result         |   1 -
 .../tests/data/004-quote_shell_args-pattern        |   1 -
 .../tests/data/004-quote_shell_args-result         |   1 -
 .../tests/data/005-quote_shell_args-pattern        |   1 -
 .../tests/data/005-quote_shell_args-result         |   1 -
 .../tests/data/006-quote_shell_args-pattern        |   1 -
 .../tests/data/006-quote_shell_args-result         |   1 -
 .../tests/data/007-quote_shell_args-pattern        |   1 -
 .../tests/data/007-quote_shell_args-result         |   1 -
 .../tests/data/008-quote_shell_args-pattern        |   1 -
 .../tests/data/008-quote_shell_args-result         |   1 -
 .../tests/data/009-quote_shell_args-pattern        |   1 -
 .../tests/data/009-quote_shell_args-result         |   1 -
 .../tests/data/010-quote_shell_args-pattern        |   1 -
 .../tests/data/010-quote_shell_args-result         |   1 -
 .../tests/data/011-quote_shell_args-pattern        |   1 -
 .../tests/data/011-quote_shell_args-result         |   1 -
 .../tests/data/012-quote_shell_args-pattern        |   1 -
 .../tests/data/012-quote_shell_args-result         |   1 -
 .../tests/data/013-quote_shell_args-pattern        |   1 -
 .../tests/data/013-quote_shell_args-result         |   1 -
 .../tests/data/014-quote_shell_args-pattern        |   1 -
 .../tests/data/014-quote_shell_args-result         |   1 -
 .../tests/data/015-quote_shell_args-pattern        |   1 -
 .../tests/data/015-quote_shell_args-result         |   1 -
 .../tests/data/016-quote_shell_args-pattern        |   1 -
 .../tests/data/016-quote_shell_args-result         |   1 -
 .../tests/data/017-quote_shell_args-pattern        |   1 -
 .../tests/data/017-quote_shell_args-result         |   1 -
 .../tests/data/018-quote_shell_args-pattern        |   1 -
 .../tests/data/018-quote_shell_args-result         |   1 -
 .../tests/data/019-quote_shell_args-pattern        |   1 -
 .../tests/data/019-quote_shell_args-result         |   1 -
 .../tests/data/020-quote_shell_args-pattern        |   1 -
 .../tests/data/020-quote_shell_args-result         |   1 -
 .../tests/data/021-quote_shell_args-pattern        |   1 -
 .../tests/data/021-quote_shell_args-result         |   1 -
 .../tests/data/022-quote_shell_args-pattern        |   1 -
 .../tests/data/022-quote_shell_args-result         |   1 -
 .../tests/data/023-quote_shell_args-pattern        |   1 -
 .../tests/data/023-quote_shell_args-result         |   1 -
 .../tests/data/024-quote_shell_args-pattern        |   1 -
 .../tests/data/024-quote_shell_args-result         |   1 -
 .../tests/data/025-quote_shell_args-pattern        |   1 -
 .../tests/data/025-quote_shell_args-result         |   1 -
 .../tests/data/026-quote_shell_args-pattern        |   1 -
 .../tests/data/026-quote_shell_args-result         |   1 -
 .../tests/data/027-quote_shell_args-pattern        |   1 -
 .../tests/data/027-quote_shell_args-result         |   1 -
 external/libshell/tests/fatal                      |  33 --
 external/libshell/tests/fill_mask                  |  43 --
 external/libshell/tests/getopt                     | 151 ------
 external/libshell/tests/ini-config/z.ini           |  12 -
 external/libshell/tests/ini_config_get             |  22 -
 external/libshell/tests/ini_config_set             |  58 --
 external/libshell/tests/message                    |  33 --
 external/libshell/tests/opt_check_dir              |  29 -
 external/libshell/tests/opt_check_number           |  31 --
 external/libshell/tests/opt_check_read             |  59 ---
 external/libshell/tests/quote_sed_regexp           |  33 --
 external/libshell/tests/quote_sed_regexp_variable  |  37 --
 external/libshell/tests/quote_shell                |  25 -
 external/libshell/tests/quote_shell_args           | 379 -------------
 external/libshell/tests/quote_shell_variable       |  25 -
 external/libshell/tests/runtests                   |  34 --
 external/libshell/tests/shell_var_trim             |  43 --
 external/libshell/tests/shell_var_unquote          |  33 --
 external/libshell/tests/signal                     |  52 --
 external/libshell/tests/signal-data/001-signal     |   3 -
 external/libshell/tests/signal-data/002-signal     |   4 -
 external/libshell/tests/signal-data/003-signal     |   4 -
 external/libshell/tests/signal-data/004-signal     |   9 -
 external/libshell/tests/signal-data/005-signal     |   4 -
 external/libshell/tests/signal-data/006-signal     |  10 -
 external/libshell/tests/signal-data/007-signal     |  11 -
 external/libshell/tests/string_quote_remove        |  33 --
 external/libshell/tests/verbose                    |  19 -
 external/remap-log.c                               | 588 ---------------------
 gerrit/aiaiai-jenkins-test-patchset                |   2 +-
 helpers/Makefile                                   |   7 +
 .../coccinelle/api/alloc/drop_kmalloc_cast.cocci   |  67 +++
 helpers/coccinelle/api/alloc/kzalloc-simple.cocci  |  86 +++
 helpers/coccinelle/api/d_find_alias.cocci          |  80 +++
 helpers/coccinelle/api/devm_ioremap_resource.cocci |  90 ++++
 .../coccinelle/api/devm_request_and_ioremap.cocci  | 105 ++++
 helpers/coccinelle/api/err_cast.cocci              |  56 ++
 helpers/coccinelle/api/kstrdup.cocci               | 104 ++++
 helpers/coccinelle/api/memdup.cocci                |  66 +++
 helpers/coccinelle/api/memdup_user.cocci           |  60 +++
 helpers/coccinelle/api/ptr_ret.cocci               |  96 ++++
 helpers/coccinelle/api/resource_size.cocci         |  93 ++++
 helpers/coccinelle/api/simple_open.cocci           |  70 +++
 helpers/coccinelle/free/clk_put.cocci              |  67 +++
 helpers/coccinelle/free/devm_free.cocci            |  71 +++
 helpers/coccinelle/free/iounmap.cocci              |  67 +++
 helpers/coccinelle/free/kfree.cocci                | 121 +++++
 helpers/coccinelle/free/kfreeaddr.cocci            |  32 ++
 helpers/coccinelle/free/pci_free_consistent.cocci  |  52 ++
 helpers/coccinelle/iterators/fen.cocci             | 123 +++++
 helpers/coccinelle/iterators/itnull.cocci          |  94 ++++
 .../coccinelle/iterators/list_entry_update.cocci   |  62 +++
 helpers/coccinelle/iterators/use_after_iter.cocci  | 147 ++++++
 helpers/coccinelle/locks/call_kern.cocci           | 105 ++++
 helpers/coccinelle/locks/double_lock.cocci         |  92 ++++
 helpers/coccinelle/locks/flags.cocci               |  80 +++
 helpers/coccinelle/locks/mini_lock.cocci           |  96 ++++
 helpers/coccinelle/misc/boolinit.cocci             | 178 +++++++
 helpers/coccinelle/misc/boolreturn.cocci           |  58 ++
 helpers/coccinelle/misc/cstptr.cocci               |  41 ++
 helpers/coccinelle/misc/doubleinit.cocci           |  53 ++
 helpers/coccinelle/misc/ifaddr.cocci               |  35 ++
 helpers/coccinelle/misc/ifcol.cocci                |  48 ++
 helpers/coccinelle/misc/irqf_oneshot.cocci         |  65 +++
 helpers/coccinelle/misc/memcpy-assign.cocci        | 103 ++++
 helpers/coccinelle/misc/noderef.cocci              |  65 +++
 helpers/coccinelle/misc/orplus.cocci               |  55 ++
 helpers/coccinelle/misc/semicolon.cocci            |  83 +++
 helpers/coccinelle/misc/warn.cocci                 | 109 ++++
 helpers/coccinelle/null/badzero.cocci              | 237 +++++++++
 helpers/coccinelle/null/deref_null.cocci           | 282 ++++++++++
 helpers/coccinelle/null/eno.cocci                  |  48 ++
 helpers/coccinelle/null/kmerr.cocci                |  72 +++
 helpers/coccinelle/tests/doublebitand.cocci        |  54 ++
 helpers/coccinelle/tests/doubletest.cocci          |  40 ++
 helpers/coccinelle/tests/odd_ptr_err.cocci         |  65 +++
 helpers/libshell/COPYING                           |  26 +
 helpers/libshell/LICENSE                           | 340 ++++++++++++
 helpers/libshell/Makefile                          |  29 +
 helpers/libshell/SYMS                              |  66 +++
 helpers/libshell/contrib/getoptx_1.0.bash          | 301 +++++++++++
 helpers/libshell/contrib/getoptx_1.1.bash          | 241 +++++++++
 helpers/libshell/contrib/shell-array               |  89 ++++
 helpers/libshell/contrib/shell-crc32               |  73 +++
 helpers/libshell/contrib/shell-lists               |  72 +++
 helpers/libshell/contrib/shell-sort                | 105 ++++
 helpers/libshell/contrib/shell-stack               |  68 +++
 helpers/libshell/docs/libshell.man                 | 115 ++++
 helpers/libshell/docs/shell-error.man              |  73 +++
 helpers/libshell/shell-args                        |  77 +++
 helpers/libshell/shell-cmdline                     | 118 +++++
 helpers/libshell/shell-config                      |  87 +++
 helpers/libshell/shell-error                       |  32 ++
 helpers/libshell/shell-getopt                      | 399 ++++++++++++++
 helpers/libshell/shell-ini-config                  | 155 ++++++
 helpers/libshell/shell-ip-address                  | 166 ++++++
 helpers/libshell/shell-mail-address                |  66 +++
 helpers/libshell/shell-quote                       | 158 ++++++
 helpers/libshell/shell-regexp                      |   1 +
 helpers/libshell/shell-run                         |  40 ++
 helpers/libshell/shell-signal                      |  73 +++
 helpers/libshell/shell-source                      |  55 ++
 helpers/libshell/shell-string                      |  28 +
 helpers/libshell/shell-unittest                    | 252 +++++++++
 helpers/libshell/shell-var                         |  75 +++
 helpers/libshell/shell-version                     |  13 +
 helpers/libshell/tests/cmdline_get                 |  59 +++
 .../tests/data/000-quote_shell_args-pattern        |   1 +
 .../tests/data/000-quote_shell_args-result         |   1 +
 .../tests/data/001-quote_shell_args-pattern        |   1 +
 .../tests/data/001-quote_shell_args-result         |   1 +
 .../tests/data/002-quote_shell_args-pattern        |   1 +
 .../tests/data/002-quote_shell_args-result         |   1 +
 .../tests/data/003-quote_shell_args-pattern        |   1 +
 .../tests/data/003-quote_shell_args-result         |   1 +
 .../tests/data/004-quote_shell_args-pattern        |   1 +
 .../tests/data/004-quote_shell_args-result         |   1 +
 .../tests/data/005-quote_shell_args-pattern        |   1 +
 .../tests/data/005-quote_shell_args-result         |   1 +
 .../tests/data/006-quote_shell_args-pattern        |   1 +
 .../tests/data/006-quote_shell_args-result         |   1 +
 .../tests/data/007-quote_shell_args-pattern        |   1 +
 .../tests/data/007-quote_shell_args-result         |   1 +
 .../tests/data/008-quote_shell_args-pattern        |   1 +
 .../tests/data/008-quote_shell_args-result         |   1 +
 .../tests/data/009-quote_shell_args-pattern        |   1 +
 .../tests/data/009-quote_shell_args-result         |   1 +
 .../tests/data/010-quote_shell_args-pattern        |   1 +
 .../tests/data/010-quote_shell_args-result         |   1 +
 .../tests/data/011-quote_shell_args-pattern        |   1 +
 .../tests/data/011-quote_shell_args-result         |   1 +
 .../tests/data/012-quote_shell_args-pattern        |   1 +
 .../tests/data/012-quote_shell_args-result         |   1 +
 .../tests/data/013-quote_shell_args-pattern        |   1 +
 .../tests/data/013-quote_shell_args-result         |   1 +
 .../tests/data/014-quote_shell_args-pattern        |   1 +
 .../tests/data/014-quote_shell_args-result         |   1 +
 .../tests/data/015-quote_shell_args-pattern        |   1 +
 .../tests/data/015-quote_shell_args-result         |   1 +
 .../tests/data/016-quote_shell_args-pattern        |   1 +
 .../tests/data/016-quote_shell_args-result         |   1 +
 .../tests/data/017-quote_shell_args-pattern        |   1 +
 .../tests/data/017-quote_shell_args-result         |   1 +
 .../tests/data/018-quote_shell_args-pattern        |   1 +
 .../tests/data/018-quote_shell_args-result         |   1 +
 .../tests/data/019-quote_shell_args-pattern        |   1 +
 .../tests/data/019-quote_shell_args-result         |   1 +
 .../tests/data/020-quote_shell_args-pattern        |   1 +
 .../tests/data/020-quote_shell_args-result         |   1 +
 .../tests/data/021-quote_shell_args-pattern        |   1 +
 .../tests/data/021-quote_shell_args-result         |   1 +
 .../tests/data/022-quote_shell_args-pattern        |   1 +
 .../tests/data/022-quote_shell_args-result         |   1 +
 .../tests/data/023-quote_shell_args-pattern        |   1 +
 .../tests/data/023-quote_shell_args-result         |   1 +
 .../tests/data/024-quote_shell_args-pattern        |   1 +
 .../tests/data/024-quote_shell_args-result         |   1 +
 .../tests/data/025-quote_shell_args-pattern        |   1 +
 .../tests/data/025-quote_shell_args-result         |   1 +
 .../tests/data/026-quote_shell_args-pattern        |   1 +
 .../tests/data/026-quote_shell_args-result         |   1 +
 .../tests/data/027-quote_shell_args-pattern        |   1 +
 .../tests/data/027-quote_shell_args-result         |   1 +
 helpers/libshell/tests/fatal                       |  33 ++
 helpers/libshell/tests/fill_mask                   |  43 ++
 helpers/libshell/tests/getopt                      | 151 ++++++
 helpers/libshell/tests/ini-config/z.ini            |  12 +
 helpers/libshell/tests/ini_config_get              |  22 +
 helpers/libshell/tests/ini_config_set              |  58 ++
 helpers/libshell/tests/message                     |  33 ++
 helpers/libshell/tests/opt_check_dir               |  29 +
 helpers/libshell/tests/opt_check_number            |  31 ++
 helpers/libshell/tests/opt_check_read              |  59 +++
 helpers/libshell/tests/quote_sed_regexp            |  33 ++
 helpers/libshell/tests/quote_sed_regexp_variable   |  37 ++
 helpers/libshell/tests/quote_shell                 |  25 +
 helpers/libshell/tests/quote_shell_args            | 379 +++++++++++++
 helpers/libshell/tests/quote_shell_variable        |  25 +
 helpers/libshell/tests/runtests                    |  34 ++
 helpers/libshell/tests/shell_var_trim              |  43 ++
 helpers/libshell/tests/shell_var_unquote           |  33 ++
 helpers/libshell/tests/signal                      |  52 ++
 helpers/libshell/tests/signal-data/001-signal      |   3 +
 helpers/libshell/tests/signal-data/002-signal      |   4 +
 helpers/libshell/tests/signal-data/003-signal      |   4 +
 helpers/libshell/tests/signal-data/004-signal      |   9 +
 helpers/libshell/tests/signal-data/005-signal      |   4 +
 helpers/libshell/tests/signal-data/006-signal      |  10 +
 helpers/libshell/tests/signal-data/007-signal      |  11 +
 helpers/libshell/tests/string_quote_remove         |  33 ++
 helpers/libshell/tests/verbose                     |  19 +
 helpers/remap-log.c                                | 588 +++++++++++++++++++++
 packaging/aiaiai.spec                              |   6 +-
 tests/test-subj-parsing                            |   2 +-
 341 files changed, 9231 insertions(+), 9230 deletions(-)
 delete mode 100644 external/Makefile
 delete mode 100644 external/coccinelle/api/alloc/drop_kmalloc_cast.cocci
 delete mode 100644 external/coccinelle/api/alloc/kzalloc-simple.cocci
 delete mode 100644 external/coccinelle/api/d_find_alias.cocci
 delete mode 100644 external/coccinelle/api/devm_ioremap_resource.cocci
 delete mode 100644 external/coccinelle/api/devm_request_and_ioremap.cocci
 delete mode 100644 external/coccinelle/api/err_cast.cocci
 delete mode 100644 external/coccinelle/api/kstrdup.cocci
 delete mode 100644 external/coccinelle/api/memdup.cocci
 delete mode 100644 external/coccinelle/api/memdup_user.cocci
 delete mode 100644 external/coccinelle/api/ptr_ret.cocci
 delete mode 100644 external/coccinelle/api/resource_size.cocci
 delete mode 100644 external/coccinelle/api/simple_open.cocci
 delete mode 100644 external/coccinelle/free/clk_put.cocci
 delete mode 100644 external/coccinelle/free/devm_free.cocci
 delete mode 100644 external/coccinelle/free/iounmap.cocci
 delete mode 100644 external/coccinelle/free/kfree.cocci
 delete mode 100644 external/coccinelle/free/kfreeaddr.cocci
 delete mode 100644 external/coccinelle/free/pci_free_consistent.cocci
 delete mode 100644 external/coccinelle/iterators/fen.cocci
 delete mode 100644 external/coccinelle/iterators/itnull.cocci
 delete mode 100644 external/coccinelle/iterators/list_entry_update.cocci
 delete mode 100644 external/coccinelle/iterators/use_after_iter.cocci
 delete mode 100644 external/coccinelle/locks/call_kern.cocci
 delete mode 100644 external/coccinelle/locks/double_lock.cocci
 delete mode 100644 external/coccinelle/locks/flags.cocci
 delete mode 100644 external/coccinelle/locks/mini_lock.cocci
 delete mode 100644 external/coccinelle/misc/boolinit.cocci
 delete mode 100644 external/coccinelle/misc/boolreturn.cocci
 delete mode 100644 external/coccinelle/misc/cstptr.cocci
 delete mode 100644 external/coccinelle/misc/doubleinit.cocci
 delete mode 100644 external/coccinelle/misc/ifaddr.cocci
 delete mode 100644 external/coccinelle/misc/ifcol.cocci
 delete mode 100644 external/coccinelle/misc/irqf_oneshot.cocci
 delete mode 100644 external/coccinelle/misc/memcpy-assign.cocci
 delete mode 100644 external/coccinelle/misc/noderef.cocci
 delete mode 100644 external/coccinelle/misc/orplus.cocci
 delete mode 100644 external/coccinelle/misc/semicolon.cocci
 delete mode 100644 external/coccinelle/misc/warn.cocci
 delete mode 100644 external/coccinelle/null/badzero.cocci
 delete mode 100644 external/coccinelle/null/deref_null.cocci
 delete mode 100644 external/coccinelle/null/eno.cocci
 delete mode 100644 external/coccinelle/null/kmerr.cocci
 delete mode 100644 external/coccinelle/tests/doublebitand.cocci
 delete mode 100644 external/coccinelle/tests/doubletest.cocci
 delete mode 100644 external/coccinelle/tests/odd_ptr_err.cocci
 delete mode 100644 external/libshell/COPYING
 delete mode 100644 external/libshell/LICENSE
 delete mode 100644 external/libshell/Makefile
 delete mode 100644 external/libshell/SYMS
 delete mode 100644 external/libshell/contrib/getoptx_1.0.bash
 delete mode 100644 external/libshell/contrib/getoptx_1.1.bash
 delete mode 100644 external/libshell/contrib/shell-array
 delete mode 100644 external/libshell/contrib/shell-crc32
 delete mode 100644 external/libshell/contrib/shell-lists
 delete mode 100644 external/libshell/contrib/shell-sort
 delete mode 100644 external/libshell/contrib/shell-stack
 delete mode 100644 external/libshell/docs/libshell.man
 delete mode 100644 external/libshell/docs/shell-error.man
 delete mode 100644 external/libshell/shell-args
 delete mode 100644 external/libshell/shell-cmdline
 delete mode 100644 external/libshell/shell-config
 delete mode 100644 external/libshell/shell-error
 delete mode 100644 external/libshell/shell-getopt
 delete mode 100644 external/libshell/shell-ini-config
 delete mode 100644 external/libshell/shell-ip-address
 delete mode 100644 external/libshell/shell-mail-address
 delete mode 100644 external/libshell/shell-quote
 delete mode 120000 external/libshell/shell-regexp
 delete mode 100644 external/libshell/shell-run
 delete mode 100644 external/libshell/shell-signal
 delete mode 100644 external/libshell/shell-source
 delete mode 100644 external/libshell/shell-string
 delete mode 100644 external/libshell/shell-unittest
 delete mode 100644 external/libshell/shell-var
 delete mode 100644 external/libshell/shell-version
 delete mode 100644 external/libshell/tests/cmdline_get
 delete mode 100644 external/libshell/tests/data/000-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/000-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/001-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/001-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/002-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/002-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/003-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/003-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/004-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/004-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/005-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/005-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/006-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/006-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/007-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/007-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/008-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/008-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/009-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/009-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/010-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/010-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/011-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/011-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/012-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/012-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/013-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/013-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/014-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/014-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/015-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/015-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/016-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/016-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/017-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/017-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/018-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/018-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/019-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/019-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/020-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/020-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/021-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/021-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/022-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/022-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/023-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/023-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/024-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/024-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/025-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/025-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/026-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/026-quote_shell_args-result
 delete mode 100644 external/libshell/tests/data/027-quote_shell_args-pattern
 delete mode 100644 external/libshell/tests/data/027-quote_shell_args-result
 delete mode 100644 external/libshell/tests/fatal
 delete mode 100644 external/libshell/tests/fill_mask
 delete mode 100644 external/libshell/tests/getopt
 delete mode 100644 external/libshell/tests/ini-config/z.ini
 delete mode 100644 external/libshell/tests/ini_config_get
 delete mode 100644 external/libshell/tests/ini_config_set
 delete mode 100644 external/libshell/tests/message
 delete mode 100644 external/libshell/tests/opt_check_dir
 delete mode 100644 external/libshell/tests/opt_check_number
 delete mode 100644 external/libshell/tests/opt_check_read
 delete mode 100644 external/libshell/tests/quote_sed_regexp
 delete mode 100644 external/libshell/tests/quote_sed_regexp_variable
 delete mode 100644 external/libshell/tests/quote_shell
 delete mode 100644 external/libshell/tests/quote_shell_args
 delete mode 100644 external/libshell/tests/quote_shell_variable
 delete mode 100755 external/libshell/tests/runtests
 delete mode 100644 external/libshell/tests/shell_var_trim
 delete mode 100644 external/libshell/tests/shell_var_unquote
 delete mode 100644 external/libshell/tests/signal
 delete mode 100755 external/libshell/tests/signal-data/001-signal
 delete mode 100755 external/libshell/tests/signal-data/002-signal
 delete mode 100755 external/libshell/tests/signal-data/003-signal
 delete mode 100755 external/libshell/tests/signal-data/004-signal
 delete mode 100755 external/libshell/tests/signal-data/005-signal
 delete mode 100755 external/libshell/tests/signal-data/006-signal
 delete mode 100755 external/libshell/tests/signal-data/007-signal
 delete mode 100644 external/libshell/tests/string_quote_remove
 delete mode 100644 external/libshell/tests/verbose
 delete mode 100644 external/remap-log.c
 create mode 100644 helpers/Makefile
 create mode 100644 helpers/coccinelle/api/alloc/drop_kmalloc_cast.cocci
 create mode 100644 helpers/coccinelle/api/alloc/kzalloc-simple.cocci
 create mode 100644 helpers/coccinelle/api/d_find_alias.cocci
 create mode 100644 helpers/coccinelle/api/devm_ioremap_resource.cocci
 create mode 100644 helpers/coccinelle/api/devm_request_and_ioremap.cocci
 create mode 100644 helpers/coccinelle/api/err_cast.cocci
 create mode 100644 helpers/coccinelle/api/kstrdup.cocci
 create mode 100644 helpers/coccinelle/api/memdup.cocci
 create mode 100644 helpers/coccinelle/api/memdup_user.cocci
 create mode 100644 helpers/coccinelle/api/ptr_ret.cocci
 create mode 100644 helpers/coccinelle/api/resource_size.cocci
 create mode 100644 helpers/coccinelle/api/simple_open.cocci
 create mode 100644 helpers/coccinelle/free/clk_put.cocci
 create mode 100644 helpers/coccinelle/free/devm_free.cocci
 create mode 100644 helpers/coccinelle/free/iounmap.cocci
 create mode 100644 helpers/coccinelle/free/kfree.cocci
 create mode 100644 helpers/coccinelle/free/kfreeaddr.cocci
 create mode 100644 helpers/coccinelle/free/pci_free_consistent.cocci
 create mode 100644 helpers/coccinelle/iterators/fen.cocci
 create mode 100644 helpers/coccinelle/iterators/itnull.cocci
 create mode 100644 helpers/coccinelle/iterators/list_entry_update.cocci
 create mode 100644 helpers/coccinelle/iterators/use_after_iter.cocci
 create mode 100644 helpers/coccinelle/locks/call_kern.cocci
 create mode 100644 helpers/coccinelle/locks/double_lock.cocci
 create mode 100644 helpers/coccinelle/locks/flags.cocci
 create mode 100644 helpers/coccinelle/locks/mini_lock.cocci
 create mode 100644 helpers/coccinelle/misc/boolinit.cocci
 create mode 100644 helpers/coccinelle/misc/boolreturn.cocci
 create mode 100644 helpers/coccinelle/misc/cstptr.cocci
 create mode 100644 helpers/coccinelle/misc/doubleinit.cocci
 create mode 100644 helpers/coccinelle/misc/ifaddr.cocci
 create mode 100644 helpers/coccinelle/misc/ifcol.cocci
 create mode 100644 helpers/coccinelle/misc/irqf_oneshot.cocci
 create mode 100644 helpers/coccinelle/misc/memcpy-assign.cocci
 create mode 100644 helpers/coccinelle/misc/noderef.cocci
 create mode 100644 helpers/coccinelle/misc/orplus.cocci
 create mode 100644 helpers/coccinelle/misc/semicolon.cocci
 create mode 100644 helpers/coccinelle/misc/warn.cocci
 create mode 100644 helpers/coccinelle/null/badzero.cocci
 create mode 100644 helpers/coccinelle/null/deref_null.cocci
 create mode 100644 helpers/coccinelle/null/eno.cocci
 create mode 100644 helpers/coccinelle/null/kmerr.cocci
 create mode 100644 helpers/coccinelle/tests/doublebitand.cocci
 create mode 100644 helpers/coccinelle/tests/doubletest.cocci
 create mode 100644 helpers/coccinelle/tests/odd_ptr_err.cocci
 create mode 100644 helpers/libshell/COPYING
 create mode 100644 helpers/libshell/LICENSE
 create mode 100644 helpers/libshell/Makefile
 create mode 100644 helpers/libshell/SYMS
 create mode 100644 helpers/libshell/contrib/getoptx_1.0.bash
 create mode 100644 helpers/libshell/contrib/getoptx_1.1.bash
 create mode 100644 helpers/libshell/contrib/shell-array
 create mode 100644 helpers/libshell/contrib/shell-crc32
 create mode 100644 helpers/libshell/contrib/shell-lists
 create mode 100644 helpers/libshell/contrib/shell-sort
 create mode 100644 helpers/libshell/contrib/shell-stack
 create mode 100644 helpers/libshell/docs/libshell.man
 create mode 100644 helpers/libshell/docs/shell-error.man
 create mode 100644 helpers/libshell/shell-args
 create mode 100644 helpers/libshell/shell-cmdline
 create mode 100644 helpers/libshell/shell-config
 create mode 100644 helpers/libshell/shell-error
 create mode 100644 helpers/libshell/shell-getopt
 create mode 100644 helpers/libshell/shell-ini-config
 create mode 100644 helpers/libshell/shell-ip-address
 create mode 100644 helpers/libshell/shell-mail-address
 create mode 100644 helpers/libshell/shell-quote
 create mode 120000 helpers/libshell/shell-regexp
 create mode 100644 helpers/libshell/shell-run
 create mode 100644 helpers/libshell/shell-signal
 create mode 100644 helpers/libshell/shell-source
 create mode 100644 helpers/libshell/shell-string
 create mode 100644 helpers/libshell/shell-unittest
 create mode 100644 helpers/libshell/shell-var
 create mode 100644 helpers/libshell/shell-version
 create mode 100644 helpers/libshell/tests/cmdline_get
 create mode 100644 helpers/libshell/tests/data/000-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/000-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/001-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/001-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/002-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/002-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/003-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/003-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/004-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/004-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/005-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/005-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/006-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/006-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/007-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/007-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/008-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/008-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/009-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/009-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/010-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/010-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/011-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/011-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/012-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/012-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/013-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/013-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/014-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/014-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/015-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/015-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/016-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/016-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/017-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/017-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/018-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/018-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/019-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/019-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/020-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/020-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/021-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/021-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/022-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/022-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/023-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/023-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/024-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/024-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/025-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/025-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/026-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/026-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/data/027-quote_shell_args-pattern
 create mode 100644 helpers/libshell/tests/data/027-quote_shell_args-result
 create mode 100644 helpers/libshell/tests/fatal
 create mode 100644 helpers/libshell/tests/fill_mask
 create mode 100644 helpers/libshell/tests/getopt
 create mode 100644 helpers/libshell/tests/ini-config/z.ini
 create mode 100644 helpers/libshell/tests/ini_config_get
 create mode 100644 helpers/libshell/tests/ini_config_set
 create mode 100644 helpers/libshell/tests/message
 create mode 100644 helpers/libshell/tests/opt_check_dir
 create mode 100644 helpers/libshell/tests/opt_check_number
 create mode 100644 helpers/libshell/tests/opt_check_read
 create mode 100644 helpers/libshell/tests/quote_sed_regexp
 create mode 100644 helpers/libshell/tests/quote_sed_regexp_variable
 create mode 100644 helpers/libshell/tests/quote_shell
 create mode 100644 helpers/libshell/tests/quote_shell_args
 create mode 100644 helpers/libshell/tests/quote_shell_variable
 create mode 100755 helpers/libshell/tests/runtests
 create mode 100644 helpers/libshell/tests/shell_var_trim
 create mode 100644 helpers/libshell/tests/shell_var_unquote
 create mode 100644 helpers/libshell/tests/signal
 create mode 100755 helpers/libshell/tests/signal-data/001-signal
 create mode 100755 helpers/libshell/tests/signal-data/002-signal
 create mode 100755 helpers/libshell/tests/signal-data/003-signal
 create mode 100755 helpers/libshell/tests/signal-data/004-signal
 create mode 100755 helpers/libshell/tests/signal-data/005-signal
 create mode 100755 helpers/libshell/tests/signal-data/006-signal
 create mode 100755 helpers/libshell/tests/signal-data/007-signal
 create mode 100644 helpers/libshell/tests/string_quote_remove
 create mode 100644 helpers/libshell/tests/verbose
 create mode 100644 helpers/remap-log.c

diff --git a/.gitignore b/.gitignore
index ed57a6f..4361bc4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
 aiaiai-locker
-external/remap-log
+helpers/remap-log
diff --git a/Makefile b/Makefile
index b97a353..a6c722c 100644
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,8 @@ CFLAGS = -O2 -g -Wextra
 
 all:
 	$(CC) $(CFLAGS) -o aiaiai-locker aiaiai-locker.c
-	make -C external
+	make -C helpers
 
 clean:
 	$(RM) aiaiai-locker
-	make -C external clean
+	make -C helpers clean
diff --git a/aiaiai-checker b/aiaiai-checker
index 5ca71c3..1c68efc 100755
--- a/aiaiai-checker
+++ b/aiaiai-checker
@@ -5,7 +5,7 @@
 # License: GPLv2
 
 srcdir="$(readlink -ev -- ${0%/*})"
-PATH="$srcdir:$srcdir/external/libshell:$srcdir/external:$PATH"
+PATH="$srcdir:$srcdir/helpers/libshell:$srcdir/helpers:$PATH"
 
 . shell-error
 . shell-args
diff --git a/aiaiai-concat-mboxes b/aiaiai-concat-mboxes
index 9d0e847..350d986 100755
--- a/aiaiai-concat-mboxes
+++ b/aiaiai-concat-mboxes
@@ -5,7 +5,7 @@
 # License: GPLv2
 
 srcdir="$(readlink -ev -- ${0%/*})"
-PATH="$srcdir:$srcdir/external/libshell:$PATH"
+PATH="$srcdir:$srcdir/helpers/libshell:$PATH"
 
 . shell-error
 
diff --git a/aiaiai-diff-log b/aiaiai-diff-log
index 55c2136..54228d9 100755
--- a/aiaiai-diff-log
+++ b/aiaiai-diff-log
@@ -6,7 +6,7 @@
 # License: GPLv2
 
 srcdir="$(readlink -ev -- ${0%/*})"
-PATH="$srcdir:$srcdir/external/libshell:$srcdir/external:$PATH"
+PATH="$srcdir:$srcdir/helpers/libshell:$srcdir/helpers:$PATH"
 
 . shell-error
 . shell-args
diff --git a/aiaiai-make-kernel b/aiaiai-make-kernel
index 5ce11aa..3bb2f02 100755
--- a/aiaiai-make-kernel
+++ b/aiaiai-make-kernel
@@ -5,7 +5,7 @@
 # License: GPLv2
 
 srcdir="$(readlink -ev -- ${0%/*})"
-export PATH="$srcdir:$srcdir/external/libshell:$srcdir/external:$PATH"
+export PATH="$srcdir:$srcdir/helpers/libshell:$srcdir/helpers:$PATH"
 
 . shell-error
 . shell-args
diff --git a/aiaiai-match-keywords b/aiaiai-match-keywords
index 701f459..bab7902 100755
--- a/aiaiai-match-keywords
+++ b/aiaiai-match-keywords
@@ -5,7 +5,7 @@
 # License: GPLv2
 
 srcdir="$(readlink -ev -- ${0%/*})"
-PATH="$srcdir:$srcdir/external/libshell:$PATH"
+PATH="$srcdir:$srcdir/helpers/libshell:$PATH"
 
 . shell-error
 . shell-args
diff --git a/aiaiai-test-bisectability b/aiaiai-test-bisectability
index 121312a..ffc0f55 100755
--- a/aiaiai-test-bisectability
+++ b/aiaiai-test-bisectability
@@ -5,7 +5,7 @@
 # License: GPLv2
 
 srcdir="$(readlink -ev -- ${0%/*})"
-PATH="$srcdir:$srcdir/external/libshell:$srcdir/external:$PATH"
+PATH="$srcdir:$srcdir/helpers/libshell:$srcdir/helpers:$PATH"
 
 . shell-error
 . shell-args
diff --git a/aiaiai-test-patchset b/aiaiai-test-patchset
index b231d30..0707019 100755
--- a/aiaiai-test-patchset
+++ b/aiaiai-test-patchset
@@ -5,7 +5,7 @@
 # License: GPLv2
 
 srcdir="$(readlink -ev -- ${0%/*})"
-PATH="$srcdir:$srcdir/external/libshell:$srcdir/external:$PATH"
+PATH="$srcdir:$srcdir/helpers/libshell:$srcdir/helpers:$PATH"
 
 . shell-error
 . shell-args
diff --git a/doc/README b/doc/README
index 1175f01..544d365 100644
--- a/doc/README
+++ b/doc/README
@@ -25,8 +25,9 @@ The layout of the repository.
 * aiaiai/email/
     All the scripts related to emails handling. If you use Aiaiai locally
     you do not need these scripts.
-* aiaiai/external/
-    Some external tools and files which we use are stored here.
+* aiaiai/helpers/
+    Variouls programs and scripts which Aiaiai users should not usually use
+    directly. Instead, Aiaiai scripts use them internally.
 * aiaiai/doc
     Some documentation.
 * aiaiai/tests/
@@ -145,14 +146,14 @@ sends it back to the patch submitter.
 
 * aiaiai-diff-log
     Compares 2 build logs and provides the differences. This script used the
-    'external/remap-log' tool to re-map line numbers in the warnings of the
+    'helpers/remap-log' tool to re-map line numbers in the warnings of the
     first build log to correspond to line numbers in the second build-log.
 
 * aiaiai-diff-log-helper
     A helper script for aiaiai-diff-log which sorts 2 build logs and compares
     them.  Written in Python because the shell version was too slow.
 
-* external/remap-log
+* helpers/remap-log
     This is a small C program originally written by Al Viro which helps
     comparing 2 build logs by remapping line numbers. Roughly speaking,
     'remap-log' takes the build log of the pre-patched kernel and the patch and
@@ -220,7 +221,7 @@ tool for comparing 2 build logs the smart way.
 
 If you just want to test a patch-set locally, you should use the
 'aiaiai-test-patchset' script. Do not forget to build the remap-log.c file in
-the 'external' subdirectory.
+the 'helpers' subdirectory.
 
 Here are some examples.
 
@@ -319,7 +320,7 @@ $ export PATH="$HOME/bin:$PATH"
 Coccinelle or "spatch" is a great semantic patch tool, very useful on its own.
 The Linux kernel contains a bunch of coccinelle semantic patches which catch
 various types of API abuses etc. We store a copy of these scripts in the
-"external" subdirectory.
+"helpers" subdirectory.
 
 The "spatch" tool is part of distributions like Debian and Fedora, so you most
 probably just need to install the corresponding package. The binary program is
diff --git a/email/aiaiai-email-dispatcher b/email/aiaiai-email-dispatcher
index 9fa7847..7487cd9 100755
--- a/email/aiaiai-email-dispatcher
+++ b/email/aiaiai-email-dispatcher
@@ -5,7 +5,7 @@
 # License: GPLv2
 
 srcdir="$(readlink -ev -- ${0%/*}/..)"
-PATH="$srcdir:$srcdir/email:$srcdir/external/libshell:$PATH"
+PATH="$srcdir:$srcdir/email:$srcdir/helpers/libshell:$PATH"
 
 . shell-error
 . shell-args
diff --git a/email/aiaiai-email-dispatcher-helper b/email/aiaiai-email-dispatcher-helper
index 91722b0..7d0365d 100755
--- a/email/aiaiai-email-dispatcher-helper
+++ b/email/aiaiai-email-dispatcher-helper
@@ -5,7 +5,7 @@
 # License: GPLv2
 
 srcdir="$(readlink -ev -- ${0%/*}/..)"
-PATH="$srcdir:$srcdir/email:$srcdir/external/libshell:$PATH"
+PATH="$srcdir:$srcdir/email:$srcdir/helpers/libshell:$PATH"
 
 . shell-error
 . shell-signal
diff --git a/email/aiaiai-email-lda b/email/aiaiai-email-lda
index 7489ffe..b9f2854 100755
--- a/email/aiaiai-email-lda
+++ b/email/aiaiai-email-lda
@@ -5,7 +5,7 @@
 # License: GPLv2
 
 srcdir="$(readlink -ev -- ${0%/*}/..)"
-PATH="$srcdir:$srcdir/email:$srcdir/external/libshell:$PATH"
+PATH="$srcdir:$srcdir/email:$srcdir/helpers/libshell:$PATH"
 
 . shell-error
 . shell-args
diff --git a/email/aiaiai-email-test-patchset b/email/aiaiai-email-test-patchset
index af38bb5..aa76b71 100755
--- a/email/aiaiai-email-test-patchset
+++ b/email/aiaiai-email-test-patchset
@@ -5,7 +5,7 @@
 # License: GPLv2
 
 srcdir="$(readlink -ev -- ${0%/*}/..)"
-PATH="$srcdir:$srcdir/email:$srcdir/external/libshell:$PATH"
+PATH="$srcdir:$srcdir/email:$srcdir/helpers/libshell:$PATH"
 
 . shell-error
 . shell-args
diff --git a/external/Makefile b/external/Makefile
deleted file mode 100644
index cbc9493..0000000
--- a/external/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-CFLAGS = -O2 -g -Wextra
-
-all:
-	$(CC) $(CFLAGS) -o remap-log remap-log.c
-
-clean:
-	$(RM) remap-log
diff --git a/external/coccinelle/api/alloc/drop_kmalloc_cast.cocci b/external/coccinelle/api/alloc/drop_kmalloc_cast.cocci
deleted file mode 100644
index bd5d08b..0000000
--- a/external/coccinelle/api/alloc/drop_kmalloc_cast.cocci
+++ /dev/null
@@ -1,67 +0,0 @@
-///
-/// Casting (void *) value returned by kmalloc is useless
-/// as mentioned in Documentation/CodingStyle, Chap 14.
-///
-// Confidence: High
-// Copyright: 2009,2010 Nicolas Palix, DIKU.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Options: --no-includes --include-headers
-//
-// Keywords: kmalloc, kzalloc, kcalloc
-// Version min: < 2.6.12 kmalloc
-// Version min: < 2.6.12 kcalloc
-// Version min:   2.6.14 kzalloc
-//
-
-virtual context
-virtual patch
-virtual org
-virtual report
-
-//----------------------------------------------------------
-//  For context mode
-//----------------------------------------------------------
-
- at depends on context@
-type T;
-@@
-
-* (T *)
-  \(kmalloc\|kzalloc\|kcalloc\)(...)
-
-//----------------------------------------------------------
-//  For patch mode
-//----------------------------------------------------------
-
- at depends on patch@
-type T;
-@@
-
-- (T *)
-  \(kmalloc\|kzalloc\|kcalloc\)(...)
-
-//----------------------------------------------------------
-//  For org and report mode
-//----------------------------------------------------------
-
- at r depends on org || report@
-type T;
-position p;
-@@
-
- (T at p *)\(kmalloc\|kzalloc\|kcalloc\)(...)
-
- at script:python depends on org@
-p << r.p;
-t << r.T;
-@@
-
-coccilib.org.print_safe_todo(p[0], t)
-
- at script:python depends on report@
-p << r.p;
-t << r.T;
-@@
-
-msg="WARNING: casting value returned by k[cmz]alloc to (%s *) is useless." % (t)
-coccilib.report.print_report(p[0], msg)
diff --git a/external/coccinelle/api/alloc/kzalloc-simple.cocci b/external/coccinelle/api/alloc/kzalloc-simple.cocci
deleted file mode 100644
index 52c55e4..0000000
--- a/external/coccinelle/api/alloc/kzalloc-simple.cocci
+++ /dev/null
@@ -1,86 +0,0 @@
-///
-/// Use kzalloc rather than kmalloc followed by memset with 0
-///
-/// This considers some simple cases that are common and easy to validate
-/// Note in particular that there are no ...s in the rule, so all of the
-/// matched code has to be contiguous
-///
-// Confidence: High
-// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU.  GPLv2.
-// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/rules/kzalloc.html
-// Options: --no-includes --include-headers
-//
-// Keywords: kmalloc, kzalloc
-// Version min: < 2.6.12 kmalloc
-// Version min:   2.6.14 kzalloc
-//
-
-virtual context
-virtual patch
-virtual org
-virtual report
-
-//----------------------------------------------------------
-//  For context mode
-//----------------------------------------------------------
-
- at depends on context@
-type T, T2;
-expression x;
-expression E1,E2;
-statement S;
-@@
-
-* x = (T)kmalloc(E1,E2);
-  if ((x==NULL) || ...) S
-* memset((T2)x,0,E1);
-
-//----------------------------------------------------------
-//  For patch mode
-//----------------------------------------------------------
-
- at depends on patch@
-type T, T2;
-expression x;
-expression E1,E2;
-statement S;
-@@
-
-- x = (T)kmalloc(E1,E2);
-+ x = kzalloc(E1,E2);
-  if ((x==NULL) || ...) S
-- memset((T2)x,0,E1);
-
-//----------------------------------------------------------
-//  For org mode
-//----------------------------------------------------------
-
- at r depends on org || report@
-type T, T2;
-expression x;
-expression E1,E2;
-statement S;
-position p;
-@@
-
- x = (T)kmalloc at p(E1,E2);
- if ((x==NULL) || ...) S
- memset((T2)x,0,E1);
-
- at script:python depends on org@
-p << r.p;
-x << r.x;
-@@
-
-msg="%s" % (x)
-msg_safe=msg.replace("[","@(").replace("]",")")
-coccilib.org.print_todo(p[0], msg_safe)
-
- at script:python depends on report@
-p << r.p;
-x << r.x;
-@@
-
-msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x)
-coccilib.report.print_report(p[0], msg)
diff --git a/external/coccinelle/api/d_find_alias.cocci b/external/coccinelle/api/d_find_alias.cocci
deleted file mode 100644
index 9594c9f..0000000
--- a/external/coccinelle/api/d_find_alias.cocci
+++ /dev/null
@@ -1,80 +0,0 @@
-/// Make sure calls to d_find_alias() have a corresponding call to dput().
-//
-// Keywords: d_find_alias, dput
-//
-// Confidence: Moderate
-// URL: http://coccinelle.lip6.fr/
-// Options: --include-headers
-
-virtual context
-virtual org
-virtual patch
-virtual report
-
- at r exists@
-local idexpression struct dentry *dent;
-expression E, E1;
-statement S1, S2;
-position p1, p2;
-@@
-(
-	if (!(dent at p1 = d_find_alias(...))) S1
-|
-	dent at p1 = d_find_alias(...)
-)
-
-<...when != dput(dent)
-    when != if (...) { <+... dput(dent) ...+> }
-    when != true !dent || ...
-    when != dent = E
-    when != E = dent
-if (!dent || ...) S2
-...>
-(
-	return <+...dent...+>;
-|
-	return @p2 ...;
-|
-	dent at p2 = E1;
-|
-	E1 = dent;
-)
-
- at depends on context@
-local idexpression struct dentry *r.dent;
-position r.p1,r.p2;
-@@
-* dent at p1 = ...
-  ...
-(
-* return at p2 ...;
-|
-* dent at p2
-)
-
-
- at script:python depends on org@
-p1 << r.p1;
-p2 << r.p2;
-@@
-cocci.print_main("Missing call to dput()",p1)
-cocci.print_secs("",p2)
-
- at depends on patch@
-local idexpression struct dentry *r.dent;
-position r.p2;
-@@
-(
-+ dput(dent);
-  return @p2 ...;
-|
-+ dput(dent);
-  dent at p2 = ...;
-)
-
- at script:python depends on report@
-p1 << r.p1;
-p2 << r.p2;
-@@
-msg = "Missing call to dput() at line %s."
-coccilib.report.print_report(p1[0], msg % (p2[0].line))
diff --git a/external/coccinelle/api/devm_ioremap_resource.cocci b/external/coccinelle/api/devm_ioremap_resource.cocci
deleted file mode 100644
index 495daa3..0000000
--- a/external/coccinelle/api/devm_ioremap_resource.cocci
+++ /dev/null
@@ -1,90 +0,0 @@
-virtual patch
-virtual report
-
- at depends on patch@
-expression base, dev, res;
-@@
-
--base = devm_request_and_ioremap(dev, res);
-+base = devm_ioremap_resource(dev, res);
- ...
- if (
--base == NULL
-+IS_ERR(base)
- || ...) {
-<...
--	return ...;
-+	return PTR_ERR(base);
-...>
- }
-
- at depends on patch@
-expression e, E, ret;
-identifier l;
-@@
-
- e = devm_ioremap_resource(...);
- ...
- if (IS_ERR(e) || ...) {
- 	... when any
--	ret = E;
-+	ret = PTR_ERR(e);
- 	...
-(
- 	return ret;
-|
- 	goto l;
-)
- }
-
- at depends on patch@
-expression e;
-@@
-
- e = devm_ioremap_resource(...);
- ...
- if (IS_ERR(e) || ...) {
- 	...
--	\(dev_dbg\|dev_err\|pr_debug\|pr_err\|DRM_ERROR\)(...);
- 	...
- }
-
- at depends on patch@
-expression e;
-identifier l;
-@@
-
- e = devm_ioremap_resource(...);
- ...
- if (IS_ERR(e) || ...)
--{
-(
- 	return ...;
-|
- 	goto l;
-)
--}
-
- at r depends on report@
-expression e;
-identifier l;
-position p1;
-@@
-
-*e = devm_request_and_ioremap at p1(...);
- ...
- if (e == NULL || ...) {
- 	...
-(
- 	return ...;
-|
- 	goto l;
-)
- }
-
- at script:python depends on r@
-p1 << r.p1;
-@@
-
-msg = "ERROR: deprecated devm_request_and_ioremap() API used on line %s" % (p1[0].line)
-coccilib.report.print_report(p1[0], msg)
diff --git a/external/coccinelle/api/devm_request_and_ioremap.cocci b/external/coccinelle/api/devm_request_and_ioremap.cocci
deleted file mode 100644
index 46beb81..0000000
--- a/external/coccinelle/api/devm_request_and_ioremap.cocci
+++ /dev/null
@@ -1,105 +0,0 @@
-/// Reimplement a call to devm_request_mem_region followed by a call to ioremap
-/// or ioremap_nocache by a call to devm_request_and_ioremap.
-/// Devm_request_and_ioremap was introduced in
-/// 72f8c0bfa0de64c68ee59f40eb9b2683bffffbb0.  It makes the code much more
-/// concise.
-///
-///
-// Confidence: High
-// Copyright: (C) 2011 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2011 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: -no_includes -include_headers
-
-virtual patch
-virtual org
-virtual report
-virtual context
-
- at nm@
-expression myname;
-identifier i;
-@@
-
-struct platform_driver i = { .driver = { .name = myname } };
-
- at depends on patch@
-expression dev,res,size;
-@@
-
--if (!devm_request_mem_region(dev, res->start, size,
--                              \(res->name\|dev_name(dev)\))) {
--   ...
--   return ...;
--}
-... when != res->start
-(
--devm_ioremap(dev,res->start,size)
-+devm_request_and_ioremap(dev,res)
-|
--devm_ioremap_nocache(dev,res->start,size)
-+devm_request_and_ioremap(dev,res)
-)
-... when any
-    when != res->start
-
-// this rule is separate from the previous one, because a single file can
-// have multiple values of myname
- at depends on patch@
-expression dev,res,size;
-expression nm.myname;
-@@
-
--if (!devm_request_mem_region(dev, res->start, size,myname)) {
--   ...
--   return ...;
--}
-... when != res->start
-(
--devm_ioremap(dev,res->start,size)
-+devm_request_and_ioremap(dev,res)
-|
--devm_ioremap_nocache(dev,res->start,size)
-+devm_request_and_ioremap(dev,res)
-)
-... when any
-    when != res->start
-
-
- at pb depends on org || report || context@
-expression dev,res,size;
-expression nm.myname;
-position p1,p2;
-@@
-
-*if
-  (!devm_request_mem_region at p1(dev, res->start, size,
-                              \(res->name\|dev_name(dev)\|myname\))) {
-   ...
-   return ...;
-}
-... when != res->start
-(
-*devm_ioremap at p2(dev,res->start,size)
-|
-*devm_ioremap_nocache at p2(dev,res->start,size)
-)
-... when any
-    when != res->start
-
- at script:python depends on org@
-p1 << pb.p1;
-p2 << pb.p2;
-@@
-
-cocci.print_main("INFO: replace by devm_request_and_ioremap",p1)
-cocci.print_secs("",p2)
-
- at script:python depends on report@
-p1 << pb.p1;
-p2 << pb.p2;
-@@
-
-msg = "INFO: devm_request_mem_region followed by ioremap on line %s can be replaced by devm_request_and_ioremap" % (p2[0].line)
-coccilib.report.print_report(p1[0],msg)
diff --git a/external/coccinelle/api/err_cast.cocci b/external/coccinelle/api/err_cast.cocci
deleted file mode 100644
index 2ce1150..0000000
--- a/external/coccinelle/api/err_cast.cocci
+++ /dev/null
@@ -1,56 +0,0 @@
-///
-/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...))
-///
-// Confidence: High
-// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU.  GPLv2.
-// Copyright: (C) 2009, 2010 Julia Lawall, DIKU.  GPLv2.
-// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Options:
-//
-// Keywords: ERR_PTR, PTR_ERR, ERR_CAST
-// Version min: 2.6.25
-//
-
-virtual context
-virtual patch
-virtual org
-virtual report
-
-
-@ depends on context && !patch && !org && !report@
-expression x;
-@@
-
-* ERR_PTR(PTR_ERR(x))
-
-@ depends on !context && patch && !org && !report @
-expression x;
-@@
-
-- ERR_PTR(PTR_ERR(x))
-+ ERR_CAST(x)
-
- at r depends on !context && !patch && (org || report)@
-expression x;
-position p;
-@@
-
- ERR_PTR at p(PTR_ERR(x))
-
- at script:python depends on org@
-p << r.p;
-x << r.x;
-@@
-
-msg="WARNING ERR_CAST can be used with %s" % (x)
-msg_safe=msg.replace("[","@(").replace("]",")")
-coccilib.org.print_todo(p[0], msg_safe)
-
- at script:python depends on report@
-p << r.p;
-x << r.x;
-@@
-
-msg="WARNING: ERR_CAST can be used with %s" % (x)
-coccilib.report.print_report(p[0], msg)
diff --git a/external/coccinelle/api/kstrdup.cocci b/external/coccinelle/api/kstrdup.cocci
deleted file mode 100644
index 09cba54..0000000
--- a/external/coccinelle/api/kstrdup.cocci
+++ /dev/null
@@ -1,104 +0,0 @@
-/// Use kstrdup rather than duplicating its implementation
-///
-// Confidence: High
-// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
-// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual context
-virtual org
-virtual report
-
- at depends on patch@
-expression from,to;
-expression flag,E1,E2;
-statement S;
-@@
-
--  to = kmalloc(strlen(from) + 1,flag);
-+  to = kstrdup(from, flag);
-   ... when != \(from = E1 \| to = E1 \)
-   if (to==NULL || ...) S
-   ... when != \(from = E2 \| to = E2 \)
--  strcpy(to, from);
-
- at depends on patch@
-expression x,from,to;
-expression flag,E1,E2,E3;
-statement S;
-@@
-
--   x = strlen(from) + 1;
-    ... when != \( x = E1 \| from = E1 \)
--   to = \(kmalloc\|kzalloc\)(x,flag);
-+   to = kstrdup(from, flag);
-    ... when != \(x = E2 \| from = E2 \| to = E2 \)
-    if (to==NULL || ...) S
-    ... when != \(x = E3 \| from = E3 \| to = E3 \)
--   memcpy(to, from, x);
-
-// ---------------------------------------------------------------------
-
- at r1 depends on !patch exists@
-expression from,to;
-expression flag,E1,E2;
-statement S;
-position p1,p2;
-@@
-
-*  to = kmalloc at p1(strlen(from) + 1,flag);
-   ... when != \(from = E1 \| to = E1 \)
-   if (to==NULL || ...) S
-   ... when != \(from = E2 \| to = E2 \)
-*  strcpy at p2(to, from);
-
- at r2 depends on !patch exists@
-expression x,from,to;
-expression flag,E1,E2,E3;
-statement S;
-position p1,p2;
-@@
-
-*   x = strlen(from) + 1;
-    ... when != \( x = E1 \| from = E1 \)
-*   to = \(kmalloc at p1\|kzalloc at p2\)(x,flag);
-    ... when != \(x = E2 \| from = E2 \| to = E2 \)
-    if (to==NULL || ...) S
-    ... when != \(x = E3 \| from = E3 \| to = E3 \)
-*   memcpy at p2(to, from, x);
-
- at script:python depends on org@
-p1 << r1.p1;
-p2 << r1.p2;
-@@
-
-cocci.print_main("WARNING opportunity for kstrdep",p1)
-cocci.print_secs("strcpy",p2)
-
- at script:python depends on org@
-p1 << r2.p1;
-p2 << r2.p2;
-@@
-
-cocci.print_main("WARNING opportunity for kstrdep",p1)
-cocci.print_secs("memcpy",p2)
-
- at script:python depends on report@
-p1 << r1.p1;
-p2 << r1.p2;
-@@
-
-msg = "WARNING opportunity for kstrdep (strcpy on line %s)" % (p2[0].line)
-coccilib.report.print_report(p1[0], msg)
-
- at script:python depends on report@
-p1 << r2.p1;
-p2 << r2.p2;
-@@
-
-msg = "WARNING opportunity for kstrdep (memcpy on line %s)" % (p2[0].line)
-coccilib.report.print_report(p1[0], msg)
diff --git a/external/coccinelle/api/memdup.cocci b/external/coccinelle/api/memdup.cocci
deleted file mode 100644
index 3d1aa71..0000000
--- a/external/coccinelle/api/memdup.cocci
+++ /dev/null
@@ -1,66 +0,0 @@
-/// Use kmemdup rather than duplicating its implementation
-///
-// Confidence: High
-// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
-// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual context
-virtual org
-virtual report
-
- at r1@
-expression from,to;
-expression flag;
-position p;
-@@
-
-   to = \(kmalloc at p\|kzalloc at p\)(strlen(from) + 1,flag);
-
- at r2@
-expression x,from,to;
-expression flag,E1;
-position p;
-@@
-
-    x = strlen(from) + 1;
-    ... when != \( x = E1 \| from = E1 \)
-    to = \(kmalloc at p\|kzalloc at p\)(x,flag);
-
- at depends on patch@
-expression from,to,size,flag;
-position p != {r1.p,r2.p};
-statement S;
-@@
-
--  to = \(kmalloc at p\|kzalloc at p\)(size,flag);
-+  to = kmemdup(from,size,flag);
-   if (to==NULL || ...) S
--  memcpy(to, from, size);
-
- at r depends on !patch@
-expression from,to,size,flag;
-position p != {r1.p,r2.p};
-statement S;
-@@
-
-*  to = \(kmalloc at p\|kzalloc at p\)(size,flag);
-   to = kmemdup(from,size,flag);
-   if (to==NULL || ...) S
-*  memcpy(to, from, size);
-
- at script:python depends on org@
-p << r.p;
-@@
-
-coccilib.org.print_todo(p[0], "WARNING opportunity for kmemdep")
-
- at script:python depends on report@
-p << r.p;
-@@
-
-coccilib.report.print_report(p[0], "WARNING opportunity for kmemdep")
diff --git a/external/coccinelle/api/memdup_user.cocci b/external/coccinelle/api/memdup_user.cocci
deleted file mode 100644
index c606231..0000000
--- a/external/coccinelle/api/memdup_user.cocci
+++ /dev/null
@@ -1,60 +0,0 @@
-/// Use memdup_user rather than duplicating its implementation
-/// This is a little bit restricted to reduce false positives
-///
-// Confidence: High
-// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
-// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual context
-virtual org
-virtual report
-
- at depends on patch@
-expression from,to,size,flag;
-identifier l1,l2;
-@@
-
--  to = \(kmalloc\|kzalloc\)(size,flag);
-+  to = memdup_user(from,size);
-   if (
--      to==NULL
-+      IS_ERR(to)
-                 || ...) {
-   <+... when != goto l1;
--  -ENOMEM
-+  PTR_ERR(to)
-   ...+>
-   }
--  if (copy_from_user(to, from, size) != 0) {
--    <+... when != goto l2;
--    -EFAULT
--    ...+>
--  }
-
- at r depends on !patch@
-expression from,to,size,flag;
-position p;
-statement S1,S2;
-@@
-
-*  to = \(kmalloc at p\|kzalloc at p\)(size,flag);
-   if (to==NULL || ...) S1
-   if (copy_from_user(to, from, size) != 0)
-   S2
-
- at script:python depends on org@
-p << r.p;
-@@
-
-coccilib.org.print_todo(p[0], "WARNING opportunity for memdup_user")
-
- at script:python depends on report@
-p << r.p;
-@@
-
-coccilib.report.print_report(p[0], "WARNING opportunity for memdup_user")
diff --git a/external/coccinelle/api/ptr_ret.cocci b/external/coccinelle/api/ptr_ret.cocci
deleted file mode 100644
index e18f840..0000000
--- a/external/coccinelle/api/ptr_ret.cocci
+++ /dev/null
@@ -1,96 +0,0 @@
-///
-/// Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR
-///
-// Confidence: High
-// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Options: --no-includes --include-headers
-//
-// Keywords: ERR_PTR, PTR_ERR, PTR_RET, PTR_ERR_OR_ZERO
-// Version min: 2.6.39
-//
-
-virtual context
-virtual patch
-virtual org
-virtual report
-
- at depends on patch@
-expression ptr;
-@@
-
-- if (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0;
-+ return PTR_ERR_OR_ZERO(ptr);
-
- at depends on patch@
-expression ptr;
-@@
-
-- if (IS_ERR(ptr)) return PTR_ERR(ptr); return 0;
-+ return PTR_ERR_OR_ZERO(ptr);
-
- at depends on patch@
-expression ptr;
-@@
-
-- (IS_ERR(ptr) ? PTR_ERR(ptr) : 0)
-+ PTR_ERR_OR_ZERO(ptr)
-
- at r1 depends on !patch@
-expression ptr;
-position p1;
-@@
-
-* if at p1 (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0;
-
- at r2 depends on !patch@
-expression ptr;
-position p2;
-@@
-
-* if at p2 (IS_ERR(ptr)) return PTR_ERR(ptr); return 0;
-
- at r3 depends on !patch@
-expression ptr;
-position p3;
-@@
-
-* IS_ERR at p3(ptr) ? PTR_ERR(ptr) : 0
-
- at script:python depends on org@
-p << r1.p1;
-@@
-
-coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used")
-
-
- at script:python depends on org@
-p << r2.p2;
-@@
-
-coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used")
-
- at script:python depends on org@
-p << r3.p3;
-@@
-
-coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used")
-
- at script:python depends on report@
-p << r1.p1;
-@@
-
-coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used")
-
- at script:python depends on report@
-p << r2.p2;
-@@
-
-coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used")
-
- at script:python depends on report@
-p << r3.p3;
-@@
-
-coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used")
diff --git a/external/coccinelle/api/resource_size.cocci b/external/coccinelle/api/resource_size.cocci
deleted file mode 100644
index 1935a58..0000000
--- a/external/coccinelle/api/resource_size.cocci
+++ /dev/null
@@ -1,93 +0,0 @@
-///
-/// Use resource_size function on resource object
-/// instead of explicit computation.
-///
-//  Confidence: High
-//  Copyright: (C) 2009, 2010 Nicolas Palix, DIKU.  GPLv2.
-//  Copyright: (C) 2009, 2010 Julia Lawall, DIKU.  GPLv2.
-//  Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
-//  URL: http://coccinelle.lip6.fr/
-//  Options:
-//
-//  Keywords: resource_size
-//  Version min: 2.6.27 resource_size
-//
-
-virtual context
-virtual patch
-virtual org
-virtual report
-
-//----------------------------------------------------------
-//  For context mode
-//----------------------------------------------------------
-
- at r_context depends on context && !patch && !org@
-struct resource *res;
-@@
-
-* (res->end - res->start) + 1
-
-//----------------------------------------------------------
-//  For patch mode
-//----------------------------------------------------------
-
- at r_patch depends on !context && patch && !org@
-struct resource *res;
-@@
-
-- (res->end - res->start) + 1
-+ resource_size(res)
-
-//----------------------------------------------------------
-//  For org mode
-//----------------------------------------------------------
-
-
- at r_org depends on !context && !patch && (org || report)@
-struct resource *res;
-position p;
-@@
-
- (res->end at p - res->start) + 1
-
- at rbad_org depends on !context && !patch && (org || report)@
-struct resource *res;
-position p != r_org.p;
-@@
-
- res->end at p - res->start
-
- at script:python depends on org@
-p << r_org.p;
-x << r_org.res;
-@@
-
-msg="ERROR with %s" % (x)
-msg_safe=msg.replace("[","@(").replace("]",")")
-coccilib.org.print_todo(p[0], msg_safe)
-
- at script:python depends on report@
-p << r_org.p;
-x << r_org.res;
-@@
-
-msg="ERROR: Missing resource_size with %s" % (x)
-coccilib.report.print_report(p[0], msg)
-
- at script:python depends on org@
-p << rbad_org.p;
-x << rbad_org.res;
-@@
-
-msg="WARNING with %s" % (x)
-msg_safe=msg.replace("[","@(").replace("]",")")
-coccilib.org.print_todo(p[0], msg_safe)
-
- at script:python depends on report@
-p << rbad_org.p;
-x << rbad_org.res;
-@@
-
-msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x)
-coccilib.report.print_report(p[0], msg)
diff --git a/external/coccinelle/api/simple_open.cocci b/external/coccinelle/api/simple_open.cocci
deleted file mode 100644
index b67e174..0000000
--- a/external/coccinelle/api/simple_open.cocci
+++ /dev/null
@@ -1,70 +0,0 @@
-/// This removes an open coded simple_open() function
-/// and replaces file operations references to the function
-/// with simple_open() instead.
-///
-// Confidence: High
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual report
-
-@ open depends on patch @
-identifier open_f != simple_open;
-identifier i, f;
-@@
--int open_f(struct inode *i, struct file *f)
--{
-(
--if (i->i_private)
--f->private_data = i->i_private;
-|
--f->private_data = i->i_private;
-)
--return 0;
--}
-
-@ has_open depends on open @
-identifier fops;
-identifier open.open_f;
-@@
-struct file_operations fops = {
-...,
--.open = open_f,
-+.open = simple_open,
-...
-};
-
-@ openr depends on report @
-identifier open_f != simple_open;
-identifier i, f;
-position p;
-@@
-int open_f at p(struct inode *i, struct file *f)
-{
-(
-if (i->i_private)
-f->private_data = i->i_private;
-|
-f->private_data = i->i_private;
-)
-return 0;
-}
-
-@ has_openr depends on openr @
-identifier fops;
-identifier openr.open_f;
-position p;
-@@
-struct file_operations fops = {
-...,
-.open = open_f at p,
-...
-};
-
- at script:python@
-pf << openr.p;
-ps << has_openr.p;
-@@
-
-coccilib.report.print_report(pf[0],"WARNING opportunity for simple_open, see also structure on line %s"%(ps[0].line))
diff --git a/external/coccinelle/free/clk_put.cocci b/external/coccinelle/free/clk_put.cocci
deleted file mode 100644
index 46747ad..0000000
--- a/external/coccinelle/free/clk_put.cocci
+++ /dev/null
@@ -1,67 +0,0 @@
-/// Find missing clk_puts.
-///
-//# This only signals a missing clk_put when there is a clk_put later
-//# in the same function.
-//# False positives can be due to loops.
-//
-// Confidence: Moderate
-// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options:
-
-virtual context
-virtual org
-virtual report
-
- at clk@
-expression e;
-statement S,S1;
-int ret;
-position p1,p2,p3;
-@@
-
-e = clk_get at p1(...)
-... when != clk_put(e)
-if (<+...e...+>) S
-... when any
-    when != clk_put(e)
-    when != if (...) { ... clk_put(e); ... }
-(
- if (ret == 0) S1
-|
-if (...)
-   { ...
-     return 0; }
-|
-if (...)
-   { ...
-     return <+...e...+>; }
-|
-*if at p2 (...)
-   { ... when != clk_put(e)
-         when forall
-     return at p3 ...; }
-)
-... when any
-clk_put(e);
-
- at script:python depends on org@
-p1 << clk.p1;
-p2 << clk.p2;
-p3 << clk.p3;
-@@
-
-cocci.print_main("clk_get",p1)
-cocci.print_secs("if",p2)
-cocci.print_secs("needed clk_put",p3)
-
- at script:python depends on report@
-p1 << clk.p1;
-p2 << clk.p2;
-p3 << clk.p3;
-@@
-
-msg = "ERROR: missing clk_put; clk_get on line %s and execution via conditional on line %s" % (p1[0].line,p2[0].line)
-coccilib.report.print_report(p3[0],msg)
diff --git a/external/coccinelle/free/devm_free.cocci b/external/coccinelle/free/devm_free.cocci
deleted file mode 100644
index 3d93490..0000000
--- a/external/coccinelle/free/devm_free.cocci
+++ /dev/null
@@ -1,71 +0,0 @@
-/// Find uses of standard freeing functons on values allocated using devm_
-/// functions.  Values allocated using the devm_functions are freed when
-/// the device is detached, and thus the use of the standard freeing
-/// function would cause a double free.
-/// See Documentation/driver-model/devres.txt for more information.
-///
-/// A difficulty of detecting this problem is that the standard freeing
-/// function might be called from a different function than the one
-/// containing the allocation function.  It is thus necessary to make the
-/// connection between the allocation function and the freeing function.
-/// Here this is done using the specific argument text, which is prone to
-/// false positives.  There is no rule for the request_region and
-/// request_mem_region variants because this heuristic seems to be a bit
-/// less reliable in these cases.
-///
-// Confidence: Moderate
-// Copyright: (C) 2011 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2011 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual org
-virtual report
-virtual context
-
- at r depends on context || org || report@
-expression x;
-@@
-
-(
- x = devm_kzalloc(...)
-|
- x = devm_request_irq(...)
-|
- x = devm_ioremap(...)
-|
- x = devm_ioremap_nocache(...)
-|
- x = devm_ioport_map(...)
-)
-
- at pb@
-expression r.x;
-position p;
-@@
-
-(
-* kfree at p(x)
-|
-* free_irq at p(x)
-|
-* iounmap at p(x)
-|
-* ioport_unmap at p(x)
-)
-
- at script:python depends on org@
-p << pb.p;
-@@
-
-msg="WARNING: invalid free of devm_ allocated data"
-coccilib.org.print_todo(p[0], msg)
-
- at script:python depends on report@
-p << pb.p;
-@@
-
-msg="WARNING: invalid free of devm_ allocated data"
-coccilib.report.print_report(p[0], msg)
-
diff --git a/external/coccinelle/free/iounmap.cocci b/external/coccinelle/free/iounmap.cocci
deleted file mode 100644
index 5384f4b..0000000
--- a/external/coccinelle/free/iounmap.cocci
+++ /dev/null
@@ -1,67 +0,0 @@
-/// Find missing iounmaps.
-///
-//# This only signals a missing iounmap when there is an iounmap later
-//# in the same function.
-//# False positives can be due to loops.
-//
-// Confidence: Moderate
-// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options:
-
-virtual context
-virtual org
-virtual report
-
- at iom@
-expression e;
-statement S,S1;
-int ret;
-position p1,p2,p3;
-@@
-
-e = \(ioremap at p1\|ioremap_nocache at p1\)(...)
-... when != iounmap(e)
-if (<+...e...+>) S
-... when any
-    when != iounmap(e)
-    when != if (...) { ... iounmap(e); ... }
-(
- if (ret == 0) S1
-|
-if (...)
-   { ...
-     return 0; }
-|
-if (...)
-   { ...
-     return <+...e...+>; }
-|
-*if at p2 (...)
-   { ... when != iounmap(e)
-         when forall
-     return at p3 ...; }
-)
-... when any
-iounmap(e);
-
- at script:python depends on org@
-p1 << iom.p1;
-p2 << iom.p2;
-p3 << iom.p3;
-@@
-
-cocci.print_main("ioremap",p1)
-cocci.print_secs("if",p2)
-cocci.print_secs("needed iounmap",p3)
-
- at script:python depends on report@
-p1 << iom.p1;
-p2 << iom.p2;
-p3 << iom.p3;
-@@
-
-msg = "ERROR: missing iounmap; ioremap on line %s and execution via conditional on line %s" % (p1[0].line,p2[0].line)
-coccilib.report.print_report(p3[0],msg)
diff --git a/external/coccinelle/free/kfree.cocci b/external/coccinelle/free/kfree.cocci
deleted file mode 100644
index 577b780..0000000
--- a/external/coccinelle/free/kfree.cocci
+++ /dev/null
@@ -1,121 +0,0 @@
-/// Find a use after free.
-//# Values of variables may imply that some
-//# execution paths are not possible, resulting in false positives.
-//# Another source of false positives are macros such as
-//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument
-///
-// Confidence: Moderate
-// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
-// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual org
-virtual report
-
- at free@
-expression E;
-position p1;
-@@
-
-kfree at p1(E)
-
- at print expression@
-constant char [] c;
-expression free.E,E2;
-type T;
-position p;
-identifier f;
-@@
-
-(
- f(...,c,...,(T)E at p,...)
-|
- E at p == E2
-|
- E at p != E2
-|
- E2 == E at p
-|
- E2 != E at p
-|
- !E at p
-|
- E at p || ...
-)
-
- at sz@
-expression free.E;
-position p;
-@@
-
- sizeof(<+...E at p...+>)
-
- at loop exists@
-expression E;
-identifier l;
-position ok;
-@@
-
-while (1) { ...
-  kfree at ok(E)
-  ... when != break;
-      when != goto l;
-      when forall
-}
-
- at r exists@
-expression free.E, subE<=free.E, E2;
-expression E1;
-iterator iter;
-statement S;
-position free.p1!=loop.ok,p2!={print.p,sz.p};
-@@
-
-kfree at p1(E,...)
-...
-(
- iter(...,subE,...) S // no use
-|
- list_remove_head(E1,subE,...)
-|
- subE = E2
-|
- subE++
-|
- ++subE
-|
- --subE
-|
- subE--
-|
- &subE
-|
- BUG(...)
-|
- BUG_ON(...)
-|
- return_VALUE(...)
-|
- return_ACPI_STATUS(...)
-|
- E at p2 // bad use
-)
-
- at script:python depends on org@
-p1 << free.p1;
-p2 << r.p2;
-@@
-
-cocci.print_main("kfree",p1)
-cocci.print_secs("ref",p2)
-
- at script:python depends on report@
-p1 << free.p1;
-p2 << r.p2;
-@@
-
-msg = "ERROR: reference preceded by free on line %s" % (p1[0].line)
-coccilib.report.print_report(p2[0],msg)
diff --git a/external/coccinelle/free/kfreeaddr.cocci b/external/coccinelle/free/kfreeaddr.cocci
deleted file mode 100644
index ce8aacc..0000000
--- a/external/coccinelle/free/kfreeaddr.cocci
+++ /dev/null
@@ -1,32 +0,0 @@
-/// Free of a structure field
-///
-// Confidence: High
-// Copyright: (C) 2013 Julia Lawall, INRIA/LIP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual org
-virtual report
-virtual context
-
- at r depends on context || report || org @
-expression e;
-identifier f;
-position p;
-@@
-
-* kfree at p(&e->f)
-
- at script:python depends on org@
-p << r.p;
-@@
-
-cocci.print_main("kfree",p)
-
- at script:python depends on report@
-p << r.p;
-@@
-
-msg = "ERROR: kfree of structure field"
-coccilib.report.print_report(p[0],msg)
diff --git a/external/coccinelle/free/pci_free_consistent.cocci b/external/coccinelle/free/pci_free_consistent.cocci
deleted file mode 100644
index 43600cc..0000000
--- a/external/coccinelle/free/pci_free_consistent.cocci
+++ /dev/null
@@ -1,52 +0,0 @@
-/// Find missing pci_free_consistent for every pci_alloc_consistent.
-///
-// Confidence: Moderate
-// Copyright: (C) 2013 Petr Strnad.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Keywords: pci_free_consistent, pci_alloc_consistent
-// Options: --no-includes --include-headers
-
-virtual report
-virtual org
-
- at search@
-local idexpression id;
-expression x,y,z,e;
-position p1,p2;
-type T;
-@@
-
-id = pci_alloc_consistent at p1(x,y,&z)
-... when != e = id
-if (id == NULL || ...) { ... return ...; }
-... when != pci_free_consistent(x,y,id,z)
-    when != if (id) { ... pci_free_consistent(x,y,id,z) ... }
-    when != if (y) { ... pci_free_consistent(x,y,id,z) ... }
-    when != e = (T)id
-    when exists
-(
-return 0;
-|
-return 1;
-|
-return id;
-|
-return at p2 ...;
-)
-
- at script:python depends on report@
-p1 << search.p1;
-p2 << search.p2;
-@@
-
-msg = "ERROR: missing pci_free_consistent; pci_alloc_consistent on line %s and return without freeing on line %s" % (p1[0].line,p2[0].line)
-coccilib.report.print_report(p2[0],msg)
-
- at script:python depends on org@
-p1 << search.p1;
-p2 << search.p2;
-@@
-
-msg = "ERROR: missing pci_free_consistent; pci_alloc_consistent on line %s and return without freeing on line %s" % (p1[0].line,p2[0].line)
-cocci.print_main(msg,p1)
-cocci.print_secs("",p2)
diff --git a/external/coccinelle/iterators/fen.cocci b/external/coccinelle/iterators/fen.cocci
deleted file mode 100644
index 48c152f..0000000
--- a/external/coccinelle/iterators/fen.cocci
+++ /dev/null
@@ -1,123 +0,0 @@
-/// These iterators only exit normally when the loop cursor is NULL, so there
-/// is no point to call of_node_put on the final value.
-///
-// Confidence: High
-// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
-// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual context
-virtual org
-virtual report
-
- at depends on patch@
-iterator name for_each_node_by_name;
-expression np,E;
-identifier l;
-@@
-
-for_each_node_by_name(np,...) {
-  ... when != break;
-      when != goto l;
-}
-... when != np = E
-- of_node_put(np);
-
- at depends on patch@
-iterator name for_each_node_by_type;
-expression np,E;
-identifier l;
-@@
-
-for_each_node_by_type(np,...) {
-  ... when != break;
-      when != goto l;
-}
-... when != np = E
-- of_node_put(np);
-
- at depends on patch@
-iterator name for_each_compatible_node;
-expression np,E;
-identifier l;
-@@
-
-for_each_compatible_node(np,...) {
-  ... when != break;
-      when != goto l;
-}
-... when != np = E
-- of_node_put(np);
-
- at depends on patch@
-iterator name for_each_matching_node;
-expression np,E;
-identifier l;
-@@
-
-for_each_matching_node(np,...) {
-  ... when != break;
-      when != goto l;
-}
-... when != np = E
-- of_node_put(np);
-
-// ----------------------------------------------------------------------
-
- at r depends on !patch forall@
-//iterator name for_each_node_by_name;
-//iterator name for_each_node_by_type;
-//iterator name for_each_compatible_node;
-//iterator name for_each_matching_node;
-expression np,E;
-identifier l;
-position p1,p2;
-@@
-
-(
-*for_each_node_by_name at p1(np,...)
-{
-  ... when != break;
-      when != goto l;
-}
-|
-*for_each_node_by_type at p1(np,...)
-{
-  ... when != break;
-      when != goto l;
-}
-|
-*for_each_compatible_node at p1(np,...)
-{
-  ... when != break;
-      when != goto l;
-}
-|
-*for_each_matching_node at p1(np,...)
-{
-  ... when != break;
-      when != goto l;
-}
-)
-... when != np = E
-* of_node_put at p2(np);
-
- at script:python depends on org@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-cocci.print_main("unneeded of_node_put",p2)
-cocci.print_secs("iterator",p1)
-
- at script:python depends on report@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-msg = "ERROR: of_node_put not needed after iterator on line %s" % (p1[0].line)
-coccilib.report.print_report(p2[0], msg)
diff --git a/external/coccinelle/iterators/itnull.cocci b/external/coccinelle/iterators/itnull.cocci
deleted file mode 100644
index f58732b..0000000
--- a/external/coccinelle/iterators/itnull.cocci
+++ /dev/null
@@ -1,94 +0,0 @@
-/// Many iterators have the property that the first argument is always bound
-/// to a real list element, never NULL.
-//# False positives arise for some iterators that do not have this property,
-//# or in cases when the loop cursor is reassigned.  The latter should only
-//# happen when the matched code is on the way to a loop exit (break, goto,
-//# or return).
-///
-// Confidence: Moderate
-// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
-// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual context
-virtual org
-virtual report
-
- at depends on patch@
-iterator I;
-expression x,E,E1,E2;
-statement S,S1,S2;
-@@
-
-I(x,...) { <...
-(
-- if (x == NULL && ...) S
-|
-- if (x != NULL || ...)
-  S
-|
-- (x == NULL) ||
-  E
-|
-- (x != NULL) &&
-  E
-|
-- (x == NULL && ...) ? E1 :
-  E2
-|
-- (x != NULL || ...) ?
-  E1
-- : E2
-|
-- if (x == NULL && ...) S1 else
-  S2
-|
-- if (x != NULL || ...)
-  S1
-- else S2
-|
-+ BAD(
-  x == NULL
-+ )
-|
-+ BAD(
-  x != NULL
-+ )
-)
-  ...> }
-
- at r depends on !patch exists@
-iterator I;
-expression x,E;
-position p1,p2;
-@@
-
-*I at p1(x,...)
-{ ... when != x = E
-(
-*  x at p2 == NULL
-|
-*  x at p2 != NULL
-)
-  ... when any
-}
-
- at script:python depends on org@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-cocci.print_main("iterator-bound variable",p1)
-cocci.print_secs("useless NULL test",p2)
-
- at script:python depends on report@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-msg = "ERROR: iterator variable bound on line %s cannot be NULL" % (p1[0].line)
-coccilib.report.print_report(p2[0], msg)
diff --git a/external/coccinelle/iterators/list_entry_update.cocci b/external/coccinelle/iterators/list_entry_update.cocci
deleted file mode 100644
index 873f444..0000000
--- a/external/coccinelle/iterators/list_entry_update.cocci
+++ /dev/null
@@ -1,62 +0,0 @@
-/// list_for_each_entry uses its first argument to get from one element of
-/// the list to the next, so it is usually not a good idea to reassign it.
-/// The first rule finds such a reassignment and the second rule checks
-/// that there is a path from the reassignment back to the top of the loop.
-///
-// Confidence: High
-// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
-// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
-// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual context
-virtual org
-virtual report
-
- at r@
-iterator name list_for_each_entry;
-expression x,E;
-position p1,p2;
-@@
-
-list_for_each_entry at p1(x,...) { <... x =@p2 E ...> }
-
- at depends on context && !org && !report@
-expression x,E;
-position r.p1,r.p2;
-statement S;
-@@
-
-*x =@p2 E
-...
-list_for_each_entry at p1(x,...) S
-
-// ------------------------------------------------------------------------
-
- at back depends on (org || report) && !context exists@
-expression x,E;
-position r.p1,r.p2;
-statement S;
-@@
-
-x =@p2 E
-...
-list_for_each_entry at p1(x,...) S
-
- at script:python depends on back && org@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-cocci.print_main("iterator",p1)
-cocci.print_secs("update",p2)
-
- at script:python depends on back && report@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-msg = "iterator with update on line %s" % (p2[0].line)
-coccilib.report.print_report(p1[0],msg)
diff --git a/external/coccinelle/iterators/use_after_iter.cocci b/external/coccinelle/iterators/use_after_iter.cocci
deleted file mode 100644
index f085f59..0000000
--- a/external/coccinelle/iterators/use_after_iter.cocci
+++ /dev/null
@@ -1,147 +0,0 @@
-/// If list_for_each_entry, etc complete a traversal of the list, the iterator
-/// variable ends up pointing to an address at an offset from the list head,
-/// and not a meaningful structure.  Thus this value should not be used after
-/// the end of the iterator.
-//#False positives arise when there is a goto in the iterator and the
-//#reported reference is at the label of this goto.  Some flag tests
-//#may also cause a report to be a false positive.
-///
-// Confidence: Moderate
-// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2012 Gilles Muller, INRIA/LIP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual context
-virtual org
-virtual report
-
- at r exists@
-identifier c,member;
-expression E,x;
-iterator name list_for_each_entry;
-iterator name list_for_each_entry_reverse;
-iterator name list_for_each_entry_continue;
-iterator name list_for_each_entry_continue_reverse;
-iterator name list_for_each_entry_from;
-iterator name list_for_each_entry_safe;
-iterator name list_for_each_entry_safe_continue;
-iterator name list_for_each_entry_safe_from;
-iterator name list_for_each_entry_safe_reverse;
-iterator name hlist_for_each_entry;
-iterator name hlist_for_each_entry_continue;
-iterator name hlist_for_each_entry_from;
-iterator name hlist_for_each_entry_safe;
-statement S;
-position p1,p2;
-@@
-
-(
-list_for_each_entry at p1(c,...,member) { ... when != break;
-                                 when forall
-                                 when strict
-}
-|
-list_for_each_entry_reverse at p1(c,...,member) { ... when != break;
-                                 when forall
-                                 when strict
-}
-|
-list_for_each_entry_continue at p1(c,...,member) { ... when != break;
-                                 when forall
-                                 when strict
-}
-|
-list_for_each_entry_continue_reverse at p1(c,...,member) { ... when != break;
-                                 when forall
-                                 when strict
-}
-|
-list_for_each_entry_from at p1(c,...,member) { ... when != break;
-                                 when forall
-                                 when strict
-}
-|
-list_for_each_entry_safe at p1(c,...,member) { ... when != break;
-                                 when forall
-                                 when strict
-}
-|
-list_for_each_entry_safe_continue at p1(c,...,member) { ... when != break;
-                                 when forall
-                                 when strict
-}
-|
-list_for_each_entry_safe_from at p1(c,...,member) { ... when != break;
-                                 when forall
-                                 when strict
-}
-|
-list_for_each_entry_safe_reverse at p1(c,...,member) { ... when != break;
-                                 when forall
-                                 when strict
-}
-)
-...
-(
-list_for_each_entry(c,...) S
-|
-list_for_each_entry_reverse(c,...) S
-|
-list_for_each_entry_continue(c,...) S
-|
-list_for_each_entry_continue_reverse(c,...) S
-|
-list_for_each_entry_from(c,...) S
-|
-list_for_each_entry_safe(c,...) S
-|
-list_for_each_entry_safe(x,c,...) S
-|
-list_for_each_entry_safe_continue(c,...) S
-|
-list_for_each_entry_safe_continue(x,c,...) S
-|
-list_for_each_entry_safe_from(c,...) S
-|
-list_for_each_entry_safe_from(x,c,...) S
-|
-list_for_each_entry_safe_reverse(c,...) S
-|
-list_for_each_entry_safe_reverse(x,c,...) S
-|
-hlist_for_each_entry(c,...) S
-|
-hlist_for_each_entry_continue(c,...) S
-|
-hlist_for_each_entry_from(c,...) S
-|
-hlist_for_each_entry_safe(c,...) S
-|
-list_remove_head(x,c,...)
-|
-sizeof(<+...c...+>)
-|
-&c->member
-|
-c = E
-|
-*c at p2
-)
-
- at script:python depends on org@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-cocci.print_main("invalid iterator index reference",p2)
-cocci.print_secs("iterator",p1)
-
- at script:python depends on report@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-msg = "ERROR: invalid reference to the index variable of the iterator on line %s" % (p1[0].line)
-coccilib.report.print_report(p2[0], msg)
diff --git a/external/coccinelle/locks/call_kern.cocci b/external/coccinelle/locks/call_kern.cocci
deleted file mode 100644
index 669b244..0000000
--- a/external/coccinelle/locks/call_kern.cocci
+++ /dev/null
@@ -1,105 +0,0 @@
-/// Find functions that refer to GFP_KERNEL but are called with locks held.
-//# The proposed change of converting the GFP_KERNEL is not necessarily the
-//# correct one.  It may be desired to unlock the lock, or to not call the
-//# function under the lock in the first place.
-///
-// Confidence: Moderate
-// Copyright: (C) 2012 Nicolas Palix.  GPLv2.
-// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual context
-virtual org
-virtual report
-
- at gfp exists@
-identifier fn;
-position p;
-@@
-
-fn(...) {
- ... when != read_unlock_irq(...)
-     when != write_unlock_irq(...)
-     when != read_unlock_irqrestore(...)
-     when != write_unlock_irqrestore(...)
-     when != spin_unlock(...)
-     when != spin_unlock_irq(...)
-     when != spin_unlock_irqrestore(...)
-     when != local_irq_enable(...)
-     when any
- GFP_KERNEL at p
- ... when any
-}
-
- at locked exists@
-identifier gfp.fn;
-position p1,p2;
-@@
-
-(
-read_lock_irq at p1
-|
-write_lock_irq at p1
-|
-read_lock_irqsave at p1
-|
-write_lock_irqsave at p1
-|
-spin_lock at p1
-|
-spin_trylock at p1
-|
-spin_lock_irq at p1
-|
-spin_lock_irqsave at p1
-|
-local_irq_disable at p1
-)
- (...)
-...  when != read_unlock_irq(...)
-     when != write_unlock_irq(...)
-     when != read_unlock_irqrestore(...)
-     when != write_unlock_irqrestore(...)
-     when != spin_unlock(...)
-     when != spin_unlock_irq(...)
-     when != spin_unlock_irqrestore(...)
-     when != local_irq_enable(...)
-fn at p2(...)
-
- at depends on locked && patch@
-position gfp.p;
-@@
-
-- GFP_KERNEL at p
-+ GFP_ATOMIC
-
- at depends on locked && !patch@
-position gfp.p;
-@@
-
-* GFP_KERNEL at p
-
- at script:python depends on !patch && org@
-p << gfp.p;
-fn << gfp.fn;
-p1 << locked.p1;
-p2 << locked.p2;
-@@
-
-cocci.print_main("lock",p1)
-cocci.print_secs("call",p2)
-cocci.print_secs("GFP_KERNEL",p)
-
- at script:python depends on !patch && report@
-p << gfp.p;
-fn << gfp.fn;
-p1 << locked.p1;
-p2 << locked.p2;
-@@
-
-msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line)
-coccilib.report.print_report(p[0], msg)
diff --git a/external/coccinelle/locks/double_lock.cocci b/external/coccinelle/locks/double_lock.cocci
deleted file mode 100644
index 002752f..0000000
--- a/external/coccinelle/locks/double_lock.cocci
+++ /dev/null
@@ -1,92 +0,0 @@
-/// Find double locks.  False positives may occur when some paths cannot
-/// occur at execution, due to the values of variables, and when there is
-/// an intervening function call that releases the lock.
-///
-// Confidence: Moderate
-// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
-// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
-// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual org
-virtual report
-
- at locked@
-position p1;
-expression E1;
-position p;
-@@
-
-(
-mutex_lock at p1
-|
-mutex_trylock at p1
-|
-spin_lock at p1
-|
-spin_trylock at p1
-|
-read_lock at p1
-|
-read_trylock at p1
-|
-write_lock at p1
-|
-write_trylock at p1
-) (E1 at p,...);
-
- at balanced@
-position p1 != locked.p1;
-position locked.p;
-identifier lock,unlock;
-expression x <= locked.E1;
-expression E,locked.E1;
-expression E2;
-@@
-
-if (E) {
- <+... when != E1
- lock(E1 at p,...)
- ...+>
-}
-... when != E1
-    when != \(x = E2\|&x\)
-    when forall
-if (E) {
- <+... when != E1
- unlock at p1(E1,...)
- ...+>
-}
-
- at r depends on !balanced exists@
-expression x <= locked.E1;
-expression locked.E1;
-expression E2;
-identifier lock;
-position locked.p,p1,p2;
-@@
-
-lock at p1 (E1 at p,...);
-... when != E1
-    when != \(x = E2\|&x\)
-lock at p2 (E1,...);
-
- at script:python depends on org@
-p1 << r.p1;
-p2 << r.p2;
-lock << r.lock;
-@@
-
-cocci.print_main(lock,p1)
-cocci.print_secs("second lock",p2)
-
- at script:python depends on report@
-p1 << r.p1;
-p2 << r.p2;
-lock << r.lock;
-@@
-
-msg = "second lock on line %s" % (p2[0].line)
-coccilib.report.print_report(p1[0],msg)
diff --git a/external/coccinelle/locks/flags.cocci b/external/coccinelle/locks/flags.cocci
deleted file mode 100644
index debd70e..0000000
--- a/external/coccinelle/locks/flags.cocci
+++ /dev/null
@@ -1,80 +0,0 @@
-/// Find nested lock+irqsave functions that use the same flags variables
-///
-// Confidence: High
-// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
-// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual context
-virtual org
-virtual report
-
- at r exists@
-expression lock1,lock2,flags;
-position p1,p2;
-@@
-
-(
-spin_lock_irqsave at p1(lock1,flags)
-|
-read_lock_irqsave at p1(lock1,flags)
-|
-write_lock_irqsave at p1(lock1,flags)
-)
-... when != flags
-(
-spin_lock_irqsave(lock1,flags)
-|
-read_lock_irqsave(lock1,flags)
-|
-write_lock_irqsave(lock1,flags)
-|
-spin_lock_irqsave at p2(lock2,flags)
-|
-read_lock_irqsave at p2(lock2,flags)
-|
-write_lock_irqsave at p2(lock2,flags)
-)
-
- at d exists@
-expression f <= r.flags;
-expression lock1,lock2,flags;
-position r.p1, r.p2;
-@@
-
-(
-*spin_lock_irqsave at p1(lock1,flags)
-|
-*read_lock_irqsave at p1(lock1,flags)
-|
-*write_lock_irqsave at p1(lock1,flags)
-)
-... when != f
-(
-*spin_lock_irqsave at p2(lock2,flags)
-|
-*read_lock_irqsave at p2(lock2,flags)
-|
-*write_lock_irqsave at p2(lock2,flags)
-)
-
-// ----------------------------------------------------------------------
-
- at script:python depends on d && org@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-cocci.print_main("original lock",p1)
-cocci.print_secs("nested lock+irqsave that reuses flags",p2)
-
- at script:python depends on d && report@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-msg="ERROR: nested lock+irqsave that reuses flags from line %s." % (p1[0].line)
-coccilib.report.print_report(p2[0], msg)
diff --git a/external/coccinelle/locks/mini_lock.cocci b/external/coccinelle/locks/mini_lock.cocci
deleted file mode 100644
index 47f649b..0000000
--- a/external/coccinelle/locks/mini_lock.cocci
+++ /dev/null
@@ -1,96 +0,0 @@
-/// Find missing unlocks.  This semantic match considers the specific case
-/// where the unlock is missing from an if branch, and there is a lock
-/// before the if and an unlock after the if.  False positives are due to
-/// cases where the if branch represents a case where the function is
-/// supposed to exit with the lock held, or where there is some preceding
-/// function call that releases the lock.
-///
-// Confidence: Moderate
-// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
-// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual context
-virtual org
-virtual report
-
- at prelocked@
-position p1,p;
-expression E1;
-@@
-
-(
-mutex_lock at p1
-|
-mutex_trylock at p1
-|
-spin_lock at p1
-|
-spin_trylock at p1
-|
-read_lock at p1
-|
-read_trylock at p1
-|
-write_lock at p1
-|
-write_trylock at p1
-|
-read_lock_irq at p1
-|
-write_lock_irq at p1
-|
-read_lock_irqsave at p1
-|
-write_lock_irqsave at p1
-|
-spin_lock_irq at p1
-|
-spin_lock_irqsave at p1
-) (E1 at p,...);
-
- at looped@
-position r;
-@@
-
-for(...;...;...) { <+... return at r ...; ...+> }
-
- at err exists@
-expression E1;
-position prelocked.p;
-position up != prelocked.p1;
-position r!=looped.r;
-identifier lock,unlock;
-@@
-
-*lock(E1 at p,...);
-<+... when != E1
-if (...) {
-  ... when != E1
-*  return at r ...;
-}
-...+>
-*unlock at up(E1,...);
-
- at script:python depends on org@
-p << prelocked.p1;
-lock << err.lock;
-unlock << err.unlock;
-p2 << err.r;
-@@
-
-cocci.print_main(lock,p)
-cocci.print_secs(unlock,p2)
-
- at script:python depends on report@
-p << prelocked.p1;
-lock << err.lock;
-unlock << err.unlock;
-p2 << err.r;
-@@
-
-msg = "preceding lock on line %s" % (p[0].line)
-coccilib.report.print_report(p2[0],msg)
diff --git a/external/coccinelle/misc/boolinit.cocci b/external/coccinelle/misc/boolinit.cocci
deleted file mode 100644
index b9abed4..0000000
--- a/external/coccinelle/misc/boolinit.cocci
+++ /dev/null
@@ -1,178 +0,0 @@
-/// Bool initializations should use true and false.  Bool tests don't need
-/// comparisons.  Based on contributions from Joe Perches, Rusty Russell
-/// and Bruce W Allan.
-///
-// Confidence: High
-// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Options: --include-headers
-
-virtual patch
-virtual context
-virtual org
-virtual report
-
- at depends on patch@
-bool t;
-symbol true;
-symbol false;
-@@
-
-(
-- t == true
-+ t
-|
-- true == t
-+ t
-|
-- t != true
-+ !t
-|
-- true != t
-+ !t
-|
-- t == false
-+ !t
-|
-- false == t
-+ !t
-|
-- t != false
-+ t
-|
-- false != t
-+ t
-)
-
- at depends on patch disable is_zero, isnt_zero@
-bool t;
-@@
-
-(
-- t == 1
-+ t
-|
-- t != 1
-+ !t
-|
-- t == 0
-+ !t
-|
-- t != 0
-+ t
-)
-
- at depends on patch@
-bool b;
-@@
-(
- b =
-- 0
-+ false
-|
- b =
-- 1
-+ true
-)
-
-// ---------------------------------------------------------------------
-
- at r1 depends on !patch@
-bool t;
-position p;
-@@
-
-(
-* t at p == true
-|
-* true == t at p
-|
-* t at p != true
-|
-* true != t at p
-|
-* t at p == false
-|
-* false == t at p
-|
-* t at p != false
-|
-* false != t at p
-)
-
- at r2 depends on !patch disable is_zero, isnt_zero@
-bool t;
-position p;
-@@
-
-(
-* t at p == 1
-|
-* t at p != 1
-|
-* t at p == 0
-|
-* t at p != 0
-)
-
- at r3 depends on !patch@
-bool b;
-position p1,p2;
-constant c;
-@@
-(
-*b at p1 = 0
-|
-*b at p1 = 1
-|
-*b at p2 = c
-)
-
- at script:python depends on org@
-p << r1.p;
-@@
-
-cocci.print_main("WARNING: Comparison to bool",p)
-
- at script:python depends on org@
-p << r2.p;
-@@
-
-cocci.print_main("WARNING: Comparison of bool to 0/1",p)
-
- at script:python depends on org@
-p1 << r3.p1;
-@@
-
-cocci.print_main("WARNING: Assignment of bool to 0/1",p1)
-
- at script:python depends on org@
-p2 << r3.p2;
-@@
-
-cocci.print_main("ERROR: Assignment of bool to non-0/1 constant",p2)
-
- at script:python depends on report@
-p << r1.p;
-@@
-
-coccilib.report.print_report(p[0],"WARNING: Comparison to bool")
-
- at script:python depends on report@
-p << r2.p;
-@@
-
-coccilib.report.print_report(p[0],"WARNING: Comparison of bool to 0/1")
-
- at script:python depends on report@
-p1 << r3.p1;
-@@
-
-coccilib.report.print_report(p1[0],"WARNING: Assignment of bool to 0/1")
-
- at script:python depends on report@
-p2 << r3.p2;
-@@
-
-coccilib.report.print_report(p2[0],"ERROR: Assignment of bool to non-0/1 constant")
diff --git a/external/coccinelle/misc/boolreturn.cocci b/external/coccinelle/misc/boolreturn.cocci
deleted file mode 100644
index a43c7b0..0000000
--- a/external/coccinelle/misc/boolreturn.cocci
+++ /dev/null
@@ -1,58 +0,0 @@
-/// Return statements in functions returning bool should use
-/// true/false instead of 1/0.
-//
-// Confidence: High
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual report
-virtual context
-
- at r1 depends on patch@
-identifier fn;
-typedef bool;
-symbol false;
-symbol true;
-@@
-
-bool fn ( ... )
-{
-<...
-return
-(
-- 0
-+ false
-|
-- 1
-+ true
-)
-  ;
-...>
-}
-
- at r2 depends on report || context@
-identifier fn;
-position p;
-@@
-
-bool fn ( ... )
-{
-<...
-return
-(
-* 0 at p
-|
-* 1 at p
-)
-  ;
-...>
-}
-
-
- at script:python depends on report@
-p << r2.p;
-fn << r2.fn;
-@@
-
-msg = "WARNING: return of 0/1 in function '%s' with return type bool" % fn
-coccilib.report.print_report(p[0], msg)
diff --git a/external/coccinelle/misc/cstptr.cocci b/external/coccinelle/misc/cstptr.cocci
deleted file mode 100644
index f0368b3..0000000
--- a/external/coccinelle/misc/cstptr.cocci
+++ /dev/null
@@ -1,41 +0,0 @@
-/// PTR_ERR should be applied before its argument is reassigned, typically
-/// to NULL
-///
-// Confidence: High
-// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual org
-virtual report
-virtual context
-
- at r exists@
-expression e,e1;
-constant c;
-position p1,p2;
-@@
-
-*e at p1 = c
-... when != e = e1
-    when != &e
-    when != true IS_ERR(e)
-*PTR_ERR at p2(e)
-
- at script:python depends on org@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-cocci.print_main("PTR_ERR",p2)
-cocci.print_secs("assignment",p1)
-
- at script:python depends on report@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-msg = "ERROR: PTR_ERR applied after initialization to constant on line %s" % (p1[0].line)
-coccilib.report.print_report(p2[0],msg)
diff --git a/external/coccinelle/misc/doubleinit.cocci b/external/coccinelle/misc/doubleinit.cocci
deleted file mode 100644
index c0c3371..0000000
--- a/external/coccinelle/misc/doubleinit.cocci
+++ /dev/null
@@ -1,53 +0,0 @@
-/// Find duplicate field initializations.  This has a high rate of false
-/// positives due to #ifdefs, which Coccinelle is not aware of in a structure
-/// initialization.
-///
-// Confidence: Low
-// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
-// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise
-// Options: --no-includes --include-headers
-
-virtual org
-virtual report
-
- at r@
-identifier I, s, fld;
-position p0,p;
-expression E;
-@@
-
-struct I s =@p0 { ..., .fld at p = E, ...};
-
- at s@
-identifier I, s, r.fld;
-position r.p0,p;
-expression E;
-@@
-
-struct I s =@p0 { ..., .fld at p = E, ...};
-
- at script:python depends on org@
-p0 << r.p0;
-fld << r.fld;
-ps << s.p;
-pr << r.p;
-@@
-
-if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
-  cocci.print_main(fld,p0)
-  cocci.print_secs("s",ps)
-  cocci.print_secs("r",pr)
-
- at script:python depends on report@
-p0 << r.p0;
-fld << r.fld;
-ps << s.p;
-pr << r.p;
-@@
-
-if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
-  msg = "%s: first occurrence line %s, second occurrence line %s" % (fld,ps[0].line,pr[0].line)
-  coccilib.report.print_report(p0[0],msg)
diff --git a/external/coccinelle/misc/ifaddr.cocci b/external/coccinelle/misc/ifaddr.cocci
deleted file mode 100644
index 8aebd18..0000000
--- a/external/coccinelle/misc/ifaddr.cocci
+++ /dev/null
@@ -1,35 +0,0 @@
-/// the address of a variable or field is non-zero is likely always to bo
-/// non-zero
-///
-// Confidence: High
-// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual org
-virtual report
-virtual context
-
- at r@
-expression x;
-statement S1,S2;
-position p;
-@@
-
-*if at p (&x)
- S1 else S2
-
- at script:python depends on org@
-p << r.p;
-@@
-
-cocci.print_main("test of a variable/field address",p)
-
- at script:python depends on report@
-p << r.p;
-@@
-
-msg = "ERROR: test of a variable/field address"
-coccilib.report.print_report(p[0],msg)
diff --git a/external/coccinelle/misc/ifcol.cocci b/external/coccinelle/misc/ifcol.cocci
deleted file mode 100644
index d0d00ef..0000000
--- a/external/coccinelle/misc/ifcol.cocci
+++ /dev/null
@@ -1,48 +0,0 @@
-/// Find confusingly indented code in or after an if.  An if branch should
-/// be indented.  The code following an if should not be indented.
-/// Sometimes, code after an if that is indented is actually intended to be
-/// part of the if branch.
-///
-/// This has a high rate of false positives, because Coccinelle's column
-/// calculation does not distinguish between spaces and tabs, so code that
-/// is not visually aligned may be considered to be in the same column.
-///
-// Confidence: Low
-// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
-// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
-// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual org
-virtual report
-
- at r disable braces4@
-position p1,p2;
-statement S1,S2;
-@@
-
-(
-if (...) { ... }
-|
-if (...) S1 at p1 S2 at p2
-)
-
- at script:python depends on org@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-if (p1[0].column == p2[0].column):
-  cocci.print_main("branch",p1)
-  cocci.print_secs("after",p2)
-
- at script:python depends on report@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-if (p1[0].column == p2[0].column):
-  msg = "code aligned with following code on line %s" % (p2[0].line)
-  coccilib.report.print_report(p1[0],msg)
diff --git a/external/coccinelle/misc/irqf_oneshot.cocci b/external/coccinelle/misc/irqf_oneshot.cocci
deleted file mode 100644
index 6cfde94..0000000
--- a/external/coccinelle/misc/irqf_oneshot.cocci
+++ /dev/null
@@ -1,65 +0,0 @@
-/// Make sure threaded IRQs without a primary handler are always request with
-/// IRQF_ONESHOT
-///
-//
-// Confidence: Good
-// Comments:
-// Options: --no-includes
-
-virtual patch
-virtual context
-virtual org
-virtual report
-
- at r1@
-expression irq;
-expression thread_fn;
-expression flags;
-position p;
-@@
-request_threaded_irq at p(irq, NULL, thread_fn,
-(
-flags | IRQF_ONESHOT
-|
-IRQF_ONESHOT
-)
-, ...)
-
- at depends on patch@
-expression irq;
-expression thread_fn;
-expression flags;
-position p != r1.p;
-@@
-request_threaded_irq at p(irq, NULL, thread_fn,
-(
--0
-+IRQF_ONESHOT
-|
--flags
-+flags | IRQF_ONESHOT
-)
-, ...)
-
- at depends on context@
-position p != r1.p;
-@@
-*request_threaded_irq at p(...)
-
- at match depends on report || org@
-expression irq;
-position p != r1.p;
-@@
-request_threaded_irq at p(irq, NULL, ...)
-
- at script:python depends on org@
-p << match.p;
-@@
-msg = "ERROR: Threaded IRQ with no primary handler requested without IRQF_ONESHOT"
-coccilib.org.print_todo(p[0],msg)
-
- at script:python depends on report@
-p << match.p;
-@@
-msg = "ERROR: Threaded IRQ with no primary handler requested without IRQF_ONESHOT"
-coccilib.report.print_report(p[0],msg)
diff --git a/external/coccinelle/misc/memcpy-assign.cocci b/external/coccinelle/misc/memcpy-assign.cocci
deleted file mode 100644
index afd058b..0000000
--- a/external/coccinelle/misc/memcpy-assign.cocci
+++ /dev/null
@@ -1,103 +0,0 @@
-//
-// Replace memcpy with struct assignment.
-//
-// Confidence: High
-// Copyright: (C) 2012 Peter Senna Tschudin, INRIA/LIP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual report
-virtual context
-virtual org
-
- at r1 depends on !patch@
-identifier struct_name;
-struct struct_name to;
-struct struct_name from;
-struct struct_name *top;
-struct struct_name *fromp;
-position p;
-@@
-memcpy at p(\(&(to)\|top\), \(&(from)\|fromp\), \(sizeof(to)\|sizeof(from)\|sizeof(struct struct_name)\|sizeof(*top)\|sizeof(*fromp)\))
-
- at script:python depends on report@
-p << r1.p;
-@@
-coccilib.report.print_report(p[0],"Replace memcpy with struct assignment")
-
- at depends on context@
-position r1.p;
-@@
-*memcpy at p(...);
-
- at script:python depends on org@
-p << r1.p;
-@@
-cocci.print_main("Replace memcpy with struct assignment",p)
-
- at depends on patch@
-identifier struct_name;
-struct struct_name to;
-struct struct_name from;
-@@
-(
--memcpy(&(to), &(from), sizeof(to));
-+to = from;
-|
--memcpy(&(to), &(from), sizeof(from));
-+to = from;
-|
--memcpy(&(to), &(from), sizeof(struct struct_name));
-+to = from;
-)
-
- at depends on patch@
-identifier struct_name;
-struct struct_name to;
-struct struct_name *from;
-@@
-(
--memcpy(&(to), from, sizeof(to));
-+to = *from;
-|
--memcpy(&(to), from, sizeof(*from));
-+to = *from;
-|
--memcpy(&(to), from, sizeof(struct struct_name));
-+to = *from;
-)
-
- at depends on patch@
-identifier struct_name;
-struct struct_name *to;
-struct struct_name from;
-@@
-(
--memcpy(to, &(from), sizeof(*to));
-+ *to = from;
-|
--memcpy(to, &(from), sizeof(from));
-+ *to = from;
-|
--memcpy(to, &(from), sizeof(struct struct_name));
-+ *to = from;
-)
-
- at depends on patch@
-identifier struct_name;
-struct struct_name *to;
-struct struct_name *from;
-@@
-(
--memcpy(to, from, sizeof(*to));
-+ *to = *from;
-|
--memcpy(to, from, sizeof(*from));
-+ *to = *from;
-|
--memcpy(to, from, sizeof(struct struct_name));
-+ *to = *from;
-)
-
diff --git a/external/coccinelle/misc/noderef.cocci b/external/coccinelle/misc/noderef.cocci
deleted file mode 100644
index 80a831c..0000000
--- a/external/coccinelle/misc/noderef.cocci
+++ /dev/null
@@ -1,65 +0,0 @@
-/// sizeof when applied to a pointer typed expression gives the size of
-/// the pointer
-///
-// Confidence: High
-// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual org
-virtual report
-virtual context
-virtual patch
-
- at depends on patch@
-expression *x;
-expression f;
-type T;
-@@
-
-(
-x = <+... sizeof(
-- x
-+ *x
-   ) ...+>
-|
-f(...,(T)(x),...,sizeof(
-- x
-+ *x
-   ),...)
-|
-f(...,sizeof(x),...,(T)(
-- x
-+ *x
-   ),...)
-)
-
- at r depends on !patch@
-expression *x;
-expression f;
-position p;
-type T;
-@@
-
-(
-*x = <+... sizeof at p(x) ...+>
-|
-*f(...,(T)(x),...,sizeof at p(x),...)
-|
-*f(...,sizeof at p(x),...,(T)(x),...)
-)
-
- at script:python depends on org@
-p << r.p;
-@@
-
-cocci.print_main("application of sizeof to pointer",p)
-
- at script:python depends on report@
-p << r.p;
-@@
-
-msg = "ERROR: application of sizeof to pointer"
-coccilib.report.print_report(p[0],msg)
diff --git a/external/coccinelle/misc/orplus.cocci b/external/coccinelle/misc/orplus.cocci
deleted file mode 100644
index 81fabf3..0000000
--- a/external/coccinelle/misc/orplus.cocci
+++ /dev/null
@@ -1,55 +0,0 @@
-/// Check for constants that are added but are used elsewhere as bitmasks
-/// The results should be checked manually to ensure that the nonzero
-/// bits in the two constants are actually disjoint.
-///
-// Confidence: Moderate
-// Copyright: (C) 2013 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2013 Gilles Muller, INRIA/LIP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual org
-virtual report
-virtual context
-
- at r@
-constant c;
-identifier i;
-expression e;
-@@
-
-(
-e | c at i
-|
-e & c at i
-|
-e |= c at i
-|
-e &= c at i
-)
-
- at s@
-constant r.c,c1;
-identifier i1;
-position p;
-@@
-
-(
- c1 + c - 1
-|
-*c1 at i1 + at p c
-)
-
- at script:python depends on org@
-p << s.p;
-@@
-
-cocci.print_main("sum of probable bitmasks, consider |",p)
-
- at script:python depends on report@
-p << s.p;
-@@
-
-msg = "WARNING: sum of probable bitmasks, consider |"
-coccilib.report.print_report(p[0],msg)
diff --git a/external/coccinelle/misc/semicolon.cocci b/external/coccinelle/misc/semicolon.cocci
deleted file mode 100644
index a47eba2..0000000
--- a/external/coccinelle/misc/semicolon.cocci
+++ /dev/null
@@ -1,83 +0,0 @@
-///
-/// Removes unneeded semicolon.
-///
-// Confidence: Moderate
-// Copyright: (C) 2012 Peter Senna Tschudin, INRIA/LIP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments: Some false positives on empty default cases in switch statements.
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual report
-virtual context
-virtual org
-
- at r_default@
-position p;
-@@
-switch (...)
-{
-default: ...;@p
-}
-
- at r_case@
-position p;
-@@
-(
-switch (...)
-{
-case ...:;@p
-}
-|
-switch (...)
-{
-case ...:...
-case ...:;@p
-}
-|
-switch (...)
-{
-case ...:...
-case ...:
-case ...:;@p
-}
-)
-
- at r1@
-statement S;
-position p1;
-position p != {r_default.p, r_case.p};
-identifier label;
-@@
-(
-label:;
-|
-S at p1;@p
-)
-
- at script:python@
-p << r1.p;
-p1 << r1.p1;
-@@
-if p[0].line != p1[0].line_end:
-	cocci.include_match(False)
-
- at depends on patch@
-position r1.p;
-@@
--;@p
-
- at script:python depends on report@
-p << r1.p;
-@@
-coccilib.report.print_report(p[0],"Unneeded semicolon")
-
- at depends on context@
-position r1.p;
-@@
-*;@p
-
- at script:python depends on org@
-p << r1.p;
-@@
-cocci.print_main("Unneeded semicolon",p)
diff --git a/external/coccinelle/misc/warn.cocci b/external/coccinelle/misc/warn.cocci
deleted file mode 100644
index d2e5b6c..0000000
--- a/external/coccinelle/misc/warn.cocci
+++ /dev/null
@@ -1,109 +0,0 @@
-/// Use WARN(1,...) rather than printk followed by WARN_ON(1)
-///
-// Confidence: High
-// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual context
-virtual org
-virtual report
-
- at bad1@
-position p;
-@@
-
-printk(...);
-printk at p(...);
-WARN_ON(1);
-
- at r1 depends on context || report || org@
-position p != bad1.p;
-@@
-
- printk at p(...);
-*WARN_ON(1);
-
- at script:python depends on org@
-p << r1.p;
-@@
-
-cocci.print_main("printk + WARN_ON can be just WARN",p)
-
- at script:python depends on report@
-p << r1.p;
-@@
-
-msg = "SUGGESTION: printk + WARN_ON can be just WARN"
-coccilib.report.print_report(p[0],msg)
-
- at ok1 depends on patch@
-expression list es;
-position p != bad1.p;
-@@
-
--printk at p(
-+WARN(1,
-  es);
--WARN_ON(1);
-
- at depends on patch@
-expression list ok1.es;
-@@
-
-if (...)
-- {
-  WARN(1,es);
-- }
-
-// --------------------------------------------------------------------
-
- at bad2@
-position p;
-@@
-
-printk(...);
-printk at p(...);
-WARN_ON_ONCE(1);
-
- at r2 depends on context || report || org@
-position p != bad1.p;
-@@
-
- printk at p(...);
-*WARN_ON_ONCE(1);
-
- at script:python depends on org@
-p << r2.p;
-@@
-
-cocci.print_main("printk + WARN_ON_ONCE can be just WARN_ONCE",p)
-
- at script:python depends on report@
-p << r2.p;
-@@
-
-msg = "SUGGESTION: printk + WARN_ON_ONCE can be just WARN_ONCE"
-coccilib.report.print_report(p[0],msg)
-
- at ok2 depends on patch@
-expression list es;
-position p != bad2.p;
-@@
-
--printk at p(
-+WARN_ONCE(1,
-  es);
--WARN_ON_ONCE(1);
-
- at depends on patch@
-expression list ok2.es;
-@@
-
-if (...)
-- {
-  WARN_ONCE(1,es);
-- }
diff --git a/external/coccinelle/null/badzero.cocci b/external/coccinelle/null/badzero.cocci
deleted file mode 100644
index d79baf7..0000000
--- a/external/coccinelle/null/badzero.cocci
+++ /dev/null
@@ -1,237 +0,0 @@
-/// Compare pointer-typed values to NULL rather than 0
-///
-//# This makes an effort to choose between !x and x == NULL.  !x is used
-//# if it has previously been used with the function used to initialize x.
-//# This relies on type information.  More type information can be obtained
-//# using the option -all_includes and the option -I to specify an
-//# include path.
-//
-// Confidence: High
-// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options:
-
-virtual patch
-virtual context
-virtual org
-virtual report
-
- at initialize:ocaml@
-let negtable = Hashtbl.create 101
-
- at depends on patch@
-expression *E;
-identifier f;
-@@
-
-(
-  (E = f(...)) ==
-- 0
-+ NULL
-|
-  (E = f(...)) !=
-- 0
-+ NULL
-|
-- 0
-+ NULL
-  == (E = f(...))
-|
-- 0
-+ NULL
-  != (E = f(...))
-)
-
-
- at t1 depends on !patch@
-expression *E;
-identifier f;
-position p;
-@@
-
-(
-  (E = f(...)) ==
-* 0 at p
-|
-  (E = f(...)) !=
-* 0 at p
-|
-* 0 at p
-  == (E = f(...))
-|
-* 0 at p
-  != (E = f(...))
-)
-
- at script:python depends on org@
-p << t1.p;
-@@
-
-coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
-
- at script:python depends on report@
-p << t1.p;
-@@
-
-coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
-
-// Tests of returned values
-
- at s@
-identifier f;
-expression E,E1;
-@@
-
- E = f(...)
- ... when != E = E1
- !E
-
- at script:ocaml depends on s@
-f << s.f;
-@@
-
-try let _ = Hashtbl.find negtable f in ()
-with Not_found -> Hashtbl.add negtable f ()
-
-@ r disable is_zero,isnt_zero exists @
-expression *E;
-identifier f;
-@@
-
-E = f(...)
-...
-(E == 0
-|E != 0
-|0 == E
-|0 != E
-)
-
- at script:ocaml@
-f << r.f;
-@@
-
-try let _ = Hashtbl.find negtable f in ()
-with Not_found -> include_match false
-
-// This rule may lead to inconsistent path problems, if E is defined in two
-// places
-@ depends on patch disable is_zero,isnt_zero @
-expression *E;
-expression E1;
-identifier r.f;
-@@
-
-E = f(...)
-<...
-(
-- E == 0
-+ !E
-|
-- E != 0
-+ E
-|
-- 0 == E
-+ !E
-|
-- 0 != E
-+ E
-)
-...>
-?E = E1
-
- at t2 depends on !patch disable is_zero,isnt_zero @
-expression *E;
-expression E1;
-identifier r.f;
-position p1;
-position p2;
-@@
-
-E = f(...)
-<...
-(
-* E == 0 at p1
-|
-* E != 0 at p2
-|
-* 0 at p1 == E
-|
-* 0 at p1 != E
-)
-...>
-?E = E1
-
- at script:python depends on org@
-p << t2.p1;
-@@
-
-coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0, suggest !E")
-
- at script:python depends on org@
-p << t2.p2;
-@@
-
-coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
-
- at script:python depends on report@
-p << t2.p1;
-@@
-
-coccilib.report.print_report(p[0], "WARNING comparing pointer to 0, suggest !E")
-
- at script:python depends on report@
-p << t2.p2;
-@@
-
-coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
-
-@ depends on patch disable is_zero,isnt_zero @
-expression *E;
-@@
-
-(
-  E ==
-- 0
-+ NULL
-|
-  E !=
-- 0
-+ NULL
-|
-- 0
-+ NULL
-  == E
-|
-- 0
-+ NULL
-  != E
-)
-
-@ t3 depends on !patch disable is_zero,isnt_zero @
-expression *E;
-position p;
-@@
-
-(
-* E == 0 at p
-|
-* E != 0 at p
-|
-* 0 at p == E
-|
-* 0 at p != E
-)
-
- at script:python depends on org@
-p << t3.p;
-@@
-
-coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
-
- at script:python depends on report@
-p << t3.p;
-@@
-
-coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
diff --git a/external/coccinelle/null/deref_null.cocci b/external/coccinelle/null/deref_null.cocci
deleted file mode 100644
index cdac6cf..0000000
--- a/external/coccinelle/null/deref_null.cocci
+++ /dev/null
@@ -1,282 +0,0 @@
-///
-/// A variable is dereference under a NULL test.
-/// Even though it is know to be NULL.
-///
-// Confidence: Moderate
-// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
-// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
-// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments: -I ... -all_includes can give more complete results
-// Options:
-
-virtual context
-virtual org
-virtual report
-
- at ifm@
-expression *E;
-statement S1,S2;
-position p1;
-@@
-
-if at p1 ((E == NULL && ...) || ...) S1 else S2
-
-// The following two rules are separate, because both can match a single
-// expression in different ways
- at pr1 expression@
-expression *ifm.E;
-identifier f;
-position p1;
-@@
-
- (E != NULL && ...) ? <+...E->f at p1...+> : ...
-
- at pr2 expression@
-expression *ifm.E;
-identifier f;
-position p2;
-@@
-
-(
-  (E != NULL) && ... && <+...E->f at p2...+>
-|
-  (E == NULL) || ... || <+...E->f at p2...+>
-|
- sizeof(<+...E->f at p2...+>)
-)
-
-// For org and report modes
-
- at r depends on !context && (org || report) exists@
-expression subE <= ifm.E;
-expression *ifm.E;
-expression E1,E2;
-identifier f;
-statement S1,S2,S3,S4;
-iterator iter;
-position p!={pr1.p1,pr2.p2};
-position ifm.p1;
-@@
-
-if at p1 ((E == NULL && ...) || ...)
-{
-  ... when != if (...) S1 else S2
-(
- iter(subE,...) S4 // no use
-|
- list_remove_head(E2,subE,...)
-|
- subE = E1
-|
- for(subE = E1;...;...) S4
-|
- subE++
-|
- ++subE
-|
- --subE
-|
- subE--
-|
- &subE
-|
- E->f at p // bad use
-)
-  ... when any
-  return ...;
-}
-else S3
-
- at script:python depends on !context && !org && report@
-p << r.p;
-p1 << ifm.p1;
-x << ifm.E;
-@@
-
-msg="ERROR: %s is NULL but dereferenced." % (x)
-coccilib.report.print_report(p[0], msg)
-cocci.include_match(False)
-
- at script:python depends on !context && org && !report@
-p << r.p;
-p1 << ifm.p1;
-x << ifm.E;
-@@
-
-msg="ERROR: %s is NULL but dereferenced." % (x)
-msg_safe=msg.replace("[","@(").replace("]",")")
-cocci.print_main(msg_safe,p)
-cocci.include_match(False)
-
- at s depends on !context && (org || report) exists@
-expression subE <= ifm.E;
-expression *ifm.E;
-expression E1,E2;
-identifier f;
-statement S1,S2,S3,S4;
-iterator iter;
-position p!={pr1.p1,pr2.p2};
-position ifm.p1;
-@@
-
-if at p1 ((E == NULL && ...) || ...)
-{
-  ... when != if (...) S1 else S2
-(
- iter(subE,...) S4 // no use
-|
- list_remove_head(E2,subE,...)
-|
- subE = E1
-|
- for(subE = E1;...;...) S4
-|
- subE++
-|
- ++subE
-|
- --subE
-|
- subE--
-|
- &subE
-|
- E->f at p // bad use
-)
-  ... when any
-}
-else S3
-
- at script:python depends on !context && !org && report@
-p << s.p;
-p1 << ifm.p1;
-x << ifm.E;
-@@
-
-msg="ERROR: %s is NULL but dereferenced." % (x)
-coccilib.report.print_report(p[0], msg)
-
- at script:python depends on !context && org && !report@
-p << s.p;
-p1 << ifm.p1;
-x << ifm.E;
-@@
-
-msg="ERROR: %s is NULL but dereferenced." % (x)
-msg_safe=msg.replace("[","@(").replace("]",")")
-cocci.print_main(msg_safe,p)
-
-// For context mode
-
- at depends on context && !org && !report exists@
-expression subE <= ifm.E;
-expression *ifm.E;
-expression E1,E2;
-identifier f;
-statement S1,S2,S3,S4;
-iterator iter;
-position p!={pr1.p1,pr2.p2};
-position ifm.p1;
-@@
-
-if at p1 ((E == NULL && ...) || ...)
-{
-  ... when != if (...) S1 else S2
-(
- iter(subE,...) S4 // no use
-|
- list_remove_head(E2,subE,...)
-|
- subE = E1
-|
- for(subE = E1;...;...) S4
-|
- subE++
-|
- ++subE
-|
- --subE
-|
- subE--
-|
- &subE
-|
-* E->f at p // bad use
-)
-  ... when any
-  return ...;
-}
-else S3
-
-// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
-// It is need because the previous rule as already made a "change".
-
- at ifm1@
-expression *E;
-statement S1,S2;
-position p1;
-@@
-
-if at p1 ((E == NULL && ...) || ...) S1 else S2
-
- at pr11 expression@
-expression *ifm1.E;
-identifier f;
-position p1;
-@@
-
- (E != NULL && ...) ? <+...E->f at p1...+> : ...
-
- at pr12 expression@
-expression *ifm1.E;
-identifier f;
-position p2;
-@@
-
-(
-  (E != NULL) && ... && <+...E->f at p2...+>
-|
-  (E == NULL) || ... || <+...E->f at p2...+>
-|
- sizeof(<+...E->f at p2...+>)
-)
-
- at depends on context && !org && !report exists@
-expression subE <= ifm1.E;
-expression *ifm1.E;
-expression E1,E2;
-identifier f;
-statement S1,S2,S3,S4;
-iterator iter;
-position p!={pr11.p1,pr12.p2};
-position ifm1.p1;
-@@
-
-if at p1 ((E == NULL && ...) || ...)
-{
-  ... when != if (...) S1 else S2
-(
- iter(subE,...) S4 // no use
-|
- list_remove_head(E2,subE,...)
-|
- subE = E1
-|
- for(subE = E1;...;...) S4
-|
- subE++
-|
- ++subE
-|
- --subE
-|
- subE--
-|
- &subE
-|
-* E->f at p // bad use
-)
-  ... when any
-}
-else S3
diff --git a/external/coccinelle/null/eno.cocci b/external/coccinelle/null/eno.cocci
deleted file mode 100644
index 9bd29aa..0000000
--- a/external/coccinelle/null/eno.cocci
+++ /dev/null
@@ -1,48 +0,0 @@
-/// The various basic memory allocation functions don't return ERR_PTR
-///
-// Confidence: High
-// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
-// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual context
-virtual org
-virtual report
-
- at depends on patch@
-expression x,E;
-@@
-
-x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...)
-... when != x = E
-- IS_ERR(x)
-+ !x
-
- at r depends on !patch exists@
-expression x,E;
-position p1,p2;
-@@
-
-*x = \(kmalloc at p1\|kzalloc at p1\|kcalloc at p1\|kmem_cache_alloc at p1\|kmem_cache_zalloc at p1\|kmem_cache_alloc_node at p1\|kmalloc_node at p1\|kzalloc_node at p1\)(...)
-... when != x = E
-* IS_ERR at p2(x)
-
- at script:python depends on org@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-cocci.print_main("alloc call",p1)
-cocci.print_secs("IS_ERR that should be NULL tests",p2)
-
- at script:python depends on report@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-msg = "ERROR: allocation function on line %s returns NULL not ERR_PTR on failure" % (p1[0].line)
-coccilib.report.print_report(p2[0], msg)
diff --git a/external/coccinelle/null/kmerr.cocci b/external/coccinelle/null/kmerr.cocci
deleted file mode 100644
index 5354a79..0000000
--- a/external/coccinelle/null/kmerr.cocci
+++ /dev/null
@@ -1,72 +0,0 @@
-/// This semantic patch looks for kmalloc etc that are not followed by a
-/// NULL check.  It only gives a report in the case where there is some
-/// error handling code later in the function, which may be helpful
-/// in determining what the error handling code for the call to kmalloc etc
-/// should be.
-///
-// Confidence: High
-// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
-// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
-// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual context
-virtual org
-virtual report
-
- at withtest@
-expression x;
-position p;
-identifier f,fld;
-@@
-
-x at p = f(...);
-... when != x->fld
-\(x == NULL \| x != NULL\)
-
- at fixed depends on context && !org && !report@
-expression x,x1;
-position p1 != withtest.p;
-statement S;
-position any withtest.p;
-identifier f;
-@@
-
-*x at p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
-...
-*x1 at p = f(...);
-if (!x1) S
-
-// ------------------------------------------------------------------------
-
- at rfixed depends on (org || report) && !context exists@
-expression x,x1;
-position p1 != withtest.p;
-position p2;
-statement S;
-position any withtest.p;
-identifier f;
-@@
-
-x at p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
-...
-x1 at p = f at p2(...);
-if (!x1) S
-
- at script:python depends on org@
-p1 << rfixed.p1;
-p2 << rfixed.p2;
-@@
-
-cocci.print_main("alloc call",p1)
-cocci.print_secs("possible model",p2)
-
- at script:python depends on report@
-p1 << rfixed.p1;
-p2 << rfixed.p2;
-@@
-
-msg = "alloc with no test, possible model on line %s" % (p2[0].line)
-coccilib.report.print_report(p1[0],msg)
diff --git a/external/coccinelle/tests/doublebitand.cocci b/external/coccinelle/tests/doublebitand.cocci
deleted file mode 100644
index 72f1572..0000000
--- a/external/coccinelle/tests/doublebitand.cocci
+++ /dev/null
@@ -1,54 +0,0 @@
-/// Find bit operations that include the same argument more than once
-//# One source of false positives is when the argument performs a side
-//# effect.  Another source of false positives is when a neutral value
-//# such as 0 for | is used to indicate no information, to maintain the
-//# same structure as other similar expressions
-///
-// Confidence: Moderate
-// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
-// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
-// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual context
-virtual org
-virtual report
-
- at r expression@
-expression E;
-position p;
-@@
-
-(
-*        E at p
-         & ... & E
-|
-*        E at p
-         | ... | E
-|
-*        E at p
-         & ... & !E
-|
-*        E at p
-         | ... | !E
-|
-*        !E at p
-         & ... & E
-|
-*        !E at p
-         | ... | E
-)
-
- at script:python depends on org@
-p << r.p;
-@@
-
-cocci.print_main("duplicated argument to & or |",p)
-
- at script:python depends on report@
-p << r.p;
-@@
-
-coccilib.report.print_report(p[0],"duplicated argument to & or |")
diff --git a/external/coccinelle/tests/doubletest.cocci b/external/coccinelle/tests/doubletest.cocci
deleted file mode 100644
index 78d74c2..0000000
--- a/external/coccinelle/tests/doubletest.cocci
+++ /dev/null
@@ -1,40 +0,0 @@
-/// Find &&/|| operations that include the same argument more than once
-//# A common source of false positives is when the argument performs a side
-//# effect.
-///
-// Confidence: Moderate
-// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
-// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
-// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual context
-virtual org
-virtual report
-
- at r expression@
-expression E;
-position p;
-@@
-
-(
-* E at p
-  || ... || E
-|
-* E at p
-  && ... && E
-)
-
- at script:python depends on org@
-p << r.p;
-@@
-
-cocci.print_main("duplicated argument to && or ||",p)
-
- at script:python depends on report@
-p << r.p;
-@@
-
-coccilib.report.print_report(p[0],"duplicated argument to && or ||")
diff --git a/external/coccinelle/tests/odd_ptr_err.cocci b/external/coccinelle/tests/odd_ptr_err.cocci
deleted file mode 100644
index cfe0a35..0000000
--- a/external/coccinelle/tests/odd_ptr_err.cocci
+++ /dev/null
@@ -1,65 +0,0 @@
-/// PTR_ERR should access the value just tested by IS_ERR
-//# There can be false positives in the patch case, where it is the call
-//# IS_ERR that is wrong.
-///
-// Confidence: High
-// Copyright: (C) 2012 Julia Lawall, INRIA.  GPLv2.
-// Copyright: (C) 2012 Gilles Muller, INRIA.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual context
-virtual org
-virtual report
-
- at depends on patch@
-expression e,e1;
-@@
-
-(
-if (IS_ERR(e)) { ... PTR_ERR(e) ... }
-|
-if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... }
-|
-if (IS_ERR(e))
- { ...
-  PTR_ERR(
--   e1
-+   e
-  )
-   ... }
-)
-
- at r depends on !patch@
-expression e,e1;
-position p1,p2;
-@@
-
-(
-if (IS_ERR(e)) { ... PTR_ERR(e) ... }
-|
-if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... }
-|
-*if (IS_ERR at p1(e))
- { ...
-*  PTR_ERR at p2(e1)
-   ... }
-)
-
- at script:python depends on org@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-cocci.print_main("inconsistent IS_ERR and PTR_ERR",p1)
-cocci.print_secs("PTR_ERR",p2)
-
- at script:python depends on report@
-p1 << r.p1;
-p2 << r.p2;
-@@
-
-msg = "inconsistent IS_ERR and PTR_ERR, PTR_ERR on line %s" % (p2[0].line)
-coccilib.report.print_report(p1[0],msg)
diff --git a/external/libshell/COPYING b/external/libshell/COPYING
deleted file mode 100644
index 462758f..0000000
--- a/external/libshell/COPYING
+++ /dev/null
@@ -1,26 +0,0 @@
-The file
-	shell-getopt
-Version 1.2 2008 by Alexey Gladkov <legion at altlinux.org>,
-            2008 by Dmitry V. Levin <ldv at altlinux.org>
-Version 1.1 2004 by Raphael <raphael at oninet dot pt>
-Version 1.0 1997 by Grigoriy Strokin (grg at philol.msu.ru), Public Domain
-
-The files
-	shell-quote, shell-args
-are Copyright (C) 2007  Dmitry V. Levin <ldv at altlinux.org>,
-                  2008  Alexey Gladkov <legion at altlinux.org>
-
-The file
-	shell-ini-config
-are Copyright (C) 2008  Stanislav Ievlev <inger at altlinux.org>,
-                  2008  Alexey Gladkov <legion at altlinux.org>
-
-The files
-	shell-version, shell-cmdline, shell-config, shell-error,
-	shell-ip-address, shell-mail-address, shell-unittest,
-	shell-signal, shell-var, shell-source shell-run
-are Copyright (C) 2009-2011  Alexey Gladkov <legion at altlinux.org>
-
-All files in this package may be freely copied under the terms
-of the GNU General Public License (GPL), version 2, or at your
-option any later version.
diff --git a/external/libshell/LICENSE b/external/libshell/LICENSE
deleted file mode 100644
index f90922e..0000000
--- a/external/libshell/LICENSE
+++ /dev/null
@@ -1,340 +0,0 @@
-		    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/external/libshell/Makefile b/external/libshell/Makefile
deleted file mode 100644
index 43633b3..0000000
--- a/external/libshell/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-DESTDIR =
-datadir = /usr/share
-man3dir = ${datadir}/man/man3
-bindir = /bin
-
-bin_TARGETS = shell-args shell-cmdline shell-config shell-error shell-getopt \
-	shell-ini-config shell-ip-address shell-mail-address shell-quote \
-	shell-regexp shell-signal shell-unittest shell-version shell-var \
-	shell-source shell-string shell-run
-
-data_TARGETS = COPYING SYMS
-
-man_TARGETS = docs/libshell.man docs/shell-error.man
-
-install: install-bin install-man
-
-install-bin: ${bin_TARGETS}
-	install -d -m755 ${DESTDIR}${bindir}
-	cp -a $^ ${DESTDIR}${bindir}/
-
-install-man: ${man_TARGETS}
-	install -d -m755 ${DESTDIR}${man3dir}
-	for i in $^; do \
-		d="$${i%.man}.3"; d="$${d##*/}"; \
-		install -m644 $$i ${DESTDIR}${man3dir}/$$d; \
-	done
-
-check:
-	@cd tests; ./runtests
diff --git a/external/libshell/SYMS b/external/libshell/SYMS
deleted file mode 100644
index caff134..0000000
--- a/external/libshell/SYMS
+++ /dev/null
@@ -1,66 +0,0 @@
-shell-args	opt_check_dir
-shell-args	opt_check_number
-shell-args	opt_check_read
-shell-args	parse_common_option
-shell-args	print_version
-shell-args	show_help
-shell-args	show_usage
-shell-cmdline	cmdline_foreach
-shell-cmdline	cmdline_get
-shell-config	shell_config_comment
-shell-config	shell_config_del
-shell-config	shell_config_get
-shell-config	shell_config_set
-shell-error	fatal
-shell-error	message
-shell-error	verbose
-shell-getopt	getopt
-shell-getopt	getoptex
-shell-getopt	getopts
-shell-getopt	getsubopt
-shell-ini-config	ini_config_comment
-shell-ini-config	ini_config_del
-shell-ini-config	ini_config_get
-shell-ini-config	ini_config_set
-shell-ip-address	ipv4_ip_subnet
-shell-ip-address	ipv4_mask2prefix
-shell-ip-address	ipv4_prefix2mask
-shell-ip-address	valid_ipv4
-shell-mail-address	valid_email
-shell-quote	quote_sed_regexp
-shell-quote	quote_sed_regexp_variable
-shell-quote	quote_shell
-shell-quote	quote_shell_args
-shell-quote	quote_shell_variable
-shell-quote	string_quote_remove
-shell-run	run_if_executable
-shell-run	run_scripts
-shell-signal	set_cleanup_handler
-shell-signal	signal_handler
-shell-signal	unset_cleanup_handler
-shell-source	source_if_executable
-shell-source	source_if_exists
-shell-source	source_if_notempty
-shell-string	fill_mask
-shell-unittest	appendTests
-shell-unittest	assertEquals
-shell-unittest	assertFalse
-shell-unittest	assertNotEquals
-shell-unittest	assertNotNull
-shell-unittest	assertNotSame
-shell-unittest	assertNull
-shell-unittest	assertSame
-shell-unittest	assertTrue
-shell-unittest	messageTest
-shell-unittest	registerTests
-shell-unittest	runUnitTests
-shell-unittest	setUp
-shell-unittest	setUpTests
-shell-unittest	shouldSkip
-shell-unittest	showSummary
-shell-unittest	tearDown
-shell-unittest	tearDownTests
-shell-var	shell_var_is_no
-shell-var	shell_var_is_yes
-shell-var	shell_var_trim
-shell-var	shell_var_unquote
diff --git a/external/libshell/contrib/getoptx_1.0.bash b/external/libshell/contrib/getoptx_1.0.bash
deleted file mode 100644
index d402c7d..0000000
--- a/external/libshell/contrib/getoptx_1.0.bash
+++ /dev/null
@@ -1,301 +0,0 @@
-#From: "Grigoriy Strokin" <grg at philol.msu.ru>
-#Newsgroups: comp.unix.shell
-#Subject: BASH: getopt function that parses long-named options
-#Date: Mon, 22 Dec 1997 20:35:18 +0300
-
-#Hi, I have written a BASH function named getoptex, that is like bash builtin
-#"getopts", but does parse long-named options and optional arguments. It only
-#uses builtin bash commands, so it is very fast.  In order to use it in your
-#bash scripts, include a command ". getopt.sh" (<dot> getopt.sh) to the file
-#containing your script, and that will define functions getopt, getoptex, and
-#optlistex (the file getopt.sh with its detailed description is listed
-#below).
-
-#*** file getopt.sh ***
-
-#! /bin/bash
-#
-# getopt.sh:
-# functions like getopts but do long-named options parsing
-# and support optional arguments
-#
-# Version 1.0 1997 by Grigoriy Strokin (grg at philol.msu.ru), Public Domain
-# Date created:  December 21, 1997
-# Date modified: December 21, 1997
-#
-# IMPORTANT FEATURES
-#
-# 1) Parses both short and long-named options
-# 2) Supports optional arguments
-# 3) Only uses bash builtins, thus no calls to external
-#    utilities such as expr or sed is done. Therefore,
-#    parsing speed is high enough
-#
-#
-# DESCRIPTION
-#
-# FUNCTION getopt
-# Usage: getopt OPTLIST {"$@"|ALTERNATIVE_PARAMETERS}
-#
-# like getopts, but parse options with both required and optional arguments,
-# Options with optional arguments must have "." instead of ":" after them.
-# Furthemore, a variable name to place option name cannot be specified
-# and is always placed in OPTOPT variable
-#
-# This function is provided for compatibility with getopts()
-# OPTLIST style, and it actually calls getoptex (see bellow)
-#
-# NOTE that a list of parameters is required and must be either "$@",
-# if processing command line arguments, or some alternative parameters.
-#
-# FUNCTION getoptex
-# Usage: getoptex OPTION_LIST {"$@"|ALTERNATIVE_PARAMETERS}
-#
-# like getopts, but parse long-named options.
-#
-# Both getopt and getoptex return 0 if an option has been parsed,
-# and 1 if all options are already parsed or an error occured
-#
-# Both getopt and getoptex set or test the following variables:
-#
-# OPTERR -- tested for whether error messages must be given for invalid
-options
-#
-# OPTOPT -- set to the name of an option parsed,
-#           or to "?" if no more options or error
-# OPTARG -- set to the option argument, if any;
-#           unset if ther is no argument;
-#           on error, set to the erroneous option name
-#
-# OPTIND -- Initialized to 1.
-#           Then set to the number of the next parameter to be parsed
-#           when getopt or getoptex will be called next time.
-#           When all options are parsed, contains a number of
-#           the first non-option argument.
-#
-#
-# OPTOFS -- If a parameter number $OPTIND containg an option parsed
-#           does not contain any more options, OPTOFS is unset;
-#           otherwise, OPTOFS is set to such a number of "?" signs
-#           which is equal to the number of options parsed
-#
-#           You might not set variables OPTIND and OPTOFS yourself
-#           unless you want to parse a list of parameters more than once.
-#           Otherwise, you whould unset OPTIND (or set it to 1)
-#           and unset OPTOFS each time you want to parse a new parameters
-list
-#
-# Option list format is DIFFERENT from one for getopts or getopt.
-getopts-style
-# option list can be converted to getoptex-style using a function optlistex
-# (see bellow)
-#
-# DESCRIPTION of option list used with getoptex:
-# Option names are separated by whitespace. Options consiting of
-# more than one character are treated as long-named (--option)
-#
-# Special characters can appear at the and of option names specifying
-# whether an argument is required (default is ";"):
-# ";" (default) -- no argument
-# ":" -- required argument
-# "," -- optional argument
-#
-# For example, an option list "a b c help version f: file: separator."
-# defines the following options:
-#    -a, -b, -c, --help, --version -- no argument
-#    -f, --file -- argument required
-#    --separator -- optional argument
-#
-# FUNCTION optlistex
-# Usage new_style_optlist=`optlistex OLD_STYLE_OPTLIST`
-#
-# Converts getopts-style option list in a format suitable for use with getoptex
-# Namely, it inserts spaces after each option name.
-#
-#
-# HOW TO USE
-#
-# In order o use in your bash scripts the functions described,
-# include a command ". getopt.sh" to the file containing the script,
-# which will define functions getopt, getoptex, and optlistex
-#
-# EXAMPLES
-#
-# See files 'getopt1' and 'getopt2' that contain sample scripts that use
-# getopt and getoptex functions respectively
-#
-#
-# Please send your comments to grg at philol.msu.ru
-
-function getoptex()
-{
-  let $# || return 1
-  local optlist="${1#;}"
-  let OPTIND || OPTIND=1
-  [ $OPTIND -lt $# ] || return 1
-  shift $OPTIND
-  if [ "$1" != "-" ] && [ "$1" != "${1#-}" ]
-  then OPTIND=$[OPTIND+1]; if [ "$1" != "--" ]
-  then
-    local o
-    o="-${1#-$OPTOFS}"
-    for opt in ${optlist#;}
-    do
-      OPTOPT="${opt%[;.:]}"
-      unset OPTARG
-      local opttype="${opt##*[^;:.]}"
-      [ -z "$opttype" ] && opttype=";"
-      if [ ${#OPTOPT} -gt 1 ]
-      then # long-named option
-        case $o in
-          "--$OPTOPT")
-            if [ "$opttype" != ":" ]; then return 0; fi
-            OPTARG="$2"
-            if [ -z "$OPTARG" ];
-            then # error: must have an agrument
-              let OPTERR && echo "$0: error: $OPTOPT must have an argument" >&2
-              OPTARG="$OPTOPT";
-              OPTOPT="?"
-              return 1;
-            fi
-            OPTIND=$[OPTIND+1] # skip option's argument
-            return 0
-          ;;
-          "--$OPTOPT="*)
-            if [ "$opttype" = ";" ];
-            then  # error: must not have arguments
-              let OPTERR && echo "$0: error: $OPTOPT must not have arguments" >&2
-              OPTARG="$OPTOPT"
-              OPTOPT="?"
-              return 1
-            fi
-            OPTARG=${o#"--$OPTOPT="}
-            return 0
-          ;;
-        esac
-      else # short-named option
-        case "$o" in
-          "-$OPTOPT")
-            unset OPTOFS
-            [ "$opttype" != ":" ] && return 0
-            OPTARG="$2"
-            if [ -z "$OPTARG" ]
-            then
-              echo "$0: error: -$OPTOPT must have an argument" >&2
-              OPTARG="$OPTOPT"
-              OPTOPT="?"
-              return 1
-            fi
-            OPTIND=$[OPTIND+1] # skip option's argument
-            return 0
-          ;;
-          "-$OPTOPT"*)
-            if [ $opttype = ";" ]
-            then # an option with no argument is in a chain of options
-              OPTOFS="$OPTOFS?" # move to the next option in the chain
-              OPTIND=$[OPTIND-1] # the chain still has other options
-              return 0
-            else
-              unset OPTOFS
-              OPTARG="${o#-$OPTOPT}"
-              return 0
-            fi
-          ;;
-        esac
-      fi
-    done
-    echo "$0: error: invalid option: $o"
-  fi; fi
-  OPTOPT="?"
-  unset OPTARG
-  return 1
-}
-function optlistex
-{
-  local l="$1"
-  local m # mask
-  local r # to store result
-  while [ ${#m} -lt $[${#l}-1] ]; do m="$m?"; done # create a "???..." mask
-  while [ -n "$l" ]
-  do
-    r="${r:+"$r "}${l%$m}" # append the first character of $l to $r
-    l="${l#?}" # cut the first charecter from $l
-    m="${m#?}"  # cut one "?" sign from m
-    if [ -n "${l%%[^:.;]*}" ]
-    then # a special character (";", ".", or ":") was found
-      r="$r${l%$m}" # append it to $r
-      l="${l#?}" # cut the special character from l
-      m="${m#?}"  # cut one more "?" sign
-    fi
-  done
-  echo $r
-}
-function getopt()
-{
-  local optlist=`optlistex "$1"`
-  shift
-  getoptex "$optlist" "$@"
-  return $?
-}
-
-#**************************************
-#     cut here
-#**************************************
-#*** (end of getopt.sh) ***
-
-
-#*** file getopt1 ***
-
-#! /bin/bash
-# getopt1:
-# Sample script using the function getopt
-#
-# Type something like "getopt1 -ab -d 10 -e20 text1 text2"
-# on the command line to see how it works
-#
-# See getopt.sh for more information
-#. getopt.sh
-#echo Using getopt to parse arguments:
-#while getopt "abcd:e." "$@"
-#do
-#  echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}"
-#done
-#shift $[OPTIND-1]
-#for arg in "$@"
-#do
-#  echo "Non option argument <$arg>"
-#done
-#
-#**************************************
-#        cut here
-#**************************************
-#*** (end of getopt1) ***
-#
-#
-#*** file getopt2 ***
-#
-#! /bin/bash
-# getopt2:
-# Sample script using the function getoptex
-#
-# Type something like "getopt2 -ab -d 10 -e20 --opt1 --opt4=100 text1 text2"
-# to see how it works
-#
-# See getopt.sh for more information
-. getopt.sh
-#echo Using getoptex to parse arguments:
-#while getoptex "a; b; c; d: e. opt1 opt2 opt3 opt4: opt5." "$@"
-#do
-#  echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}"
-#done
-#shift $[OPTIND-1]
-#for arg in "$@"
-#do
-#  echo "Non option argument <$arg>"
-#done
-#
-#**************************************
-#         cut here
-#**************************************
-#*** (end of getopt2) ***
-
diff --git a/external/libshell/contrib/getoptx_1.1.bash b/external/libshell/contrib/getoptx_1.1.bash
deleted file mode 100644
index 4e6d40e..0000000
--- a/external/libshell/contrib/getoptx_1.1.bash
+++ /dev/null
@@ -1,241 +0,0 @@
-#! /bin/bash
-#
-# getopt.sh:
-# functions like getopts but do long-named options parsing
-# and support optional arguments
-#
-# Version 1.1 2004 by Raphael <raphael at oninet dot pt>
-# Date modified: April 6, 2004
-# Version 1.0 1997 by Grigoriy Strokin (grg at philol.msu.ru), Public Domain
-# Date created: December 21, 1997
-# Date modified: December 21, 1997
-#
-# UPDATE (by raphael)
-#
-# I found the routine wouldn't report option that need arguments right
-# if they where between or before other options. Rather it would take
-# the following option as the argument. The routine now checks if
-# the required argument starts with a dash '-' indicating that it is an
-# option. See source below.
-#
-# IMPORTANT FEATURES
-#
-# 1) Parses both short and long-named options
-# 2) Supports optional arguments
-# 3) Only uses bash builtins, thus no calls to external
-# utilities such as expr or sed is done. Therefore,
-# parsing speed is high enough
-#
-#
-# DESCRIPTION
-#
-# FUNCTION getopt
-# Usage: getopt OPTLIST {"$@"|ALTERNATIVE_PARAMETERS}
-#
-# like getopts, but parse options with both required and optional arguments,
-# Options with optional arguments must have "." instead of ":" after them.
-# Furthemore, a variable name to place option name cannot be specified
-# and is always placed in OPTOPT variable
-#
-# This function is provided for compatibility with getopts()
-# OPTLIST style, and it actually calls getoptex (see bellow)
-#
-# NOTE that a list of parameters is required and must be either "$@",
-# if processing command line arguments, or some alternative parameters.
-#
-# FUNCTION getoptex
-# Usage: getoptex OPTION_LIST {"$@"|ALTERNATIVE_PARAMETERS}
-#
-# like getopts, but parse long-named options.
-#
-# Both getopt and getoptex return 0 if an option has been parsed,
-# and 1 if all options are already parsed or an error occured
-#
-# Both getopt and getoptex set or test the following variables:
-#
-# OPTERR -- tested for whether error messages must be given for invalid options
-#
-# OPTOPT -- set to the name of an option parsed,
-# or to "?" if no more options or error
-# OPTARG -- set to the option argument, if any;
-# unset if ther is no argument;
-# on error, set to the erroneous option name
-#
-# OPTIND -- Initialized to 1.
-# Then set to the number of the next parameter to be parsed
-# when getopt or getoptex will be called next time.
-# When all options are parsed, contains a number of
-# the first non-option argument.
-#
-#
-# OPTOFS -- If a parameter number $OPTIND containg an option parsed
-# does not contain any more options, OPTOFS is unset;
-# otherwise, OPTOFS is set to such a number of "?" signs
-# which is equal to the number of options parsed
-#
-# You might not set variables OPTIND and OPTOFS yourself
-# unless you want to parse a list of parameters more than once.
-# Otherwise, you whould unset OPTIND (or set it to 1)
-# and unset OPTOFS each time you want to parse a new parameters list
-#
-# Option list format is DIFFERENT from one for getopts or getopt. getopts-style
-# option list can be converted to getoptex-style using a function optlistex
-# (see bellow)
-#
-# DESCRIPTION of option list used with getoptex:
-# Option names are separated by whitespace. Options consiting of
-# more than one character are treated as long-named (--option)
-#
-# Special characters can appear at the and of option names specifying
-# whether an argument is required (default is ";"):
-# ";" (default) -- no argument
-# ":" -- required argument
-# "," -- optional argument
-#
-# For example, an option list "a b c help version f: file: separator."
-# defines the following options:
-# -a, -b, -c, --help, --version -- no argument
-# -f, --file -- argument required
-# --separator -- optional argument
-#
-# FUNCTION optlistex
-# Usage new_style_optlist=`optlistex OLD_STYLE_OPTLIST`
-#
-# Converts getopts-style option list in a format suitable for use with getoptex
-# Namely, it inserts spaces after each option name.
-#
-#
-# HOW TO USE
-#
-# In order o use in your bash scripts the functions described,
-# include a command ". getopt.sh" to the file containing the script,
-# which will define functions getopt, getoptex, and optlistex
-#
-# EXAMPLES
-#
-# See files 'getopt1' and 'getopt2' that contain sample scripts that use
-# getopt and getoptex functions respectively
-#
-#
-# Please send your comments to grg at philol.msu.ru
-
-function getoptex()
-{
-  let $# || return 1
-  local optlist="${1#;}"
-  let OPTIND || OPTIND=1
-  [ $OPTIND -lt $# ] || return 1
-  shift $OPTIND
-  if [ "$1" != "-" -a "$1" != "${1#-}" ]
-  then OPTIND=$[OPTIND+1]; if [ "$1" != "--" ]
-  then
-    local o
-    o="-${1#-$OPTOFS}"
-    for opt in ${optlist#;}
-    do
-      OPTOPT="${opt%[;.:]}"
-      unset OPTARG
-      local opttype="${opt##*[^;:.]}"
-      [ -z "$opttype" ] && opttype=";"
-      if [ ${#OPTOPT} -gt 1 ]
-      then # long-named option
-        case $o in
-          "--$OPTOPT")
-            if [ "$opttype" != ":" ]; then return 0; fi
-            OPTARG="$2"
-
-# Added test on following argument being an option identified by '-' this way #
-# the routine no longer takes options as an argument thus breaking error #
-# detection. 2004-04-04 by raphael at oninet dot pt #
-
-            if [ -z "$OPTARG" -o "${OPTARG:0:1}" = "-" ] ;
-            then # error: must have an agrument
-              let OPTERR && echo "$0: error: $OPTOPT must have an argument" >&2
-              OPTARG="$OPTOPT";
-              OPTOPT="?"
-              return 1;
-            fi
-            OPTIND=$[OPTIND+1] # skip option's argument
-            return 0
-          ;;
-          "--$OPTOPT="*)
-            if [ "$opttype" = ";" ];
-            then # error: must not have arguments
-              let OPTERR && echo "$0: error: $OPTOPT must not have arguments" >&2
-              OPTARG="$OPTOPT"
-              OPTOPT="?"
-              return 1
-            fi
-            OPTARG=${o#"--$OPTOPT="}
-            return 0
-          ;;
-        esac
-      else # short-named option
-        case "$o" in
-          "-$OPTOPT")
-            unset OPTOFS
-            [ "$opttype" != ":" ] && return 0
-            OPTARG="$2"
-
-# Added test on following argument being an option identified by '-' this way #
-# the routine no longer takes options as an argument thus breaking error #
-# detection. 2004-04-04 by raphael at oninet dot pt #
-
-            if [ -z "$OPTARG" -o "${OPTARG:0:1}" = "-" ] ;
-            then
-              echo "$0: error: -$OPTOPT must have an argument" >&2
-              OPTARG="$OPTOPT"
-              OPTOPT="?"
-              return 1
-            fi
-            OPTIND=$[OPTIND+1] # skip option's argument
-            return 0
-          ;;
-          "-$OPTOPT"*)
-            if [ $opttype = ";" ]
-            then # an option with no argument is in a chain of options
-              OPTOFS="$OPTOFS?" # move to the next option in the chain
-              OPTIND=$[OPTIND-1] # the chain still has other options
-              return 0
-            else
-              unset OPTOFS
-              OPTARG="${o#-$OPTOPT}"
-              return 0
-            fi
-          ;;
-        esac
-      fi
-    done
-    echo "$0: error: invalid option: $o"
-  fi; fi
-  OPTOPT="?"
-  unset OPTARG
-  return 1
-}
-function optlistex
-{
-  local l="$1"
-  local m # mask
-  local r # to store result
-  while [ ${#m} -lt $[${#l}-1] ]; do m="$m?"; done # create a "???..." mask
-  while [ -n "$l" ]
-  do
-    r="${r:+"$r "}${l%$m}" # append the first character of $l to $r
-    l="${l#?}" # cut the first charecter from $l
-    m="${m#?}" # cut one "?" sign from m
-    if [ -n "${l%%[^:.;]*}" ]
-    then # a special character (";", ".", or ":") was found
-      r="$r${l%$m}" # append it to $r
-      l="${l#?}" # cut the special character from l
-      m="${m#?}" # cut one more "?" sign
-    fi
-  done
-  echo $r
-}
-function getopt()
-{
-  local optlist=`optlistex "$1"`
-  shift
-  getoptex "$optlist" "$@"
-  return $?
-} 
diff --git a/external/libshell/contrib/shell-array b/external/libshell/contrib/shell-array
deleted file mode 100644
index d08693d..0000000
--- a/external/libshell/contrib/shell-array
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/bin/sh -efu
-
-if [ -z "${__included_shell_array-}" ]; then
-__included_shell_array=1
-
-if [ -n "${__libshell_experimental-}" ]; then
-
-#. shell-crc32
-
-# arr[ZZZ-zzz] = "XXX-xxx"
-#
-# ARRAY_arr_{n}_key="ZZZ-zzz"
-# ARRAY_arr_{n}_arg="XXX-xxx"
-# ARRAY_arr_{sign}={n}
-# ARRAY_arr={size}
-
-# Usage: array ARRNAME key value
-#    or: array ARRNAME key
-#    or: array ARRNAME
-array()
-{
-	local arr key arg num i
-	arr="$1"
-	[ "$#" -lt 2 ] || key="$2"
-	[ "$#" -lt 3 ] || arg="$3"
-
-	eval "num=\${ARRAY_$arr:-0}"
-	if [ "$#" -eq 1 ]; then
-		printf '%d\n' "$num"
-		return
-	fi
-
-	#shell_crc32 "sign" "$key"
-	sign="$(printf '%s' "$key" |sha1sum)"
-	sign="${sign%% *}"
-	eval "i=\"\${ARRAY_${arr}_${sign}-}\""
-
-	if [ "$#" -eq 2 ]; then
-		if [ -n "$i" ]; then
-			eval "arg=\$ARRAY_${arr}_${i}_arg"
-			printf '%s\n' "$arg"
-			return
-		fi
-		return 1
-	fi
-
-	if [ -z "$i" ]; then
-		i="$num"
-		num=$(($num+1))
-		eval "ARRAY_$arr=\$num"
-	fi
-
-	eval "ARRAY_${arr}_${i}_key=\"\$key\""
-	eval "ARRAY_${arr}_${i}_arg=\"\$arg\""
-	eval "ARRAY_${arr}_${sign}=\"\$i\""
-}
-
-# Usage: shell_array_foreach ARRNAME callback
-array_foreach()
-{
-	local arrname callback i num key arg
-	arrname="$1"; shift
-	callback="$1"; shift
-
-	eval "num=\${ARRAY_$arrname:-0}"
-	[ "$num" -gt 0 ] ||
-		return 0
-	i=0
-	while [ $i -lt $num ]; do
-		eval "key=\"\$ARRAY_${arrname}_${i}_key\""
-		eval "arg=\"\$ARRAY_${arrname}_${i}_arg\""
-		$callback "$i" "$key" "$arg"
-		i=$(($i+1))
-	done
-}
-
-array_flip()
-{
-	local arrname tmp key1 key2 num1 num2
-	arrname="$1"; shift
-	key1="$1"; shift
-	key2="$1"; shift
-
-	eval 
-}
-
-fi #__libshell_experimental
-
-fi #__included_shell_array
diff --git a/external/libshell/contrib/shell-crc32 b/external/libshell/contrib/shell-crc32
deleted file mode 100644
index 8f38e9a..0000000
--- a/external/libshell/contrib/shell-crc32
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/ash -efu
-
-# http://ru.wikipedia.org/wiki/CRC32#CRC-32
-#
-# Name  : CRC-32
-# Poly  : 0x04C11DB7    x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 
-#                       + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
-# Init  : 0xFFFFFFFF
-# Revert: true
-# XorOut: 0xFFFFFFFF
-# Check : 0xCBF43926 ("123456789")
-#
-
-__shell_crc32_table=
-__shell_crc32_init()
-{
-	[ -z "${__shell_crc32_table-}" ] ||
-		return 0;
-
-	local i=0 j crc
-
-	while [ $i -lt 256 ]; do
-		crc=$i
-		j=0
-		while [ $j -lt 8 ]; do
-			[ $(($crc & 1)) -ne 0 ] &&
-				crc=$((($crc >> 1) ^ 0xEDB88320)) ||
-				crc=$((($crc >> 1)))
-			j=$(($j+1))
-		done
-		__shell_crc32_table="$__shell_crc32_table $crc"
-		i=$(($i+1))
-	done
-}
-
-shell_crc32()
-{
-	local __shell_crc32_crc __shell_crc32_name __shell_crc32_buf
-	__shell_crc32_name="$1"; shift
-	__shell_crc32_buf="$2"; shift
-
-	__shell_crc32()
-	{
-		local c crc i=1 j
-
-		__shell_crc32_init
-		set -- ${__shell_crc32_table}
-
-		local args= mask=
-		while [ $i -lt ${#buf} ]; do
-			mask="$mask?"
-			i=$(($i+1))
-		done
-
-		while [ -n "$buf" ]; do
-			args="$args '${buf%$mask}"
-			buf=${buf#?}
-			mask=${mask#?}
-		done
-
-		crc=$((0xFFFFFFFF))
-		for c in $(printf '%d ' $args); do
-			j=$((($crc ^ $c) & 0xFF))
-			j=$(($j+1))
-			eval "crc=\$((\${$j} ^ (\$crc >> 0x00000008)))"
-		done
-		__shell_crc32_crc=$(($crc ^ 0xFFFFFFFF))
-	}
-	__shell_crc32
-	eval "$__shell_crc32_name=\"\${__shell_crc32_crc}\""
-}
-
-#shell_crc32 "" "123456789"
diff --git a/external/libshell/contrib/shell-lists b/external/libshell/contrib/shell-lists
deleted file mode 100644
index 7540808..0000000
--- a/external/libshell/contrib/shell-lists
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/bin/sh -efu
-
-if [ -z "${__included_shell_lists-}" ]; then
-__included_shell_lists=1
-
-. shell-quote
-
-shell_list_add() {
-	local __shell_list_add_var="$1"
-	shift
-	local __shell_list_add_qvalue
-	while [ "$#" -gt 0 ]; do
-		quote_shell_variable __shell_list_add_qvalue "$1"
-		eval "$__shell_list_add_var=\"\$$__shell_list_add_var \\\"\$__shell_list_add_qvalue\\\"\""
-		shift
-	done
-}
-
-shell_list_remove() {
-	local __shell_list_remove_var __shell_list_remove_value
-	__shell_list_remove_var="$1"; shift
-	__shell_list_remove_value="$1"; shift
-
-	local __shell_list_remove_qvalue __shell_list_remove_nvar=
-
-	eval "__shell_list_remove_nvar=\$$var"
-	eval "set -- $__shell_list_remove_nvar"
-	eval "__shell_list_remove_nvar=''"
-
-	while [ "$#" -gt 0 ]; do
-		if [ "$__shell_list_remove_value" != "$1" ]; then
-			quote_shell_variable __shell_list_remove_qvalue "$1"
-			eval "__shell_list_remove_nvar=\"\$__shell_list_remove_nvar \\\"\$__shell_list_remove_qvalue\\\"\""
-		fi
-		shift
-	done
-
-	eval "$__shell_list_remove_var=\"\$__shell_list_remove_nvar\""
-}
-
-shell_list_get() {
-	local __shell_list_get_var __shell_list_get_name __shell_list_get_value
-	__shell_list_get_var="$1"; shift
-	__shell_list_get_name="$1"; shift
-	__shell_list_get_value="$1"; shift
-
-	local __shell_list_get_lst=
-	eval "__shell_list_get_lst=\"\$$__shell_list_get_var\""
-	eval "set -- $__shell_list_get_lst"
-	[ "$__shell_list_get_value" -le "$#" ] ||
-		return 1
-	eval "$__shell_list_get_name=\"\${$__shell_list_get_value-}\""
-}
-
-SHELLLIST_FOREACH=1
-shell_list_foreach() {
-	local __shell_list_foreach_var __shell_list_foreach_name
-	__shell_list_foreach_var="$1"; shift
-	__shell_list_foreach_name="$1"; shift
-
-	local __shell_list_foreach_lst=
-	eval "__shell_list_foreach_lst=\"\$$__shell_list_foreach_var\""
-	eval "set -- $__shell_list_foreach_lst"
-	if [ "$SHELLLIST_FOREACH" -gt "$#" ]; then
-		SHELLLIST_FOREACH=1
-		return 1
-	fi
-	eval "$__shell_list_foreach_name=\"\$$SHELLLIST_FOREACH\""
-	SHELLLIST_FOREACH=$(( $SHELLLIST_FOREACH + 1 ))
-}
-
-fi # __included_shell_lists
diff --git a/external/libshell/contrib/shell-sort b/external/libshell/contrib/shell-sort
deleted file mode 100644
index 324bf0f..0000000
--- a/external/libshell/contrib/shell-sort
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/bin/ash -efu
-
-if [ -z "${__included_shell_sort-}" ]; then
-__included_shell_sort=1
-
-if [ -n "${__libshell_experimental-}" ]; then
-
-. ./shell-array
-
-INSERTIONSORT='__shell_compare_sort'
-QUICKSORT='__shell_compare_sort'
-HEAPSORT='__shell_compare_sort'
-__shell_compare_sort() {
-	test "$1" "$3" "$2" || return 1
-}
-
-__insertion_sort() {
-	local arr="$1" first="$2" last="$3"
-	local i j=0 key_i key_j
-
-	j=$(($first+1))
-	while [ $j -lt $last ]; do
-		array_get "$arr[$j]" key_j
-		i=$(($j-1))
-
-		while [ $i -ge $first ]; do
-			array_get "$arr[$i]" key_i
-			if array_compare "$INSERTIONSORT" "$arr[$i]" "$arr[$j]" "$order"; then
-				array_set "$arr[$(($i+1))]" "$key_i"
-				i=$(($i-1))
-			else
-				break
-			fi
-		done
-		array_set "$arr[$(($i+1))]" "$key_j"
-		j=$(($j+1))
-	done
-}
-
-# Usage: insertion_sort ARR
-insertion_sort() {
-	local order=-ge arr r
-	arr="$1"; shift
-	array_size "$arr" r
-	__insertion_sort "$arr" 0 "$r"
-}
-
-__shell_partition() {
-	local var="$1" arr="$2" p="$3" r="$4"
-	local i=$p j=$p
-
-	while [ "$j" -lt "$r" ]; do
-		if array_compare "$QUICKSORT" "$arr[$r]" "$arr[$j]" "$order"; then
-			array_swap "$arr[$i]" "$arr[$j]"
-			i=$(($i+1))
-		fi
-		j=$(($j+1))
-	done
-	array_swap "$arr[$i]" "$arr[$r]"
-	eval "$var=\"$i\""
-}
-
-__quicksort() {
-	local q arr="$1" p="$2" r="$3"
-	while [ "$p" -lt "$r" ]; do
-		__shell_partition q "$arr" "$p" "$r"
-		__quicksort "$arr" "$p" "$(($q-1))"
-		p=$(($q+1))
-	done
-}
-
-# Usage: quicksort ARR [order]
-quicksort() {
-	local order=-le arr r
-	arr="$1"; shift
-	[ "$#" -eq 0 ] || order=-ge
-
-	array_size "$arr" r
-	__quicksort "$arr" 0 "$(($r-1))"
-}
-
-heapsort() {
-	local arr siz c p i=1 order=-gt
-	arr="$1"; shift
-	[ "$#" -eq 0 ] || order=-lt
-
-	array_size "$arr" siz
-	while [ $i -lt $siz ]; do
-		c=$i
-		while [ $c -gt 0 ]; do
-			p=$(($c-1))
-			if array_compare "$HEAPSORT" "$arr[$p]" "$arr[$c]" "$order"; then
-				array_swap "$arr[$p]" "$arr[$c]"
-				c=$p
-			else
-				break
-			fi
-		done
-		i=$(($i+1))
-	done
-}
-
-fi #__libshell_experimental
-
-fi #__included_shell_sort
diff --git a/external/libshell/contrib/shell-stack b/external/libshell/contrib/shell-stack
deleted file mode 100644
index f37fbe9..0000000
--- a/external/libshell/contrib/shell-stack
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/bin/sh -efu
-
-stack_push() {
-	local name str last stack
-	name="$1"; shift
-	str="$1"; shift
-
-	eval "stack=\"\${__${name}:-}\";"
-	set $stack
-	last=$(($# + 1))
-
-	eval "__${name}=\"\${__$name:+\$__$name }${last}\";
-	      __${name}_${last}=\"\$str\";"
-}
-
-stack_pop() {
-	local name var last stack
-	name="$1"; shift
-	var="$1"; shift
-
-	eval "stack=\"\${__${name}:-}\";"
-	set $stack
-	last="$#"
-
-	if [ "$last" = 0 ]; then
-		eval "$var=''"
-		return
-	fi
-
-	eval "$var=\"\${__${name}_${last}:-}\";
-	      unset __${name}_${last};
-	      __${name}=\"\${__${name}% *}\";"
-}
-
-stack_shift() {
-	local name var last stack
-	name="$1"; shift
-	var="$1"; shift
-
-	eval "stack=\"\${__${name}:-}\";"
-	set $stack
-	last="$#"
-
-	if [ "$last" = 0 ]; then
-		eval "$var=''"
-		return
-	fi
-
-	last="${stack%% *}"
-	last="${last## }"
-
-	eval "$var=\"\${__${name}_${last}:-}\";
-	      unset __${name}_${last};
-	      __${name}=\"\${__${name}#* }\";"
-}
-
-stack_unshift() {
-	local name str last stack
-	name="$1"; shift
-	str="$1"; shift
-
-	eval "stack=\"\${__${name}:-}\";"
-	set $stack
-	last="$(($# + 1))"
-
-	eval "__${name}=\"${last}\${__$name:+ \$__$name}\";
-	      __${name}_${last}=\"\$str\";"
-}
diff --git a/external/libshell/docs/libshell.man b/external/libshell/docs/libshell.man
deleted file mode 100644
index 2bfdd70..0000000
--- a/external/libshell/docs/libshell.man
+++ /dev/null
@@ -1,115 +0,0 @@
-.\" Copyright (C) 2008  Alexey Gladkov <legion at altlinux.org>
-.\"
-.\" Additional documentation for the libshell.
-.\"
-.\" This file 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
-.
-.TH "LIBSHELL" "3" "November 2008" "libshell" "File Formats"
-.SH NAME
-libshell \- the library of shell functions
-.
-.
-.SH DESCRIPTION
-.
-The
-.B libshell
-library is a set of the most commonly-used shell functions.
-All functions use minimum of external utilities and written for POSIX-shell.
-.
-.
-.SH STRUCTURE
-.
-Library has modular structure. Each module used for own special purpose.
-Some modules use the functionality of each other and load the necessary dependence.
-.TP
-.BR shell-getopt
-Shell implementation of getopt(1) utility and getopt family;
-.TP
-.BR shell-config
-Functions to work (read, change and remove variables) with a shell-like config files;
-.TP
-.BR shell-ini-config
-Functions to work with a ini-like config files;
-.TP
-.BR shell-signal
-Functions to change the action taken by a process on receipt of a specific signal;
-.TP
-.BR shell-args
-Functions to check argument type, display version and program usage;
-.TP
-.BR shell-ip-address
-Functions to validate the IP address;
-.TP
-.BR shell-mail-address
-Functions to validate the domain and email address;
-.TP
-.BR shell-quote
-Functions to quote variables;
-.TP
-.BR shell-unittest
-Unit testing framework for shell (xUnit compatible);
-.TP
-.BR shell-error
-Functions to display error and verbose messages;
-.TP
-.BR shell-version
-Module contain libshell ABI version.
-.BR
-.
-.
-.
-.SH USING MODULES
-All
-.B libshell
-modules
-.I MUST
-be kept in the PATH and could be not executable. It really helps to include
-these modules in the shell-program:
-.RS
-.IP
-.EX
-\&#!/bin/sh
-\&. shell-error
-\&. shell-getopt
-\&
-\&# something useful ...
-.EE
-.RE
-.PP
-The
-.B bash-completion
-will not find these modules in the PATH, if they are not executable.
-.
-.
-.SH AUTHOR
-.PP
-This manual page written by
-.MT legion at altlinux.org
-Alexey Gladkov
-.ME .
-.PP
-Authors and contributors of the programs included in the
-.B libshell
-package are listed in the COPYING file.
-.
-.
-.SH SEE ALSO
-.PP
-.na
-.nh
-.tr -\(hy
-.BR sh (1),
-.BR bash (1),
-.BR dash (1).
diff --git a/external/libshell/docs/shell-error.man b/external/libshell/docs/shell-error.man
deleted file mode 100644
index b728ad9..0000000
--- a/external/libshell/docs/shell-error.man
+++ /dev/null
@@ -1,73 +0,0 @@
-.\" Copyright (C) 2008  Alexey Gladkov <legion at altlinux.org>
-.\"
-.\" Additional documentation for the libshell.
-.\"
-.\" This file 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
-.
-.TH "SHELL-ERROR" "3" "November 2008" "libshell" "File Formats"
-.SH NAME
-message, fatal, verbose \- functions to display error and verbose messages
-.
-.
-.SH SYNOPSIS
-.nf
-.B . shell-error
-.sp
-.BI "PROG=" "${0##*/}"
-.sp
-.BI "message " TEXT
-.sp
-.BI "fatal " TEXT
-.sp
-.BI "verbose= quiet="
-.sp
-.BI "verbose " TEXT
-.ad b
-.SH DESCRIPTION
-The
-.BR message ()
-function show
-.B TEXT
-message to the stderr.
-.PP
-Function
-.BR fatal ()
-is equivalent to the function message(), except that
-the script will be completed after displaying a message.
-.PP
-.BR verbose ()
-will show message if
-.B $verbose
-is set and 
-.B $quiet
-unset.
-.SH AUTHOR
-.PP
-This manual page written by
-.MT legion at altlinux.org
-Alexey Gladkov
-.ME .
-.PP
-Authors and contributors of the programs included in the
-.B libshell
-package are listed in the COPYING file.
-.
-.
-.SH SEE ALSO
-.PP
-.na
-.nh
-.tr -\(hy
-.BR libshell (3).
diff --git a/external/libshell/shell-args b/external/libshell/shell-args
deleted file mode 100644
index 9a0b9b7..0000000
--- a/external/libshell/shell-args
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_args-}" ]; then
-__included_shell_args=1
-
-. shell-error
-
-# Checks that given option value is a readable file.
-# Arguments: $1 is option name, $2 is option value.
-# If $2 is a readable file, outputs canonicalized file name,
-# otherwise fails.
-opt_check_read() {
-	local value
-	[ -r "$2" ] &&
-	value="$(readlink -ev "$2")" ||
-		fatal "$1: $2: file not available."
-	printf %s "$value"
-}
-
-# Checks that given option value is a traversable directory.
-# Arguments: $1 is option name, $2 is option value.
-# If $2 is a readable file, outputs canonicalized directory name,
-# otherwise fails.
-opt_check_dir() {
-	local value
-	[ -d "$2" -a -x "$2" ] &&
-	value="$(readlink -ev "$2")" ||
-		fatal "$1: $2: directory not available."
-	printf %s "$value"
-}
-
-# Checks that given option value is a positive decimal number.
-# Arguments: $1 is option name, $2 is option value.
-# If $2 is a positive decimal number, outputs it, otherwise fails.
-opt_check_number()
-{
-	[ -n "${2##0*}" -a -n "${2##*[!0-9]*}" ] &&
-	[ "$2" -gt 0 ] 2>/dev/null ||
-		fatal "$1: $2: invalid number."
-	printf %s "$2"
-}
-
-show_usage() {
-	[ -z "$*" ] || message "$*"
-	echo "Try \`$PROG --help' for more information." >&2
-	exit 1
-}
-
-show_help() {
-	fatal "show_help(): Undefined function"
-}
-
-print_version() {
-	fatal "print_version() Undefined function"
-}
-
-readonly getopt_common_opts="q,v,V,h"
-readonly getopt_common_longopts="quiet,verbose,version,help"
-parse_common_option() {
-	case "$1" in
-		-h|--help) show_help
-			;;
-		-q|--quiet) quiet=-q; verbose=
-			;;
-		-v|--verbose) verbose=-v; quiet=
-			;;
-		-V|--version) print_version "$PROG"
-			;;
-		*) fatal "Unrecognized option: $1"
-			;;
-	esac
-}
-
-fi #__included_shell_args
diff --git a/external/libshell/shell-cmdline b/external/libshell/shell-cmdline
deleted file mode 100644
index c10b78b..0000000
--- a/external/libshell/shell-cmdline
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_cmdline-}" ]; then
-__included_shell_cmdline=1
-
-. shell-string
-
-# Run handler for each variable in /proc/cmdline.
-#
-cmdline_foreach() {
-	local l h c= m=
-
-	l="$1"; shift
-	h="$1"; shift
-
-	__is_set() {
-		[ $(( $1 & $2 )) -eq $2 ]
-	}
-
-	fill_mask m "$l"
-
-	local state=$((0x00))
-	local VALUE=$((0x02))
-	local EQUAL=$((0x04))
-	local QUOTE=$((0x10))
-
-	local n= v=
-
-	while [ -n "$l" ]; do
-		c="${l%$m}"
-
-		case "$c" in
-			'"')
-				__is_set $state $QUOTE &&
-					state=$(($state ^ $QUOTE)) ||
-					state=$(($state | $QUOTE))
-				;;
-			' ')
-				if __is_set $state $QUOTE; then
-					v="$v$c"
-				else
-					__is_set $state $EQUAL ||
-						v=1
-					$h "$n" "$v" ||
-						break
-					n= v=
-					state=$((0x00))
-				fi
-				;;
-			'=')
-				! __is_set $state $VALUE ||
-					v="$v$c"
-				state=$(($state | $VALUE | $EQUAL))
-				;;
-			*)
-				if ! __is_set $state $VALUE; then
-					[ "$c" != '-' ] || c='_'
-					n="$n$c"
-				else
-					v="$v$c"
-				fi
-				;;
-		esac
-
-		l="${l#?}"
-		m="${m#?}"
-	done
-
-	[ -z "$n" ] ||
-		$h "$n" "$v" ||:
-
-	unset __is_set
-}
-
-# Find spicified variable in /proc/cmdline and store result into variable.
-# Usage example:
-#   read cmdline < /proc/cmdline
-#   cmdline_get 'initrd_value' 'initrd' "$cmdline"
-#   echo "$initrd_value"
-# or:
-#   cmdline_get 'initrd_value' 'initrd'
-#   echo "$initrd_value"
-#
-cmdline_get() {
-	local __cmdline __retv __getn
-
-	__retv="$1"; shift
-	__getn="$1"; shift
-	if [ "$#" -eq 0 ]; then
-		read __cmdline < /proc/cmdline
-	else
-		__cmdline="$1"
-	fi
-
-	local c m l="$__getn"
-	__getn=
-
-	fill_mask m "$l"
-	while [ -n "$l" ]; do
-		c="${l%$m}"
-		[ "$c" != '-' ] || c='_'
-		__getn="$__getn$c"
-		l="${l#?}"
-		m="${m#?}"
-	done
-	unset c m l
-
-	__getval() {
-		[ "$1" != "$__getn" ] || eval "$__retv=\"\$2\""
-	}
-	cmdline_foreach "$__cmdline" __getval
-	unset __getval
-}
-
-fi #__included_shell_cmdline
diff --git a/external/libshell/shell-config b/external/libshell/shell-config
deleted file mode 100644
index bf2cdb6..0000000
--- a/external/libshell/shell-config
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_config-}" ]; then
-__included_shell_config=1
-
-. shell-error
-. shell-quote
-
-__shell_config_comment='#'
-
-shell_config_get() {
-	[ "$#" -ge 2 -a "$#" -le 3 ] ||
-		fatal "Usage: shell_config_get file name [delim]"
-	local file="$1" name="$2" delim="${3-=}"
-
-	[ -s "$file" ] ||
-		return 0
-	quote_sed_regexp_variable name "$name"
-	sed -n -e "s/^[[:space:]]*$name$delim//p" -- "$file"
-}
-
-shell_config_set() {
-	[ "$#" -ge 3 -a "$#" -le 5 ] ||
-		fatal "Usage: shell_config_set file name value [read-delim [write-delim]]"
-
-	local file="$1" name="$2" value="$3" r_delim="${4-=}" w_delim="${5-=}"
-	local n v nv= created=
-
-	if [ ! -f "$file" ]; then
-		if [ ! -w "${file%/*}" ]; then
-			message "${file%/*}: not writable."
-			return 1
-		fi
-		touch -- "$file" ||
-			return 1
-		created=1
-	fi
-
-	if [ -z "$created" ]; then
-		quote_sed_regexp_variable n "$name"
-
-		if v="$(grep -m1 "^[[:space:]]*$n$r_delim" -- "$file" 2>/dev/null)"; then
-			if [ "${v#*$name$r_delim}" != "$value" ]; then
-				quote_sed_regexp_variable nv "$w_delim$value"
-				sed -i -e "s/^[[:space:]]*$n$r_delim.*/$n$nv/" -- "$file"
-			fi
-			return
-		fi
-
-		if [ -n "${__shell_config_comment-}" ] &&
-		   v="$(grep -m1 "^[[:space:]]*${__shell_config_comment:-#}[[:space:]]*$n$r_delim" -- "$file" 2>/dev/null)"; then
-			quote_sed_regexp_variable v "$v"
-			quote_sed_regexp_variable nv "$w_delim$value"
-			sed -i -e "s/^$v\$/$n$nv/" -- "$file"
-			return
-		fi
-	fi
-
-	printf '%s\n' "$name$w_delim$value" >> "$file"
-}
-
-shell_config_del() {
-	[ "$#" -ge 2 -a "$#" -le 3 ] ||
-		fatal "Usage: shell_config_del file name [delim]"
-	local file="$1" name="$2" delim="${3-=}"
-
-	[ -s "$file" ] ||
-		return 0
-	quote_sed_regexp_variable name "$name"
-	sed -i -e "/^[[:space:]]*$name$delim/d" -- "$file"
-}
-
-shell_config_comment() {
-	[ "$#" -ge 2 -a "$#" -le 3 ] ||
-		fatal "Usage: shell_config_comment file name [delim]"
-	local file="$1" name="$2" delim="${3-=}"
-
-	[ -s "$file" ] ||
-		return 0
-	quote_sed_regexp_variable name "$name"
-	sed -i -e "s/^[[:space:]]*$name$delim.*/${__shell_config_comment:-#}&/" -- "$file"
-}
-
-fi #__included_shell_config
diff --git a/external/libshell/shell-error b/external/libshell/shell-error
deleted file mode 100644
index b066e7d..0000000
--- a/external/libshell/shell-error
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_error-}" ]; then
-__included_shell_error=1
-
-PROG="${PROG:-${0##*/}}"
-
-message_time=
-message_time_format=
-message() {
-	local prefix=
-	[ -z "$message_time" ] ||
-		prefix="$(date +"${message_time_format:-[%Y-%m-%d %T]} " 2>/dev/null)" ||:
-	printf %s\\n "${prefix}$PROG: $*" >&2
-}
-
-fatal() {
-	message "$@"
-	exit 1
-}
-
-quiet="${quiet-}"
-verbose="${verbose-}"
-verbose() {
-	[ -n "$verbose" ] || return 0
-	message "$@"
-}
-
-fi #__included_shell_error
diff --git a/external/libshell/shell-getopt b/external/libshell/shell-getopt
deleted file mode 100644
index f591a2b..0000000
--- a/external/libshell/shell-getopt
+++ /dev/null
@@ -1,399 +0,0 @@
-#! /bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_getopt-}" ]; then
-__included_shell_getopt=1
-
-. shell-error
-. shell-quote
-. shell-string
-
-# Ignore unknown options.
-GETOPT_ALLOW_UNKNOWN=
-
-# Long options may be abbreviated, as long as the abbreviation is not ambiguous.
-GETOPT_ALLOW_ABBREV=1
-
-# Allow long options to start with a single ‘-’. See (getopt -a).
-GETOPT_ALLOW_ALTERNATIVE=
-
-OPTERR=1
-OPTTYP=
-OPTUKN=
-OPTOPT=
-OPTARG=
-OPTIND=1
-OPTOFS=
-
-#*** Example ***
-### Usage: getopt2 -ab -d 10 -e20 --opt1 --opt4=100 text1 text2
-###
-# . shell-getopt
-# echo Using getoptex to parse arguments:
-# while getoptex "a; b; c; d: e. opt1 opt2 opt3 opt4: opt5." "$@"; do
-#	echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}"
-# done
-# shift $(($OPTIND-1))
-# set -- $@ ${OPTUKN-}
-# for arg in "$@"; do
-#	echo "Non option argument <$arg>"
-# done
-
-getoptex() {
-	[ "$#" -gt 0 ] ||
-		return 1
-
-	[ "${OPTIND-}" -gt 0 ] 2>/dev/null ||
-		OPTIND=1
-
-	[ "$OPTIND" -lt "$#" ] ||
-		return 1
-
-	getoptex_badarg() {
-		[ -z "${OPTERR-}" ] ||
-			message "option requires an argument -- '$OPTOPT'"
-		OPTARG="$OPTOPT"
-		OPTOPT='?'
-	}
-	getoptex_argument() {
-		[ "$OPTTYP" = ':' ] ||
-			return 0
-		OPTARG="$1"
-		# Added test on following argument being an option identified by '-' this way #
-		# the routine no longer takes options as an argument thus breaking error #
-		# detection. 2004-04-04 by raphael at oninet dot pt #
-
-		[ -n "$OPTARG" -a -n "${OPTARG%%-*}" ] ||
-			{ getoptex_badarg; return 1; }
-
-		OPTARG="${1#[#]}"
-		OPTIND=$(($OPTIND+1)) # skip option's argument
-	}
-	getoptex_option_long() {
-		local arg="$1" v p
-		for p in '--' ${GETOPT_ALLOW_ALTERNATIVE:+'-'}; do
-			if [ -n "${GETOPT_ALLOW_ABBREV-}" ]; then
-				arg="${1%%=*}" v="${1#*=}" o="$p$OPTOPT"
-				if [ -z "${o##$arg*}" ]; then
-					[ "$arg" != "$v" ] &&
-						arg="$o=$v" ||
-						arg="$o"
-					unset o v
-				fi
-			fi
-			case "$arg" in
-				$p$OPTOPT=*)
-					[ -n "$OPTTYP" ] ||
-						{ getoptex_badarg; return 3; }
-					OPTARG="${arg#$p$OPTOPT=}"
-					return 1
-					;;
-				$p$OPTOPT)
-					getoptex_argument "$2" ||
-						return 3
-					return 1
-					;;
-			esac
-		done
-	}
-	getoptex_option_short() {
-		local o="-${1#-${OPTOFS-}}"
-		case "$o" in
-			-$OPTOPT)
-				OPTOFS=
-				getoptex_argument "$2" ||
-					return 3
-				return 1
-				;;
-			-$OPTOPT*)
-				if [ -z "$OPTTYP" ]; then # an option with no argument is in a chain of options
-					OPTOFS="${OPTOFS-}?" # move to the next option in the chain
-					OPTIND=$(($OPTIND-1)) # the chain still has other options
-				else
-					OPTOFS=
-					OPTARG="${o#-$OPTOPT}"
-				fi
-				return 1
-				;;
-		esac
-	}
-
-	local optlist="${1#;}" value=
-	shift $OPTIND
-
-	[ "$#" -lt 2 ] ||
-		value="#$2"
-
-	OPTTYP=
-	# test whether $1 is an option.
-	if [ "$1" = '--' ]; then
-		OPTTYP='--'
-		OPTIND=$(($OPTIND+1))
-	elif [ "$1" != '-' -a "$1" != "${1#-}" ]; then
-		OPTIND=$(($OPTIND+1))
-
-		local cmd argtype
-		for opt in $optlist; do
-			OPTOPT="${opt%[;.:]}"
-			OPTARG=
-			OPTTYP=
-			[ "$OPTTYP" = ';' ] ||
-				OPTTYP="${opt#$OPTOPT}"
-
-			cmd=long
-			[ "${#OPTOPT}" -gt 1 ] ||
-				cmd=short
-
-			getoptex_option_$cmd "$1" "$value" ||
-				return $(($?-1))
-		done
-		OPTOPT='?'
-		OPTARG=
-
-		if [ -n "${GETOPT_ALLOW_UNKNOWN-}" ]; then
-			local q_arg
-			quote_shell_variable q_arg "$1"
-			OPTUKN="${OPTUKN-} \"$q_arg\""
-			return 0
-		fi
-		message "unrecognized option '$1'"
-		return 2
-	fi
-	OPTOPT='?'
-	OPTARG=
-	return 1
-}
-
-#*** Example ***
-### Usage: getopt1 -ab -d 10 -e20 text1 text2
-###
-# . shell-getopt
-# echo "Using getopt to parse arguments:"
-# while getopts "abcd:e." "$@"; do
-#	echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}"
-# done
-# shift $(($OPTIND-1))
-# set -- $@ ${OPTUKN-}
-# for arg in "$@"; do
-#	echo "Non option argument <$arg>"
-# done
-
-getopts() {
-	local l="$1"
-	local m= # mask
-	local r= # to store result
-	fill_mask m "$l" # create a "???..." mask
-
-	while [ -n "$l" ]; do
-		r="${r:+"$r "}${l%$m}" # append the first character of $l to $r
-		l="${l#?}" # cut the first charecter from $l
-		m="${m#?}" # cut one "?" sign from m
-		if [ "${l#[:.;]}" != "$l" ]; then # a special character (";", ".", or ":") was found
-			r="$r${l%$m}" # append it to $r
-			l="${l#?}" # cut the special character from l
-			m="${m#?}" # cut one more "?" sign
-		fi
-	done
-	shift
-	getoptex "$r" "$@" ||
-		return $?
-}
-
-
-#*** Example ***
-# . shell-getopt
-# while getsubopt 'rw mode: path: dev:' 'rw,mode=755,path="/zzz xxx",dev=/dev/zzz'; do
-#	echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}"
-# done
-
-__getsubopt_arguments=
-getsubopt() {
-	local l="$2"
-
-	if [ -z "$__getsubopt_arguments" ]; then
-		local ch m=
-		fill_mask m "$l"
-
-		__getsubopt_arguments='--'
-		while [ -n "$l" ]; do
-			ch="${l%$m}"
-			l="${l#?}"
-			m="${m#?}"
-
-			case "$ch" in
-				,) ch=' --' ;;
-				[\\\\\`\$\"\ ]) ch="\\$ch" ;;
-			esac
-
-			__getsubopt_arguments="$__getsubopt_arguments$ch"
-		done
-	fi
-
-	local GETOPT_ALLOW_ABBREV=
-	eval getoptex "\"$1\"" "$__getsubopt_arguments" ||
-		return $?
-}
-
-. shell-version
-
-GETOPT_POSIXLY_CORRECT=
-
-getopt() {
-	__getopt_version() {
-		cat <<-EOF
-		$PROG version $libshell_version
-		Written by Alexey Gladkov <gladkov.alexey at gmail.com>
-
-		Copyright (C) 2008  Alexey Gladkov <gladkov.alexey at gmail.com>
-		This is free software; see the source for copying conditions.  There is NO
-		warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-		EOF
-	}
-	__getopt_usage() {
-		cat <<-EOF
-		Try \`$PROG --help' for more information.
-		EOF
-	}
-	__getopt_help() {
-		cat <<-EOF
-		Usage: $PROG optstring parameters
-		   or: $PROG [options] [--] optstring parameters
-		   or: $PROG [options] -o|--options optstring [options] [--] parameters
-
-		Options ignored:
-		  -s, --shell=shell            Set shell quoting conventions;
-		  -u, --unqote                 Do not quote the output;
-
-		Options:
-		  -a, --alternative            Allow long options starting with single -;
-		  -l, --longoptions=longopts   Long options to be recognized;
-		  -n, --name=progname          The name under which errors are reported;
-		  -o, --options=optstring      Short options to be recognized;
-		  -q, --quiet                  Disable error reporting;
-		  -Q, --quiet-output           No normal output;
-		  -T, --test                   Test for getopt version;
-		  -V, --version                Output version information;
-		  -h, --help                   This small usage guide.
-
-		Report bugs to http://bugzilla.altlinux.org/
-
-		EOF
-	}
-
-	local PROG='getopt' OPTIND=1 OPTERR=1 prg= opts= lopts= quiet_output= alt= order= rc
-	local GETOPT_POSIXLY_CORRECT
-
-	while getoptex 'a alternative h help l: longoptions: n: name: o: options: q quiet Q quiet-output s shell T test u unquoted V version' "$@" && rc=0 || rc=$?; do
-		case "$rc" in
-			2) __getopt_usage; return 2 ;;
-			1) break ;;
-		esac
-
-		case "$OPTOPT" in
-			a|alternative) alt=1 ;;
-			n|name) prg="$OPTARG" ;;
-			o|options) opts="$OPTARG " ;;
-			l|longoptions) lopts="$OPTARG" ;;
-			q|quiet) OPTERR= ;;
-			Q|quiet-output) quiet_output=1 ;;
-			T|test) return 4 ;;
-			V|version)
-				__getopt_version
-				return 0
-				;;
-			h|help)
-				__getopt_help
-				return 2
-				;;
-		esac
-	done
-
-	shift $(($OPTIND-1))
-	set -- "$@"
-
-	if [ -z "${opts##+*}" ]; then
-		opts="${opts#+}"
-		GETOPT_POSIXLY_CORRECT=1
-	elif [ -z "${opts##-*}" ]; then
-		opts="${opts#-}"
-		order=1
-	fi
-	if [ -z "$opts" ]; then
-		if [ "$#" -gt 1 -a "${1#-}" = "$1" -a "$1" != '--' ]; then
-			opts="$1"
-			shift
-		else
-			message "$PROG: missing optstring argument"
-			__getopt_usage
-			return 2
-		fi
-	fi
-	opts="${lopts:+$lopts,}$opts"
-	while :; do
-		case "$opts" in
-			*,*)  opts="${opts%%,*} ${opts#*,}"   ;;
-			*::*) opts="${opts%%::*}.${opts#*::}" ;;
-			*) break ;;
-		esac
-	done
-
-	local OPTIND=1 OPTOFS= GETOPT_ALLOW_ALTERNATIVE="${alt:+1}"
-	local ret=0 out=' -- '
-
-	! printenv POSIXLY_CORRECT >/dev/null 2>&1 ||
-		GETOPT_POSIXLY_CORRECT=1
-
-	__getopt_out_arg() {
-		local q_arg
-		shift $(($OPTIND-1))
-		quote_shell_variable q_arg "$1"
-		[ -z "$order" ] &&
-			out="${out%% -- *} -- ${out#* -- } \"$q_arg\"" ||
-			out="${out%% -- *} \"$q_arg\" -- ${out#* -- }"
-	}
-
-	PROG="$prg"
-	while getoptex "$opts" "$@" && rc=0 || rc=$?; do
-		case "$rc" in
-			1)
-				[ $# -ge $OPTIND -a -z "${GETOPT_POSIXLY_CORRECT-}" ] ||
-					break
-				__getopt_out_arg "$@"
-				OPTIND=$(($OPTIND+1))
-				[ "$OPTTYP" != '--' ] ||
-					break
-				continue
-				;;
-			2)	ret=1
-				;;
-		esac
-		if [ "$OPTOPT" = '?' ]; then
-			if [ -n "$GETOPT_ALLOW_UNKNOWN" ]; then
-				out="${out%% -- *} -- ${out#* -- }$OPTUKN"
-				OPTUKN=
-			fi
-			continue
-		fi
-		pfx='-'
-		[ "${#OPTOPT}" -eq 1 ] ||
-			pfx='--'
-		out="${out%% -- *} $pfx$OPTOPT${OPTTYP:+ '$OPTARG'} -- ${out#* -- }"
-	done
-
-	local q_arg
-	shift $(($OPTIND-1))
-	set -- "$@"
-	while [ "$#" -gt 0 ]; do
-		quote_shell_variable q_arg "$1"
-		out="${out%% -- *} -- ${out#* -- } \"$q_arg\""
-		shift
-	done
-
-	[ -n "$quiet_output" ] ||
-		printf '%s\n' "$out${OPTUKN:+$OPTUKN}"
-	return $ret
-}
-
-fi #__included_shell_getopt
diff --git a/external/libshell/shell-ini-config b/external/libshell/shell-ini-config
deleted file mode 100644
index 5ed42f1..0000000
--- a/external/libshell/shell-ini-config
+++ /dev/null
@@ -1,155 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_ini_config-}" ]; then
-__included_shell_ini_config=1
-
-shell_ini_config_comment='#'
-
-. shell-error
-. shell-var
-
-# Usage: ini_config_get file section var
-ini_config_get() {
-	local fn section var sect= str eof= n v
-	fn="$1" section="$2" var="$3"
-
-	while [ -z "$eof" ]; do
-		read -r str || eof=1
-
-		case "$str" in
-			"["*"]")
-				[ "$str" != "[$section]" ] ||
-					sect=1
-				;;
-			"$shell_ini_config_comment"*|'')
-				;;
-			*)
-				if [ -n "$sect" ]; then
-					shell_var_trim n "${str%%=*}"
-
-					if [ "$n" = "$var" ]; then
-						shell_var_trim v "${str#*=}"
-						printf '%s\n' "$v"
-						break
-					fi
-				fi
-				;;
-		esac
-	done < "$fn"
-}
-
-# Usage: ini_config_set file section var value
-ini_config_set() {
-	local fn fn_tmp section var value sect= don= str eof= n v
-
-	fn="$1" section="$2" var="$3" value="$4"
-	fn_tmp="$(mktemp "$fn.XXXXXX")"
-
-	while [ -z "$eof" ]; do
-		read -r str || eof=1
-
-
-		case "$str" in
-			"[$section]")
-				sect=2
-				printf '%s\n' "$str"
-				;;
-			"["*"]")
-				if [ "$sect" = 2 -a -z "$don" ]; then
-					printf '\t%s\n' "$var = $value"
-					don=1
-				fi
-				sect=1
-				printf '%s\n' "$str"
-				;;
-			"$shell_ini_config_comment"*|'')
-				[ -n "$str" ] &&
-					printf ${sect:+'\t'}'%s\n' "$str" ||
-					printf '\n'
-				;;
-			*)
-				shell_var_trim n "${str%%=*}"
-				shell_var_trim v "${str#*=}"
-
-				if [ "$sect" = 2 -a "$n" = "$var" ]; then
-					[ -n "$don" ] ||
-						printf '\t%s\n' "$n = $value"
-					don=1
-					continue
-				fi
-				printf '\t%s\n' "$n = $v"
-				;;
-		esac
-
-		if [ -n "$eof" -a -z "$don" ]; then
-			[ "$sect" = 2 ] ||
-				printf '[%s]\n' "$section"
-			printf '\t%s\n' "$var = $value"
-		fi
-
-	done < "$fn" > "$fn_tmp"
-	mv -f -- "$fn_tmp" "$fn"
-}
-
-__ini_config_del_comment() {
-	local fn_tmp sect= str eof= n v
-	fn_tmp="$(mktemp "$fn.XXXXXX")"
-
-	while [ -z "$eof" ]; do
-		read -r str || eof=1
-
-		case "$str" in
-			"["*"]")
-				sect=1
-				[ "$str" != "[$section]" ] ||
-					sect=2
-				printf '%s\n' "$str"
-				;;
-			"$shell_ini_config_comment"*|'')
-				[ -n "$str" ] &&
-					printf ${sect:+'\t'}'%s\n' "$str" ||
-					printf '\n'
-				;;
-			*)
-				shell_var_trim n "${str%%=*}"
-				shell_var_trim v "${str#*=}"
-
-				[ "$sect" = 2 ] &&
-					__ini_config_action "$n" "$v" ||
-					printf '\t%s\n' "$n = $v"
-				;;
-		esac
-	done < "$fn" > "$fn_tmp"
-	mv -f -- "$fn_tmp" "$fn"
-	unset __ini_config_action
-}
-
-# Usage: ini_config_del file section [var]
-ini_config_del() {
-	local fn="$1" section="$2" var="${3-}"
-
-	__ini_config_action() {
-		[ -z "$var" -o "$1" = "$var" ] ||
-			printf '\t%s\n' "$1 = $2"
-	}
-	__ini_config_del_comment
-}
-
-# Usage: ini_config_comment file section [var]
-ini_config_comment() {
-	local fn="$1" section="$2" var="${3-}"
-
-	__ini_config_action() {
-		if [ -n "$var" -a "$1" != "$var" ]; then
-			printf '\t%s\n' "$1 = $2"
-			return
-		fi
-		printf '\t%s\n' "$shell_ini_config_comment $1 = $2"
-	}
-	__ini_config_del_comment
-}
-
-fi #__included_shell_ini_config
diff --git a/external/libshell/shell-ip-address b/external/libshell/shell-ip-address
deleted file mode 100644
index 39e4570..0000000
--- a/external/libshell/shell-ip-address
+++ /dev/null
@@ -1,166 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_ip_address-}" ]; then
-__included_shell_ip_address=1
-
-# Regexp for single byte
-readonly regex_byte='([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])'
-
-# Regexp for 4-byte address
-readonly regex_ipaddr="$regex_byte(\.$regex_byte){3}"
-
-# Regexp for IPv4 address
-#
-# (http://en.wikipedia.org/wiki/IP_address)
-#
-# Some first-octet values have special meanings:
-#
-# * First octet 127 represents the local computer, regardless of what network
-#   it is really in. This is useful when testing internal operations.
-#
-# * First octet 224 and above are reserved for special purposes such as
-#   multicasting.
-#
-# Octets 0 and 255 are not acceptable values in some situations, but 0 can be used
-# as the second and/or third octet (e.g. 10.2.0.100).
-#
-readonly __regex_fbyte='([1-9][0-9]?|1[0-9][0-9]|2[01][0-9]|22[0-3])'
-readonly __regex_sbyte='([1]?[0-9][0-9]?|2[0-4][0-9]|25[0-4])'
-readonly __regex_lbyte='([1]?[0-9][0-9]?|2[0-4][0-9]|25[0-4])'
-
-readonly regex_ipv4="${__regex_fbyte}(\.${__regex_sbyte}){2}\.${__regex_lbyte}"
-
-# Checks that given option value is a valid IPv4 address.
-valid_ipv4() {
-	local ipaddr="$1"
-	local i=0 byte
-
-	byte="${ipaddr##*.}"
-	ipaddr="${ipaddr%.$byte}"
-
-	[ "$byte" -gt 0 -a "$byte" -lt 255 ] 2>/dev/null ||
-			return 1
-
-	while [ $i -lt 3 ]; do
-		byte="${ipaddr##*.}"
-
-		[ "$byte" != "$ipaddr" ] ||
-			break
-
-		ipaddr="${ipaddr%.$byte}"
-
-		[ "$byte" -ge 0 -a "$byte" -lt 255 ] 2>/dev/null ||
-			return 1
-
-		i=$(($i+1))
-	done
-
-	[ $i -eq 2 -a \
-	  "$byte" -ne 127 -a "$byte" -gt 0 -a "$byte" -lt 224 ] 2>/dev/null ||
-		return 1
-}
-
-__ipv4_hex() {
-	[ -n "${1-}" ] ||
-		return 2
-
-	local IFS=.
-	set -- $1
-
-	local i=0
-	for b; do
-		[ "$b" -ge 0 -a "$b" -le 255 ] 2>/dev/null ||
-			return 2
-		i=$(($i + 1))
-	done
-
-	[ "$i" -eq 4 ] ||
-		return 2
-
-	printf '0x'
-	printf '%02x' "$@"
-}
-
-# Checks that IP address is in subnet
-# Usage example:
-# ipv4_ip_subnet 172.16.1.2 172.16.1.0/24; echo res=$?
-# res=0
-#
-# ipv4_ip_subnet 172.16.3.2 172.16.1.0/24; echo res=$?
-# res=1
-ipv4_ip_subnet() {
-	local ip net prefix
-	ip="${1-}"; shift
-	net="${1-}"; shift
-	prefix="${net##*/}"
-
-	[ -n "$prefix" -a "$prefix" -ge 0 ] 2>/dev/null ||
-		return 2
-
-	local hex_addr hex_net hex_mask p
-
-	hex_addr="$(__ipv4_hex "$ip")" &&
-	hex_net="$(__ipv4_hex "${net%%/*}")" ||
-		return 2
-
-	p=$((0xFFFFFFFF))
-	hex_mask="$(($p - ($p >> $prefix)))"
-	[ "$(($hex_net & $hex_mask))" -eq "$(($hex_addr & $hex_mask))" ] ||
-		return 1
-}
-
-# Convert netmask to routing prefix.
-# Usage example:
-# ipv4_mask2prefix 255.255.0.0
-# 16
-#
-# ipv4_prefix2mask 255.255.255.0
-# 24
-ipv4_mask2prefix() {
-	local hex_mask
-	hex_mask="$(__ipv4_hex "${1-}")" ||
-		return 2
-
-	local p i=0 prefix=
-
-	p=$((~$hex_mask & 0xFFFFFFFF))
-
-	while [ "$p" -ne 0 ]; do
-		p=$(($p >> 1 & 0xFFFFFFFF))
-		i=$(($i + 1))
-	done
-	prefix=$((32 - $i))
-
-	[ "$prefix" -ge 0 -a "$prefix" -le 32 ] ||
-		return 1
-	echo "$prefix"
-}
-
-# Convert routing prefix to netmask.
-# Usage example:
-# ipv4_prefix2mask 16
-# 255.255.0.0
-#
-# ipv4_prefix2mask 24
-# 255.255.255.0
-ipv4_prefix2mask() {
-	local len
-	len="${1-}"
-
-	[ "$len" -ge 0 -a "$len" -le 32 ] 2>/dev/null ||
-		return 1
-
-	local position=$((0xFFFFFFFF))
-	local mask=$(($position - ($position >> $len)))
-
-	printf '%s.%s.%s.%s\n' \
-	    "$(($mask >> 24 & 0xFF))" \
-	    "$(($mask >> 16 & 0xFF))" \
-	    "$(($mask >> 8  & 0xFF))" \
-	    "$(($mask       & 0xFF))"
-}
-
-fi #__included_shell_ip_address
diff --git a/external/libshell/shell-mail-address b/external/libshell/shell-mail-address
deleted file mode 100644
index 7e20cbb..0000000
--- a/external/libshell/shell-mail-address
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_mail_address-}" ]; then
-__included_shell_mail_address=1
-
-if [ -n "${shell_mail_address_strict-}" ]; then
-	#
-	# (http://en.wikipedia.org/wiki/Country_code_top-level_domain)
-	#
-	# A country code top-level domain (ccTLD) is an Internet top-level domain
-	# generally used or reserved for a country or a dependent territory.
-	#
-	readonly regex_cctld_active='(a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstwyz]|c[acdfghiklmnoruvxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[adefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklnrstwy]|qa|r[eosuw]|s[abcdeghiklmnrtuvyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|ye|z[amw])'
-	readonly regex_cctld_reserved='(um|bl|eh|mf)'
-	readonly regex_cctld_allocated='(bv|gb|pm|sj|so|yt)'
-	readonly regex_cctld_phaseout='(tp|yu)'
-	readonly regex_cctld_deleted='(cs|dd|zr)'
-
-	# (http://en.wikipedia.org/wiki/GTLD)
-	#
-	# A generic top-level domain (gTLD) is a top-level domain used by a
-	# particular class of organization.
-	#
-	readonly regex_gtld='(aero|arpa|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel)'
-
-	regex_tld="($regex_gtld|$regex_cctld_active|$regex_cctld_reserved|$regex_cctld_allocated|$regex_cctld_phaseout)"
-else
-	regex_tld='([a-zA-Z]{2,4}|museum|travel)'
-fi
-
-# 6. ADDRESS SPECIFICATION (http://tools.ietf.org/html/rfc822)
-#
-# addr-spec   =  local-part "@" domain        ; global address
-# local-part  =  word *("." word)             ; uninterpreted
-#                                             ; case-preserved
-# domain      =  sub-domain *("." sub-domain)
-# sub-domain  =  domain-ref / domain-literal
-# domain-ref  =  atom                         ; symbolic reference
-#
-# 6.2.3. DOMAIN TERMS
-# A domain-ref must be THE official name of a registry, network,
-# or host.
-
-# This regexp should be used ignoring case.
-readonly regex_domain="([a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*)\.$regex_tld"
-
-# Regexp can be used to check and parse email address. This regexp
-# should be used ignoring case.
-# Usage example:
-# username="$(printf '%s' "$email" |sed -e "s/^$regex_email\$/\1/i")
-#   domain="$(printf '%s' "$email" |sed -e "s/^$regex_email\$/\2/i")
-#
-readonly regex_email="([_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*)@($regex_domain)"
-
-# Checks that given option value is a valid email address.
-valid_email() {
-	local email="$1"
-	printf '%s' "$email" |
-		egrep -iqs "^$regex_email\$" ||
-		return 1
-}
-
-fi #__included_shell_mail_address
diff --git a/external/libshell/shell-quote b/external/libshell/shell-quote
deleted file mode 100644
index 4f06f60..0000000
--- a/external/libshell/shell-quote
+++ /dev/null
@@ -1,158 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_quote-}" ]; then
-__included_shell_quote=1
-
-. shell-version
-. shell-error
-. shell-string
-
-# Quote argument for sed basic regular expression and store result into variable.
-# Usage example:
-# quote_sed_regexp_variable var_pattern "$pattern"
-# quote_sed_regexp_variable var_replace "$replace"
-# sed "s/$var_pattern/$var_replace/"
-quote_sed_regexp_variable() {
-	local __quote_set_regexp_variable_var __quote_set_regexp_variable_out
-	__quote_set_regexp_variable_var="$1"; shift
-	__quote_set_regexp_variable_out="$*"
-	if [ -z "${__quote_set_regexp_variable_out##*[\[\].*&^\$\\\\/]*}" ]; then
-		__quote_set_regexp_variable_out="$(printf %s "$__quote_set_regexp_variable_out" |
-				sed -e 's/[].*&^$[\/]/\\&/g')" ||
-			return 1
-	fi
-	eval "$__quote_set_regexp_variable_var=\"\$__quote_set_regexp_variable_out\""
-}
-
-# Quote given arguments for sed basic regular expression.
-# Usage example: sed "s/$(quote_sed_regexp "$var_pattern")/$(quote_sed_regexp "$var_replacement")/"
-quote_sed_regexp() {
-	local result
-	quote_sed_regexp_variable result "$@"
-	printf %s "$result"
-}
-
-# Quote argument for shell and store result into variable.
-# Usage example:
-# quote_shell_variable var_name "$var_value"
-# printf '%s\n' "$var_name"
-quote_shell_variable() {
-	local __quote_shell_variable_var __quote_shell_variable_out
-	__quote_shell_variable_var="$1"; shift
-	__quote_shell_variable_out="$*"
-	if [ -z "${__quote_shell_variable_out##*[\"\$\`\\\\]*}" ]; then
-		__quote_shell_variable_out="$(printf %s "$__quote_shell_variable_out" |
-				sed -e 's/[\"$\`\\]/\\&/g')" ||
-			return 1
-	fi
-	eval "$__quote_shell_variable_var=\"\$__quote_shell_variable_out\""
-}
-
-# Quote argument for shell.
-# Usage example: eval "$var_name=\"$(quote_shell "$var_value")\""
-quote_shell() {
-	local result
-	quote_shell_variable result "$@"
-	printf %s "$result"
-}
-
-# Quote argument for shell and store result into variable.
-#
-# Usage example:
-# quote_shell_args args "$var_args"
-# eval "set -- $args"
-quote_shell_args() {
-# This is an internal function to avoid the use of ugly namespace.
-__quote_shell_args() {
-	local m= r= c= l="$1"
-	# backslash/double/single quote mode
-	local bq= dq= sq=
-
-	__quote_shell_args_toggle() {
-		# toggle $1 value
-		eval [ -n \"\$$1\" ] && eval "$1=" || eval "$1=\$$2"
-	}
-
-	fill_mask m "$l"
-
-	while [ -n "$l" ]; do
-		c="${l%$m}"
-		l="${l#?}"
-		m="${m#?}"
-
-		case "$c" in
-			\")
-				# toggle double quote mode unless
-				# in backslash or single quote mode
-				[ -n "$bq$sq" ] || __quote_shell_args_toggle dq c
-				;;
-			\')
-				# toggle single quote mode unless
-				# in backslash or double quote mode
-				[ -n "$bq$dq" ] || __quote_shell_args_toggle sq c
-				;;
-			\$|\`)
-				# quote special character unless
-				# in backslash or single quote mode
-				[ -n "$bq$sq" ] || bq=\\
-				;;
-			\\)
-				# toggle backslash quote mode unless
-				# in single quote mode
-				if [ -z "$sq" ]; then
-					if [ -z "$bq" ]; then
-						# enter backslash quote mode
-						bq=\\
-						continue
-					else
-						# leave backslash quote mode
-						r="$r\\"
-						bq=
-					fi
-				fi
-				;;
-			[!A-Za-z0-9_\ \	])
-				# quote non-regular character unless
-				# in any quote mode
-				[ -n "$bq$dq$sq" ] || bq=\\
-				;;
-		esac
-		r="$r$bq$c"
-		# leave backslash quote mode if any
-		bq=
-	done
-
-	[ -z "$bq$dq$sq" ] ||
-		{ message "unmatched character ($bq$dq$sq) found"; return 1; }
-	__quote_shell_args_out="$r"
-}
-	local __quote_shell_args_out= __quote_shell_args_rc=0
-	__quote_shell_args "$2" ||
-		__quote_shell_args_rc=1
-	eval "$1=\"\$__quote_shell_args_out\""
-
-	# Remove internal functions from user namespace.
-	unset __quote_shell_args __quote_shell_args_toggle
-
-	return $__quote_shell_args_rc
-}
-
-if [ -n "${__export_compatibility_string_quote_remove-}" ]; then
-# Obsolete function. You shouldn't use it.
-string_quote_remove() {
-	local out="$1"
-	if [ -z "${1##*\'}${1%%\'*}" ]; then
-		out="${1#\'}"
-		out="${out%\'}"
-	elif [ -z "${1##*\"}${1%%\"*}" ]; then
-		out="${1#\"}"
-		out="${out%\"}"
-	fi
-	printf %s "$out"
-}
-fi # __export_compatibility_string_quote_remove
-
-fi #__included_shell_quote
diff --git a/external/libshell/shell-regexp b/external/libshell/shell-regexp
deleted file mode 120000
index 1d9df4e..0000000
--- a/external/libshell/shell-regexp
+++ /dev/null
@@ -1 +0,0 @@
-shell-quote
\ No newline at end of file
diff --git a/external/libshell/shell-run b/external/libshell/shell-run
deleted file mode 100644
index 9719bf8..0000000
--- a/external/libshell/shell-run
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_run-}" ]; then
-__included_shell_run=1
-
-. shell-args
-. shell-source
-
-# Execute command if file is executable.
-# Usage: run_if_executable /file arg1 arg2
-#    or: run_if_executable  file arg1 arg2
-run_if_executable() {
-	local v f
-	f="$1"; shift
-	! __shell_source_find v "$f" || [ ! -x "$v" ] || "$v" "$@"
-}
-
-# Run scripts from directory.
-# Usage: run_scripts <dir> [args]
-RUN_SCRIPTS_EXCLUDE='*.rpm* *.swp *,v *~ *.\#'
-run_scripts() {
-	[ "$#" -ge 1 ] ||
-		fatal "Usage: run_scripts <dir> [args]"
-	local p f d rc=0
-	d="$(opt_check_dir "dir" "$1")"; shift
-
-	for f in $(find -L "$d" -mindepth 1 -maxdepth 1 -type f); do
-		for p in $RUN_SCRIPTS_EXCLUDE; do
-			[ -n "${f##$p}" ] ||
-				continue 2
-		done
-		run_if_executable "$f" "$@" || rc=1
-	done
-	return $rc
-}
-
-fi #__included_shell_run
diff --git a/external/libshell/shell-signal b/external/libshell/shell-signal
deleted file mode 100644
index d7d49f4..0000000
--- a/external/libshell/shell-signal
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_signal-}" ]; then
-__included_shell_signal=1
-
-. shell-error
-. shell-quote
-
-__shell_signal_handlers=
-# Set handler code whan any of the specified signals are received.
-# Return code of handler function will be ignored. Special handlers is
-# SIG_IGN and SIG_DFL (See signal(2)).
-#
-# Usage example:
-# signal_handler 'echo $arg' TERM EXIT HUP
-# signal_handler SIG_IGN     TERM EXIT HUP
-# signal_handler SIG_DFL     TERM EXIT HUP
-signal_handler() {
-	local action real_action sign
-	action="$1"; shift
-
-	for sign; do
-		sign="${sign#SIG}"
-		case "$action" in
-			SIG_IGN)
-				eval "unset __signal_handlers_$sign"
-				real_action=:
-				trap : "$sign"
-				;;
-			SIG_DFL)
-				eval "unset __signal_handlers_$sign"
-				real_action=-
-				trap - "$sign"
-				;;
-			*)
-				eval "handler=\"\${__signal_handlers_$sign-} \$action;\""
-				trap "$handler" "$sign"
-				eval "__signal_handlers_$sign=\"\$handler\""
-				;;
-		esac
-	done
-}
-
-# Set exit handler. Return code of handler function will be ignored.
-#
-# Usage example:
-# exit_function() { echo "Exit with return code '$1'"; }
-# set_cleanup_handler exit_function
-__cleanup_handler_name=
-set_cleanup_handler() {
-	__cleanup_handler_name="${1-}"
-	__cleanup_handler() {
-		trap - EXIT
-		[ -z "${__cleanup_handler_name-}" ] ||
-			"$__cleanup_handler_name" "$1" ||:
-		exit "$1"
-	}
-	signal_handler '__cleanup_handler $?' EXIT
-	signal_handler '__cleanup_handler  1' HUP PIPE INT QUIT TERM
-}
-
-# Remove exit handler.
-#
-# Usage example: unset_cleanup_handler
-unset_cleanup_handler() {
-	signal_handler SIG_DFL EXIT HUP PIPE INT QUIT TERM
-	__cleanup_handler_name=
-}
-
-fi #__included_shell_signal
diff --git a/external/libshell/shell-source b/external/libshell/shell-source
deleted file mode 100644
index 0838849..0000000
--- a/external/libshell/shell-source
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_source-}" ]; then
-__included_shell_source=1
-
-__shell_source_find() {
-	local r f IFS=:
-	r="$1"; shift
-	f="$1"; shift
-
-	if [ -n "${f##*/*}" ]; then
-		set -- ${PATH-}
-		while [ "$#" -gt 0 ]; do
-			if [ -e "$1/$f" ]; then
-				f="$1/$f"
-				break
-			fi
-			shift
-		done
-	fi
-	[ -e "$f" ] || return 1
-	eval "$r=\"\$f\""
-}
-
-# Execute commands from file in the current environment if file exists.
-# Usage: source_if_exists /file arg1 arg2
-#    or: source_if_exists  file arg1 arg2
-source_if_exists() {
-	local v f
-	f="$1";	shift
-	! __shell_source_find v "$f" || [ ! -f "$v" ] || . "$v"
-}
-
-# Execute commands from file in the current environment if file is not empty.
-# Usage: source_if_notempty /file arg1 arg2
-#    or: source_if_notempty  file arg1 arg2
-source_if_notempty() {
-	local v f
-	f="$1"; shift
-	! __shell_source_find v "$f" || [ ! -s "$v" ] || . "$v"
-}
-
-# Execute commands from file in the current environment if file is executable.
-# Usage: source_if_executable /file arg1 arg2
-#    or: source_if_executable  file arg1 arg2
-source_if_executable() {
-	local v f
-	f="$1"; shift
-	! __shell_source_find v "$f" || [ ! -x "$v" ] || . "$v"
-}
-
-fi #__included_shell_source
diff --git a/external/libshell/shell-string b/external/libshell/shell-string
deleted file mode 100644
index eb249b5..0000000
--- a/external/libshell/shell-string
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_string-}" ]; then
-__included_shell_string=1
-
-# Creates a mask of equal length string.
-# Usage: fill_mask var str [full-length]
-fill_mask() {
-	local __i=0 __m= __v="$1" __s="$2"
-	while [ $__i -lt ${#__s} ]; do
-		__m="$__m?????"
-		__i=$(($__i + 5))
-	done
-	case $((${#__m} - ${#__s})) in
-		5) __m="${__m#?????}" ;;
-		4) __m="${__m#????}" ;;
-		3) __m="${__m#???}" ;;
-		2) __m="${__m#??}" ;;
-		1) __m="${__m#?}" ;;
-	esac
-	[ -n "${3-}" ] || __m="${__m#?}"
-	eval "$__v=\$__m"
-}
-
-fi #__included_shell_string
diff --git a/external/libshell/shell-unittest b/external/libshell/shell-unittest
deleted file mode 100644
index 67cb0c5..0000000
--- a/external/libshell/shell-unittest
+++ /dev/null
@@ -1,252 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_unittest-}" ]; then
-__included_shell_unittest=1
-
-. shell-error
-
-# Append tests condition to comment message if test failed.
-unittest_show_condition="${unittest_show_condition-}"
-
-# Called before each test is run.
-setUp() { :; }
-
-# Called after each test is run.
-tearDown() { :; }
-
-# Called before any test is run.
-setUpTests() { :; }
-
-# Called after any test is run.
-tearDownTests() { :; }
-
-# Register new testing function.
-# appendTests (TestFunc)
-__shell_unit_tests=
-appendTests() {
-	while [ "$#" -gt 0 ]; do
-		__shell_unit_tests="$__shell_unit_tests
-$1"
-		shift
-	done
-}
-
-# Automatically register test functions with 'UnitTest' comment.
-# Name of current shell script will be used if argument is not present.
-# registerTests([/tmp/Tests-File])
-# Example:
-# my_testcase_function() { # UnitTest
-#     blah blah blah ...
-# }
-registerTests() {
-	local l="$(sed -ne 's/^\([[:alnum:]_]\+\)().*[[:space:]]*#[[:space:]]*UnitTest/\1/p' "${1:-$0}")"
-	[ -z "$l" ] || appendTests $l
-}
-
-# Skip test (called in testing function)
-shouldSkip() {
-	exit 2
-}
-
-# Asserts that a given shell test condition (or integer) is true.
-# assertTrue([comment], condition)
-# assertTrue([comment], integer)
-assertTrue() {
-	local comment= condition
-	[ "$#" -lt 2 ] ||
-		{ comment="$1"; shift; }
-	condition="$1"; shift
-
-	[ -z "$unittest_show_condition" ] ||
-		comment="${comment:+$comment }($condition) == false"
-
-	if [ -n "${condition##*[!0-9\-]*}" ]; then
-		[ $condition -ne 0 ] ||
-			return 0
-		[ -z "$comment" ] ||
-			printf '%s' "$comment"
-		exit 1
-	fi
-
-	if ! ( eval "$condition" ) >/dev/null; then
-		[ -z "$comment" ] ||
-			printf '%s' "$comment"
-		exit 1
-	fi
-}
-
-# Asserts that a given shell test condition (or integer) is false.
-# assertFalse([comment], condition)
-# assertFalse([comment], integer)
-assertFalse() {
-	local comment= condition
-	[ "$#" -lt 2 ] ||
-		{ comment="$1"; shift; }
-	condition="$1"; shift
-
-	[ -z "$unittest_show_condition" ] ||
-		comment="${comment:+$comment }($condition) == true"
-
-	if [ -n "${condition##*[!0-9\-]*}" ]; then
-		[ $condition -eq 0 ] ||
-			return 0
-		[ -z "$comment" ] ||
-			printf '%s' "$comment"
-		exit 1
-	fi
-
-	if ( eval "$condition" ) >/dev/null; then
-		[ -z "$comment" ] ||
-			printf '%s' "$comment"
-		exit 1
-	fi
-}
-
-# Asserts that two arguments are equal to one another.
-# assertEquals([comment], expected, actual)
-assertEquals() {
-	local comment= expected actual
-	[ "$#" -lt 3 ] ||
-		{ comment="$1"; shift; }
-	expected="$1"; shift
-	actual="$1"; shift
-
-	if [ "$expected" != "$actual" ]; then
-		[ -z "$unittest_show_condition" ] ||
-			comment="${comment:+$comment }($expected) != ($actual)"
-		[ -z "$comment" ] ||
-			printf '%s' "$comment"
-		exit 1
-	fi
-}
-
-# Asserts that two arguments are same.
-# assertSame([comment], expected, actual)
-assertSame() {
-	assertEquals "${@-}"
-}
-
-# Asserts that two arguments are not equal to one another.
-# assertNotEquals([comment], expected, actual)
-assertNotEquals() {
-	local comment= expected actual
-	[ "$#" -lt 3 ] ||
-		{ comment="$1"; shift; }
-	expected="$1"; shift
-	actual="$1"; shift
-
-	if [ "$expected" = "$actual" ]; then
-		[ -z "$unittest_show_condition" ] ||
-			comment="${comment:+$comment }($expected) == ($actual)"
-		[ -z "$comment" ] ||
-			printf '%s' "$comment"
-		exit 1
-	fi
-}
-
-# Asserts that two arguments are not same.
-# assertNotSame([comment], expected, actual)
-assertNotSame() {
-	assertNotEquals "${@-}"
-}
-
-# Asserts that argument is a zero-length string.
-# assertNull([comment], value)
-assertNull() {
-	local comment= value
-	[ "$#" -lt 2 ] ||
-		{ comment="$1"; shift; }
-	value="$1"; shift
-
-	if [ -n "$value" ]; then
-		[ -z "$unittest_show_condition" ] ||
-			comment="${comment:+$comment }($value) == ''"
-		[ -z "$comment" ] ||
-			printf '%s' "$comment"
-		exit 1
-	fi
-}
-
-# Asserts that argument is not empty string.
-# assertNotNull([comment], value)
-assertNotNull() {
-	local comment= value
-	[ "$#" -lt 2 ] ||
-		{ comment="$1"; shift; }
-	value="$1"; shift
-
-	if [ -z "$value" ]; then
-		[ -z "$unittest_show_condition" ] ||
-			comment="${comment:+$comment }($value) != ''"
-		[ -z "$comment" ] ||
-			printf '%s' "$comment"
-		exit 1
-	fi
-}
-
-# Display status message after each test.
-messageTest() {
-	case "$3" in
-		0) printf '[done]' ;;
-		1) printf '[FAIL]' ;;
-		2) printf '[skip]' ;;
-		*) printf '[status=%s]' $3 ;;
-	esac
-	printf ' (%s) %s\n' "$1" "$2"
-}
-
-# Display summary statistic.
-showSummary() {
-	if [ "$total" -eq 0 ]; then
-		message "Nothing to do"
-		return
-	fi
-	printf '\n'
-	printf 'tests passed:  %6d %3d%%\n' "$passed" "$((($passed*100)/$total))"
-	printf 'tests failed:  %6d %3d%%\n' "$failed" "$((($failed*100)/$total))"
-	printf 'tests skipped: %6d %3d%%\n' "$skipped" "$((($skipped*100)/$total))"
-	printf 'tests total:   %6d\n\n' "$total"
-}
-
-# Run tests.
-runUnitTests() {
-
-	run_or_exit() {
-		"$@" || fatal "$1() fail rc=$?"
-	}
-
-	run_or_exit setUpTests
-
-	local IFS=' 	
-'
-	__shell_unit_tests="$(printf '%s\n' "$__shell_unit_tests" |sort -u)"
-	set -- ${__shell_unit_tests-}
-
-	local retval=0 rc passed=0 failed=0 skipped=0 total="$#"
-
-	while [ "$#" -gt 0 ]; do
-		run_or_exit setUp
-
-		rc=0
-		msg="$("$1")" || rc=$?
-
-		case "$rc" in
-			0) passed=$(($passed+1)) ;;
-			1) failed=$(($failed+1)); retval=1; ;;
-			2) skipped=$(($skipped+1)) ;;
-		esac
-		run_or_exit messageTest "$1" "$msg" "$rc"
-
-		run_or_exit tearDown
-		shift
-	done
-	run_or_exit showSummary
-	run_or_exit tearDownTests
-
-	return $retval
-}
-
-fi #__included_shell_unittest
diff --git a/external/libshell/shell-var b/external/libshell/shell-var
deleted file mode 100644
index 39c1299..0000000
--- a/external/libshell/shell-var
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_var-}" ]; then
-__included_shell_var=1
-
-. shell-error
-
-shell_var_is_yes() {
-	[ "$#" -eq 1 ] ||
-		fatal "Usage: shell_var_yes value"
-	case "$1" in
-		[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|[Yy]|1) return 0 ;;
-	esac
-	return 1
-}
-
-shell_var_is_no() {
-	[ "$#" -eq 1 ] ||
-		fatal "Usage: shell_var_no value"
-	case "$1" in
-		[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|[Nn]|0) return 0 ;;
-	esac
-	return 1
-}
-
-# Strip whitespace from the beginning and end of a string
-# Usage: shell_var_trim retval "   aaa bb  aaa "; echo "[$retval]"
-# [aaa bb  aaa]
-shell_var_trim() {
-	[ "$#" -eq 2 ] ||
-		fatal "Usage: shell_var_trim varname value"
-	local __shell_var_trim_var="$1" __shell_var_trim_ret="$2"
-	local IFS=' 	
-'
-	set -- $__shell_var_trim_ret
-	if [ "$#" -eq 0 ]; then
-		eval "$__shell_var_trim_var=''"
-		return
-	fi
-	__shell_var_trim_ret="$1${__shell_var_trim_ret#*$1}"
-	shift $(($#-1))
-	__shell_var_trim_ret="${__shell_var_trim_ret%$1*}$1"
-	eval "$__shell_var_trim_var=\"\$__shell_var_trim_ret\""
-}
-
-# Remove quote symbol from string
-# Usage example:
-# for i in "\"str1\"" "'str2'" "\"str3'"; do
-#    shell_var_unquote var "$i";
-#    echo "$var";
-# done
-#
-# Result:
-# str1
-# str2
-# "str3'
-#
-shell_var_unquote() {
-	[ "$#" -eq 2 ] ||
-		fatal "Usage: shell_var_unquote varname value"
-	local __shell_var_unquote_var="$1" __shell_var_unquote_out="$2"
-	if [ -z "${__shell_var_unquote_out##*\'}${__shell_var_unquote_out%%\'*}" ]; then
-		__shell_var_unquote_out="${__shell_var_unquote_out#\'}"
-		__shell_var_unquote_out="${__shell_var_unquote_out%\'}"
-	elif [ -z "${__shell_var_unquote_out##*\"}${__shell_var_unquote_out%%\"*}" ]; then
-		__shell_var_unquote_out="${__shell_var_unquote_out#\"}"
-		__shell_var_unquote_out="${__shell_var_unquote_out%\"}"
-	fi
-	eval "$__shell_var_unquote_var=\"\$__shell_var_unquote_out\""
-}
-
-fi #__included_shell_var
diff --git a/external/libshell/shell-version b/external/libshell/shell-version
deleted file mode 100644
index 12eb48a..0000000
--- a/external/libshell/shell-version
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh -efu
-# This file is covered by the GNU General Public License,
-# which should be included with libshell as the file LICENSE.
-# All copyright information are listed in the COPYING.
-
-if [ -z "${__included_shell_version-}" ]; then
-__included_shell_version=1
-
-libshell_version=3
-
-__export_compatibility_string_quote_remove=1
-
-fi #__included_shell_version
diff --git a/external/libshell/tests/cmdline_get b/external/libshell/tests/cmdline_get
deleted file mode 100644
index 786415f..0000000
--- a/external/libshell/tests/cmdline_get
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/ash -efu
-
-CMDLINE='ro rw= root=LABEL=ROOT resume=/dev/sda1 panic=30 foo.bar="zzz xxx" BOOT_IMAGE=/bad/param BOOT-IMAGE=/boot/vmlinuz'
-
-cmdline_get_test1() { # UnitTest
-	. ../shell-cmdline
-
-	local result
-	cmdline_get 'result' 'resume' "$CMDLINE"
-	assertEquals "resume=[$result]" "$result" '/dev/sda1'
-}
-
-cmdline_get_test2() { # UnitTest
-	. ../shell-cmdline
-
-	local result
-	cmdline_get 'result' 'ro' "$CMDLINE"
-	assertEquals "ro=[$result]" "$result" '1'
-}
-
-cmdline_get_test3() { # UnitTest
-	. ../shell-cmdline
-
-	local result
-	cmdline_get 'result' 'rw' "$CMDLINE"
-	assertEquals "rw=[$result]" "$result" ''
-}
-
-cmdline_get_test4() { # UnitTest
-	. ../shell-cmdline
-
-	local result
-	cmdline_get 'result' 'root' "$CMDLINE"
-	assertEquals "root=[$result]" "$result" 'LABEL=ROOT'
-}
-
-cmdline_get_test5() { # UnitTest
-	. ../shell-cmdline
-
-	local result
-	cmdline_get 'result' 'foo.bar' "$CMDLINE"
-	assertEquals "foo.bar=[$result]" "$result" 'zzz xxx'
-}
-
-cmdline_get_test6() { # UnitTest
-	. ../shell-cmdline
-
-	local result
-	cmdline_get 'result' 'BOOT-IMAGE' "$CMDLINE"
-	assertEquals "BOOT-IMAGE=[$result]" "$result" '/boot/vmlinuz'
-}
-
-cmdline_get_test7() { # UnitTest
-	. ../shell-cmdline
-
-	local result
-	cmdline_get 'result' 'BOOT_IMAGE' "$CMDLINE"
-	assertEquals "BOOT_IMAGE=[$result]" "$result" '/boot/vmlinuz'
-}
diff --git a/external/libshell/tests/data/000-quote_shell_args-pattern b/external/libshell/tests/data/000-quote_shell_args-pattern
deleted file mode 100644
index 6cd822a..0000000
--- a/external/libshell/tests/data/000-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-a b "c d" 'e f'
diff --git a/external/libshell/tests/data/000-quote_shell_args-result b/external/libshell/tests/data/000-quote_shell_args-result
deleted file mode 100644
index 3a61335..0000000
--- a/external/libshell/tests/data/000-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[a] [b] [c d] [e f]
diff --git a/external/libshell/tests/data/001-quote_shell_args-pattern b/external/libshell/tests/data/001-quote_shell_args-pattern
deleted file mode 100644
index 2295343..0000000
--- a/external/libshell/tests/data/001-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-a b "c ' d" 'e " f'
diff --git a/external/libshell/tests/data/001-quote_shell_args-result b/external/libshell/tests/data/001-quote_shell_args-result
deleted file mode 100644
index 6cbd863..0000000
--- a/external/libshell/tests/data/001-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[a] [b] [c ' d] [e " f]
diff --git a/external/libshell/tests/data/002-quote_shell_args-pattern b/external/libshell/tests/data/002-quote_shell_args-pattern
deleted file mode 100644
index 4864ed2..0000000
--- a/external/libshell/tests/data/002-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-a b "c \" d" e f
diff --git a/external/libshell/tests/data/002-quote_shell_args-result b/external/libshell/tests/data/002-quote_shell_args-result
deleted file mode 100644
index 55f3ed0..0000000
--- a/external/libshell/tests/data/002-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[a] [b] [c " d] [e] [f]
diff --git a/external/libshell/tests/data/003-quote_shell_args-pattern b/external/libshell/tests/data/003-quote_shell_args-pattern
deleted file mode 100644
index dd00149..0000000
--- a/external/libshell/tests/data/003-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-a $HOME \$HOME \\$HOME \\\$HOME \\\\$HOME c
diff --git a/external/libshell/tests/data/003-quote_shell_args-result b/external/libshell/tests/data/003-quote_shell_args-result
deleted file mode 100644
index 165edcf..0000000
--- a/external/libshell/tests/data/003-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[a] [$HOME] [$HOME] [\$HOME] [\$HOME] [\\$HOME] [c]
diff --git a/external/libshell/tests/data/004-quote_shell_args-pattern b/external/libshell/tests/data/004-quote_shell_args-pattern
deleted file mode 100644
index 2625179..0000000
--- a/external/libshell/tests/data/004-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-a "$HOME \$HOME \\$HOME \\\$HOME \\\\$HOME" c
diff --git a/external/libshell/tests/data/004-quote_shell_args-result b/external/libshell/tests/data/004-quote_shell_args-result
deleted file mode 100644
index 042a83a..0000000
--- a/external/libshell/tests/data/004-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[a] [$HOME $HOME \$HOME \$HOME \\$HOME] [c]
diff --git a/external/libshell/tests/data/005-quote_shell_args-pattern b/external/libshell/tests/data/005-quote_shell_args-pattern
deleted file mode 100644
index 1b7a7ab..0000000
--- a/external/libshell/tests/data/005-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-a '$HOME \$HOME \\$HOME \\\$HOME \\\\$HOME' c
diff --git a/external/libshell/tests/data/005-quote_shell_args-result b/external/libshell/tests/data/005-quote_shell_args-result
deleted file mode 100644
index 7a90df0..0000000
--- a/external/libshell/tests/data/005-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[a] [$HOME \$HOME \\$HOME \\\$HOME \\\\$HOME] [c]
diff --git a/external/libshell/tests/data/006-quote_shell_args-pattern b/external/libshell/tests/data/006-quote_shell_args-pattern
deleted file mode 100644
index 0441d5b..0000000
--- a/external/libshell/tests/data/006-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-/bin/shell-* /bin/shell-[a-z]* /bin/shell-{error,getopt}
diff --git a/external/libshell/tests/data/006-quote_shell_args-result b/external/libshell/tests/data/006-quote_shell_args-result
deleted file mode 100644
index 08120b3..0000000
--- a/external/libshell/tests/data/006-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[/bin/shell-*] [/bin/shell-[a-z]*] [/bin/shell-{error,getopt}]
diff --git a/external/libshell/tests/data/007-quote_shell_args-pattern b/external/libshell/tests/data/007-quote_shell_args-pattern
deleted file mode 100644
index 704540f..0000000
--- a/external/libshell/tests/data/007-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-"/bin/shell-* /bin/shell-[a-z]* /bin/shell-{error,getopt}"
diff --git a/external/libshell/tests/data/007-quote_shell_args-result b/external/libshell/tests/data/007-quote_shell_args-result
deleted file mode 100644
index 3551aca..0000000
--- a/external/libshell/tests/data/007-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[/bin/shell-* /bin/shell-[a-z]* /bin/shell-{error,getopt}]
diff --git a/external/libshell/tests/data/008-quote_shell_args-pattern b/external/libshell/tests/data/008-quote_shell_args-pattern
deleted file mode 100644
index 13a6e8c..0000000
--- a/external/libshell/tests/data/008-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-/bin/shell-* "/bin/shell-[a-z]* /bin/shell-{error,getopt}"
diff --git a/external/libshell/tests/data/008-quote_shell_args-result b/external/libshell/tests/data/008-quote_shell_args-result
deleted file mode 100644
index ba3c8ae..0000000
--- a/external/libshell/tests/data/008-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[/bin/shell-*] [/bin/shell-[a-z]* /bin/shell-{error,getopt}]
diff --git a/external/libshell/tests/data/009-quote_shell_args-pattern b/external/libshell/tests/data/009-quote_shell_args-pattern
deleted file mode 100644
index e5f904d..0000000
--- a/external/libshell/tests/data/009-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-'/bin/shell-* /bin/shell-[a-z]* /bin/shell-{error,getopt}'
diff --git a/external/libshell/tests/data/009-quote_shell_args-result b/external/libshell/tests/data/009-quote_shell_args-result
deleted file mode 100644
index 3551aca..0000000
--- a/external/libshell/tests/data/009-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[/bin/shell-* /bin/shell-[a-z]* /bin/shell-{error,getopt}]
diff --git a/external/libshell/tests/data/010-quote_shell_args-pattern b/external/libshell/tests/data/010-quote_shell_args-pattern
deleted file mode 100644
index e861ce6..0000000
--- a/external/libshell/tests/data/010-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-`echo $HOME` "`echo $HOME`" '`echo $HOME`' "(`echo $HOME`)"
diff --git a/external/libshell/tests/data/010-quote_shell_args-result b/external/libshell/tests/data/010-quote_shell_args-result
deleted file mode 100644
index 98ef34d..0000000
--- a/external/libshell/tests/data/010-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[`echo] [$HOME`] [`echo $HOME`] [`echo $HOME`] [(`echo $HOME`)]
diff --git a/external/libshell/tests/data/011-quote_shell_args-pattern b/external/libshell/tests/data/011-quote_shell_args-pattern
deleted file mode 100644
index 9701008..0000000
--- a/external/libshell/tests/data/011-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-echo |- echo;echo echo echo||echo "echo||echo" 'echo||echo'
diff --git a/external/libshell/tests/data/011-quote_shell_args-result b/external/libshell/tests/data/011-quote_shell_args-result
deleted file mode 100644
index 9b75bcd..0000000
--- a/external/libshell/tests/data/011-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[echo] [|-] [echo;echo] [echo] [echo||echo] [echo||echo] [echo||echo]
diff --git a/external/libshell/tests/data/012-quote_shell_args-pattern b/external/libshell/tests/data/012-quote_shell_args-pattern
deleted file mode 100644
index a63d458..0000000
--- a/external/libshell/tests/data/012-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-a b "c \\\" ' d" 'e " f'
diff --git a/external/libshell/tests/data/012-quote_shell_args-result b/external/libshell/tests/data/012-quote_shell_args-result
deleted file mode 100644
index 05edec3..0000000
--- a/external/libshell/tests/data/012-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[a] [b] [c \" ' d] [e " f]
diff --git a/external/libshell/tests/data/013-quote_shell_args-pattern b/external/libshell/tests/data/013-quote_shell_args-pattern
deleted file mode 100644
index d29c27d..0000000
--- a/external/libshell/tests/data/013-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-a b <<EOF "<<EOF" '<<EOF' <<'__EOF__' c
diff --git a/external/libshell/tests/data/013-quote_shell_args-result b/external/libshell/tests/data/013-quote_shell_args-result
deleted file mode 100644
index 93cb351..0000000
--- a/external/libshell/tests/data/013-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[a] [b] [<<EOF] [<<EOF] [<<EOF] [<<__EOF__] [c]
diff --git a/external/libshell/tests/data/014-quote_shell_args-pattern b/external/libshell/tests/data/014-quote_shell_args-pattern
deleted file mode 100644
index 3fd87ba..0000000
--- a/external/libshell/tests/data/014-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-a || b && c "&&" d '&&' e &
diff --git a/external/libshell/tests/data/014-quote_shell_args-result b/external/libshell/tests/data/014-quote_shell_args-result
deleted file mode 100644
index a4c53b3..0000000
--- a/external/libshell/tests/data/014-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[a] [||] [b] [&&] [c] [&&] [d] [&&] [e] [&]
diff --git a/external/libshell/tests/data/015-quote_shell_args-pattern b/external/libshell/tests/data/015-quote_shell_args-pattern
deleted file mode 100644
index bcaec60..0000000
--- a/external/libshell/tests/data/015-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-a ! b "! c" '!' d
diff --git a/external/libshell/tests/data/015-quote_shell_args-result b/external/libshell/tests/data/015-quote_shell_args-result
deleted file mode 100644
index 43a574f..0000000
--- a/external/libshell/tests/data/015-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[a] [!] [b] [! c] [!] [d]
diff --git a/external/libshell/tests/data/016-quote_shell_args-pattern b/external/libshell/tests/data/016-quote_shell_args-pattern
deleted file mode 100644
index c0e6470..0000000
--- a/external/libshell/tests/data/016-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-echo ~ "echo ~" 'echo ~'
diff --git a/external/libshell/tests/data/016-quote_shell_args-result b/external/libshell/tests/data/016-quote_shell_args-result
deleted file mode 100644
index 4f4670a..0000000
--- a/external/libshell/tests/data/016-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[echo] [~] [echo ~] [echo ~]
diff --git a/external/libshell/tests/data/017-quote_shell_args-pattern b/external/libshell/tests/data/017-quote_shell_args-pattern
deleted file mode 100644
index e07dfd1..0000000
--- a/external/libshell/tests/data/017-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-. /etc/passwd ". /etc/passwd"
diff --git a/external/libshell/tests/data/017-quote_shell_args-result b/external/libshell/tests/data/017-quote_shell_args-result
deleted file mode 100644
index 7c16fa6..0000000
--- a/external/libshell/tests/data/017-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[.] [/etc/passwd] [. /etc/passwd]
diff --git a/external/libshell/tests/data/018-quote_shell_args-pattern b/external/libshell/tests/data/018-quote_shell_args-pattern
deleted file mode 100644
index 1418321..0000000
--- a/external/libshell/tests/data/018-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-\\''
diff --git a/external/libshell/tests/data/018-quote_shell_args-result b/external/libshell/tests/data/018-quote_shell_args-result
deleted file mode 100644
index c147d78..0000000
--- a/external/libshell/tests/data/018-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[\]
diff --git a/external/libshell/tests/data/019-quote_shell_args-pattern b/external/libshell/tests/data/019-quote_shell_args-pattern
deleted file mode 100644
index a35d9d7..0000000
--- a/external/libshell/tests/data/019-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-\'
diff --git a/external/libshell/tests/data/019-quote_shell_args-result b/external/libshell/tests/data/019-quote_shell_args-result
deleted file mode 100644
index efa1f25..0000000
--- a/external/libshell/tests/data/019-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[']
diff --git a/external/libshell/tests/data/020-quote_shell_args-pattern b/external/libshell/tests/data/020-quote_shell_args-pattern
deleted file mode 100644
index 6bc83a6..0000000
--- a/external/libshell/tests/data/020-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-a\
diff --git a/external/libshell/tests/data/020-quote_shell_args-result b/external/libshell/tests/data/020-quote_shell_args-result
deleted file mode 100644
index fe51488..0000000
--- a/external/libshell/tests/data/020-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[]
diff --git a/external/libshell/tests/data/021-quote_shell_args-pattern b/external/libshell/tests/data/021-quote_shell_args-pattern
deleted file mode 100644
index bd91527..0000000
--- a/external/libshell/tests/data/021-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-1"22"333"4444
diff --git a/external/libshell/tests/data/021-quote_shell_args-result b/external/libshell/tests/data/021-quote_shell_args-result
deleted file mode 100644
index fe51488..0000000
--- a/external/libshell/tests/data/021-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[]
diff --git a/external/libshell/tests/data/022-quote_shell_args-pattern b/external/libshell/tests/data/022-quote_shell_args-pattern
deleted file mode 100644
index 6cd22b7..0000000
--- a/external/libshell/tests/data/022-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-1'22'333'4444
diff --git a/external/libshell/tests/data/022-quote_shell_args-result b/external/libshell/tests/data/022-quote_shell_args-result
deleted file mode 100644
index fe51488..0000000
--- a/external/libshell/tests/data/022-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[]
diff --git a/external/libshell/tests/data/023-quote_shell_args-pattern b/external/libshell/tests/data/023-quote_shell_args-pattern
deleted file mode 100644
index 032d059..0000000
--- a/external/libshell/tests/data/023-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-"\
diff --git a/external/libshell/tests/data/023-quote_shell_args-result b/external/libshell/tests/data/023-quote_shell_args-result
deleted file mode 100644
index fe51488..0000000
--- a/external/libshell/tests/data/023-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[]
diff --git a/external/libshell/tests/data/024-quote_shell_args-pattern b/external/libshell/tests/data/024-quote_shell_args-pattern
deleted file mode 100644
index 4196dc7..0000000
--- a/external/libshell/tests/data/024-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-'\' '\\'
diff --git a/external/libshell/tests/data/024-quote_shell_args-result b/external/libshell/tests/data/024-quote_shell_args-result
deleted file mode 100644
index 43ba0fc..0000000
--- a/external/libshell/tests/data/024-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[\] [\\]
diff --git a/external/libshell/tests/data/025-quote_shell_args-pattern b/external/libshell/tests/data/025-quote_shell_args-pattern
deleted file mode 100644
index bc1abfd..0000000
--- a/external/libshell/tests/data/025-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-"\"" "\\"
diff --git a/external/libshell/tests/data/025-quote_shell_args-result b/external/libshell/tests/data/025-quote_shell_args-result
deleted file mode 100644
index 1df8039..0000000
--- a/external/libshell/tests/data/025-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-["] [\]
diff --git a/external/libshell/tests/data/026-quote_shell_args-pattern b/external/libshell/tests/data/026-quote_shell_args-pattern
deleted file mode 100644
index a3e94b8..0000000
--- a/external/libshell/tests/data/026-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-\123 \xab \" \\ \a \b \c \d \e \f \n \r \t \v
diff --git a/external/libshell/tests/data/026-quote_shell_args-result b/external/libshell/tests/data/026-quote_shell_args-result
deleted file mode 100644
index 34687dd..0000000
--- a/external/libshell/tests/data/026-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[123] [xab] ["] [\] [a] [b] [c] [d] [e] [f] [n] [r] [t] [v]
diff --git a/external/libshell/tests/data/027-quote_shell_args-pattern b/external/libshell/tests/data/027-quote_shell_args-pattern
deleted file mode 100644
index ada69c1..0000000
--- a/external/libshell/tests/data/027-quote_shell_args-pattern
+++ /dev/null
@@ -1 +0,0 @@
-$'\n' $"\r"
diff --git a/external/libshell/tests/data/027-quote_shell_args-result b/external/libshell/tests/data/027-quote_shell_args-result
deleted file mode 100644
index ab66eb8..0000000
--- a/external/libshell/tests/data/027-quote_shell_args-result
+++ /dev/null
@@ -1 +0,0 @@
-[$\n] [$\r]
diff --git a/external/libshell/tests/fatal b/external/libshell/tests/fatal
deleted file mode 100644
index 7738f87..0000000
--- a/external/libshell/tests/fatal
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/ash -efu
-
-PROG='TEST'
-
-fatal_test1() { # UnitTest
-	. ../shell-error
-	expect="$PROG: message message;"
-	result=`fatal "message message" 2>&1 |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-fatal_test2() { # UnitTest
-	. ../shell-error
-	expect="$PROG: message;message;"
-	result=`fatal "message
-message" 2>&1 |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-fatal_test3() { # UnitTest
-	. ../shell-error
-	zzz=ZZZ
-	expect="$PROG: message ZZZ message;"
-	result=`fatal "message $zzz message" 2>&1 |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-fatal_test4() { # UnitTest
-	. ../shell-error
-	expect="$PROG: message message;"
-	result=`{ fatal "message message" 2>&1; echo "another message"; } |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
diff --git a/external/libshell/tests/fill_mask b/external/libshell/tests/fill_mask
deleted file mode 100644
index 9e07be4..0000000
--- a/external/libshell/tests/fill_mask
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/ash -efu
-
-fill_mask_test01() { # UnitTest
-	. ../shell-quote
-	local result string='1234567890'
-	fill_mask result "$string"
-	assertEquals "$string" "$result" "?????????"
-}
-
-fill_mask_test02() { # UnitTest
-	. ../shell-quote
-	local result string='1234567890123'
-	fill_mask result "$string"
-	assertEquals "$string" "$result" "????????????"
-}
-
-fill_mask_test03() { # UnitTest
-	. ../shell-quote
-	local result string='1234567890123'
-	fill_mask result "$string" 1
-	assertEquals "$string" "$result" "?????????????"
-}
-
-fill_mask_test04() { # UnitTest
-	. ../shell-quote
-	local result string='1'
-	fill_mask result "$string"
-	assertEquals "$string" "$result" ""
-}
-
-fill_mask_test05() { # UnitTest
-	. ../shell-quote
-	local result string='12'
-	fill_mask result "$string"
-	assertEquals "$string" "$result" "?"
-}
-
-fill_mask_test06() { # UnitTest
-	. ../shell-quote
-	local result string='123'
-	fill_mask result "$string"
-	assertEquals "$string" "$result" "??"
-}
diff --git a/external/libshell/tests/getopt b/external/libshell/tests/getopt
deleted file mode 100644
index b602487..0000000
--- a/external/libshell/tests/getopt
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/bin/ash -efu
-
-normalize() {
-	sed \
-		-e "s/\"/'/g" \
-		-e 's/[[:space:]]\+/ /g' \
-		-e 's/^[[:space:]]\+//' \
-		-e 's/[[:space:]]\+$//'
-}
-
-getopt_test001() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-getopt_test002() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o ' ' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o ' ' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-getopt_test003() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o '' -l ' ' -- ZZZ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o '' -l ' ' -- ZZZ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-
-getopt_test004() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o 'a,b,c' -- -abc -a -b -c ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o 'a,b,c' -- -abc -a -b -c ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-getopt_test005() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -abc --caa 'AAA' --cba='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -abc --caa 'AAA' --cba='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-getopt_test006() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- --cb 'AAA' --c='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- --cb 'AAA' --c='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-getopt_test007() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- --cbz 'AAA' --c='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- --cbz 'AAA' --c='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-getopt_test008() { # UnitTest
-	LANG=C
-	expect=`{ getopt -a -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -cb 'AAA' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -a -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -cb 'AAA' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-getopt_test009() { # UnitTest
-	LANG=C
-	expect=`{ getopt -a -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -c='AAA' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -a -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -c='AAA' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	(assertEquals "$result" "$result" "$expect") ||:
-	shouldSkip
-}
-
-getopt_test010() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -c='AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -c='AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	(assertEquals "$result" "$result" "$expect") ||:
-	shouldSkip
-}
-
-getopt_test011() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o 'a,b,c' -l 'abcd:,cbce:' -- --abcx 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o 'a,b,c' -l 'abcd:,cbce:' -- --abcx 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-getopt_test012() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o 'a:,b,c' -- -abc 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o 'a:,b,c' -- -abc 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-getopt_test013() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o 'a::,b,c' -- -a -bc 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o 'a::,b,c' -- -a -bc 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-getopt_test014() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- 'BBB' 'XXX ZZZ'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- 'BBB' 'XXX ZZZ'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-getopt_test015() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o '+a,b,c' -l 'caa:,cba:' -- --caa='AAA' 'BBB' --zzz -x; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o '+a,b,c' -l 'caa:,cba:' -- --caa='AAA' 'BBB' --zzz -x; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-
-getopt_test016() { # UnitTest
-	LANG=C
-	expect=`{ getopt -n TEST -o '-a,b,c' -l 'caa:,cba:' -- 'AAA' --caa='BBB' 'CCC'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	. ../shell-getopt
-	result=`{ getopt -n TEST -o '-a,b,c' -l 'caa:,cba:' -- 'AAA' --caa='BBB' 'CCC'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-getopt_test017() { # UnitTest
-	LANG=C
-	. ../shell-getopt
-	expect=' -a -b -- 
- -a -b -- 
- -a -b -- '
-	result=`for i in 1 2 3; do getopt -n TEST -o 'a,b' -- -ab; done 2>&1`
-	assertEquals "$result" "$result" "$expect"
-}
diff --git a/external/libshell/tests/ini-config/z.ini b/external/libshell/tests/ini-config/z.ini
deleted file mode 100644
index 967c5c4..0000000
--- a/external/libshell/tests/ini-config/z.ini
+++ /dev/null
@@ -1,12 +0,0 @@
-[global]
-	user= 	Foo Bar
-email = foo at bar
-
-[sect1]
-opt=OPT
-opt1=OPT1
-opt=OPT
-
-# Blah Blah
-[sect]
-opt="ZZZ XXX"
\ No newline at end of file
diff --git a/external/libshell/tests/ini_config_get b/external/libshell/tests/ini_config_get
deleted file mode 100644
index 7ccb269..0000000
--- a/external/libshell/tests/ini_config_get
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/ash -efu
-
-ini_config_get_test1() { # UnitTest
-	. ../shell-ini-config
-	local result expect="Foo Bar"
-	result="$(ini_config_get ini-config/z.ini global user)"
-	assertEquals "$result" "$result" "$expect"
-}
-
-ini_config_get_test2() { # UnitTest
-	. ../shell-ini-config
-	local result expect="foo at bar"
-	result="$(ini_config_get ini-config/z.ini global email)"
-	assertEquals "$result" "$result" "$expect"
-}
-
-ini_config_get_test3() { # UnitTest
-	. ../shell-ini-config
-	local result expect="\"ZZZ XXX\""
-	result="$(ini_config_get ini-config/z.ini sect opt)"
-	assertEquals "$result" "$result" "$expect"
-}
diff --git a/external/libshell/tests/ini_config_set b/external/libshell/tests/ini_config_set
deleted file mode 100644
index bb46e35..0000000
--- a/external/libshell/tests/ini_config_set
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/ash -efu
-
-ini_config_set_test1() { # UnitTest
-	. ../shell-ini-config
-	local result expect="Aaa Bbb"
-	cp -f ini-config/z.ini ini-config/t1.ini
-
-	ini_config_set ini-config/t1.ini global user "$expect"
-
-	result="$(ini_config_get ini-config/t1.ini global user)"
-	assertEquals "$result" "$result" "$expect"
-}
-
-ini_config_set_test2() { # UnitTest
-	. ../shell-ini-config
-	local result expect='$1 \n\1 "Bbb"'
-	cp -f ini-config/z.ini ini-config/t2.ini
-
-	ini_config_set ini-config/t2.ini global user "$expect"
-
-	result="$(ini_config_get ini-config/t2.ini global user)"
-	assertEquals "$result" "$result" "$expect"
-}
-
-ini_config_set_test3() { # UnitTest
-	. ../shell-ini-config
-	local result expect='XXX'
-	cp -f ini-config/z.ini ini-config/t3.ini
-
-	ini_config_del ini-config/t3.ini global user
-	ini_config_set ini-config/t3.ini global user "$expect"
-
-	result="$(ini_config_get ini-config/t3.ini global user)"
-	assertEquals "$result" "$result" "$expect"
-}
-
-ini_config_set_test4() { # UnitTest
-	. ../shell-ini-config
-	local result expect='XXX'
-	cp -f ini-config/z.ini ini-config/t4.ini
-
-	ini_config_comment ini-config/t4.ini global user
-	ini_config_set ini-config/t4.ini global user "$expect"
-
-	result="$(ini_config_get ini-config/t4.ini global user)"
-	assertEquals "$result" "$result" "$expect"
-}
-
-ini_config_set_test5() { # UnitTest
-	. ../shell-ini-config
-	local result expect='ZZZ'
-	cp -f ini-config/z.ini ini-config/t5.ini
-
-	ini_config_set ini-config/t5.ini sect1 opt "$expect"
-
-	result="$(ini_config_get ini-config/t5.ini sect1 opt)"
-	assertEquals "$result" "$result" "$expect"
-}
diff --git a/external/libshell/tests/message b/external/libshell/tests/message
deleted file mode 100644
index b4ae2c0..0000000
--- a/external/libshell/tests/message
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/ash -efu
-
-PROG='TEST'
-
-message_test1() { # UnitTest
-	. ../shell-error
-	expect="$PROG: message message;"
-	result=`message "message message" 2>&1 |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-message_test2() { # UnitTest
-	. ../shell-error
-	expect="$PROG: message;message;"
-	result=`message "message
-message" 2>&1 |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-message_test3() { # UnitTest
-	. ../shell-error
-	zzz=ZZZ
-	expect="$PROG: message ZZZ message;"
-	result=`message "message $zzz message" 2>&1 |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-message_test4() { # UnitTest
-	. ../shell-error
-	expect="$PROG: message message;another message;"
-	result=`{ message "message message" 2>&1; echo "another message"; } |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
diff --git a/external/libshell/tests/opt_check_dir b/external/libshell/tests/opt_check_dir
deleted file mode 100644
index c2a20e6..0000000
--- a/external/libshell/tests/opt_check_dir
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/ash -efu
-
-opt_check_dir_test1() { # UnitTest
-	. ../shell-args
-
-	[ -d "$WORKDIR/dir-644" ] ||
-		mkdir -m644 "$WORKDIR/dir-644"
-	cd "$WORKDIR"
-
-	expect="$(message "DIR: ./dir-644: directory not available." 2>&1)"
-	result="$(opt_check_dir "DIR" "./dir-644" 2>&1)" ||:
-	rmdir "dir-644"
-
-	assertEquals "$result" "$result" "$expect"
-}
-
-opt_check_dir_test2() { # UnitTest
-	. ../shell-args
-
-	[ -d "$WORKDIR/dir-755" ] ||
-		mkdir -m755 "$WORKDIR/dir-755"
-	cd "$WORKDIR"
-
-	expect="$(readlink -ev ./dir-755 2>&1)" ||:
-	result="$(opt_check_dir "DIR" "./dir-755" 2>&1)" ||:
-	rmdir "dir-755"
-
-	assertEquals "$result" "$result" "$expect"
-}
diff --git a/external/libshell/tests/opt_check_number b/external/libshell/tests/opt_check_number
deleted file mode 100644
index 54d48d8..0000000
--- a/external/libshell/tests/opt_check_number
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/ash -efu
-
-opt_check_number_test1() { # UnitTest
-	. ../shell-args
-
-	string="1234"
-	expect="1234"
-	result="$(opt_check_number "NUM" "$string" 2>&1)" ||:
-
-	assertEquals "$result" "$result" "$expect"
-}
-
-opt_check_number_test2() { # UnitTest
-	. ../shell-args
-
-	string="0001"
-	expect="$(message "NUM: $string: invalid number." 2>&1)"
-	result="$(opt_check_number "NUM" "$string" 2>&1)" ||:
-
-	assertEquals "$result" "$result" "$expect"
-}
-
-opt_check_number_test3() { # UnitTest
-	. ../shell-args
-
-	string="1 2"
-	expect="$(message "NUM: $string: invalid number." 2>&1)"
-	result="$(opt_check_number "NUM" "$string" 2>&1)" ||:
-
-	assertEquals "$result" "$result" "$expect"
-}
diff --git a/external/libshell/tests/opt_check_read b/external/libshell/tests/opt_check_read
deleted file mode 100644
index c1d5297..0000000
--- a/external/libshell/tests/opt_check_read
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/ash -efu
-
-opt_check_read_test1() { # UnitTest
-	. ../shell-args
-
-	if [ ! -f "$WORKDIR/file-000" ]; then
-		> "$WORKDIR/file-000"
-		chmod 000 "$WORKDIR/file-000"
-	fi
-	cd "$WORKDIR"
-
-	expect="$(message "FILE: ./file-000: file not available." 2>&1)"
-	result="$(opt_check_read "FILE" "./file-000" 2>&1)" ||:
-
-	assertEquals "$result" "$result" "$expect"
-}
-opt_check_read_test2() { # UnitTest
-	. ../shell-args
-
-	if [ ! -f "$WORKDIR/file-200" ]; then
-		> "$WORKDIR/file-200"
-		chmod 200 "$WORKDIR/file-200"
-	fi
-	cd "$WORKDIR"
-
-	expect="$(message "FILE: ./file-200: file not available." 2>&1)"
-	result="$(opt_check_read "FILE" "./file-200" 2>&1)" ||:
-
-	assertEquals "$result" "$result" "$expect"
-}
-
-opt_check_read_test3() { # UnitTest
-	. ../shell-args
-
-	if [ ! -f "$WORKDIR/file-644" ]; then
-		> "$WORKDIR/file-644"
-		chmod 644 "$WORKDIR/file-644"
-	fi
-	cd "$WORKDIR"
-
-	expect="$(readlink -ev ./file-644)"
-	result="$(opt_check_read "FILE" "./file-644" 2>&1)" ||:
-
-	assertEquals "$result" "$result" "$expect"
-}
-
-opt_check_read_test4() { # UnitTest
-	. ../shell-args
-
-	if [ ! -e "$WORKDIR/broken-symlink" ]; then
-		ln -s "$WORKDIR/broken-symlink" "$WORKDIR/broken-symlink"
-	fi
-	cd "$WORKDIR"
-
-	expect="$(message "FILE: ./broken-symlink: file not available." 2>&1)"
-	result="$(opt_check_read "FILE" "./broken-symlink" 2>&1)" ||:
-
-	assertEquals "$result" "$result" "$expect"
-}
diff --git a/external/libshell/tests/quote_sed_regexp b/external/libshell/tests/quote_sed_regexp
deleted file mode 100644
index 19e42b2..0000000
--- a/external/libshell/tests/quote_sed_regexp
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/ash -efu
-
-quote_sed_regexp_test1() { # UnitTest
-	. ../shell-quote
-	local string='.*'
-	local regexp="$(quote_sed_regexp "$string")"
-	local result="$(printf '%s\n' "$string passed" |sed -e "s/^$regexp/test/")"
-	assertEquals "$string" "$result" 'test passed'
-}
-
-quote_sed_regexp_test2() { # UnitTest
-	. ../shell-quote
-	local string='[[:space:]]'
-	local regexp="$(quote_sed_regexp "$string")"
-	local result="$(printf '%s\n' "test $string" |sed -e "s/$regexp/passed/")"
-	assertEquals "$string" "$result" 'test passed'
-}
-
-quote_sed_regexp_test3() { # UnitTest
-	. ../shell-quote
-	local string='t{1,3}'
-	local regexp="$(quote_sed_regexp "$string")"
-	local result="$(printf '%s\n' "test$string passed" |sed -e "s/$regexp//")"
-	assertEquals "$string" "$result" 'test passed'
-}
-
-quote_sed_regexp_test4() { # UnitTest
-	. ../shell-quote
-	local string='&\1'
-	local regexp="$(quote_sed_regexp "$string")"
-	local result="$(printf '%s\n' "test not passed" |sed -e "s/\(not\)/$regexp/")" #"
-	assertEquals "$string" "$result" 'test &\1 passed'
-}
diff --git a/external/libshell/tests/quote_sed_regexp_variable b/external/libshell/tests/quote_sed_regexp_variable
deleted file mode 100644
index 6d227c6..0000000
--- a/external/libshell/tests/quote_sed_regexp_variable
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/ash -efu
-
-quote_sed_regexp_variable_test1() { # UnitTest
-	. ../shell-quote
-	local string='.*'
-	local regexp
-	quote_sed_regexp_variable regexp "$string"
-	local result="$(printf '%s\n' "$string passed" |sed -e "s/^$regexp/test/")"
-	assertEquals "$string" "$result" 'test passed'
-}
-
-quote_sed_regexp_variable_test2() { # UnitTest
-	. ../shell-quote
-	local string='[[:space:]]'
-	local regexp
-	quote_sed_regexp_variable regexp "$string"
-	local result="$(printf '%s\n' "test $string" |sed -e "s/$regexp/passed/")"
-	assertEquals "$string" "$result" 'test passed'
-}
-
-quote_sed_regexp_variable_test3() { # UnitTest
-	. ../shell-quote
-	local string='t{1,3}'
-	local regexp
-	quote_sed_regexp_variable regexp "$string"
-	local result="$(printf '%s\n' "test$string passed" |sed -e "s/$regexp//")"
-	assertEquals "$string" "$result" 'test passed'
-}
-
-quote_sed_regexp_variable_test4() { # UnitTest
-	. ../shell-quote
-	local string='&\1'
-	local regexp
-	quote_sed_regexp_variable regexp "$string"
-	local result="$(printf '%s\n' "test not passed" |sed -e "s/\(not\)/$regexp/")" #"
-	assertEquals "$string" "$result" 'test &\1 passed'
-}
diff --git a/external/libshell/tests/quote_shell b/external/libshell/tests/quote_shell
deleted file mode 100644
index 2a81947..0000000
--- a/external/libshell/tests/quote_shell
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/ash -efu
-
-quote_shell_test1() { # UnitTest
-	. ../shell-quote
-	local string='`true`'
-	local result
-	eval "result=\"$(quote_shell "$string")\""
-	assertEquals "$string" "$result" "$string"
-}
-
-quote_shell_test2() { # UnitTest
-	. ../shell-quote
-	local string='$(true)'
-	local result
-	eval "result=\"$(quote_shell "$string")\""
-	assertEquals "$string" "$result" "$string"
-}
-
-quote_shell_test3() { # UnitTest
-	. ../shell-quote
-	local string='\`true\`; echo zzz'
-	local result
-	eval "result=\"$(quote_shell "$string")\""
-	assertEquals "$string" "$result" "$string"
-}
diff --git a/external/libshell/tests/quote_shell_args b/external/libshell/tests/quote_shell_args
deleted file mode 100644
index ca0cead..0000000
--- a/external/libshell/tests/quote_shell_args
+++ /dev/null
@@ -1,379 +0,0 @@
-#!/bin/ash -efu
-
-PROG='TEST'
-
-quote_process() {
-	local opts=
-        quote_shell_args opts "$1" &&
-                eval "set -- $opts" ||:
-
-        local a= result=
-        for a; do
-                result="$result[$a] "
-        done
-        printf '%s\n' "${result% }"
-}
-
-quote_shell_args_test_000() { # UnitTest
-	local num=000
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_001() { # UnitTest
-	local num=001
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_002() { # UnitTest
-	local num=002
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_003() { # UnitTest
-	local num=003
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_004() { # UnitTest
-	local num=001
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_005() { # UnitTest
-	local num=005
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_006() { # UnitTest
-	local num=006
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_007() { # UnitTest
-	local num=007
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_008() { # UnitTest
-	local num=008
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_009() { # UnitTest
-	local num=009
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_010() { # UnitTest
-	local num=010
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_011() { # UnitTest
-	local num=011
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_012() { # UnitTest
-	local num=012
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_013() { # UnitTest
-	local num=013
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_014() { # UnitTest
-	local num=014
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_015() { # UnitTest
-	local num=015
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_016() { # UnitTest
-	local num=016
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_017() { # UnitTest
-	local num=017
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_018() { # UnitTest
-	local num=018
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_019() { # UnitTest
-	local num=019
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_020() { # UnitTest
-	local num=020
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1 |tr '\n' ' ')"
-
-	assertEquals "$result" 'TEST: unmatched character (\) found [a\] ' "$result"
-}
-
-quote_shell_args_test_021() { # UnitTest
-	local num=021
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1 |tr '\n' ' ')"
-
-	assertEquals "$result" 'TEST: unmatched character (") found [1"22"333"4444] ' "$result"
-}
-
-quote_shell_args_test_022() { # UnitTest
-	local num=022
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1 |tr '\n' ' ')"
-
-	assertEquals "$result" "TEST: unmatched character (') found [1'22'333'4444] " "$result"
-}
-
-quote_shell_args_test_023() { # UnitTest
-	local num=023
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1 |tr '\n' ' ')"
-
-	assertEquals "$result" 'TEST: unmatched character (\") found ["\] ' "$result"
-}
-
-quote_shell_args_test_024() { # UnitTest
-	local num=024
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_025() { # UnitTest
-	local num=025
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_026() { # UnitTest
-	local num=026
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
-
-quote_shell_args_test_027() { # UnitTest
-	local num=027
-
-	. ../shell-error
-	. ../shell-quote
-
-	local input="$(cat ./data/$num-quote_shell_args-pattern)"
-	local expect="$(cat ./data/$num-quote_shell_args-result)"
-	local result="$(quote_process "$input" 2>&1)"
-
-	assertEquals "$result" "$expect" "$result"
-}
diff --git a/external/libshell/tests/quote_shell_variable b/external/libshell/tests/quote_shell_variable
deleted file mode 100644
index 90008a5..0000000
--- a/external/libshell/tests/quote_shell_variable
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/ash -efu
-
-quote_shell_variable_test1() { # UnitTest
-	. ../shell-quote
-	local string='`true`' expect='\`true\`'
-	local result
-	quote_shell_variable result "$string"
-	assertEquals "$string" "$result" "$expect"
-}
-
-quote_shell_variable_test2() { # UnitTest
-	. ../shell-quote
-	local string='$(true)' expect='\$(true)'
-	local result
-	quote_shell_variable result "$string"
-	assertEquals "$string" "$result" "$expect"
-}
-
-quote_shell_variable_test3() { # UnitTest
-	. ../shell-quote
-	local string='\`true\`; echo zzz' expect='\\\`true\\\`; echo zzz'
-	local result
-	quote_shell_variable result "$string"
-	assertEquals "$string" "$result" "$expect"
-}
diff --git a/external/libshell/tests/runtests b/external/libshell/tests/runtests
deleted file mode 100755
index cc5e073..0000000
--- a/external/libshell/tests/runtests
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh -efu
-
-srcdir="$(readlink -ev ..)"
-export PATH="$srcdir:$PATH"
-
-. ../shell-unittest
-
-WORKDIR=
-setUpTests() {
-	WORKDIR="$(mktemp -d "$PROG.XXXXXXXXX")"
-}
-
-tearDownTests() {
-	rm -rf -- "$WORKDIR"
-}
-
-for s in \
-	quote_sed_regexp quote_shell string_quote_remove \
-	opt_check_dir opt_check_number opt_check_read \
-	quote_sed_regexp_variable quote_shell_variable \
-	getopt signal \
-	fatal message verbose \
-	quote_shell_args \
-	ini_config_get ini_config_set \
-	shell_var_unquote shell_var_trim \
-	fill_mask \
-	cmdline_get \
-	;
-do
-	. "./$s"
-	registerTests "./$s"
-done
-
-runUnitTests
diff --git a/external/libshell/tests/shell_var_trim b/external/libshell/tests/shell_var_trim
deleted file mode 100644
index 5786521..0000000
--- a/external/libshell/tests/shell_var_trim
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-
-shell_var_trim_test1() { # UnitTest
-	. ../shell-var
-
-	local result string='test'
-	shell_var_trim result "$string"
-	assertEquals "$string" "$result" 'test'
-}
-
-shell_var_trim_test2() { # UnitTest
-	. ../shell-var
-
-	local result string='test   '
-	shell_var_trim result "$string"
-	assertEquals "$string" "$result" 'test'
-}
-
-shell_var_trim_test3() { # UnitTest
-	. ../shell-var
-
-	local result string='test	
-        '
-	shell_var_trim result "$string"
-	assertEquals "$string" "$result" 'test'
-}
-
-shell_var_trim_test4() { # UnitTest
-	. ../shell-var
-
-	local result string='	   test 	 test	
-        '
-	shell_var_trim result "$string"
-	assertEquals "$string" "$result" 'test 	 test'
-}
-
-shell_var_trim_test5() { # UnitTest
-	. ../shell-var
-
-	local result string=' " test " '
-	shell_var_trim result "$string"
-	assertEquals "$string" "$result" '" test "'
-}
diff --git a/external/libshell/tests/shell_var_unquote b/external/libshell/tests/shell_var_unquote
deleted file mode 100644
index 627e999..0000000
--- a/external/libshell/tests/shell_var_unquote
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-
-shell_var_unquote_test1() { # UnitTest
-	. ../shell-var
-
-	local result string='"test passed"'
-	shell_var_unquote result "$string"
-	assertEquals "$string" "$result" 'test passed'
-}
-
-shell_var_unquote_test2() { # UnitTest
-	. ../shell-var
-
-	local result string="'test passed'"
-	shell_var_unquote result "$string"
-	assertEquals "$string" "$result" 'test passed'
-}
-
-shell_var_unquote_test3() { # UnitTest
-	. ../shell-var
-
-	local result string="'test passed\""
-	shell_var_unquote result "$string"
-	assertEquals "$string" "$result" "'test passed\""
-}
-
-shell_var_unquote_test4() { # UnitTest
-	. ../shell-var
-
-	local result string="test ' passed"
-	shell_var_unquote result "$string"
-	assertEquals "$string" "$result" "test ' passed"
-}
diff --git a/external/libshell/tests/signal b/external/libshell/tests/signal
deleted file mode 100644
index ef61cf7..0000000
--- a/external/libshell/tests/signal
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/ash -efu
-
-PROG='TEST'
-__libshell_experimental=1
-
-signal_test_handler() {
-	printf '%s\n' "$PROG: signal_test_handler() called"
-}
-
-signal_test1() { # UnitTest
-	expect="EXIT-0"
-	result=$(./signal-data/001-signal)
-	assertEquals "$result" "$result" "$expect"
-}
-
-signal_test2() { # UnitTest
-	expect="INT-2"
-	result=$(./signal-data/002-signal)
-	assertEquals "$result" "$result" "$expect"
-}
-
-signal_test3() { # UnitTest
-	expect="EXIT-0
-EXIT-0"
-	result=$(./signal-data/003-signal)
-	assertEquals "$result" "$result" "$expect"
-}
-
-signal_test4() { # UnitTest
-	expect="BAR1
-BAR2"
-	result=$(./signal-data/004-signal)
-	assertEquals "$result" "$result" "$expect"
-}
-
-signal_test5() { # UnitTest
-	expect="EXIT-5"
-	result=$(./signal-data/005-signal) ||:
-	assertEquals "$result" "$result" "$expect"
-}
-
-signal_test6() { # UnitTest
-	expect="Got 5"
-	result=$(./signal-data/006-signal) ||:
-	assertEquals "$result" "$result" "$expect"
-}
-
-signal_test7() { # UnitTest
-	expect=""
-	result=$(./signal-data/007-signal) ||:
-	assertEquals "$result" "$result" "$expect"
-}
diff --git a/external/libshell/tests/signal-data/001-signal b/external/libshell/tests/signal-data/001-signal
deleted file mode 100755
index b5c12ef..0000000
--- a/external/libshell/tests/signal-data/001-signal
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh -efu
-. ../shell-signal
-signal_handler 'echo EXIT-$?' EXIT HUP;
diff --git a/external/libshell/tests/signal-data/002-signal b/external/libshell/tests/signal-data/002-signal
deleted file mode 100755
index 028e72e..0000000
--- a/external/libshell/tests/signal-data/002-signal
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh -efu
-. ../shell-signal
-signal_handler 'echo INT-2' INT
-/bin/kill -INT $$
diff --git a/external/libshell/tests/signal-data/003-signal b/external/libshell/tests/signal-data/003-signal
deleted file mode 100755
index 4331db1..0000000
--- a/external/libshell/tests/signal-data/003-signal
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh -efu
-. ../shell-signal
-signal_handler 'echo EXIT-$?' TERM EXIT HUP;
-signal_handler 'echo EXIT-$?' TERM EXIT HUP;
diff --git a/external/libshell/tests/signal-data/004-signal b/external/libshell/tests/signal-data/004-signal
deleted file mode 100755
index 346dd30..0000000
--- a/external/libshell/tests/signal-data/004-signal
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh -efu
-. ../shell-signal
-signal_handler 'echo FOO1' USR2;
-signal_handler 'echo FOO2' USR2;
-signal_handler 'echo BAR1' USR1;
-signal_handler 'echo BAR2' USR1;
-signal_handler 'echo BAZ1' TERM;
-signal_handler 'echo BAZ2' TERM;
-/bin/kill -USR1 $$
diff --git a/external/libshell/tests/signal-data/005-signal b/external/libshell/tests/signal-data/005-signal
deleted file mode 100755
index 39cc7f4..0000000
--- a/external/libshell/tests/signal-data/005-signal
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh -efu
-. ../shell-signal
-signal_handler 'echo EXIT-$?' EXIT;
-exit 5
diff --git a/external/libshell/tests/signal-data/006-signal b/external/libshell/tests/signal-data/006-signal
deleted file mode 100755
index 5c0f94f..0000000
--- a/external/libshell/tests/signal-data/006-signal
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh -efu
-. ../shell-signal
-
-myhand() {
-	echo "Got $1"
-}
-
-set_cleanup_handler myhand;
-exit 5
-
diff --git a/external/libshell/tests/signal-data/007-signal b/external/libshell/tests/signal-data/007-signal
deleted file mode 100755
index 21b8a8d..0000000
--- a/external/libshell/tests/signal-data/007-signal
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh -efu
-. ../shell-signal
-
-myhand() {
-	echo "Got $1"
-}
-
-set_cleanup_handler myhand;
-unset_cleanup_handler;
-exit 5
-
diff --git a/external/libshell/tests/string_quote_remove b/external/libshell/tests/string_quote_remove
deleted file mode 100644
index 6025be2..0000000
--- a/external/libshell/tests/string_quote_remove
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-
-string_quote_remove_test1() { # UnitTest
-	. ../shell-quote
-
-	local string='"test passed"'
-	local result="$(string_quote_remove "$string")"
-	assertEquals "$string" "$result" 'test passed'
-}
-
-string_quote_remove_test2() { # UnitTest
-	. ../shell-quote
-
-	local string="'test passed'"
-	local result="$(string_quote_remove "$string")"
-	assertEquals "$string" "$result" 'test passed'
-}
-
-string_quote_remove_test3() { # UnitTest
-	. ../shell-quote
-
-	local string="'test passed\""
-	local result="$(string_quote_remove "$string")"
-	assertEquals "$string" "$result" "'test passed\""
-}
-
-string_quote_remove_test4() { # UnitTest
-	. ../shell-quote
-
-	local string="test ' passed"
-	local result="$(string_quote_remove "$string")"
-	assertEquals "$string" "$result" "test ' passed"
-}
diff --git a/external/libshell/tests/verbose b/external/libshell/tests/verbose
deleted file mode 100644
index af8cee3..0000000
--- a/external/libshell/tests/verbose
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/ash -efu
-
-PROG='TEST'
-
-verbose_test1() { # UnitTest
-	. ../shell-error
-	verbose=1
-	expect="$PROG: message message;"
-	result=`verbose "message message" 2>&1 |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
-
-verbose_test2() { # UnitTest
-	. ../shell-error
-	verbose=
-	expect=
-	result=`verbose "message message" 2>&1 |tr '\n' ';'`
-	assertEquals "$result" "$result" "$expect"
-}
diff --git a/external/remap-log.c b/external/remap-log.c
deleted file mode 100644
index 518e003..0000000
--- a/external/remap-log.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * Copyright (c) 2006, Al Viro.  All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-char *prefix1 = "a/", *prefix2 = "b/";
-char *old_prefix = "O:";
-char *user_pattern;
-
-char *line;
-
-void die(char *s)
-{
-	fprintf(stderr, "remap: %s\n", s);
-	exit(1);
-}
-
-void Enomem(void)
-{
-	die("out of memory");
-}
-
-void Eio(void)
-{
-	die("IO error");
-}
-
-enum {SIZE = 4096};
-
-char *buffer;
-int get_line(int fd)
-{
-	static char *end, *end_buffer, *next;
-	static size_t size;
-	ssize_t count;
-
-	if (!buffer) {
-		next = end = buffer = malloc(size = SIZE);
-		if (!buffer)
-			Enomem();
-		end_buffer = buffer + SIZE;
-	}
-	line = next;
-
-	while (1) {
-		if (next < end) {
-			next = memchr(next, '\n', end - next);
-			if (next) {
-				*next++ = '\0';
-				return 1;
-			}
-		}
-		if (end == end_buffer) {
-			size_t n = line - buffer;
-			if (n >= SIZE) {
-				n -= n % SIZE;
-				memmove(line - n, line, end - line);
-				line -= n;
-				end -= n;
-			} else {
-				char *p = malloc(size *= 2);
-				if (!p)
-					Enomem();
-				memcpy(p + n, line, end - line);
-				line = p + n;
-				end = p + (end - buffer);
-				free(buffer);
-				buffer = p;
-				end_buffer = p + size;
-			}
-		}
-		next = end;
-		count = read(fd, end, end_buffer - end);
-		if (!count)
-			break;
-		if (count < 0)
-			Eio();
-		end += count;
-	}
-
-	*end = '\0';
-	return line != end;
-}
-
-/* to == 0 -> deletion */
-struct range_map {
-	int from, to;
-};
-
-struct file_map {
-	char *name;
-	size_t name_len;
-	struct file_map *next;
-	char *new_name;
-	int count;
-	int allocated;
-	int last;
-	struct range_map ranges[];
-};
-
-struct file_map *alloc_map(char *name)
-{
-	struct file_map *map;
-
-	map = malloc(sizeof(struct file_map) + 16 * sizeof(struct range_map));
-	if (!map)
-		Enomem();
-	map->name_len = strlen(name);
-	map->name = map->new_name = malloc(map->name_len + 1);
-	if (!map->name)
-		Enomem();
-	memcpy(map->name, name, map->name_len + 1);
-	map->count = 0;
-	map->allocated = 16;
-	map->next = NULL;
-	map->last = 0;
-	return map;
-}
-
-/* this is 32bit FNV1 */
-uint32_t FNV_hash(char *name, size_t len)
-{
-	uint32_t n = 0x811c9dc5;
-	while (len--) {
-		unsigned char c = *name++;
-		n *= 0x01000193;
-		n ^= c;
-	}
-	return n;
-}
-
-struct file_map *hash[1024];
-
-int hash_map(struct file_map *map)
-{
-	size_t len = map->name_len;
-	char *name = map->name;
-	int n = FNV_hash(name, len) % 1024;
-	struct file_map **p = &hash[n];
-
-	while (*p) {
-		if ((*p)->name_len == len && !memcmp((*p)->name, name, len))
-			return 0;
-		p = &(*p)->next;
-	}
-	*p = map;
-	if (map->new_name && !map->count)
-		return 0;
-	if (map->new_name && map->ranges[0].from != 1)
-		return 0;
-	return 1;
-}
-
-struct file_map *find_map(char *name, size_t len)
-{
-	static struct file_map *last = NULL;
-	int n = FNV_hash(name, len) % 1024;
-	struct file_map *p;
-
-	if (last && last->name_len == len && !memcmp(last->name, name, len))
-		return last;
-
-	for (p = hash[n]; p; p = p->next)
-		if (p->name_len == len && !memcmp(p->name, name, len))
-			break;
-	if (p)
-		last = p;
-	return p;
-}
-
-void parse_map(char *name)
-{
-	struct file_map *map = NULL;
-	struct range_map *range;
-	char *s;
-	int fd;
-
-	fd = open(name, O_RDONLY);
-	if (fd < 0)
-		die("can't open map");
-	while (get_line(fd)) {
-		if (line[0] == 'D') {
-			if (map && !hash_map(map))
-				goto Ebadmap;
-			if (line[1] != ' ')
-				goto Ebadmap;
-			if (strchr(line + 2, ' '))
-				goto Ebadmap;
-			map = alloc_map(line + 2);
-			map->new_name = NULL;
-			continue;
-		}
-		if (line[0] == 'M') {
-			if (map && !hash_map(map))
-				goto Ebadmap;
-			if (line[1] != ' ')
-				goto Ebadmap;
-			s = strchr(line + 2, ' ');
-			if (!s)
-				goto Ebadmap;
-			*s++ = '\0';
-			if (strchr(s, ' '))
-				goto Ebadmap;
-			map = alloc_map(line + 2);
-			if (strcmp(line + 2, s)) {
-				map->new_name = strdup(s);
-				if (!map->new_name)
-					Enomem();
-			}
-			continue;
-		}
-		if (!map || !map->new_name)
-			goto Ebadmap;
-		if (map->count == map->allocated) {
-			int n = 2 * map->allocated;
-			map = realloc(map, sizeof(struct file_map) +
-					   n * sizeof(struct range_map));
-			if (!map)
-				Enomem();
-			map->allocated = n;
-		}
-		range = &map->ranges[map->count++];
-		if (sscanf(line, "%d %d%*c", &range->from, &range->to) != 2)
-			goto Ebadmap;
-		if (range > map->ranges && range->from <= range[-1].from)
-			goto Ebadmap;
-	}
-	if (map && !hash_map(map))
-		goto Ebadmap;
-	close(fd);
-	return;
-Ebadmap:
-	die("bad map");
-}
-
-struct range_map *find_range(struct file_map *map, int l)
-{
-	struct range_map *range = &map->ranges[map->last];
-	struct range_map *p;
-
-	if (range->from <= l) {
-		p = &map->ranges[map->count - 1];
-		if (p->from > l) {
-			for (p = range; p->from <= l; p++)
-				;
-			p--;
-		}
-	} else {
-		for (p = map->ranges; p->from <= l; p++)
-			;
-		p--;
-	}
-	map->last = p - map->ranges;
-	return p;
-}
-
-char *strnstr(char *haystack, char *needle, ssize_t len)
-{
-	ssize_t nl = strlen(needle), i;
-
-	for (i = 0; i <= len - nl; i++) {
-		if (!memcmp(haystack + i, needle, nl))
-			return haystack + i;
-	}
-
-	return NULL;
-}
-
-void map_pattern(char *patt, char *start, char *end, struct file_map *map)
-{
-	size_t plen = strlen(patt);
-
-	while (end > start) {
-		struct range_map *range;
-		unsigned long l;
-		char *s, *more;
-
-		s = strnstr(start, patt, end - start);
-		if (!s)
-			break;
-
-		s += plen;
-		printf("%.*s", (int)(s - start), start);
-		start = s;
-
-		l = strtoul(s, &more, 10);
-		if (more == s || !l || l > INT_MAX)
-			continue;
-
-		if (map->new_name && (range = find_range(map, l))->to)
-			l += range->to - range->from;
-
-		printf("%lu", l);
-		start = s = more;
-	}
-
-	printf("%.*s", (int)(end - start), start);
-}
-
-void mapline(char *patt)
-{
-	char *s = line, *start = line, *end = line - 1, *sp = line - 1;
-	struct file_map *last_mapped = NULL;
-
-	while (1) {
-		struct file_map *map;
-		struct range_map *range;
-		unsigned long l;
-		char *more;
-
-		end = strchr(end + 1, ':');
-		if (!end)
-			break;
-
-		if (sp < s)
-			sp = strchr(s, ' ');
-
-		while (sp && sp < end) {
-			s = sp + 1;
-			sp = strchr(s , ' ');
-		}
-
-		l = strtoul(end + 1, &more, 10);
-		if (more == end + 1 || !l || l > INT_MAX)
-			continue;
-
-		map = find_map(s, end - s);
-		if (!map)
-			continue;
-
-		if (patt)
-			map_pattern(patt, start, s, map);
-
-		if (map->new_name && (range = find_range(map, l))->to) {
-			l += range->to - range->from;
-			printf("%s:%lu", map->new_name, l);
-		} else {
-			printf("%s%.*s", old_prefix, (int)(more - s), s);
-		}
-		start = s = more;
-		last_mapped = map;
-	}
-
-	if (patt && start != line)
-		map_pattern(patt, start, start + strlen(start), last_mapped);
-	else
-		printf("%s", start);
-
-	printf("\n");
-}
-
-int parse_hunk(int *l1, int *l2, int *n1, int *n2)
-{
-	unsigned long n;
-	char *s, *p;
-	if (line[3] != '-')
-		return 0;
-	n = strtoul(line + 4, &s, 10);
-	if (s == line + 4 || n > INT_MAX)
-		return 0;
-	*l1 = n;
-	if (*s == ',') {
-		n = strtoul(s + 1, &p, 10);
-		if (p == s + 1 || n > INT_MAX)
-			return 0;
-		*n1 = n;
-		if (!n)
-			(*l1)++;
-	} else {
-		p = s;
-		*n1 = 1;
-	}
-	if (*p != ' ' || p[1] != '+')
-		return 0;
-	n = strtoul(p + 2, &s, 10);
-	if (s == p + 2 || n > INT_MAX)
-		return 0;
-	*l2 = n;
-	if (*s == ',') {
-		n = strtoul(s + 1, &p, 10);
-		if (p == s + 1 || n > INT_MAX)
-			return 0;
-		*n2 = n;
-		if (!n)
-			(*l2)++;
-	} else {
-		p = s;
-		*n2 = 1;
-	}
-	return 1;
-}
-
-void parse_diff(void)
-{
-	int skipping = -1, suppress = 1;
-	char *name1 = NULL, *name2 = NULL;
-	int from = 1, to = 1;
-	int l1, l2, n1, n2;
-	enum cmd {
-		Diff, Hunk, New, Del, Copy, Rename, Junk
-	} cmd;
-	static struct { const char *s; size_t len; } pref[] = {
-		[Hunk] = {"@@ ", 3},
-		[Diff] = {"diff ", 5},
-		[New] = {"new file ", 9},
-		[Del] = {"deleted file ", 12},
-		[Copy] = {"copy from ", 10},
-		[Rename] = {"rename from ", 11},
-		[Junk] = {"", 0},
-	};
-	size_t len1 = strlen(prefix1), len2 = strlen(prefix2);
-
-	while (get_line(0)) {
-		if (skipping > 0) {
-			switch (line[0]) {
-			case '+':
-			case '-':
-			case '\\':
-				continue;
-			}
-		}
-		for (cmd = 0; strncmp(line, pref[cmd].s, pref[cmd].len); cmd++)
-			;
-		switch (cmd) {
-		case Hunk:
-			if (skipping < 0)
-				goto Ediff;
-			if (!suppress) {
-				if (!skipping)
-					printf("M %s %s\n", name1, name2);
-				if (!parse_hunk(&l1, &l2, &n1, &n2))
-					goto Ediff;
-				if (l1 > from)
-					printf("%d %d\n", from, to);
-				if (n1)
-					printf("%d 0\n", l1);
-				from = l1 + n1;
-				to = l2 + n2;
-			}
-			skipping = 1;
-			break;
-		case Diff:
-			if (!suppress) {
-				if (!skipping)
-					printf("M %s %s\n", name1, name2);
-				printf("%d %d\n", from, to);
-			}
-			free(name1);
-			free(name2);
-			name2 = strrchr(line, ' ');
-			if (!name2)
-				goto Ediff;
-			*name2 = '\0';
-			name1 = strrchr(line, ' ');
-			if (!name1)
-				goto Ediff;
-			if (strncmp(name1 + 1, prefix1, len1))
-				goto Ediff;
-			if (strncmp(name2 + 1, prefix2, len2))
-				goto Ediff;
-			name1 = strdup(name1 + len1 + 1);
-			name2 = strdup(name2 + len2 + 1);
-			if (!name1 || !name2)
-				goto Ediff;
-			skipping = 0;
-			suppress = 0;
-			from = to = 1;
-			break;
-		case New:
-			if (skipping)
-				goto Ediff;
-			suppress = 1;
-			break;
-		case Del:
-		case Copy:
-			if (skipping)
-				goto Ediff;
-			printf("D %s\n", name2);
-			suppress = 1;
-			break;
-		case Rename:
-			if (skipping)
-				goto Ediff;
-			printf("D %s\n", name2);
-			break;
-		default:
-			break;
-		}
-	}
-	if (!suppress) {
-		if (!skipping)
-			printf("M %s %s\n", name1, name2);
-		printf("%d %d\n", from, to);
-	}
-	return;
-Ediff:
-	die("odd diff");
-}
-
-int main(int argc, char **argv)
-{
-	char *map_name = NULL;
-	char opt;
-	char *arg;
-	size_t len;
-	for (argc--, argv++; argc; argc--, argv++) {
-		if (argv[0][0] != '-') {
-			map_name = argv[0];
-			continue;
-		}
-		opt = argv[0][1];
-		if (!opt)
-			goto Eargs;
-		arg = argv[0] + 2;
-		if (!*arg) {
-			if (!--argc)
-				goto Eargs;
-			arg = *++argv;
-		}
-		len = strlen(arg);
-		switch (opt) {
-		case 'O':
-			prefix1 = malloc(len + 2);
-			if (!prefix1)
-				Enomem();
-			memcpy(prefix1, arg, len);
-			prefix1[len] = '/';
-			prefix1[len + 1] = '\0';
-			break;
-		case 'N':
-			prefix2 = malloc(len + 2);
-			if (!prefix2)
-				Enomem();
-			memcpy(prefix2, arg, len);
-			prefix2[len] = '/';
-			prefix2[len + 1] = '\0';
-			break;
-		case 'o':
-			old_prefix = arg;
-			break;
-		case 'p':
-			user_pattern = arg;
-			break;
-		default:
-		Eargs:
-			die("bad arguments");
-		}
-	}
-
-	if (!map_name) {
-		parse_diff();
-	} else {
-		parse_map(map_name);
-		buffer = NULL;
-		while (get_line(0))
-			mapline(user_pattern);
-	}
-	return 0;
-
-}
diff --git a/gerrit/aiaiai-jenkins-test-patchset b/gerrit/aiaiai-jenkins-test-patchset
index bc5c948..326268b 100755
--- a/gerrit/aiaiai-jenkins-test-patchset
+++ b/gerrit/aiaiai-jenkins-test-patchset
@@ -5,7 +5,7 @@
 # License: GPLv2
 
 srcdir="$(readlink -ev -- ${0%/*})"
-PATH="$srcdir/..:$srcdir/../external/libshell:$PATH"
+PATH="$srcdir/..:$srcdir/../helpers/libshell:$PATH"
 
 . shell-error
 . shell-args
diff --git a/helpers/Makefile b/helpers/Makefile
new file mode 100644
index 0000000..cbc9493
--- /dev/null
+++ b/helpers/Makefile
@@ -0,0 +1,7 @@
+CFLAGS = -O2 -g -Wextra
+
+all:
+	$(CC) $(CFLAGS) -o remap-log remap-log.c
+
+clean:
+	$(RM) remap-log
diff --git a/helpers/coccinelle/api/alloc/drop_kmalloc_cast.cocci b/helpers/coccinelle/api/alloc/drop_kmalloc_cast.cocci
new file mode 100644
index 0000000..bd5d08b
--- /dev/null
+++ b/helpers/coccinelle/api/alloc/drop_kmalloc_cast.cocci
@@ -0,0 +1,67 @@
+///
+/// Casting (void *) value returned by kmalloc is useless
+/// as mentioned in Documentation/CodingStyle, Chap 14.
+///
+// Confidence: High
+// Copyright: 2009,2010 Nicolas Palix, DIKU.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Options: --no-includes --include-headers
+//
+// Keywords: kmalloc, kzalloc, kcalloc
+// Version min: < 2.6.12 kmalloc
+// Version min: < 2.6.12 kcalloc
+// Version min:   2.6.14 kzalloc
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+//----------------------------------------------------------
+//  For context mode
+//----------------------------------------------------------
+
+ at depends on context@
+type T;
+@@
+
+* (T *)
+  \(kmalloc\|kzalloc\|kcalloc\)(...)
+
+//----------------------------------------------------------
+//  For patch mode
+//----------------------------------------------------------
+
+ at depends on patch@
+type T;
+@@
+
+- (T *)
+  \(kmalloc\|kzalloc\|kcalloc\)(...)
+
+//----------------------------------------------------------
+//  For org and report mode
+//----------------------------------------------------------
+
+ at r depends on org || report@
+type T;
+position p;
+@@
+
+ (T at p *)\(kmalloc\|kzalloc\|kcalloc\)(...)
+
+ at script:python depends on org@
+p << r.p;
+t << r.T;
+@@
+
+coccilib.org.print_safe_todo(p[0], t)
+
+ at script:python depends on report@
+p << r.p;
+t << r.T;
+@@
+
+msg="WARNING: casting value returned by k[cmz]alloc to (%s *) is useless." % (t)
+coccilib.report.print_report(p[0], msg)
diff --git a/helpers/coccinelle/api/alloc/kzalloc-simple.cocci b/helpers/coccinelle/api/alloc/kzalloc-simple.cocci
new file mode 100644
index 0000000..52c55e4
--- /dev/null
+++ b/helpers/coccinelle/api/alloc/kzalloc-simple.cocci
@@ -0,0 +1,86 @@
+///
+/// Use kzalloc rather than kmalloc followed by memset with 0
+///
+/// This considers some simple cases that are common and easy to validate
+/// Note in particular that there are no ...s in the rule, so all of the
+/// matched code has to be contiguous
+///
+// Confidence: High
+// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU.  GPLv2.
+// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/rules/kzalloc.html
+// Options: --no-includes --include-headers
+//
+// Keywords: kmalloc, kzalloc
+// Version min: < 2.6.12 kmalloc
+// Version min:   2.6.14 kzalloc
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+//----------------------------------------------------------
+//  For context mode
+//----------------------------------------------------------
+
+ at depends on context@
+type T, T2;
+expression x;
+expression E1,E2;
+statement S;
+@@
+
+* x = (T)kmalloc(E1,E2);
+  if ((x==NULL) || ...) S
+* memset((T2)x,0,E1);
+
+//----------------------------------------------------------
+//  For patch mode
+//----------------------------------------------------------
+
+ at depends on patch@
+type T, T2;
+expression x;
+expression E1,E2;
+statement S;
+@@
+
+- x = (T)kmalloc(E1,E2);
++ x = kzalloc(E1,E2);
+  if ((x==NULL) || ...) S
+- memset((T2)x,0,E1);
+
+//----------------------------------------------------------
+//  For org mode
+//----------------------------------------------------------
+
+ at r depends on org || report@
+type T, T2;
+expression x;
+expression E1,E2;
+statement S;
+position p;
+@@
+
+ x = (T)kmalloc at p(E1,E2);
+ if ((x==NULL) || ...) S
+ memset((T2)x,0,E1);
+
+ at script:python depends on org@
+p << r.p;
+x << r.x;
+@@
+
+msg="%s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+
+ at script:python depends on report@
+p << r.p;
+x << r.x;
+@@
+
+msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x)
+coccilib.report.print_report(p[0], msg)
diff --git a/helpers/coccinelle/api/d_find_alias.cocci b/helpers/coccinelle/api/d_find_alias.cocci
new file mode 100644
index 0000000..9594c9f
--- /dev/null
+++ b/helpers/coccinelle/api/d_find_alias.cocci
@@ -0,0 +1,80 @@
+/// Make sure calls to d_find_alias() have a corresponding call to dput().
+//
+// Keywords: d_find_alias, dput
+//
+// Confidence: Moderate
+// URL: http://coccinelle.lip6.fr/
+// Options: --include-headers
+
+virtual context
+virtual org
+virtual patch
+virtual report
+
+ at r exists@
+local idexpression struct dentry *dent;
+expression E, E1;
+statement S1, S2;
+position p1, p2;
+@@
+(
+	if (!(dent at p1 = d_find_alias(...))) S1
+|
+	dent at p1 = d_find_alias(...)
+)
+
+<...when != dput(dent)
+    when != if (...) { <+... dput(dent) ...+> }
+    when != true !dent || ...
+    when != dent = E
+    when != E = dent
+if (!dent || ...) S2
+...>
+(
+	return <+...dent...+>;
+|
+	return @p2 ...;
+|
+	dent at p2 = E1;
+|
+	E1 = dent;
+)
+
+ at depends on context@
+local idexpression struct dentry *r.dent;
+position r.p1,r.p2;
+@@
+* dent at p1 = ...
+  ...
+(
+* return at p2 ...;
+|
+* dent at p2
+)
+
+
+ at script:python depends on org@
+p1 << r.p1;
+p2 << r.p2;
+@@
+cocci.print_main("Missing call to dput()",p1)
+cocci.print_secs("",p2)
+
+ at depends on patch@
+local idexpression struct dentry *r.dent;
+position r.p2;
+@@
+(
++ dput(dent);
+  return @p2 ...;
+|
++ dput(dent);
+  dent at p2 = ...;
+)
+
+ at script:python depends on report@
+p1 << r.p1;
+p2 << r.p2;
+@@
+msg = "Missing call to dput() at line %s."
+coccilib.report.print_report(p1[0], msg % (p2[0].line))
diff --git a/helpers/coccinelle/api/devm_ioremap_resource.cocci b/helpers/coccinelle/api/devm_ioremap_resource.cocci
new file mode 100644
index 0000000..495daa3
--- /dev/null
+++ b/helpers/coccinelle/api/devm_ioremap_resource.cocci
@@ -0,0 +1,90 @@
+virtual patch
+virtual report
+
+ at depends on patch@
+expression base, dev, res;
+@@
+
+-base = devm_request_and_ioremap(dev, res);
++base = devm_ioremap_resource(dev, res);
+ ...
+ if (
+-base == NULL
++IS_ERR(base)
+ || ...) {
+<...
+-	return ...;
++	return PTR_ERR(base);
+...>
+ }
+
+ at depends on patch@
+expression e, E, ret;
+identifier l;
+@@
+
+ e = devm_ioremap_resource(...);
+ ...
+ if (IS_ERR(e) || ...) {
+ 	... when any
+-	ret = E;
++	ret = PTR_ERR(e);
+ 	...
+(
+ 	return ret;
+|
+ 	goto l;
+)
+ }
+
+ at depends on patch@
+expression e;
+@@
+
+ e = devm_ioremap_resource(...);
+ ...
+ if (IS_ERR(e) || ...) {
+ 	...
+-	\(dev_dbg\|dev_err\|pr_debug\|pr_err\|DRM_ERROR\)(...);
+ 	...
+ }
+
+ at depends on patch@
+expression e;
+identifier l;
+@@
+
+ e = devm_ioremap_resource(...);
+ ...
+ if (IS_ERR(e) || ...)
+-{
+(
+ 	return ...;
+|
+ 	goto l;
+)
+-}
+
+ at r depends on report@
+expression e;
+identifier l;
+position p1;
+@@
+
+*e = devm_request_and_ioremap at p1(...);
+ ...
+ if (e == NULL || ...) {
+ 	...
+(
+ 	return ...;
+|
+ 	goto l;
+)
+ }
+
+ at script:python depends on r@
+p1 << r.p1;
+@@
+
+msg = "ERROR: deprecated devm_request_and_ioremap() API used on line %s" % (p1[0].line)
+coccilib.report.print_report(p1[0], msg)
diff --git a/helpers/coccinelle/api/devm_request_and_ioremap.cocci b/helpers/coccinelle/api/devm_request_and_ioremap.cocci
new file mode 100644
index 0000000..46beb81
--- /dev/null
+++ b/helpers/coccinelle/api/devm_request_and_ioremap.cocci
@@ -0,0 +1,105 @@
+/// Reimplement a call to devm_request_mem_region followed by a call to ioremap
+/// or ioremap_nocache by a call to devm_request_and_ioremap.
+/// Devm_request_and_ioremap was introduced in
+/// 72f8c0bfa0de64c68ee59f40eb9b2683bffffbb0.  It makes the code much more
+/// concise.
+///
+///
+// Confidence: High
+// Copyright: (C) 2011 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2011 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: -no_includes -include_headers
+
+virtual patch
+virtual org
+virtual report
+virtual context
+
+ at nm@
+expression myname;
+identifier i;
+@@
+
+struct platform_driver i = { .driver = { .name = myname } };
+
+ at depends on patch@
+expression dev,res,size;
+@@
+
+-if (!devm_request_mem_region(dev, res->start, size,
+-                              \(res->name\|dev_name(dev)\))) {
+-   ...
+-   return ...;
+-}
+... when != res->start
+(
+-devm_ioremap(dev,res->start,size)
++devm_request_and_ioremap(dev,res)
+|
+-devm_ioremap_nocache(dev,res->start,size)
++devm_request_and_ioremap(dev,res)
+)
+... when any
+    when != res->start
+
+// this rule is separate from the previous one, because a single file can
+// have multiple values of myname
+ at depends on patch@
+expression dev,res,size;
+expression nm.myname;
+@@
+
+-if (!devm_request_mem_region(dev, res->start, size,myname)) {
+-   ...
+-   return ...;
+-}
+... when != res->start
+(
+-devm_ioremap(dev,res->start,size)
++devm_request_and_ioremap(dev,res)
+|
+-devm_ioremap_nocache(dev,res->start,size)
++devm_request_and_ioremap(dev,res)
+)
+... when any
+    when != res->start
+
+
+ at pb depends on org || report || context@
+expression dev,res,size;
+expression nm.myname;
+position p1,p2;
+@@
+
+*if
+  (!devm_request_mem_region at p1(dev, res->start, size,
+                              \(res->name\|dev_name(dev)\|myname\))) {
+   ...
+   return ...;
+}
+... when != res->start
+(
+*devm_ioremap at p2(dev,res->start,size)
+|
+*devm_ioremap_nocache at p2(dev,res->start,size)
+)
+... when any
+    when != res->start
+
+ at script:python depends on org@
+p1 << pb.p1;
+p2 << pb.p2;
+@@
+
+cocci.print_main("INFO: replace by devm_request_and_ioremap",p1)
+cocci.print_secs("",p2)
+
+ at script:python depends on report@
+p1 << pb.p1;
+p2 << pb.p2;
+@@
+
+msg = "INFO: devm_request_mem_region followed by ioremap on line %s can be replaced by devm_request_and_ioremap" % (p2[0].line)
+coccilib.report.print_report(p1[0],msg)
diff --git a/helpers/coccinelle/api/err_cast.cocci b/helpers/coccinelle/api/err_cast.cocci
new file mode 100644
index 0000000..2ce1150
--- /dev/null
+++ b/helpers/coccinelle/api/err_cast.cocci
@@ -0,0 +1,56 @@
+///
+/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...))
+///
+// Confidence: High
+// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU.  GPLv2.
+// Copyright: (C) 2009, 2010 Julia Lawall, DIKU.  GPLv2.
+// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Options:
+//
+// Keywords: ERR_PTR, PTR_ERR, ERR_CAST
+// Version min: 2.6.25
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+
+@ depends on context && !patch && !org && !report@
+expression x;
+@@
+
+* ERR_PTR(PTR_ERR(x))
+
+@ depends on !context && patch && !org && !report @
+expression x;
+@@
+
+- ERR_PTR(PTR_ERR(x))
++ ERR_CAST(x)
+
+ at r depends on !context && !patch && (org || report)@
+expression x;
+position p;
+@@
+
+ ERR_PTR at p(PTR_ERR(x))
+
+ at script:python depends on org@
+p << r.p;
+x << r.x;
+@@
+
+msg="WARNING ERR_CAST can be used with %s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+
+ at script:python depends on report@
+p << r.p;
+x << r.x;
+@@
+
+msg="WARNING: ERR_CAST can be used with %s" % (x)
+coccilib.report.print_report(p[0], msg)
diff --git a/helpers/coccinelle/api/kstrdup.cocci b/helpers/coccinelle/api/kstrdup.cocci
new file mode 100644
index 0000000..09cba54
--- /dev/null
+++ b/helpers/coccinelle/api/kstrdup.cocci
@@ -0,0 +1,104 @@
+/// Use kstrdup rather than duplicating its implementation
+///
+// Confidence: High
+// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+ at depends on patch@
+expression from,to;
+expression flag,E1,E2;
+statement S;
+@@
+
+-  to = kmalloc(strlen(from) + 1,flag);
++  to = kstrdup(from, flag);
+   ... when != \(from = E1 \| to = E1 \)
+   if (to==NULL || ...) S
+   ... when != \(from = E2 \| to = E2 \)
+-  strcpy(to, from);
+
+ at depends on patch@
+expression x,from,to;
+expression flag,E1,E2,E3;
+statement S;
+@@
+
+-   x = strlen(from) + 1;
+    ... when != \( x = E1 \| from = E1 \)
+-   to = \(kmalloc\|kzalloc\)(x,flag);
++   to = kstrdup(from, flag);
+    ... when != \(x = E2 \| from = E2 \| to = E2 \)
+    if (to==NULL || ...) S
+    ... when != \(x = E3 \| from = E3 \| to = E3 \)
+-   memcpy(to, from, x);
+
+// ---------------------------------------------------------------------
+
+ at r1 depends on !patch exists@
+expression from,to;
+expression flag,E1,E2;
+statement S;
+position p1,p2;
+@@
+
+*  to = kmalloc at p1(strlen(from) + 1,flag);
+   ... when != \(from = E1 \| to = E1 \)
+   if (to==NULL || ...) S
+   ... when != \(from = E2 \| to = E2 \)
+*  strcpy at p2(to, from);
+
+ at r2 depends on !patch exists@
+expression x,from,to;
+expression flag,E1,E2,E3;
+statement S;
+position p1,p2;
+@@
+
+*   x = strlen(from) + 1;
+    ... when != \( x = E1 \| from = E1 \)
+*   to = \(kmalloc at p1\|kzalloc at p2\)(x,flag);
+    ... when != \(x = E2 \| from = E2 \| to = E2 \)
+    if (to==NULL || ...) S
+    ... when != \(x = E3 \| from = E3 \| to = E3 \)
+*   memcpy at p2(to, from, x);
+
+ at script:python depends on org@
+p1 << r1.p1;
+p2 << r1.p2;
+@@
+
+cocci.print_main("WARNING opportunity for kstrdep",p1)
+cocci.print_secs("strcpy",p2)
+
+ at script:python depends on org@
+p1 << r2.p1;
+p2 << r2.p2;
+@@
+
+cocci.print_main("WARNING opportunity for kstrdep",p1)
+cocci.print_secs("memcpy",p2)
+
+ at script:python depends on report@
+p1 << r1.p1;
+p2 << r1.p2;
+@@
+
+msg = "WARNING opportunity for kstrdep (strcpy on line %s)" % (p2[0].line)
+coccilib.report.print_report(p1[0], msg)
+
+ at script:python depends on report@
+p1 << r2.p1;
+p2 << r2.p2;
+@@
+
+msg = "WARNING opportunity for kstrdep (memcpy on line %s)" % (p2[0].line)
+coccilib.report.print_report(p1[0], msg)
diff --git a/helpers/coccinelle/api/memdup.cocci b/helpers/coccinelle/api/memdup.cocci
new file mode 100644
index 0000000..3d1aa71
--- /dev/null
+++ b/helpers/coccinelle/api/memdup.cocci
@@ -0,0 +1,66 @@
+/// Use kmemdup rather than duplicating its implementation
+///
+// Confidence: High
+// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+ at r1@
+expression from,to;
+expression flag;
+position p;
+@@
+
+   to = \(kmalloc at p\|kzalloc at p\)(strlen(from) + 1,flag);
+
+ at r2@
+expression x,from,to;
+expression flag,E1;
+position p;
+@@
+
+    x = strlen(from) + 1;
+    ... when != \( x = E1 \| from = E1 \)
+    to = \(kmalloc at p\|kzalloc at p\)(x,flag);
+
+ at depends on patch@
+expression from,to,size,flag;
+position p != {r1.p,r2.p};
+statement S;
+@@
+
+-  to = \(kmalloc at p\|kzalloc at p\)(size,flag);
++  to = kmemdup(from,size,flag);
+   if (to==NULL || ...) S
+-  memcpy(to, from, size);
+
+ at r depends on !patch@
+expression from,to,size,flag;
+position p != {r1.p,r2.p};
+statement S;
+@@
+
+*  to = \(kmalloc at p\|kzalloc at p\)(size,flag);
+   to = kmemdup(from,size,flag);
+   if (to==NULL || ...) S
+*  memcpy(to, from, size);
+
+ at script:python depends on org@
+p << r.p;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING opportunity for kmemdep")
+
+ at script:python depends on report@
+p << r.p;
+@@
+
+coccilib.report.print_report(p[0], "WARNING opportunity for kmemdep")
diff --git a/helpers/coccinelle/api/memdup_user.cocci b/helpers/coccinelle/api/memdup_user.cocci
new file mode 100644
index 0000000..c606231
--- /dev/null
+++ b/helpers/coccinelle/api/memdup_user.cocci
@@ -0,0 +1,60 @@
+/// Use memdup_user rather than duplicating its implementation
+/// This is a little bit restricted to reduce false positives
+///
+// Confidence: High
+// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+ at depends on patch@
+expression from,to,size,flag;
+identifier l1,l2;
+@@
+
+-  to = \(kmalloc\|kzalloc\)(size,flag);
++  to = memdup_user(from,size);
+   if (
+-      to==NULL
++      IS_ERR(to)
+                 || ...) {
+   <+... when != goto l1;
+-  -ENOMEM
++  PTR_ERR(to)
+   ...+>
+   }
+-  if (copy_from_user(to, from, size) != 0) {
+-    <+... when != goto l2;
+-    -EFAULT
+-    ...+>
+-  }
+
+ at r depends on !patch@
+expression from,to,size,flag;
+position p;
+statement S1,S2;
+@@
+
+*  to = \(kmalloc at p\|kzalloc at p\)(size,flag);
+   if (to==NULL || ...) S1
+   if (copy_from_user(to, from, size) != 0)
+   S2
+
+ at script:python depends on org@
+p << r.p;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING opportunity for memdup_user")
+
+ at script:python depends on report@
+p << r.p;
+@@
+
+coccilib.report.print_report(p[0], "WARNING opportunity for memdup_user")
diff --git a/helpers/coccinelle/api/ptr_ret.cocci b/helpers/coccinelle/api/ptr_ret.cocci
new file mode 100644
index 0000000..e18f840
--- /dev/null
+++ b/helpers/coccinelle/api/ptr_ret.cocci
@@ -0,0 +1,96 @@
+///
+/// Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR
+///
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Options: --no-includes --include-headers
+//
+// Keywords: ERR_PTR, PTR_ERR, PTR_RET, PTR_ERR_OR_ZERO
+// Version min: 2.6.39
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+ at depends on patch@
+expression ptr;
+@@
+
+- if (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0;
++ return PTR_ERR_OR_ZERO(ptr);
+
+ at depends on patch@
+expression ptr;
+@@
+
+- if (IS_ERR(ptr)) return PTR_ERR(ptr); return 0;
++ return PTR_ERR_OR_ZERO(ptr);
+
+ at depends on patch@
+expression ptr;
+@@
+
+- (IS_ERR(ptr) ? PTR_ERR(ptr) : 0)
++ PTR_ERR_OR_ZERO(ptr)
+
+ at r1 depends on !patch@
+expression ptr;
+position p1;
+@@
+
+* if at p1 (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0;
+
+ at r2 depends on !patch@
+expression ptr;
+position p2;
+@@
+
+* if at p2 (IS_ERR(ptr)) return PTR_ERR(ptr); return 0;
+
+ at r3 depends on !patch@
+expression ptr;
+position p3;
+@@
+
+* IS_ERR at p3(ptr) ? PTR_ERR(ptr) : 0
+
+ at script:python depends on org@
+p << r1.p1;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used")
+
+
+ at script:python depends on org@
+p << r2.p2;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used")
+
+ at script:python depends on org@
+p << r3.p3;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used")
+
+ at script:python depends on report@
+p << r1.p1;
+@@
+
+coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used")
+
+ at script:python depends on report@
+p << r2.p2;
+@@
+
+coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used")
+
+ at script:python depends on report@
+p << r3.p3;
+@@
+
+coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used")
diff --git a/helpers/coccinelle/api/resource_size.cocci b/helpers/coccinelle/api/resource_size.cocci
new file mode 100644
index 0000000..1935a58
--- /dev/null
+++ b/helpers/coccinelle/api/resource_size.cocci
@@ -0,0 +1,93 @@
+///
+/// Use resource_size function on resource object
+/// instead of explicit computation.
+///
+//  Confidence: High
+//  Copyright: (C) 2009, 2010 Nicolas Palix, DIKU.  GPLv2.
+//  Copyright: (C) 2009, 2010 Julia Lawall, DIKU.  GPLv2.
+//  Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+//  URL: http://coccinelle.lip6.fr/
+//  Options:
+//
+//  Keywords: resource_size
+//  Version min: 2.6.27 resource_size
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+//----------------------------------------------------------
+//  For context mode
+//----------------------------------------------------------
+
+ at r_context depends on context && !patch && !org@
+struct resource *res;
+@@
+
+* (res->end - res->start) + 1
+
+//----------------------------------------------------------
+//  For patch mode
+//----------------------------------------------------------
+
+ at r_patch depends on !context && patch && !org@
+struct resource *res;
+@@
+
+- (res->end - res->start) + 1
++ resource_size(res)
+
+//----------------------------------------------------------
+//  For org mode
+//----------------------------------------------------------
+
+
+ at r_org depends on !context && !patch && (org || report)@
+struct resource *res;
+position p;
+@@
+
+ (res->end at p - res->start) + 1
+
+ at rbad_org depends on !context && !patch && (org || report)@
+struct resource *res;
+position p != r_org.p;
+@@
+
+ res->end at p - res->start
+
+ at script:python depends on org@
+p << r_org.p;
+x << r_org.res;
+@@
+
+msg="ERROR with %s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+
+ at script:python depends on report@
+p << r_org.p;
+x << r_org.res;
+@@
+
+msg="ERROR: Missing resource_size with %s" % (x)
+coccilib.report.print_report(p[0], msg)
+
+ at script:python depends on org@
+p << rbad_org.p;
+x << rbad_org.res;
+@@
+
+msg="WARNING with %s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+
+ at script:python depends on report@
+p << rbad_org.p;
+x << rbad_org.res;
+@@
+
+msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x)
+coccilib.report.print_report(p[0], msg)
diff --git a/helpers/coccinelle/api/simple_open.cocci b/helpers/coccinelle/api/simple_open.cocci
new file mode 100644
index 0000000..b67e174
--- /dev/null
+++ b/helpers/coccinelle/api/simple_open.cocci
@@ -0,0 +1,70 @@
+/// This removes an open coded simple_open() function
+/// and replaces file operations references to the function
+/// with simple_open() instead.
+///
+// Confidence: High
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual report
+
+@ open depends on patch @
+identifier open_f != simple_open;
+identifier i, f;
+@@
+-int open_f(struct inode *i, struct file *f)
+-{
+(
+-if (i->i_private)
+-f->private_data = i->i_private;
+|
+-f->private_data = i->i_private;
+)
+-return 0;
+-}
+
+@ has_open depends on open @
+identifier fops;
+identifier open.open_f;
+@@
+struct file_operations fops = {
+...,
+-.open = open_f,
++.open = simple_open,
+...
+};
+
+@ openr depends on report @
+identifier open_f != simple_open;
+identifier i, f;
+position p;
+@@
+int open_f at p(struct inode *i, struct file *f)
+{
+(
+if (i->i_private)
+f->private_data = i->i_private;
+|
+f->private_data = i->i_private;
+)
+return 0;
+}
+
+@ has_openr depends on openr @
+identifier fops;
+identifier openr.open_f;
+position p;
+@@
+struct file_operations fops = {
+...,
+.open = open_f at p,
+...
+};
+
+ at script:python@
+pf << openr.p;
+ps << has_openr.p;
+@@
+
+coccilib.report.print_report(pf[0],"WARNING opportunity for simple_open, see also structure on line %s"%(ps[0].line))
diff --git a/helpers/coccinelle/free/clk_put.cocci b/helpers/coccinelle/free/clk_put.cocci
new file mode 100644
index 0000000..46747ad
--- /dev/null
+++ b/helpers/coccinelle/free/clk_put.cocci
@@ -0,0 +1,67 @@
+/// Find missing clk_puts.
+///
+//# This only signals a missing clk_put when there is a clk_put later
+//# in the same function.
+//# False positives can be due to loops.
+//
+// Confidence: Moderate
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options:
+
+virtual context
+virtual org
+virtual report
+
+ at clk@
+expression e;
+statement S,S1;
+int ret;
+position p1,p2,p3;
+@@
+
+e = clk_get at p1(...)
+... when != clk_put(e)
+if (<+...e...+>) S
+... when any
+    when != clk_put(e)
+    when != if (...) { ... clk_put(e); ... }
+(
+ if (ret == 0) S1
+|
+if (...)
+   { ...
+     return 0; }
+|
+if (...)
+   { ...
+     return <+...e...+>; }
+|
+*if at p2 (...)
+   { ... when != clk_put(e)
+         when forall
+     return at p3 ...; }
+)
+... when any
+clk_put(e);
+
+ at script:python depends on org@
+p1 << clk.p1;
+p2 << clk.p2;
+p3 << clk.p3;
+@@
+
+cocci.print_main("clk_get",p1)
+cocci.print_secs("if",p2)
+cocci.print_secs("needed clk_put",p3)
+
+ at script:python depends on report@
+p1 << clk.p1;
+p2 << clk.p2;
+p3 << clk.p3;
+@@
+
+msg = "ERROR: missing clk_put; clk_get on line %s and execution via conditional on line %s" % (p1[0].line,p2[0].line)
+coccilib.report.print_report(p3[0],msg)
diff --git a/helpers/coccinelle/free/devm_free.cocci b/helpers/coccinelle/free/devm_free.cocci
new file mode 100644
index 0000000..3d93490
--- /dev/null
+++ b/helpers/coccinelle/free/devm_free.cocci
@@ -0,0 +1,71 @@
+/// Find uses of standard freeing functons on values allocated using devm_
+/// functions.  Values allocated using the devm_functions are freed when
+/// the device is detached, and thus the use of the standard freeing
+/// function would cause a double free.
+/// See Documentation/driver-model/devres.txt for more information.
+///
+/// A difficulty of detecting this problem is that the standard freeing
+/// function might be called from a different function than the one
+/// containing the allocation function.  It is thus necessary to make the
+/// connection between the allocation function and the freeing function.
+/// Here this is done using the specific argument text, which is prone to
+/// false positives.  There is no rule for the request_region and
+/// request_mem_region variants because this heuristic seems to be a bit
+/// less reliable in these cases.
+///
+// Confidence: Moderate
+// Copyright: (C) 2011 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2011 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+virtual context
+
+ at r depends on context || org || report@
+expression x;
+@@
+
+(
+ x = devm_kzalloc(...)
+|
+ x = devm_request_irq(...)
+|
+ x = devm_ioremap(...)
+|
+ x = devm_ioremap_nocache(...)
+|
+ x = devm_ioport_map(...)
+)
+
+ at pb@
+expression r.x;
+position p;
+@@
+
+(
+* kfree at p(x)
+|
+* free_irq at p(x)
+|
+* iounmap at p(x)
+|
+* ioport_unmap at p(x)
+)
+
+ at script:python depends on org@
+p << pb.p;
+@@
+
+msg="WARNING: invalid free of devm_ allocated data"
+coccilib.org.print_todo(p[0], msg)
+
+ at script:python depends on report@
+p << pb.p;
+@@
+
+msg="WARNING: invalid free of devm_ allocated data"
+coccilib.report.print_report(p[0], msg)
+
diff --git a/helpers/coccinelle/free/iounmap.cocci b/helpers/coccinelle/free/iounmap.cocci
new file mode 100644
index 0000000..5384f4b
--- /dev/null
+++ b/helpers/coccinelle/free/iounmap.cocci
@@ -0,0 +1,67 @@
+/// Find missing iounmaps.
+///
+//# This only signals a missing iounmap when there is an iounmap later
+//# in the same function.
+//# False positives can be due to loops.
+//
+// Confidence: Moderate
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options:
+
+virtual context
+virtual org
+virtual report
+
+ at iom@
+expression e;
+statement S,S1;
+int ret;
+position p1,p2,p3;
+@@
+
+e = \(ioremap at p1\|ioremap_nocache at p1\)(...)
+... when != iounmap(e)
+if (<+...e...+>) S
+... when any
+    when != iounmap(e)
+    when != if (...) { ... iounmap(e); ... }
+(
+ if (ret == 0) S1
+|
+if (...)
+   { ...
+     return 0; }
+|
+if (...)
+   { ...
+     return <+...e...+>; }
+|
+*if at p2 (...)
+   { ... when != iounmap(e)
+         when forall
+     return at p3 ...; }
+)
+... when any
+iounmap(e);
+
+ at script:python depends on org@
+p1 << iom.p1;
+p2 << iom.p2;
+p3 << iom.p3;
+@@
+
+cocci.print_main("ioremap",p1)
+cocci.print_secs("if",p2)
+cocci.print_secs("needed iounmap",p3)
+
+ at script:python depends on report@
+p1 << iom.p1;
+p2 << iom.p2;
+p3 << iom.p3;
+@@
+
+msg = "ERROR: missing iounmap; ioremap on line %s and execution via conditional on line %s" % (p1[0].line,p2[0].line)
+coccilib.report.print_report(p3[0],msg)
diff --git a/helpers/coccinelle/free/kfree.cocci b/helpers/coccinelle/free/kfree.cocci
new file mode 100644
index 0000000..577b780
--- /dev/null
+++ b/helpers/coccinelle/free/kfree.cocci
@@ -0,0 +1,121 @@
+/// Find a use after free.
+//# Values of variables may imply that some
+//# execution paths are not possible, resulting in false positives.
+//# Another source of false positives are macros such as
+//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument
+///
+// Confidence: Moderate
+// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+
+ at free@
+expression E;
+position p1;
+@@
+
+kfree at p1(E)
+
+ at print expression@
+constant char [] c;
+expression free.E,E2;
+type T;
+position p;
+identifier f;
+@@
+
+(
+ f(...,c,...,(T)E at p,...)
+|
+ E at p == E2
+|
+ E at p != E2
+|
+ E2 == E at p
+|
+ E2 != E at p
+|
+ !E at p
+|
+ E at p || ...
+)
+
+ at sz@
+expression free.E;
+position p;
+@@
+
+ sizeof(<+...E at p...+>)
+
+ at loop exists@
+expression E;
+identifier l;
+position ok;
+@@
+
+while (1) { ...
+  kfree at ok(E)
+  ... when != break;
+      when != goto l;
+      when forall
+}
+
+ at r exists@
+expression free.E, subE<=free.E, E2;
+expression E1;
+iterator iter;
+statement S;
+position free.p1!=loop.ok,p2!={print.p,sz.p};
+@@
+
+kfree at p1(E,...)
+...
+(
+ iter(...,subE,...) S // no use
+|
+ list_remove_head(E1,subE,...)
+|
+ subE = E2
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+ BUG(...)
+|
+ BUG_ON(...)
+|
+ return_VALUE(...)
+|
+ return_ACPI_STATUS(...)
+|
+ E at p2 // bad use
+)
+
+ at script:python depends on org@
+p1 << free.p1;
+p2 << r.p2;
+@@
+
+cocci.print_main("kfree",p1)
+cocci.print_secs("ref",p2)
+
+ at script:python depends on report@
+p1 << free.p1;
+p2 << r.p2;
+@@
+
+msg = "ERROR: reference preceded by free on line %s" % (p1[0].line)
+coccilib.report.print_report(p2[0],msg)
diff --git a/helpers/coccinelle/free/kfreeaddr.cocci b/helpers/coccinelle/free/kfreeaddr.cocci
new file mode 100644
index 0000000..ce8aacc
--- /dev/null
+++ b/helpers/coccinelle/free/kfreeaddr.cocci
@@ -0,0 +1,32 @@
+/// Free of a structure field
+///
+// Confidence: High
+// Copyright: (C) 2013 Julia Lawall, INRIA/LIP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+virtual context
+
+ at r depends on context || report || org @
+expression e;
+identifier f;
+position p;
+@@
+
+* kfree at p(&e->f)
+
+ at script:python depends on org@
+p << r.p;
+@@
+
+cocci.print_main("kfree",p)
+
+ at script:python depends on report@
+p << r.p;
+@@
+
+msg = "ERROR: kfree of structure field"
+coccilib.report.print_report(p[0],msg)
diff --git a/helpers/coccinelle/free/pci_free_consistent.cocci b/helpers/coccinelle/free/pci_free_consistent.cocci
new file mode 100644
index 0000000..43600cc
--- /dev/null
+++ b/helpers/coccinelle/free/pci_free_consistent.cocci
@@ -0,0 +1,52 @@
+/// Find missing pci_free_consistent for every pci_alloc_consistent.
+///
+// Confidence: Moderate
+// Copyright: (C) 2013 Petr Strnad.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Keywords: pci_free_consistent, pci_alloc_consistent
+// Options: --no-includes --include-headers
+
+virtual report
+virtual org
+
+ at search@
+local idexpression id;
+expression x,y,z,e;
+position p1,p2;
+type T;
+@@
+
+id = pci_alloc_consistent at p1(x,y,&z)
+... when != e = id
+if (id == NULL || ...) { ... return ...; }
+... when != pci_free_consistent(x,y,id,z)
+    when != if (id) { ... pci_free_consistent(x,y,id,z) ... }
+    when != if (y) { ... pci_free_consistent(x,y,id,z) ... }
+    when != e = (T)id
+    when exists
+(
+return 0;
+|
+return 1;
+|
+return id;
+|
+return at p2 ...;
+)
+
+ at script:python depends on report@
+p1 << search.p1;
+p2 << search.p2;
+@@
+
+msg = "ERROR: missing pci_free_consistent; pci_alloc_consistent on line %s and return without freeing on line %s" % (p1[0].line,p2[0].line)
+coccilib.report.print_report(p2[0],msg)
+
+ at script:python depends on org@
+p1 << search.p1;
+p2 << search.p2;
+@@
+
+msg = "ERROR: missing pci_free_consistent; pci_alloc_consistent on line %s and return without freeing on line %s" % (p1[0].line,p2[0].line)
+cocci.print_main(msg,p1)
+cocci.print_secs("",p2)
diff --git a/helpers/coccinelle/iterators/fen.cocci b/helpers/coccinelle/iterators/fen.cocci
new file mode 100644
index 0000000..48c152f
--- /dev/null
+++ b/helpers/coccinelle/iterators/fen.cocci
@@ -0,0 +1,123 @@
+/// These iterators only exit normally when the loop cursor is NULL, so there
+/// is no point to call of_node_put on the final value.
+///
+// Confidence: High
+// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+ at depends on patch@
+iterator name for_each_node_by_name;
+expression np,E;
+identifier l;
+@@
+
+for_each_node_by_name(np,...) {
+  ... when != break;
+      when != goto l;
+}
+... when != np = E
+- of_node_put(np);
+
+ at depends on patch@
+iterator name for_each_node_by_type;
+expression np,E;
+identifier l;
+@@
+
+for_each_node_by_type(np,...) {
+  ... when != break;
+      when != goto l;
+}
+... when != np = E
+- of_node_put(np);
+
+ at depends on patch@
+iterator name for_each_compatible_node;
+expression np,E;
+identifier l;
+@@
+
+for_each_compatible_node(np,...) {
+  ... when != break;
+      when != goto l;
+}
+... when != np = E
+- of_node_put(np);
+
+ at depends on patch@
+iterator name for_each_matching_node;
+expression np,E;
+identifier l;
+@@
+
+for_each_matching_node(np,...) {
+  ... when != break;
+      when != goto l;
+}
+... when != np = E
+- of_node_put(np);
+
+// ----------------------------------------------------------------------
+
+ at r depends on !patch forall@
+//iterator name for_each_node_by_name;
+//iterator name for_each_node_by_type;
+//iterator name for_each_compatible_node;
+//iterator name for_each_matching_node;
+expression np,E;
+identifier l;
+position p1,p2;
+@@
+
+(
+*for_each_node_by_name at p1(np,...)
+{
+  ... when != break;
+      when != goto l;
+}
+|
+*for_each_node_by_type at p1(np,...)
+{
+  ... when != break;
+      when != goto l;
+}
+|
+*for_each_compatible_node at p1(np,...)
+{
+  ... when != break;
+      when != goto l;
+}
+|
+*for_each_matching_node at p1(np,...)
+{
+  ... when != break;
+      when != goto l;
+}
+)
+... when != np = E
+* of_node_put at p2(np);
+
+ at script:python depends on org@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+cocci.print_main("unneeded of_node_put",p2)
+cocci.print_secs("iterator",p1)
+
+ at script:python depends on report@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+msg = "ERROR: of_node_put not needed after iterator on line %s" % (p1[0].line)
+coccilib.report.print_report(p2[0], msg)
diff --git a/helpers/coccinelle/iterators/itnull.cocci b/helpers/coccinelle/iterators/itnull.cocci
new file mode 100644
index 0000000..f58732b
--- /dev/null
+++ b/helpers/coccinelle/iterators/itnull.cocci
@@ -0,0 +1,94 @@
+/// Many iterators have the property that the first argument is always bound
+/// to a real list element, never NULL.
+//# False positives arise for some iterators that do not have this property,
+//# or in cases when the loop cursor is reassigned.  The latter should only
+//# happen when the matched code is on the way to a loop exit (break, goto,
+//# or return).
+///
+// Confidence: Moderate
+// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+ at depends on patch@
+iterator I;
+expression x,E,E1,E2;
+statement S,S1,S2;
+@@
+
+I(x,...) { <...
+(
+- if (x == NULL && ...) S
+|
+- if (x != NULL || ...)
+  S
+|
+- (x == NULL) ||
+  E
+|
+- (x != NULL) &&
+  E
+|
+- (x == NULL && ...) ? E1 :
+  E2
+|
+- (x != NULL || ...) ?
+  E1
+- : E2
+|
+- if (x == NULL && ...) S1 else
+  S2
+|
+- if (x != NULL || ...)
+  S1
+- else S2
+|
++ BAD(
+  x == NULL
++ )
+|
++ BAD(
+  x != NULL
++ )
+)
+  ...> }
+
+ at r depends on !patch exists@
+iterator I;
+expression x,E;
+position p1,p2;
+@@
+
+*I at p1(x,...)
+{ ... when != x = E
+(
+*  x at p2 == NULL
+|
+*  x at p2 != NULL
+)
+  ... when any
+}
+
+ at script:python depends on org@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+cocci.print_main("iterator-bound variable",p1)
+cocci.print_secs("useless NULL test",p2)
+
+ at script:python depends on report@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+msg = "ERROR: iterator variable bound on line %s cannot be NULL" % (p1[0].line)
+coccilib.report.print_report(p2[0], msg)
diff --git a/helpers/coccinelle/iterators/list_entry_update.cocci b/helpers/coccinelle/iterators/list_entry_update.cocci
new file mode 100644
index 0000000..873f444
--- /dev/null
+++ b/helpers/coccinelle/iterators/list_entry_update.cocci
@@ -0,0 +1,62 @@
+/// list_for_each_entry uses its first argument to get from one element of
+/// the list to the next, so it is usually not a good idea to reassign it.
+/// The first rule finds such a reassignment and the second rule checks
+/// that there is a path from the reassignment back to the top of the loop.
+///
+// Confidence: High
+// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
+// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual context
+virtual org
+virtual report
+
+ at r@
+iterator name list_for_each_entry;
+expression x,E;
+position p1,p2;
+@@
+
+list_for_each_entry at p1(x,...) { <... x =@p2 E ...> }
+
+ at depends on context && !org && !report@
+expression x,E;
+position r.p1,r.p2;
+statement S;
+@@
+
+*x =@p2 E
+...
+list_for_each_entry at p1(x,...) S
+
+// ------------------------------------------------------------------------
+
+ at back depends on (org || report) && !context exists@
+expression x,E;
+position r.p1,r.p2;
+statement S;
+@@
+
+x =@p2 E
+...
+list_for_each_entry at p1(x,...) S
+
+ at script:python depends on back && org@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+cocci.print_main("iterator",p1)
+cocci.print_secs("update",p2)
+
+ at script:python depends on back && report@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+msg = "iterator with update on line %s" % (p2[0].line)
+coccilib.report.print_report(p1[0],msg)
diff --git a/helpers/coccinelle/iterators/use_after_iter.cocci b/helpers/coccinelle/iterators/use_after_iter.cocci
new file mode 100644
index 0000000..f085f59
--- /dev/null
+++ b/helpers/coccinelle/iterators/use_after_iter.cocci
@@ -0,0 +1,147 @@
+/// If list_for_each_entry, etc complete a traversal of the list, the iterator
+/// variable ends up pointing to an address at an offset from the list head,
+/// and not a meaningful structure.  Thus this value should not be used after
+/// the end of the iterator.
+//#False positives arise when there is a goto in the iterator and the
+//#reported reference is at the label of this goto.  Some flag tests
+//#may also cause a report to be a false positive.
+///
+// Confidence: Moderate
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LIP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual context
+virtual org
+virtual report
+
+ at r exists@
+identifier c,member;
+expression E,x;
+iterator name list_for_each_entry;
+iterator name list_for_each_entry_reverse;
+iterator name list_for_each_entry_continue;
+iterator name list_for_each_entry_continue_reverse;
+iterator name list_for_each_entry_from;
+iterator name list_for_each_entry_safe;
+iterator name list_for_each_entry_safe_continue;
+iterator name list_for_each_entry_safe_from;
+iterator name list_for_each_entry_safe_reverse;
+iterator name hlist_for_each_entry;
+iterator name hlist_for_each_entry_continue;
+iterator name hlist_for_each_entry_from;
+iterator name hlist_for_each_entry_safe;
+statement S;
+position p1,p2;
+@@
+
+(
+list_for_each_entry at p1(c,...,member) { ... when != break;
+                                 when forall
+                                 when strict
+}
+|
+list_for_each_entry_reverse at p1(c,...,member) { ... when != break;
+                                 when forall
+                                 when strict
+}
+|
+list_for_each_entry_continue at p1(c,...,member) { ... when != break;
+                                 when forall
+                                 when strict
+}
+|
+list_for_each_entry_continue_reverse at p1(c,...,member) { ... when != break;
+                                 when forall
+                                 when strict
+}
+|
+list_for_each_entry_from at p1(c,...,member) { ... when != break;
+                                 when forall
+                                 when strict
+}
+|
+list_for_each_entry_safe at p1(c,...,member) { ... when != break;
+                                 when forall
+                                 when strict
+}
+|
+list_for_each_entry_safe_continue at p1(c,...,member) { ... when != break;
+                                 when forall
+                                 when strict
+}
+|
+list_for_each_entry_safe_from at p1(c,...,member) { ... when != break;
+                                 when forall
+                                 when strict
+}
+|
+list_for_each_entry_safe_reverse at p1(c,...,member) { ... when != break;
+                                 when forall
+                                 when strict
+}
+)
+...
+(
+list_for_each_entry(c,...) S
+|
+list_for_each_entry_reverse(c,...) S
+|
+list_for_each_entry_continue(c,...) S
+|
+list_for_each_entry_continue_reverse(c,...) S
+|
+list_for_each_entry_from(c,...) S
+|
+list_for_each_entry_safe(c,...) S
+|
+list_for_each_entry_safe(x,c,...) S
+|
+list_for_each_entry_safe_continue(c,...) S
+|
+list_for_each_entry_safe_continue(x,c,...) S
+|
+list_for_each_entry_safe_from(c,...) S
+|
+list_for_each_entry_safe_from(x,c,...) S
+|
+list_for_each_entry_safe_reverse(c,...) S
+|
+list_for_each_entry_safe_reverse(x,c,...) S
+|
+hlist_for_each_entry(c,...) S
+|
+hlist_for_each_entry_continue(c,...) S
+|
+hlist_for_each_entry_from(c,...) S
+|
+hlist_for_each_entry_safe(c,...) S
+|
+list_remove_head(x,c,...)
+|
+sizeof(<+...c...+>)
+|
+&c->member
+|
+c = E
+|
+*c at p2
+)
+
+ at script:python depends on org@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+cocci.print_main("invalid iterator index reference",p2)
+cocci.print_secs("iterator",p1)
+
+ at script:python depends on report@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+msg = "ERROR: invalid reference to the index variable of the iterator on line %s" % (p1[0].line)
+coccilib.report.print_report(p2[0], msg)
diff --git a/helpers/coccinelle/locks/call_kern.cocci b/helpers/coccinelle/locks/call_kern.cocci
new file mode 100644
index 0000000..669b244
--- /dev/null
+++ b/helpers/coccinelle/locks/call_kern.cocci
@@ -0,0 +1,105 @@
+/// Find functions that refer to GFP_KERNEL but are called with locks held.
+//# The proposed change of converting the GFP_KERNEL is not necessarily the
+//# correct one.  It may be desired to unlock the lock, or to not call the
+//# function under the lock in the first place.
+///
+// Confidence: Moderate
+// Copyright: (C) 2012 Nicolas Palix.  GPLv2.
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+ at gfp exists@
+identifier fn;
+position p;
+@@
+
+fn(...) {
+ ... when != read_unlock_irq(...)
+     when != write_unlock_irq(...)
+     when != read_unlock_irqrestore(...)
+     when != write_unlock_irqrestore(...)
+     when != spin_unlock(...)
+     when != spin_unlock_irq(...)
+     when != spin_unlock_irqrestore(...)
+     when != local_irq_enable(...)
+     when any
+ GFP_KERNEL at p
+ ... when any
+}
+
+ at locked exists@
+identifier gfp.fn;
+position p1,p2;
+@@
+
+(
+read_lock_irq at p1
+|
+write_lock_irq at p1
+|
+read_lock_irqsave at p1
+|
+write_lock_irqsave at p1
+|
+spin_lock at p1
+|
+spin_trylock at p1
+|
+spin_lock_irq at p1
+|
+spin_lock_irqsave at p1
+|
+local_irq_disable at p1
+)
+ (...)
+...  when != read_unlock_irq(...)
+     when != write_unlock_irq(...)
+     when != read_unlock_irqrestore(...)
+     when != write_unlock_irqrestore(...)
+     when != spin_unlock(...)
+     when != spin_unlock_irq(...)
+     when != spin_unlock_irqrestore(...)
+     when != local_irq_enable(...)
+fn at p2(...)
+
+ at depends on locked && patch@
+position gfp.p;
+@@
+
+- GFP_KERNEL at p
++ GFP_ATOMIC
+
+ at depends on locked && !patch@
+position gfp.p;
+@@
+
+* GFP_KERNEL at p
+
+ at script:python depends on !patch && org@
+p << gfp.p;
+fn << gfp.fn;
+p1 << locked.p1;
+p2 << locked.p2;
+@@
+
+cocci.print_main("lock",p1)
+cocci.print_secs("call",p2)
+cocci.print_secs("GFP_KERNEL",p)
+
+ at script:python depends on !patch && report@
+p << gfp.p;
+fn << gfp.fn;
+p1 << locked.p1;
+p2 << locked.p2;
+@@
+
+msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line)
+coccilib.report.print_report(p[0], msg)
diff --git a/helpers/coccinelle/locks/double_lock.cocci b/helpers/coccinelle/locks/double_lock.cocci
new file mode 100644
index 0000000..002752f
--- /dev/null
+++ b/helpers/coccinelle/locks/double_lock.cocci
@@ -0,0 +1,92 @@
+/// Find double locks.  False positives may occur when some paths cannot
+/// occur at execution, due to the values of variables, and when there is
+/// an intervening function call that releases the lock.
+///
+// Confidence: Moderate
+// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
+// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+
+ at locked@
+position p1;
+expression E1;
+position p;
+@@
+
+(
+mutex_lock at p1
+|
+mutex_trylock at p1
+|
+spin_lock at p1
+|
+spin_trylock at p1
+|
+read_lock at p1
+|
+read_trylock at p1
+|
+write_lock at p1
+|
+write_trylock at p1
+) (E1 at p,...);
+
+ at balanced@
+position p1 != locked.p1;
+position locked.p;
+identifier lock,unlock;
+expression x <= locked.E1;
+expression E,locked.E1;
+expression E2;
+@@
+
+if (E) {
+ <+... when != E1
+ lock(E1 at p,...)
+ ...+>
+}
+... when != E1
+    when != \(x = E2\|&x\)
+    when forall
+if (E) {
+ <+... when != E1
+ unlock at p1(E1,...)
+ ...+>
+}
+
+ at r depends on !balanced exists@
+expression x <= locked.E1;
+expression locked.E1;
+expression E2;
+identifier lock;
+position locked.p,p1,p2;
+@@
+
+lock at p1 (E1 at p,...);
+... when != E1
+    when != \(x = E2\|&x\)
+lock at p2 (E1,...);
+
+ at script:python depends on org@
+p1 << r.p1;
+p2 << r.p2;
+lock << r.lock;
+@@
+
+cocci.print_main(lock,p1)
+cocci.print_secs("second lock",p2)
+
+ at script:python depends on report@
+p1 << r.p1;
+p2 << r.p2;
+lock << r.lock;
+@@
+
+msg = "second lock on line %s" % (p2[0].line)
+coccilib.report.print_report(p1[0],msg)
diff --git a/helpers/coccinelle/locks/flags.cocci b/helpers/coccinelle/locks/flags.cocci
new file mode 100644
index 0000000..debd70e
--- /dev/null
+++ b/helpers/coccinelle/locks/flags.cocci
@@ -0,0 +1,80 @@
+/// Find nested lock+irqsave functions that use the same flags variables
+///
+// Confidence: High
+// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual context
+virtual org
+virtual report
+
+ at r exists@
+expression lock1,lock2,flags;
+position p1,p2;
+@@
+
+(
+spin_lock_irqsave at p1(lock1,flags)
+|
+read_lock_irqsave at p1(lock1,flags)
+|
+write_lock_irqsave at p1(lock1,flags)
+)
+... when != flags
+(
+spin_lock_irqsave(lock1,flags)
+|
+read_lock_irqsave(lock1,flags)
+|
+write_lock_irqsave(lock1,flags)
+|
+spin_lock_irqsave at p2(lock2,flags)
+|
+read_lock_irqsave at p2(lock2,flags)
+|
+write_lock_irqsave at p2(lock2,flags)
+)
+
+ at d exists@
+expression f <= r.flags;
+expression lock1,lock2,flags;
+position r.p1, r.p2;
+@@
+
+(
+*spin_lock_irqsave at p1(lock1,flags)
+|
+*read_lock_irqsave at p1(lock1,flags)
+|
+*write_lock_irqsave at p1(lock1,flags)
+)
+... when != f
+(
+*spin_lock_irqsave at p2(lock2,flags)
+|
+*read_lock_irqsave at p2(lock2,flags)
+|
+*write_lock_irqsave at p2(lock2,flags)
+)
+
+// ----------------------------------------------------------------------
+
+ at script:python depends on d && org@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+cocci.print_main("original lock",p1)
+cocci.print_secs("nested lock+irqsave that reuses flags",p2)
+
+ at script:python depends on d && report@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+msg="ERROR: nested lock+irqsave that reuses flags from line %s." % (p1[0].line)
+coccilib.report.print_report(p2[0], msg)
diff --git a/helpers/coccinelle/locks/mini_lock.cocci b/helpers/coccinelle/locks/mini_lock.cocci
new file mode 100644
index 0000000..47f649b
--- /dev/null
+++ b/helpers/coccinelle/locks/mini_lock.cocci
@@ -0,0 +1,96 @@
+/// Find missing unlocks.  This semantic match considers the specific case
+/// where the unlock is missing from an if branch, and there is a lock
+/// before the if and an unlock after the if.  False positives are due to
+/// cases where the if branch represents a case where the function is
+/// supposed to exit with the lock held, or where there is some preceding
+/// function call that releases the lock.
+///
+// Confidence: Moderate
+// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual context
+virtual org
+virtual report
+
+ at prelocked@
+position p1,p;
+expression E1;
+@@
+
+(
+mutex_lock at p1
+|
+mutex_trylock at p1
+|
+spin_lock at p1
+|
+spin_trylock at p1
+|
+read_lock at p1
+|
+read_trylock at p1
+|
+write_lock at p1
+|
+write_trylock at p1
+|
+read_lock_irq at p1
+|
+write_lock_irq at p1
+|
+read_lock_irqsave at p1
+|
+write_lock_irqsave at p1
+|
+spin_lock_irq at p1
+|
+spin_lock_irqsave at p1
+) (E1 at p,...);
+
+ at looped@
+position r;
+@@
+
+for(...;...;...) { <+... return at r ...; ...+> }
+
+ at err exists@
+expression E1;
+position prelocked.p;
+position up != prelocked.p1;
+position r!=looped.r;
+identifier lock,unlock;
+@@
+
+*lock(E1 at p,...);
+<+... when != E1
+if (...) {
+  ... when != E1
+*  return at r ...;
+}
+...+>
+*unlock at up(E1,...);
+
+ at script:python depends on org@
+p << prelocked.p1;
+lock << err.lock;
+unlock << err.unlock;
+p2 << err.r;
+@@
+
+cocci.print_main(lock,p)
+cocci.print_secs(unlock,p2)
+
+ at script:python depends on report@
+p << prelocked.p1;
+lock << err.lock;
+unlock << err.unlock;
+p2 << err.r;
+@@
+
+msg = "preceding lock on line %s" % (p[0].line)
+coccilib.report.print_report(p2[0],msg)
diff --git a/helpers/coccinelle/misc/boolinit.cocci b/helpers/coccinelle/misc/boolinit.cocci
new file mode 100644
index 0000000..b9abed4
--- /dev/null
+++ b/helpers/coccinelle/misc/boolinit.cocci
@@ -0,0 +1,178 @@
+/// Bool initializations should use true and false.  Bool tests don't need
+/// comparisons.  Based on contributions from Joe Perches, Rusty Russell
+/// and Bruce W Allan.
+///
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Options: --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+ at depends on patch@
+bool t;
+symbol true;
+symbol false;
+@@
+
+(
+- t == true
++ t
+|
+- true == t
++ t
+|
+- t != true
++ !t
+|
+- true != t
++ !t
+|
+- t == false
++ !t
+|
+- false == t
++ !t
+|
+- t != false
++ t
+|
+- false != t
++ t
+)
+
+ at depends on patch disable is_zero, isnt_zero@
+bool t;
+@@
+
+(
+- t == 1
++ t
+|
+- t != 1
++ !t
+|
+- t == 0
++ !t
+|
+- t != 0
++ t
+)
+
+ at depends on patch@
+bool b;
+@@
+(
+ b =
+- 0
++ false
+|
+ b =
+- 1
++ true
+)
+
+// ---------------------------------------------------------------------
+
+ at r1 depends on !patch@
+bool t;
+position p;
+@@
+
+(
+* t at p == true
+|
+* true == t at p
+|
+* t at p != true
+|
+* true != t at p
+|
+* t at p == false
+|
+* false == t at p
+|
+* t at p != false
+|
+* false != t at p
+)
+
+ at r2 depends on !patch disable is_zero, isnt_zero@
+bool t;
+position p;
+@@
+
+(
+* t at p == 1
+|
+* t at p != 1
+|
+* t at p == 0
+|
+* t at p != 0
+)
+
+ at r3 depends on !patch@
+bool b;
+position p1,p2;
+constant c;
+@@
+(
+*b at p1 = 0
+|
+*b at p1 = 1
+|
+*b at p2 = c
+)
+
+ at script:python depends on org@
+p << r1.p;
+@@
+
+cocci.print_main("WARNING: Comparison to bool",p)
+
+ at script:python depends on org@
+p << r2.p;
+@@
+
+cocci.print_main("WARNING: Comparison of bool to 0/1",p)
+
+ at script:python depends on org@
+p1 << r3.p1;
+@@
+
+cocci.print_main("WARNING: Assignment of bool to 0/1",p1)
+
+ at script:python depends on org@
+p2 << r3.p2;
+@@
+
+cocci.print_main("ERROR: Assignment of bool to non-0/1 constant",p2)
+
+ at script:python depends on report@
+p << r1.p;
+@@
+
+coccilib.report.print_report(p[0],"WARNING: Comparison to bool")
+
+ at script:python depends on report@
+p << r2.p;
+@@
+
+coccilib.report.print_report(p[0],"WARNING: Comparison of bool to 0/1")
+
+ at script:python depends on report@
+p1 << r3.p1;
+@@
+
+coccilib.report.print_report(p1[0],"WARNING: Assignment of bool to 0/1")
+
+ at script:python depends on report@
+p2 << r3.p2;
+@@
+
+coccilib.report.print_report(p2[0],"ERROR: Assignment of bool to non-0/1 constant")
diff --git a/helpers/coccinelle/misc/boolreturn.cocci b/helpers/coccinelle/misc/boolreturn.cocci
new file mode 100644
index 0000000..a43c7b0
--- /dev/null
+++ b/helpers/coccinelle/misc/boolreturn.cocci
@@ -0,0 +1,58 @@
+/// Return statements in functions returning bool should use
+/// true/false instead of 1/0.
+//
+// Confidence: High
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual report
+virtual context
+
+ at r1 depends on patch@
+identifier fn;
+typedef bool;
+symbol false;
+symbol true;
+@@
+
+bool fn ( ... )
+{
+<...
+return
+(
+- 0
++ false
+|
+- 1
++ true
+)
+  ;
+...>
+}
+
+ at r2 depends on report || context@
+identifier fn;
+position p;
+@@
+
+bool fn ( ... )
+{
+<...
+return
+(
+* 0 at p
+|
+* 1 at p
+)
+  ;
+...>
+}
+
+
+ at script:python depends on report@
+p << r2.p;
+fn << r2.fn;
+@@
+
+msg = "WARNING: return of 0/1 in function '%s' with return type bool" % fn
+coccilib.report.print_report(p[0], msg)
diff --git a/helpers/coccinelle/misc/cstptr.cocci b/helpers/coccinelle/misc/cstptr.cocci
new file mode 100644
index 0000000..f0368b3
--- /dev/null
+++ b/helpers/coccinelle/misc/cstptr.cocci
@@ -0,0 +1,41 @@
+/// PTR_ERR should be applied before its argument is reassigned, typically
+/// to NULL
+///
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+virtual context
+
+ at r exists@
+expression e,e1;
+constant c;
+position p1,p2;
+@@
+
+*e at p1 = c
+... when != e = e1
+    when != &e
+    when != true IS_ERR(e)
+*PTR_ERR at p2(e)
+
+ at script:python depends on org@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+cocci.print_main("PTR_ERR",p2)
+cocci.print_secs("assignment",p1)
+
+ at script:python depends on report@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+msg = "ERROR: PTR_ERR applied after initialization to constant on line %s" % (p1[0].line)
+coccilib.report.print_report(p2[0],msg)
diff --git a/helpers/coccinelle/misc/doubleinit.cocci b/helpers/coccinelle/misc/doubleinit.cocci
new file mode 100644
index 0000000..c0c3371
--- /dev/null
+++ b/helpers/coccinelle/misc/doubleinit.cocci
@@ -0,0 +1,53 @@
+/// Find duplicate field initializations.  This has a high rate of false
+/// positives due to #ifdefs, which Coccinelle is not aware of in a structure
+/// initialization.
+///
+// Confidence: Low
+// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+
+ at r@
+identifier I, s, fld;
+position p0,p;
+expression E;
+@@
+
+struct I s =@p0 { ..., .fld at p = E, ...};
+
+ at s@
+identifier I, s, r.fld;
+position r.p0,p;
+expression E;
+@@
+
+struct I s =@p0 { ..., .fld at p = E, ...};
+
+ at script:python depends on org@
+p0 << r.p0;
+fld << r.fld;
+ps << s.p;
+pr << r.p;
+@@
+
+if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
+  cocci.print_main(fld,p0)
+  cocci.print_secs("s",ps)
+  cocci.print_secs("r",pr)
+
+ at script:python depends on report@
+p0 << r.p0;
+fld << r.fld;
+ps << s.p;
+pr << r.p;
+@@
+
+if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
+  msg = "%s: first occurrence line %s, second occurrence line %s" % (fld,ps[0].line,pr[0].line)
+  coccilib.report.print_report(p0[0],msg)
diff --git a/helpers/coccinelle/misc/ifaddr.cocci b/helpers/coccinelle/misc/ifaddr.cocci
new file mode 100644
index 0000000..8aebd18
--- /dev/null
+++ b/helpers/coccinelle/misc/ifaddr.cocci
@@ -0,0 +1,35 @@
+/// the address of a variable or field is non-zero is likely always to bo
+/// non-zero
+///
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+virtual context
+
+ at r@
+expression x;
+statement S1,S2;
+position p;
+@@
+
+*if at p (&x)
+ S1 else S2
+
+ at script:python depends on org@
+p << r.p;
+@@
+
+cocci.print_main("test of a variable/field address",p)
+
+ at script:python depends on report@
+p << r.p;
+@@
+
+msg = "ERROR: test of a variable/field address"
+coccilib.report.print_report(p[0],msg)
diff --git a/helpers/coccinelle/misc/ifcol.cocci b/helpers/coccinelle/misc/ifcol.cocci
new file mode 100644
index 0000000..d0d00ef
--- /dev/null
+++ b/helpers/coccinelle/misc/ifcol.cocci
@@ -0,0 +1,48 @@
+/// Find confusingly indented code in or after an if.  An if branch should
+/// be indented.  The code following an if should not be indented.
+/// Sometimes, code after an if that is indented is actually intended to be
+/// part of the if branch.
+///
+/// This has a high rate of false positives, because Coccinelle's column
+/// calculation does not distinguish between spaces and tabs, so code that
+/// is not visually aligned may be considered to be in the same column.
+///
+// Confidence: Low
+// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
+// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+
+ at r disable braces4@
+position p1,p2;
+statement S1,S2;
+@@
+
+(
+if (...) { ... }
+|
+if (...) S1 at p1 S2 at p2
+)
+
+ at script:python depends on org@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+if (p1[0].column == p2[0].column):
+  cocci.print_main("branch",p1)
+  cocci.print_secs("after",p2)
+
+ at script:python depends on report@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+if (p1[0].column == p2[0].column):
+  msg = "code aligned with following code on line %s" % (p2[0].line)
+  coccilib.report.print_report(p1[0],msg)
diff --git a/helpers/coccinelle/misc/irqf_oneshot.cocci b/helpers/coccinelle/misc/irqf_oneshot.cocci
new file mode 100644
index 0000000..6cfde94
--- /dev/null
+++ b/helpers/coccinelle/misc/irqf_oneshot.cocci
@@ -0,0 +1,65 @@
+/// Make sure threaded IRQs without a primary handler are always request with
+/// IRQF_ONESHOT
+///
+//
+// Confidence: Good
+// Comments:
+// Options: --no-includes
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+ at r1@
+expression irq;
+expression thread_fn;
+expression flags;
+position p;
+@@
+request_threaded_irq at p(irq, NULL, thread_fn,
+(
+flags | IRQF_ONESHOT
+|
+IRQF_ONESHOT
+)
+, ...)
+
+ at depends on patch@
+expression irq;
+expression thread_fn;
+expression flags;
+position p != r1.p;
+@@
+request_threaded_irq at p(irq, NULL, thread_fn,
+(
+-0
++IRQF_ONESHOT
+|
+-flags
++flags | IRQF_ONESHOT
+)
+, ...)
+
+ at depends on context@
+position p != r1.p;
+@@
+*request_threaded_irq at p(...)
+
+ at match depends on report || org@
+expression irq;
+position p != r1.p;
+@@
+request_threaded_irq at p(irq, NULL, ...)
+
+ at script:python depends on org@
+p << match.p;
+@@
+msg = "ERROR: Threaded IRQ with no primary handler requested without IRQF_ONESHOT"
+coccilib.org.print_todo(p[0],msg)
+
+ at script:python depends on report@
+p << match.p;
+@@
+msg = "ERROR: Threaded IRQ with no primary handler requested without IRQF_ONESHOT"
+coccilib.report.print_report(p[0],msg)
diff --git a/helpers/coccinelle/misc/memcpy-assign.cocci b/helpers/coccinelle/misc/memcpy-assign.cocci
new file mode 100644
index 0000000..afd058b
--- /dev/null
+++ b/helpers/coccinelle/misc/memcpy-assign.cocci
@@ -0,0 +1,103 @@
+//
+// Replace memcpy with struct assignment.
+//
+// Confidence: High
+// Copyright: (C) 2012 Peter Senna Tschudin, INRIA/LIP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual report
+virtual context
+virtual org
+
+ at r1 depends on !patch@
+identifier struct_name;
+struct struct_name to;
+struct struct_name from;
+struct struct_name *top;
+struct struct_name *fromp;
+position p;
+@@
+memcpy at p(\(&(to)\|top\), \(&(from)\|fromp\), \(sizeof(to)\|sizeof(from)\|sizeof(struct struct_name)\|sizeof(*top)\|sizeof(*fromp)\))
+
+ at script:python depends on report@
+p << r1.p;
+@@
+coccilib.report.print_report(p[0],"Replace memcpy with struct assignment")
+
+ at depends on context@
+position r1.p;
+@@
+*memcpy at p(...);
+
+ at script:python depends on org@
+p << r1.p;
+@@
+cocci.print_main("Replace memcpy with struct assignment",p)
+
+ at depends on patch@
+identifier struct_name;
+struct struct_name to;
+struct struct_name from;
+@@
+(
+-memcpy(&(to), &(from), sizeof(to));
++to = from;
+|
+-memcpy(&(to), &(from), sizeof(from));
++to = from;
+|
+-memcpy(&(to), &(from), sizeof(struct struct_name));
++to = from;
+)
+
+ at depends on patch@
+identifier struct_name;
+struct struct_name to;
+struct struct_name *from;
+@@
+(
+-memcpy(&(to), from, sizeof(to));
++to = *from;
+|
+-memcpy(&(to), from, sizeof(*from));
++to = *from;
+|
+-memcpy(&(to), from, sizeof(struct struct_name));
++to = *from;
+)
+
+ at depends on patch@
+identifier struct_name;
+struct struct_name *to;
+struct struct_name from;
+@@
+(
+-memcpy(to, &(from), sizeof(*to));
++ *to = from;
+|
+-memcpy(to, &(from), sizeof(from));
++ *to = from;
+|
+-memcpy(to, &(from), sizeof(struct struct_name));
++ *to = from;
+)
+
+ at depends on patch@
+identifier struct_name;
+struct struct_name *to;
+struct struct_name *from;
+@@
+(
+-memcpy(to, from, sizeof(*to));
++ *to = *from;
+|
+-memcpy(to, from, sizeof(*from));
++ *to = *from;
+|
+-memcpy(to, from, sizeof(struct struct_name));
++ *to = *from;
+)
+
diff --git a/helpers/coccinelle/misc/noderef.cocci b/helpers/coccinelle/misc/noderef.cocci
new file mode 100644
index 0000000..80a831c
--- /dev/null
+++ b/helpers/coccinelle/misc/noderef.cocci
@@ -0,0 +1,65 @@
+/// sizeof when applied to a pointer typed expression gives the size of
+/// the pointer
+///
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+virtual context
+virtual patch
+
+ at depends on patch@
+expression *x;
+expression f;
+type T;
+@@
+
+(
+x = <+... sizeof(
+- x
++ *x
+   ) ...+>
+|
+f(...,(T)(x),...,sizeof(
+- x
++ *x
+   ),...)
+|
+f(...,sizeof(x),...,(T)(
+- x
++ *x
+   ),...)
+)
+
+ at r depends on !patch@
+expression *x;
+expression f;
+position p;
+type T;
+@@
+
+(
+*x = <+... sizeof at p(x) ...+>
+|
+*f(...,(T)(x),...,sizeof at p(x),...)
+|
+*f(...,sizeof at p(x),...,(T)(x),...)
+)
+
+ at script:python depends on org@
+p << r.p;
+@@
+
+cocci.print_main("application of sizeof to pointer",p)
+
+ at script:python depends on report@
+p << r.p;
+@@
+
+msg = "ERROR: application of sizeof to pointer"
+coccilib.report.print_report(p[0],msg)
diff --git a/helpers/coccinelle/misc/orplus.cocci b/helpers/coccinelle/misc/orplus.cocci
new file mode 100644
index 0000000..81fabf3
--- /dev/null
+++ b/helpers/coccinelle/misc/orplus.cocci
@@ -0,0 +1,55 @@
+/// Check for constants that are added but are used elsewhere as bitmasks
+/// The results should be checked manually to ensure that the nonzero
+/// bits in the two constants are actually disjoint.
+///
+// Confidence: Moderate
+// Copyright: (C) 2013 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2013 Gilles Muller, INRIA/LIP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+virtual context
+
+ at r@
+constant c;
+identifier i;
+expression e;
+@@
+
+(
+e | c at i
+|
+e & c at i
+|
+e |= c at i
+|
+e &= c at i
+)
+
+ at s@
+constant r.c,c1;
+identifier i1;
+position p;
+@@
+
+(
+ c1 + c - 1
+|
+*c1 at i1 + at p c
+)
+
+ at script:python depends on org@
+p << s.p;
+@@
+
+cocci.print_main("sum of probable bitmasks, consider |",p)
+
+ at script:python depends on report@
+p << s.p;
+@@
+
+msg = "WARNING: sum of probable bitmasks, consider |"
+coccilib.report.print_report(p[0],msg)
diff --git a/helpers/coccinelle/misc/semicolon.cocci b/helpers/coccinelle/misc/semicolon.cocci
new file mode 100644
index 0000000..a47eba2
--- /dev/null
+++ b/helpers/coccinelle/misc/semicolon.cocci
@@ -0,0 +1,83 @@
+///
+/// Removes unneeded semicolon.
+///
+// Confidence: Moderate
+// Copyright: (C) 2012 Peter Senna Tschudin, INRIA/LIP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments: Some false positives on empty default cases in switch statements.
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual report
+virtual context
+virtual org
+
+ at r_default@
+position p;
+@@
+switch (...)
+{
+default: ...;@p
+}
+
+ at r_case@
+position p;
+@@
+(
+switch (...)
+{
+case ...:;@p
+}
+|
+switch (...)
+{
+case ...:...
+case ...:;@p
+}
+|
+switch (...)
+{
+case ...:...
+case ...:
+case ...:;@p
+}
+)
+
+ at r1@
+statement S;
+position p1;
+position p != {r_default.p, r_case.p};
+identifier label;
+@@
+(
+label:;
+|
+S at p1;@p
+)
+
+ at script:python@
+p << r1.p;
+p1 << r1.p1;
+@@
+if p[0].line != p1[0].line_end:
+	cocci.include_match(False)
+
+ at depends on patch@
+position r1.p;
+@@
+-;@p
+
+ at script:python depends on report@
+p << r1.p;
+@@
+coccilib.report.print_report(p[0],"Unneeded semicolon")
+
+ at depends on context@
+position r1.p;
+@@
+*;@p
+
+ at script:python depends on org@
+p << r1.p;
+@@
+cocci.print_main("Unneeded semicolon",p)
diff --git a/helpers/coccinelle/misc/warn.cocci b/helpers/coccinelle/misc/warn.cocci
new file mode 100644
index 0000000..d2e5b6c
--- /dev/null
+++ b/helpers/coccinelle/misc/warn.cocci
@@ -0,0 +1,109 @@
+/// Use WARN(1,...) rather than printk followed by WARN_ON(1)
+///
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+ at bad1@
+position p;
+@@
+
+printk(...);
+printk at p(...);
+WARN_ON(1);
+
+ at r1 depends on context || report || org@
+position p != bad1.p;
+@@
+
+ printk at p(...);
+*WARN_ON(1);
+
+ at script:python depends on org@
+p << r1.p;
+@@
+
+cocci.print_main("printk + WARN_ON can be just WARN",p)
+
+ at script:python depends on report@
+p << r1.p;
+@@
+
+msg = "SUGGESTION: printk + WARN_ON can be just WARN"
+coccilib.report.print_report(p[0],msg)
+
+ at ok1 depends on patch@
+expression list es;
+position p != bad1.p;
+@@
+
+-printk at p(
++WARN(1,
+  es);
+-WARN_ON(1);
+
+ at depends on patch@
+expression list ok1.es;
+@@
+
+if (...)
+- {
+  WARN(1,es);
+- }
+
+// --------------------------------------------------------------------
+
+ at bad2@
+position p;
+@@
+
+printk(...);
+printk at p(...);
+WARN_ON_ONCE(1);
+
+ at r2 depends on context || report || org@
+position p != bad1.p;
+@@
+
+ printk at p(...);
+*WARN_ON_ONCE(1);
+
+ at script:python depends on org@
+p << r2.p;
+@@
+
+cocci.print_main("printk + WARN_ON_ONCE can be just WARN_ONCE",p)
+
+ at script:python depends on report@
+p << r2.p;
+@@
+
+msg = "SUGGESTION: printk + WARN_ON_ONCE can be just WARN_ONCE"
+coccilib.report.print_report(p[0],msg)
+
+ at ok2 depends on patch@
+expression list es;
+position p != bad2.p;
+@@
+
+-printk at p(
++WARN_ONCE(1,
+  es);
+-WARN_ON_ONCE(1);
+
+ at depends on patch@
+expression list ok2.es;
+@@
+
+if (...)
+- {
+  WARN_ONCE(1,es);
+- }
diff --git a/helpers/coccinelle/null/badzero.cocci b/helpers/coccinelle/null/badzero.cocci
new file mode 100644
index 0000000..d79baf7
--- /dev/null
+++ b/helpers/coccinelle/null/badzero.cocci
@@ -0,0 +1,237 @@
+/// Compare pointer-typed values to NULL rather than 0
+///
+//# This makes an effort to choose between !x and x == NULL.  !x is used
+//# if it has previously been used with the function used to initialize x.
+//# This relies on type information.  More type information can be obtained
+//# using the option -all_includes and the option -I to specify an
+//# include path.
+//
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options:
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+ at initialize:ocaml@
+let negtable = Hashtbl.create 101
+
+ at depends on patch@
+expression *E;
+identifier f;
+@@
+
+(
+  (E = f(...)) ==
+- 0
++ NULL
+|
+  (E = f(...)) !=
+- 0
++ NULL
+|
+- 0
++ NULL
+  == (E = f(...))
+|
+- 0
++ NULL
+  != (E = f(...))
+)
+
+
+ at t1 depends on !patch@
+expression *E;
+identifier f;
+position p;
+@@
+
+(
+  (E = f(...)) ==
+* 0 at p
+|
+  (E = f(...)) !=
+* 0 at p
+|
+* 0 at p
+  == (E = f(...))
+|
+* 0 at p
+  != (E = f(...))
+)
+
+ at script:python depends on org@
+p << t1.p;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
+
+ at script:python depends on report@
+p << t1.p;
+@@
+
+coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
+
+// Tests of returned values
+
+ at s@
+identifier f;
+expression E,E1;
+@@
+
+ E = f(...)
+ ... when != E = E1
+ !E
+
+ at script:ocaml depends on s@
+f << s.f;
+@@
+
+try let _ = Hashtbl.find negtable f in ()
+with Not_found -> Hashtbl.add negtable f ()
+
+@ r disable is_zero,isnt_zero exists @
+expression *E;
+identifier f;
+@@
+
+E = f(...)
+...
+(E == 0
+|E != 0
+|0 == E
+|0 != E
+)
+
+ at script:ocaml@
+f << r.f;
+@@
+
+try let _ = Hashtbl.find negtable f in ()
+with Not_found -> include_match false
+
+// This rule may lead to inconsistent path problems, if E is defined in two
+// places
+@ depends on patch disable is_zero,isnt_zero @
+expression *E;
+expression E1;
+identifier r.f;
+@@
+
+E = f(...)
+<...
+(
+- E == 0
++ !E
+|
+- E != 0
++ E
+|
+- 0 == E
++ !E
+|
+- 0 != E
++ E
+)
+...>
+?E = E1
+
+ at t2 depends on !patch disable is_zero,isnt_zero @
+expression *E;
+expression E1;
+identifier r.f;
+position p1;
+position p2;
+@@
+
+E = f(...)
+<...
+(
+* E == 0 at p1
+|
+* E != 0 at p2
+|
+* 0 at p1 == E
+|
+* 0 at p1 != E
+)
+...>
+?E = E1
+
+ at script:python depends on org@
+p << t2.p1;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0, suggest !E")
+
+ at script:python depends on org@
+p << t2.p2;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
+
+ at script:python depends on report@
+p << t2.p1;
+@@
+
+coccilib.report.print_report(p[0], "WARNING comparing pointer to 0, suggest !E")
+
+ at script:python depends on report@
+p << t2.p2;
+@@
+
+coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
+
+@ depends on patch disable is_zero,isnt_zero @
+expression *E;
+@@
+
+(
+  E ==
+- 0
++ NULL
+|
+  E !=
+- 0
++ NULL
+|
+- 0
++ NULL
+  == E
+|
+- 0
++ NULL
+  != E
+)
+
+@ t3 depends on !patch disable is_zero,isnt_zero @
+expression *E;
+position p;
+@@
+
+(
+* E == 0 at p
+|
+* E != 0 at p
+|
+* 0 at p == E
+|
+* 0 at p != E
+)
+
+ at script:python depends on org@
+p << t3.p;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
+
+ at script:python depends on report@
+p << t3.p;
+@@
+
+coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
diff --git a/helpers/coccinelle/null/deref_null.cocci b/helpers/coccinelle/null/deref_null.cocci
new file mode 100644
index 0000000..cdac6cf
--- /dev/null
+++ b/helpers/coccinelle/null/deref_null.cocci
@@ -0,0 +1,282 @@
+///
+/// A variable is dereference under a NULL test.
+/// Even though it is know to be NULL.
+///
+// Confidence: Moderate
+// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
+// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments: -I ... -all_includes can give more complete results
+// Options:
+
+virtual context
+virtual org
+virtual report
+
+ at ifm@
+expression *E;
+statement S1,S2;
+position p1;
+@@
+
+if at p1 ((E == NULL && ...) || ...) S1 else S2
+
+// The following two rules are separate, because both can match a single
+// expression in different ways
+ at pr1 expression@
+expression *ifm.E;
+identifier f;
+position p1;
+@@
+
+ (E != NULL && ...) ? <+...E->f at p1...+> : ...
+
+ at pr2 expression@
+expression *ifm.E;
+identifier f;
+position p2;
+@@
+
+(
+  (E != NULL) && ... && <+...E->f at p2...+>
+|
+  (E == NULL) || ... || <+...E->f at p2...+>
+|
+ sizeof(<+...E->f at p2...+>)
+)
+
+// For org and report modes
+
+ at r depends on !context && (org || report) exists@
+expression subE <= ifm.E;
+expression *ifm.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr1.p1,pr2.p2};
+position ifm.p1;
+@@
+
+if at p1 ((E == NULL && ...) || ...)
+{
+  ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+ E->f at p // bad use
+)
+  ... when any
+  return ...;
+}
+else S3
+
+ at script:python depends on !context && !org && report@
+p << r.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+coccilib.report.print_report(p[0], msg)
+cocci.include_match(False)
+
+ at script:python depends on !context && org && !report@
+p << r.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+cocci.print_main(msg_safe,p)
+cocci.include_match(False)
+
+ at s depends on !context && (org || report) exists@
+expression subE <= ifm.E;
+expression *ifm.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr1.p1,pr2.p2};
+position ifm.p1;
+@@
+
+if at p1 ((E == NULL && ...) || ...)
+{
+  ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+ E->f at p // bad use
+)
+  ... when any
+}
+else S3
+
+ at script:python depends on !context && !org && report@
+p << s.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+coccilib.report.print_report(p[0], msg)
+
+ at script:python depends on !context && org && !report@
+p << s.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+cocci.print_main(msg_safe,p)
+
+// For context mode
+
+ at depends on context && !org && !report exists@
+expression subE <= ifm.E;
+expression *ifm.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr1.p1,pr2.p2};
+position ifm.p1;
+@@
+
+if at p1 ((E == NULL && ...) || ...)
+{
+  ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+* E->f at p // bad use
+)
+  ... when any
+  return ...;
+}
+else S3
+
+// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
+// It is need because the previous rule as already made a "change".
+
+ at ifm1@
+expression *E;
+statement S1,S2;
+position p1;
+@@
+
+if at p1 ((E == NULL && ...) || ...) S1 else S2
+
+ at pr11 expression@
+expression *ifm1.E;
+identifier f;
+position p1;
+@@
+
+ (E != NULL && ...) ? <+...E->f at p1...+> : ...
+
+ at pr12 expression@
+expression *ifm1.E;
+identifier f;
+position p2;
+@@
+
+(
+  (E != NULL) && ... && <+...E->f at p2...+>
+|
+  (E == NULL) || ... || <+...E->f at p2...+>
+|
+ sizeof(<+...E->f at p2...+>)
+)
+
+ at depends on context && !org && !report exists@
+expression subE <= ifm1.E;
+expression *ifm1.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr11.p1,pr12.p2};
+position ifm1.p1;
+@@
+
+if at p1 ((E == NULL && ...) || ...)
+{
+  ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+* E->f at p // bad use
+)
+  ... when any
+}
+else S3
diff --git a/helpers/coccinelle/null/eno.cocci b/helpers/coccinelle/null/eno.cocci
new file mode 100644
index 0000000..9bd29aa
--- /dev/null
+++ b/helpers/coccinelle/null/eno.cocci
@@ -0,0 +1,48 @@
+/// The various basic memory allocation functions don't return ERR_PTR
+///
+// Confidence: High
+// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+ at depends on patch@
+expression x,E;
+@@
+
+x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...)
+... when != x = E
+- IS_ERR(x)
++ !x
+
+ at r depends on !patch exists@
+expression x,E;
+position p1,p2;
+@@
+
+*x = \(kmalloc at p1\|kzalloc at p1\|kcalloc at p1\|kmem_cache_alloc at p1\|kmem_cache_zalloc at p1\|kmem_cache_alloc_node at p1\|kmalloc_node at p1\|kzalloc_node at p1\)(...)
+... when != x = E
+* IS_ERR at p2(x)
+
+ at script:python depends on org@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+cocci.print_main("alloc call",p1)
+cocci.print_secs("IS_ERR that should be NULL tests",p2)
+
+ at script:python depends on report@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+msg = "ERROR: allocation function on line %s returns NULL not ERR_PTR on failure" % (p1[0].line)
+coccilib.report.print_report(p2[0], msg)
diff --git a/helpers/coccinelle/null/kmerr.cocci b/helpers/coccinelle/null/kmerr.cocci
new file mode 100644
index 0000000..5354a79
--- /dev/null
+++ b/helpers/coccinelle/null/kmerr.cocci
@@ -0,0 +1,72 @@
+/// This semantic patch looks for kmalloc etc that are not followed by a
+/// NULL check.  It only gives a report in the case where there is some
+/// error handling code later in the function, which may be helpful
+/// in determining what the error handling code for the call to kmalloc etc
+/// should be.
+///
+// Confidence: High
+// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
+// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual context
+virtual org
+virtual report
+
+ at withtest@
+expression x;
+position p;
+identifier f,fld;
+@@
+
+x at p = f(...);
+... when != x->fld
+\(x == NULL \| x != NULL\)
+
+ at fixed depends on context && !org && !report@
+expression x,x1;
+position p1 != withtest.p;
+statement S;
+position any withtest.p;
+identifier f;
+@@
+
+*x at p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
+...
+*x1 at p = f(...);
+if (!x1) S
+
+// ------------------------------------------------------------------------
+
+ at rfixed depends on (org || report) && !context exists@
+expression x,x1;
+position p1 != withtest.p;
+position p2;
+statement S;
+position any withtest.p;
+identifier f;
+@@
+
+x at p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
+...
+x1 at p = f at p2(...);
+if (!x1) S
+
+ at script:python depends on org@
+p1 << rfixed.p1;
+p2 << rfixed.p2;
+@@
+
+cocci.print_main("alloc call",p1)
+cocci.print_secs("possible model",p2)
+
+ at script:python depends on report@
+p1 << rfixed.p1;
+p2 << rfixed.p2;
+@@
+
+msg = "alloc with no test, possible model on line %s" % (p2[0].line)
+coccilib.report.print_report(p1[0],msg)
diff --git a/helpers/coccinelle/tests/doublebitand.cocci b/helpers/coccinelle/tests/doublebitand.cocci
new file mode 100644
index 0000000..72f1572
--- /dev/null
+++ b/helpers/coccinelle/tests/doublebitand.cocci
@@ -0,0 +1,54 @@
+/// Find bit operations that include the same argument more than once
+//# One source of false positives is when the argument performs a side
+//# effect.  Another source of false positives is when a neutral value
+//# such as 0 for | is used to indicate no information, to maintain the
+//# same structure as other similar expressions
+///
+// Confidence: Moderate
+// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
+// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual context
+virtual org
+virtual report
+
+ at r expression@
+expression E;
+position p;
+@@
+
+(
+*        E at p
+         & ... & E
+|
+*        E at p
+         | ... | E
+|
+*        E at p
+         & ... & !E
+|
+*        E at p
+         | ... | !E
+|
+*        !E at p
+         & ... & E
+|
+*        !E at p
+         | ... | E
+)
+
+ at script:python depends on org@
+p << r.p;
+@@
+
+cocci.print_main("duplicated argument to & or |",p)
+
+ at script:python depends on report@
+p << r.p;
+@@
+
+coccilib.report.print_report(p[0],"duplicated argument to & or |")
diff --git a/helpers/coccinelle/tests/doubletest.cocci b/helpers/coccinelle/tests/doubletest.cocci
new file mode 100644
index 0000000..78d74c2
--- /dev/null
+++ b/helpers/coccinelle/tests/doubletest.cocci
@@ -0,0 +1,40 @@
+/// Find &&/|| operations that include the same argument more than once
+//# A common source of false positives is when the argument performs a side
+//# effect.
+///
+// Confidence: Moderate
+// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
+// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual context
+virtual org
+virtual report
+
+ at r expression@
+expression E;
+position p;
+@@
+
+(
+* E at p
+  || ... || E
+|
+* E at p
+  && ... && E
+)
+
+ at script:python depends on org@
+p << r.p;
+@@
+
+cocci.print_main("duplicated argument to && or ||",p)
+
+ at script:python depends on report@
+p << r.p;
+@@
+
+coccilib.report.print_report(p[0],"duplicated argument to && or ||")
diff --git a/helpers/coccinelle/tests/odd_ptr_err.cocci b/helpers/coccinelle/tests/odd_ptr_err.cocci
new file mode 100644
index 0000000..cfe0a35
--- /dev/null
+++ b/helpers/coccinelle/tests/odd_ptr_err.cocci
@@ -0,0 +1,65 @@
+/// PTR_ERR should access the value just tested by IS_ERR
+//# There can be false positives in the patch case, where it is the call
+//# IS_ERR that is wrong.
+///
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA.  GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+ at depends on patch@
+expression e,e1;
+@@
+
+(
+if (IS_ERR(e)) { ... PTR_ERR(e) ... }
+|
+if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... }
+|
+if (IS_ERR(e))
+ { ...
+  PTR_ERR(
+-   e1
++   e
+  )
+   ... }
+)
+
+ at r depends on !patch@
+expression e,e1;
+position p1,p2;
+@@
+
+(
+if (IS_ERR(e)) { ... PTR_ERR(e) ... }
+|
+if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... }
+|
+*if (IS_ERR at p1(e))
+ { ...
+*  PTR_ERR at p2(e1)
+   ... }
+)
+
+ at script:python depends on org@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+cocci.print_main("inconsistent IS_ERR and PTR_ERR",p1)
+cocci.print_secs("PTR_ERR",p2)
+
+ at script:python depends on report@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+msg = "inconsistent IS_ERR and PTR_ERR, PTR_ERR on line %s" % (p2[0].line)
+coccilib.report.print_report(p1[0],msg)
diff --git a/helpers/libshell/COPYING b/helpers/libshell/COPYING
new file mode 100644
index 0000000..462758f
--- /dev/null
+++ b/helpers/libshell/COPYING
@@ -0,0 +1,26 @@
+The file
+	shell-getopt
+Version 1.2 2008 by Alexey Gladkov <legion at altlinux.org>,
+            2008 by Dmitry V. Levin <ldv at altlinux.org>
+Version 1.1 2004 by Raphael <raphael at oninet dot pt>
+Version 1.0 1997 by Grigoriy Strokin (grg at philol.msu.ru), Public Domain
+
+The files
+	shell-quote, shell-args
+are Copyright (C) 2007  Dmitry V. Levin <ldv at altlinux.org>,
+                  2008  Alexey Gladkov <legion at altlinux.org>
+
+The file
+	shell-ini-config
+are Copyright (C) 2008  Stanislav Ievlev <inger at altlinux.org>,
+                  2008  Alexey Gladkov <legion at altlinux.org>
+
+The files
+	shell-version, shell-cmdline, shell-config, shell-error,
+	shell-ip-address, shell-mail-address, shell-unittest,
+	shell-signal, shell-var, shell-source shell-run
+are Copyright (C) 2009-2011  Alexey Gladkov <legion at altlinux.org>
+
+All files in this package may be freely copied under the terms
+of the GNU General Public License (GPL), version 2, or at your
+option any later version.
diff --git a/helpers/libshell/LICENSE b/helpers/libshell/LICENSE
new file mode 100644
index 0000000..f90922e
--- /dev/null
+++ b/helpers/libshell/LICENSE
@@ -0,0 +1,340 @@
+		    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/helpers/libshell/Makefile b/helpers/libshell/Makefile
new file mode 100644
index 0000000..43633b3
--- /dev/null
+++ b/helpers/libshell/Makefile
@@ -0,0 +1,29 @@
+DESTDIR =
+datadir = /usr/share
+man3dir = ${datadir}/man/man3
+bindir = /bin
+
+bin_TARGETS = shell-args shell-cmdline shell-config shell-error shell-getopt \
+	shell-ini-config shell-ip-address shell-mail-address shell-quote \
+	shell-regexp shell-signal shell-unittest shell-version shell-var \
+	shell-source shell-string shell-run
+
+data_TARGETS = COPYING SYMS
+
+man_TARGETS = docs/libshell.man docs/shell-error.man
+
+install: install-bin install-man
+
+install-bin: ${bin_TARGETS}
+	install -d -m755 ${DESTDIR}${bindir}
+	cp -a $^ ${DESTDIR}${bindir}/
+
+install-man: ${man_TARGETS}
+	install -d -m755 ${DESTDIR}${man3dir}
+	for i in $^; do \
+		d="$${i%.man}.3"; d="$${d##*/}"; \
+		install -m644 $$i ${DESTDIR}${man3dir}/$$d; \
+	done
+
+check:
+	@cd tests; ./runtests
diff --git a/helpers/libshell/SYMS b/helpers/libshell/SYMS
new file mode 100644
index 0000000..caff134
--- /dev/null
+++ b/helpers/libshell/SYMS
@@ -0,0 +1,66 @@
+shell-args	opt_check_dir
+shell-args	opt_check_number
+shell-args	opt_check_read
+shell-args	parse_common_option
+shell-args	print_version
+shell-args	show_help
+shell-args	show_usage
+shell-cmdline	cmdline_foreach
+shell-cmdline	cmdline_get
+shell-config	shell_config_comment
+shell-config	shell_config_del
+shell-config	shell_config_get
+shell-config	shell_config_set
+shell-error	fatal
+shell-error	message
+shell-error	verbose
+shell-getopt	getopt
+shell-getopt	getoptex
+shell-getopt	getopts
+shell-getopt	getsubopt
+shell-ini-config	ini_config_comment
+shell-ini-config	ini_config_del
+shell-ini-config	ini_config_get
+shell-ini-config	ini_config_set
+shell-ip-address	ipv4_ip_subnet
+shell-ip-address	ipv4_mask2prefix
+shell-ip-address	ipv4_prefix2mask
+shell-ip-address	valid_ipv4
+shell-mail-address	valid_email
+shell-quote	quote_sed_regexp
+shell-quote	quote_sed_regexp_variable
+shell-quote	quote_shell
+shell-quote	quote_shell_args
+shell-quote	quote_shell_variable
+shell-quote	string_quote_remove
+shell-run	run_if_executable
+shell-run	run_scripts
+shell-signal	set_cleanup_handler
+shell-signal	signal_handler
+shell-signal	unset_cleanup_handler
+shell-source	source_if_executable
+shell-source	source_if_exists
+shell-source	source_if_notempty
+shell-string	fill_mask
+shell-unittest	appendTests
+shell-unittest	assertEquals
+shell-unittest	assertFalse
+shell-unittest	assertNotEquals
+shell-unittest	assertNotNull
+shell-unittest	assertNotSame
+shell-unittest	assertNull
+shell-unittest	assertSame
+shell-unittest	assertTrue
+shell-unittest	messageTest
+shell-unittest	registerTests
+shell-unittest	runUnitTests
+shell-unittest	setUp
+shell-unittest	setUpTests
+shell-unittest	shouldSkip
+shell-unittest	showSummary
+shell-unittest	tearDown
+shell-unittest	tearDownTests
+shell-var	shell_var_is_no
+shell-var	shell_var_is_yes
+shell-var	shell_var_trim
+shell-var	shell_var_unquote
diff --git a/helpers/libshell/contrib/getoptx_1.0.bash b/helpers/libshell/contrib/getoptx_1.0.bash
new file mode 100644
index 0000000..d402c7d
--- /dev/null
+++ b/helpers/libshell/contrib/getoptx_1.0.bash
@@ -0,0 +1,301 @@
+#From: "Grigoriy Strokin" <grg at philol.msu.ru>
+#Newsgroups: comp.unix.shell
+#Subject: BASH: getopt function that parses long-named options
+#Date: Mon, 22 Dec 1997 20:35:18 +0300
+
+#Hi, I have written a BASH function named getoptex, that is like bash builtin
+#"getopts", but does parse long-named options and optional arguments. It only
+#uses builtin bash commands, so it is very fast.  In order to use it in your
+#bash scripts, include a command ". getopt.sh" (<dot> getopt.sh) to the file
+#containing your script, and that will define functions getopt, getoptex, and
+#optlistex (the file getopt.sh with its detailed description is listed
+#below).
+
+#*** file getopt.sh ***
+
+#! /bin/bash
+#
+# getopt.sh:
+# functions like getopts but do long-named options parsing
+# and support optional arguments
+#
+# Version 1.0 1997 by Grigoriy Strokin (grg at philol.msu.ru), Public Domain
+# Date created:  December 21, 1997
+# Date modified: December 21, 1997
+#
+# IMPORTANT FEATURES
+#
+# 1) Parses both short and long-named options
+# 2) Supports optional arguments
+# 3) Only uses bash builtins, thus no calls to external
+#    utilities such as expr or sed is done. Therefore,
+#    parsing speed is high enough
+#
+#
+# DESCRIPTION
+#
+# FUNCTION getopt
+# Usage: getopt OPTLIST {"$@"|ALTERNATIVE_PARAMETERS}
+#
+# like getopts, but parse options with both required and optional arguments,
+# Options with optional arguments must have "." instead of ":" after them.
+# Furthemore, a variable name to place option name cannot be specified
+# and is always placed in OPTOPT variable
+#
+# This function is provided for compatibility with getopts()
+# OPTLIST style, and it actually calls getoptex (see bellow)
+#
+# NOTE that a list of parameters is required and must be either "$@",
+# if processing command line arguments, or some alternative parameters.
+#
+# FUNCTION getoptex
+# Usage: getoptex OPTION_LIST {"$@"|ALTERNATIVE_PARAMETERS}
+#
+# like getopts, but parse long-named options.
+#
+# Both getopt and getoptex return 0 if an option has been parsed,
+# and 1 if all options are already parsed or an error occured
+#
+# Both getopt and getoptex set or test the following variables:
+#
+# OPTERR -- tested for whether error messages must be given for invalid
+options
+#
+# OPTOPT -- set to the name of an option parsed,
+#           or to "?" if no more options or error
+# OPTARG -- set to the option argument, if any;
+#           unset if ther is no argument;
+#           on error, set to the erroneous option name
+#
+# OPTIND -- Initialized to 1.
+#           Then set to the number of the next parameter to be parsed
+#           when getopt or getoptex will be called next time.
+#           When all options are parsed, contains a number of
+#           the first non-option argument.
+#
+#
+# OPTOFS -- If a parameter number $OPTIND containg an option parsed
+#           does not contain any more options, OPTOFS is unset;
+#           otherwise, OPTOFS is set to such a number of "?" signs
+#           which is equal to the number of options parsed
+#
+#           You might not set variables OPTIND and OPTOFS yourself
+#           unless you want to parse a list of parameters more than once.
+#           Otherwise, you whould unset OPTIND (or set it to 1)
+#           and unset OPTOFS each time you want to parse a new parameters
+list
+#
+# Option list format is DIFFERENT from one for getopts or getopt.
+getopts-style
+# option list can be converted to getoptex-style using a function optlistex
+# (see bellow)
+#
+# DESCRIPTION of option list used with getoptex:
+# Option names are separated by whitespace. Options consiting of
+# more than one character are treated as long-named (--option)
+#
+# Special characters can appear at the and of option names specifying
+# whether an argument is required (default is ";"):
+# ";" (default) -- no argument
+# ":" -- required argument
+# "," -- optional argument
+#
+# For example, an option list "a b c help version f: file: separator."
+# defines the following options:
+#    -a, -b, -c, --help, --version -- no argument
+#    -f, --file -- argument required
+#    --separator -- optional argument
+#
+# FUNCTION optlistex
+# Usage new_style_optlist=`optlistex OLD_STYLE_OPTLIST`
+#
+# Converts getopts-style option list in a format suitable for use with getoptex
+# Namely, it inserts spaces after each option name.
+#
+#
+# HOW TO USE
+#
+# In order o use in your bash scripts the functions described,
+# include a command ". getopt.sh" to the file containing the script,
+# which will define functions getopt, getoptex, and optlistex
+#
+# EXAMPLES
+#
+# See files 'getopt1' and 'getopt2' that contain sample scripts that use
+# getopt and getoptex functions respectively
+#
+#
+# Please send your comments to grg at philol.msu.ru
+
+function getoptex()
+{
+  let $# || return 1
+  local optlist="${1#;}"
+  let OPTIND || OPTIND=1
+  [ $OPTIND -lt $# ] || return 1
+  shift $OPTIND
+  if [ "$1" != "-" ] && [ "$1" != "${1#-}" ]
+  then OPTIND=$[OPTIND+1]; if [ "$1" != "--" ]
+  then
+    local o
+    o="-${1#-$OPTOFS}"
+    for opt in ${optlist#;}
+    do
+      OPTOPT="${opt%[;.:]}"
+      unset OPTARG
+      local opttype="${opt##*[^;:.]}"
+      [ -z "$opttype" ] && opttype=";"
+      if [ ${#OPTOPT} -gt 1 ]
+      then # long-named option
+        case $o in
+          "--$OPTOPT")
+            if [ "$opttype" != ":" ]; then return 0; fi
+            OPTARG="$2"
+            if [ -z "$OPTARG" ];
+            then # error: must have an agrument
+              let OPTERR && echo "$0: error: $OPTOPT must have an argument" >&2
+              OPTARG="$OPTOPT";
+              OPTOPT="?"
+              return 1;
+            fi
+            OPTIND=$[OPTIND+1] # skip option's argument
+            return 0
+          ;;
+          "--$OPTOPT="*)
+            if [ "$opttype" = ";" ];
+            then  # error: must not have arguments
+              let OPTERR && echo "$0: error: $OPTOPT must not have arguments" >&2
+              OPTARG="$OPTOPT"
+              OPTOPT="?"
+              return 1
+            fi
+            OPTARG=${o#"--$OPTOPT="}
+            return 0
+          ;;
+        esac
+      else # short-named option
+        case "$o" in
+          "-$OPTOPT")
+            unset OPTOFS
+            [ "$opttype" != ":" ] && return 0
+            OPTARG="$2"
+            if [ -z "$OPTARG" ]
+            then
+              echo "$0: error: -$OPTOPT must have an argument" >&2
+              OPTARG="$OPTOPT"
+              OPTOPT="?"
+              return 1
+            fi
+            OPTIND=$[OPTIND+1] # skip option's argument
+            return 0
+          ;;
+          "-$OPTOPT"*)
+            if [ $opttype = ";" ]
+            then # an option with no argument is in a chain of options
+              OPTOFS="$OPTOFS?" # move to the next option in the chain
+              OPTIND=$[OPTIND-1] # the chain still has other options
+              return 0
+            else
+              unset OPTOFS
+              OPTARG="${o#-$OPTOPT}"
+              return 0
+            fi
+          ;;
+        esac
+      fi
+    done
+    echo "$0: error: invalid option: $o"
+  fi; fi
+  OPTOPT="?"
+  unset OPTARG
+  return 1
+}
+function optlistex
+{
+  local l="$1"
+  local m # mask
+  local r # to store result
+  while [ ${#m} -lt $[${#l}-1] ]; do m="$m?"; done # create a "???..." mask
+  while [ -n "$l" ]
+  do
+    r="${r:+"$r "}${l%$m}" # append the first character of $l to $r
+    l="${l#?}" # cut the first charecter from $l
+    m="${m#?}"  # cut one "?" sign from m
+    if [ -n "${l%%[^:.;]*}" ]
+    then # a special character (";", ".", or ":") was found
+      r="$r${l%$m}" # append it to $r
+      l="${l#?}" # cut the special character from l
+      m="${m#?}"  # cut one more "?" sign
+    fi
+  done
+  echo $r
+}
+function getopt()
+{
+  local optlist=`optlistex "$1"`
+  shift
+  getoptex "$optlist" "$@"
+  return $?
+}
+
+#**************************************
+#     cut here
+#**************************************
+#*** (end of getopt.sh) ***
+
+
+#*** file getopt1 ***
+
+#! /bin/bash
+# getopt1:
+# Sample script using the function getopt
+#
+# Type something like "getopt1 -ab -d 10 -e20 text1 text2"
+# on the command line to see how it works
+#
+# See getopt.sh for more information
+#. getopt.sh
+#echo Using getopt to parse arguments:
+#while getopt "abcd:e." "$@"
+#do
+#  echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}"
+#done
+#shift $[OPTIND-1]
+#for arg in "$@"
+#do
+#  echo "Non option argument <$arg>"
+#done
+#
+#**************************************
+#        cut here
+#**************************************
+#*** (end of getopt1) ***
+#
+#
+#*** file getopt2 ***
+#
+#! /bin/bash
+# getopt2:
+# Sample script using the function getoptex
+#
+# Type something like "getopt2 -ab -d 10 -e20 --opt1 --opt4=100 text1 text2"
+# to see how it works
+#
+# See getopt.sh for more information
+. getopt.sh
+#echo Using getoptex to parse arguments:
+#while getoptex "a; b; c; d: e. opt1 opt2 opt3 opt4: opt5." "$@"
+#do
+#  echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}"
+#done
+#shift $[OPTIND-1]
+#for arg in "$@"
+#do
+#  echo "Non option argument <$arg>"
+#done
+#
+#**************************************
+#         cut here
+#**************************************
+#*** (end of getopt2) ***
+
diff --git a/helpers/libshell/contrib/getoptx_1.1.bash b/helpers/libshell/contrib/getoptx_1.1.bash
new file mode 100644
index 0000000..4e6d40e
--- /dev/null
+++ b/helpers/libshell/contrib/getoptx_1.1.bash
@@ -0,0 +1,241 @@
+#! /bin/bash
+#
+# getopt.sh:
+# functions like getopts but do long-named options parsing
+# and support optional arguments
+#
+# Version 1.1 2004 by Raphael <raphael at oninet dot pt>
+# Date modified: April 6, 2004
+# Version 1.0 1997 by Grigoriy Strokin (grg at philol.msu.ru), Public Domain
+# Date created: December 21, 1997
+# Date modified: December 21, 1997
+#
+# UPDATE (by raphael)
+#
+# I found the routine wouldn't report option that need arguments right
+# if they where between or before other options. Rather it would take
+# the following option as the argument. The routine now checks if
+# the required argument starts with a dash '-' indicating that it is an
+# option. See source below.
+#
+# IMPORTANT FEATURES
+#
+# 1) Parses both short and long-named options
+# 2) Supports optional arguments
+# 3) Only uses bash builtins, thus no calls to external
+# utilities such as expr or sed is done. Therefore,
+# parsing speed is high enough
+#
+#
+# DESCRIPTION
+#
+# FUNCTION getopt
+# Usage: getopt OPTLIST {"$@"|ALTERNATIVE_PARAMETERS}
+#
+# like getopts, but parse options with both required and optional arguments,
+# Options with optional arguments must have "." instead of ":" after them.
+# Furthemore, a variable name to place option name cannot be specified
+# and is always placed in OPTOPT variable
+#
+# This function is provided for compatibility with getopts()
+# OPTLIST style, and it actually calls getoptex (see bellow)
+#
+# NOTE that a list of parameters is required and must be either "$@",
+# if processing command line arguments, or some alternative parameters.
+#
+# FUNCTION getoptex
+# Usage: getoptex OPTION_LIST {"$@"|ALTERNATIVE_PARAMETERS}
+#
+# like getopts, but parse long-named options.
+#
+# Both getopt and getoptex return 0 if an option has been parsed,
+# and 1 if all options are already parsed or an error occured
+#
+# Both getopt and getoptex set or test the following variables:
+#
+# OPTERR -- tested for whether error messages must be given for invalid options
+#
+# OPTOPT -- set to the name of an option parsed,
+# or to "?" if no more options or error
+# OPTARG -- set to the option argument, if any;
+# unset if ther is no argument;
+# on error, set to the erroneous option name
+#
+# OPTIND -- Initialized to 1.
+# Then set to the number of the next parameter to be parsed
+# when getopt or getoptex will be called next time.
+# When all options are parsed, contains a number of
+# the first non-option argument.
+#
+#
+# OPTOFS -- If a parameter number $OPTIND containg an option parsed
+# does not contain any more options, OPTOFS is unset;
+# otherwise, OPTOFS is set to such a number of "?" signs
+# which is equal to the number of options parsed
+#
+# You might not set variables OPTIND and OPTOFS yourself
+# unless you want to parse a list of parameters more than once.
+# Otherwise, you whould unset OPTIND (or set it to 1)
+# and unset OPTOFS each time you want to parse a new parameters list
+#
+# Option list format is DIFFERENT from one for getopts or getopt. getopts-style
+# option list can be converted to getoptex-style using a function optlistex
+# (see bellow)
+#
+# DESCRIPTION of option list used with getoptex:
+# Option names are separated by whitespace. Options consiting of
+# more than one character are treated as long-named (--option)
+#
+# Special characters can appear at the and of option names specifying
+# whether an argument is required (default is ";"):
+# ";" (default) -- no argument
+# ":" -- required argument
+# "," -- optional argument
+#
+# For example, an option list "a b c help version f: file: separator."
+# defines the following options:
+# -a, -b, -c, --help, --version -- no argument
+# -f, --file -- argument required
+# --separator -- optional argument
+#
+# FUNCTION optlistex
+# Usage new_style_optlist=`optlistex OLD_STYLE_OPTLIST`
+#
+# Converts getopts-style option list in a format suitable for use with getoptex
+# Namely, it inserts spaces after each option name.
+#
+#
+# HOW TO USE
+#
+# In order o use in your bash scripts the functions described,
+# include a command ". getopt.sh" to the file containing the script,
+# which will define functions getopt, getoptex, and optlistex
+#
+# EXAMPLES
+#
+# See files 'getopt1' and 'getopt2' that contain sample scripts that use
+# getopt and getoptex functions respectively
+#
+#
+# Please send your comments to grg at philol.msu.ru
+
+function getoptex()
+{
+  let $# || return 1
+  local optlist="${1#;}"
+  let OPTIND || OPTIND=1
+  [ $OPTIND -lt $# ] || return 1
+  shift $OPTIND
+  if [ "$1" != "-" -a "$1" != "${1#-}" ]
+  then OPTIND=$[OPTIND+1]; if [ "$1" != "--" ]
+  then
+    local o
+    o="-${1#-$OPTOFS}"
+    for opt in ${optlist#;}
+    do
+      OPTOPT="${opt%[;.:]}"
+      unset OPTARG
+      local opttype="${opt##*[^;:.]}"
+      [ -z "$opttype" ] && opttype=";"
+      if [ ${#OPTOPT} -gt 1 ]
+      then # long-named option
+        case $o in
+          "--$OPTOPT")
+            if [ "$opttype" != ":" ]; then return 0; fi
+            OPTARG="$2"
+
+# Added test on following argument being an option identified by '-' this way #
+# the routine no longer takes options as an argument thus breaking error #
+# detection. 2004-04-04 by raphael at oninet dot pt #
+
+            if [ -z "$OPTARG" -o "${OPTARG:0:1}" = "-" ] ;
+            then # error: must have an agrument
+              let OPTERR && echo "$0: error: $OPTOPT must have an argument" >&2
+              OPTARG="$OPTOPT";
+              OPTOPT="?"
+              return 1;
+            fi
+            OPTIND=$[OPTIND+1] # skip option's argument
+            return 0
+          ;;
+          "--$OPTOPT="*)
+            if [ "$opttype" = ";" ];
+            then # error: must not have arguments
+              let OPTERR && echo "$0: error: $OPTOPT must not have arguments" >&2
+              OPTARG="$OPTOPT"
+              OPTOPT="?"
+              return 1
+            fi
+            OPTARG=${o#"--$OPTOPT="}
+            return 0
+          ;;
+        esac
+      else # short-named option
+        case "$o" in
+          "-$OPTOPT")
+            unset OPTOFS
+            [ "$opttype" != ":" ] && return 0
+            OPTARG="$2"
+
+# Added test on following argument being an option identified by '-' this way #
+# the routine no longer takes options as an argument thus breaking error #
+# detection. 2004-04-04 by raphael at oninet dot pt #
+
+            if [ -z "$OPTARG" -o "${OPTARG:0:1}" = "-" ] ;
+            then
+              echo "$0: error: -$OPTOPT must have an argument" >&2
+              OPTARG="$OPTOPT"
+              OPTOPT="?"
+              return 1
+            fi
+            OPTIND=$[OPTIND+1] # skip option's argument
+            return 0
+          ;;
+          "-$OPTOPT"*)
+            if [ $opttype = ";" ]
+            then # an option with no argument is in a chain of options
+              OPTOFS="$OPTOFS?" # move to the next option in the chain
+              OPTIND=$[OPTIND-1] # the chain still has other options
+              return 0
+            else
+              unset OPTOFS
+              OPTARG="${o#-$OPTOPT}"
+              return 0
+            fi
+          ;;
+        esac
+      fi
+    done
+    echo "$0: error: invalid option: $o"
+  fi; fi
+  OPTOPT="?"
+  unset OPTARG
+  return 1
+}
+function optlistex
+{
+  local l="$1"
+  local m # mask
+  local r # to store result
+  while [ ${#m} -lt $[${#l}-1] ]; do m="$m?"; done # create a "???..." mask
+  while [ -n "$l" ]
+  do
+    r="${r:+"$r "}${l%$m}" # append the first character of $l to $r
+    l="${l#?}" # cut the first charecter from $l
+    m="${m#?}" # cut one "?" sign from m
+    if [ -n "${l%%[^:.;]*}" ]
+    then # a special character (";", ".", or ":") was found
+      r="$r${l%$m}" # append it to $r
+      l="${l#?}" # cut the special character from l
+      m="${m#?}" # cut one more "?" sign
+    fi
+  done
+  echo $r
+}
+function getopt()
+{
+  local optlist=`optlistex "$1"`
+  shift
+  getoptex "$optlist" "$@"
+  return $?
+} 
diff --git a/helpers/libshell/contrib/shell-array b/helpers/libshell/contrib/shell-array
new file mode 100644
index 0000000..d08693d
--- /dev/null
+++ b/helpers/libshell/contrib/shell-array
@@ -0,0 +1,89 @@
+#!/bin/sh -efu
+
+if [ -z "${__included_shell_array-}" ]; then
+__included_shell_array=1
+
+if [ -n "${__libshell_experimental-}" ]; then
+
+#. shell-crc32
+
+# arr[ZZZ-zzz] = "XXX-xxx"
+#
+# ARRAY_arr_{n}_key="ZZZ-zzz"
+# ARRAY_arr_{n}_arg="XXX-xxx"
+# ARRAY_arr_{sign}={n}
+# ARRAY_arr={size}
+
+# Usage: array ARRNAME key value
+#    or: array ARRNAME key
+#    or: array ARRNAME
+array()
+{
+	local arr key arg num i
+	arr="$1"
+	[ "$#" -lt 2 ] || key="$2"
+	[ "$#" -lt 3 ] || arg="$3"
+
+	eval "num=\${ARRAY_$arr:-0}"
+	if [ "$#" -eq 1 ]; then
+		printf '%d\n' "$num"
+		return
+	fi
+
+	#shell_crc32 "sign" "$key"
+	sign="$(printf '%s' "$key" |sha1sum)"
+	sign="${sign%% *}"
+	eval "i=\"\${ARRAY_${arr}_${sign}-}\""
+
+	if [ "$#" -eq 2 ]; then
+		if [ -n "$i" ]; then
+			eval "arg=\$ARRAY_${arr}_${i}_arg"
+			printf '%s\n' "$arg"
+			return
+		fi
+		return 1
+	fi
+
+	if [ -z "$i" ]; then
+		i="$num"
+		num=$(($num+1))
+		eval "ARRAY_$arr=\$num"
+	fi
+
+	eval "ARRAY_${arr}_${i}_key=\"\$key\""
+	eval "ARRAY_${arr}_${i}_arg=\"\$arg\""
+	eval "ARRAY_${arr}_${sign}=\"\$i\""
+}
+
+# Usage: shell_array_foreach ARRNAME callback
+array_foreach()
+{
+	local arrname callback i num key arg
+	arrname="$1"; shift
+	callback="$1"; shift
+
+	eval "num=\${ARRAY_$arrname:-0}"
+	[ "$num" -gt 0 ] ||
+		return 0
+	i=0
+	while [ $i -lt $num ]; do
+		eval "key=\"\$ARRAY_${arrname}_${i}_key\""
+		eval "arg=\"\$ARRAY_${arrname}_${i}_arg\""
+		$callback "$i" "$key" "$arg"
+		i=$(($i+1))
+	done
+}
+
+array_flip()
+{
+	local arrname tmp key1 key2 num1 num2
+	arrname="$1"; shift
+	key1="$1"; shift
+	key2="$1"; shift
+
+	eval 
+}
+
+fi #__libshell_experimental
+
+fi #__included_shell_array
diff --git a/helpers/libshell/contrib/shell-crc32 b/helpers/libshell/contrib/shell-crc32
new file mode 100644
index 0000000..8f38e9a
--- /dev/null
+++ b/helpers/libshell/contrib/shell-crc32
@@ -0,0 +1,73 @@
+#!/bin/ash -efu
+
+# http://ru.wikipedia.org/wiki/CRC32#CRC-32
+#
+# Name  : CRC-32
+# Poly  : 0x04C11DB7    x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 
+#                       + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
+# Init  : 0xFFFFFFFF
+# Revert: true
+# XorOut: 0xFFFFFFFF
+# Check : 0xCBF43926 ("123456789")
+#
+
+__shell_crc32_table=
+__shell_crc32_init()
+{
+	[ -z "${__shell_crc32_table-}" ] ||
+		return 0;
+
+	local i=0 j crc
+
+	while [ $i -lt 256 ]; do
+		crc=$i
+		j=0
+		while [ $j -lt 8 ]; do
+			[ $(($crc & 1)) -ne 0 ] &&
+				crc=$((($crc >> 1) ^ 0xEDB88320)) ||
+				crc=$((($crc >> 1)))
+			j=$(($j+1))
+		done
+		__shell_crc32_table="$__shell_crc32_table $crc"
+		i=$(($i+1))
+	done
+}
+
+shell_crc32()
+{
+	local __shell_crc32_crc __shell_crc32_name __shell_crc32_buf
+	__shell_crc32_name="$1"; shift
+	__shell_crc32_buf="$2"; shift
+
+	__shell_crc32()
+	{
+		local c crc i=1 j
+
+		__shell_crc32_init
+		set -- ${__shell_crc32_table}
+
+		local args= mask=
+		while [ $i -lt ${#buf} ]; do
+			mask="$mask?"
+			i=$(($i+1))
+		done
+
+		while [ -n "$buf" ]; do
+			args="$args '${buf%$mask}"
+			buf=${buf#?}
+			mask=${mask#?}
+		done
+
+		crc=$((0xFFFFFFFF))
+		for c in $(printf '%d ' $args); do
+			j=$((($crc ^ $c) & 0xFF))
+			j=$(($j+1))
+			eval "crc=\$((\${$j} ^ (\$crc >> 0x00000008)))"
+		done
+		__shell_crc32_crc=$(($crc ^ 0xFFFFFFFF))
+	}
+	__shell_crc32
+	eval "$__shell_crc32_name=\"\${__shell_crc32_crc}\""
+}
+
+#shell_crc32 "" "123456789"
diff --git a/helpers/libshell/contrib/shell-lists b/helpers/libshell/contrib/shell-lists
new file mode 100644
index 0000000..7540808
--- /dev/null
+++ b/helpers/libshell/contrib/shell-lists
@@ -0,0 +1,72 @@
+#!/bin/sh -efu
+
+if [ -z "${__included_shell_lists-}" ]; then
+__included_shell_lists=1
+
+. shell-quote
+
+shell_list_add() {
+	local __shell_list_add_var="$1"
+	shift
+	local __shell_list_add_qvalue
+	while [ "$#" -gt 0 ]; do
+		quote_shell_variable __shell_list_add_qvalue "$1"
+		eval "$__shell_list_add_var=\"\$$__shell_list_add_var \\\"\$__shell_list_add_qvalue\\\"\""
+		shift
+	done
+}
+
+shell_list_remove() {
+	local __shell_list_remove_var __shell_list_remove_value
+	__shell_list_remove_var="$1"; shift
+	__shell_list_remove_value="$1"; shift
+
+	local __shell_list_remove_qvalue __shell_list_remove_nvar=
+
+	eval "__shell_list_remove_nvar=\$$var"
+	eval "set -- $__shell_list_remove_nvar"
+	eval "__shell_list_remove_nvar=''"
+
+	while [ "$#" -gt 0 ]; do
+		if [ "$__shell_list_remove_value" != "$1" ]; then
+			quote_shell_variable __shell_list_remove_qvalue "$1"
+			eval "__shell_list_remove_nvar=\"\$__shell_list_remove_nvar \\\"\$__shell_list_remove_qvalue\\\"\""
+		fi
+		shift
+	done
+
+	eval "$__shell_list_remove_var=\"\$__shell_list_remove_nvar\""
+}
+
+shell_list_get() {
+	local __shell_list_get_var __shell_list_get_name __shell_list_get_value
+	__shell_list_get_var="$1"; shift
+	__shell_list_get_name="$1"; shift
+	__shell_list_get_value="$1"; shift
+
+	local __shell_list_get_lst=
+	eval "__shell_list_get_lst=\"\$$__shell_list_get_var\""
+	eval "set -- $__shell_list_get_lst"
+	[ "$__shell_list_get_value" -le "$#" ] ||
+		return 1
+	eval "$__shell_list_get_name=\"\${$__shell_list_get_value-}\""
+}
+
+SHELLLIST_FOREACH=1
+shell_list_foreach() {
+	local __shell_list_foreach_var __shell_list_foreach_name
+	__shell_list_foreach_var="$1"; shift
+	__shell_list_foreach_name="$1"; shift
+
+	local __shell_list_foreach_lst=
+	eval "__shell_list_foreach_lst=\"\$$__shell_list_foreach_var\""
+	eval "set -- $__shell_list_foreach_lst"
+	if [ "$SHELLLIST_FOREACH" -gt "$#" ]; then
+		SHELLLIST_FOREACH=1
+		return 1
+	fi
+	eval "$__shell_list_foreach_name=\"\$$SHELLLIST_FOREACH\""
+	SHELLLIST_FOREACH=$(( $SHELLLIST_FOREACH + 1 ))
+}
+
+fi # __included_shell_lists
diff --git a/helpers/libshell/contrib/shell-sort b/helpers/libshell/contrib/shell-sort
new file mode 100644
index 0000000..324bf0f
--- /dev/null
+++ b/helpers/libshell/contrib/shell-sort
@@ -0,0 +1,105 @@
+#!/bin/ash -efu
+
+if [ -z "${__included_shell_sort-}" ]; then
+__included_shell_sort=1
+
+if [ -n "${__libshell_experimental-}" ]; then
+
+. ./shell-array
+
+INSERTIONSORT='__shell_compare_sort'
+QUICKSORT='__shell_compare_sort'
+HEAPSORT='__shell_compare_sort'
+__shell_compare_sort() {
+	test "$1" "$3" "$2" || return 1
+}
+
+__insertion_sort() {
+	local arr="$1" first="$2" last="$3"
+	local i j=0 key_i key_j
+
+	j=$(($first+1))
+	while [ $j -lt $last ]; do
+		array_get "$arr[$j]" key_j
+		i=$(($j-1))
+
+		while [ $i -ge $first ]; do
+			array_get "$arr[$i]" key_i
+			if array_compare "$INSERTIONSORT" "$arr[$i]" "$arr[$j]" "$order"; then
+				array_set "$arr[$(($i+1))]" "$key_i"
+				i=$(($i-1))
+			else
+				break
+			fi
+		done
+		array_set "$arr[$(($i+1))]" "$key_j"
+		j=$(($j+1))
+	done
+}
+
+# Usage: insertion_sort ARR
+insertion_sort() {
+	local order=-ge arr r
+	arr="$1"; shift
+	array_size "$arr" r
+	__insertion_sort "$arr" 0 "$r"
+}
+
+__shell_partition() {
+	local var="$1" arr="$2" p="$3" r="$4"
+	local i=$p j=$p
+
+	while [ "$j" -lt "$r" ]; do
+		if array_compare "$QUICKSORT" "$arr[$r]" "$arr[$j]" "$order"; then
+			array_swap "$arr[$i]" "$arr[$j]"
+			i=$(($i+1))
+		fi
+		j=$(($j+1))
+	done
+	array_swap "$arr[$i]" "$arr[$r]"
+	eval "$var=\"$i\""
+}
+
+__quicksort() {
+	local q arr="$1" p="$2" r="$3"
+	while [ "$p" -lt "$r" ]; do
+		__shell_partition q "$arr" "$p" "$r"
+		__quicksort "$arr" "$p" "$(($q-1))"
+		p=$(($q+1))
+	done
+}
+
+# Usage: quicksort ARR [order]
+quicksort() {
+	local order=-le arr r
+	arr="$1"; shift
+	[ "$#" -eq 0 ] || order=-ge
+
+	array_size "$arr" r
+	__quicksort "$arr" 0 "$(($r-1))"
+}
+
+heapsort() {
+	local arr siz c p i=1 order=-gt
+	arr="$1"; shift
+	[ "$#" -eq 0 ] || order=-lt
+
+	array_size "$arr" siz
+	while [ $i -lt $siz ]; do
+		c=$i
+		while [ $c -gt 0 ]; do
+			p=$(($c-1))
+			if array_compare "$HEAPSORT" "$arr[$p]" "$arr[$c]" "$order"; then
+				array_swap "$arr[$p]" "$arr[$c]"
+				c=$p
+			else
+				break
+			fi
+		done
+		i=$(($i+1))
+	done
+}
+
+fi #__libshell_experimental
+
+fi #__included_shell_sort
diff --git a/helpers/libshell/contrib/shell-stack b/helpers/libshell/contrib/shell-stack
new file mode 100644
index 0000000..f37fbe9
--- /dev/null
+++ b/helpers/libshell/contrib/shell-stack
@@ -0,0 +1,68 @@
+#!/bin/sh -efu
+
+stack_push() {
+	local name str last stack
+	name="$1"; shift
+	str="$1"; shift
+
+	eval "stack=\"\${__${name}:-}\";"
+	set $stack
+	last=$(($# + 1))
+
+	eval "__${name}=\"\${__$name:+\$__$name }${last}\";
+	      __${name}_${last}=\"\$str\";"
+}
+
+stack_pop() {
+	local name var last stack
+	name="$1"; shift
+	var="$1"; shift
+
+	eval "stack=\"\${__${name}:-}\";"
+	set $stack
+	last="$#"
+
+	if [ "$last" = 0 ]; then
+		eval "$var=''"
+		return
+	fi
+
+	eval "$var=\"\${__${name}_${last}:-}\";
+	      unset __${name}_${last};
+	      __${name}=\"\${__${name}% *}\";"
+}
+
+stack_shift() {
+	local name var last stack
+	name="$1"; shift
+	var="$1"; shift
+
+	eval "stack=\"\${__${name}:-}\";"
+	set $stack
+	last="$#"
+
+	if [ "$last" = 0 ]; then
+		eval "$var=''"
+		return
+	fi
+
+	last="${stack%% *}"
+	last="${last## }"
+
+	eval "$var=\"\${__${name}_${last}:-}\";
+	      unset __${name}_${last};
+	      __${name}=\"\${__${name}#* }\";"
+}
+
+stack_unshift() {
+	local name str last stack
+	name="$1"; shift
+	str="$1"; shift
+
+	eval "stack=\"\${__${name}:-}\";"
+	set $stack
+	last="$(($# + 1))"
+
+	eval "__${name}=\"${last}\${__$name:+ \$__$name}\";
+	      __${name}_${last}=\"\$str\";"
+}
diff --git a/helpers/libshell/docs/libshell.man b/helpers/libshell/docs/libshell.man
new file mode 100644
index 0000000..2bfdd70
--- /dev/null
+++ b/helpers/libshell/docs/libshell.man
@@ -0,0 +1,115 @@
+.\" Copyright (C) 2008  Alexey Gladkov <legion at altlinux.org>
+.\"
+.\" Additional documentation for the libshell.
+.\"
+.\" This file 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
+.
+.TH "LIBSHELL" "3" "November 2008" "libshell" "File Formats"
+.SH NAME
+libshell \- the library of shell functions
+.
+.
+.SH DESCRIPTION
+.
+The
+.B libshell
+library is a set of the most commonly-used shell functions.
+All functions use minimum of external utilities and written for POSIX-shell.
+.
+.
+.SH STRUCTURE
+.
+Library has modular structure. Each module used for own special purpose.
+Some modules use the functionality of each other and load the necessary dependence.
+.TP
+.BR shell-getopt
+Shell implementation of getopt(1) utility and getopt family;
+.TP
+.BR shell-config
+Functions to work (read, change and remove variables) with a shell-like config files;
+.TP
+.BR shell-ini-config
+Functions to work with a ini-like config files;
+.TP
+.BR shell-signal
+Functions to change the action taken by a process on receipt of a specific signal;
+.TP
+.BR shell-args
+Functions to check argument type, display version and program usage;
+.TP
+.BR shell-ip-address
+Functions to validate the IP address;
+.TP
+.BR shell-mail-address
+Functions to validate the domain and email address;
+.TP
+.BR shell-quote
+Functions to quote variables;
+.TP
+.BR shell-unittest
+Unit testing framework for shell (xUnit compatible);
+.TP
+.BR shell-error
+Functions to display error and verbose messages;
+.TP
+.BR shell-version
+Module contain libshell ABI version.
+.BR
+.
+.
+.
+.SH USING MODULES
+All
+.B libshell
+modules
+.I MUST
+be kept in the PATH and could be not executable. It really helps to include
+these modules in the shell-program:
+.RS
+.IP
+.EX
+\&#!/bin/sh
+\&. shell-error
+\&. shell-getopt
+\&
+\&# something useful ...
+.EE
+.RE
+.PP
+The
+.B bash-completion
+will not find these modules in the PATH, if they are not executable.
+.
+.
+.SH AUTHOR
+.PP
+This manual page written by
+.MT legion at altlinux.org
+Alexey Gladkov
+.ME .
+.PP
+Authors and contributors of the programs included in the
+.B libshell
+package are listed in the COPYING file.
+.
+.
+.SH SEE ALSO
+.PP
+.na
+.nh
+.tr -\(hy
+.BR sh (1),
+.BR bash (1),
+.BR dash (1).
diff --git a/helpers/libshell/docs/shell-error.man b/helpers/libshell/docs/shell-error.man
new file mode 100644
index 0000000..b728ad9
--- /dev/null
+++ b/helpers/libshell/docs/shell-error.man
@@ -0,0 +1,73 @@
+.\" Copyright (C) 2008  Alexey Gladkov <legion at altlinux.org>
+.\"
+.\" Additional documentation for the libshell.
+.\"
+.\" This file 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
+.
+.TH "SHELL-ERROR" "3" "November 2008" "libshell" "File Formats"
+.SH NAME
+message, fatal, verbose \- functions to display error and verbose messages
+.
+.
+.SH SYNOPSIS
+.nf
+.B . shell-error
+.sp
+.BI "PROG=" "${0##*/}"
+.sp
+.BI "message " TEXT
+.sp
+.BI "fatal " TEXT
+.sp
+.BI "verbose= quiet="
+.sp
+.BI "verbose " TEXT
+.ad b
+.SH DESCRIPTION
+The
+.BR message ()
+function show
+.B TEXT
+message to the stderr.
+.PP
+Function
+.BR fatal ()
+is equivalent to the function message(), except that
+the script will be completed after displaying a message.
+.PP
+.BR verbose ()
+will show message if
+.B $verbose
+is set and 
+.B $quiet
+unset.
+.SH AUTHOR
+.PP
+This manual page written by
+.MT legion at altlinux.org
+Alexey Gladkov
+.ME .
+.PP
+Authors and contributors of the programs included in the
+.B libshell
+package are listed in the COPYING file.
+.
+.
+.SH SEE ALSO
+.PP
+.na
+.nh
+.tr -\(hy
+.BR libshell (3).
diff --git a/helpers/libshell/shell-args b/helpers/libshell/shell-args
new file mode 100644
index 0000000..9a0b9b7
--- /dev/null
+++ b/helpers/libshell/shell-args
@@ -0,0 +1,77 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_args-}" ]; then
+__included_shell_args=1
+
+. shell-error
+
+# Checks that given option value is a readable file.
+# Arguments: $1 is option name, $2 is option value.
+# If $2 is a readable file, outputs canonicalized file name,
+# otherwise fails.
+opt_check_read() {
+	local value
+	[ -r "$2" ] &&
+	value="$(readlink -ev "$2")" ||
+		fatal "$1: $2: file not available."
+	printf %s "$value"
+}
+
+# Checks that given option value is a traversable directory.
+# Arguments: $1 is option name, $2 is option value.
+# If $2 is a readable file, outputs canonicalized directory name,
+# otherwise fails.
+opt_check_dir() {
+	local value
+	[ -d "$2" -a -x "$2" ] &&
+	value="$(readlink -ev "$2")" ||
+		fatal "$1: $2: directory not available."
+	printf %s "$value"
+}
+
+# Checks that given option value is a positive decimal number.
+# Arguments: $1 is option name, $2 is option value.
+# If $2 is a positive decimal number, outputs it, otherwise fails.
+opt_check_number()
+{
+	[ -n "${2##0*}" -a -n "${2##*[!0-9]*}" ] &&
+	[ "$2" -gt 0 ] 2>/dev/null ||
+		fatal "$1: $2: invalid number."
+	printf %s "$2"
+}
+
+show_usage() {
+	[ -z "$*" ] || message "$*"
+	echo "Try \`$PROG --help' for more information." >&2
+	exit 1
+}
+
+show_help() {
+	fatal "show_help(): Undefined function"
+}
+
+print_version() {
+	fatal "print_version() Undefined function"
+}
+
+readonly getopt_common_opts="q,v,V,h"
+readonly getopt_common_longopts="quiet,verbose,version,help"
+parse_common_option() {
+	case "$1" in
+		-h|--help) show_help
+			;;
+		-q|--quiet) quiet=-q; verbose=
+			;;
+		-v|--verbose) verbose=-v; quiet=
+			;;
+		-V|--version) print_version "$PROG"
+			;;
+		*) fatal "Unrecognized option: $1"
+			;;
+	esac
+}
+
+fi #__included_shell_args
diff --git a/helpers/libshell/shell-cmdline b/helpers/libshell/shell-cmdline
new file mode 100644
index 0000000..c10b78b
--- /dev/null
+++ b/helpers/libshell/shell-cmdline
@@ -0,0 +1,118 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_cmdline-}" ]; then
+__included_shell_cmdline=1
+
+. shell-string
+
+# Run handler for each variable in /proc/cmdline.
+#
+cmdline_foreach() {
+	local l h c= m=
+
+	l="$1"; shift
+	h="$1"; shift
+
+	__is_set() {
+		[ $(( $1 & $2 )) -eq $2 ]
+	}
+
+	fill_mask m "$l"
+
+	local state=$((0x00))
+	local VALUE=$((0x02))
+	local EQUAL=$((0x04))
+	local QUOTE=$((0x10))
+
+	local n= v=
+
+	while [ -n "$l" ]; do
+		c="${l%$m}"
+
+		case "$c" in
+			'"')
+				__is_set $state $QUOTE &&
+					state=$(($state ^ $QUOTE)) ||
+					state=$(($state | $QUOTE))
+				;;
+			' ')
+				if __is_set $state $QUOTE; then
+					v="$v$c"
+				else
+					__is_set $state $EQUAL ||
+						v=1
+					$h "$n" "$v" ||
+						break
+					n= v=
+					state=$((0x00))
+				fi
+				;;
+			'=')
+				! __is_set $state $VALUE ||
+					v="$v$c"
+				state=$(($state | $VALUE | $EQUAL))
+				;;
+			*)
+				if ! __is_set $state $VALUE; then
+					[ "$c" != '-' ] || c='_'
+					n="$n$c"
+				else
+					v="$v$c"
+				fi
+				;;
+		esac
+
+		l="${l#?}"
+		m="${m#?}"
+	done
+
+	[ -z "$n" ] ||
+		$h "$n" "$v" ||:
+
+	unset __is_set
+}
+
+# Find spicified variable in /proc/cmdline and store result into variable.
+# Usage example:
+#   read cmdline < /proc/cmdline
+#   cmdline_get 'initrd_value' 'initrd' "$cmdline"
+#   echo "$initrd_value"
+# or:
+#   cmdline_get 'initrd_value' 'initrd'
+#   echo "$initrd_value"
+#
+cmdline_get() {
+	local __cmdline __retv __getn
+
+	__retv="$1"; shift
+	__getn="$1"; shift
+	if [ "$#" -eq 0 ]; then
+		read __cmdline < /proc/cmdline
+	else
+		__cmdline="$1"
+	fi
+
+	local c m l="$__getn"
+	__getn=
+
+	fill_mask m "$l"
+	while [ -n "$l" ]; do
+		c="${l%$m}"
+		[ "$c" != '-' ] || c='_'
+		__getn="$__getn$c"
+		l="${l#?}"
+		m="${m#?}"
+	done
+	unset c m l
+
+	__getval() {
+		[ "$1" != "$__getn" ] || eval "$__retv=\"\$2\""
+	}
+	cmdline_foreach "$__cmdline" __getval
+	unset __getval
+}
+
+fi #__included_shell_cmdline
diff --git a/helpers/libshell/shell-config b/helpers/libshell/shell-config
new file mode 100644
index 0000000..bf2cdb6
--- /dev/null
+++ b/helpers/libshell/shell-config
@@ -0,0 +1,87 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_config-}" ]; then
+__included_shell_config=1
+
+. shell-error
+. shell-quote
+
+__shell_config_comment='#'
+
+shell_config_get() {
+	[ "$#" -ge 2 -a "$#" -le 3 ] ||
+		fatal "Usage: shell_config_get file name [delim]"
+	local file="$1" name="$2" delim="${3-=}"
+
+	[ -s "$file" ] ||
+		return 0
+	quote_sed_regexp_variable name "$name"
+	sed -n -e "s/^[[:space:]]*$name$delim//p" -- "$file"
+}
+
+shell_config_set() {
+	[ "$#" -ge 3 -a "$#" -le 5 ] ||
+		fatal "Usage: shell_config_set file name value [read-delim [write-delim]]"
+
+	local file="$1" name="$2" value="$3" r_delim="${4-=}" w_delim="${5-=}"
+	local n v nv= created=
+
+	if [ ! -f "$file" ]; then
+		if [ ! -w "${file%/*}" ]; then
+			message "${file%/*}: not writable."
+			return 1
+		fi
+		touch -- "$file" ||
+			return 1
+		created=1
+	fi
+
+	if [ -z "$created" ]; then
+		quote_sed_regexp_variable n "$name"
+
+		if v="$(grep -m1 "^[[:space:]]*$n$r_delim" -- "$file" 2>/dev/null)"; then
+			if [ "${v#*$name$r_delim}" != "$value" ]; then
+				quote_sed_regexp_variable nv "$w_delim$value"
+				sed -i -e "s/^[[:space:]]*$n$r_delim.*/$n$nv/" -- "$file"
+			fi
+			return
+		fi
+
+		if [ -n "${__shell_config_comment-}" ] &&
+		   v="$(grep -m1 "^[[:space:]]*${__shell_config_comment:-#}[[:space:]]*$n$r_delim" -- "$file" 2>/dev/null)"; then
+			quote_sed_regexp_variable v "$v"
+			quote_sed_regexp_variable nv "$w_delim$value"
+			sed -i -e "s/^$v\$/$n$nv/" -- "$file"
+			return
+		fi
+	fi
+
+	printf '%s\n' "$name$w_delim$value" >> "$file"
+}
+
+shell_config_del() {
+	[ "$#" -ge 2 -a "$#" -le 3 ] ||
+		fatal "Usage: shell_config_del file name [delim]"
+	local file="$1" name="$2" delim="${3-=}"
+
+	[ -s "$file" ] ||
+		return 0
+	quote_sed_regexp_variable name "$name"
+	sed -i -e "/^[[:space:]]*$name$delim/d" -- "$file"
+}
+
+shell_config_comment() {
+	[ "$#" -ge 2 -a "$#" -le 3 ] ||
+		fatal "Usage: shell_config_comment file name [delim]"
+	local file="$1" name="$2" delim="${3-=}"
+
+	[ -s "$file" ] ||
+		return 0
+	quote_sed_regexp_variable name "$name"
+	sed -i -e "s/^[[:space:]]*$name$delim.*/${__shell_config_comment:-#}&/" -- "$file"
+}
+
+fi #__included_shell_config
diff --git a/helpers/libshell/shell-error b/helpers/libshell/shell-error
new file mode 100644
index 0000000..b066e7d
--- /dev/null
+++ b/helpers/libshell/shell-error
@@ -0,0 +1,32 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_error-}" ]; then
+__included_shell_error=1
+
+PROG="${PROG:-${0##*/}}"
+
+message_time=
+message_time_format=
+message() {
+	local prefix=
+	[ -z "$message_time" ] ||
+		prefix="$(date +"${message_time_format:-[%Y-%m-%d %T]} " 2>/dev/null)" ||:
+	printf %s\\n "${prefix}$PROG: $*" >&2
+}
+
+fatal() {
+	message "$@"
+	exit 1
+}
+
+quiet="${quiet-}"
+verbose="${verbose-}"
+verbose() {
+	[ -n "$verbose" ] || return 0
+	message "$@"
+}
+
+fi #__included_shell_error
diff --git a/helpers/libshell/shell-getopt b/helpers/libshell/shell-getopt
new file mode 100644
index 0000000..f591a2b
--- /dev/null
+++ b/helpers/libshell/shell-getopt
@@ -0,0 +1,399 @@
+#! /bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_getopt-}" ]; then
+__included_shell_getopt=1
+
+. shell-error
+. shell-quote
+. shell-string
+
+# Ignore unknown options.
+GETOPT_ALLOW_UNKNOWN=
+
+# Long options may be abbreviated, as long as the abbreviation is not ambiguous.
+GETOPT_ALLOW_ABBREV=1
+
+# Allow long options to start with a single ‘-’. See (getopt -a).
+GETOPT_ALLOW_ALTERNATIVE=
+
+OPTERR=1
+OPTTYP=
+OPTUKN=
+OPTOPT=
+OPTARG=
+OPTIND=1
+OPTOFS=
+
+#*** Example ***
+### Usage: getopt2 -ab -d 10 -e20 --opt1 --opt4=100 text1 text2
+###
+# . shell-getopt
+# echo Using getoptex to parse arguments:
+# while getoptex "a; b; c; d: e. opt1 opt2 opt3 opt4: opt5." "$@"; do
+#	echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}"
+# done
+# shift $(($OPTIND-1))
+# set -- $@ ${OPTUKN-}
+# for arg in "$@"; do
+#	echo "Non option argument <$arg>"
+# done
+
+getoptex() {
+	[ "$#" -gt 0 ] ||
+		return 1
+
+	[ "${OPTIND-}" -gt 0 ] 2>/dev/null ||
+		OPTIND=1
+
+	[ "$OPTIND" -lt "$#" ] ||
+		return 1
+
+	getoptex_badarg() {
+		[ -z "${OPTERR-}" ] ||
+			message "option requires an argument -- '$OPTOPT'"
+		OPTARG="$OPTOPT"
+		OPTOPT='?'
+	}
+	getoptex_argument() {
+		[ "$OPTTYP" = ':' ] ||
+			return 0
+		OPTARG="$1"
+		# Added test on following argument being an option identified by '-' this way #
+		# the routine no longer takes options as an argument thus breaking error #
+		# detection. 2004-04-04 by raphael at oninet dot pt #
+
+		[ -n "$OPTARG" -a -n "${OPTARG%%-*}" ] ||
+			{ getoptex_badarg; return 1; }
+
+		OPTARG="${1#[#]}"
+		OPTIND=$(($OPTIND+1)) # skip option's argument
+	}
+	getoptex_option_long() {
+		local arg="$1" v p
+		for p in '--' ${GETOPT_ALLOW_ALTERNATIVE:+'-'}; do
+			if [ -n "${GETOPT_ALLOW_ABBREV-}" ]; then
+				arg="${1%%=*}" v="${1#*=}" o="$p$OPTOPT"
+				if [ -z "${o##$arg*}" ]; then
+					[ "$arg" != "$v" ] &&
+						arg="$o=$v" ||
+						arg="$o"
+					unset o v
+				fi
+			fi
+			case "$arg" in
+				$p$OPTOPT=*)
+					[ -n "$OPTTYP" ] ||
+						{ getoptex_badarg; return 3; }
+					OPTARG="${arg#$p$OPTOPT=}"
+					return 1
+					;;
+				$p$OPTOPT)
+					getoptex_argument "$2" ||
+						return 3
+					return 1
+					;;
+			esac
+		done
+	}
+	getoptex_option_short() {
+		local o="-${1#-${OPTOFS-}}"
+		case "$o" in
+			-$OPTOPT)
+				OPTOFS=
+				getoptex_argument "$2" ||
+					return 3
+				return 1
+				;;
+			-$OPTOPT*)
+				if [ -z "$OPTTYP" ]; then # an option with no argument is in a chain of options
+					OPTOFS="${OPTOFS-}?" # move to the next option in the chain
+					OPTIND=$(($OPTIND-1)) # the chain still has other options
+				else
+					OPTOFS=
+					OPTARG="${o#-$OPTOPT}"
+				fi
+				return 1
+				;;
+		esac
+	}
+
+	local optlist="${1#;}" value=
+	shift $OPTIND
+
+	[ "$#" -lt 2 ] ||
+		value="#$2"
+
+	OPTTYP=
+	# test whether $1 is an option.
+	if [ "$1" = '--' ]; then
+		OPTTYP='--'
+		OPTIND=$(($OPTIND+1))
+	elif [ "$1" != '-' -a "$1" != "${1#-}" ]; then
+		OPTIND=$(($OPTIND+1))
+
+		local cmd argtype
+		for opt in $optlist; do
+			OPTOPT="${opt%[;.:]}"
+			OPTARG=
+			OPTTYP=
+			[ "$OPTTYP" = ';' ] ||
+				OPTTYP="${opt#$OPTOPT}"
+
+			cmd=long
+			[ "${#OPTOPT}" -gt 1 ] ||
+				cmd=short
+
+			getoptex_option_$cmd "$1" "$value" ||
+				return $(($?-1))
+		done
+		OPTOPT='?'
+		OPTARG=
+
+		if [ -n "${GETOPT_ALLOW_UNKNOWN-}" ]; then
+			local q_arg
+			quote_shell_variable q_arg "$1"
+			OPTUKN="${OPTUKN-} \"$q_arg\""
+			return 0
+		fi
+		message "unrecognized option '$1'"
+		return 2
+	fi
+	OPTOPT='?'
+	OPTARG=
+	return 1
+}
+
+#*** Example ***
+### Usage: getopt1 -ab -d 10 -e20 text1 text2
+###
+# . shell-getopt
+# echo "Using getopt to parse arguments:"
+# while getopts "abcd:e." "$@"; do
+#	echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}"
+# done
+# shift $(($OPTIND-1))
+# set -- $@ ${OPTUKN-}
+# for arg in "$@"; do
+#	echo "Non option argument <$arg>"
+# done
+
+getopts() {
+	local l="$1"
+	local m= # mask
+	local r= # to store result
+	fill_mask m "$l" # create a "???..." mask
+
+	while [ -n "$l" ]; do
+		r="${r:+"$r "}${l%$m}" # append the first character of $l to $r
+		l="${l#?}" # cut the first charecter from $l
+		m="${m#?}" # cut one "?" sign from m
+		if [ "${l#[:.;]}" != "$l" ]; then # a special character (";", ".", or ":") was found
+			r="$r${l%$m}" # append it to $r
+			l="${l#?}" # cut the special character from l
+			m="${m#?}" # cut one more "?" sign
+		fi
+	done
+	shift
+	getoptex "$r" "$@" ||
+		return $?
+}
+
+
+#*** Example ***
+# . shell-getopt
+# while getsubopt 'rw mode: path: dev:' 'rw,mode=755,path="/zzz xxx",dev=/dev/zzz'; do
+#	echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}"
+# done
+
+__getsubopt_arguments=
+getsubopt() {
+	local l="$2"
+
+	if [ -z "$__getsubopt_arguments" ]; then
+		local ch m=
+		fill_mask m "$l"
+
+		__getsubopt_arguments='--'
+		while [ -n "$l" ]; do
+			ch="${l%$m}"
+			l="${l#?}"
+			m="${m#?}"
+
+			case "$ch" in
+				,) ch=' --' ;;
+				[\\\\\`\$\"\ ]) ch="\\$ch" ;;
+			esac
+
+			__getsubopt_arguments="$__getsubopt_arguments$ch"
+		done
+	fi
+
+	local GETOPT_ALLOW_ABBREV=
+	eval getoptex "\"$1\"" "$__getsubopt_arguments" ||
+		return $?
+}
+
+. shell-version
+
+GETOPT_POSIXLY_CORRECT=
+
+getopt() {
+	__getopt_version() {
+		cat <<-EOF
+		$PROG version $libshell_version
+		Written by Alexey Gladkov <gladkov.alexey at gmail.com>
+
+		Copyright (C) 2008  Alexey Gladkov <gladkov.alexey at gmail.com>
+		This is free software; see the source for copying conditions.  There is NO
+		warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+		EOF
+	}
+	__getopt_usage() {
+		cat <<-EOF
+		Try \`$PROG --help' for more information.
+		EOF
+	}
+	__getopt_help() {
+		cat <<-EOF
+		Usage: $PROG optstring parameters
+		   or: $PROG [options] [--] optstring parameters
+		   or: $PROG [options] -o|--options optstring [options] [--] parameters
+
+		Options ignored:
+		  -s, --shell=shell            Set shell quoting conventions;
+		  -u, --unqote                 Do not quote the output;
+
+		Options:
+		  -a, --alternative            Allow long options starting with single -;
+		  -l, --longoptions=longopts   Long options to be recognized;
+		  -n, --name=progname          The name under which errors are reported;
+		  -o, --options=optstring      Short options to be recognized;
+		  -q, --quiet                  Disable error reporting;
+		  -Q, --quiet-output           No normal output;
+		  -T, --test                   Test for getopt version;
+		  -V, --version                Output version information;
+		  -h, --help                   This small usage guide.
+
+		Report bugs to http://bugzilla.altlinux.org/
+
+		EOF
+	}
+
+	local PROG='getopt' OPTIND=1 OPTERR=1 prg= opts= lopts= quiet_output= alt= order= rc
+	local GETOPT_POSIXLY_CORRECT
+
+	while getoptex 'a alternative h help l: longoptions: n: name: o: options: q quiet Q quiet-output s shell T test u unquoted V version' "$@" && rc=0 || rc=$?; do
+		case "$rc" in
+			2) __getopt_usage; return 2 ;;
+			1) break ;;
+		esac
+
+		case "$OPTOPT" in
+			a|alternative) alt=1 ;;
+			n|name) prg="$OPTARG" ;;
+			o|options) opts="$OPTARG " ;;
+			l|longoptions) lopts="$OPTARG" ;;
+			q|quiet) OPTERR= ;;
+			Q|quiet-output) quiet_output=1 ;;
+			T|test) return 4 ;;
+			V|version)
+				__getopt_version
+				return 0
+				;;
+			h|help)
+				__getopt_help
+				return 2
+				;;
+		esac
+	done
+
+	shift $(($OPTIND-1))
+	set -- "$@"
+
+	if [ -z "${opts##+*}" ]; then
+		opts="${opts#+}"
+		GETOPT_POSIXLY_CORRECT=1
+	elif [ -z "${opts##-*}" ]; then
+		opts="${opts#-}"
+		order=1
+	fi
+	if [ -z "$opts" ]; then
+		if [ "$#" -gt 1 -a "${1#-}" = "$1" -a "$1" != '--' ]; then
+			opts="$1"
+			shift
+		else
+			message "$PROG: missing optstring argument"
+			__getopt_usage
+			return 2
+		fi
+	fi
+	opts="${lopts:+$lopts,}$opts"
+	while :; do
+		case "$opts" in
+			*,*)  opts="${opts%%,*} ${opts#*,}"   ;;
+			*::*) opts="${opts%%::*}.${opts#*::}" ;;
+			*) break ;;
+		esac
+	done
+
+	local OPTIND=1 OPTOFS= GETOPT_ALLOW_ALTERNATIVE="${alt:+1}"
+	local ret=0 out=' -- '
+
+	! printenv POSIXLY_CORRECT >/dev/null 2>&1 ||
+		GETOPT_POSIXLY_CORRECT=1
+
+	__getopt_out_arg() {
+		local q_arg
+		shift $(($OPTIND-1))
+		quote_shell_variable q_arg "$1"
+		[ -z "$order" ] &&
+			out="${out%% -- *} -- ${out#* -- } \"$q_arg\"" ||
+			out="${out%% -- *} \"$q_arg\" -- ${out#* -- }"
+	}
+
+	PROG="$prg"
+	while getoptex "$opts" "$@" && rc=0 || rc=$?; do
+		case "$rc" in
+			1)
+				[ $# -ge $OPTIND -a -z "${GETOPT_POSIXLY_CORRECT-}" ] ||
+					break
+				__getopt_out_arg "$@"
+				OPTIND=$(($OPTIND+1))
+				[ "$OPTTYP" != '--' ] ||
+					break
+				continue
+				;;
+			2)	ret=1
+				;;
+		esac
+		if [ "$OPTOPT" = '?' ]; then
+			if [ -n "$GETOPT_ALLOW_UNKNOWN" ]; then
+				out="${out%% -- *} -- ${out#* -- }$OPTUKN"
+				OPTUKN=
+			fi
+			continue
+		fi
+		pfx='-'
+		[ "${#OPTOPT}" -eq 1 ] ||
+			pfx='--'
+		out="${out%% -- *} $pfx$OPTOPT${OPTTYP:+ '$OPTARG'} -- ${out#* -- }"
+	done
+
+	local q_arg
+	shift $(($OPTIND-1))
+	set -- "$@"
+	while [ "$#" -gt 0 ]; do
+		quote_shell_variable q_arg "$1"
+		out="${out%% -- *} -- ${out#* -- } \"$q_arg\""
+		shift
+	done
+
+	[ -n "$quiet_output" ] ||
+		printf '%s\n' "$out${OPTUKN:+$OPTUKN}"
+	return $ret
+}
+
+fi #__included_shell_getopt
diff --git a/helpers/libshell/shell-ini-config b/helpers/libshell/shell-ini-config
new file mode 100644
index 0000000..5ed42f1
--- /dev/null
+++ b/helpers/libshell/shell-ini-config
@@ -0,0 +1,155 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_ini_config-}" ]; then
+__included_shell_ini_config=1
+
+shell_ini_config_comment='#'
+
+. shell-error
+. shell-var
+
+# Usage: ini_config_get file section var
+ini_config_get() {
+	local fn section var sect= str eof= n v
+	fn="$1" section="$2" var="$3"
+
+	while [ -z "$eof" ]; do
+		read -r str || eof=1
+
+		case "$str" in
+			"["*"]")
+				[ "$str" != "[$section]" ] ||
+					sect=1
+				;;
+			"$shell_ini_config_comment"*|'')
+				;;
+			*)
+				if [ -n "$sect" ]; then
+					shell_var_trim n "${str%%=*}"
+
+					if [ "$n" = "$var" ]; then
+						shell_var_trim v "${str#*=}"
+						printf '%s\n' "$v"
+						break
+					fi
+				fi
+				;;
+		esac
+	done < "$fn"
+}
+
+# Usage: ini_config_set file section var value
+ini_config_set() {
+	local fn fn_tmp section var value sect= don= str eof= n v
+
+	fn="$1" section="$2" var="$3" value="$4"
+	fn_tmp="$(mktemp "$fn.XXXXXX")"
+
+	while [ -z "$eof" ]; do
+		read -r str || eof=1
+
+
+		case "$str" in
+			"[$section]")
+				sect=2
+				printf '%s\n' "$str"
+				;;
+			"["*"]")
+				if [ "$sect" = 2 -a -z "$don" ]; then
+					printf '\t%s\n' "$var = $value"
+					don=1
+				fi
+				sect=1
+				printf '%s\n' "$str"
+				;;
+			"$shell_ini_config_comment"*|'')
+				[ -n "$str" ] &&
+					printf ${sect:+'\t'}'%s\n' "$str" ||
+					printf '\n'
+				;;
+			*)
+				shell_var_trim n "${str%%=*}"
+				shell_var_trim v "${str#*=}"
+
+				if [ "$sect" = 2 -a "$n" = "$var" ]; then
+					[ -n "$don" ] ||
+						printf '\t%s\n' "$n = $value"
+					don=1
+					continue
+				fi
+				printf '\t%s\n' "$n = $v"
+				;;
+		esac
+
+		if [ -n "$eof" -a -z "$don" ]; then
+			[ "$sect" = 2 ] ||
+				printf '[%s]\n' "$section"
+			printf '\t%s\n' "$var = $value"
+		fi
+
+	done < "$fn" > "$fn_tmp"
+	mv -f -- "$fn_tmp" "$fn"
+}
+
+__ini_config_del_comment() {
+	local fn_tmp sect= str eof= n v
+	fn_tmp="$(mktemp "$fn.XXXXXX")"
+
+	while [ -z "$eof" ]; do
+		read -r str || eof=1
+
+		case "$str" in
+			"["*"]")
+				sect=1
+				[ "$str" != "[$section]" ] ||
+					sect=2
+				printf '%s\n' "$str"
+				;;
+			"$shell_ini_config_comment"*|'')
+				[ -n "$str" ] &&
+					printf ${sect:+'\t'}'%s\n' "$str" ||
+					printf '\n'
+				;;
+			*)
+				shell_var_trim n "${str%%=*}"
+				shell_var_trim v "${str#*=}"
+
+				[ "$sect" = 2 ] &&
+					__ini_config_action "$n" "$v" ||
+					printf '\t%s\n' "$n = $v"
+				;;
+		esac
+	done < "$fn" > "$fn_tmp"
+	mv -f -- "$fn_tmp" "$fn"
+	unset __ini_config_action
+}
+
+# Usage: ini_config_del file section [var]
+ini_config_del() {
+	local fn="$1" section="$2" var="${3-}"
+
+	__ini_config_action() {
+		[ -z "$var" -o "$1" = "$var" ] ||
+			printf '\t%s\n' "$1 = $2"
+	}
+	__ini_config_del_comment
+}
+
+# Usage: ini_config_comment file section [var]
+ini_config_comment() {
+	local fn="$1" section="$2" var="${3-}"
+
+	__ini_config_action() {
+		if [ -n "$var" -a "$1" != "$var" ]; then
+			printf '\t%s\n' "$1 = $2"
+			return
+		fi
+		printf '\t%s\n' "$shell_ini_config_comment $1 = $2"
+	}
+	__ini_config_del_comment
+}
+
+fi #__included_shell_ini_config
diff --git a/helpers/libshell/shell-ip-address b/helpers/libshell/shell-ip-address
new file mode 100644
index 0000000..39e4570
--- /dev/null
+++ b/helpers/libshell/shell-ip-address
@@ -0,0 +1,166 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_ip_address-}" ]; then
+__included_shell_ip_address=1
+
+# Regexp for single byte
+readonly regex_byte='([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])'
+
+# Regexp for 4-byte address
+readonly regex_ipaddr="$regex_byte(\.$regex_byte){3}"
+
+# Regexp for IPv4 address
+#
+# (http://en.wikipedia.org/wiki/IP_address)
+#
+# Some first-octet values have special meanings:
+#
+# * First octet 127 represents the local computer, regardless of what network
+#   it is really in. This is useful when testing internal operations.
+#
+# * First octet 224 and above are reserved for special purposes such as
+#   multicasting.
+#
+# Octets 0 and 255 are not acceptable values in some situations, but 0 can be used
+# as the second and/or third octet (e.g. 10.2.0.100).
+#
+readonly __regex_fbyte='([1-9][0-9]?|1[0-9][0-9]|2[01][0-9]|22[0-3])'
+readonly __regex_sbyte='([1]?[0-9][0-9]?|2[0-4][0-9]|25[0-4])'
+readonly __regex_lbyte='([1]?[0-9][0-9]?|2[0-4][0-9]|25[0-4])'
+
+readonly regex_ipv4="${__regex_fbyte}(\.${__regex_sbyte}){2}\.${__regex_lbyte}"
+
+# Checks that given option value is a valid IPv4 address.
+valid_ipv4() {
+	local ipaddr="$1"
+	local i=0 byte
+
+	byte="${ipaddr##*.}"
+	ipaddr="${ipaddr%.$byte}"
+
+	[ "$byte" -gt 0 -a "$byte" -lt 255 ] 2>/dev/null ||
+			return 1
+
+	while [ $i -lt 3 ]; do
+		byte="${ipaddr##*.}"
+
+		[ "$byte" != "$ipaddr" ] ||
+			break
+
+		ipaddr="${ipaddr%.$byte}"
+
+		[ "$byte" -ge 0 -a "$byte" -lt 255 ] 2>/dev/null ||
+			return 1
+
+		i=$(($i+1))
+	done
+
+	[ $i -eq 2 -a \
+	  "$byte" -ne 127 -a "$byte" -gt 0 -a "$byte" -lt 224 ] 2>/dev/null ||
+		return 1
+}
+
+__ipv4_hex() {
+	[ -n "${1-}" ] ||
+		return 2
+
+	local IFS=.
+	set -- $1
+
+	local i=0
+	for b; do
+		[ "$b" -ge 0 -a "$b" -le 255 ] 2>/dev/null ||
+			return 2
+		i=$(($i + 1))
+	done
+
+	[ "$i" -eq 4 ] ||
+		return 2
+
+	printf '0x'
+	printf '%02x' "$@"
+}
+
+# Checks that IP address is in subnet
+# Usage example:
+# ipv4_ip_subnet 172.16.1.2 172.16.1.0/24; echo res=$?
+# res=0
+#
+# ipv4_ip_subnet 172.16.3.2 172.16.1.0/24; echo res=$?
+# res=1
+ipv4_ip_subnet() {
+	local ip net prefix
+	ip="${1-}"; shift
+	net="${1-}"; shift
+	prefix="${net##*/}"
+
+	[ -n "$prefix" -a "$prefix" -ge 0 ] 2>/dev/null ||
+		return 2
+
+	local hex_addr hex_net hex_mask p
+
+	hex_addr="$(__ipv4_hex "$ip")" &&
+	hex_net="$(__ipv4_hex "${net%%/*}")" ||
+		return 2
+
+	p=$((0xFFFFFFFF))
+	hex_mask="$(($p - ($p >> $prefix)))"
+	[ "$(($hex_net & $hex_mask))" -eq "$(($hex_addr & $hex_mask))" ] ||
+		return 1
+}
+
+# Convert netmask to routing prefix.
+# Usage example:
+# ipv4_mask2prefix 255.255.0.0
+# 16
+#
+# ipv4_prefix2mask 255.255.255.0
+# 24
+ipv4_mask2prefix() {
+	local hex_mask
+	hex_mask="$(__ipv4_hex "${1-}")" ||
+		return 2
+
+	local p i=0 prefix=
+
+	p=$((~$hex_mask & 0xFFFFFFFF))
+
+	while [ "$p" -ne 0 ]; do
+		p=$(($p >> 1 & 0xFFFFFFFF))
+		i=$(($i + 1))
+	done
+	prefix=$((32 - $i))
+
+	[ "$prefix" -ge 0 -a "$prefix" -le 32 ] ||
+		return 1
+	echo "$prefix"
+}
+
+# Convert routing prefix to netmask.
+# Usage example:
+# ipv4_prefix2mask 16
+# 255.255.0.0
+#
+# ipv4_prefix2mask 24
+# 255.255.255.0
+ipv4_prefix2mask() {
+	local len
+	len="${1-}"
+
+	[ "$len" -ge 0 -a "$len" -le 32 ] 2>/dev/null ||
+		return 1
+
+	local position=$((0xFFFFFFFF))
+	local mask=$(($position - ($position >> $len)))
+
+	printf '%s.%s.%s.%s\n' \
+	    "$(($mask >> 24 & 0xFF))" \
+	    "$(($mask >> 16 & 0xFF))" \
+	    "$(($mask >> 8  & 0xFF))" \
+	    "$(($mask       & 0xFF))"
+}
+
+fi #__included_shell_ip_address
diff --git a/helpers/libshell/shell-mail-address b/helpers/libshell/shell-mail-address
new file mode 100644
index 0000000..7e20cbb
--- /dev/null
+++ b/helpers/libshell/shell-mail-address
@@ -0,0 +1,66 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_mail_address-}" ]; then
+__included_shell_mail_address=1
+
+if [ -n "${shell_mail_address_strict-}" ]; then
+	#
+	# (http://en.wikipedia.org/wiki/Country_code_top-level_domain)
+	#
+	# A country code top-level domain (ccTLD) is an Internet top-level domain
+	# generally used or reserved for a country or a dependent territory.
+	#
+	readonly regex_cctld_active='(a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstwyz]|c[acdfghiklmnoruvxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[adefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklnrstwy]|qa|r[eosuw]|s[abcdeghiklmnrtuvyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|ye|z[amw])'
+	readonly regex_cctld_reserved='(um|bl|eh|mf)'
+	readonly regex_cctld_allocated='(bv|gb|pm|sj|so|yt)'
+	readonly regex_cctld_phaseout='(tp|yu)'
+	readonly regex_cctld_deleted='(cs|dd|zr)'
+
+	# (http://en.wikipedia.org/wiki/GTLD)
+	#
+	# A generic top-level domain (gTLD) is a top-level domain used by a
+	# particular class of organization.
+	#
+	readonly regex_gtld='(aero|arpa|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel)'
+
+	regex_tld="($regex_gtld|$regex_cctld_active|$regex_cctld_reserved|$regex_cctld_allocated|$regex_cctld_phaseout)"
+else
+	regex_tld='([a-zA-Z]{2,4}|museum|travel)'
+fi
+
+# 6. ADDRESS SPECIFICATION (http://tools.ietf.org/html/rfc822)
+#
+# addr-spec   =  local-part "@" domain        ; global address
+# local-part  =  word *("." word)             ; uninterpreted
+#                                             ; case-preserved
+# domain      =  sub-domain *("." sub-domain)
+# sub-domain  =  domain-ref / domain-literal
+# domain-ref  =  atom                         ; symbolic reference
+#
+# 6.2.3. DOMAIN TERMS
+# A domain-ref must be THE official name of a registry, network,
+# or host.
+
+# This regexp should be used ignoring case.
+readonly regex_domain="([a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*)\.$regex_tld"
+
+# Regexp can be used to check and parse email address. This regexp
+# should be used ignoring case.
+# Usage example:
+# username="$(printf '%s' "$email" |sed -e "s/^$regex_email\$/\1/i")
+#   domain="$(printf '%s' "$email" |sed -e "s/^$regex_email\$/\2/i")
+#
+readonly regex_email="([_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*)@($regex_domain)"
+
+# Checks that given option value is a valid email address.
+valid_email() {
+	local email="$1"
+	printf '%s' "$email" |
+		egrep -iqs "^$regex_email\$" ||
+		return 1
+}
+
+fi #__included_shell_mail_address
diff --git a/helpers/libshell/shell-quote b/helpers/libshell/shell-quote
new file mode 100644
index 0000000..4f06f60
--- /dev/null
+++ b/helpers/libshell/shell-quote
@@ -0,0 +1,158 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_quote-}" ]; then
+__included_shell_quote=1
+
+. shell-version
+. shell-error
+. shell-string
+
+# Quote argument for sed basic regular expression and store result into variable.
+# Usage example:
+# quote_sed_regexp_variable var_pattern "$pattern"
+# quote_sed_regexp_variable var_replace "$replace"
+# sed "s/$var_pattern/$var_replace/"
+quote_sed_regexp_variable() {
+	local __quote_set_regexp_variable_var __quote_set_regexp_variable_out
+	__quote_set_regexp_variable_var="$1"; shift
+	__quote_set_regexp_variable_out="$*"
+	if [ -z "${__quote_set_regexp_variable_out##*[\[\].*&^\$\\\\/]*}" ]; then
+		__quote_set_regexp_variable_out="$(printf %s "$__quote_set_regexp_variable_out" |
+				sed -e 's/[].*&^$[\/]/\\&/g')" ||
+			return 1
+	fi
+	eval "$__quote_set_regexp_variable_var=\"\$__quote_set_regexp_variable_out\""
+}
+
+# Quote given arguments for sed basic regular expression.
+# Usage example: sed "s/$(quote_sed_regexp "$var_pattern")/$(quote_sed_regexp "$var_replacement")/"
+quote_sed_regexp() {
+	local result
+	quote_sed_regexp_variable result "$@"
+	printf %s "$result"
+}
+
+# Quote argument for shell and store result into variable.
+# Usage example:
+# quote_shell_variable var_name "$var_value"
+# printf '%s\n' "$var_name"
+quote_shell_variable() {
+	local __quote_shell_variable_var __quote_shell_variable_out
+	__quote_shell_variable_var="$1"; shift
+	__quote_shell_variable_out="$*"
+	if [ -z "${__quote_shell_variable_out##*[\"\$\`\\\\]*}" ]; then
+		__quote_shell_variable_out="$(printf %s "$__quote_shell_variable_out" |
+				sed -e 's/[\"$\`\\]/\\&/g')" ||
+			return 1
+	fi
+	eval "$__quote_shell_variable_var=\"\$__quote_shell_variable_out\""
+}
+
+# Quote argument for shell.
+# Usage example: eval "$var_name=\"$(quote_shell "$var_value")\""
+quote_shell() {
+	local result
+	quote_shell_variable result "$@"
+	printf %s "$result"
+}
+
+# Quote argument for shell and store result into variable.
+#
+# Usage example:
+# quote_shell_args args "$var_args"
+# eval "set -- $args"
+quote_shell_args() {
+# This is an internal function to avoid the use of ugly namespace.
+__quote_shell_args() {
+	local m= r= c= l="$1"
+	# backslash/double/single quote mode
+	local bq= dq= sq=
+
+	__quote_shell_args_toggle() {
+		# toggle $1 value
+		eval [ -n \"\$$1\" ] && eval "$1=" || eval "$1=\$$2"
+	}
+
+	fill_mask m "$l"
+
+	while [ -n "$l" ]; do
+		c="${l%$m}"
+		l="${l#?}"
+		m="${m#?}"
+
+		case "$c" in
+			\")
+				# toggle double quote mode unless
+				# in backslash or single quote mode
+				[ -n "$bq$sq" ] || __quote_shell_args_toggle dq c
+				;;
+			\')
+				# toggle single quote mode unless
+				# in backslash or double quote mode
+				[ -n "$bq$dq" ] || __quote_shell_args_toggle sq c
+				;;
+			\$|\`)
+				# quote special character unless
+				# in backslash or single quote mode
+				[ -n "$bq$sq" ] || bq=\\
+				;;
+			\\)
+				# toggle backslash quote mode unless
+				# in single quote mode
+				if [ -z "$sq" ]; then
+					if [ -z "$bq" ]; then
+						# enter backslash quote mode
+						bq=\\
+						continue
+					else
+						# leave backslash quote mode
+						r="$r\\"
+						bq=
+					fi
+				fi
+				;;
+			[!A-Za-z0-9_\ \	])
+				# quote non-regular character unless
+				# in any quote mode
+				[ -n "$bq$dq$sq" ] || bq=\\
+				;;
+		esac
+		r="$r$bq$c"
+		# leave backslash quote mode if any
+		bq=
+	done
+
+	[ -z "$bq$dq$sq" ] ||
+		{ message "unmatched character ($bq$dq$sq) found"; return 1; }
+	__quote_shell_args_out="$r"
+}
+	local __quote_shell_args_out= __quote_shell_args_rc=0
+	__quote_shell_args "$2" ||
+		__quote_shell_args_rc=1
+	eval "$1=\"\$__quote_shell_args_out\""
+
+	# Remove internal functions from user namespace.
+	unset __quote_shell_args __quote_shell_args_toggle
+
+	return $__quote_shell_args_rc
+}
+
+if [ -n "${__export_compatibility_string_quote_remove-}" ]; then
+# Obsolete function. You shouldn't use it.
+string_quote_remove() {
+	local out="$1"
+	if [ -z "${1##*\'}${1%%\'*}" ]; then
+		out="${1#\'}"
+		out="${out%\'}"
+	elif [ -z "${1##*\"}${1%%\"*}" ]; then
+		out="${1#\"}"
+		out="${out%\"}"
+	fi
+	printf %s "$out"
+}
+fi # __export_compatibility_string_quote_remove
+
+fi #__included_shell_quote
diff --git a/helpers/libshell/shell-regexp b/helpers/libshell/shell-regexp
new file mode 120000
index 0000000..1d9df4e
--- /dev/null
+++ b/helpers/libshell/shell-regexp
@@ -0,0 +1 @@
+shell-quote
\ No newline at end of file
diff --git a/helpers/libshell/shell-run b/helpers/libshell/shell-run
new file mode 100644
index 0000000..9719bf8
--- /dev/null
+++ b/helpers/libshell/shell-run
@@ -0,0 +1,40 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_run-}" ]; then
+__included_shell_run=1
+
+. shell-args
+. shell-source
+
+# Execute command if file is executable.
+# Usage: run_if_executable /file arg1 arg2
+#    or: run_if_executable  file arg1 arg2
+run_if_executable() {
+	local v f
+	f="$1"; shift
+	! __shell_source_find v "$f" || [ ! -x "$v" ] || "$v" "$@"
+}
+
+# Run scripts from directory.
+# Usage: run_scripts <dir> [args]
+RUN_SCRIPTS_EXCLUDE='*.rpm* *.swp *,v *~ *.\#'
+run_scripts() {
+	[ "$#" -ge 1 ] ||
+		fatal "Usage: run_scripts <dir> [args]"
+	local p f d rc=0
+	d="$(opt_check_dir "dir" "$1")"; shift
+
+	for f in $(find -L "$d" -mindepth 1 -maxdepth 1 -type f); do
+		for p in $RUN_SCRIPTS_EXCLUDE; do
+			[ -n "${f##$p}" ] ||
+				continue 2
+		done
+		run_if_executable "$f" "$@" || rc=1
+	done
+	return $rc
+}
+
+fi #__included_shell_run
diff --git a/helpers/libshell/shell-signal b/helpers/libshell/shell-signal
new file mode 100644
index 0000000..d7d49f4
--- /dev/null
+++ b/helpers/libshell/shell-signal
@@ -0,0 +1,73 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_signal-}" ]; then
+__included_shell_signal=1
+
+. shell-error
+. shell-quote
+
+__shell_signal_handlers=
+# Set handler code whan any of the specified signals are received.
+# Return code of handler function will be ignored. Special handlers is
+# SIG_IGN and SIG_DFL (See signal(2)).
+#
+# Usage example:
+# signal_handler 'echo $arg' TERM EXIT HUP
+# signal_handler SIG_IGN     TERM EXIT HUP
+# signal_handler SIG_DFL     TERM EXIT HUP
+signal_handler() {
+	local action real_action sign
+	action="$1"; shift
+
+	for sign; do
+		sign="${sign#SIG}"
+		case "$action" in
+			SIG_IGN)
+				eval "unset __signal_handlers_$sign"
+				real_action=:
+				trap : "$sign"
+				;;
+			SIG_DFL)
+				eval "unset __signal_handlers_$sign"
+				real_action=-
+				trap - "$sign"
+				;;
+			*)
+				eval "handler=\"\${__signal_handlers_$sign-} \$action;\""
+				trap "$handler" "$sign"
+				eval "__signal_handlers_$sign=\"\$handler\""
+				;;
+		esac
+	done
+}
+
+# Set exit handler. Return code of handler function will be ignored.
+#
+# Usage example:
+# exit_function() { echo "Exit with return code '$1'"; }
+# set_cleanup_handler exit_function
+__cleanup_handler_name=
+set_cleanup_handler() {
+	__cleanup_handler_name="${1-}"
+	__cleanup_handler() {
+		trap - EXIT
+		[ -z "${__cleanup_handler_name-}" ] ||
+			"$__cleanup_handler_name" "$1" ||:
+		exit "$1"
+	}
+	signal_handler '__cleanup_handler $?' EXIT
+	signal_handler '__cleanup_handler  1' HUP PIPE INT QUIT TERM
+}
+
+# Remove exit handler.
+#
+# Usage example: unset_cleanup_handler
+unset_cleanup_handler() {
+	signal_handler SIG_DFL EXIT HUP PIPE INT QUIT TERM
+	__cleanup_handler_name=
+}
+
+fi #__included_shell_signal
diff --git a/helpers/libshell/shell-source b/helpers/libshell/shell-source
new file mode 100644
index 0000000..0838849
--- /dev/null
+++ b/helpers/libshell/shell-source
@@ -0,0 +1,55 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_source-}" ]; then
+__included_shell_source=1
+
+__shell_source_find() {
+	local r f IFS=:
+	r="$1"; shift
+	f="$1"; shift
+
+	if [ -n "${f##*/*}" ]; then
+		set -- ${PATH-}
+		while [ "$#" -gt 0 ]; do
+			if [ -e "$1/$f" ]; then
+				f="$1/$f"
+				break
+			fi
+			shift
+		done
+	fi
+	[ -e "$f" ] || return 1
+	eval "$r=\"\$f\""
+}
+
+# Execute commands from file in the current environment if file exists.
+# Usage: source_if_exists /file arg1 arg2
+#    or: source_if_exists  file arg1 arg2
+source_if_exists() {
+	local v f
+	f="$1";	shift
+	! __shell_source_find v "$f" || [ ! -f "$v" ] || . "$v"
+}
+
+# Execute commands from file in the current environment if file is not empty.
+# Usage: source_if_notempty /file arg1 arg2
+#    or: source_if_notempty  file arg1 arg2
+source_if_notempty() {
+	local v f
+	f="$1"; shift
+	! __shell_source_find v "$f" || [ ! -s "$v" ] || . "$v"
+}
+
+# Execute commands from file in the current environment if file is executable.
+# Usage: source_if_executable /file arg1 arg2
+#    or: source_if_executable  file arg1 arg2
+source_if_executable() {
+	local v f
+	f="$1"; shift
+	! __shell_source_find v "$f" || [ ! -x "$v" ] || . "$v"
+}
+
+fi #__included_shell_source
diff --git a/helpers/libshell/shell-string b/helpers/libshell/shell-string
new file mode 100644
index 0000000..eb249b5
--- /dev/null
+++ b/helpers/libshell/shell-string
@@ -0,0 +1,28 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_string-}" ]; then
+__included_shell_string=1
+
+# Creates a mask of equal length string.
+# Usage: fill_mask var str [full-length]
+fill_mask() {
+	local __i=0 __m= __v="$1" __s="$2"
+	while [ $__i -lt ${#__s} ]; do
+		__m="$__m?????"
+		__i=$(($__i + 5))
+	done
+	case $((${#__m} - ${#__s})) in
+		5) __m="${__m#?????}" ;;
+		4) __m="${__m#????}" ;;
+		3) __m="${__m#???}" ;;
+		2) __m="${__m#??}" ;;
+		1) __m="${__m#?}" ;;
+	esac
+	[ -n "${3-}" ] || __m="${__m#?}"
+	eval "$__v=\$__m"
+}
+
+fi #__included_shell_string
diff --git a/helpers/libshell/shell-unittest b/helpers/libshell/shell-unittest
new file mode 100644
index 0000000..67cb0c5
--- /dev/null
+++ b/helpers/libshell/shell-unittest
@@ -0,0 +1,252 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_unittest-}" ]; then
+__included_shell_unittest=1
+
+. shell-error
+
+# Append tests condition to comment message if test failed.
+unittest_show_condition="${unittest_show_condition-}"
+
+# Called before each test is run.
+setUp() { :; }
+
+# Called after each test is run.
+tearDown() { :; }
+
+# Called before any test is run.
+setUpTests() { :; }
+
+# Called after any test is run.
+tearDownTests() { :; }
+
+# Register new testing function.
+# appendTests (TestFunc)
+__shell_unit_tests=
+appendTests() {
+	while [ "$#" -gt 0 ]; do
+		__shell_unit_tests="$__shell_unit_tests
+$1"
+		shift
+	done
+}
+
+# Automatically register test functions with 'UnitTest' comment.
+# Name of current shell script will be used if argument is not present.
+# registerTests([/tmp/Tests-File])
+# Example:
+# my_testcase_function() { # UnitTest
+#     blah blah blah ...
+# }
+registerTests() {
+	local l="$(sed -ne 's/^\([[:alnum:]_]\+\)().*[[:space:]]*#[[:space:]]*UnitTest/\1/p' "${1:-$0}")"
+	[ -z "$l" ] || appendTests $l
+}
+
+# Skip test (called in testing function)
+shouldSkip() {
+	exit 2
+}
+
+# Asserts that a given shell test condition (or integer) is true.
+# assertTrue([comment], condition)
+# assertTrue([comment], integer)
+assertTrue() {
+	local comment= condition
+	[ "$#" -lt 2 ] ||
+		{ comment="$1"; shift; }
+	condition="$1"; shift
+
+	[ -z "$unittest_show_condition" ] ||
+		comment="${comment:+$comment }($condition) == false"
+
+	if [ -n "${condition##*[!0-9\-]*}" ]; then
+		[ $condition -ne 0 ] ||
+			return 0
+		[ -z "$comment" ] ||
+			printf '%s' "$comment"
+		exit 1
+	fi
+
+	if ! ( eval "$condition" ) >/dev/null; then
+		[ -z "$comment" ] ||
+			printf '%s' "$comment"
+		exit 1
+	fi
+}
+
+# Asserts that a given shell test condition (or integer) is false.
+# assertFalse([comment], condition)
+# assertFalse([comment], integer)
+assertFalse() {
+	local comment= condition
+	[ "$#" -lt 2 ] ||
+		{ comment="$1"; shift; }
+	condition="$1"; shift
+
+	[ -z "$unittest_show_condition" ] ||
+		comment="${comment:+$comment }($condition) == true"
+
+	if [ -n "${condition##*[!0-9\-]*}" ]; then
+		[ $condition -eq 0 ] ||
+			return 0
+		[ -z "$comment" ] ||
+			printf '%s' "$comment"
+		exit 1
+	fi
+
+	if ( eval "$condition" ) >/dev/null; then
+		[ -z "$comment" ] ||
+			printf '%s' "$comment"
+		exit 1
+	fi
+}
+
+# Asserts that two arguments are equal to one another.
+# assertEquals([comment], expected, actual)
+assertEquals() {
+	local comment= expected actual
+	[ "$#" -lt 3 ] ||
+		{ comment="$1"; shift; }
+	expected="$1"; shift
+	actual="$1"; shift
+
+	if [ "$expected" != "$actual" ]; then
+		[ -z "$unittest_show_condition" ] ||
+			comment="${comment:+$comment }($expected) != ($actual)"
+		[ -z "$comment" ] ||
+			printf '%s' "$comment"
+		exit 1
+	fi
+}
+
+# Asserts that two arguments are same.
+# assertSame([comment], expected, actual)
+assertSame() {
+	assertEquals "${@-}"
+}
+
+# Asserts that two arguments are not equal to one another.
+# assertNotEquals([comment], expected, actual)
+assertNotEquals() {
+	local comment= expected actual
+	[ "$#" -lt 3 ] ||
+		{ comment="$1"; shift; }
+	expected="$1"; shift
+	actual="$1"; shift
+
+	if [ "$expected" = "$actual" ]; then
+		[ -z "$unittest_show_condition" ] ||
+			comment="${comment:+$comment }($expected) == ($actual)"
+		[ -z "$comment" ] ||
+			printf '%s' "$comment"
+		exit 1
+	fi
+}
+
+# Asserts that two arguments are not same.
+# assertNotSame([comment], expected, actual)
+assertNotSame() {
+	assertNotEquals "${@-}"
+}
+
+# Asserts that argument is a zero-length string.
+# assertNull([comment], value)
+assertNull() {
+	local comment= value
+	[ "$#" -lt 2 ] ||
+		{ comment="$1"; shift; }
+	value="$1"; shift
+
+	if [ -n "$value" ]; then
+		[ -z "$unittest_show_condition" ] ||
+			comment="${comment:+$comment }($value) == ''"
+		[ -z "$comment" ] ||
+			printf '%s' "$comment"
+		exit 1
+	fi
+}
+
+# Asserts that argument is not empty string.
+# assertNotNull([comment], value)
+assertNotNull() {
+	local comment= value
+	[ "$#" -lt 2 ] ||
+		{ comment="$1"; shift; }
+	value="$1"; shift
+
+	if [ -z "$value" ]; then
+		[ -z "$unittest_show_condition" ] ||
+			comment="${comment:+$comment }($value) != ''"
+		[ -z "$comment" ] ||
+			printf '%s' "$comment"
+		exit 1
+	fi
+}
+
+# Display status message after each test.
+messageTest() {
+	case "$3" in
+		0) printf '[done]' ;;
+		1) printf '[FAIL]' ;;
+		2) printf '[skip]' ;;
+		*) printf '[status=%s]' $3 ;;
+	esac
+	printf ' (%s) %s\n' "$1" "$2"
+}
+
+# Display summary statistic.
+showSummary() {
+	if [ "$total" -eq 0 ]; then
+		message "Nothing to do"
+		return
+	fi
+	printf '\n'
+	printf 'tests passed:  %6d %3d%%\n' "$passed" "$((($passed*100)/$total))"
+	printf 'tests failed:  %6d %3d%%\n' "$failed" "$((($failed*100)/$total))"
+	printf 'tests skipped: %6d %3d%%\n' "$skipped" "$((($skipped*100)/$total))"
+	printf 'tests total:   %6d\n\n' "$total"
+}
+
+# Run tests.
+runUnitTests() {
+
+	run_or_exit() {
+		"$@" || fatal "$1() fail rc=$?"
+	}
+
+	run_or_exit setUpTests
+
+	local IFS=' 	
+'
+	__shell_unit_tests="$(printf '%s\n' "$__shell_unit_tests" |sort -u)"
+	set -- ${__shell_unit_tests-}
+
+	local retval=0 rc passed=0 failed=0 skipped=0 total="$#"
+
+	while [ "$#" -gt 0 ]; do
+		run_or_exit setUp
+
+		rc=0
+		msg="$("$1")" || rc=$?
+
+		case "$rc" in
+			0) passed=$(($passed+1)) ;;
+			1) failed=$(($failed+1)); retval=1; ;;
+			2) skipped=$(($skipped+1)) ;;
+		esac
+		run_or_exit messageTest "$1" "$msg" "$rc"
+
+		run_or_exit tearDown
+		shift
+	done
+	run_or_exit showSummary
+	run_or_exit tearDownTests
+
+	return $retval
+}
+
+fi #__included_shell_unittest
diff --git a/helpers/libshell/shell-var b/helpers/libshell/shell-var
new file mode 100644
index 0000000..39c1299
--- /dev/null
+++ b/helpers/libshell/shell-var
@@ -0,0 +1,75 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_var-}" ]; then
+__included_shell_var=1
+
+. shell-error
+
+shell_var_is_yes() {
+	[ "$#" -eq 1 ] ||
+		fatal "Usage: shell_var_yes value"
+	case "$1" in
+		[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|[Yy]|1) return 0 ;;
+	esac
+	return 1
+}
+
+shell_var_is_no() {
+	[ "$#" -eq 1 ] ||
+		fatal "Usage: shell_var_no value"
+	case "$1" in
+		[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|[Nn]|0) return 0 ;;
+	esac
+	return 1
+}
+
+# Strip whitespace from the beginning and end of a string
+# Usage: shell_var_trim retval "   aaa bb  aaa "; echo "[$retval]"
+# [aaa bb  aaa]
+shell_var_trim() {
+	[ "$#" -eq 2 ] ||
+		fatal "Usage: shell_var_trim varname value"
+	local __shell_var_trim_var="$1" __shell_var_trim_ret="$2"
+	local IFS=' 	
+'
+	set -- $__shell_var_trim_ret
+	if [ "$#" -eq 0 ]; then
+		eval "$__shell_var_trim_var=''"
+		return
+	fi
+	__shell_var_trim_ret="$1${__shell_var_trim_ret#*$1}"
+	shift $(($#-1))
+	__shell_var_trim_ret="${__shell_var_trim_ret%$1*}$1"
+	eval "$__shell_var_trim_var=\"\$__shell_var_trim_ret\""
+}
+
+# Remove quote symbol from string
+# Usage example:
+# for i in "\"str1\"" "'str2'" "\"str3'"; do
+#    shell_var_unquote var "$i";
+#    echo "$var";
+# done
+#
+# Result:
+# str1
+# str2
+# "str3'
+#
+shell_var_unquote() {
+	[ "$#" -eq 2 ] ||
+		fatal "Usage: shell_var_unquote varname value"
+	local __shell_var_unquote_var="$1" __shell_var_unquote_out="$2"
+	if [ -z "${__shell_var_unquote_out##*\'}${__shell_var_unquote_out%%\'*}" ]; then
+		__shell_var_unquote_out="${__shell_var_unquote_out#\'}"
+		__shell_var_unquote_out="${__shell_var_unquote_out%\'}"
+	elif [ -z "${__shell_var_unquote_out##*\"}${__shell_var_unquote_out%%\"*}" ]; then
+		__shell_var_unquote_out="${__shell_var_unquote_out#\"}"
+		__shell_var_unquote_out="${__shell_var_unquote_out%\"}"
+	fi
+	eval "$__shell_var_unquote_var=\"\$__shell_var_unquote_out\""
+}
+
+fi #__included_shell_var
diff --git a/helpers/libshell/shell-version b/helpers/libshell/shell-version
new file mode 100644
index 0000000..12eb48a
--- /dev/null
+++ b/helpers/libshell/shell-version
@@ -0,0 +1,13 @@
+#!/bin/sh -efu
+# This file is covered by the GNU General Public License,
+# which should be included with libshell as the file LICENSE.
+# All copyright information are listed in the COPYING.
+
+if [ -z "${__included_shell_version-}" ]; then
+__included_shell_version=1
+
+libshell_version=3
+
+__export_compatibility_string_quote_remove=1
+
+fi #__included_shell_version
diff --git a/helpers/libshell/tests/cmdline_get b/helpers/libshell/tests/cmdline_get
new file mode 100644
index 0000000..786415f
--- /dev/null
+++ b/helpers/libshell/tests/cmdline_get
@@ -0,0 +1,59 @@
+#!/bin/ash -efu
+
+CMDLINE='ro rw= root=LABEL=ROOT resume=/dev/sda1 panic=30 foo.bar="zzz xxx" BOOT_IMAGE=/bad/param BOOT-IMAGE=/boot/vmlinuz'
+
+cmdline_get_test1() { # UnitTest
+	. ../shell-cmdline
+
+	local result
+	cmdline_get 'result' 'resume' "$CMDLINE"
+	assertEquals "resume=[$result]" "$result" '/dev/sda1'
+}
+
+cmdline_get_test2() { # UnitTest
+	. ../shell-cmdline
+
+	local result
+	cmdline_get 'result' 'ro' "$CMDLINE"
+	assertEquals "ro=[$result]" "$result" '1'
+}
+
+cmdline_get_test3() { # UnitTest
+	. ../shell-cmdline
+
+	local result
+	cmdline_get 'result' 'rw' "$CMDLINE"
+	assertEquals "rw=[$result]" "$result" ''
+}
+
+cmdline_get_test4() { # UnitTest
+	. ../shell-cmdline
+
+	local result
+	cmdline_get 'result' 'root' "$CMDLINE"
+	assertEquals "root=[$result]" "$result" 'LABEL=ROOT'
+}
+
+cmdline_get_test5() { # UnitTest
+	. ../shell-cmdline
+
+	local result
+	cmdline_get 'result' 'foo.bar' "$CMDLINE"
+	assertEquals "foo.bar=[$result]" "$result" 'zzz xxx'
+}
+
+cmdline_get_test6() { # UnitTest
+	. ../shell-cmdline
+
+	local result
+	cmdline_get 'result' 'BOOT-IMAGE' "$CMDLINE"
+	assertEquals "BOOT-IMAGE=[$result]" "$result" '/boot/vmlinuz'
+}
+
+cmdline_get_test7() { # UnitTest
+	. ../shell-cmdline
+
+	local result
+	cmdline_get 'result' 'BOOT_IMAGE' "$CMDLINE"
+	assertEquals "BOOT_IMAGE=[$result]" "$result" '/boot/vmlinuz'
+}
diff --git a/helpers/libshell/tests/data/000-quote_shell_args-pattern b/helpers/libshell/tests/data/000-quote_shell_args-pattern
new file mode 100644
index 0000000..6cd822a
--- /dev/null
+++ b/helpers/libshell/tests/data/000-quote_shell_args-pattern
@@ -0,0 +1 @@
+a b "c d" 'e f'
diff --git a/helpers/libshell/tests/data/000-quote_shell_args-result b/helpers/libshell/tests/data/000-quote_shell_args-result
new file mode 100644
index 0000000..3a61335
--- /dev/null
+++ b/helpers/libshell/tests/data/000-quote_shell_args-result
@@ -0,0 +1 @@
+[a] [b] [c d] [e f]
diff --git a/helpers/libshell/tests/data/001-quote_shell_args-pattern b/helpers/libshell/tests/data/001-quote_shell_args-pattern
new file mode 100644
index 0000000..2295343
--- /dev/null
+++ b/helpers/libshell/tests/data/001-quote_shell_args-pattern
@@ -0,0 +1 @@
+a b "c ' d" 'e " f'
diff --git a/helpers/libshell/tests/data/001-quote_shell_args-result b/helpers/libshell/tests/data/001-quote_shell_args-result
new file mode 100644
index 0000000..6cbd863
--- /dev/null
+++ b/helpers/libshell/tests/data/001-quote_shell_args-result
@@ -0,0 +1 @@
+[a] [b] [c ' d] [e " f]
diff --git a/helpers/libshell/tests/data/002-quote_shell_args-pattern b/helpers/libshell/tests/data/002-quote_shell_args-pattern
new file mode 100644
index 0000000..4864ed2
--- /dev/null
+++ b/helpers/libshell/tests/data/002-quote_shell_args-pattern
@@ -0,0 +1 @@
+a b "c \" d" e f
diff --git a/helpers/libshell/tests/data/002-quote_shell_args-result b/helpers/libshell/tests/data/002-quote_shell_args-result
new file mode 100644
index 0000000..55f3ed0
--- /dev/null
+++ b/helpers/libshell/tests/data/002-quote_shell_args-result
@@ -0,0 +1 @@
+[a] [b] [c " d] [e] [f]
diff --git a/helpers/libshell/tests/data/003-quote_shell_args-pattern b/helpers/libshell/tests/data/003-quote_shell_args-pattern
new file mode 100644
index 0000000..dd00149
--- /dev/null
+++ b/helpers/libshell/tests/data/003-quote_shell_args-pattern
@@ -0,0 +1 @@
+a $HOME \$HOME \\$HOME \\\$HOME \\\\$HOME c
diff --git a/helpers/libshell/tests/data/003-quote_shell_args-result b/helpers/libshell/tests/data/003-quote_shell_args-result
new file mode 100644
index 0000000..165edcf
--- /dev/null
+++ b/helpers/libshell/tests/data/003-quote_shell_args-result
@@ -0,0 +1 @@
+[a] [$HOME] [$HOME] [\$HOME] [\$HOME] [\\$HOME] [c]
diff --git a/helpers/libshell/tests/data/004-quote_shell_args-pattern b/helpers/libshell/tests/data/004-quote_shell_args-pattern
new file mode 100644
index 0000000..2625179
--- /dev/null
+++ b/helpers/libshell/tests/data/004-quote_shell_args-pattern
@@ -0,0 +1 @@
+a "$HOME \$HOME \\$HOME \\\$HOME \\\\$HOME" c
diff --git a/helpers/libshell/tests/data/004-quote_shell_args-result b/helpers/libshell/tests/data/004-quote_shell_args-result
new file mode 100644
index 0000000..042a83a
--- /dev/null
+++ b/helpers/libshell/tests/data/004-quote_shell_args-result
@@ -0,0 +1 @@
+[a] [$HOME $HOME \$HOME \$HOME \\$HOME] [c]
diff --git a/helpers/libshell/tests/data/005-quote_shell_args-pattern b/helpers/libshell/tests/data/005-quote_shell_args-pattern
new file mode 100644
index 0000000..1b7a7ab
--- /dev/null
+++ b/helpers/libshell/tests/data/005-quote_shell_args-pattern
@@ -0,0 +1 @@
+a '$HOME \$HOME \\$HOME \\\$HOME \\\\$HOME' c
diff --git a/helpers/libshell/tests/data/005-quote_shell_args-result b/helpers/libshell/tests/data/005-quote_shell_args-result
new file mode 100644
index 0000000..7a90df0
--- /dev/null
+++ b/helpers/libshell/tests/data/005-quote_shell_args-result
@@ -0,0 +1 @@
+[a] [$HOME \$HOME \\$HOME \\\$HOME \\\\$HOME] [c]
diff --git a/helpers/libshell/tests/data/006-quote_shell_args-pattern b/helpers/libshell/tests/data/006-quote_shell_args-pattern
new file mode 100644
index 0000000..0441d5b
--- /dev/null
+++ b/helpers/libshell/tests/data/006-quote_shell_args-pattern
@@ -0,0 +1 @@
+/bin/shell-* /bin/shell-[a-z]* /bin/shell-{error,getopt}
diff --git a/helpers/libshell/tests/data/006-quote_shell_args-result b/helpers/libshell/tests/data/006-quote_shell_args-result
new file mode 100644
index 0000000..08120b3
--- /dev/null
+++ b/helpers/libshell/tests/data/006-quote_shell_args-result
@@ -0,0 +1 @@
+[/bin/shell-*] [/bin/shell-[a-z]*] [/bin/shell-{error,getopt}]
diff --git a/helpers/libshell/tests/data/007-quote_shell_args-pattern b/helpers/libshell/tests/data/007-quote_shell_args-pattern
new file mode 100644
index 0000000..704540f
--- /dev/null
+++ b/helpers/libshell/tests/data/007-quote_shell_args-pattern
@@ -0,0 +1 @@
+"/bin/shell-* /bin/shell-[a-z]* /bin/shell-{error,getopt}"
diff --git a/helpers/libshell/tests/data/007-quote_shell_args-result b/helpers/libshell/tests/data/007-quote_shell_args-result
new file mode 100644
index 0000000..3551aca
--- /dev/null
+++ b/helpers/libshell/tests/data/007-quote_shell_args-result
@@ -0,0 +1 @@
+[/bin/shell-* /bin/shell-[a-z]* /bin/shell-{error,getopt}]
diff --git a/helpers/libshell/tests/data/008-quote_shell_args-pattern b/helpers/libshell/tests/data/008-quote_shell_args-pattern
new file mode 100644
index 0000000..13a6e8c
--- /dev/null
+++ b/helpers/libshell/tests/data/008-quote_shell_args-pattern
@@ -0,0 +1 @@
+/bin/shell-* "/bin/shell-[a-z]* /bin/shell-{error,getopt}"
diff --git a/helpers/libshell/tests/data/008-quote_shell_args-result b/helpers/libshell/tests/data/008-quote_shell_args-result
new file mode 100644
index 0000000..ba3c8ae
--- /dev/null
+++ b/helpers/libshell/tests/data/008-quote_shell_args-result
@@ -0,0 +1 @@
+[/bin/shell-*] [/bin/shell-[a-z]* /bin/shell-{error,getopt}]
diff --git a/helpers/libshell/tests/data/009-quote_shell_args-pattern b/helpers/libshell/tests/data/009-quote_shell_args-pattern
new file mode 100644
index 0000000..e5f904d
--- /dev/null
+++ b/helpers/libshell/tests/data/009-quote_shell_args-pattern
@@ -0,0 +1 @@
+'/bin/shell-* /bin/shell-[a-z]* /bin/shell-{error,getopt}'
diff --git a/helpers/libshell/tests/data/009-quote_shell_args-result b/helpers/libshell/tests/data/009-quote_shell_args-result
new file mode 100644
index 0000000..3551aca
--- /dev/null
+++ b/helpers/libshell/tests/data/009-quote_shell_args-result
@@ -0,0 +1 @@
+[/bin/shell-* /bin/shell-[a-z]* /bin/shell-{error,getopt}]
diff --git a/helpers/libshell/tests/data/010-quote_shell_args-pattern b/helpers/libshell/tests/data/010-quote_shell_args-pattern
new file mode 100644
index 0000000..e861ce6
--- /dev/null
+++ b/helpers/libshell/tests/data/010-quote_shell_args-pattern
@@ -0,0 +1 @@
+`echo $HOME` "`echo $HOME`" '`echo $HOME`' "(`echo $HOME`)"
diff --git a/helpers/libshell/tests/data/010-quote_shell_args-result b/helpers/libshell/tests/data/010-quote_shell_args-result
new file mode 100644
index 0000000..98ef34d
--- /dev/null
+++ b/helpers/libshell/tests/data/010-quote_shell_args-result
@@ -0,0 +1 @@
+[`echo] [$HOME`] [`echo $HOME`] [`echo $HOME`] [(`echo $HOME`)]
diff --git a/helpers/libshell/tests/data/011-quote_shell_args-pattern b/helpers/libshell/tests/data/011-quote_shell_args-pattern
new file mode 100644
index 0000000..9701008
--- /dev/null
+++ b/helpers/libshell/tests/data/011-quote_shell_args-pattern
@@ -0,0 +1 @@
+echo |- echo;echo echo echo||echo "echo||echo" 'echo||echo'
diff --git a/helpers/libshell/tests/data/011-quote_shell_args-result b/helpers/libshell/tests/data/011-quote_shell_args-result
new file mode 100644
index 0000000..9b75bcd
--- /dev/null
+++ b/helpers/libshell/tests/data/011-quote_shell_args-result
@@ -0,0 +1 @@
+[echo] [|-] [echo;echo] [echo] [echo||echo] [echo||echo] [echo||echo]
diff --git a/helpers/libshell/tests/data/012-quote_shell_args-pattern b/helpers/libshell/tests/data/012-quote_shell_args-pattern
new file mode 100644
index 0000000..a63d458
--- /dev/null
+++ b/helpers/libshell/tests/data/012-quote_shell_args-pattern
@@ -0,0 +1 @@
+a b "c \\\" ' d" 'e " f'
diff --git a/helpers/libshell/tests/data/012-quote_shell_args-result b/helpers/libshell/tests/data/012-quote_shell_args-result
new file mode 100644
index 0000000..05edec3
--- /dev/null
+++ b/helpers/libshell/tests/data/012-quote_shell_args-result
@@ -0,0 +1 @@
+[a] [b] [c \" ' d] [e " f]
diff --git a/helpers/libshell/tests/data/013-quote_shell_args-pattern b/helpers/libshell/tests/data/013-quote_shell_args-pattern
new file mode 100644
index 0000000..d29c27d
--- /dev/null
+++ b/helpers/libshell/tests/data/013-quote_shell_args-pattern
@@ -0,0 +1 @@
+a b <<EOF "<<EOF" '<<EOF' <<'__EOF__' c
diff --git a/helpers/libshell/tests/data/013-quote_shell_args-result b/helpers/libshell/tests/data/013-quote_shell_args-result
new file mode 100644
index 0000000..93cb351
--- /dev/null
+++ b/helpers/libshell/tests/data/013-quote_shell_args-result
@@ -0,0 +1 @@
+[a] [b] [<<EOF] [<<EOF] [<<EOF] [<<__EOF__] [c]
diff --git a/helpers/libshell/tests/data/014-quote_shell_args-pattern b/helpers/libshell/tests/data/014-quote_shell_args-pattern
new file mode 100644
index 0000000..3fd87ba
--- /dev/null
+++ b/helpers/libshell/tests/data/014-quote_shell_args-pattern
@@ -0,0 +1 @@
+a || b && c "&&" d '&&' e &
diff --git a/helpers/libshell/tests/data/014-quote_shell_args-result b/helpers/libshell/tests/data/014-quote_shell_args-result
new file mode 100644
index 0000000..a4c53b3
--- /dev/null
+++ b/helpers/libshell/tests/data/014-quote_shell_args-result
@@ -0,0 +1 @@
+[a] [||] [b] [&&] [c] [&&] [d] [&&] [e] [&]
diff --git a/helpers/libshell/tests/data/015-quote_shell_args-pattern b/helpers/libshell/tests/data/015-quote_shell_args-pattern
new file mode 100644
index 0000000..bcaec60
--- /dev/null
+++ b/helpers/libshell/tests/data/015-quote_shell_args-pattern
@@ -0,0 +1 @@
+a ! b "! c" '!' d
diff --git a/helpers/libshell/tests/data/015-quote_shell_args-result b/helpers/libshell/tests/data/015-quote_shell_args-result
new file mode 100644
index 0000000..43a574f
--- /dev/null
+++ b/helpers/libshell/tests/data/015-quote_shell_args-result
@@ -0,0 +1 @@
+[a] [!] [b] [! c] [!] [d]
diff --git a/helpers/libshell/tests/data/016-quote_shell_args-pattern b/helpers/libshell/tests/data/016-quote_shell_args-pattern
new file mode 100644
index 0000000..c0e6470
--- /dev/null
+++ b/helpers/libshell/tests/data/016-quote_shell_args-pattern
@@ -0,0 +1 @@
+echo ~ "echo ~" 'echo ~'
diff --git a/helpers/libshell/tests/data/016-quote_shell_args-result b/helpers/libshell/tests/data/016-quote_shell_args-result
new file mode 100644
index 0000000..4f4670a
--- /dev/null
+++ b/helpers/libshell/tests/data/016-quote_shell_args-result
@@ -0,0 +1 @@
+[echo] [~] [echo ~] [echo ~]
diff --git a/helpers/libshell/tests/data/017-quote_shell_args-pattern b/helpers/libshell/tests/data/017-quote_shell_args-pattern
new file mode 100644
index 0000000..e07dfd1
--- /dev/null
+++ b/helpers/libshell/tests/data/017-quote_shell_args-pattern
@@ -0,0 +1 @@
+. /etc/passwd ". /etc/passwd"
diff --git a/helpers/libshell/tests/data/017-quote_shell_args-result b/helpers/libshell/tests/data/017-quote_shell_args-result
new file mode 100644
index 0000000..7c16fa6
--- /dev/null
+++ b/helpers/libshell/tests/data/017-quote_shell_args-result
@@ -0,0 +1 @@
+[.] [/etc/passwd] [. /etc/passwd]
diff --git a/helpers/libshell/tests/data/018-quote_shell_args-pattern b/helpers/libshell/tests/data/018-quote_shell_args-pattern
new file mode 100644
index 0000000..1418321
--- /dev/null
+++ b/helpers/libshell/tests/data/018-quote_shell_args-pattern
@@ -0,0 +1 @@
+\\''
diff --git a/helpers/libshell/tests/data/018-quote_shell_args-result b/helpers/libshell/tests/data/018-quote_shell_args-result
new file mode 100644
index 0000000..c147d78
--- /dev/null
+++ b/helpers/libshell/tests/data/018-quote_shell_args-result
@@ -0,0 +1 @@
+[\]
diff --git a/helpers/libshell/tests/data/019-quote_shell_args-pattern b/helpers/libshell/tests/data/019-quote_shell_args-pattern
new file mode 100644
index 0000000..a35d9d7
--- /dev/null
+++ b/helpers/libshell/tests/data/019-quote_shell_args-pattern
@@ -0,0 +1 @@
+\'
diff --git a/helpers/libshell/tests/data/019-quote_shell_args-result b/helpers/libshell/tests/data/019-quote_shell_args-result
new file mode 100644
index 0000000..efa1f25
--- /dev/null
+++ b/helpers/libshell/tests/data/019-quote_shell_args-result
@@ -0,0 +1 @@
+[']
diff --git a/helpers/libshell/tests/data/020-quote_shell_args-pattern b/helpers/libshell/tests/data/020-quote_shell_args-pattern
new file mode 100644
index 0000000..6bc83a6
--- /dev/null
+++ b/helpers/libshell/tests/data/020-quote_shell_args-pattern
@@ -0,0 +1 @@
+a\
diff --git a/helpers/libshell/tests/data/020-quote_shell_args-result b/helpers/libshell/tests/data/020-quote_shell_args-result
new file mode 100644
index 0000000..fe51488
--- /dev/null
+++ b/helpers/libshell/tests/data/020-quote_shell_args-result
@@ -0,0 +1 @@
+[]
diff --git a/helpers/libshell/tests/data/021-quote_shell_args-pattern b/helpers/libshell/tests/data/021-quote_shell_args-pattern
new file mode 100644
index 0000000..bd91527
--- /dev/null
+++ b/helpers/libshell/tests/data/021-quote_shell_args-pattern
@@ -0,0 +1 @@
+1"22"333"4444
diff --git a/helpers/libshell/tests/data/021-quote_shell_args-result b/helpers/libshell/tests/data/021-quote_shell_args-result
new file mode 100644
index 0000000..fe51488
--- /dev/null
+++ b/helpers/libshell/tests/data/021-quote_shell_args-result
@@ -0,0 +1 @@
+[]
diff --git a/helpers/libshell/tests/data/022-quote_shell_args-pattern b/helpers/libshell/tests/data/022-quote_shell_args-pattern
new file mode 100644
index 0000000..6cd22b7
--- /dev/null
+++ b/helpers/libshell/tests/data/022-quote_shell_args-pattern
@@ -0,0 +1 @@
+1'22'333'4444
diff --git a/helpers/libshell/tests/data/022-quote_shell_args-result b/helpers/libshell/tests/data/022-quote_shell_args-result
new file mode 100644
index 0000000..fe51488
--- /dev/null
+++ b/helpers/libshell/tests/data/022-quote_shell_args-result
@@ -0,0 +1 @@
+[]
diff --git a/helpers/libshell/tests/data/023-quote_shell_args-pattern b/helpers/libshell/tests/data/023-quote_shell_args-pattern
new file mode 100644
index 0000000..032d059
--- /dev/null
+++ b/helpers/libshell/tests/data/023-quote_shell_args-pattern
@@ -0,0 +1 @@
+"\
diff --git a/helpers/libshell/tests/data/023-quote_shell_args-result b/helpers/libshell/tests/data/023-quote_shell_args-result
new file mode 100644
index 0000000..fe51488
--- /dev/null
+++ b/helpers/libshell/tests/data/023-quote_shell_args-result
@@ -0,0 +1 @@
+[]
diff --git a/helpers/libshell/tests/data/024-quote_shell_args-pattern b/helpers/libshell/tests/data/024-quote_shell_args-pattern
new file mode 100644
index 0000000..4196dc7
--- /dev/null
+++ b/helpers/libshell/tests/data/024-quote_shell_args-pattern
@@ -0,0 +1 @@
+'\' '\\'
diff --git a/helpers/libshell/tests/data/024-quote_shell_args-result b/helpers/libshell/tests/data/024-quote_shell_args-result
new file mode 100644
index 0000000..43ba0fc
--- /dev/null
+++ b/helpers/libshell/tests/data/024-quote_shell_args-result
@@ -0,0 +1 @@
+[\] [\\]
diff --git a/helpers/libshell/tests/data/025-quote_shell_args-pattern b/helpers/libshell/tests/data/025-quote_shell_args-pattern
new file mode 100644
index 0000000..bc1abfd
--- /dev/null
+++ b/helpers/libshell/tests/data/025-quote_shell_args-pattern
@@ -0,0 +1 @@
+"\"" "\\"
diff --git a/helpers/libshell/tests/data/025-quote_shell_args-result b/helpers/libshell/tests/data/025-quote_shell_args-result
new file mode 100644
index 0000000..1df8039
--- /dev/null
+++ b/helpers/libshell/tests/data/025-quote_shell_args-result
@@ -0,0 +1 @@
+["] [\]
diff --git a/helpers/libshell/tests/data/026-quote_shell_args-pattern b/helpers/libshell/tests/data/026-quote_shell_args-pattern
new file mode 100644
index 0000000..a3e94b8
--- /dev/null
+++ b/helpers/libshell/tests/data/026-quote_shell_args-pattern
@@ -0,0 +1 @@
+\123 \xab \" \\ \a \b \c \d \e \f \n \r \t \v
diff --git a/helpers/libshell/tests/data/026-quote_shell_args-result b/helpers/libshell/tests/data/026-quote_shell_args-result
new file mode 100644
index 0000000..34687dd
--- /dev/null
+++ b/helpers/libshell/tests/data/026-quote_shell_args-result
@@ -0,0 +1 @@
+[123] [xab] ["] [\] [a] [b] [c] [d] [e] [f] [n] [r] [t] [v]
diff --git a/helpers/libshell/tests/data/027-quote_shell_args-pattern b/helpers/libshell/tests/data/027-quote_shell_args-pattern
new file mode 100644
index 0000000..ada69c1
--- /dev/null
+++ b/helpers/libshell/tests/data/027-quote_shell_args-pattern
@@ -0,0 +1 @@
+$'\n' $"\r"
diff --git a/helpers/libshell/tests/data/027-quote_shell_args-result b/helpers/libshell/tests/data/027-quote_shell_args-result
new file mode 100644
index 0000000..ab66eb8
--- /dev/null
+++ b/helpers/libshell/tests/data/027-quote_shell_args-result
@@ -0,0 +1 @@
+[$\n] [$\r]
diff --git a/helpers/libshell/tests/fatal b/helpers/libshell/tests/fatal
new file mode 100644
index 0000000..7738f87
--- /dev/null
+++ b/helpers/libshell/tests/fatal
@@ -0,0 +1,33 @@
+#!/bin/ash -efu
+
+PROG='TEST'
+
+fatal_test1() { # UnitTest
+	. ../shell-error
+	expect="$PROG: message message;"
+	result=`fatal "message message" 2>&1 |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+fatal_test2() { # UnitTest
+	. ../shell-error
+	expect="$PROG: message;message;"
+	result=`fatal "message
+message" 2>&1 |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+fatal_test3() { # UnitTest
+	. ../shell-error
+	zzz=ZZZ
+	expect="$PROG: message ZZZ message;"
+	result=`fatal "message $zzz message" 2>&1 |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+fatal_test4() { # UnitTest
+	. ../shell-error
+	expect="$PROG: message message;"
+	result=`{ fatal "message message" 2>&1; echo "another message"; } |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
diff --git a/helpers/libshell/tests/fill_mask b/helpers/libshell/tests/fill_mask
new file mode 100644
index 0000000..9e07be4
--- /dev/null
+++ b/helpers/libshell/tests/fill_mask
@@ -0,0 +1,43 @@
+#!/bin/ash -efu
+
+fill_mask_test01() { # UnitTest
+	. ../shell-quote
+	local result string='1234567890'
+	fill_mask result "$string"
+	assertEquals "$string" "$result" "?????????"
+}
+
+fill_mask_test02() { # UnitTest
+	. ../shell-quote
+	local result string='1234567890123'
+	fill_mask result "$string"
+	assertEquals "$string" "$result" "????????????"
+}
+
+fill_mask_test03() { # UnitTest
+	. ../shell-quote
+	local result string='1234567890123'
+	fill_mask result "$string" 1
+	assertEquals "$string" "$result" "?????????????"
+}
+
+fill_mask_test04() { # UnitTest
+	. ../shell-quote
+	local result string='1'
+	fill_mask result "$string"
+	assertEquals "$string" "$result" ""
+}
+
+fill_mask_test05() { # UnitTest
+	. ../shell-quote
+	local result string='12'
+	fill_mask result "$string"
+	assertEquals "$string" "$result" "?"
+}
+
+fill_mask_test06() { # UnitTest
+	. ../shell-quote
+	local result string='123'
+	fill_mask result "$string"
+	assertEquals "$string" "$result" "??"
+}
diff --git a/helpers/libshell/tests/getopt b/helpers/libshell/tests/getopt
new file mode 100644
index 0000000..b602487
--- /dev/null
+++ b/helpers/libshell/tests/getopt
@@ -0,0 +1,151 @@
+#!/bin/ash -efu
+
+normalize() {
+	sed \
+		-e "s/\"/'/g" \
+		-e 's/[[:space:]]\+/ /g' \
+		-e 's/^[[:space:]]\+//' \
+		-e 's/[[:space:]]\+$//'
+}
+
+getopt_test001() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+getopt_test002() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o ' ' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o ' ' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+getopt_test003() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o '' -l ' ' -- ZZZ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o '' -l ' ' -- ZZZ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+
+getopt_test004() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o 'a,b,c' -- -abc -a -b -c ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o 'a,b,c' -- -abc -a -b -c ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+getopt_test005() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -abc --caa 'AAA' --cba='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -abc --caa 'AAA' --cba='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+getopt_test006() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- --cb 'AAA' --c='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- --cb 'AAA' --c='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+getopt_test007() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- --cbz 'AAA' --c='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- --cbz 'AAA' --c='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+getopt_test008() { # UnitTest
+	LANG=C
+	expect=`{ getopt -a -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -cb 'AAA' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -a -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -cb 'AAA' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+getopt_test009() { # UnitTest
+	LANG=C
+	expect=`{ getopt -a -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -c='AAA' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -a -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -c='AAA' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	(assertEquals "$result" "$result" "$expect") ||:
+	shouldSkip
+}
+
+getopt_test010() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -c='AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -c='AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	(assertEquals "$result" "$result" "$expect") ||:
+	shouldSkip
+}
+
+getopt_test011() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o 'a,b,c' -l 'abcd:,cbce:' -- --abcx 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o 'a,b,c' -l 'abcd:,cbce:' -- --abcx 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+getopt_test012() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o 'a:,b,c' -- -abc 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o 'a:,b,c' -- -abc 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+getopt_test013() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o 'a::,b,c' -- -a -bc 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o 'a::,b,c' -- -a -bc 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+getopt_test014() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- 'BBB' 'XXX ZZZ'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- 'BBB' 'XXX ZZZ'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+getopt_test015() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o '+a,b,c' -l 'caa:,cba:' -- --caa='AAA' 'BBB' --zzz -x; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o '+a,b,c' -l 'caa:,cba:' -- --caa='AAA' 'BBB' --zzz -x; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+
+getopt_test016() { # UnitTest
+	LANG=C
+	expect=`{ getopt -n TEST -o '-a,b,c' -l 'caa:,cba:' -- 'AAA' --caa='BBB' 'CCC'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	. ../shell-getopt
+	result=`{ getopt -n TEST -o '-a,b,c' -l 'caa:,cba:' -- 'AAA' --caa='BBB' 'CCC'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+getopt_test017() { # UnitTest
+	LANG=C
+	. ../shell-getopt
+	expect=' -a -b -- 
+ -a -b -- 
+ -a -b -- '
+	result=`for i in 1 2 3; do getopt -n TEST -o 'a,b' -- -ab; done 2>&1`
+	assertEquals "$result" "$result" "$expect"
+}
diff --git a/helpers/libshell/tests/ini-config/z.ini b/helpers/libshell/tests/ini-config/z.ini
new file mode 100644
index 0000000..967c5c4
--- /dev/null
+++ b/helpers/libshell/tests/ini-config/z.ini
@@ -0,0 +1,12 @@
+[global]
+	user= 	Foo Bar
+email = foo at bar
+
+[sect1]
+opt=OPT
+opt1=OPT1
+opt=OPT
+
+# Blah Blah
+[sect]
+opt="ZZZ XXX"
\ No newline at end of file
diff --git a/helpers/libshell/tests/ini_config_get b/helpers/libshell/tests/ini_config_get
new file mode 100644
index 0000000..7ccb269
--- /dev/null
+++ b/helpers/libshell/tests/ini_config_get
@@ -0,0 +1,22 @@
+#!/bin/ash -efu
+
+ini_config_get_test1() { # UnitTest
+	. ../shell-ini-config
+	local result expect="Foo Bar"
+	result="$(ini_config_get ini-config/z.ini global user)"
+	assertEquals "$result" "$result" "$expect"
+}
+
+ini_config_get_test2() { # UnitTest
+	. ../shell-ini-config
+	local result expect="foo at bar"
+	result="$(ini_config_get ini-config/z.ini global email)"
+	assertEquals "$result" "$result" "$expect"
+}
+
+ini_config_get_test3() { # UnitTest
+	. ../shell-ini-config
+	local result expect="\"ZZZ XXX\""
+	result="$(ini_config_get ini-config/z.ini sect opt)"
+	assertEquals "$result" "$result" "$expect"
+}
diff --git a/helpers/libshell/tests/ini_config_set b/helpers/libshell/tests/ini_config_set
new file mode 100644
index 0000000..bb46e35
--- /dev/null
+++ b/helpers/libshell/tests/ini_config_set
@@ -0,0 +1,58 @@
+#!/bin/ash -efu
+
+ini_config_set_test1() { # UnitTest
+	. ../shell-ini-config
+	local result expect="Aaa Bbb"
+	cp -f ini-config/z.ini ini-config/t1.ini
+
+	ini_config_set ini-config/t1.ini global user "$expect"
+
+	result="$(ini_config_get ini-config/t1.ini global user)"
+	assertEquals "$result" "$result" "$expect"
+}
+
+ini_config_set_test2() { # UnitTest
+	. ../shell-ini-config
+	local result expect='$1 \n\1 "Bbb"'
+	cp -f ini-config/z.ini ini-config/t2.ini
+
+	ini_config_set ini-config/t2.ini global user "$expect"
+
+	result="$(ini_config_get ini-config/t2.ini global user)"
+	assertEquals "$result" "$result" "$expect"
+}
+
+ini_config_set_test3() { # UnitTest
+	. ../shell-ini-config
+	local result expect='XXX'
+	cp -f ini-config/z.ini ini-config/t3.ini
+
+	ini_config_del ini-config/t3.ini global user
+	ini_config_set ini-config/t3.ini global user "$expect"
+
+	result="$(ini_config_get ini-config/t3.ini global user)"
+	assertEquals "$result" "$result" "$expect"
+}
+
+ini_config_set_test4() { # UnitTest
+	. ../shell-ini-config
+	local result expect='XXX'
+	cp -f ini-config/z.ini ini-config/t4.ini
+
+	ini_config_comment ini-config/t4.ini global user
+	ini_config_set ini-config/t4.ini global user "$expect"
+
+	result="$(ini_config_get ini-config/t4.ini global user)"
+	assertEquals "$result" "$result" "$expect"
+}
+
+ini_config_set_test5() { # UnitTest
+	. ../shell-ini-config
+	local result expect='ZZZ'
+	cp -f ini-config/z.ini ini-config/t5.ini
+
+	ini_config_set ini-config/t5.ini sect1 opt "$expect"
+
+	result="$(ini_config_get ini-config/t5.ini sect1 opt)"
+	assertEquals "$result" "$result" "$expect"
+}
diff --git a/helpers/libshell/tests/message b/helpers/libshell/tests/message
new file mode 100644
index 0000000..b4ae2c0
--- /dev/null
+++ b/helpers/libshell/tests/message
@@ -0,0 +1,33 @@
+#!/bin/ash -efu
+
+PROG='TEST'
+
+message_test1() { # UnitTest
+	. ../shell-error
+	expect="$PROG: message message;"
+	result=`message "message message" 2>&1 |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+message_test2() { # UnitTest
+	. ../shell-error
+	expect="$PROG: message;message;"
+	result=`message "message
+message" 2>&1 |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+message_test3() { # UnitTest
+	. ../shell-error
+	zzz=ZZZ
+	expect="$PROG: message ZZZ message;"
+	result=`message "message $zzz message" 2>&1 |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+message_test4() { # UnitTest
+	. ../shell-error
+	expect="$PROG: message message;another message;"
+	result=`{ message "message message" 2>&1; echo "another message"; } |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
diff --git a/helpers/libshell/tests/opt_check_dir b/helpers/libshell/tests/opt_check_dir
new file mode 100644
index 0000000..c2a20e6
--- /dev/null
+++ b/helpers/libshell/tests/opt_check_dir
@@ -0,0 +1,29 @@
+#!/bin/ash -efu
+
+opt_check_dir_test1() { # UnitTest
+	. ../shell-args
+
+	[ -d "$WORKDIR/dir-644" ] ||
+		mkdir -m644 "$WORKDIR/dir-644"
+	cd "$WORKDIR"
+
+	expect="$(message "DIR: ./dir-644: directory not available." 2>&1)"
+	result="$(opt_check_dir "DIR" "./dir-644" 2>&1)" ||:
+	rmdir "dir-644"
+
+	assertEquals "$result" "$result" "$expect"
+}
+
+opt_check_dir_test2() { # UnitTest
+	. ../shell-args
+
+	[ -d "$WORKDIR/dir-755" ] ||
+		mkdir -m755 "$WORKDIR/dir-755"
+	cd "$WORKDIR"
+
+	expect="$(readlink -ev ./dir-755 2>&1)" ||:
+	result="$(opt_check_dir "DIR" "./dir-755" 2>&1)" ||:
+	rmdir "dir-755"
+
+	assertEquals "$result" "$result" "$expect"
+}
diff --git a/helpers/libshell/tests/opt_check_number b/helpers/libshell/tests/opt_check_number
new file mode 100644
index 0000000..54d48d8
--- /dev/null
+++ b/helpers/libshell/tests/opt_check_number
@@ -0,0 +1,31 @@
+#!/bin/ash -efu
+
+opt_check_number_test1() { # UnitTest
+	. ../shell-args
+
+	string="1234"
+	expect="1234"
+	result="$(opt_check_number "NUM" "$string" 2>&1)" ||:
+
+	assertEquals "$result" "$result" "$expect"
+}
+
+opt_check_number_test2() { # UnitTest
+	. ../shell-args
+
+	string="0001"
+	expect="$(message "NUM: $string: invalid number." 2>&1)"
+	result="$(opt_check_number "NUM" "$string" 2>&1)" ||:
+
+	assertEquals "$result" "$result" "$expect"
+}
+
+opt_check_number_test3() { # UnitTest
+	. ../shell-args
+
+	string="1 2"
+	expect="$(message "NUM: $string: invalid number." 2>&1)"
+	result="$(opt_check_number "NUM" "$string" 2>&1)" ||:
+
+	assertEquals "$result" "$result" "$expect"
+}
diff --git a/helpers/libshell/tests/opt_check_read b/helpers/libshell/tests/opt_check_read
new file mode 100644
index 0000000..c1d5297
--- /dev/null
+++ b/helpers/libshell/tests/opt_check_read
@@ -0,0 +1,59 @@
+#!/bin/ash -efu
+
+opt_check_read_test1() { # UnitTest
+	. ../shell-args
+
+	if [ ! -f "$WORKDIR/file-000" ]; then
+		> "$WORKDIR/file-000"
+		chmod 000 "$WORKDIR/file-000"
+	fi
+	cd "$WORKDIR"
+
+	expect="$(message "FILE: ./file-000: file not available." 2>&1)"
+	result="$(opt_check_read "FILE" "./file-000" 2>&1)" ||:
+
+	assertEquals "$result" "$result" "$expect"
+}
+opt_check_read_test2() { # UnitTest
+	. ../shell-args
+
+	if [ ! -f "$WORKDIR/file-200" ]; then
+		> "$WORKDIR/file-200"
+		chmod 200 "$WORKDIR/file-200"
+	fi
+	cd "$WORKDIR"
+
+	expect="$(message "FILE: ./file-200: file not available." 2>&1)"
+	result="$(opt_check_read "FILE" "./file-200" 2>&1)" ||:
+
+	assertEquals "$result" "$result" "$expect"
+}
+
+opt_check_read_test3() { # UnitTest
+	. ../shell-args
+
+	if [ ! -f "$WORKDIR/file-644" ]; then
+		> "$WORKDIR/file-644"
+		chmod 644 "$WORKDIR/file-644"
+	fi
+	cd "$WORKDIR"
+
+	expect="$(readlink -ev ./file-644)"
+	result="$(opt_check_read "FILE" "./file-644" 2>&1)" ||:
+
+	assertEquals "$result" "$result" "$expect"
+}
+
+opt_check_read_test4() { # UnitTest
+	. ../shell-args
+
+	if [ ! -e "$WORKDIR/broken-symlink" ]; then
+		ln -s "$WORKDIR/broken-symlink" "$WORKDIR/broken-symlink"
+	fi
+	cd "$WORKDIR"
+
+	expect="$(message "FILE: ./broken-symlink: file not available." 2>&1)"
+	result="$(opt_check_read "FILE" "./broken-symlink" 2>&1)" ||:
+
+	assertEquals "$result" "$result" "$expect"
+}
diff --git a/helpers/libshell/tests/quote_sed_regexp b/helpers/libshell/tests/quote_sed_regexp
new file mode 100644
index 0000000..19e42b2
--- /dev/null
+++ b/helpers/libshell/tests/quote_sed_regexp
@@ -0,0 +1,33 @@
+#!/bin/ash -efu
+
+quote_sed_regexp_test1() { # UnitTest
+	. ../shell-quote
+	local string='.*'
+	local regexp="$(quote_sed_regexp "$string")"
+	local result="$(printf '%s\n' "$string passed" |sed -e "s/^$regexp/test/")"
+	assertEquals "$string" "$result" 'test passed'
+}
+
+quote_sed_regexp_test2() { # UnitTest
+	. ../shell-quote
+	local string='[[:space:]]'
+	local regexp="$(quote_sed_regexp "$string")"
+	local result="$(printf '%s\n' "test $string" |sed -e "s/$regexp/passed/")"
+	assertEquals "$string" "$result" 'test passed'
+}
+
+quote_sed_regexp_test3() { # UnitTest
+	. ../shell-quote
+	local string='t{1,3}'
+	local regexp="$(quote_sed_regexp "$string")"
+	local result="$(printf '%s\n' "test$string passed" |sed -e "s/$regexp//")"
+	assertEquals "$string" "$result" 'test passed'
+}
+
+quote_sed_regexp_test4() { # UnitTest
+	. ../shell-quote
+	local string='&\1'
+	local regexp="$(quote_sed_regexp "$string")"
+	local result="$(printf '%s\n' "test not passed" |sed -e "s/\(not\)/$regexp/")" #"
+	assertEquals "$string" "$result" 'test &\1 passed'
+}
diff --git a/helpers/libshell/tests/quote_sed_regexp_variable b/helpers/libshell/tests/quote_sed_regexp_variable
new file mode 100644
index 0000000..6d227c6
--- /dev/null
+++ b/helpers/libshell/tests/quote_sed_regexp_variable
@@ -0,0 +1,37 @@
+#!/bin/ash -efu
+
+quote_sed_regexp_variable_test1() { # UnitTest
+	. ../shell-quote
+	local string='.*'
+	local regexp
+	quote_sed_regexp_variable regexp "$string"
+	local result="$(printf '%s\n' "$string passed" |sed -e "s/^$regexp/test/")"
+	assertEquals "$string" "$result" 'test passed'
+}
+
+quote_sed_regexp_variable_test2() { # UnitTest
+	. ../shell-quote
+	local string='[[:space:]]'
+	local regexp
+	quote_sed_regexp_variable regexp "$string"
+	local result="$(printf '%s\n' "test $string" |sed -e "s/$regexp/passed/")"
+	assertEquals "$string" "$result" 'test passed'
+}
+
+quote_sed_regexp_variable_test3() { # UnitTest
+	. ../shell-quote
+	local string='t{1,3}'
+	local regexp
+	quote_sed_regexp_variable regexp "$string"
+	local result="$(printf '%s\n' "test$string passed" |sed -e "s/$regexp//")"
+	assertEquals "$string" "$result" 'test passed'
+}
+
+quote_sed_regexp_variable_test4() { # UnitTest
+	. ../shell-quote
+	local string='&\1'
+	local regexp
+	quote_sed_regexp_variable regexp "$string"
+	local result="$(printf '%s\n' "test not passed" |sed -e "s/\(not\)/$regexp/")" #"
+	assertEquals "$string" "$result" 'test &\1 passed'
+}
diff --git a/helpers/libshell/tests/quote_shell b/helpers/libshell/tests/quote_shell
new file mode 100644
index 0000000..2a81947
--- /dev/null
+++ b/helpers/libshell/tests/quote_shell
@@ -0,0 +1,25 @@
+#!/bin/ash -efu
+
+quote_shell_test1() { # UnitTest
+	. ../shell-quote
+	local string='`true`'
+	local result
+	eval "result=\"$(quote_shell "$string")\""
+	assertEquals "$string" "$result" "$string"
+}
+
+quote_shell_test2() { # UnitTest
+	. ../shell-quote
+	local string='$(true)'
+	local result
+	eval "result=\"$(quote_shell "$string")\""
+	assertEquals "$string" "$result" "$string"
+}
+
+quote_shell_test3() { # UnitTest
+	. ../shell-quote
+	local string='\`true\`; echo zzz'
+	local result
+	eval "result=\"$(quote_shell "$string")\""
+	assertEquals "$string" "$result" "$string"
+}
diff --git a/helpers/libshell/tests/quote_shell_args b/helpers/libshell/tests/quote_shell_args
new file mode 100644
index 0000000..ca0cead
--- /dev/null
+++ b/helpers/libshell/tests/quote_shell_args
@@ -0,0 +1,379 @@
+#!/bin/ash -efu
+
+PROG='TEST'
+
+quote_process() {
+	local opts=
+        quote_shell_args opts "$1" &&
+                eval "set -- $opts" ||:
+
+        local a= result=
+        for a; do
+                result="$result[$a] "
+        done
+        printf '%s\n' "${result% }"
+}
+
+quote_shell_args_test_000() { # UnitTest
+	local num=000
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_001() { # UnitTest
+	local num=001
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_002() { # UnitTest
+	local num=002
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_003() { # UnitTest
+	local num=003
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_004() { # UnitTest
+	local num=001
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_005() { # UnitTest
+	local num=005
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_006() { # UnitTest
+	local num=006
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_007() { # UnitTest
+	local num=007
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_008() { # UnitTest
+	local num=008
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_009() { # UnitTest
+	local num=009
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_010() { # UnitTest
+	local num=010
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_011() { # UnitTest
+	local num=011
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_012() { # UnitTest
+	local num=012
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_013() { # UnitTest
+	local num=013
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_014() { # UnitTest
+	local num=014
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_015() { # UnitTest
+	local num=015
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_016() { # UnitTest
+	local num=016
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_017() { # UnitTest
+	local num=017
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_018() { # UnitTest
+	local num=018
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_019() { # UnitTest
+	local num=019
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_020() { # UnitTest
+	local num=020
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1 |tr '\n' ' ')"
+
+	assertEquals "$result" 'TEST: unmatched character (\) found [a\] ' "$result"
+}
+
+quote_shell_args_test_021() { # UnitTest
+	local num=021
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1 |tr '\n' ' ')"
+
+	assertEquals "$result" 'TEST: unmatched character (") found [1"22"333"4444] ' "$result"
+}
+
+quote_shell_args_test_022() { # UnitTest
+	local num=022
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1 |tr '\n' ' ')"
+
+	assertEquals "$result" "TEST: unmatched character (') found [1'22'333'4444] " "$result"
+}
+
+quote_shell_args_test_023() { # UnitTest
+	local num=023
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1 |tr '\n' ' ')"
+
+	assertEquals "$result" 'TEST: unmatched character (\") found ["\] ' "$result"
+}
+
+quote_shell_args_test_024() { # UnitTest
+	local num=024
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_025() { # UnitTest
+	local num=025
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_026() { # UnitTest
+	local num=026
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
+
+quote_shell_args_test_027() { # UnitTest
+	local num=027
+
+	. ../shell-error
+	. ../shell-quote
+
+	local input="$(cat ./data/$num-quote_shell_args-pattern)"
+	local expect="$(cat ./data/$num-quote_shell_args-result)"
+	local result="$(quote_process "$input" 2>&1)"
+
+	assertEquals "$result" "$expect" "$result"
+}
diff --git a/helpers/libshell/tests/quote_shell_variable b/helpers/libshell/tests/quote_shell_variable
new file mode 100644
index 0000000..90008a5
--- /dev/null
+++ b/helpers/libshell/tests/quote_shell_variable
@@ -0,0 +1,25 @@
+#!/bin/ash -efu
+
+quote_shell_variable_test1() { # UnitTest
+	. ../shell-quote
+	local string='`true`' expect='\`true\`'
+	local result
+	quote_shell_variable result "$string"
+	assertEquals "$string" "$result" "$expect"
+}
+
+quote_shell_variable_test2() { # UnitTest
+	. ../shell-quote
+	local string='$(true)' expect='\$(true)'
+	local result
+	quote_shell_variable result "$string"
+	assertEquals "$string" "$result" "$expect"
+}
+
+quote_shell_variable_test3() { # UnitTest
+	. ../shell-quote
+	local string='\`true\`; echo zzz' expect='\\\`true\\\`; echo zzz'
+	local result
+	quote_shell_variable result "$string"
+	assertEquals "$string" "$result" "$expect"
+}
diff --git a/helpers/libshell/tests/runtests b/helpers/libshell/tests/runtests
new file mode 100755
index 0000000..cc5e073
--- /dev/null
+++ b/helpers/libshell/tests/runtests
@@ -0,0 +1,34 @@
+#!/bin/sh -efu
+
+srcdir="$(readlink -ev ..)"
+export PATH="$srcdir:$PATH"
+
+. ../shell-unittest
+
+WORKDIR=
+setUpTests() {
+	WORKDIR="$(mktemp -d "$PROG.XXXXXXXXX")"
+}
+
+tearDownTests() {
+	rm -rf -- "$WORKDIR"
+}
+
+for s in \
+	quote_sed_regexp quote_shell string_quote_remove \
+	opt_check_dir opt_check_number opt_check_read \
+	quote_sed_regexp_variable quote_shell_variable \
+	getopt signal \
+	fatal message verbose \
+	quote_shell_args \
+	ini_config_get ini_config_set \
+	shell_var_unquote shell_var_trim \
+	fill_mask \
+	cmdline_get \
+	;
+do
+	. "./$s"
+	registerTests "./$s"
+done
+
+runUnitTests
diff --git a/helpers/libshell/tests/shell_var_trim b/helpers/libshell/tests/shell_var_trim
new file mode 100644
index 0000000..5786521
--- /dev/null
+++ b/helpers/libshell/tests/shell_var_trim
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+shell_var_trim_test1() { # UnitTest
+	. ../shell-var
+
+	local result string='test'
+	shell_var_trim result "$string"
+	assertEquals "$string" "$result" 'test'
+}
+
+shell_var_trim_test2() { # UnitTest
+	. ../shell-var
+
+	local result string='test   '
+	shell_var_trim result "$string"
+	assertEquals "$string" "$result" 'test'
+}
+
+shell_var_trim_test3() { # UnitTest
+	. ../shell-var
+
+	local result string='test	
+        '
+	shell_var_trim result "$string"
+	assertEquals "$string" "$result" 'test'
+}
+
+shell_var_trim_test4() { # UnitTest
+	. ../shell-var
+
+	local result string='	   test 	 test	
+        '
+	shell_var_trim result "$string"
+	assertEquals "$string" "$result" 'test 	 test'
+}
+
+shell_var_trim_test5() { # UnitTest
+	. ../shell-var
+
+	local result string=' " test " '
+	shell_var_trim result "$string"
+	assertEquals "$string" "$result" '" test "'
+}
diff --git a/helpers/libshell/tests/shell_var_unquote b/helpers/libshell/tests/shell_var_unquote
new file mode 100644
index 0000000..627e999
--- /dev/null
+++ b/helpers/libshell/tests/shell_var_unquote
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+shell_var_unquote_test1() { # UnitTest
+	. ../shell-var
+
+	local result string='"test passed"'
+	shell_var_unquote result "$string"
+	assertEquals "$string" "$result" 'test passed'
+}
+
+shell_var_unquote_test2() { # UnitTest
+	. ../shell-var
+
+	local result string="'test passed'"
+	shell_var_unquote result "$string"
+	assertEquals "$string" "$result" 'test passed'
+}
+
+shell_var_unquote_test3() { # UnitTest
+	. ../shell-var
+
+	local result string="'test passed\""
+	shell_var_unquote result "$string"
+	assertEquals "$string" "$result" "'test passed\""
+}
+
+shell_var_unquote_test4() { # UnitTest
+	. ../shell-var
+
+	local result string="test ' passed"
+	shell_var_unquote result "$string"
+	assertEquals "$string" "$result" "test ' passed"
+}
diff --git a/helpers/libshell/tests/signal b/helpers/libshell/tests/signal
new file mode 100644
index 0000000..ef61cf7
--- /dev/null
+++ b/helpers/libshell/tests/signal
@@ -0,0 +1,52 @@
+#!/bin/ash -efu
+
+PROG='TEST'
+__libshell_experimental=1
+
+signal_test_handler() {
+	printf '%s\n' "$PROG: signal_test_handler() called"
+}
+
+signal_test1() { # UnitTest
+	expect="EXIT-0"
+	result=$(./signal-data/001-signal)
+	assertEquals "$result" "$result" "$expect"
+}
+
+signal_test2() { # UnitTest
+	expect="INT-2"
+	result=$(./signal-data/002-signal)
+	assertEquals "$result" "$result" "$expect"
+}
+
+signal_test3() { # UnitTest
+	expect="EXIT-0
+EXIT-0"
+	result=$(./signal-data/003-signal)
+	assertEquals "$result" "$result" "$expect"
+}
+
+signal_test4() { # UnitTest
+	expect="BAR1
+BAR2"
+	result=$(./signal-data/004-signal)
+	assertEquals "$result" "$result" "$expect"
+}
+
+signal_test5() { # UnitTest
+	expect="EXIT-5"
+	result=$(./signal-data/005-signal) ||:
+	assertEquals "$result" "$result" "$expect"
+}
+
+signal_test6() { # UnitTest
+	expect="Got 5"
+	result=$(./signal-data/006-signal) ||:
+	assertEquals "$result" "$result" "$expect"
+}
+
+signal_test7() { # UnitTest
+	expect=""
+	result=$(./signal-data/007-signal) ||:
+	assertEquals "$result" "$result" "$expect"
+}
diff --git a/helpers/libshell/tests/signal-data/001-signal b/helpers/libshell/tests/signal-data/001-signal
new file mode 100755
index 0000000..b5c12ef
--- /dev/null
+++ b/helpers/libshell/tests/signal-data/001-signal
@@ -0,0 +1,3 @@
+#!/bin/sh -efu
+. ../shell-signal
+signal_handler 'echo EXIT-$?' EXIT HUP;
diff --git a/helpers/libshell/tests/signal-data/002-signal b/helpers/libshell/tests/signal-data/002-signal
new file mode 100755
index 0000000..028e72e
--- /dev/null
+++ b/helpers/libshell/tests/signal-data/002-signal
@@ -0,0 +1,4 @@
+#!/bin/sh -efu
+. ../shell-signal
+signal_handler 'echo INT-2' INT
+/bin/kill -INT $$
diff --git a/helpers/libshell/tests/signal-data/003-signal b/helpers/libshell/tests/signal-data/003-signal
new file mode 100755
index 0000000..4331db1
--- /dev/null
+++ b/helpers/libshell/tests/signal-data/003-signal
@@ -0,0 +1,4 @@
+#!/bin/sh -efu
+. ../shell-signal
+signal_handler 'echo EXIT-$?' TERM EXIT HUP;
+signal_handler 'echo EXIT-$?' TERM EXIT HUP;
diff --git a/helpers/libshell/tests/signal-data/004-signal b/helpers/libshell/tests/signal-data/004-signal
new file mode 100755
index 0000000..346dd30
--- /dev/null
+++ b/helpers/libshell/tests/signal-data/004-signal
@@ -0,0 +1,9 @@
+#!/bin/sh -efu
+. ../shell-signal
+signal_handler 'echo FOO1' USR2;
+signal_handler 'echo FOO2' USR2;
+signal_handler 'echo BAR1' USR1;
+signal_handler 'echo BAR2' USR1;
+signal_handler 'echo BAZ1' TERM;
+signal_handler 'echo BAZ2' TERM;
+/bin/kill -USR1 $$
diff --git a/helpers/libshell/tests/signal-data/005-signal b/helpers/libshell/tests/signal-data/005-signal
new file mode 100755
index 0000000..39cc7f4
--- /dev/null
+++ b/helpers/libshell/tests/signal-data/005-signal
@@ -0,0 +1,4 @@
+#!/bin/sh -efu
+. ../shell-signal
+signal_handler 'echo EXIT-$?' EXIT;
+exit 5
diff --git a/helpers/libshell/tests/signal-data/006-signal b/helpers/libshell/tests/signal-data/006-signal
new file mode 100755
index 0000000..5c0f94f
--- /dev/null
+++ b/helpers/libshell/tests/signal-data/006-signal
@@ -0,0 +1,10 @@
+#!/bin/sh -efu
+. ../shell-signal
+
+myhand() {
+	echo "Got $1"
+}
+
+set_cleanup_handler myhand;
+exit 5
+
diff --git a/helpers/libshell/tests/signal-data/007-signal b/helpers/libshell/tests/signal-data/007-signal
new file mode 100755
index 0000000..21b8a8d
--- /dev/null
+++ b/helpers/libshell/tests/signal-data/007-signal
@@ -0,0 +1,11 @@
+#!/bin/sh -efu
+. ../shell-signal
+
+myhand() {
+	echo "Got $1"
+}
+
+set_cleanup_handler myhand;
+unset_cleanup_handler;
+exit 5
+
diff --git a/helpers/libshell/tests/string_quote_remove b/helpers/libshell/tests/string_quote_remove
new file mode 100644
index 0000000..6025be2
--- /dev/null
+++ b/helpers/libshell/tests/string_quote_remove
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+string_quote_remove_test1() { # UnitTest
+	. ../shell-quote
+
+	local string='"test passed"'
+	local result="$(string_quote_remove "$string")"
+	assertEquals "$string" "$result" 'test passed'
+}
+
+string_quote_remove_test2() { # UnitTest
+	. ../shell-quote
+
+	local string="'test passed'"
+	local result="$(string_quote_remove "$string")"
+	assertEquals "$string" "$result" 'test passed'
+}
+
+string_quote_remove_test3() { # UnitTest
+	. ../shell-quote
+
+	local string="'test passed\""
+	local result="$(string_quote_remove "$string")"
+	assertEquals "$string" "$result" "'test passed\""
+}
+
+string_quote_remove_test4() { # UnitTest
+	. ../shell-quote
+
+	local string="test ' passed"
+	local result="$(string_quote_remove "$string")"
+	assertEquals "$string" "$result" "test ' passed"
+}
diff --git a/helpers/libshell/tests/verbose b/helpers/libshell/tests/verbose
new file mode 100644
index 0000000..af8cee3
--- /dev/null
+++ b/helpers/libshell/tests/verbose
@@ -0,0 +1,19 @@
+#!/bin/ash -efu
+
+PROG='TEST'
+
+verbose_test1() { # UnitTest
+	. ../shell-error
+	verbose=1
+	expect="$PROG: message message;"
+	result=`verbose "message message" 2>&1 |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
+
+verbose_test2() { # UnitTest
+	. ../shell-error
+	verbose=
+	expect=
+	result=`verbose "message message" 2>&1 |tr '\n' ';'`
+	assertEquals "$result" "$result" "$expect"
+}
diff --git a/helpers/remap-log.c b/helpers/remap-log.c
new file mode 100644
index 0000000..518e003
--- /dev/null
+++ b/helpers/remap-log.c
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 2006, Al Viro.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+char *prefix1 = "a/", *prefix2 = "b/";
+char *old_prefix = "O:";
+char *user_pattern;
+
+char *line;
+
+void die(char *s)
+{
+	fprintf(stderr, "remap: %s\n", s);
+	exit(1);
+}
+
+void Enomem(void)
+{
+	die("out of memory");
+}
+
+void Eio(void)
+{
+	die("IO error");
+}
+
+enum {SIZE = 4096};
+
+char *buffer;
+int get_line(int fd)
+{
+	static char *end, *end_buffer, *next;
+	static size_t size;
+	ssize_t count;
+
+	if (!buffer) {
+		next = end = buffer = malloc(size = SIZE);
+		if (!buffer)
+			Enomem();
+		end_buffer = buffer + SIZE;
+	}
+	line = next;
+
+	while (1) {
+		if (next < end) {
+			next = memchr(next, '\n', end - next);
+			if (next) {
+				*next++ = '\0';
+				return 1;
+			}
+		}
+		if (end == end_buffer) {
+			size_t n = line - buffer;
+			if (n >= SIZE) {
+				n -= n % SIZE;
+				memmove(line - n, line, end - line);
+				line -= n;
+				end -= n;
+			} else {
+				char *p = malloc(size *= 2);
+				if (!p)
+					Enomem();
+				memcpy(p + n, line, end - line);
+				line = p + n;
+				end = p + (end - buffer);
+				free(buffer);
+				buffer = p;
+				end_buffer = p + size;
+			}
+		}
+		next = end;
+		count = read(fd, end, end_buffer - end);
+		if (!count)
+			break;
+		if (count < 0)
+			Eio();
+		end += count;
+	}
+
+	*end = '\0';
+	return line != end;
+}
+
+/* to == 0 -> deletion */
+struct range_map {
+	int from, to;
+};
+
+struct file_map {
+	char *name;
+	size_t name_len;
+	struct file_map *next;
+	char *new_name;
+	int count;
+	int allocated;
+	int last;
+	struct range_map ranges[];
+};
+
+struct file_map *alloc_map(char *name)
+{
+	struct file_map *map;
+
+	map = malloc(sizeof(struct file_map) + 16 * sizeof(struct range_map));
+	if (!map)
+		Enomem();
+	map->name_len = strlen(name);
+	map->name = map->new_name = malloc(map->name_len + 1);
+	if (!map->name)
+		Enomem();
+	memcpy(map->name, name, map->name_len + 1);
+	map->count = 0;
+	map->allocated = 16;
+	map->next = NULL;
+	map->last = 0;
+	return map;
+}
+
+/* this is 32bit FNV1 */
+uint32_t FNV_hash(char *name, size_t len)
+{
+	uint32_t n = 0x811c9dc5;
+	while (len--) {
+		unsigned char c = *name++;
+		n *= 0x01000193;
+		n ^= c;
+	}
+	return n;
+}
+
+struct file_map *hash[1024];
+
+int hash_map(struct file_map *map)
+{
+	size_t len = map->name_len;
+	char *name = map->name;
+	int n = FNV_hash(name, len) % 1024;
+	struct file_map **p = &hash[n];
+
+	while (*p) {
+		if ((*p)->name_len == len && !memcmp((*p)->name, name, len))
+			return 0;
+		p = &(*p)->next;
+	}
+	*p = map;
+	if (map->new_name && !map->count)
+		return 0;
+	if (map->new_name && map->ranges[0].from != 1)
+		return 0;
+	return 1;
+}
+
+struct file_map *find_map(char *name, size_t len)
+{
+	static struct file_map *last = NULL;
+	int n = FNV_hash(name, len) % 1024;
+	struct file_map *p;
+
+	if (last && last->name_len == len && !memcmp(last->name, name, len))
+		return last;
+
+	for (p = hash[n]; p; p = p->next)
+		if (p->name_len == len && !memcmp(p->name, name, len))
+			break;
+	if (p)
+		last = p;
+	return p;
+}
+
+void parse_map(char *name)
+{
+	struct file_map *map = NULL;
+	struct range_map *range;
+	char *s;
+	int fd;
+
+	fd = open(name, O_RDONLY);
+	if (fd < 0)
+		die("can't open map");
+	while (get_line(fd)) {
+		if (line[0] == 'D') {
+			if (map && !hash_map(map))
+				goto Ebadmap;
+			if (line[1] != ' ')
+				goto Ebadmap;
+			if (strchr(line + 2, ' '))
+				goto Ebadmap;
+			map = alloc_map(line + 2);
+			map->new_name = NULL;
+			continue;
+		}
+		if (line[0] == 'M') {
+			if (map && !hash_map(map))
+				goto Ebadmap;
+			if (line[1] != ' ')
+				goto Ebadmap;
+			s = strchr(line + 2, ' ');
+			if (!s)
+				goto Ebadmap;
+			*s++ = '\0';
+			if (strchr(s, ' '))
+				goto Ebadmap;
+			map = alloc_map(line + 2);
+			if (strcmp(line + 2, s)) {
+				map->new_name = strdup(s);
+				if (!map->new_name)
+					Enomem();
+			}
+			continue;
+		}
+		if (!map || !map->new_name)
+			goto Ebadmap;
+		if (map->count == map->allocated) {
+			int n = 2 * map->allocated;
+			map = realloc(map, sizeof(struct file_map) +
+					   n * sizeof(struct range_map));
+			if (!map)
+				Enomem();
+			map->allocated = n;
+		}
+		range = &map->ranges[map->count++];
+		if (sscanf(line, "%d %d%*c", &range->from, &range->to) != 2)
+			goto Ebadmap;
+		if (range > map->ranges && range->from <= range[-1].from)
+			goto Ebadmap;
+	}
+	if (map && !hash_map(map))
+		goto Ebadmap;
+	close(fd);
+	return;
+Ebadmap:
+	die("bad map");
+}
+
+struct range_map *find_range(struct file_map *map, int l)
+{
+	struct range_map *range = &map->ranges[map->last];
+	struct range_map *p;
+
+	if (range->from <= l) {
+		p = &map->ranges[map->count - 1];
+		if (p->from > l) {
+			for (p = range; p->from <= l; p++)
+				;
+			p--;
+		}
+	} else {
+		for (p = map->ranges; p->from <= l; p++)
+			;
+		p--;
+	}
+	map->last = p - map->ranges;
+	return p;
+}
+
+char *strnstr(char *haystack, char *needle, ssize_t len)
+{
+	ssize_t nl = strlen(needle), i;
+
+	for (i = 0; i <= len - nl; i++) {
+		if (!memcmp(haystack + i, needle, nl))
+			return haystack + i;
+	}
+
+	return NULL;
+}
+
+void map_pattern(char *patt, char *start, char *end, struct file_map *map)
+{
+	size_t plen = strlen(patt);
+
+	while (end > start) {
+		struct range_map *range;
+		unsigned long l;
+		char *s, *more;
+
+		s = strnstr(start, patt, end - start);
+		if (!s)
+			break;
+
+		s += plen;
+		printf("%.*s", (int)(s - start), start);
+		start = s;
+
+		l = strtoul(s, &more, 10);
+		if (more == s || !l || l > INT_MAX)
+			continue;
+
+		if (map->new_name && (range = find_range(map, l))->to)
+			l += range->to - range->from;
+
+		printf("%lu", l);
+		start = s = more;
+	}
+
+	printf("%.*s", (int)(end - start), start);
+}
+
+void mapline(char *patt)
+{
+	char *s = line, *start = line, *end = line - 1, *sp = line - 1;
+	struct file_map *last_mapped = NULL;
+
+	while (1) {
+		struct file_map *map;
+		struct range_map *range;
+		unsigned long l;
+		char *more;
+
+		end = strchr(end + 1, ':');
+		if (!end)
+			break;
+
+		if (sp < s)
+			sp = strchr(s, ' ');
+
+		while (sp && sp < end) {
+			s = sp + 1;
+			sp = strchr(s , ' ');
+		}
+
+		l = strtoul(end + 1, &more, 10);
+		if (more == end + 1 || !l || l > INT_MAX)
+			continue;
+
+		map = find_map(s, end - s);
+		if (!map)
+			continue;
+
+		if (patt)
+			map_pattern(patt, start, s, map);
+
+		if (map->new_name && (range = find_range(map, l))->to) {
+			l += range->to - range->from;
+			printf("%s:%lu", map->new_name, l);
+		} else {
+			printf("%s%.*s", old_prefix, (int)(more - s), s);
+		}
+		start = s = more;
+		last_mapped = map;
+	}
+
+	if (patt && start != line)
+		map_pattern(patt, start, start + strlen(start), last_mapped);
+	else
+		printf("%s", start);
+
+	printf("\n");
+}
+
+int parse_hunk(int *l1, int *l2, int *n1, int *n2)
+{
+	unsigned long n;
+	char *s, *p;
+	if (line[3] != '-')
+		return 0;
+	n = strtoul(line + 4, &s, 10);
+	if (s == line + 4 || n > INT_MAX)
+		return 0;
+	*l1 = n;
+	if (*s == ',') {
+		n = strtoul(s + 1, &p, 10);
+		if (p == s + 1 || n > INT_MAX)
+			return 0;
+		*n1 = n;
+		if (!n)
+			(*l1)++;
+	} else {
+		p = s;
+		*n1 = 1;
+	}
+	if (*p != ' ' || p[1] != '+')
+		return 0;
+	n = strtoul(p + 2, &s, 10);
+	if (s == p + 2 || n > INT_MAX)
+		return 0;
+	*l2 = n;
+	if (*s == ',') {
+		n = strtoul(s + 1, &p, 10);
+		if (p == s + 1 || n > INT_MAX)
+			return 0;
+		*n2 = n;
+		if (!n)
+			(*l2)++;
+	} else {
+		p = s;
+		*n2 = 1;
+	}
+	return 1;
+}
+
+void parse_diff(void)
+{
+	int skipping = -1, suppress = 1;
+	char *name1 = NULL, *name2 = NULL;
+	int from = 1, to = 1;
+	int l1, l2, n1, n2;
+	enum cmd {
+		Diff, Hunk, New, Del, Copy, Rename, Junk
+	} cmd;
+	static struct { const char *s; size_t len; } pref[] = {
+		[Hunk] = {"@@ ", 3},
+		[Diff] = {"diff ", 5},
+		[New] = {"new file ", 9},
+		[Del] = {"deleted file ", 12},
+		[Copy] = {"copy from ", 10},
+		[Rename] = {"rename from ", 11},
+		[Junk] = {"", 0},
+	};
+	size_t len1 = strlen(prefix1), len2 = strlen(prefix2);
+
+	while (get_line(0)) {
+		if (skipping > 0) {
+			switch (line[0]) {
+			case '+':
+			case '-':
+			case '\\':
+				continue;
+			}
+		}
+		for (cmd = 0; strncmp(line, pref[cmd].s, pref[cmd].len); cmd++)
+			;
+		switch (cmd) {
+		case Hunk:
+			if (skipping < 0)
+				goto Ediff;
+			if (!suppress) {
+				if (!skipping)
+					printf("M %s %s\n", name1, name2);
+				if (!parse_hunk(&l1, &l2, &n1, &n2))
+					goto Ediff;
+				if (l1 > from)
+					printf("%d %d\n", from, to);
+				if (n1)
+					printf("%d 0\n", l1);
+				from = l1 + n1;
+				to = l2 + n2;
+			}
+			skipping = 1;
+			break;
+		case Diff:
+			if (!suppress) {
+				if (!skipping)
+					printf("M %s %s\n", name1, name2);
+				printf("%d %d\n", from, to);
+			}
+			free(name1);
+			free(name2);
+			name2 = strrchr(line, ' ');
+			if (!name2)
+				goto Ediff;
+			*name2 = '\0';
+			name1 = strrchr(line, ' ');
+			if (!name1)
+				goto Ediff;
+			if (strncmp(name1 + 1, prefix1, len1))
+				goto Ediff;
+			if (strncmp(name2 + 1, prefix2, len2))
+				goto Ediff;
+			name1 = strdup(name1 + len1 + 1);
+			name2 = strdup(name2 + len2 + 1);
+			if (!name1 || !name2)
+				goto Ediff;
+			skipping = 0;
+			suppress = 0;
+			from = to = 1;
+			break;
+		case New:
+			if (skipping)
+				goto Ediff;
+			suppress = 1;
+			break;
+		case Del:
+		case Copy:
+			if (skipping)
+				goto Ediff;
+			printf("D %s\n", name2);
+			suppress = 1;
+			break;
+		case Rename:
+			if (skipping)
+				goto Ediff;
+			printf("D %s\n", name2);
+			break;
+		default:
+			break;
+		}
+	}
+	if (!suppress) {
+		if (!skipping)
+			printf("M %s %s\n", name1, name2);
+		printf("%d %d\n", from, to);
+	}
+	return;
+Ediff:
+	die("odd diff");
+}
+
+int main(int argc, char **argv)
+{
+	char *map_name = NULL;
+	char opt;
+	char *arg;
+	size_t len;
+	for (argc--, argv++; argc; argc--, argv++) {
+		if (argv[0][0] != '-') {
+			map_name = argv[0];
+			continue;
+		}
+		opt = argv[0][1];
+		if (!opt)
+			goto Eargs;
+		arg = argv[0] + 2;
+		if (!*arg) {
+			if (!--argc)
+				goto Eargs;
+			arg = *++argv;
+		}
+		len = strlen(arg);
+		switch (opt) {
+		case 'O':
+			prefix1 = malloc(len + 2);
+			if (!prefix1)
+				Enomem();
+			memcpy(prefix1, arg, len);
+			prefix1[len] = '/';
+			prefix1[len + 1] = '\0';
+			break;
+		case 'N':
+			prefix2 = malloc(len + 2);
+			if (!prefix2)
+				Enomem();
+			memcpy(prefix2, arg, len);
+			prefix2[len] = '/';
+			prefix2[len + 1] = '\0';
+			break;
+		case 'o':
+			old_prefix = arg;
+			break;
+		case 'p':
+			user_pattern = arg;
+			break;
+		default:
+		Eargs:
+			die("bad arguments");
+		}
+	}
+
+	if (!map_name) {
+		parse_diff();
+	} else {
+		parse_map(map_name);
+		buffer = NULL;
+		while (get_line(0))
+			mapline(user_pattern);
+	}
+	return 0;
+
+}
diff --git a/packaging/aiaiai.spec b/packaging/aiaiai.spec
index aa5e7a7..45026c7 100644
--- a/packaging/aiaiai.spec
+++ b/packaging/aiaiai.spec
@@ -52,13 +52,13 @@ rm -rf %{buildroot}/usr/bin/packaging
 rm -rf %{buildroot}/usr/bin/doc
 rm %{buildroot}/usr/bin/*.c
 rm %{buildroot}/usr/bin/Makefile
-rm %{buildroot}/usr/bin/external/*.c
-rm %{buildroot}/usr/bin/external/Makefile
+rm %{buildroot}/usr/bin/helpers/*.c
+rm %{buildroot}/usr/bin/helpers/Makefile
 
 %files
 %defattr(-,root,root,-)
 %{_bindir}/aiaiai*
-%{_bindir}/external
+%{_bindir}/helpers
 
 %files email
 %defattr(-,root,root,-)
diff --git a/tests/test-subj-parsing b/tests/test-subj-parsing
index a5d3f64..19cd5b4 100755
--- a/tests/test-subj-parsing
+++ b/tests/test-subj-parsing
@@ -8,7 +8,7 @@
 # it to the mscripts directory and run.
 
 srcdir="$(readlink -ev -- ${0%/*})"
-PATH="$srcdir/..:$srcdir/../external/libshell:$PATH"
+PATH="$srcdir/..:$srcdir/../helpers/libshell:$PATH"
 
 . shell-error
 . email/aiaiai-email-sh-functions
-- 
1.8.5.2




More information about the aiaiai mailing list