summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Makemodule.am56
-rwxr-xr-xtools/checkadoc-missing.sh89
-rwxr-xr-xtools/checkadoc-repeat.sh80
-rwxr-xr-xtools/checkcompletion.sh45
-rwxr-xr-xtools/checkconfig.sh64
-rwxr-xr-xtools/checkdecl.sh21
-rwxr-xr-xtools/checkincludes.pl24
-rwxr-xr-xtools/checklibdocs.sh43
-rwxr-xr-xtools/checkusage.sh159
-rwxr-xr-xtools/checkxalloc.sh23
-rwxr-xr-xtools/compare-buildsys.sh35
-rwxr-xr-xtools/config-gen57
-rw-r--r--tools/config-gen-functions.sh33
-rw-r--r--tools/config-gen.d/all-non-nls.conf2
-rw-r--r--tools/config-gen.d/all.conf5
-rw-r--r--tools/config-gen.d/audit.conf3
-rw-r--r--tools/config-gen.d/chfnsh-libuser.conf5
-rw-r--r--tools/config-gen.d/chfnsh-no-password.conf6
-rw-r--r--tools/config-gen.d/chfnsh-pam.conf6
-rw-r--r--tools/config-gen.d/core.conf2
-rw-r--r--tools/config-gen.d/cryptsetup.conf3
-rw-r--r--tools/config-gen.d/devel-non-asan.conf7
-rw-r--r--tools/config-gen.d/devel-non-docs.conf6
-rw-r--r--tools/config-gen.d/devel.conf8
-rw-r--r--tools/config-gen.d/disable-all.conf1
-rw-r--r--tools/config-gen.d/enable-schedutils.conf3
-rw-r--r--tools/config-gen.d/fuzz.conf4
-rw-r--r--tools/config-gen.d/non-libblkid.conf3
-rw-r--r--tools/config-gen.d/non-libmount.conf3
-rw-r--r--tools/config-gen.d/non-libs.conf5
-rw-r--r--tools/config-gen.d/non-libsmartcols.conf3
-rw-r--r--tools/config-gen.d/non-libuuid.conf3
-rw-r--r--tools/config-gen.d/non-nls.conf3
-rw-r--r--tools/config-gen.d/non-widechar.conf3
-rw-r--r--tools/config-gen.d/selinux.conf3
-rw-r--r--tools/config-gen.d/slang.conf3
-rw-r--r--tools/config-gen.d/static.conf3
-rwxr-xr-xtools/git-tp-sync58
-rwxr-xr-xtools/git-tp-sync-man54
-rwxr-xr-xtools/git-version-gen170
-rwxr-xr-xtools/ko-release-gen103
-rwxr-xr-xtools/ko-release-push70
-rwxr-xr-xtools/libtool.m4.patch24
-rw-r--r--tools/meson-make-manpage-stub.sh5
-rwxr-xr-xtools/meson-make-symlink.sh12
-rwxr-xr-xtools/oss-fuzz.sh31
-rw-r--r--tools/smatch-data/no_return_funcs16
47 files changed, 1365 insertions, 0 deletions
diff --git a/tools/Makemodule.am b/tools/Makemodule.am
new file mode 100644
index 0000000..e9845ad
--- /dev/null
+++ b/tools/Makemodule.am
@@ -0,0 +1,56 @@
+
+EXTRA_DIST += \
+ tools/git-tp-sync \
+ tools/git-tp-sync-man \
+ tools/git-version-gen \
+ tools/ko-release-gen \
+ tools/ko-release-push \
+ \
+ tools/checkadoc-missing.sh \
+ tools/checkadoc-repeat.sh \
+ tools/checkcompletion.sh \
+ tools/checkconfig.sh \
+ tools/checkdecl.sh \
+ tools/checkincludes.pl \
+ tools/checklibdocs.sh \
+ tools/checkusage.sh \
+ tools/checkxalloc.sh \
+ \
+ tools/libtool.m4.patch \
+ \
+ tools/compare-buildsys.sh \
+ tools/meson-make-manpage-stub.sh \
+ tools/meson-make-symlink.sh \
+ \
+ tools/smatch-data \
+ tools/smatch-data/no_return_funcs \
+ \
+ tools/oss-fuzz.sh \
+ \
+ tools/config-gen \
+ tools/config-gen-functions.sh \
+ tools/config-gen.d \
+ tools/config-gen.d/fuzz.conf \
+ tools/config-gen.d/chfnsh-libuser.conf \
+ tools/config-gen.d/core.conf \
+ tools/config-gen.d/non-libsmartcols.conf \
+ tools/config-gen.d/devel.conf \
+ tools/config-gen.d/audit.conf \
+ tools/config-gen.d/cryptsetup.conf \
+ tools/config-gen.d/disable-all.conf \
+ tools/config-gen.d/non-nls.conf \
+ tools/config-gen.d/chfnsh-no-password.conf \
+ tools/config-gen.d/enable-schedutils.conf \
+ tools/config-gen.d/chfnsh-pam.conf \
+ tools/config-gen.d/selinux.conf \
+ tools/config-gen.d/all.conf \
+ tools/config-gen.d/devel-non-docs.conf \
+ tools/config-gen.d/non-libblkid.conf \
+ tools/config-gen.d/devel-non-asan.conf \
+ tools/config-gen.d/slang.conf \
+ tools/config-gen.d/static.conf \
+ tools/config-gen.d/all-non-nls.conf \
+ tools/config-gen.d/non-libs.conf \
+ tools/config-gen.d/non-libuuid.conf \
+ tools/config-gen.d/non-widechar.conf \
+ tools/config-gen.d/non-libmount.conf
diff --git a/tools/checkadoc-missing.sh b/tools/checkadoc-missing.sh
new file mode 100755
index 0000000..a1c3b38
--- /dev/null
+++ b/tools/checkadoc-missing.sh
@@ -0,0 +1,89 @@
+#!/bin/bash
+#
+# Copyright (C) 2021 Karel Zak <kzak@redhat.com>
+# based on checkman.sh from Sami Kerola <kerolasa@iki.fi>
+#
+set -e # exit on errors
+set -o pipefail # exit if pipe writer fails
+set -u # disallow usage of unset variables
+set -C # disallow redirection file overwriting
+SCRIPT_INVOCATION_SHORT_NAME=$(basename ${0})
+trap 'echo "${SCRIPT_INVOCATION_SHORT_NAME}: exit on error"; exit 1' ERR
+
+usage() {
+ echo "Usage: ${0} [-vVh]"
+ echo " -h print this help and exit"
+}
+
+while getopts h OPTIONS; do
+ case ${OPTIONS} in
+ h)
+ usage
+ exit 0
+ ;;
+ *)
+ usage
+ exit 1
+ esac
+done
+
+declare -A ADOCS_LIST BIN_LIST
+
+remove_repeats()
+{
+ set +u
+ for KN in ${KNOWN_REPEATS[${I##*/}]}; do
+ if [ "${KN}" = "${REPEATS[$1]}" ]; then
+ if $VERBOSE; then
+ echo "info: ${I} removing repeat: ${REPEATS[$1]}"
+ fi
+ unset REPEATS[$1]
+ fi
+ done
+ set -u
+}
+
+cd $(git rev-parse --show-toplevel)
+
+for I in $(
+ find . -type f -name '*[[:alpha:]].[1-8].adoc' |grep -v "autom4te.cache\|\.libs/\|\.git"
+); do
+ ADOCS_FILE=${I##*/}
+ ADOCS_LIST[${ADOCS_FILE%%.[0-9].adoc}]=1
+done
+
+# Create a list of build targets.
+for I in $(find $(git rev-parse --show-toplevel) -name 'Make*.am' | xargs awk '
+$1 ~ /_SOURCES/ {
+ if ($1 ~ /^test/ ||
+ $1 ~ /^no(inst|dist)/ ||
+ $1 ~ /^sample/ ||
+ $1 ~ /^BUILT/) {
+ next
+ }
+ sub(/_SOURCES/, "")
+ if ($1 ~ /^lib.*_la/) {
+ next
+ }
+ if ($1 ~ /^pylib.*_la/) {
+ next
+ }
+ sub(/_static/, "")
+ gsub(/_/, ".")
+ sub(/switch.root/, "switch_root")
+ sub(/pivot.root/, "pivot_root")
+ print $1
+}'); do
+ BIN_LIST[$I]=1
+done
+
+# Find if build target does not have manual.
+set +u
+for I in ${!BIN_LIST[@]}; do
+ if [ -v ${ADOCS_LIST[$I]} ]; then
+ echo "warning: ${SCRIPT_INVOCATION_SHORT_NAME}: ${I} does not have man page"
+ fi
+done
+set -u
+
+exit 0
diff --git a/tools/checkadoc-repeat.sh b/tools/checkadoc-repeat.sh
new file mode 100755
index 0000000..223d647
--- /dev/null
+++ b/tools/checkadoc-repeat.sh
@@ -0,0 +1,80 @@
+#!/bin/bash
+
+set -e # exit on errors
+set -o pipefail # exit if pipe writer fails
+set -u # disallow usage of unset variables
+set -C # disallow redirection file overwriting
+SCRIPT_INVOCATION_SHORT_NAME=$(basename ${0})
+trap 'echo "${SCRIPT_INVOCATION_SHORT_NAME}: exit on error"; exit 1' ERR
+
+usage() {
+ echo "Usage: ${0} [-vVh]"
+ echo " -h print this help and exit"
+}
+
+VERBOSE='false'
+while getopts vVh OPTIONS; do
+ case ${OPTIONS} in
+ h)
+ usage
+ exit 0
+ ;;
+ *)
+ usage
+ exit 1
+ esac
+done
+
+# Try to find missing manuals matching build targets with manual files.
+declare -A ADOC_LIST
+
+declare -i COUNT_REPEATS=0
+declare -a REPEATS
+declare -A KNOWN_REPEATS
+KNOWN_REPEATS[mount.8.adoc]='foo l2 l c overlay'
+KNOWN_REPEATS[hexdump.1.adoc]='l'
+KNOWN_REPEATS[flock.1.adoc]='"$0"'
+KNOWN_REPEATS[switch_root.8.adoc]='$DIR'
+KNOWN_REPEATS[logger.1.adoc]='-'
+KNOWN_REPEATS[unshare.1.adoc]='1000 0 1'
+
+remove_repeats()
+{
+ set +u
+ for KN in ${KNOWN_REPEATS[${I##*/}]}; do
+ if [ "${KN}" = "${REPEATS[$1]}" ]; then
+ if $VERBOSE; then
+ echo "info: ${I} removing repeat: ${REPEATS[$1]}"
+ fi
+ unset REPEATS[$1]
+ fi
+ done
+ set -u
+}
+
+cd $(git rev-parse --show-toplevel)
+
+for I in $(
+ find . -type f -name '*[[:alpha:]].[1-8].adoc' |grep -v "autom4te.cache\|\.libs/\|\.git"
+); do
+ ADOC_FILE=${I##*/}
+ ADOC_LIST[${ADOC_FILE%%.[0-9]}]=1
+
+ REPEATS=( $(cat ${I} |
+ col -b |
+ sed -e 's/\/\/\/\///g; s/\.\.\.\.//g;' |
+ awk 'BEGIN { p="" } { if (0 < length($0)) { if (p == $0) { print } } p = $0 }') )
+ if [ 0 -lt "${#REPEATS[@]}" ]; then
+ ITER=${#REPEATS[@]}+1
+ while ((ITER--)); do
+ remove_repeats ${ITER}
+ done
+ if [ 0 -lt "${#REPEATS[@]}" ]; then
+ echo "warning: ${I} has repeating words: ${REPEATS[@]}"
+ echo "=================================================="
+ ((++COUNT_REPEATS))
+ fi
+ fi
+done
+
+exit 0
diff --git a/tools/checkcompletion.sh b/tools/checkcompletion.sh
new file mode 100755
index 0000000..f3fdda4
--- /dev/null
+++ b/tools/checkcompletion.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+#
+# This script checks if we have bash-completion scripts for the all compiled
+# binaries.
+#
+# Copyright (C) 2016 Karel Zak <kzak@redhat.com>
+#
+
+
+die() {
+ echo "error: $1"
+ exit 1
+}
+
+usage() {
+ echo "Usage:"
+ echo " $0 [<top_srcdir>]"
+}
+
+# unwanted scripts -- use grep -E, e.g. (aaa|bbb|ccc)
+completion_exclude="(nologin)"
+
+top_srcdir=${1-"."}
+completion_dir="${top_srcdir}/bash-completion"
+
+[ -d "${completion_dir}" ] || die "not found ${completion_dir}"
+
+bin_files=$(cd ${top_srcdir} && find * -maxdepth 0 -perm /u+x \
+ \! -type d \
+ \! -name \*.sh \! -name \*.cache \! -name \*.status \
+ \! -name configure \! -name libtool | sort)
+
+completion_files=$(cd ${completion_dir}/ && find * ! -name '*.am' | sort -u)
+completion_missing=$(comm -3 <(echo "$completion_files") <(echo "$bin_files"))
+
+if [ -n "$completion_missing" -a -n "$completion_exclude" ]; then
+ completion_missing=$(echo "$completion_missing" | grep -v -E "$completion_exclude")
+fi
+
+if [ -n "$completion_missing" ]; then
+ echo "Missing completion scripts:"
+ echo "$completion_missing"
+fi
+
diff --git a/tools/checkconfig.sh b/tools/checkconfig.sh
new file mode 100755
index 0000000..5f2063a
--- /dev/null
+++ b/tools/checkconfig.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+#
+# This script checks for HAVE_ and ENABLE_ macros which are
+# not included in config.h.in
+#
+# Usage: checkconfig.sh <top_srcdir> <srcfile> [<srcfile> ...]
+#
+# Copyright (C) 2007 Matthias Koenig <mkoenig@suse.de>
+# Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+#
+
+
+die() {
+ echo "error: $1"
+ exit 1
+}
+
+usage() {
+ echo "Usage:"
+ echo " $0 <top_srcdir> <srcfile> [<srcfile> ...]"
+ echo "Example:"
+ echo " find . -name '*.c' | xargs $0 \$(git rev-parse --show-toplevel)"
+}
+
+if [ $# -eq 0 ]; then
+ usage
+ exit 1
+fi
+srcdir=$1
+config="$srcdir/config.h.in"
+
+[ -d "$srcdir" ] || die "$srcdir: not such directory."
+[ -f "$config" ] || die "$config: not such file."
+
+shift
+
+while [ "$#" -ne 0 ]; do
+ srcfile=$1
+ shift
+
+ [ ! -f "$srcfile" ] && continue;
+
+ # Note that we use HAVE_ macros since util-linux-ng-2.14. The
+ # previous version also have used ENABLE_ too.
+ #
+ # ENABLE_ and HAVE_ macros shouldn't be used for any other pupose that
+ # for config/build options.
+ #
+ DEFINES=$(sed -n -e 's/.*[ \t(]\+\(HAVE_[[:alnum:]]\+[^ \t);]*\).*/\1/p' \
+ -e 's/.*[ \t(]\+\(ENABLE_[[:alnum:]]\+[^ \t);]*\).*/\1/p' \
+ $srcfile | sort -u)
+ [ -z "$DEFINES" ] && continue
+
+ for d in $DEFINES; do
+ case $d in
+ HAVE_CONFIG_H) continue
+ ;;
+ *) grep -q "$d\( \|\>\)" $config || \
+ echo $(echo $srcfile | sed 's:\\'$srcdir/'::') ": $d"
+ ;;
+ esac
+ done
+done
diff --git a/tools/checkdecl.sh b/tools/checkdecl.sh
new file mode 100755
index 0000000..d2c8f95
--- /dev/null
+++ b/tools/checkdecl.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+#
+# This script checks for #ifdef HAVE_DECL_SYMBOL in code.
+#
+# Autoconf docs:
+#
+# Unlike the other autoconf ‘AC_CHECK_*S’ macros, when a symbol is not
+# declared, HAVE_DECL_symbol is defined to ‘0’ instead of leaving
+# HAVE_DECL_symbol undeclared. When you are sure that the check was performed,
+# use HAVE_DECL_symbol in #if.
+#
+
+if [ ! -f ./configure ]; then
+ echo "Not found configure script"
+ exit 1
+fi
+
+for decl in $(awk '/HAVE_DECL_.*ac_have_decl/ { print $2 }' configure); do
+ git grep -nE '[[:blank:]]*#[[:blank:]]*if(ndef|def)[[:blank:]]*'$decl;
+done | sort -u
diff --git a/tools/checkincludes.pl b/tools/checkincludes.pl
new file mode 100755
index 0000000..c7e547f
--- /dev/null
+++ b/tools/checkincludes.pl
@@ -0,0 +1,24 @@
+#!/usr/bin/perl
+#
+# checkincludes: Find files included more than once in (other) files.
+# Copyright abandoned, 2000, Niels Kristian Bech Jensen <nkbj@image.dk>.
+
+foreach $file (@ARGV) {
+ open(FILE, $file) or die "Cannot open $file: $!.\n";
+
+ my %includedfiles = ();
+
+ while (<FILE>) {
+ if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
+ ++$includedfiles{$1};
+ }
+ }
+
+ foreach $filename (keys %includedfiles) {
+ if ($includedfiles{$filename} > 1) {
+ print "$file: $filename is included more than once.\n";
+ }
+ }
+
+ close(FILE);
+}
diff --git a/tools/checklibdocs.sh b/tools/checklibdocs.sh
new file mode 100755
index 0000000..094d2cb
--- /dev/null
+++ b/tools/checklibdocs.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+FILE_API_SYMBOLS="$1"
+FILE_API_DOCS="$2"
+
+if [ ! -f "$FILE_API_SYMBOLS" ]; then
+ echo "File $FILE_API_SYMBOLS is missing."
+ exit 1
+fi
+
+if [ ! -f "$FILE_API_DOCS" ]; then
+ echo "File $FILE_API_DOCS is missing."
+ exit 1
+fi
+
+fail_ct=0
+api_symbols=$(awk '/^([[:space:]]+)([[:alnum:]_]+);/ { gsub(";",""); print $1; }' "$FILE_API_SYMBOLS" | sort)
+doc_symbols=$(awk '/^([[:space:]])*$/ {next}; !/<.*>/ { print $1 }' "$FILE_API_DOCS" | sort)
+
+echo -n "Checking $FILE_API_SYMBOLS documentation ... "
+
+for sym in $api_symbols; do
+ case "$doc_symbols" in
+ *"$sym"*)
+ #echo -ne "\n '$sym'"
+ ;;
+ *)
+ echo -ne "\n '$sym' undocumented"
+ fail_ct=$(($fail_ct + 1))
+ ;;
+ esac
+done
+
+if [ $fail_ct -ne 0 ]; then
+ echo
+ echo "$fail_ct symbols is missing in ${FILE_API_DOCS}."
+ echo
+ exit 1
+else
+ echo "OK"
+fi
+
+exit 0
diff --git a/tools/checkusage.sh b/tools/checkusage.sh
new file mode 100755
index 0000000..69d69fd
--- /dev/null
+++ b/tools/checkusage.sh
@@ -0,0 +1,159 @@
+#!/bin/bash
+
+## This script is potentially dangerous! Don't run it on
+## arbitrary commands.
+
+export LC_ALL=C
+
+if [ "$#" -lt 1 ]; then
+ echo "usage: $0 program..." >&2
+ echo " or try 'make checkusage' to check all built programs" >&2
+ exit 1
+fi
+
+builddir="."
+cmds=$(echo $@ | tr ' ' '\n' | sort)
+
+# set env to dump all output to files
+test -z "$CU_DUMP" || rm -f /tmp/checkusage--{help,version,unknownopt}
+
+## Set alternative options for --help, --version
+## or --unknownopt. "x" means "not implemented".
+##
+## Examples:
+## alt_whereis__help="-h" # in past whereis(1) had no longopt for --help
+## alt_more__help="x" # more(1) had neither --help nor -h
+
+alt_fsck__unknownopt="x" # fsck passes unknown opts to fsck.ext4, etc.
+alt_mkfs__unknownopt="x" # dito
+alt_kill__unknownopt="inval pids" # trick, kill does not use errtryhelp()
+if [ $(id -ru) -eq 0 ]; then
+ alt_sulogin__unknownopt="x" # would hang at pwd prompt
+fi
+
+function exec_option {
+ local cmdb=$1
+ local cmd=$2
+ opt=$3
+ local tofile="/tmp/checkusage$opt"
+
+ local alt="alt_${cmdb}${opt}"
+ alt=${alt//-/_}
+ alt=${alt//./_}
+ alt=$(eval printf -- \"\$${alt}\")
+ if test -n "$alt"; then
+ if test "$alt" = "x"; then
+ return 1
+ fi
+ opt=$alt
+ fi
+
+ test -z "$CU_DUMP" || {
+ echo "##########################################################"
+ echo "#### $cmdb"
+ $cmd $opt
+ } >> "$tofile" 2>&1
+
+ out=$("$cmd" $opt 2>/dev/null)
+ err=$("$cmd" $opt 2>&1 >/dev/null)
+ ret=$?
+
+ # hardcoded ... nologin should always return false
+ if test "$cmdb" = "nologin" &&
+ test "$opt" = "--help" -o "$opt" = "--version"; then
+ if test "$ret" -eq 0 -o "$ret" -ge 128; then
+ echo "$cmdb, $opt, should return false: $ret"
+ fi
+ ret=0
+ fi
+
+ return 0
+}
+
+
+function check_help {
+ local cb=$1
+ local c=$2
+
+ if ! exec_option "$cb" "$c" --help; then
+ return 1
+ fi
+
+ if test $ret != 0; then
+ echo "$cb: $opt, returns error"
+ else
+ if test -z "$out"; then
+ echo "$cb: $opt, no stdout"
+ fi
+ if test -n "$err"; then
+ echo "$cb: $opt, non-empty stderr"
+ fi
+ fi
+ return 0
+}
+
+function check_version {
+ local cb=$1
+ local c=$2
+
+ if ! exec_option "$cb" "$c" --version; then
+ return 1
+ fi
+
+ if test $ret != 0; then
+ echo "$cb: $opt, returns error"
+ else
+ if test -z "$out"; then
+ echo "$cb: $opt, no stdout"
+ fi
+ if test -n "$err"; then
+ echo "$cb: $opt, non-empty stderr"
+ fi
+ fi
+}
+
+function check_unknownopt {
+ local cb=$1
+ local c=$2
+ local nohelp=$3
+
+ if ! exec_option "$cb" "$c" --unknownopt; then
+ return 1
+ fi
+
+ if test $ret = 0; then
+ echo "$cb: $opt, returns no error"
+ elif test $ret -ge 128; then
+ echo "$cb: $opt, abnormal exit: $ret"
+ fi
+ if test -n "$out"; then
+ echo "$cb: $opt, non-empty stdout"
+ fi
+ if test -z "$err"; then
+ echo "$cb: $opt, no stderr"
+ elif test -z "$nohelp" -o "$nohelp" != "yes"; then
+ out_len=$(echo "$out" | wc -l)
+ err_len=$(echo "$err" | wc -l)
+ if test "$err_len" -gt 2; then
+ echo "$cb: $opt, stderr too long: $err_len"
+ elif test "$err_len" -lt 2; then
+ echo "$cb: $opt, stderr too short: $err_len"
+ fi
+ fi
+}
+
+for cb in $cmds; do
+ c="$builddir/$cb"
+ if ! type "$c" &>/dev/null; then
+ echo "$cb: does not exist"
+ continue
+ fi
+
+ nohelp="no"
+ if ! check_help "$cb" "$c"; then
+ nohelp="yes"
+ fi
+ check_version "$cb" "$c"
+ check_unknownopt "$cb" "$c" "$nohelp"
+done
+
diff --git a/tools/checkxalloc.sh b/tools/checkxalloc.sh
new file mode 100755
index 0000000..3c34254
--- /dev/null
+++ b/tools/checkxalloc.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+#
+# Find files which include the xalloc.h header, but which still call
+# the unwrapped calloc and malloc.
+#
+
+cd "$(git rev-parse --show-toplevel)" || {
+ echo "error: failed to chdir to git root"
+ exit 1
+}
+
+git grep -zl '#include "xalloc.h"' |
+ xargs -0 grep -nE '\b(([cm]|re)alloc|strdup|asprintf)[[:space:]]*\([^)]'
+
+result=$?
+
+if [ $result -eq 123 ]; then
+ exit 0 # not found
+elif [ $result -eq 0 ]; then
+ exit 1 # found
+fi
+
+exit $result
diff --git a/tools/compare-buildsys.sh b/tools/compare-buildsys.sh
new file mode 100755
index 0000000..e88cbd5
--- /dev/null
+++ b/tools/compare-buildsys.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+FILTER="$1"
+
+MESON_CONFIG_H="build/config.h"
+AUTOCONF_CONFIG_H="./config.h"
+
+if [ ! -f $MESON_CONFIG_H ]; then
+ echo 'Meson is not ready in the build/ directory (try "meson build")'
+ exit 1
+fi
+
+if [ ! -f $AUTOCONF_CONFIG_H ]; then
+ echo 'Autotools are not ready (try "./autogen.sh; ./configure")'
+ exit 1
+fi
+
+TMPFILE_MESON="/tmp/util-linux-meson"
+TMPFILE_AUTOCONF="/tmp/util-linux-autoconf"
+
+GREP_PATTERN="#define "
+
+if [ "$FILTER" = "headers" ]; then
+ GREP_PATTERN="#define .*_H[[:blank:]]"
+fi
+
+echo "===MESON===" > $TMPFILE_MESON
+grep "$GREP_PATTERN" $MESON_CONFIG_H | sort >> $TMPFILE_MESON
+
+echo "===AUTOCONF===" > $TMPFILE_AUTOCONF
+grep "$GREP_PATTERN" $AUTOCONF_CONFIG_H | sort >> $TMPFILE_AUTOCONF
+
+diff --side-by-side $TMPFILE_AUTOCONF $TMPFILE_MESON
+
+rm -rf $TMPFILE_MESON $TMPFILE_AUTOCONF
diff --git a/tools/config-gen b/tools/config-gen
new file mode 100755
index 0000000..e1d6474
--- /dev/null
+++ b/tools/config-gen
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# Copyright (C) 2011 Karel Zak <kzak@redhat.com>
+#
+
+test -f sys-utils/mount.c || {
+ echo
+ echo "You must run this script in the top-level util-linux directory"
+ echo
+ exit 1
+}
+
+. tools/config-gen-functions.sh
+
+if [ $# -eq 0 ]; then
+ echo "This script requires at least one of the folloving arguments:"
+ cd tools/config-gen.d
+ for i in *.conf; do
+ echo " ${i%%.conf}"
+ done
+ exit 1
+fi
+
+while [ -n "$1" ]; do
+ opts="$opts $(ul_get_configuration tools/config-gen.d/$1.conf)"
+ if [ "$1" == "fuzz" ]; then
+ export CC=${CC:-clang}
+ export CXX=${CXX:-clang++}
+ fi
+ shift
+done
+
+opts=$(echo $opts | tr " " "\n" | sort -u)
+echo "Configure options:"
+for x in $opts; do
+ echo " $x"
+done
+echo
+
+if [ -n "$CFLAGS" ]; then
+ echo "CFLAGS: $CFLAGS"
+ CFLAGS="$CFLAGS"
+ export CFLAGS
+ echo
+fi
+if [ -n "$LDFLAGS" ]; then
+ echo "LDFLAGS: $LDFLAGS"
+ LDFLAGS="$LDFLAGS"
+ export LDFLAGS
+ echo
+fi
+
+if [ ! -f ./configure ]; then
+ ./autogen.sh
+fi
+
+./configure $opts
diff --git a/tools/config-gen-functions.sh b/tools/config-gen-functions.sh
new file mode 100644
index 0000000..ea62432
--- /dev/null
+++ b/tools/config-gen-functions.sh
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2011 Karel Zak <kzak@redhat.com>
+#
+
+
+# Returns configure options from selected config file
+#
+# ul_get_configuration <config-file>
+#
+# for example
+#
+# ul_get_configuration $top_srcdir/tools/config-gen.d/all
+#
+ul_get_configuration() {
+ local conf="$1"
+ local dir=$(dirname $1)
+ local opts=$(cat $conf)
+ local old_opts=
+
+ while [ "$opts" != "$old_opts" ]; do
+ local new_opts=
+
+ old_opts="$opts"
+ for citem in $opts; do
+ case $citem in
+ include:*) new_opts="$new_opts $(cat $dir/${citem##*:})" ;;
+ *) new_opts="$new_opts $citem" ;;
+ esac
+ done
+ opts="$new_opts"
+ done
+ echo $opts | tr " " "\n" | sort -u
+}
diff --git a/tools/config-gen.d/all-non-nls.conf b/tools/config-gen.d/all-non-nls.conf
new file mode 100644
index 0000000..d8fc6fe
--- /dev/null
+++ b/tools/config-gen.d/all-non-nls.conf
@@ -0,0 +1,2 @@
+include:all.conf
+include:non-nls.conf
diff --git a/tools/config-gen.d/all.conf b/tools/config-gen.d/all.conf
new file mode 100644
index 0000000..f8860a1
--- /dev/null
+++ b/tools/config-gen.d/all.conf
@@ -0,0 +1,5 @@
+include:core.conf
+
+--enable-all-programs
+--enable-login-stat-mail
+--with-smack
diff --git a/tools/config-gen.d/audit.conf b/tools/config-gen.d/audit.conf
new file mode 100644
index 0000000..604b78d
--- /dev/null
+++ b/tools/config-gen.d/audit.conf
@@ -0,0 +1,3 @@
+include:core.conf
+
+--with-audit
diff --git a/tools/config-gen.d/chfnsh-libuser.conf b/tools/config-gen.d/chfnsh-libuser.conf
new file mode 100644
index 0000000..9bb6bfe
--- /dev/null
+++ b/tools/config-gen.d/chfnsh-libuser.conf
@@ -0,0 +1,5 @@
+include:audit.conf
+include:selinux.conf
+
+--enable-chfn-chsh
+--with-user
diff --git a/tools/config-gen.d/chfnsh-no-password.conf b/tools/config-gen.d/chfnsh-no-password.conf
new file mode 100644
index 0000000..fba4264
--- /dev/null
+++ b/tools/config-gen.d/chfnsh-no-password.conf
@@ -0,0 +1,6 @@
+include:audit.conf
+include:selinux.conf
+
+--enable-chfn-chsh
+--disable-chfn-chsh-password
+--without-user
diff --git a/tools/config-gen.d/chfnsh-pam.conf b/tools/config-gen.d/chfnsh-pam.conf
new file mode 100644
index 0000000..f859f58
--- /dev/null
+++ b/tools/config-gen.d/chfnsh-pam.conf
@@ -0,0 +1,6 @@
+include:audit.conf
+include:selinux.conf
+
+--enable-chfn-chsh
+--enable-chfn-chsh-password
+--without-user
diff --git a/tools/config-gen.d/core.conf b/tools/config-gen.d/core.conf
new file mode 100644
index 0000000..4abf4e0
--- /dev/null
+++ b/tools/config-gen.d/core.conf
@@ -0,0 +1,2 @@
+--disable-rpath
+--disable-makeinstall-chown
diff --git a/tools/config-gen.d/cryptsetup.conf b/tools/config-gen.d/cryptsetup.conf
new file mode 100644
index 0000000..d52d529
--- /dev/null
+++ b/tools/config-gen.d/cryptsetup.conf
@@ -0,0 +1,3 @@
+include:all.conf
+
+--with-cryptsetup
diff --git a/tools/config-gen.d/devel-non-asan.conf b/tools/config-gen.d/devel-non-asan.conf
new file mode 100644
index 0000000..b7c18ab
--- /dev/null
+++ b/tools/config-gen.d/devel-non-asan.conf
@@ -0,0 +1,7 @@
+include:all.conf
+include:audit.conf
+include:selinux.conf
+
+--enable-gtk-doc
+--with-utempter
+--enable-werror
diff --git a/tools/config-gen.d/devel-non-docs.conf b/tools/config-gen.d/devel-non-docs.conf
new file mode 100644
index 0000000..7eeffdb
--- /dev/null
+++ b/tools/config-gen.d/devel-non-docs.conf
@@ -0,0 +1,6 @@
+include:all.conf
+include:audit.conf
+include:selinux.conf
+
+--with-utempter
+--enable-werror
diff --git a/tools/config-gen.d/devel.conf b/tools/config-gen.d/devel.conf
new file mode 100644
index 0000000..7493372
--- /dev/null
+++ b/tools/config-gen.d/devel.conf
@@ -0,0 +1,8 @@
+include:all.conf
+include:audit.conf
+include:selinux.conf
+
+--enable-gtk-doc
+--with-utempter
+--enable-asan
+--enable-werror
diff --git a/tools/config-gen.d/disable-all.conf b/tools/config-gen.d/disable-all.conf
new file mode 100644
index 0000000..1d178b2
--- /dev/null
+++ b/tools/config-gen.d/disable-all.conf
@@ -0,0 +1 @@
+--disable-all-programs
diff --git a/tools/config-gen.d/enable-schedutils.conf b/tools/config-gen.d/enable-schedutils.conf
new file mode 100644
index 0000000..08deee4
--- /dev/null
+++ b/tools/config-gen.d/enable-schedutils.conf
@@ -0,0 +1,3 @@
+include:disable-all.conf
+
+--enable-schedutils
diff --git a/tools/config-gen.d/fuzz.conf b/tools/config-gen.d/fuzz.conf
new file mode 100644
index 0000000..b1d8eda
--- /dev/null
+++ b/tools/config-gen.d/fuzz.conf
@@ -0,0 +1,4 @@
+include:devel.conf
+
+--enable-ubsan
+--enable-fuzzing-engine
diff --git a/tools/config-gen.d/non-libblkid.conf b/tools/config-gen.d/non-libblkid.conf
new file mode 100644
index 0000000..b3a7452
--- /dev/null
+++ b/tools/config-gen.d/non-libblkid.conf
@@ -0,0 +1,3 @@
+include:core.conf
+
+--disable-libblkid
diff --git a/tools/config-gen.d/non-libmount.conf b/tools/config-gen.d/non-libmount.conf
new file mode 100644
index 0000000..dae9d60
--- /dev/null
+++ b/tools/config-gen.d/non-libmount.conf
@@ -0,0 +1,3 @@
+include:core.conf
+
+--disable-libmount
diff --git a/tools/config-gen.d/non-libs.conf b/tools/config-gen.d/non-libs.conf
new file mode 100644
index 0000000..a73e8ad
--- /dev/null
+++ b/tools/config-gen.d/non-libs.conf
@@ -0,0 +1,5 @@
+include:core.conf
+include:non-libblkid.conf
+include:non-libmount.conf
+include:non-libuuid.conf
+include:non-libsmartcols.conf
diff --git a/tools/config-gen.d/non-libsmartcols.conf b/tools/config-gen.d/non-libsmartcols.conf
new file mode 100644
index 0000000..ea273bf
--- /dev/null
+++ b/tools/config-gen.d/non-libsmartcols.conf
@@ -0,0 +1,3 @@
+include:core.conf
+
+--disable-libsmartcols
diff --git a/tools/config-gen.d/non-libuuid.conf b/tools/config-gen.d/non-libuuid.conf
new file mode 100644
index 0000000..8ac0629
--- /dev/null
+++ b/tools/config-gen.d/non-libuuid.conf
@@ -0,0 +1,3 @@
+include:core.conf
+
+--disable-libuuid
diff --git a/tools/config-gen.d/non-nls.conf b/tools/config-gen.d/non-nls.conf
new file mode 100644
index 0000000..029ad9a
--- /dev/null
+++ b/tools/config-gen.d/non-nls.conf
@@ -0,0 +1,3 @@
+include:core.conf
+
+--disable-nls
diff --git a/tools/config-gen.d/non-widechar.conf b/tools/config-gen.d/non-widechar.conf
new file mode 100644
index 0000000..7319726
--- /dev/null
+++ b/tools/config-gen.d/non-widechar.conf
@@ -0,0 +1,3 @@
+include:core.conf
+
+--disable-widechar
diff --git a/tools/config-gen.d/selinux.conf b/tools/config-gen.d/selinux.conf
new file mode 100644
index 0000000..288cf55
--- /dev/null
+++ b/tools/config-gen.d/selinux.conf
@@ -0,0 +1,3 @@
+include:core.conf
+
+--with-selinux
diff --git a/tools/config-gen.d/slang.conf b/tools/config-gen.d/slang.conf
new file mode 100644
index 0000000..ee20993
--- /dev/null
+++ b/tools/config-gen.d/slang.conf
@@ -0,0 +1,3 @@
+include:core.conf
+
+--with-slang
diff --git a/tools/config-gen.d/static.conf b/tools/config-gen.d/static.conf
new file mode 100644
index 0000000..bc19283
--- /dev/null
+++ b/tools/config-gen.d/static.conf
@@ -0,0 +1,3 @@
+include:core.conf
+
+--enable-static-programs
diff --git a/tools/git-tp-sync b/tools/git-tp-sync
new file mode 100755
index 0000000..c2e2d8d
--- /dev/null
+++ b/tools/git-tp-sync
@@ -0,0 +1,58 @@
+#!/bin/bash
+#
+# git-tp-sync - downloads the latest PO files from translationproject.org
+# and commits changes to your GIT repository.
+#
+# Features:
+# - commit per PO file (no more huge commits for all .po files)
+# - the commit "Author:" field is set according to the Last-Translator
+#
+# Copyright (C) 2007-2016 Karel Zak <kzak@redhat.com>
+#
+# 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 file 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.
+#
+
+PROJECT="util-linux"
+if [ -n "$1" ]; then
+ while (( "$#" )); do
+ if [ -n "$1" ]; then
+ rsync -Lrtvz rsync://translationproject.org/tp/latest/$PROJECT/$1.po po
+ fi
+ shift
+ done
+else
+ rsync -Lrtvz rsync://translationproject.org/tp/latest/$PROJECT/ po
+fi
+
+PO_NEW=$(git ls-files -o | gawk '/po\/[[:alpha:]_\-]*\.po/ { sub("po/", ""); print $0; }' | sort)
+PO_MOD=$(git ls-files -m | gawk '/po\/[[:alpha:]_\-]*\.po/ { sub("po/", ""); print $0; }' | sort)
+
+function get_author {
+ echo $(gawk 'BEGIN { FS=": " } /Last-Translator/ { sub("\\\\n\"", ""); print $2 }' "$1")
+}
+
+function do_commit {
+ local POFILE="$1"
+ local MSG="$2"
+ local AUTHOR=$(get_author "$POFILE")
+
+ git commit --author "$AUTHOR" -m "$MSG" "$POFILE"
+}
+
+for f in $PO_MOD; do
+ do_commit "po/$f" "po: update $f (from translationproject.org)"
+done
+
+for f in $PO_NEW; do
+ git add "po/$f"
+ do_commit "po/$f" "po: add $f (from translationproject.org)"
+done
+
diff --git a/tools/git-tp-sync-man b/tools/git-tp-sync-man
new file mode 100755
index 0000000..8a4f34f
--- /dev/null
+++ b/tools/git-tp-sync-man
@@ -0,0 +1,54 @@
+#!/bin/bash
+#
+# Based on tools/git-tp-sync.
+# Copyright (C) 2007-2016 Karel Zak <kzak@redhat.com>
+#
+# TODO: merge git-tp-sync and git-tp-sync-man scripts.
+#
+# 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 file 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.
+#
+
+PROJECT="util-linux-man"
+if [ -n "$1" ]; then
+ while (( "$#" )); do
+ if [ -n "$1" ]; then
+ rsync -Lrtvz rsync://translationproject.org/tp/latest/$PROJECT/$1.po po-man
+ fi
+ shift
+ done
+else
+ rsync -Lrtvz rsync://translationproject.org/tp/latest/$PROJECT/ po-man
+fi
+
+PO_NEW=$(git ls-files -o | gawk '/po-man\/[[:alpha:]_\-]*\.po/ { sub("po-man/", ""); print $0; }' | sort)
+PO_MOD=$(git ls-files -m | gawk '/po-man\/[[:alpha:]_\-]*\.po/ { sub("po-man/", ""); print $0; }' | sort)
+
+function get_author {
+ echo $(gawk 'BEGIN { FS=": " } /Last-Translator/ { sub("\\\\n\"", ""); print $2 }' "$1")
+}
+
+function do_commit {
+ local POFILE="$1"
+ local MSG="$2"
+ local AUTHOR=$(get_author "$POFILE")
+
+ git commit --author "$AUTHOR" -m "$MSG" "$POFILE"
+}
+
+for f in $PO_MOD; do
+ do_commit "po-man/$f" "po-man: update $f (from translationproject.org)"
+done
+
+for f in $PO_NEW; do
+ git add "po-man/$f"
+ do_commit "po-man/$f" "po-man: add $f (from translationproject.org)"
+done
+
diff --git a/tools/git-version-gen b/tools/git-version-gen
new file mode 100755
index 0000000..435f1fa
--- /dev/null
+++ b/tools/git-version-gen
@@ -0,0 +1,170 @@
+#!/bin/sh
+# Print a version string.
+scriptversion=2011-02-19.19; # UTC
+
+# Copyright (C) 2007-2011 Free Software Foundation, Inc.
+# Copyright (C) 2011-2021 Karel Zak <kzak@redhat.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
+# It may be run two ways:
+# - from a git repository in which the "git describe" command below
+# produces useful output (thus requiring at least one signed tag)
+# - from a non-git-repo directory containing a .tarball-version file, which
+# presumes this script is invoked like "./git-version-gen [.tarball-version]".
+
+# In order to use intra-version strings in your project, you will need:
+#
+# .tarball-version - present only in a distribution tarball, and not in
+# a checked-out repository. Created with contents that were learned at
+# the last time autoconf was run, and used by git-version-gen. Must not
+# be present in either $(srcdir) or $(builddir) for git-version-gen to
+# give accurate answers during normal development with a checked out tree,
+# but must be present in a tarball when there is no version control system.
+# Therefore, it cannot be used in any dependencies. GNUmakefile has
+# hooks to force a reconfigure at distribution time to get the value
+# correct, without penalizing normal development with extra reconfigures.
+#
+# .version - present in a checked-out repository and in a distribution
+# tarball. Usable in dependencies, particularly for files that don't
+# want to depend on config.h but do want to track version changes.
+# Delete this file prior to any autoconf run where you want to rebuild
+# files to pick up a version string change; and leave it stale to
+# minimize rebuild time after unrelated changes to configure sources.
+#
+# NEWS - present everywhere. It's used only as a fallback solution for
+# 3rd-party tarballs generated by the unofficial way (e.g. GitHub).
+# The version string is read from the first line of the file, the expected
+# format is "project-name version: date".
+#
+# It is probably wise to add these two files to .gitignore, so that you
+# don't accidentally commit either generated file.
+#
+# Use the following line in your configure.ac, so that $(VERSION) will
+# automatically be up-to-date each time configure is run (and note that
+# since configure.ac no longer includes a version string, Makefile rules
+# should not depend on configure.ac for version updates).
+#
+# AC_INIT([GNU project],
+# m4_esyscmd([build-aux/git-version-gen .tarball-version]),
+# [bug-project@example])
+#
+# Then use the following lines in your Makefile.am, so that .version
+# will be present for dependencies, and so that .tarball-version will
+# exist in distribution tarballs.
+#
+# BUILT_SOURCES = $(top_srcdir)/.version
+# $(top_srcdir)/.version:
+# echo $(VERSION) > $@-t && mv $@-t $@
+# dist-hook:
+# echo $(VERSION) > $(distdir)/.tarball-version
+
+case $# in
+ 0|1|2) ;;
+ *) echo 1>&2 "Usage: $0 [[\$srcdir/.tarball-version]" \
+ '[TAG-NORMALIZATION-SED-SCRIPT]]'
+ exit 1;;
+esac
+
+tarball_version_file=${1:-".tarball-version"}
+tag_sed_script="${2:-s/x/x/}"
+nl='
+'
+
+# Avoid meddling by environment variable of the same name.
+v=
+v_from_git=
+
+# First see if there is a tarball-only version file.
+# then try "git describe", then default.
+if test -f $tarball_version_file
+then
+ v=`cat $tarball_version_file` || v=
+ case $v in
+ *$nl*) v= ;; # reject multi-line output
+ [0-9]*) ;;
+ *) v= ;;
+ esac
+ test -z "$v" \
+ && echo "$0: WARNING: $tarball_version_file is missing or damaged" 1>&2
+fi
+
+if test -n "$v"
+then
+ : # use $v
+# Otherwise, if there is at least one git commit involving the working
+# directory, and "git describe" output looks sensible, use that to
+# derive a version string.
+elif test "`git log -1 --pretty=format:x . 2>&1`" = x \
+ && v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
+ || git describe --abbrev=4 HEAD 2>/dev/null` \
+ && v=`printf '%s\n' "$v" | sed "$tag_sed_script"` \
+ && case $v in
+ v[0-9]*) ;;
+ *) (exit 1) ;;
+ esac
+then
+
+ # Remove the "g" in git describe's output string, to save a byte.
+ v=`echo "$v" | sed 's/-g/-/'`;
+
+ case $v in
+ *-rc*)
+ ;;
+ *)
+ # Change the first '-' to a '.', so version-comparing tools work properly.
+ v=`echo "$v" | sed 's/-/./'`;
+ ;;
+ esac
+ v_from_git=1
+else
+ if test -f NEWS
+ then
+ v=`sed '1s/.*[[:blank:]]\(.*\):.*/\1/; q;' NEWS`
+ else
+ v=UNKNOWN
+ fi
+fi
+
+v=`echo "$v" |sed 's/^v//'`
+
+# Test whether to append the "-dirty" suffix only if the version
+# string we're using came from git. I.e., skip the test if it's "UNKNOWN"
+# or if it came from .tarball-version.
+if test -n "$v_from_git"; then
+ # Don't declare a version "dirty" merely because a time stamp has changed.
+ git update-index --refresh > /dev/null 2>&1
+
+ dirty=`exec 2>/dev/null;git diff-index --name-only HEAD` || dirty=
+ case "$dirty" in
+ '') ;;
+ *) # Append the suffix only if there isn't one already.
+ case $v in
+ *-dirty) ;;
+ *) v="$v-dirty" ;;
+ esac ;;
+ esac
+fi
+
+# Omit the trailing newline, so that m4_esyscmd can use the result directly.
+echo "$v" | tr -d "$nl"
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/tools/ko-release-gen b/tools/ko-release-gen
new file mode 100755
index 0000000..b3afc39
--- /dev/null
+++ b/tools/ko-release-gen
@@ -0,0 +1,103 @@
+#!/bin/sh
+#
+# Copyright (C) 2012 Karel Zak <kzak@redhat.com>
+#
+# Usage: ko-release-gen [<directory> [<file>]]
+#
+# This script prepares a new release for publishing on kernel.org. The
+# hierarchy of release files is created in the <directory> (default directory
+# is "kernel.org"). Use case:
+#
+# make distcheck
+# make changelog
+# tools/ko-release-gen
+# tools/ko-release-push
+#
+
+cd "$(git rev-parse --show-toplevel)" || {
+ echo "error: failed to chdir to git root"
+ exit 1
+}
+
+[ -f ".version" ] || \
+ echo "error: cannot found version file (call make distcheck)"
+
+VERSION=$(cat .version)
+VERSION_MAJOR=$(echo $VERSION | sed 's/-rc[0-9]//; s/\(.*\..*\)\..*/\1/')
+VERSION_DOCS=$(echo $VERSION | sed 's/-rc[0-9]//')
+DISTDIR=${1:-"kernel.org"}/v${VERSION_MAJOR}
+
+GPG_PROG=${GPG_PROG:-"gpg"}
+GPG_CMD="$GPG_PROG --use-agent --armor --detach-sign --quiet"
+
+die() {
+ echo $1
+ exit 1
+}
+
+add_file() {
+ local src="$1"
+ local name=$(basename $1)
+ local subdir=$DISTDIR/${2:-""}
+
+ mkdir -p $subdir
+ cp $src $subdir || die "$src: copy failed"
+
+ [ -f $subdir/$name ] || die "$name not found"
+ echo -n " $subdir/$name ..."
+
+ case "$name" in
+ *.tar.xz)
+ local sig=$(echo "$name" | sed 's/\.tar\.xz/.tar.sign/')
+ xz -d -c $subdir/$name | $GPG_CMD --output $subdir/$sig
+ ;;
+ *.tar.gz)
+ local sig=$(echo "$name" | sed 's/\.tar\.gz/.tar.sign/')
+ gzip -d -c $subdir/$name | $GPG_CMD --output $subdir/$sig
+ ;;
+ *.tar.bz2)
+ local sig=$(echo "$name" | sed 's/\.tar\.bz2/.tar.sign/')
+ bzip2 -d -c $subdir/$name | $GPG_CMD --output $subdir/$sig
+ ;;
+ *)
+ local sig="${name}.sign"
+ cat $subdir/$name | $GPG_CMD --output $subdir/$sig
+ ;;
+ esac
+ echo " OK "
+}
+
+add_html_dir() {
+ local src="$1" # source dir
+ local tgt="$2" # target dir
+
+ for fl in $(ls $src/*.html $src/*.css $src/*.png); do
+ add_file $fl $tgt
+ done
+}
+
+rm -rf $DISTDIR
+
+eval $(gpg-agent --daemon)
+
+# Add just specified files only
+if [ -f "$2" ]; then
+ shift
+ while (( "$#" )); do
+ add_file "$1"
+ shift
+ done
+ killall gpg-agent
+ exit 0
+fi
+
+add_file util-linux-${VERSION}.tar.xz
+add_file v${VERSION}-ChangeLog
+add_file Documentation/releases/v${VERSION_DOCS}-ReleaseNotes
+add_html_dir libmount/docs/html libmount-docs
+add_html_dir libblkid/docs/html libblkid-docs
+add_html_dir libsmartcols/docs/html libsmartcols-docs
+add_html_dir libfdisk/docs/html libfdisk-docs
+
+killall gpg-agent
+
diff --git a/tools/ko-release-push b/tools/ko-release-push
new file mode 100755
index 0000000..530c3a7
--- /dev/null
+++ b/tools/ko-release-push
@@ -0,0 +1,70 @@
+#!/bin/sh
+#
+# Copyright (C) 2012 Karel Zak <kzak@redhat.com>
+#
+# Usage: ko-release-push [<directory> [<version>]]
+#
+# This script pushs files from <directory>/v<version> to kernel.org. The
+# default <directory> is "kernel.org" and the default <version> is the current
+# package version.
+#
+# The <directory>/v<version> files should be generated by ko-release-gen script.
+#
+
+cd "$(git rev-parse --show-toplevel)" || {
+ echo "error: failed to chdir to git root"
+ exit 1
+}
+
+[ -f ".version" ] || \
+ echo "error: cannot found version file (call make distcheck)"
+
+VERSION=${2:-$(cat .version)}
+VERSION_MAJOR=$(echo $VERSION | sed 's/-rc[0-9]//; s/\(.*\..*\)\..*/\1/')
+BASEDIR=${1:-"kernel.org"}
+DISTDIR="${BASEDIR}/v${VERSION_MAJOR}"
+
+KO_DIR="/pub/linux/utils/util-linux/v${VERSION_MAJOR}"
+
+die() {
+ echo $1
+ exit 1
+}
+
+function push_file {
+ local sig="$1"
+
+ case "$sig" in
+ *.tar.sign)
+ fl=${sig%%.sign}
+ if [ -f ${fl}.xz ]; then fl=${fl}.xz
+ elif [ -f ${fl}.gz ]; then fl=${fl}.gz
+ elif [ -f ${fl}.bz2 ]; then fl=${fl}.bz2
+ else die "cannot found original file for $sig"
+ fi
+ ;;
+ *)
+ fl=$(echo "$sig" | sed 's/\.sign//')
+ ;;
+ esac
+
+ echo -n " PUSH $fl ..."
+ kup put $fl $sig ${KO_DIR}/${fl##${DISTDIR}/}
+ echo " OK "
+}
+
+[ -d "$DISTDIR" ] || die "$DISTDIR: Not such directory"
+
+FILES=$(find $DISTDIR -name "*.sign" | sort)
+DIRS=$(for f in $FILES; do echo $(dirname ${KO_DIR}/${f##${DISTDIR}/}); done | sort -u)
+
+for d in $DIRS; do
+ echo -n " MKDIR $d ..."
+ kup mkdir $d
+ echo " OK "
+done
+
+for f in $FILES; do
+ push_file $f
+done
+
diff --git a/tools/libtool.m4.patch b/tools/libtool.m4.patch
new file mode 100755
index 0000000..bd8becd
--- /dev/null
+++ b/tools/libtool.m4.patch
@@ -0,0 +1,24 @@
+--- a/m4/libtool.m4 2021-10-14 11:55:26.305333399 +0200
++++ b/m4/libtool.m4 2021-10-14 12:01:45.487505638 +0200
+@@ -1067,16 +1067,11 @@
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+- darwin*) # darwin 5.x on
+- # if running on 10.5 or later, the deployment target defaults
+- # to the OS version, if on x86, and 10.4, the deployment
+- # target defaults to 10.4. Don't you love it?
+- case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+- 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+- _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+- 10.[[012]][[,.]]*)
+- _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+- 10.*)
++ darwin*)
++ case ${MACOSX_DEPLOYMENT_TARGET},$host in
++ 10.[[012]],*|,*powerpc*)
++ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
++ *)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
diff --git a/tools/meson-make-manpage-stub.sh b/tools/meson-make-manpage-stub.sh
new file mode 100644
index 0000000..b1af333
--- /dev/null
+++ b/tools/meson-make-manpage-stub.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+set -eu
+
+mkdir -vp "$(dirname "${DESTDIR:-}$2")"
+printf '.so %s\n' "$1" > "${DESTDIR:-}$2"
diff --git a/tools/meson-make-symlink.sh b/tools/meson-make-symlink.sh
new file mode 100755
index 0000000..061e81a
--- /dev/null
+++ b/tools/meson-make-symlink.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+set -eu
+
+# this is needed mostly because $DESTDIR is provided as a variable,
+# and we need to create the target directory...
+
+mkdir -vp "$(dirname "${DESTDIR:-}$2")"
+if [ "$(dirname $1)" = . ]; then
+ ln -fs -T "$1" "${DESTDIR:-}$2"
+else
+ ln -fs -T --relative "${DESTDIR:-}$1" "${DESTDIR:-}$2"
+fi
diff --git a/tools/oss-fuzz.sh b/tools/oss-fuzz.sh
new file mode 100755
index 0000000..588d4aa
--- /dev/null
+++ b/tools/oss-fuzz.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+
+set -ex
+
+export LC_CTYPE=C.UTF-8
+
+export CC=${CC:-clang}
+export CXX=${CXX:-clang++}
+export LIB_FUZZING_ENGINE=${LIB_FUZZING_ENGINE:--fsanitize=fuzzer}
+
+SANITIZER=${SANITIZER:-address -fsanitize-address-use-after-scope}
+flags="-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=$SANITIZER -fsanitize=fuzzer-no-link"
+
+export CFLAGS=${CFLAGS:-$flags}
+export CXXFLAGS=${CXXFLAGS:-$flags}
+
+export OUT=${OUT:-$(pwd)/out}
+mkdir -p $OUT
+
+./autogen.sh
+./configure --disable-all-programs --enable-libuuid --enable-libfdisk --enable-last --enable-fuzzing-engine --enable-libmount --enable-libblkid
+make -j$(nproc) V=1 check-programs
+
+for d in "$(dirname $0)"/../tests/ts/fuzzers/test_*_fuzz_files; do
+ bd=$(basename "$d")
+ fuzzer=${bd%_files}
+ zip -jqr $OUT/${fuzzer}_seed_corpus.zip "$d"
+done
+
+find . -maxdepth 1 -type f -executable -name "test_*_fuzz" -exec mv {} $OUT \;
+find . -type f -name "fuzz-*.dict" -exec cp {} $OUT \;
diff --git a/tools/smatch-data/no_return_funcs b/tools/smatch-data/no_return_funcs
new file mode 100644
index 0000000..9da8de8
--- /dev/null
+++ b/tools/smatch-data/no_return_funcs
@@ -0,0 +1,16 @@
+// list of functions which don't return.
+// generated by `gen_no_return_funcs.sh`
+__assert_fail
+exit
+__builtin_unreachable
+help
+server_loop
+terminate_intr
+usage
+err
+errx
+err_oom
+log_err
+sleepexit
+die
+badconv